llfontfreetype.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957
  1. /**
  2. * @file llfontfreetype.cpp
  3. * @brief Font library wrapper
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewergpl$
  6. *
  7. * Copyright (c) 2010, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "linden_common.h"
  33. // Import NanoSVG header-only implementation
  34. #if LL_WINDOWS
  35. # pragma warning (push)
  36. # pragma warning (disable : 4702)
  37. #endif
  38. #define NANOSVG_IMPLEMENTATION
  39. #include "nanosvg/nanosvg.h"
  40. #define NANOSVGRAST_IMPLEMENTATION
  41. #include "nanosvg/nanosvgrast.h"
  42. #if LL_WINDOWS
  43. # pragma warning (pop)
  44. #endif
  45. // Freetype stuff
  46. #include "ft2build.h"
  47. #include "freetype/fttypes.h"
  48. #include "freetype/ftmodapi.h"
  49. #include "freetype/otsvg.h"
  50. #include "llfontfreetype.h"
  51. #include "llfontgl.h"
  52. #include "llfontbitmapcache.h"
  53. #include "llgl.h"
  54. #include "llimage.h"
  55. #include "llmath.h"
  56. #include "llstl.h" // For DeletePairedPointer()
  57. #include "llstring.h"
  58. FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL;
  59. LLFontManager* gFontManagerp = NULL;
  60. FT_Library gFTLibrary = NULL;
  61. ///////////////////////////////////////////////////////////////////////////////
  62. // Static callbacks for SVG rendering with Freetype via NanoSVG. This is
  63. // implemented in a purely static LLFontFreeTypeSvgRenderer class in LL's
  64. // sources (llfontfreetypesvg.cpp/h files), but it is only used in this
  65. // llfontfreetype.cpp file, so let's keep things simple and just use static
  66. // functions in here instead. HB
  67. // See: https://freetype.org/freetype2/docs/reference/ft2-svg_fonts.html
  68. ///////////////////////////////////////////////////////////////////////////////
  69. // Note: about mError, FreeType currently (2.12.1) ignores the error value
  70. // returned by the preset glyph slot callback so we return it at render time.
  71. // See: https://github.com/freetype/freetype/blob/5faa1df8b93ebecf0f8fd5fe8fda7b9082eddced/src/base/ftobjs.c#L1170
  72. struct LLSvgRenderData
  73. {
  74. NSVGimage* mNSvgImage = NULL;
  75. FT_UInt mGlyphIndex = 0;
  76. F32 mScale = 0.f;
  77. FT_Error mError = FT_Err_Ok;
  78. };
  79. static FT_Error svg_on_init(FT_Pointer* statep)
  80. {
  81. // The SVG driver hook state is shared across all callback invocations;
  82. // since our state is lightweight we store it in the glyph instead.
  83. *statep = NULL;
  84. return FT_Err_Ok;
  85. }
  86. static void svg_on_free(FT_Pointer*)
  87. {
  88. }
  89. static void svg_on_data_finalize(void* objectp)
  90. {
  91. FT_GlyphSlot slotp = (FT_GlyphSlot)objectp;
  92. LLSvgRenderData* datap = (LLSvgRenderData*)slotp->generic.data;
  93. slotp->generic.data = NULL;
  94. slotp->generic.finalizer = NULL;
  95. delete datap;
  96. }
  97. static FT_Error svg_on_preset_glypth_slot(FT_GlyphSlot slotp,
  98. FT_Bool cache, FT_Pointer*)
  99. {
  100. FT_SVG_Document docp = (FT_SVG_Document)slotp->other;
  101. if (!slotp->generic.data)
  102. {
  103. slotp->generic.data = new LLSvgRenderData();
  104. slotp->generic.finalizer = svg_on_data_finalize;
  105. }
  106. LLSvgRenderData* datap = (LLSvgRenderData*)slotp->generic.data;
  107. if (!cache)
  108. {
  109. datap->mGlyphIndex = slotp->glyph_index;
  110. datap->mError = FT_Err_Ok;
  111. }
  112. if (!datap->mNSvgImage)
  113. {
  114. // Note: nsvgParse modifies the input string so we need a temporary
  115. // copy.
  116. size_t doc_len = docp->svg_document_length;
  117. char* bufferp = new char[doc_len + 1];
  118. memcpy((void*)bufferp, (const void*)docp->svg_document, doc_len);
  119. bufferp[doc_len] = '\0';
  120. datap->mNSvgImage = nsvgParse(bufferp, "px", 0.0);
  121. delete[] bufferp;
  122. }
  123. if (!datap->mNSvgImage)
  124. {
  125. datap->mError = FT_Err_Invalid_SVG_Document;
  126. return FT_Err_Invalid_SVG_Document;
  127. }
  128. // We do not currently support transformations so test for an identity
  129. // rotation matrix + zero translation.
  130. if (docp->transform.xx != (1 << 16) || docp->transform.yx != 0 ||
  131. docp->transform.xy != 0 || docp->transform.yy != (1 << 16) ||
  132. docp->delta.x > 0 || docp->delta.y > 0)
  133. {
  134. datap->mError = FT_Err_Unimplemented_Feature;
  135. return FT_Err_Unimplemented_Feature;
  136. }
  137. F32 svg_width = datap->mNSvgImage->width;
  138. F32 svg_height = datap->mNSvgImage->height;
  139. if (svg_width <= 0.f || svg_height <= 0.f)
  140. {
  141. svg_width = docp->units_per_EM;
  142. svg_height = docp->units_per_EM;
  143. }
  144. F32 svg_x_scale = (F32)docp->metrics.x_ppem / floorf(svg_width);
  145. F32 svg_y_scale = (F32)docp->metrics.y_ppem / floorf(svg_height);
  146. F32 svg_scale = llmin(svg_x_scale, svg_y_scale);
  147. datap->mScale = svg_scale;
  148. slotp->bitmap.width = floorf(svg_width) * svg_scale;
  149. slotp->bitmap.rows = floorf(svg_height) * svg_scale;
  150. slotp->bitmap_left = (docp->metrics.x_ppem - slotp->bitmap.width) / 2;
  151. slotp->bitmap_top = slotp->face->size->metrics.ascender / 64.f;
  152. slotp->bitmap.pitch = slotp->bitmap.width * 4;
  153. slotp->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
  154. // Copied as-is from fcft (MIT license)
  155. // Compute all the bearings and set them correctly. The outline is scaled
  156. // already, we just need to use the bounding box.
  157. F32 h_bearing_x = 0;
  158. F32 h_bearing_y = -slotp->bitmap_top;
  159. F32 v_bearing_x = slotp->metrics.horiBearingX / 64.f -
  160. slotp->metrics.horiAdvance / 128.f;
  161. F32 v_bearing_y = (slotp->metrics.vertAdvance / 64.f -
  162. slotp->metrics.height / 64.f) * 0.5f;
  163. // Do conversion in two steps to avoid 'bad function cast' warning
  164. slotp->metrics.width = slotp->bitmap.width * 64.f;
  165. slotp->metrics.height = slotp->bitmap.rows * 64.f;
  166. slotp->metrics.horiBearingX = h_bearing_x * 64.f;
  167. slotp->metrics.horiBearingY = h_bearing_y * 64.f;
  168. slotp->metrics.vertBearingX = v_bearing_x * 64.f;
  169. slotp->metrics.vertBearingY = v_bearing_y * 64.f;
  170. if (slotp->metrics.vertAdvance == 0)
  171. {
  172. slotp->metrics.vertAdvance = slotp->bitmap.rows * (1.2f * 64.f);
  173. }
  174. return FT_Err_Ok;
  175. }
  176. static FT_Error svg_on_render(FT_GlyphSlot slotp, FT_Pointer*)
  177. {
  178. LLSvgRenderData* datap = (LLSvgRenderData*)slotp->generic.data;
  179. if (datap->mError != FT_Err_Ok)
  180. {
  181. return datap->mError;
  182. }
  183. // Render to glyph bitmap
  184. NSVGrasterizer* rasterizerp = nsvgCreateRasterizer();
  185. nsvgRasterize(rasterizerp, datap->mNSvgImage, 0, 0, datap->mScale,
  186. slotp->bitmap.buffer, slotp->bitmap.width,
  187. slotp->bitmap.rows, slotp->bitmap.pitch);
  188. nsvgDeleteRasterizer(rasterizerp);
  189. nsvgDelete(datap->mNSvgImage);
  190. datap->mNSvgImage = NULL;
  191. // Convert from RGBA to BGRA
  192. U32* pixbuffp = (U32*)slotp->bitmap.buffer;
  193. U8* bytebuffp = slotp->bitmap.buffer;
  194. for (size_t y = 0, h = slotp->bitmap.rows; y < h; ++y)
  195. {
  196. for (size_t x = 0, w = slotp->bitmap.pitch / 4; x < w; ++x)
  197. {
  198. size_t p_idx = y * w + x;
  199. size_t b_idx = p_idx * 4;
  200. U8 alpha = bytebuffp[b_idx + 3];
  201. // Store as ARGB.
  202. // *TODO: do we still have to care about endianness ?
  203. pixbuffp[y * w + x] = alpha << 24 |
  204. (bytebuffp[b_idx] * alpha / 255) << 16 |
  205. (bytebuffp[b_idx + 1] * alpha / 255) << 8 |
  206. (bytebuffp[b_idx + 2] * alpha / 255);
  207. }
  208. }
  209. slotp->format = FT_GLYPH_FORMAT_BITMAP;
  210. slotp->bitmap.pixel_mode = FT_PIXEL_MODE_BGRA;
  211. return FT_Err_Ok;
  212. }
  213. ///////////////////////////////////////////////////////////////////////////////
  214. // LLFontManager class
  215. ///////////////////////////////////////////////////////////////////////////////
  216. //static
  217. void LLFontManager::initClass()
  218. {
  219. if (!gFontManagerp)
  220. {
  221. gFontManagerp = new LLFontManager;
  222. }
  223. }
  224. //static
  225. void LLFontManager::cleanupClass()
  226. {
  227. delete gFontManagerp;
  228. gFontManagerp = NULL;
  229. }
  230. LLFontManager::LLFontManager()
  231. {
  232. int error = FT_Init_FreeType(&gFTLibrary);
  233. if (error)
  234. {
  235. llerrs << "Freetype initialization failure !" << llendl;
  236. }
  237. SVG_RendererHooks hooks =
  238. {
  239. svg_on_init,
  240. svg_on_free,
  241. svg_on_render,
  242. svg_on_preset_glypth_slot
  243. };
  244. FT_Property_Set(gFTLibrary, "ot-svg", "svg-hooks", &hooks);
  245. }
  246. LLFontManager::~LLFontManager()
  247. {
  248. FT_Done_FreeType(gFTLibrary);
  249. }
  250. ///////////////////////////////////////////////////////////////////////////////
  251. // LLFontFreetype class
  252. ///////////////////////////////////////////////////////////////////////////////
  253. LLFontFreetype::LLFontFreetype()
  254. : mFontBitmapCachep(new LLFontBitmapCache),
  255. mIsFallback(false),
  256. mAscender(0.f),
  257. mDescender(0.f),
  258. mLineHeight(0.f),
  259. mFTFace(NULL),
  260. mRenderGlyphCount(0),
  261. mAddGlyphCount(0),
  262. mStyle(0),
  263. mPointSize(0)
  264. {
  265. }
  266. LLFontFreetype::~LLFontFreetype()
  267. {
  268. // Clean up freetype libs.
  269. if (mFTFace)
  270. {
  271. FT_Done_Face(mFTFace);
  272. mFTFace = NULL;
  273. }
  274. // Delete glyph info
  275. std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(),
  276. DeletePairedPointer());
  277. mCharGlyphInfoMap.clear();
  278. // mFontBitmapCachep will be cleaned up by LLPointer destructor.
  279. // mFallbackFonts cleaned up by LLPointer destructor
  280. }
  281. bool LLFontFreetype::loadFace(const std::string& filename, F32 point_size,
  282. F32 vert_dpi, F32 horz_dpi, bool is_fallback)
  283. {
  284. // Do not leak face objects. This is also needed to deal with changed font
  285. // file names.
  286. if (mFTFace)
  287. {
  288. FT_Done_Face(mFTFace);
  289. mFTFace = NULL;
  290. }
  291. int error = FT_New_Face(gFTLibrary, filename.c_str(), 0, &mFTFace);
  292. if (error)
  293. {
  294. return false;
  295. }
  296. error = FT_Select_Charmap(mFTFace, FT_ENCODING_UNICODE);
  297. if (error)
  298. {
  299. // Note: failures *will* happen (and are harmless) for Windows TTF
  300. // fonts. So, do not spam the log with them... HB
  301. LL_DEBUGS("Freetype") << "Failure to select Unicode char map for font: "
  302. << filename << LL_ENDL;
  303. }
  304. mIsFallback = is_fallback;
  305. // Please, keep the following calculation in this order; while it would be
  306. // better to use "point_size * vert_dpi / 72.0f" to lower math rounding
  307. // errors, the latter gives a different result than what viewers are used
  308. // to give and would mean having to change font vertical justification in
  309. // the UI code and/or XML menu definitions...
  310. F32 pixels_per_em = (point_size / 72.f) * vert_dpi; // Size in inches * dpi
  311. error = FT_Set_Char_Size(mFTFace, // handle to face object
  312. 0, // char_width in 1/64th of pt
  313. (S32)(point_size * 64.f), // char_height in 1/64th of pt
  314. (U32)horz_dpi, // horizontal device res
  315. (U32)vert_dpi); // vertical device res
  316. if (error)
  317. {
  318. LL_DEBUGS("Freetype") << "Failure to set characters size for font: "
  319. << filename << LL_ENDL;
  320. // Clean up freetype libs.
  321. FT_Done_Face(mFTFace);
  322. mFTFace = NULL;
  323. return false;
  324. }
  325. F32 y_max, y_min, x_max, x_min;
  326. F32 ems_per_unit = 1.f / mFTFace->units_per_EM;
  327. F32 pixels_per_unit = pixels_per_em * ems_per_unit;
  328. // Get size of bbox in pixels
  329. y_max = mFTFace->bbox.yMax * pixels_per_unit;
  330. y_min = mFTFace->bbox.yMin * pixels_per_unit;
  331. x_max = mFTFace->bbox.xMax * pixels_per_unit;
  332. x_min = mFTFace->bbox.xMin * pixels_per_unit;
  333. mAscender = mFTFace->ascender * pixels_per_unit;
  334. mDescender = -mFTFace->descender * pixels_per_unit;
  335. mLineHeight = mFTFace->height * pixels_per_unit;
  336. S32 max_char_width = ll_roundp(0.5f + x_max - x_min);
  337. S32 max_char_height = ll_roundp(0.5f + y_max - y_min);
  338. mFontBitmapCachep->init(max_char_width, max_char_height);
  339. if (!mFTFace->charmap)
  340. {
  341. FT_Set_Charmap(mFTFace, mFTFace->charmaps[0]);
  342. }
  343. if (!mIsFallback)
  344. {
  345. // Add the default glyph
  346. addGlyphFromFont(this, 0, 0);
  347. }
  348. mName = filename;
  349. mPointSize = point_size;
  350. mStyle = LLFontGL::NORMAL;
  351. if (mFTFace->style_flags & FT_STYLE_FLAG_BOLD)
  352. {
  353. mStyle |= LLFontGL::BOLD;
  354. }
  355. if (mFTFace->style_flags & FT_STYLE_FLAG_ITALIC)
  356. {
  357. mStyle |= LLFontGL::ITALIC;
  358. }
  359. return true;
  360. }
  361. void LLFontFreetype::addFallbackFont(const LLPointer<LLFontFreetype>& fallback_font,
  362. const char_functor_t& functor)
  363. {
  364. mFallbackFonts.emplace_back(fallback_font, functor);
  365. }
  366. F32 LLFontFreetype::getXAdvance(llwchar wch) const
  367. {
  368. if (!mFTFace)
  369. {
  370. return 0.f;
  371. }
  372. // Return existing info only if it is current
  373. LLFontGlyphInfo* gi = getGlyphInfo(wch);
  374. if (gi)
  375. {
  376. return gi->mXAdvance;
  377. }
  378. glyph_info_map_t::iterator it = mCharGlyphInfoMap.find((llwchar)0);
  379. if (it != mCharGlyphInfoMap.end())
  380. {
  381. return it->second->mXAdvance;
  382. }
  383. // Last ditch fallback - no glyphs defined at all.
  384. return (F32)mFontBitmapCachep->getMaxCharWidth();
  385. }
  386. F32 LLFontFreetype::getXKerning(const LLFontGlyphInfo* left_glyph_info,
  387. const LLFontGlyphInfo* right_glyph_info) const
  388. {
  389. if (!mFTFace)
  390. {
  391. return 0.f;
  392. }
  393. U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
  394. U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
  395. U64 kerning_key = right_glyph;
  396. kerning_key |= U64(left_glyph) << 32;
  397. kerning_cache_map_t::iterator it = mKerningCache.find(kerning_key);
  398. if (it != mKerningCache.end())
  399. {
  400. return it->second;
  401. }
  402. FT_Vector delta;
  403. delta.x = delta.y = 0;
  404. if (FT_HAS_KERNING(mFTFace))
  405. {
  406. FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted,
  407. &delta);
  408. }
  409. constexpr F32 k = 1.f / 64.f;
  410. F32 ret = delta.x * k;
  411. mKerningCache[kerning_key] = ret;
  412. return ret;
  413. }
  414. bool LLFontFreetype::hasGlyph(const llwchar wch) const
  415. {
  416. return !mIsFallback && mCharGlyphInfoMap.count(wch) != 0;
  417. }
  418. LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch, U32 glyph_type) const
  419. {
  420. if (!mFTFace || mIsFallback)
  421. {
  422. return NULL;
  423. }
  424. // Initialize char to glyph map
  425. FT_UInt glyph_index = FT_Get_Char_Index(mFTFace, wch);
  426. if (glyph_index)
  427. {
  428. LL_DEBUGS("Freetype") << "Glyph index for 0x" << std::hex << (U32)wch
  429. << std::dec << " in " << mName << ": "
  430. << glyph_index << LL_ENDL;
  431. }
  432. else
  433. {
  434. LL_DEBUGS("Freetype") << "No glyph found for 0x" << std::hex
  435. << (U32)wch << std::dec << " in " << mName
  436. << ". Searching in fallback fonts..." << LL_ENDL;
  437. // No corresponding glyph in this font: look for a glyph in fallback
  438. // fonts.
  439. size_t count = mFallbackFonts.size();
  440. if (LLStringOps::isEmoji(wch))
  441. {
  442. // This is a "genuine" emoji (in the range 0x1f000-0x20000): print
  443. // it using the emoji font(s) if possible. HB
  444. for (size_t i = 0; i < count; ++i)
  445. {
  446. const font_t& pair = mFallbackFonts[i];
  447. if (!pair.second || !pair.second(wch))
  448. {
  449. // If this font does not have a functor, or the character
  450. // does not pass the functor, reject it. Note: we keep the
  451. // functor test (despite the fact we already tested for
  452. // LLStringOps::isEmoji(wch) above), in case we would use
  453. // different, more restrictive or partitionned functors in
  454. // the future with several different emoji fonts. HB
  455. continue;
  456. }
  457. glyph_index = FT_Get_Char_Index(pair.first->mFTFace, wch);
  458. if (glyph_index)
  459. {
  460. LL_DEBUGS("Freetype") << "Glyph index for 0x" << std::hex
  461. << (U32)wch << std::dec
  462. << " in " << pair.first->mName
  463. << ": " << glyph_index << LL_ENDL;
  464. return addGlyphFromFont(pair.first, wch, glyph_index,
  465. glyph_type);
  466. }
  467. }
  468. }
  469. // Then try and find a monochrome fallback font that could print this
  470. // glyph: such fonts do *not* have a functor. We give priority to
  471. // monochrome fonts for non-genuine emojis so that UI elements which
  472. // used to render with them before the emojis font introduction (e.g.
  473. // check marks in menus, or LSL dialogs text and buttons) do render the
  474. // same way as they always did. HB
  475. std::vector<size_t> emoji_fonts_idx;
  476. for (size_t i = 0; i < count; ++i)
  477. {
  478. const font_t& pair = mFallbackFonts[i];
  479. if (pair.second)
  480. {
  481. // If this font got a functor, remember the index for later and
  482. // try the next fallback font. HB
  483. emoji_fonts_idx.push_back(i);
  484. continue;
  485. }
  486. glyph_index = FT_Get_Char_Index(pair.first->mFTFace, wch);
  487. if (glyph_index)
  488. {
  489. LL_DEBUGS("Freetype") << "Glyph index for 0x" << std::hex
  490. << (U32)wch << std::dec
  491. << " in " << pair.first->mName << ": "
  492. << glyph_index << LL_ENDL;
  493. return addGlyphFromFont(pair.first, wch, glyph_index,
  494. glyph_type);
  495. }
  496. }
  497. // Everything failed so far: this character is not a genuine emoji,
  498. // neither a special character known from our monochrome fallback
  499. // fonts: make a last try, using the emoji font(s), but ignoring the
  500. // functor to render using whatever (colorful) glyph that might be
  501. // available in such fonts for this character. HB
  502. for (size_t j = 0, count2 = emoji_fonts_idx.size(); j < count2; ++j)
  503. {
  504. const font_t& pair = mFallbackFonts[emoji_fonts_idx[j]];
  505. glyph_index = FT_Get_Char_Index(pair.first->mFTFace, wch);
  506. if (glyph_index)
  507. {
  508. LL_DEBUGS("Freetype") << "Glyph index for 0x" << std::hex
  509. << (U32)wch << std::dec
  510. << " in " << pair.first->mName << ": "
  511. << glyph_index << LL_ENDL;
  512. return addGlyphFromFont(pair.first, wch, glyph_index,
  513. glyph_type);
  514. }
  515. }
  516. #if 0 // For some reason, this causes crashes, excepted under Linux x86_64:
  517. // Something to do with jemalloc usage that would prevent the
  518. // crash ?... HB
  519. // No corresponding glyph to be found anywhere: replace it with the
  520. // UTF-8 "replacement character". HB
  521. constexpr llwchar rch = (llwchar)0x0fffdUL;
  522. for (size_t i = 0; i < count; ++i)
  523. {
  524. const font_t& pair = mFallbackFonts[i];
  525. if (pair.second)
  526. {
  527. continue; // Do not bother with emoji fonts. HB
  528. }
  529. glyph_index = FT_Get_Char_Index(pair.first->mFTFace, rch);
  530. if (glyph_index)
  531. {
  532. LL_DEBUGS("Freetype") << "Replacement character found in "
  533. << pair.first->mName << " at index: "
  534. << glyph_index << LL_ENDL;
  535. return addGlyphFromFont(pair.first, wch, glyph_index,
  536. glyph_type);
  537. }
  538. }
  539. #endif
  540. // Ultimate fallback: use a question mark if none of our fallback
  541. // fonts got a glyph for the UTF-8 "replacement character". HB
  542. glyph_index = FT_Get_Char_Index(mFTFace, (FT_ULong)'?');
  543. }
  544. auto range_it = mCharGlyphInfoMap.equal_range(wch);
  545. glyph_info_map_t::iterator it =
  546. std::find_if(range_it.first, range_it.second,
  547. [&glyph_type](const glyph_info_map_t::value_type& entry)
  548. {
  549. return entry.second->mGlyphType == glyph_type;
  550. });
  551. if (it == range_it.second)
  552. {
  553. return addGlyphFromFont(this, wch, glyph_index, glyph_type);
  554. }
  555. return NULL;
  556. }
  557. LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype* fontp,
  558. llwchar wch,
  559. U32 glyph_index,
  560. U32 glyph_type) const
  561. {
  562. if (!mFTFace || mIsFallback)
  563. {
  564. return NULL;
  565. }
  566. fontp->renderGlyph(glyph_type, glyph_index);
  567. U32 b_type = EFontGlyphType::Unspecified;
  568. switch (fontp->mFTFace->glyph->bitmap.pixel_mode)
  569. {
  570. case FT_PIXEL_MODE_MONO:
  571. case FT_PIXEL_MODE_GRAY:
  572. b_type = EFontGlyphType::Grayscale;
  573. break;
  574. case FT_PIXEL_MODE_BGRA:
  575. b_type = EFontGlyphType::Color;
  576. break;
  577. default:
  578. llerrs << "Unknown glyph type: "
  579. << fontp->mFTFace->glyph->bitmap.pixel_mode << llendl;
  580. }
  581. S32 width = fontp->mFTFace->glyph->bitmap.width;
  582. S32 height = fontp->mFTFace->glyph->bitmap.rows;
  583. S32 pos_x, pos_y;
  584. U32 bitmap_num;
  585. mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, b_type, bitmap_num);
  586. ++mAddGlyphCount;
  587. // Convert these from 26.6 units to float pixels.
  588. constexpr F32 k = 1.f / 64.f;
  589. F32 x_advance = fontp->mFTFace->glyph->advance.x * k;
  590. F32 y_advance = fontp->mFTFace->glyph->advance.y * k;
  591. LLFontGlyphInfo* gip =
  592. new LLFontGlyphInfo(glyph_index, glyph_type, b_type, bitmap_num,
  593. pos_x, pos_y, width, height,
  594. fontp->mFTFace->glyph->bitmap_left,
  595. fontp->mFTFace->glyph->bitmap_top,
  596. x_advance, y_advance);
  597. insertGlyphInfo(wch, gip);
  598. if (glyph_type != b_type)
  599. {
  600. LLFontGlyphInfo* tempgip = new LLFontGlyphInfo(*gip);
  601. tempgip->mGlyphType = b_type;
  602. insertGlyphInfo(wch, tempgip);
  603. }
  604. if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO ||
  605. fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
  606. {
  607. U8* bufferp = fontp->mFTFace->glyph->bitmap.buffer;
  608. S32 buffer_row_stride = fontp->mFTFace->glyph->bitmap.pitch;
  609. U8* graydatap = NULL;
  610. if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO)
  611. {
  612. // Need to expand 1-bit bitmap to 8-bit graymap.
  613. graydatap = new U8[width * height];
  614. S32 xpos, ypos;
  615. for (ypos = 0; ypos < height; ++ypos)
  616. {
  617. S32 bm_row_offset = buffer_row_stride * ypos;
  618. for (xpos = 0; xpos < width; ++xpos)
  619. {
  620. U32 bm_col_offsetbyte = xpos / 8;
  621. U32 bm_col_offsetbit = 7 - (xpos % 8);
  622. U32 bit = !!(bufferp[bm_row_offset + bm_col_offsetbyte] &
  623. (1 << bm_col_offsetbit));
  624. graydatap[width * ypos + xpos] = 255 * bit;
  625. }
  626. }
  627. // Use newly-built graymap.
  628. bufferp = graydatap;
  629. buffer_row_stride = width;
  630. }
  631. setSubImageLuminanceAlpha(pos_x, pos_y, bitmap_num, width, height,
  632. bufferp, buffer_row_stride);
  633. if (graydatap)
  634. {
  635. delete[] graydatap;
  636. }
  637. }
  638. else if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
  639. {
  640. setSubImageBGRA(pos_x, pos_y, bitmap_num,
  641. fontp->mFTFace->glyph->bitmap.width,
  642. fontp->mFTFace->glyph->bitmap.rows,
  643. fontp->mFTFace->glyph->bitmap.buffer,
  644. abs(fontp->mFTFace->glyph->bitmap.pitch));
  645. }
  646. else
  647. {
  648. // We do not know how to handle this pixel format from Freetype; omit
  649. // it from the font-image.
  650. llwarns_once << "Unknown pixel format for font: "
  651. << fontp->mName << ". Will not render..." << llendl;
  652. }
  653. LLImageGL* glimagep = mFontBitmapCachep->getImageGL(b_type, bitmap_num);
  654. LLImageRaw* rawimagep = mFontBitmapCachep->getImageRaw(b_type, bitmap_num);
  655. if (glimagep && rawimagep)
  656. {
  657. glimagep->setSubImage(rawimagep, 0, 0, glimagep->getWidth(),
  658. glimagep->getHeight());
  659. }
  660. else
  661. {
  662. llwarns << "Failed to add glyph image for character: " << std::hex
  663. << (S32)wch << std::dec << " ! Out of memory ?" << llendl;
  664. }
  665. return gip;
  666. }
  667. LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(llwchar wch, U32 g_type) const
  668. {
  669. auto range_it = mCharGlyphInfoMap.equal_range(wch);
  670. glyph_info_map_t::iterator it;
  671. if (g_type == EFontGlyphType::Unspecified)
  672. {
  673. it = range_it.first;
  674. g_type = EFontGlyphType::Grayscale;
  675. }
  676. else
  677. {
  678. it = std::find_if(range_it.first, range_it.second,
  679. [&g_type](const glyph_info_map_t::value_type& entry)
  680. {
  681. return entry.second->mGlyphType == g_type;
  682. });
  683. }
  684. if (it != range_it.second)
  685. {
  686. return it->second;
  687. }
  688. // This glyph does not yet exist, so render it and return the result
  689. return addGlyph(wch, g_type);
  690. }
  691. void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gip) const
  692. {
  693. auto range_it = mCharGlyphInfoMap.equal_range(wch);
  694. glyph_info_map_t::iterator it =
  695. std::find_if(range_it.first, range_it.second,
  696. [&gip](const glyph_info_map_t::value_type& entry)
  697. {
  698. return entry.second->mGlyphType == gip->mGlyphType;
  699. });
  700. if (it != range_it.second)
  701. {
  702. delete it->second;
  703. it->second = gip;
  704. }
  705. else
  706. {
  707. mCharGlyphInfoMap.insert(std::make_pair(wch, gip));
  708. }
  709. }
  710. void LLFontFreetype::renderGlyph(U32 bitmap_type, U32 glyph_index) const
  711. {
  712. if (!mFTFace)
  713. {
  714. return;
  715. }
  716. #if 1 // Do *not* force auto-hinting. HB
  717. FT_Int32 load_flags = FT_LOAD_DEFAULT;
  718. #else
  719. FT_Int32 load_flags = FT_LOAD_FORCE_AUTOHINT;
  720. #endif
  721. if (bitmap_type == EFontGlyphType::Color)
  722. {
  723. // We may not actually get a color render so our caller should always
  724. // examine mFTFace->glyph->bitmap.pixel_mode
  725. load_flags |= FT_LOAD_COLOR;
  726. }
  727. FT_Error error = FT_Load_Glyph(mFTFace, glyph_index, load_flags);
  728. if (error)
  729. {
  730. LL_DEBUGS("Freetype") << "Error loading glyph, index: "
  731. << glyph_index << LL_ENDL;
  732. glyph_index = FT_Get_Char_Index(mFTFace, (FT_ULong)'?');
  733. FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT);
  734. }
  735. error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode);
  736. if (error)
  737. {
  738. LL_DEBUGS("Freetype") << "Error rendering glyph, index: "
  739. << glyph_index << LL_ENDL;
  740. llassert(false);
  741. }
  742. ++mRenderGlyphCount;
  743. }
  744. void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi)
  745. {
  746. resetBitmapCache();
  747. loadFace(mName, mPointSize, vert_dpi, horz_dpi, mIsFallback);
  748. if (mIsFallback)
  749. {
  750. return;
  751. }
  752. if (mFallbackFonts.empty())
  753. {
  754. llwarns << "No fallback fonts present" << llendl;
  755. return;
  756. }
  757. // This is the head of the list, we need to rebuild ourself and all
  758. // fallbacks.
  759. for (U32 i = 0, count = mFallbackFonts.size(); i < count; ++i)
  760. {
  761. mFallbackFonts[i].first->reset(vert_dpi, horz_dpi);
  762. }
  763. }
  764. void LLFontFreetype::resetBitmapCache()
  765. {
  766. for (glyph_info_map_t::iterator it = mCharGlyphInfoMap.begin(),
  767. end = mCharGlyphInfoMap.end();
  768. it != end; ++it)
  769. {
  770. delete it->second;
  771. }
  772. mCharGlyphInfoMap.clear();
  773. mFontBitmapCachep->reset();
  774. if (!mIsFallback)
  775. {
  776. // Add the empty glyph
  777. addGlyphFromFont(this, 0, 0);
  778. }
  779. }
  780. void LLFontFreetype::destroyGL()
  781. {
  782. mFontBitmapCachep->destroyGL();
  783. }
  784. void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num,
  785. U32 width, U32 height,
  786. U8* datap, S32 stride) const
  787. {
  788. if (mIsFallback || !datap)
  789. {
  790. return;
  791. }
  792. LLImageRaw* imagep =
  793. mFontBitmapCachep->getImageRaw(EFontGlyphType::Grayscale, bitmap_num);
  794. if (!imagep || imagep->getComponents() != 2)
  795. {
  796. return;
  797. }
  798. U8* targetp = imagep->getData();
  799. if (!targetp)
  800. {
  801. return;
  802. }
  803. if (stride == 0)
  804. {
  805. stride = width;
  806. }
  807. U32 target_width = imagep->getWidth();
  808. for (U32 i = 0; i < height; ++i)
  809. {
  810. U32 to_offset = (y + i) * target_width + x;
  811. U32 from_offset = (height - 1 - i) * stride;
  812. for (U32 j = 0; j < width; ++j)
  813. {
  814. *(targetp + to_offset++ * 2 + 1) = *(datap + from_offset++);
  815. }
  816. }
  817. }
  818. void LLFontFreetype::setSubImageBGRA(U32 x, U32 y, U32 bitmap_num,
  819. U32 width, U32 height,
  820. U8* datap, S32 stride) const
  821. {
  822. if (mIsFallback)
  823. {
  824. return;
  825. }
  826. LLImageRaw* imagep = mFontBitmapCachep->getImageRaw(EFontGlyphType::Color,
  827. bitmap_num);
  828. if (!imagep || imagep->getComponents() != 4)
  829. {
  830. return;
  831. }
  832. U32* targetp = (U32*)imagep->getData();
  833. if (!targetp)
  834. {
  835. return;
  836. }
  837. const U32 image_width = imagep->getWidth();
  838. for (U32 row = 0; row < height; ++row)
  839. {
  840. U32 src_offset = (height - row - 1) * width * 4;
  841. U32 dst_offset = (y + row) * image_width + x;
  842. for (U32 col = 0; col < width; ++col)
  843. {
  844. U32 pixel = src_offset + col * 4;
  845. targetp[dst_offset + col] = datap[pixel + 3] << 24 |
  846. datap[pixel] << 16 |
  847. datap[pixel + 1] << 8 |
  848. datap[pixel + 2];
  849. }
  850. }
  851. }