static FT_Error IntRequestFontSize(PDC dc, PFONTGDI FontGDI, LONG lfWidth, LONG lfHeight) { FT_Error error; FT_Size_RequestRec req; FT_Face face = FontGDI->SharedFace->Face; TT_OS2 *pOS2; TT_HoriHeader *pHori; FT_WinFNT_HeaderRec WinFNT; LONG Ascent, Descent, Sum, EmHeight64; LONG Height, Width; // Height = lfHeight; // Width = lfWidth; // Width = abs(Width); // Height = abs(Height); // lfWidth = abs(lfWidth); if (lfHeight == 0) { if (lfWidth == 0) { DPRINT("lfHeight and lfWidth are zero.\n"); lfHeight = -16; } else { lfHeight = lfWidth; } } if (lfHeight == -1) lfHeight = -2; ASSERT_FREETYPE_LOCK_HELD(); pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, FT_SFNT_OS2); pHori = (TT_HoriHeader *)FT_Get_Sfnt_Table(face, FT_SFNT_HHEA); if (!pOS2 || !pHori) { error = FT_Get_WinFNT_Header(face, &WinFNT); if (error) { DPRINT1("%s: Failed to request font size.\n", face->family_name); ASSERT(FALSE); return error; } FontGDI->tmHeight = WinFNT.pixel_height; FontGDI->tmAscent = WinFNT.ascent; FontGDI->tmDescent = FontGDI->tmHeight - FontGDI->tmAscent; FontGDI->tmInternalLeading = WinFNT.internal_leading; FontGDI->EmHeight = FontGDI->tmHeight - FontGDI->tmInternalLeading; FontGDI->EmHeight = max(FontGDI->EmHeight, 1); FontGDI->EmHeight = min(FontGDI->EmHeight, USHORT_MAX); FontGDI->Magic = FONTGDI_MAGIC; req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; req.width = 0; req.height = (FT_Long)(FontGDI->EmHeight << 6); req.horiResolution = 0; req.vertResolution = 0; return FT_Request_Size(face, &req); } if (Height == 0 && dc) // Maybe added test for dc will help { Height = dc->ppdev->devinfo.lfDefaultFont.lfHeight; // Very questionable } /* See also: https://docs.microsoft.com/en-us/typography/opentype/spec/os2#fsselection */ #define FM_SEL_USE_TYPO_METRICS 0x80 if (lfHeight > 0) { /* case (A): lfHeight is positive */ Sum = pOS2->usWinAscent + pOS2->usWinDescent; if (Sum == 0 || (pOS2->fsSelection & FM_SEL_USE_TYPO_METRICS)) { Ascent = pHori->Ascender; Descent = -pHori->Descender; Sum = Ascent + Descent; } else { Ascent = pOS2->usWinAscent; Descent = pOS2->usWinDescent; } FontGDI->tmAscent = FT_MulDiv(lfHeight, Ascent, Sum); FontGDI->tmDescent = FT_MulDiv(lfHeight, Descent, Sum); FontGDI->tmHeight = FontGDI->tmAscent + FontGDI->tmDescent; FontGDI->tmInternalLeading = FontGDI->tmHeight - FT_MulDiv(lfHeight, face->units_per_EM, Sum); } else if (lfHeight < 0) { /* case (B): lfHeight is negative */ if (pOS2->fsSelection & FM_SEL_USE_TYPO_METRICS) { FontGDI->tmAscent = FT_MulDiv(-lfHeight, pHori->Ascender, face->units_per_EM); FontGDI->tmDescent = FT_MulDiv(-lfHeight, -pHori->Descender, face->units_per_EM); } else { FontGDI->tmAscent = FT_MulDiv(-lfHeight, pOS2->usWinAscent, face->units_per_EM); FontGDI->tmDescent = FT_MulDiv(-lfHeight, pOS2->usWinDescent, face->units_per_EM); } FontGDI->tmHeight = FontGDI->tmAscent + FontGDI->tmDescent; FontGDI->tmInternalLeading = FontGDI->tmHeight + lfHeight; } #undef FM_SEL_USE_TYPO_METRICS FontGDI->EmHeight = FontGDI->tmHeight - FontGDI->tmInternalLeading; FontGDI->EmHeight = max(FontGDI->EmHeight, 1); FontGDI->EmHeight = min(FontGDI->EmHeight, USHORT_MAX); FontGDI->Magic = FONTGDI_MAGIC; if (Height == 0) // { // Height = Width; // } // if (Height < 1) // This was commented, but I have added it back Height = 1; // This was commented, but I have added it back if (Width > 0xFFFFU) // Width = 0xFFFFU; // if (Height > 0xFFFFU) // Height = 0xFFFFU; // if (lfHeight > 0) EmHeight64 = (FontGDI->EmHeight << 6) + 31; else EmHeight64 = (FontGDI->EmHeight << 6); if (strcmp(face->family_name, "Marlett")==0) // Decision if Marlett use Old calc { req.width = (FT_Long)(Width << 6); // Old Path req.height = (FT_Long)(Height << 6); // Old Path DPRINT1("Old Height is '%ld', Width is '%ld', New EmHeight64 is '%ld'.\n", Height << 6, Width << 6, EmHeight64); } else { req.width = 0; // New path req.height = EmHeight64; // New path } req.type = FT_SIZE_REQUEST_TYPE_NOMINAL; // req.width = 0; // See Above for Marlett vs Non-Marlett // req.height = EmHeight64; // See Above for Marlett vs Non-Marlett req.horiResolution = 0; req.vertResolution = 0; return FT_Request_Size(face, &req); }