| 265 | |
| 266 | auto renderer = std::make_unique<ui::FontRenderer>(); |
| 267 | if (!renderer->LoadFontFromStream(stream)) |
| 268 | return nullptr; |
| 269 | renderer->SetSyntheticOblique(syntheticOblique); |
| 270 | renderer->SetSyntheticBold(syntheticBold); |
| 271 | |
| 272 | auto* ptr = renderer.get(); |
| 273 | renderers[key] = std::move(renderer); |
| 274 | return ptr; |
| 275 | } |
| 276 | |
| 277 | void Font::Load(const char* name) |
| 278 | { |
| 279 | strcpy(_name, name); |
| 280 | strlwr(_name); |
| 281 | |
| 282 | // strip directory prefix for mapping lookup |
| 283 | const char* baseName = strrchr(_name, '\\'); |
| 284 | baseName = baseName ? baseName + 1 : _name; |
| 285 | |
| 286 | // FreeType eligibility depends only on whether a slot mapping + |
| 287 | // TTF exists on disk — never on init-time order. Gating on |
| 288 | // FontSystem::IsAvailable() here meant fonts created before |
| 289 | // FontSystem::Initialize() ran (e.g. ProgressSystem's font during |
| 290 | // InitializeWorld, before InitializeSubsystems) were permanently |
| 291 | // routed through the .fxy bitmap atlas, which walks the input |
| 292 | // string byte-by-byte (fontDraw.cpp:86) — UTF-8 multibyte |
| 293 | // sequences then drew two glyphs per codepoint. Now Font::Load |
| 294 | // always tries FreeType first; the gate only controls log noise |
| 295 | // for apps that opted out of text rendering. |
| 296 | if (!AppConfig::Instance().NoFreeType()) |
| 297 | { |
| 298 | auto* mapping = FindFontMapping(baseName); |
| 299 | if (mapping) |
| 300 | { |
| 301 | auto* renderer = GetOrCreateRenderer(mapping->ttfPath, mapping->syntheticOblique, mapping->syntheticBold); |
| 302 | if (renderer) |
| 303 | { |
| 304 | _isFreeType = true; |
| 305 | _ftRenderer = renderer; |
| 306 | _ftReferencePx = mapping->renderPx; |
| 307 | _maxHeight = mapping->bitmapMaxHeight; |
| 308 | _ftWidthScale = mapping->widthScale; |
| 309 | _ftBaselineOffset = mapping->baselineOffset; |
| 310 | _ftLetterSpacing = mapping->letterSpacing; |
| 311 | _nChars = 0; |
| 312 | return; |
| 313 | } |
| 314 | } |
| 315 | } |
| 316 | |
| 317 | char fontName[256]; |
| 318 | QIFStreamB f; |
| 319 | snprintf(fontName, sizeof(fontName), "%s.fxy", _name); |
| 320 | f.AutoOpen(fontName); |
| 321 | if (f.rest() > 0) |
| 322 | { |
| 323 | FXYData data = ParseFXY(f, _name); |
| 324 |
no test coverage detected