15#include FT_TYPE1_TABLES_H
16#include FT_TRUETYPE_TABLES_H
17#include FT_TRUETYPE_TAGS_H
18#include FT_TRIGONOMETRY_H
22#include FT_SFNT_NAMES_H
23#include FT_SYNTHESIS_H
24#include FT_TRUETYPE_IDS_H
26#ifndef FT_INTERNAL_INTERNAL_H
27 #define FT_INTERNAL_INTERNAL_H <freetype/internal/internal.h>
28 #include FT_INTERNAL_INTERNAL_H
30#include FT_INTERNAL_TRUETYPE_TYPES_H
62#define FONTLINK_DEFAULT_CHAR 0x30FB
71#define MAX_FONTLINK_CACHE 128
95 DWORD cbData, dwValue;
102 L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontLink",
107 cbData =
sizeof(dwValue);
129 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\FontAssoc\\Associated DefaultFonts",
134 cbData =
sizeof(szValue);
142 cbData =
sizeof(szValue);
167 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\FontAssoc\\Associated Charset",
172 cbData =
sizeof(szValue);
180 cbData =
sizeof(szValue);
188 cbData =
sizeof(szValue);
223 if (pChain->pszzFontLink)
263 ASSERT(pNewHead != pOldHead);
288 pCache->
LogFont = pChain->LogFont;
289 pCache->
Chain = *pChain;
328#define HIGH_SURROGATE_MIN 0xD800U
329#define HIGH_SURROGATE_MAX 0xDBFFU
330#define LOW_SURROGATE_MIN 0xDC00U
331#define LOW_SURROGATE_MAX 0xDFFFU
333#define IS_HIGH_SURROGATE(ch0) (HIGH_SURROGATE_MIN <= (ch0) && (ch0) <= HIGH_SURROGATE_MAX)
334#define IS_LOW_SURROGATE(ch1) (LOW_SURROGATE_MIN <= (ch1) && (ch1) <= LOW_SURROGATE_MAX)
343#ifndef _TMPF_VARIABLE_PITCH
344 #define _TMPF_VARIABLE_PITCH TMPF_FIXED_PITCH
348#define EMUBOLD_NEEDED(original, request) \
349 (((request) != FW_DONTCARE) && ((request) - (original) >= FW_BOLD - FW_MEDIUM))
357#define gmxWorldToDeviceDefault gmxWorldToPageDefault
363 RTL_CONSTANT_STRING(
L"\\REGISTRY\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
373#define ASSERT_FREETYPE_LOCK_HELD() \
374 ASSERT(g_FreeTypeLock->Owner == KeGetCurrentThread())
376#define ASSERT_FREETYPE_LOCK_NOT_HELD() \
377 ASSERT(g_FreeTypeLock->Owner != KeGetCurrentThread())
379#define IntLockFreeType() \
381 ASSERT_FREETYPE_LOCK_NOT_HELD(); \
382 ExEnterCriticalRegionAndAcquireFastMutexUnsafe(g_FreeTypeLock); \
385#define IntUnLockFreeType() \
387 ASSERT_FREETYPE_LOCK_HELD(); \
388 ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(g_FreeTypeLock); \
391#define MAX_FONT_CACHE 256
423#define MAXTCIINDEX 32
514 if (pFontLink->bIgnore)
517 if (pFontLink->SharedFace)
534 pFontLink->bIgnore =
TRUE;
538 pFontGDI =
ObjToGDI(pFontObj, FONT);
546 pFontLink->bIgnore =
TRUE;
567 Cache->OutlineRequiredSize = 0;
601 Ptr->IsMapping = IsMapping;
602 DPRINT(
"Creating SharedMem for %p (%i, %p)\n",
Buffer, IsMapping,
Ptr);
635 for (CurrentEntry = g_FontCacheListHead.
Flink;
636 CurrentEntry != &g_FontCacheListHead;
637 CurrentEntry = NextEntry)
640 NextEntry = CurrentEntry->
Flink;
654 if (
Ptr->RefCount <= 0)
658 if (
Ptr->RefCount == 0)
660 DPRINT(
"Releasing SharedMem for %p (%i, %p)\n",
Ptr->Buffer,
Ptr->IsMapping,
Ptr);
682 if (
Ptr->RefCount <= 0)
686 if (
Ptr->RefCount == 0)
688 DPRINT(
"Releasing SharedFace for %s\n",
Ptr->Face->family_name ?
Ptr->Face->family_name :
"<NULL>");
730 pt->x.fract = (
vec->
x & 0x3f) << 10;
731 pt->x.fract |= ((
pt->x.fract >> 6) | (
pt->x.fract >> 12));
733 pt->y.fract = (
vec->
y & 0x3f) << 10;
734 pt->y.fract |= ((
pt->y.fract >> 6) | (
pt->y.fract >> 12));
751 const char *style_name;
770 style_name =
"<invalid>";
773 DPRINT(
"family_name '%s', style_name '%s', FaceName '%wZ', StyleName '%wZ', FontGDI %p, "
774 "FontObj %p, iUnique %lu, SharedFace %p, Face %p, CharSet %u, Filename '%S'\n",
793 DPRINT(
"## DumpFontList(%p)\n", Head);
798 DumpFontEntry(CurrentEntry);
804 DPRINT(
"%wZ,%u -> %wZ,%u\n",
817 DPRINT(
"## DumpFontSubstList\n");
819 for (pListEntry = pHead->
Flink;
821 pListEntry = pListEntry->
Flink)
824 DumpFontSubstEntry(pSubstEntry);
828VOID DumpPrivateFontList(
BOOL bDoLock)
850VOID DumpGlobalFontList(
BOOL bDoLock)
855 DumpFontList(&g_FontListHead);
863 DumpGlobalFontList(bDoLock);
864 DumpPrivateFontList(bDoLock);
881 BYTE InfoBuffer[128];
890 L"Microsoft\\Windows NT\\CurrentVersion\\"
906 &KeyFullInfo,
sizeof(KeyFullInfo), &
Length);
919 InfoBuffer,
sizeof(InfoBuffer), &
Length);
933 DPRINT(
"RtlCreateUnicodeString failed\n");
939 InfoBuffer,
sizeof(InfoBuffer), &
Length);
955 DPRINT(
"RtlCreateUnicodeString failed\n");
997 DPRINT(
"ExAllocatePoolWithTag failed\n");
1036 DPRINT1(
"FT_Init_FreeType failed with error code 0x%x\n", ulError);
1042 DPRINT1(
"Fonts registry is empty.\n");
1073 pHead = &g_FontCacheListHead;
1082 pHead = &g_FontSubstListHead;
1091 pHead = &g_FontListHead;
1111 nTenthsOfDegrees %= 360 * 10;
1112 if (nTenthsOfDegrees >= 0)
1113 return nTenthsOfDegrees;
1114 return nTenthsOfDegrees + 360 * 10;
1123 pmat->
xx = vecAngle.
x;
1124 pmat->
xy = -vecAngle.
y;
1125 pmat->
yx = -pmat->
xy;
1126 pmat->
yy = pmat->
xx;
1162 BYTE RequestedCharSet,
1173 for (pListEntry = pHead->
Flink;
1174 pListEntry != pHead;
1175 pListEntry = pListEntry->
Flink)
1260 UINT RecurseCount = 5;
1271 while (RecurseCount-- > 0)
1274 &OutputNameW, &InputNameW,
1300 pChain->pBaseTextObj = pTextObj;
1301 pChain->pDefFace =
face;
1307 L"tahoma.ttf,Tahoma\0"
1308 L"msgothic.ttc,MS UI Gothic\0"
1309 L"mingliu.ttc,PMingLiU\0"
1310 L"simsun.ttc,SimSun\0"
1311 L"gulim.ttc,Gulim\0"
1315 L"cour.ttf,Courier New\0"
1316 L"msgothic.ttc,MS Gothic\0"
1317 L"mingliu.ttc,MingLiU\0"
1318 L"simsun.ttc,NSimSun\0"
1319 L"gulim.ttc,GulimChe\0"
1330 WCHAR szzFontLink[512];
1334 ASSERT(pLF->lfFaceName[0]);
1338 L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink",
1344 cbData =
sizeof(szzFontLink);
1351 cbData =
sizeof(szzFontLink);
1358 if (cbData >= 2 *
sizeof(
WCHAR))
1360 FontLinkSize = cbData;
1371 pszzFontLink =
NULL;
1408 pChain->pszzFontLink = pszzFontLink;
1479 PTEXTOBJ pTextObj = pChain->pBaseTextObj;
1506 default: bFixCharSet =
TRUE;
break;
1516 *pChain = pLinkCache->
Chain;
1522 pChain->LogFont = lfBase;
1529 pszLink = pChain->pszzFontLink;
1532 DPRINT(
"pszLink: '%S'\n", pszLink);
1536 pszLink +=
wcslen(pszLink) + 1;
1545 DPRINT(
"szEntry: '%S'\n", szEntry);
1567 BYTE *DirInfoBuffer;
1609 if (DirInfoBuffer ==
NULL)
1627 Status = ZwQueryDirectoryFile(
1678 bRestartScan =
FALSE;
1694 if (CodePageRange1 == 0)
1699 for (BitIndex = 0; BitIndex <
MAXTCIINDEX; ++BitIndex)
1701 if (CodePageRange1 & (1 << BitIndex))
1704 if ((nIndex >= 0) && (nCount == (
UINT)nIndex))
1716#define PX2PT(pixels) FT_MulDiv((pixels), 72, 96)
1740 if (SharedFace ==
NULL && CharSetIndex == -1)
1748 ((FontIndex != -1) ? FontIndex : 0),
1764 if (
Error == FT_Err_Unknown_File_Format)
1765 DPRINT1(
"Unknown font file format\n");
1767 DPRINT1(
"Error reading font (error code: %d)\n",
Error);
1773 Face = SharedFace->
Face;
1921 if (pOS2 && os2_version >= 1)
1928 for (BitIndex = 0; BitIndex <
MAXTCIINDEX; ++BitIndex)
1930 if (os2_ulCodePageRange1 & (1 << BitIndex))
1935 if ((CharSetIndex == -1 && CharSetCount == 0) ||
1936 CharSetIndex == CharSetCount)
1961 DPRINT(
"Font loaded: %s (%s)\n",
1968 Entry->Font = FontGDI;
1969 Entry->NotEnum = (Characteristics & FR_NOT_ENUM);
1972 if (Characteristics & FR_PRIVATE)
1987 if (FontIndex == -1)
2004 if (CharSetIndex == -1)
2009 if (
Entry->StyleName.Length)
2010 NameLength +=
Entry->StyleName.Length +
sizeof(
WCHAR);
2038 *pValueName = NewString;
2040 if (
Entry->StyleName.Length)
2046 for (
i = 1;
i < CharSetCount; ++
i)
2080 default:
return L"Unknown";
2119 RtlInitEmptyUnicodeString(&PathName, pszBuffer,
Length);
2142 DPRINT1(
"Could not load font file: %wZ\n", &PathName);
2151 DPRINT1(
"ObReferenceObjectByHandle failed.\n");
2164 DPRINT1(
"Could not map file: %wZ\n", &PathName);
2175 DPRINT1(
"Could not map file: %wZ\n", &PathName);
2184 LoadFont.Characteristics = Characteristics;
2214 RtlInitEmptyUnicodeString(&NewString, pszBuffer,
Length);
2237 RtlInitEmptyUnicodeString(&NewString, pszBuffer,
Length);
2263 pFileName = PathName.
Buffer;
2298 if (!lpszPath || !*lpszPath)
2300 if (*lpszPath ==
L'\\' || (*lpszPath && lpszPath[1] ==
L':'))
2335 &KeyFullInfo,
sizeof(KeyFullInfo), &
Length);
2348 DPRINT1(
"ExAllocatePoolWithTag failed\n");
2354 for (
i = 0;
i < KeyFullInfo.
Values; ++
i)
2358 InfoBuffer, InfoSize, &
Length);
2367 DPRINT1(
"ExAllocatePoolWithTag failed\n");
2372 InfoBuffer, InfoSize, &
Length);
2387 DPRINT1(
"RtlCreateUnicodeString failed\n");
2393 InfoBuffer, InfoSize, &
Length);
2402 DPRINT1(
"ExAllocatePoolWithTag failed\n");
2407 InfoBuffer, InfoSize, &
Length);
2427 L"\\SystemRoot\\Fonts\\%s", pchPath);
2454 return (KeyFullInfo.
Values != 0 && nFontCount != 0);
2475 LoadFont.Characteristics = FR_PRIVATE | FR_NOT_ENUM;
2491 if (EntryCollection)
2501 Ret = EntryCollection->
Handle;
2563 if (CurrentEntry->
Handle == hMMFont)
2565 EntryCollection = CurrentEntry;
2573 if (EntryCollection)
2590 DPRINT(
"IntGdiCleanupPrivateFontsForProcess()\n");
2593 EntryCollection =
NULL;
2606 if (EntryCollection)
2684 if (lf->lfEscapement != lf->lfOrientation)
2778 int Ascent, Descent;
2835 - ((Ascent + Descent)
2837 YScale) + 32) >> 6);
3026 Names->OtmSize = OtmSize;
3106 if (
Size == 0 &&
Cache->OutlineRequiredSize > 0)
3109 return Cache->OutlineRequiredSize;
3124 return Cache->OutlineRequiredSize;
3129 if (Size < Cache->OutlineRequiredSize)
3131 DPRINT1(
"Size %u < OutlineRequiredSize %u\n",
Size,
3132 Cache->OutlineRequiredSize);
3151 DPRINT1(
"Can't find OS/2 table - not TT font?\n");
3160 DPRINT1(
"Can't find HHEA table - not TT font?\n");
3181#define SCALE_X(value) ((FT_MulFix((value), XScale) + 32) >> 6)
3182#define SCALE_Y(value) ((FT_MulFix((value), YScale) + 32) >> 6)
3231 return Cache->OutlineRequiredSize;
3298 INT i,
Count, BestIndex, Score, BestScore;
3339 if (
Name.name_id != NameID)
3352 (
Name.string[0] == 0 &&
Name.string[1] == 0))
3376 if (Score > BestScore)
3435 if (!
Cache->FontFamily.Buffer)
3441 if (!
Cache->FullName.Buffer)
3486 Lf = &
Info->EnumLogFontEx.elfLogFont;
3499 Ntm = &
Info->NewTextMetricEx.ntmTm;
3544 sizeof(
Info->EnumLogFontEx.elfFullName),
3548 StyleW.
Buffer =
Info->EnumLogFontEx.elfStyle;
3589 if (
fs.fsCsb[0] == 0)
3596 case FT_ENCODING_UNICODE:
3597 case FT_ENCODING_APPLE_ROMAN:
3600 case FT_ENCODING_MS_SYMBOL:
3612 if (
fs.fsCsb[0] & fs0)
3624 DPRINT1(
"Unknown elfscript for bit %u\n",
i);
3629 Info->NewTextMetricEx.ntmFontSig =
fs;
3649 FontGDI = CurrentEntry->
Font;
3776 const DWORD *pdw = pv;
3792 DWORD dwHash = pCache->dwHash;
3796 for (CurrentEntry = g_FontCacheListHead.
Flink;
3797 CurrentEntry != &g_FontCacheListHead;
3798 CurrentEntry = CurrentEntry->
Flink)
3801 if (FontEntry->
dwHash == dwHash &&
3803 FontEntry->
Hashed.
Face == pCache->Hashed.Face &&
3814 if (CurrentEntry == &g_FontCacheListHead)
3840 DPRINT1(
"Failure caching glyph.\n");
3848 DPRINT1(
"Failure rendering glyph.\n");
3855 DPRINT1(
"Alloc failure caching glyph.\n");
3864 DPRINT1(
"Conversion failed\n");
3872 BitmapGlyph->
bitmap = AlignedBitmap;
3893 int needed = 0,
point = 0, contour, first_pt;
3894 unsigned int pph_start, cpfx;
3897 for (contour = 0; contour <
outline->n_contours; contour++)
3914 needed +=
sizeof(*pph);
3916 while (point <= outline->contours[contour])
3928 }
while (point <= outline->contours[contour] &&
3940 else if (point <= outline->contours[contour] &&
3954 needed +=
sizeof(*ppc) + (cpfx - 1) *
sizeof(
POINTFX);
3957 pph->
cb = needed - pph_start;
3980 int contour,
point = 0, first_pt;
3985 unsigned int needed = 0;
3987 for (contour = 0; contour <
outline->n_contours; contour++)
3997 needed +=
sizeof(*pph);
3999 while (point <= outline->contours[contour])
4026 cubic_control[0].
x >>= 1;
4027 cubic_control[0].
y >>= 1;
4030 cubic_control[3] =
outline->points[first_pt];
4038 cubic_control[3].
x >>= 1;
4039 cubic_control[3].
y >>= 1;
4044 cubic_control[1].
x = (2 *
outline->points[
point].x + 1) / 3;
4045 cubic_control[1].
y = (2 *
outline->points[
point].y + 1) / 3;
4046 cubic_control[2] = cubic_control[1];
4047 cubic_control[1].
x += (cubic_control[0].
x + 1) / 3;
4048 cubic_control[1].
y += (cubic_control[0].
y + 1) / 3;
4049 cubic_control[2].
x += (cubic_control[3].
x + 1) / 3;
4050 cubic_control[2].
y += (cubic_control[3].
y + 1) / 3;
4060 }
while (point <= outline->contours[contour] &&
4066 if (point <= outline->contours[contour] &&
4078 needed +=
sizeof(*ppc) + (cpfx - 1) *
sizeof(
POINTFX);
4081 pph->
cb = needed - pph_start;
4095 LONG Ascent, Descent, Sum, EmHeight, Width64;
4097 lfWidth =
abs(lfWidth);
4102 DPRINT(
"lfHeight and lfWidth are zero.\n");
4125 if (!pOS2 || !pHori)
4130 DPRINT1(
"%s: Failed to request font size.\n",
face->family_name);
4154#define FM_SEL_USE_TYPO_METRICS 0x80
4163 Sum = Ascent + Descent;
4176 else if (lfHeight < 0)
4192#undef FM_SEL_USE_TYPO_METRICS
4199 EmHeight =
max(EmHeight, 1);
4212 Width64 = (
FT_MulDiv(lfWidth, 96 * 5, 72 * 3) << 6);
4218 req.
width = Width64;
4219 req.
height = (EmHeight << 6);
4243 DPRINT(
"WARNING: No charmap selected!\n");
4244 DPRINT(
"This font face has %d charmaps\n",
face->num_charmaps);
4247 for (
n = 0;
n <
face->num_charmaps;
n++)
4249 charmap =
face->charmaps[
n];
4250 if (charmap->
encoding == FT_ENCODING_UNICODE)
4258 for (
n = 0;
n <
face->num_charmaps;
n++)
4260 charmap =
face->charmaps[
n];
4270 for (
n = 0;
n <
face->num_charmaps;
n++)
4272 charmap =
face->charmaps[
n];
4273 if (charmap->
encoding == FT_ENCODING_MS_SYMBOL)
4280 if (!found &&
face->num_charmaps > 0)
4282 found =
face->charmaps[0];
4286 DPRINT1(
"WARNING: Could not find desired charmap!\n");
4294 DPRINT1(
"WARNING: Could not set the charmap!\n");
4320 if (glyph < 0x100) glyph += 0xf000;