This code is not thread safe.
| 217 | |
| 218 | // This code is not thread safe. |
| 219 | void Shape(hb_buffer_t * hbBuffer, int fontPixelSize, int fontIndex, text::TextMetrics & outMetrics) |
| 220 | { |
| 221 | // TODO(AB): Do not set the same font size every time. |
| 222 | // TODO(AB): Use hb_font_set_scale to scale the same size font in HB instead of changing it in Freetype. |
| 223 | FREETYPE_CHECK(FT_Set_Pixel_Sizes(m_fontFace, 0 /* pixel_width */, fontPixelSize /* pixel_height */)); |
| 224 | if (!m_harfbuzzFont) |
| 225 | m_harfbuzzFont = hb_ft_font_create(m_fontFace, nullptr); |
| 226 | // else |
| 227 | // Call on each font size change. |
| 228 | // hb_ft_font_changed(m_harfbuzzFont); |
| 229 | |
| 230 | // Shape! |
| 231 | hb_shape(m_harfbuzzFont, hbBuffer, nullptr, 0); |
| 232 | |
| 233 | // Get the glyph and position information. |
| 234 | unsigned int glyphCount; |
| 235 | hb_glyph_info_t const * glyphInfo = hb_buffer_get_glyph_infos(hbBuffer, &glyphCount); |
| 236 | hb_glyph_position_t const * glyphPos = hb_buffer_get_glyph_positions(hbBuffer, &glyphCount); |
| 237 | |
| 238 | for (unsigned int i = 0; i < glyphCount; ++i) |
| 239 | { |
| 240 | // TODO(AB): Check for missing glyph ID? |
| 241 | auto const glyphId = static_cast<uint16_t>(glyphInfo[i].codepoint); |
| 242 | |
| 243 | FT_Int32 constexpr flags = FT_LOAD_DEFAULT; |
| 244 | FREETYPE_CHECK(FT_Load_Glyph(m_fontFace, glyphId, flags)); |
| 245 | |
| 246 | auto const & currPos = glyphPos[i]; |
| 247 | |
| 248 | auto const & metrics = m_fontFace->glyph->metrics; |
| 249 | auto const xOffset = static_cast<int32_t>((currPos.x_offset + metrics.horiBearingX) >> 6); |
| 250 | // The original Drape code expects a bottom, not a top offset in its calculations. |
| 251 | auto const yOffset = static_cast<int32_t>((currPos.y_offset + metrics.horiBearingY - metrics.height) >> 6); |
| 252 | int32_t const xAdvance = currPos.x_advance >> 6; |
| 253 | // yAdvance is always zero for horizontal text layouts. |
| 254 | |
| 255 | outMetrics.AddGlyphMetrics(static_cast<int16_t>(fontIndex), glyphId, xOffset, yOffset, xAdvance, fontPixelSize); |
| 256 | } |
| 257 | } |
| 258 | |
| 259 | private: |
| 260 | ReaderPtr<Reader> m_fontReader; |
no test coverage detected