PageRenderTime 40ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llrender/llfontfreetype.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 595 lines | 439 code | 97 blank | 59 comment | 65 complexity | 2de0f25948265440b840ceecacde2223 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llfontfreetype.cpp
  3. * @brief Freetype font library wrapper
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "llfontfreetype.h"
  28. #include "llfontgl.h"
  29. // Freetype stuff
  30. #include <ft2build.h>
  31. // For some reason, this won't work if it's not wrapped in the ifdef
  32. #ifdef FT_FREETYPE_H
  33. #include FT_FREETYPE_H
  34. #endif
  35. #include "llerror.h"
  36. #include "llimage.h"
  37. //#include "llimagej2c.h"
  38. #include "llmath.h" // Linden math
  39. #include "llstring.h"
  40. //#include "imdebug.h"
  41. #include "llfontbitmapcache.h"
  42. #include "llgl.h"
  43. FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL;
  44. LLFontManager *gFontManagerp = NULL;
  45. FT_Library gFTLibrary = NULL;
  46. //static
  47. void LLFontManager::initClass()
  48. {
  49. if (!gFontManagerp)
  50. {
  51. gFontManagerp = new LLFontManager;
  52. }
  53. }
  54. //static
  55. void LLFontManager::cleanupClass()
  56. {
  57. delete gFontManagerp;
  58. gFontManagerp = NULL;
  59. }
  60. LLFontManager::LLFontManager()
  61. {
  62. int error;
  63. error = FT_Init_FreeType(&gFTLibrary);
  64. if (error)
  65. {
  66. // Clean up freetype libs.
  67. llerrs << "Freetype initialization failure!" << llendl;
  68. FT_Done_FreeType(gFTLibrary);
  69. }
  70. }
  71. LLFontManager::~LLFontManager()
  72. {
  73. FT_Done_FreeType(gFTLibrary);
  74. }
  75. LLFontGlyphInfo::LLFontGlyphInfo(U32 index)
  76. : mGlyphIndex(index),
  77. mWidth(0), // In pixels
  78. mHeight(0), // In pixels
  79. mXAdvance(0.f), // In pixels
  80. mYAdvance(0.f), // In pixels
  81. mXBitmapOffset(0), // Offset to the origin in the bitmap
  82. mYBitmapOffset(0), // Offset to the origin in the bitmap
  83. mXBearing(0), // Distance from baseline to left in pixels
  84. mYBearing(0), // Distance from baseline to top in pixels
  85. mBitmapNum(0) // Which bitmap in the bitmap cache contains this glyph
  86. {
  87. }
  88. LLFontFreetype::LLFontFreetype()
  89. : mFontBitmapCachep(new LLFontBitmapCache),
  90. mValid(FALSE),
  91. mAscender(0.f),
  92. mDescender(0.f),
  93. mLineHeight(0.f),
  94. mIsFallback(FALSE),
  95. mFTFace(NULL),
  96. mRenderGlyphCount(0),
  97. mAddGlyphCount(0),
  98. mStyle(0),
  99. mPointSize(0)
  100. {
  101. }
  102. LLFontFreetype::~LLFontFreetype()
  103. {
  104. // Clean up freetype libs.
  105. if (mFTFace)
  106. FT_Done_Face(mFTFace);
  107. mFTFace = NULL;
  108. // Delete glyph info
  109. std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer());
  110. // mFontBitmapCachep will be cleaned up by LLPointer destructor.
  111. // mFallbackFonts cleaned up by LLPointer destructor
  112. }
  113. BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback)
  114. {
  115. // Don't leak face objects. This is also needed to deal with
  116. // changed font file names.
  117. if (mFTFace)
  118. {
  119. FT_Done_Face(mFTFace);
  120. mFTFace = NULL;
  121. }
  122. int error;
  123. error = FT_New_Face( gFTLibrary,
  124. filename.c_str(),
  125. 0,
  126. &mFTFace );
  127. if (error)
  128. {
  129. return FALSE;
  130. }
  131. mIsFallback = is_fallback;
  132. F32 pixels_per_em = (point_size / 72.f)*vert_dpi; // Size in inches * dpi
  133. error = FT_Set_Char_Size(mFTFace, /* handle to face object */
  134. 0, /* char_width in 1/64th of points */
  135. (S32)(point_size*64), /* char_height in 1/64th of points */
  136. (U32)horz_dpi, /* horizontal device resolution */
  137. (U32)vert_dpi); /* vertical device resolution */
  138. if (error)
  139. {
  140. // Clean up freetype libs.
  141. FT_Done_Face(mFTFace);
  142. mFTFace = NULL;
  143. return FALSE;
  144. }
  145. F32 y_max, y_min, x_max, x_min;
  146. F32 ems_per_unit = 1.f/ mFTFace->units_per_EM;
  147. F32 pixels_per_unit = pixels_per_em * ems_per_unit;
  148. // Get size of bbox in pixels
  149. y_max = mFTFace->bbox.yMax * pixels_per_unit;
  150. y_min = mFTFace->bbox.yMin * pixels_per_unit;
  151. x_max = mFTFace->bbox.xMax * pixels_per_unit;
  152. x_min = mFTFace->bbox.xMin * pixels_per_unit;
  153. mAscender = mFTFace->ascender * pixels_per_unit;
  154. mDescender = -mFTFace->descender * pixels_per_unit;
  155. mLineHeight = mFTFace->height * pixels_per_unit;
  156. S32 max_char_width = llround(0.5f + (x_max - x_min));
  157. S32 max_char_height = llround(0.5f + (y_max - y_min));
  158. mFontBitmapCachep->init(components, max_char_width, max_char_height);
  159. if (!mFTFace->charmap)
  160. {
  161. //llinfos << " no unicode encoding, set whatever encoding there is..." << llendl;
  162. FT_Set_Charmap(mFTFace, mFTFace->charmaps[0]);
  163. }
  164. if (!mIsFallback)
  165. {
  166. // Add the default glyph
  167. addGlyphFromFont(this, 0, 0);
  168. }
  169. mName = filename;
  170. mPointSize = point_size;
  171. mStyle = LLFontGL::NORMAL;
  172. if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD)
  173. {
  174. mStyle |= LLFontGL::BOLD;
  175. mStyle &= ~LLFontGL::NORMAL;
  176. }
  177. if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC)
  178. {
  179. mStyle |= LLFontGL::ITALIC;
  180. mStyle &= ~LLFontGL::NORMAL;
  181. }
  182. return TRUE;
  183. }
  184. void LLFontFreetype::setFallbackFonts(const font_vector_t &font)
  185. {
  186. mFallbackFonts = font;
  187. }
  188. const LLFontFreetype::font_vector_t &LLFontFreetype::getFallbackFonts() const
  189. {
  190. return mFallbackFonts;
  191. }
  192. F32 LLFontFreetype::getLineHeight() const
  193. {
  194. return mLineHeight;
  195. }
  196. F32 LLFontFreetype::getAscenderHeight() const
  197. {
  198. return mAscender;
  199. }
  200. F32 LLFontFreetype::getDescenderHeight() const
  201. {
  202. return mDescender;
  203. }
  204. F32 LLFontFreetype::getXAdvance(llwchar wch) const
  205. {
  206. if (mFTFace == NULL)
  207. return 0.0;
  208. // Return existing info only if it is current
  209. LLFontGlyphInfo* gi = getGlyphInfo(wch);
  210. if (gi)
  211. {
  212. return gi->mXAdvance;
  213. }
  214. else
  215. {
  216. char_glyph_info_map_t::iterator found_it = mCharGlyphInfoMap.find((llwchar)0);
  217. if (found_it != mCharGlyphInfoMap.end())
  218. {
  219. return found_it->second->mXAdvance;
  220. }
  221. }
  222. // Last ditch fallback - no glyphs defined at all.
  223. return (F32)mFontBitmapCachep->getMaxCharWidth();
  224. }
  225. F32 LLFontFreetype::getXAdvance(const LLFontGlyphInfo* glyph) const
  226. {
  227. if (mFTFace == NULL)
  228. return 0.0;
  229. return glyph->mXAdvance;
  230. }
  231. F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const
  232. {
  233. if (mFTFace == NULL)
  234. return 0.0;
  235. //llassert(!mIsFallback);
  236. LLFontGlyphInfo* left_glyph_info = getGlyphInfo(char_left);;
  237. U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
  238. // Kern this puppy.
  239. LLFontGlyphInfo* right_glyph_info = getGlyphInfo(char_right);
  240. U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
  241. FT_Vector delta;
  242. llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta));
  243. return delta.x*(1.f/64.f);
  244. }
  245. F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const
  246. {
  247. if (mFTFace == NULL)
  248. return 0.0;
  249. U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
  250. U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
  251. FT_Vector delta;
  252. llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta));
  253. return delta.x*(1.f/64.f);
  254. }
  255. BOOL LLFontFreetype::hasGlyph(llwchar wch) const
  256. {
  257. llassert(!mIsFallback);
  258. return(mCharGlyphInfoMap.find(wch) != mCharGlyphInfoMap.end());
  259. }
  260. LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch) const
  261. {
  262. if (mFTFace == NULL)
  263. return FALSE;
  264. llassert(!mIsFallback);
  265. //lldebugs << "Adding new glyph for " << wch << " to font" << llendl;
  266. FT_UInt glyph_index;
  267. // Initialize char to glyph map
  268. glyph_index = FT_Get_Char_Index(mFTFace, wch);
  269. if (glyph_index == 0)
  270. {
  271. //llinfos << "Trying to add glyph from fallback font!" << llendl;
  272. font_vector_t::const_iterator iter;
  273. for(iter = mFallbackFonts.begin(); iter != mFallbackFonts.end(); iter++)
  274. {
  275. glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
  276. if (glyph_index)
  277. {
  278. return addGlyphFromFont(*iter, wch, glyph_index);
  279. }
  280. }
  281. }
  282. char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
  283. if (iter == mCharGlyphInfoMap.end())
  284. {
  285. return addGlyphFromFont(this, wch, glyph_index);
  286. }
  287. return NULL;
  288. }
  289. LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const
  290. {
  291. if (mFTFace == NULL)
  292. return NULL;
  293. llassert(!mIsFallback);
  294. fontp->renderGlyph(glyph_index);
  295. S32 width = fontp->mFTFace->glyph->bitmap.width;
  296. S32 height = fontp->mFTFace->glyph->bitmap.rows;
  297. S32 pos_x, pos_y;
  298. S32 bitmap_num;
  299. mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_num);
  300. mAddGlyphCount++;
  301. LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index);
  302. gi->mXBitmapOffset = pos_x;
  303. gi->mYBitmapOffset = pos_y;
  304. gi->mBitmapNum = bitmap_num;
  305. gi->mWidth = width;
  306. gi->mHeight = height;
  307. gi->mXBearing = fontp->mFTFace->glyph->bitmap_left;
  308. gi->mYBearing = fontp->mFTFace->glyph->bitmap_top;
  309. // Convert these from 26.6 units to float pixels.
  310. gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
  311. gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
  312. insertGlyphInfo(wch, gi);
  313. llassert(fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO
  314. || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
  315. if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO
  316. || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
  317. {
  318. U8 *buffer_data = fontp->mFTFace->glyph->bitmap.buffer;
  319. S32 buffer_row_stride = fontp->mFTFace->glyph->bitmap.pitch;
  320. U8 *tmp_graydata = NULL;
  321. if (fontp->mFTFace->glyph->bitmap.pixel_mode
  322. == FT_PIXEL_MODE_MONO)
  323. {
  324. // need to expand 1-bit bitmap to 8-bit graymap.
  325. tmp_graydata = new U8[width * height];
  326. S32 xpos, ypos;
  327. for (ypos = 0; ypos < height; ++ypos)
  328. {
  329. S32 bm_row_offset = buffer_row_stride * ypos;
  330. for (xpos = 0; xpos < width; ++xpos)
  331. {
  332. U32 bm_col_offsetbyte = xpos / 8;
  333. U32 bm_col_offsetbit = 7 - (xpos % 8);
  334. U32 bit =
  335. !!(buffer_data[bm_row_offset
  336. + bm_col_offsetbyte
  337. ] & (1 << bm_col_offsetbit) );
  338. tmp_graydata[width*ypos + xpos] =
  339. 255 * bit;
  340. }
  341. }
  342. // use newly-built graymap.
  343. buffer_data = tmp_graydata;
  344. buffer_row_stride = width;
  345. }
  346. switch (mFontBitmapCachep->getNumComponents())
  347. {
  348. case 1:
  349. mFontBitmapCachep->getImageRaw(bitmap_num)->setSubImage(pos_x,
  350. pos_y,
  351. width,
  352. height,
  353. buffer_data,
  354. buffer_row_stride,
  355. TRUE);
  356. break;
  357. case 2:
  358. setSubImageLuminanceAlpha(pos_x,
  359. pos_y,
  360. bitmap_num,
  361. width,
  362. height,
  363. buffer_data,
  364. buffer_row_stride);
  365. break;
  366. default:
  367. break;
  368. }
  369. if (tmp_graydata)
  370. delete[] tmp_graydata;
  371. } else {
  372. // we don't know how to handle this pixel format from FreeType;
  373. // omit it from the font-image.
  374. }
  375. LLImageGL *image_gl = mFontBitmapCachep->getImageGL(bitmap_num);
  376. LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);
  377. image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight());
  378. return gi;
  379. }
  380. LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(llwchar wch) const
  381. {
  382. char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
  383. if (iter != mCharGlyphInfoMap.end())
  384. {
  385. return iter->second;
  386. }
  387. else
  388. {
  389. // this glyph doesn't yet exist, so render it and return the result
  390. return addGlyph(wch);
  391. }
  392. }
  393. void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
  394. {
  395. char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
  396. if (iter != mCharGlyphInfoMap.end())
  397. {
  398. delete iter->second;
  399. iter->second = gi;
  400. }
  401. else
  402. {
  403. mCharGlyphInfoMap[wch] = gi;
  404. }
  405. }
  406. void LLFontFreetype::renderGlyph(U32 glyph_index) const
  407. {
  408. if (mFTFace == NULL)
  409. return;
  410. int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_FORCE_AUTOHINT );
  411. llassert(!error);
  412. error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode);
  413. mRenderGlyphCount++;
  414. llassert(!error);
  415. }
  416. void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi)
  417. {
  418. resetBitmapCache();
  419. loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mFontBitmapCachep->getNumComponents(), mIsFallback);
  420. if (!mIsFallback)
  421. {
  422. // This is the head of the list - need to rebuild ourself and all fallbacks.
  423. if (mFallbackFonts.empty())
  424. {
  425. llwarns << "LLFontGL::reset(), no fallback fonts present" << llendl;
  426. }
  427. else
  428. {
  429. for(font_vector_t::iterator it = mFallbackFonts.begin();
  430. it != mFallbackFonts.end();
  431. ++it)
  432. {
  433. (*it)->reset(vert_dpi, horz_dpi);
  434. }
  435. }
  436. }
  437. }
  438. void LLFontFreetype::resetBitmapCache()
  439. {
  440. for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer());
  441. mCharGlyphInfoMap.clear();
  442. mFontBitmapCachep->reset();
  443. // Adding default glyph is skipped for fallback fonts here as well as in loadFace().
  444. // This if was added as fix for EXT-4971.
  445. if(!mIsFallback)
  446. {
  447. // Add the empty glyph
  448. addGlyphFromFont(this, 0, 0);
  449. }
  450. }
  451. void LLFontFreetype::destroyGL()
  452. {
  453. mFontBitmapCachep->destroyGL();
  454. }
  455. const std::string &LLFontFreetype::getName() const
  456. {
  457. return mName;
  458. }
  459. const LLPointer<LLFontBitmapCache> LLFontFreetype::getFontBitmapCache() const
  460. {
  461. return mFontBitmapCachep;
  462. }
  463. void LLFontFreetype::setStyle(U8 style)
  464. {
  465. mStyle = style;
  466. }
  467. U8 LLFontFreetype::getStyle() const
  468. {
  469. return mStyle;
  470. }
  471. void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride) const
  472. {
  473. LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);
  474. llassert(!mIsFallback);
  475. llassert(image_raw && (image_raw->getComponents() == 2));
  476. U8 *target = image_raw->getData();
  477. if (!data)
  478. {
  479. return;
  480. }
  481. if (0 == stride)
  482. stride = width;
  483. U32 i, j;
  484. U32 to_offset;
  485. U32 from_offset;
  486. U32 target_width = image_raw->getWidth();
  487. for (i = 0; i < height; i++)
  488. {
  489. to_offset = (y + i)*target_width + x;
  490. from_offset = (height - 1 - i)*stride;
  491. for (j = 0; j < width; j++)
  492. {
  493. *(target + to_offset*2 + 1) = *(data + from_offset);
  494. to_offset++;
  495. from_offset++;
  496. }
  497. }
  498. }