| 206 | } |
| 207 | |
| 208 | TextResult TextLayoutLegacyCreate(HFontCollection collection, |
| 209 | uint32_t* codepoints, uint32_t num_codepoints, |
| 210 | TextLayoutSettings* settings, HTextLayout* outlayout) |
| 211 | { |
| 212 | TextLayout* layout = new TextLayout; |
| 213 | layout->m_Destroy = TextLayoutLegacyFree; |
| 214 | layout->m_RefCount = 1; |
| 215 | |
| 216 | layout->m_Glyphs.SetCapacity(num_codepoints); |
| 217 | layout->m_Glyphs.SetSize(num_codepoints); |
| 218 | layout->m_Lines.SetSize(0); |
| 219 | layout->m_FontCollection = collection; |
| 220 | layout->m_Direction = TEXT_DIRECTION_LTR; |
| 221 | layout->m_NumValidGlyphs = 0; |
| 222 | |
| 223 | HFont font = FontCollectionGetFont(collection, 0); |
| 224 | float scale = FontGetScaleFromSize(font, settings->m_Size); |
| 225 | |
| 226 | uint32_t ascent = (uint32_t)FontGetAscent(font, 1.0f); |
| 227 | uint32_t descent = (uint32_t)fabsf(FontGetDescent(font, 1.0f)); |
| 228 | uint32_t line_height = ascent + descent; |
| 229 | float line_height_scaled = line_height * scale; |
| 230 | float tracking = line_height_scaled * settings->m_Tracking; |
| 231 | |
| 232 | FontGlyphOptions options; |
| 233 | options.m_Scale = 1.0f; // Return in points |
| 234 | options.m_GenerateImage = false; |
| 235 | |
| 236 | uint32_t num_whitespaces = 0; |
| 237 | // Lay them all out in a single line, using points |
| 238 | // TODO: Make this optional, so that user can choose to use pixel alignment |
| 239 | float x = 0; |
| 240 | float y = 0; // the legacy "shaping" doesn't support Y offsets |
| 241 | FontGlyph font_glyph; |
| 242 | for (uint32_t i = 0; i < num_codepoints; ++i) |
| 243 | { |
| 244 | uint32_t c = codepoints[i]; |
| 245 | FontResult r = FontGetGlyph(font, c, &options, &font_glyph); |
| 246 | |
| 247 | if (FONT_RESULT_OK != r && CHAR_FALLBACK) |
| 248 | { |
| 249 | r = FontGetGlyph(font, CHAR_FALLBACK, &options, &font_glyph); |
| 250 | } |
| 251 | |
| 252 | TextGlyph g = {0}; |
| 253 | g.m_Font = font; |
| 254 | g.m_Codepoint = c; |
| 255 | // make sure to always set the position of the glyph, regardless |
| 256 | // if FontGetGlyph was successful or not (see #11766) |
| 257 | g.m_X = x; |
| 258 | g.m_Y = y; |
| 259 | |
| 260 | uint32_t whitespace = dmUtf8::IsWhiteSpace(c); |
| 261 | num_whitespaces += whitespace; |
| 262 | |
| 263 | if (FONT_RESULT_OK == r) |
| 264 | { |
| 265 | if (!whitespace) |