ReactOS 0.4.16-dev-2380-gf63df20
freetype.c File Reference
#include <win32k.h>
#include <freetype/internal/ftcalc.h>
#include <gdi/eng/floatobj.h>
#include "font.h"
#include "utils.h"
#include <debug.h>
Include dependency graph for freetype.c:

Go to the source code of this file.

Classes

struct  _FONTLINK
 
struct  _FONTLINK_CHAIN
 
struct  _FONTLINK_CACHE
 
struct  _FONT_LOOKUP_CACHE
 
struct  FONT_NAMES
 

Macros

#define NDEBUG
 
#define FONTLINK_DEFAULT_CHAR   0x30FB
 
#define MAX_FONTLINK_CACHE   128
 
#define MAX_FONT_LOOKUP_CACHE   64
 
#define _TMPF_VARIABLE_PITCH   TMPF_FIXED_PITCH
 
#define EMUBOLD_NEEDED(original, request)    (((request) != FW_DONTCARE) && ((request) - (original) >= FW_BOLD - FW_MEDIUM))
 
#define gmxWorldToDeviceDefault   gmxWorldToPageDefault
 
#define ASSERT_FREETYPE_LOCK_HELD()    ASSERT(g_FreeTypeLock->Owner == KeGetCurrentThread())
 
#define ASSERT_FREETYPE_LOCK_NOT_HELD()    ASSERT(g_FreeTypeLock->Owner != KeGetCurrentThread())
 
#define IntLockFreeType()
 
#define IntUnLockFreeType()
 
#define MAX_FONT_CACHE   256
 
#define CP_SYMBOL   42
 
#define MAXTCIINDEX   32
 
#define CP_OEMCP   1
 
#define CP_MACCP   2
 
#define PX2PT(pixels)   FT_MulDiv((pixels), 72, 96)
 
#define SCALE_X(value)   ((FT_MulFix((value), XScale) + 32) >> 6)
 
#define SCALE_Y(value)   ((FT_MulFix((value), YScale) + 32) >> 6)
 
#define FM_SEL_USE_TYPO_METRICS   0x80
 
#define GOT_PENALTY(name, value)   Penalty += (value)
 
#define VALIGN_MASK   (TA_TOP | TA_BASELINE | TA_BOTTOM)
 
#define STACK_TEXT_BUFFER_SIZE   512
 

Typedefs

typedef struct _FONTLINK FONTLINK
 
typedef struct _FONTLINKPFONTLINK
 
typedef struct _FONTLINK_CHAIN FONTLINK_CHAIN
 
typedef struct _FONTLINK_CHAINPFONTLINK_CHAIN
 
typedef struct _FONTLINK_CACHE FONTLINK_CACHE
 
typedef struct _FONTLINK_CACHEPFONTLINK_CACHE
 
typedef struct _FONT_LOOKUP_CACHE FONT_LOOKUP_CACHE
 
typedef struct _FONT_LOOKUP_CACHEPFONT_LOOKUP_CACHE
 
typedef struct FONT_NAMES FONT_NAMES
 
typedef struct FONT_NAMESLPFONT_NAMES
 

Functions

static RTL_STATIC_LIST_HEAD (g_FontLinkCache)
 
static NTSTATUS FontLink_LoadSettings (VOID)
 
static NTSTATUS FontLink_LoadDefaultFonts (VOID)
 
static NTSTATUS FontLink_LoadDefaultCharset (VOID)
 
static VOID FontLink_Destroy (_Inout_ PFONTLINK pLink)
 
static BOOL FontLink_Chain_IsPopulated (const FONTLINK_CHAIN *pChain)
 
static VOID FontLink_Chain_Free (_Inout_ PFONTLINK_CHAIN pChain)
 
static VOID FontLink_AddCache (_In_ PFONTLINK_CACHE pCache)
 
static VOID FontLink_Chain_Finish (_Inout_ PFONTLINK_CHAIN pChain)
 
static PFONTLINK_CACHE FontLink_FindCache (_In_ const LOGFONTW *pLogFont)
 
static VOID FontLink_CleanupCache (VOID)
 
static RTL_STATIC_LIST_HEAD (s_FontLookupCacheList)
 
static RTL_STATIC_LIST_HEAD (g_FontListHead)
 
static RTL_STATIC_LIST_HEAD (g_FontCacheListHead)
 
BYTE FASTCALL IntCharSetFromCodePage (UINT uCodePage)
 
static __inline VOID FindBestFontFromList (FONTOBJ **FontObj, ULONG *MatchPenalty, const LOGFONTW *LogFont, const PLIST_ENTRY Head)
 
PSHARED_FACE IntRealizeFont (const LOGFONTW *pLogFont, _Inout_opt_ PTEXTOBJ TextObj)
 
static BOOL FontLink_PrepareFontInfo (_Inout_ PFONTLINK pFontLink)
 
static RTL_STATIC_LIST_HEAD (g_FontSubstListHead)
 
static void SharedMem_AddRef (PSHARED_MEM Ptr)
 
static void SharedFaceCache_Init (PSHARED_FACE_CACHE Cache)
 
static PSHARED_FACE SharedFace_Create (FT_Face Face, PSHARED_MEM Memory)
 
static PSHARED_MEM SharedMem_Create (PBYTE Buffer, ULONG BufferSize, BOOL IsMapping)
 
static void SharedFace_AddRef (PSHARED_FACE Ptr)
 
static void RemoveCachedEntry (PFONT_CACHE_ENTRY Entry)
 
static void RemoveCacheEntries (FT_Face Face)
 
static void SharedMem_Release (PSHARED_MEM Ptr)
 
static void SharedFaceCache_Release (PSHARED_FACE_CACHE Cache)
 
static void SharedFace_Release (PSHARED_FACE Ptr, BOOL bDoLock)
 
static VOID FASTCALL CleanupFontEntryEx (PFONT_ENTRY FontEntry, PFONTGDI FontGDI)
 
static __inline VOID FASTCALL CleanupFontEntry (PFONT_ENTRY FontEntry)
 
static __inline void FTVectorToPOINTFX (FT_Vector *vec, POINTFX *pt)
 
static __inline FT_Fixed FT_FixedFromFIXED (FIXED f)
 
BOOL FASTCALL IntLoadFontSubstList (PLIST_ENTRY pHead)
 
static void FontLookUp_Destroy (PFONT_LOOKUP_CACHE pCache)
 
static void FontLookUp_Cleanup (_In_ BOOL bDoLock, _Inout_opt_ PSHARED_FACE SharedFace)
 
BOOL FASTCALL InitFontSupport (VOID)
 
VOID FASTCALL FreeFontSupport (VOID)
 
static VOID FASTCALL IntEscapeMatrix (FT_Matrix *pmat, LONG lfEscapement)
 
static VOID FASTCALL IntMatrixFromMx (FT_Matrix *pmat, const MATRIX *pmx)
 
static BOOL SubstituteFontByList (PLIST_ENTRY pHead, PUNICODE_STRING pOutputName, PUNICODE_STRING pInputName, BYTE RequestedCharSet, BYTE CharSetMap[FONTSUBST_FROM_AND_TO])
 
static BOOL SubstituteFontRecurse (PLOGFONTW pLogFont)
 
static VOID FontLink_Chain_Init (_Out_ PFONTLINK_CHAIN pChain, _Inout_ PTEXTOBJ pTextObj, _In_ FT_Face face)
 
static NTSTATUS FontLink_Chain_LoadReg (_Inout_ PFONTLINK_CHAIN pChain, _Inout_ PLOGFONTW pLF)
 
static PFONTLINK FontLink_Chain_FindLink (PFONTLINK_CHAIN pChain, PLOGFONTW plf)
 
static PFONTLINK FontLink_Create (_Inout_ PFONTLINK_CHAIN pChain, _In_ const LOGFONTW *plfBase, _In_ LPCWSTR pszLink)
 
static NTSTATUS FontLink_Chain_Populate (_Inout_ PFONTLINK_CHAIN pChain)
 
VOID FASTCALL IntLoadSystemFonts (VOID)
 
UINT FASTCALL IntGetCharSet (INT nIndex, FT_ULong CodePageRange1)
 
static INT FASTCALL IntGdiLoadFontsFromMemory (PGDI_LOAD_FONT pLoadFont, PSHARED_FACE SharedFace, FT_Long FontIndex, INT CharSetIndex)
 
static INT FASTCALL IntGdiLoadFontByIndexFromMemory (PGDI_LOAD_FONT pLoadFont, FT_Long FontIndex)
 
static INT FASTCALL IntGdiAddFontResourceSingle (_In_ PCUNICODE_STRING FileName, _In_ DWORD Characteristics, _In_ DWORD dwFlags)
 
INT FASTCALL IntGdiAddFontResourceEx (_In_ PCUNICODE_STRING FileName, _In_ DWORD cFiles, _In_ DWORD Characteristics, _In_ DWORD dwFlags)
 
VOID IntDeleteRegFontEntries (_In_ PCWSTR pszFileName, _In_ DWORD dwFlags)
 
static BOOL FASTCALL IntGdiRemoveFontResourceSingle (_In_ PCUNICODE_STRING FileName, _In_ DWORD dwFlags)
 
BOOL FASTCALL IntGdiRemoveFontResource (_In_ PCUNICODE_STRING FileName, _In_ DWORD cFiles, _In_ DWORD dwFlags)
 
BOOL FASTCALL IntLoadFontsInRegistry (VOID)
 
HANDLE FASTCALL IntGdiAddFontMemResource (PVOID Buffer, DWORD dwSize, PDWORD pNumAdded)
 
VOID FASTCALL IntGdiCleanupMemEntry (PFONT_ENTRY_MEM Head)
 
static VOID FASTCALL UnlinkFontMemCollection (PFONT_ENTRY_COLL_MEM Collection)
 
BOOL FASTCALL IntGdiRemoveFontMemResource (HANDLE hMMFont)
 
VOID FASTCALL IntGdiCleanupPrivateFontsForProcess (VOID)
 
BOOL FASTCALL IntIsFontRenderingEnabled (VOID)
 
VOID FASTCALL IntEnableFontRendering (BOOL Enable)
 
FT_Render_Mode FASTCALL IntGetFontRenderMode (LOGFONTW *logfont)
 
NTSTATUS FASTCALL TextIntCreateFontIndirect (CONST LPLOGFONTW lf, HFONT *NewFont)
 
static BOOLEAN IntTranslateCharsetInfo (PDWORD Src, LPCHARSETINFO Cs, DWORD Flags)
 
static BOOL face_has_symbol_charmap (FT_Face ft_face)
 
static void FASTCALL FillTM (TEXTMETRICW *TM, PFONTGDI FontGDI, TT_OS2 *pOS2, TT_HoriHeader *pHori, FT_WinFNT_HeaderRec *pFNT)
 
static NTSTATUS IntGetFontLocalizedName (PUNICODE_STRING pNameW, PSHARED_FACE SharedFace, FT_UShort NameID, FT_UShort LangID)
 
static __inline void FASTCALL IntInitFontNames (FONT_NAMES *Names, PSHARED_FACE SharedFace)
 
static SIZE_T FASTCALL IntStoreName (_In_ const UNICODE_STRING *pName, _Out_ PBYTE pb)
 
PBYTE FASTCALL IntStoreFontNames (_In_ const FONT_NAMES *Names, _Out_ OUTLINETEXTMETRICW *Otm)
 
static __inline void FASTCALL IntFreeFontNames (FONT_NAMES *Names)
 
INT FASTCALL IntGetOutlineTextMetrics (PFONTGDI FontGDI, UINT Size, OUTLINETEXTMETRICW *Otm, BOOL bLocked)
 
static void FASTCALL FontFamilyFillInfo (PFONTFAMILYINFO Info, LPCWSTR FaceName, LPCWSTR FullName, PFONTGDI FontGDI)
 
static BOOLEAN FASTCALL GetFontFamilyInfoForList (const LOGFONTW *LogFont, PFONTFAMILYINFO Info, LPCWSTR NominalName, LONG *pCount, LONG MaxCount, PLIST_ENTRY Head)
 
static BOOLEAN FASTCALL GetFontFamilyInfoForSubstitutes (const LOGFONTW *LogFont, PFONTFAMILYINFO Info, LONG *pCount, LONG MaxCount)
 
BOOL FASTCALL ftGdiGetRasterizerCaps (LPRASTERIZER_STATUS lprs)
 
static DWORD IntGetHash (IN LPCVOID pv, IN DWORD cdw)
 
static FT_BitmapGlyph IntFindGlyphCache (IN const FONT_CACHE_ENTRY *pCache)
 
static FT_BitmapGlyph IntGetBitmapGlyphWithCache (IN OUT PFONT_CACHE_ENTRY Cache, IN FT_GlyphSlot GlyphSlot)
 
static unsigned int get_native_glyph_outline (FT_Outline *outline, unsigned int buflen, char *buf)
 
static unsigned int get_bezier_glyph_outline (FT_Outline *outline, unsigned int buflen, char *buf)
 
static FT_Error IntRequestFontSize (PDC dc, PFONTGDI FontGDI, LONG lfWidth, LONG lfHeight)
 
BOOL FASTCALL TextIntUpdateSize (PDC dc, PTEXTOBJ TextObj, PFONTGDI FontGDI, BOOL bDoLock)
 
static FT_UInt FASTCALL get_glyph_index_symbol (FT_Face ft_face, UINT glyph)
 
static FT_UInt FASTCALL get_glyph_index (FT_Face ft_face, UINT glyph)
 
static FT_UInt FASTCALL get_glyph_index_flagged (FT_Face face, FT_ULong code, BOOL fCodeAsIndex)
 
static VOID FontLink_Chain_Dump (_In_ PFONTLINK_CHAIN pChain)
 
static UINT FontLink_Chain_FindGlyph (_Inout_ PFONTLINK_CHAIN pChain, _Out_ PFONT_CACHE_ENTRY pCache, _Inout_ FT_Face *pFace, _In_ UINT code, _In_ BOOL fCodeAsIndex)
 
ULONG FASTCALL ftGdiGetGlyphOutline (PDC dc, WCHAR wch, UINT iFormat, LPGLYPHMETRICS pgm, ULONG cjBuf, PVOID pvBuf, const MAT2 *pmat2, BOOL bIgnoreRotation)
 
static FT_BitmapGlyph IntGetRealGlyph (IN OUT PFONT_CACHE_ENTRY Cache)
 
BOOL FASTCALL TextIntGetTextExtentPoint (_In_ PDC dc, _In_ PTEXTOBJ TextObj, _In_reads_(Count) PCWCH String, _In_ INT Count, _In_ ULONG MaxExtent, _Out_ PINT Fit, _Out_writes_to_opt_(Count, *Fit) PINT Dx, _Out_ PSIZE Size, _In_ FLONG fl)
 
INT FASTCALL ftGdiGetTextCharsetInfo (PDC Dc, LPFONTSIGNATURE lpSig, DWORD dwFlags)
 
DWORD FASTCALL ftGetFontUnicodeRanges (PFONTGDI Font, PGLYPHSET glyphset)
 
BOOL FASTCALL ftGdiGetTextMetricsW (HDC hDC, PTMW_INTERNAL ptmwi)
 
DWORD FASTCALL ftGdiGetFontData (PFONTGDI FontGdi, DWORD Table, DWORD Offset, PVOID Buffer, DWORD Size)
 
static UINT GetFontPenalty (const LOGFONTW *LogFont, const OUTLINETEXTMETRICW *Otm, const char *style_name)
 
static VOID FASTCALL IntFontType (PFONTGDI Font)
 
static BOOL MatchFontName (PSHARED_FACE SharedFace, PUNICODE_STRING Name1, FT_UShort NameID, FT_UShort LangID)
 
static BOOL MatchFontNames (PSHARED_FACE SharedFace, LPCWSTR lfFaceName)
 
static void IntPopulateTextObj (PTEXTOBJ TextObj, PFONTGDI FontGdi, FONTOBJ *pFontObj, const LOGFONTW *pLogFont, PLOGFONTW SubstitutedLogFont)
 
static void IntPopulateFontGdi (PFONTGDI FontGdi, const FONTOBJ *pFontObj, const LOGFONTW *pLogFont)
 
static PFONT_LOOKUP_CACHE FontLookUp_LookUp (const LOGFONTW *pLogFont)
 
static void FontLookUp_Add (const LOGFONTW *LogFont, PSHARED_FACE SharedFace, FONTOBJ *pFontObj)
 
NTSTATUS FASTCALL TextIntRealizeFont (HFONT FontHandle, PTEXTOBJ pTextObj)
 
static BOOL FASTCALL IntGetFullFileName (POBJECT_NAME_INFORMATION NameInfo, ULONG Size, PUNICODE_STRING FileName)
 
static BOOL EqualFamilyInfo (const FONTFAMILYINFO *pInfo1, const FONTFAMILYINFO *pInfo2)
 
static VOID IntAddNameFromFamInfo (LPWSTR psz, FONTFAMILYINFO *FamInfo)
 
BOOL FASTCALL IntGdiGetFontResourceInfo (PUNICODE_STRING FileName, PVOID pBuffer, DWORD *pdwBytes, DWORD dwType)
 
BOOL FASTCALL ftGdiRealizationInfo (PFONTGDI Font, PREALIZATION_INFO Info)
 
DWORD FASTCALL ftGdiGetKerningPairs (PFONTGDI Font, DWORD cPairs, LPKERNINGPAIR pKerningPair)
 
LONG FASTCALL IntGetFontFamilyInfo (HDC Dc, const LOGFONTW *SafeLogFont, PFONTFAMILYINFO SafeInfo, LONG InfoCount)
 
LONG NTAPI NtGdiGetFontFamilyInfo (_In_ HDC Dc, _In_ const LOGFONTW *UnsafeLogFont, _Out_ PFONTFAMILYINFO UnsafeInfo, _Inout_ PLONG UnsafeInfoCount)
 
static BOOL IntGetTextDisposition (_Out_ LONGLONG *pX64, _Out_ LONGLONG *pY64, _In_reads_(Count) PCWCH String, _In_ INT Count, _In_opt_ const INT *Dx, _Inout_ PFONT_CACHE_ENTRY Cache, _In_ UINT fuOptions, _In_ BOOL bNoTransform, _Inout_ PFONTLINK_CHAIN pChain)
 
BOOL APIENTRY IntExtTextOutW (_In_ PDC dc, _In_ INT XStart, _In_ INT YStart, _In_ UINT fuOptions, _In_opt_ PRECTL lprc, _In_reads_opt_(Count) PCWCH String, _In_ INT Count, _In_opt_ const INT *Dx, _In_ DWORD dwCodePage)
 
BOOL APIENTRY GreExtTextOutW (_In_ HDC hDC, _In_ INT XStart, _In_ INT YStart, _In_ UINT fuOptions, _In_opt_ PRECTL lprc, _In_reads_opt_(Count) PCWCH String, _In_ INT Count, _In_opt_ const INT *Dx, _In_ DWORD dwCodePage)
 
BOOL APIENTRY NtGdiExtTextOutW (_In_ HDC hDC, _In_ INT XStart, _In_ INT YStart, _In_ UINT fuOptions, _In_opt_ LPCRECT UnsafeRect, _In_reads_opt_(Count) PCWCH UnsafeString, _In_range_(0, 0xFFFF) UINT Count, _In_reads_opt_(_Inexpressible_(cwc)) const INT *UnsafeDx, _In_ DWORD dwCodePage)
 
static BOOL FASTCALL IntSelectFaceCharmap (FT_Face face)
 
BOOL APIENTRY GreGetCharABCWidthsW (_In_ HDC hDC, _In_ UINT FirstChar, _In_ UINT Count, _In_reads_opt_(Count) PCWCH Safepwch, _In_ FLONG fl, _Out_writes_bytes_(Count *sizeof(ABC)) PVOID SafeBuffer)
 
BOOL APIENTRY GreGetCharWidthW (_In_ HDC hDC, _In_ UINT FirstChar, _In_ UINT Count, _In_reads_opt_(Count) PCWCH Safepwc, _In_ FLONG fl, _Out_writes_bytes_(Count *sizeof(INT)) PVOID Buffer)
 
static BOOL IntGetFontDefaultChar (_In_ FT_Face Face, _Out_ PWCHAR pDefChar)
 
__kernel_entry W32KAPI DWORD APIENTRY NtGdiGetGlyphIndicesW (_In_ HDC hdc, _In_reads_opt_(cwc) PCWCH pwc, _In_ INT cwc, _Out_writes_opt_(cwc) PWORD pgi, _In_ DWORD iMode)
 

Variables

static DWORD s_chFontLinkDefaultChar = FONTLINK_DEFAULT_CHAR
 
static WCHAR s_szDefFontLinkFileName [MAX_PATH] = L""
 
static WCHAR s_szDefFontLinkFontName [MAX_PATH] = L""
 
static BOOL s_fFontLinkUseAnsi = FALSE
 
static BOOL s_fFontLinkUseOem = FALSE
 
static BOOL s_fFontLinkUseSymbol = FALSE
 
static LONG g_nFontLinkCacheCount = 0
 
static ULONG s_FontLookupCacheCount = 0
 
const MATRIX gmxWorldToDeviceDefault
 
const MATRIX gmxWorldToPageDefault
 
static const FT_Matrix identityMat = {(1 << 16), 0, 0, (1 << 16)}
 
FT_Library g_FreeTypeLibrary
 
UNICODE_STRING g_FontRegPath
 
static PFAST_MUTEX g_FreeTypeLock
 
static BOOL g_RenderingEnabled = TRUE
 
static UINT g_FontCacheNumEntries
 
static PWCHAR g_ElfScripts [32]
 
static const CHARSETINFO g_FontTci [MAXTCIINDEX]
 
static const WCHAR s_szzDefFontLink []
 
static const WCHAR s_szzDefFixedFontLink []
 
static const UNICODE_STRING DosPathPrefix = RTL_CONSTANT_STRING(L"\\??\\")
 

Macro Definition Documentation

◆ _TMPF_VARIABLE_PITCH

#define _TMPF_VARIABLE_PITCH   TMPF_FIXED_PITCH

Definition at line 304 of file freetype.c.

◆ ASSERT_FREETYPE_LOCK_HELD

#define ASSERT_FREETYPE_LOCK_HELD ( )     ASSERT(g_FreeTypeLock->Owner == KeGetCurrentThread())

Definition at line 331 of file freetype.c.

◆ ASSERT_FREETYPE_LOCK_NOT_HELD

#define ASSERT_FREETYPE_LOCK_NOT_HELD ( )     ASSERT(g_FreeTypeLock->Owner != KeGetCurrentThread())

Definition at line 334 of file freetype.c.

◆ CP_MACCP

#define CP_MACCP   2

Definition at line 425 of file freetype.c.

◆ CP_OEMCP

#define CP_OEMCP   1

Definition at line 424 of file freetype.c.

◆ CP_SYMBOL

#define CP_SYMBOL   42

Definition at line 380 of file freetype.c.

◆ EMUBOLD_NEEDED

#define EMUBOLD_NEEDED (   original,
  request 
)     (((request) != FW_DONTCARE) && ((request) - (original) >= FW_BOLD - FW_MEDIUM))

Definition at line 308 of file freetype.c.

◆ FM_SEL_USE_TYPO_METRICS

#define FM_SEL_USE_TYPO_METRICS   0x80

◆ FONTLINK_DEFAULT_CHAR

#define FONTLINK_DEFAULT_CHAR   0x30FB

Definition at line 58 of file freetype.c.

◆ gmxWorldToDeviceDefault

#define gmxWorldToDeviceDefault   gmxWorldToPageDefault

Definition at line 316 of file freetype.c.

◆ GOT_PENALTY

#define GOT_PENALTY (   name,
  value 
)    Penalty += (value)

Definition at line 5401 of file freetype.c.

◆ IntLockFreeType

#define IntLockFreeType ( )
Value:
do { \
ASSERT_FREETYPE_LOCK_NOT_HELD(); \
ExEnterCriticalRegionAndAcquireFastMutexUnsafe(g_FreeTypeLock); \
} while (0)
static PFAST_MUTEX g_FreeTypeLock
Definition: freetype.c:326

Definition at line 337 of file freetype.c.

◆ IntUnLockFreeType

#define IntUnLockFreeType ( )
Value:
do { \
ASSERT_FREETYPE_LOCK_HELD(); \
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(g_FreeTypeLock); \
} while(0)

Definition at line 343 of file freetype.c.

◆ MAX_FONT_CACHE

#define MAX_FONT_CACHE   256

Definition at line 349 of file freetype.c.

◆ MAX_FONT_LOOKUP_CACHE

#define MAX_FONT_LOOKUP_CACHE   64

Definition at line 299 of file freetype.c.

◆ MAX_FONTLINK_CACHE

#define MAX_FONTLINK_CACHE   128

Definition at line 67 of file freetype.c.

◆ MAXTCIINDEX

#define MAXTCIINDEX   32

Definition at line 381 of file freetype.c.

◆ NDEBUG

#define NDEBUG

Definition at line 30 of file freetype.c.

◆ PX2PT

#define PX2PT (   pixels)    FT_MulDiv((pixels), 72, 96)

Definition at line 1646 of file freetype.c.

◆ SCALE_X

#define SCALE_X (   value)    ((FT_MulFix((value), XScale) + 32) >> 6)

◆ SCALE_Y

#define SCALE_Y (   value)    ((FT_MulFix((value), YScale) + 32) >> 6)

◆ STACK_TEXT_BUFFER_SIZE

#define STACK_TEXT_BUFFER_SIZE   512

Definition at line 7329 of file freetype.c.

◆ VALIGN_MASK

#define VALIGN_MASK   (TA_TOP | TA_BASELINE | TA_BOTTOM)

Typedef Documentation

◆ FONT_LOOKUP_CACHE

◆ FONT_NAMES

◆ FONTLINK

◆ FONTLINK_CACHE

◆ FONTLINK_CHAIN

◆ LPFONT_NAMES

◆ PFONT_LOOKUP_CACHE

◆ PFONTLINK

◆ PFONTLINK_CACHE

◆ PFONTLINK_CHAIN

Function Documentation

◆ CleanupFontEntry()

static __inline VOID FASTCALL CleanupFontEntry ( PFONT_ENTRY  FontEntry)
static

Definition at line 653 of file freetype.c.

654{
655 CleanupFontEntryEx(FontEntry, FontEntry->Font);
656}
static VOID FASTCALL CleanupFontEntryEx(PFONT_ENTRY FontEntry, PFONTGDI FontGDI)
Definition: freetype.c:633
FONTGDI * Font
Definition: font.h:7

Referenced by FreeFontSupport(), IntGdiCleanupMemEntry(), IntGdiCleanupPrivateFontsForProcess(), and IntGdiRemoveFontResourceSingle().

◆ CleanupFontEntryEx()

static VOID FASTCALL CleanupFontEntryEx ( PFONT_ENTRY  FontEntry,
PFONTGDI  FontGDI 
)
static

Definition at line 633 of file freetype.c.

634{
635 // PFONTGDI FontGDI = FontEntry->Font;
636 PSHARED_FACE SharedFace = FontGDI->SharedFace;
637
638 if (FontGDI->Filename)
640
641 if (FontEntry->StyleName.Buffer)
642 RtlFreeUnicodeString(&FontEntry->StyleName);
643
644 if (FontEntry->FaceName.Buffer)
645 RtlFreeUnicodeString(&FontEntry->FaceName);
646
647 EngFreeMem(FontGDI);
648 SharedFace_Release(SharedFace, TRUE);
649 ExFreePoolWithTag(FontEntry, TAG_FONT);
650}
#define TRUE
Definition: types.h:120
static void SharedFace_Release(PSHARED_FACE Ptr, BOOL bDoLock)
Definition: freetype.c:605
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define EngFreeMem
Definition: polytest.cpp:56
LPWSTR Filename
Definition: engobjects.h:151
PSHARED_FACE SharedFace
Definition: engobjects.h:145
UNICODE_STRING StyleName
Definition: font.h:9
UNICODE_STRING FaceName
Definition: font.h:8
#define TAG_FONT
Definition: tags.h:12
#define GDITAG_PFF
Definition: tags.h:149

Referenced by CleanupFontEntry().

◆ EqualFamilyInfo()

static BOOL EqualFamilyInfo ( const FONTFAMILYINFO pInfo1,
const FONTFAMILYINFO pInfo2 
)
static

Definition at line 6143 of file freetype.c.

6144{
6145 const ENUMLOGFONTEXW *pLog1 = &pInfo1->EnumLogFontEx;
6146 const ENUMLOGFONTEXW *pLog2 = &pInfo2->EnumLogFontEx;
6147 const LOGFONTW *plf1 = &pLog1->elfLogFont;
6148 const LOGFONTW *plf2 = &pLog2->elfLogFont;
6149
6150 if (_wcsicmp(plf1->lfFaceName, plf2->lfFaceName) != 0)
6151 {
6152 return FALSE;
6153 }
6154
6155 if (_wcsicmp(pLog1->elfStyle, pLog2->elfStyle) != 0)
6156 {
6157 return FALSE;
6158 }
6159
6160 return TRUE;
6161}
#define FALSE
Definition: types.h:117
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:159
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
WCHAR elfStyle[LF_FACESIZE]
Definition: wingdi.h:3150
LOGFONTW elfLogFont
Definition: wingdi.h:3148
ENUMLOGFONTEXW EnumLogFontEx
Definition: ntgdibad.h:47

Referenced by IntGdiGetFontResourceInfo().

◆ face_has_symbol_charmap()

static BOOL face_has_symbol_charmap ( FT_Face  ft_face)
static

Definition at line 2821 of file freetype.c.

2822{
2823 int i;
2824
2825 for(i = 0; i < ft_face->num_charmaps; i++)
2826 {
2827 if (ft_face->charmaps[i]->platform_id == TT_PLATFORM_MICROSOFT &&
2828 ft_face->charmaps[i]->encoding == FT_ENCODING_MS_SYMBOL)
2829 {
2830 return TRUE;
2831 }
2832 }
2833 return FALSE;
2834}
#define TT_PLATFORM_MICROSOFT
Definition: font.c:1174
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FT_Encoding encoding
Definition: freetype.h:820
FT_UShort platform_id
Definition: freetype.h:821
FT_Int num_charmaps
Definition: freetype.h:1044
FT_CharMap * charmaps
Definition: freetype.h:1045

Referenced by FillTM(), and get_glyph_index().

◆ FillTM()

static void FASTCALL FillTM ( TEXTMETRICW TM,
PFONTGDI  FontGDI,
TT_OS2 pOS2,
TT_HoriHeader pHori,
FT_WinFNT_HeaderRec pFNT 
)
static

Definition at line 2837 of file freetype.c.

2840{
2841 FT_Fixed XScale, YScale;
2842 int Ascent, Descent;
2843 FT_Face Face = FontGDI->SharedFace->Face;
2844
2846
2847 XScale = Face->size->metrics.x_scale;
2848 YScale = Face->size->metrics.y_scale;
2849
2850 if (pFNT)
2851 {
2852 TM->tmHeight = pFNT->pixel_height;
2853 TM->tmAscent = pFNT->ascent;
2854 TM->tmDescent = TM->tmHeight - TM->tmAscent;
2857 TM->tmAveCharWidth = pFNT->avg_width;
2858 TM->tmMaxCharWidth = pFNT->max_width;
2859 TM->tmOverhang = 0;
2862 TM->tmFirstChar = pFNT->first_char;
2863 TM->tmLastChar = pFNT->last_char;
2864 TM->tmDefaultChar = pFNT->default_char + pFNT->first_char;
2865 TM->tmBreakChar = pFNT->break_char + pFNT->first_char;
2867 TM->tmWeight = FontGDI->RequestWeight;
2868 TM->tmItalic = FontGDI->RequestItalic;
2869 TM->tmUnderlined = FontGDI->RequestUnderline;
2870 TM->tmStruckOut = FontGDI->RequestStrikeOut;
2871 TM->tmCharSet = FontGDI->CharSet;
2872 return;
2873 }
2874
2875 ASSERT(pOS2);
2876 if (!pOS2)
2877 return;
2878
2879 if ((FT_Short)pOS2->usWinAscent + (FT_Short)pOS2->usWinDescent == 0)
2880 {
2881 Ascent = pHori->Ascender;
2882 Descent = -pHori->Descender;
2883 }
2884 else
2885 {
2886 Ascent = (FT_Short)pOS2->usWinAscent;
2887 Descent = (FT_Short)pOS2->usWinDescent;
2888 }
2889
2890 TM->tmAscent = FontGDI->tmAscent;
2891 TM->tmDescent = FontGDI->tmDescent;
2892 TM->tmHeight = TM->tmAscent + TM->tmDescent;
2893 TM->tmInternalLeading = FontGDI->tmInternalLeading;
2894
2895 /* MSDN says:
2896 * el = MAX(0, LineGap - ((WinAscent + WinDescent) - (Ascender - Descender)))
2897 */
2898 TM->tmExternalLeading = max(0, (FT_MulFix(pHori->Line_Gap
2899 - ((Ascent + Descent)
2900 - (pHori->Ascender - pHori->Descender)),
2901 YScale) + 32) >> 6);
2902 if (FontGDI->lfWidth != 0)
2903 TM->tmAveCharWidth = FontGDI->lfWidth;
2904 else
2905 TM->tmAveCharWidth = (FT_MulFix(pOS2->xAvgCharWidth, XScale) + 32) >> 6;
2906
2907 if (TM->tmAveCharWidth == 0)
2908 TM->tmAveCharWidth = 1;
2909
2910 /* Correct forumla to get the maxcharwidth from unicode and ansi font */
2911 TM->tmMaxCharWidth = (FT_MulFix(Face->max_advance_width, XScale) + 32) >> 6;
2912
2913 if (FontGDI->OriginalWeight != FW_DONTCARE &&
2914 FontGDI->OriginalWeight > FontGDI->RequestWeight)
2915 {
2916 TM->tmWeight = FontGDI->OriginalWeight;
2917 }
2918 else
2919 {
2920 TM->tmWeight = FontGDI->RequestWeight;
2921 }
2922
2923 TM->tmOverhang = 0;
2924 TM->tmDigitizedAspectX = 96;
2925 TM->tmDigitizedAspectY = 96;
2926 if (face_has_symbol_charmap(Face) ||
2927 (pOS2->usFirstCharIndex >= 0xf000 && pOS2->usFirstCharIndex < 0xf100))
2928 {
2929 USHORT cpOEM, cpAnsi;
2930
2931 EngGetCurrentCodePage(&cpOEM, &cpAnsi);
2932 TM->tmFirstChar = 0;
2933 switch(cpAnsi)
2934 {
2935 case 1257: /* Baltic */
2936 TM->tmLastChar = 0xf8fd;
2937 break;
2938 default:
2939 TM->tmLastChar = 0xf0ff;
2940 }
2941 TM->tmBreakChar = 0x20;
2942 TM->tmDefaultChar = 0x1f;
2943 }
2944 else
2945 {
2946 TM->tmFirstChar = pOS2->usFirstCharIndex; /* Should be the first char in the cmap */
2947 TM->tmLastChar = pOS2->usLastCharIndex; /* Should be min(cmap_last, os2_last) */
2948
2949 if(pOS2->usFirstCharIndex <= 1)
2950 TM->tmBreakChar = pOS2->usFirstCharIndex + 2;
2951 else if (pOS2->usFirstCharIndex > 0xff)
2952 TM->tmBreakChar = 0x20;
2953 else
2954 TM->tmBreakChar = pOS2->usFirstCharIndex;
2955 TM->tmDefaultChar = TM->tmBreakChar - 1;
2956 }
2957
2958 if (FontGDI->OriginalItalic || FontGDI->RequestItalic)
2959 {
2960 TM->tmItalic = 0xFF;
2961 }
2962 else
2963 {
2964 TM->tmItalic = 0;
2965 }
2966 TM->tmUnderlined = (FontGDI->RequestUnderline ? 0xFF : 0);
2967 TM->tmStruckOut = (FontGDI->RequestStrikeOut ? 0xFF : 0);
2968
2969 if (!FT_IS_FIXED_WIDTH(Face))
2970 {
2971 switch (pOS2->panose[PAN_PROPORTION_INDEX])
2972 {
2974 TM->tmPitchAndFamily = 0;
2975 break;
2976 default:
2978 break;
2979 }
2980 }
2981 else
2982 {
2983 TM->tmPitchAndFamily = 0;
2984 }
2985
2986 switch (pOS2->panose[PAN_FAMILYTYPE_INDEX])
2987 {
2988 case PAN_FAMILY_SCRIPT:
2990 break;
2993 break;
2994
2995 case PAN_ANY:
2996 case PAN_NO_FIT:
2998 case PAN_FAMILY_PICTORIAL: /* Symbol fonts get treated as if they were text */
2999 /* Which is clearly not what the panose spec says. */
3000 if (TM->tmPitchAndFamily == 0) /* Fixed */
3001 {
3003 }
3004 else
3005 {
3006 switch (pOS2->panose[PAN_SERIFSTYLE_INDEX])
3007 {
3008 case PAN_ANY:
3009 case PAN_NO_FIT:
3010 default:
3012 break;
3013
3014 case PAN_SERIF_COVE:
3018 case PAN_SERIF_SQUARE:
3019 case PAN_SERIF_THIN:
3020 case PAN_SERIF_BONE:
3022 case PAN_SERIF_TRIANGLE:
3024 break;
3025
3029 case PAN_SERIF_FLARED:
3030 case PAN_SERIF_ROUNDED:
3032 break;
3033 }
3034 }
3035 break;
3036 default:
3038 }
3039
3040 if (FT_IS_SCALABLE(Face))
3041 {
3043 }
3044 if (FT_IS_SFNT(Face))
3045 {
3047 }
3048
3049 TM->tmCharSet = FontGDI->CharSet;
3050}
static BOOL face_has_symbol_charmap(FT_Face ft_face)
Definition: freetype.c:2821
#define ASSERT_FREETYPE_LOCK_HELD()
Definition: freetype.c:331
#define _TMPF_VARIABLE_PITCH
Definition: freetype.c:304
#define FT_IS_SFNT(face)
Definition: freetype.h:1290
#define FT_IS_SCALABLE(face)
Definition: freetype.h:1271
#define FT_IS_FIXED_WIDTH(face)
Definition: freetype.h:1305
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:508
signed long FT_Fixed
Definition: fttypes.h:287
signed short FT_Short
Definition: fttypes.h:198
#define ASSERT(a)
Definition: mode.c:44
unsigned short USHORT
Definition: pedump.c:61
FT_Size size
Definition: freetype.h:1066
FT_Short max_advance_width
Definition: freetype.h:1059
FT_Size_Metrics metrics
Definition: freetype.h:1636
FT_Fixed y_scale
Definition: freetype.h:1601
FT_Fixed x_scale
Definition: freetype.h:1600
FT_UShort horizontal_resolution
Definition: ftwinfnt.h:191
FT_Byte pitch_and_family
Definition: ftwinfnt.h:202
FT_Byte default_char
Definition: ftwinfnt.h:207
FT_UShort internal_leading
Definition: ftwinfnt.h:193
FT_UShort avg_width
Definition: ftwinfnt.h:203
FT_UShort external_leading
Definition: ftwinfnt.h:194
FT_UShort ascent
Definition: ftwinfnt.h:192
FT_UShort max_width
Definition: ftwinfnt.h:204
FT_UShort pixel_height
Definition: ftwinfnt.h:201
FT_UShort vertical_resolution
Definition: ftwinfnt.h:190
FT_Short Line_Gap
Definition: tttables.h:205
FT_Short Ascender
Definition: tttables.h:203
FT_Short Descender
Definition: tttables.h:204
FT_UShort usLastCharIndex
Definition: tttables.h:405
FT_Byte panose[10]
Definition: tttables.h:394
FT_UShort usWinDescent
Definition: tttables.h:410
FT_UShort usWinAscent
Definition: tttables.h:409
FT_Short xAvgCharWidth
Definition: tttables.h:378
FT_UShort usFirstCharIndex
Definition: tttables.h:404
LONG tmInternalLeading
Definition: engobjects.h:164
BYTE RequestItalic
Definition: engobjects.h:154
LONG RequestWeight
Definition: engobjects.h:155
LONG lfWidth
Definition: engobjects.h:167
LONG tmAscent
Definition: engobjects.h:162
BYTE RequestStrikeOut
Definition: engobjects.h:153
LONG tmDescent
Definition: engobjects.h:163
BYTE OriginalItalic
Definition: engobjects.h:156
BYTE CharSet
Definition: engobjects.h:158
LONG OriginalWeight
Definition: engobjects.h:157
BYTE RequestUnderline
Definition: engobjects.h:152
FT_Face Face
Definition: engobjects.h:132
WCHAR tmFirstChar
Definition: wingdi.h:2840
LONG tmDigitizedAspectX
Definition: wingdi.h:2838
LONG tmDigitizedAspectY
Definition: wingdi.h:2839
LONG tmOverhang
Definition: wingdi.h:2837
LONG tmAveCharWidth
Definition: wingdi.h:2834
LONG tmAscent
Definition: wingdi.h:2830
LONG tmMaxCharWidth
Definition: wingdi.h:2835
BYTE tmItalic
Definition: wingdi.h:2844
BYTE tmStruckOut
Definition: wingdi.h:2846
LONG tmInternalLeading
Definition: wingdi.h:2832
BYTE tmUnderlined
Definition: wingdi.h:2845
LONG tmExternalLeading
Definition: wingdi.h:2833
BYTE tmPitchAndFamily
Definition: wingdi.h:2847
LONG tmWeight
Definition: wingdi.h:2836
WCHAR tmBreakChar
Definition: wingdi.h:2843
WCHAR tmDefaultChar
Definition: wingdi.h:2842
BYTE tmCharSet
Definition: wingdi.h:2848
WCHAR tmLastChar
Definition: wingdi.h:2841
LONG tmHeight
Definition: wingdi.h:2829
LONG tmDescent
Definition: wingdi.h:2831
#define max(a, b)
Definition: svc.c:63
ENGAPI VOID APIENTRY EngGetCurrentCodePage(_Out_ PUSHORT OemCodePage, _Out_ PUSHORT AnsiCodePage)
Definition: engmisc.c:232
#define PAN_SERIF_THIN
Definition: wingdi.h:476
#define PAN_FAMILY_TEXT_DISPLAY
Definition: wingdi.h:467
#define PAN_PROP_MONOSPACED
Definition: wingdi.h:502
#define FW_DONTCARE
Definition: wingdi.h:368
#define PAN_SERIFSTYLE_INDEX
Definition: wingdi.h:455
#define FF_MODERN
Definition: wingdi.h:449
#define FF_DECORATIVE
Definition: wingdi.h:447
#define PAN_SERIF_NORMAL_SANS
Definition: wingdi.h:480
#define FF_SCRIPT
Definition: wingdi.h:451
#define PAN_SERIF_BONE
Definition: wingdi.h:477
#define FF_ROMAN
Definition: wingdi.h:450
#define PAN_SERIF_OBTUSE_SANS
Definition: wingdi.h:481
#define PAN_FAMILY_PICTORIAL
Definition: wingdi.h:470
#define FF_DONTCARE
Definition: wingdi.h:448
#define PAN_SERIF_TRIANGLE
Definition: wingdi.h:479
#define TMPF_TRUETYPE
Definition: wingdi.h:1313
#define PAN_PROPORTION_INDEX
Definition: wingdi.h:457
#define PAN_NO_FIT
Definition: wingdi.h:466
#define PAN_SERIF_SQUARE_COVE
Definition: wingdi.h:473
#define PAN_SERIF_SQUARE
Definition: wingdi.h:475
#define PAN_SERIF_OBTUSE_SQUARE_COVE
Definition: wingdi.h:474
#define PAN_SERIF_COVE
Definition: wingdi.h:471
#define TMPF_VECTOR
Definition: wingdi.h:1312
#define PAN_SERIF_EXAGGERATED
Definition: wingdi.h:478
#define PAN_SERIF_ROUNDED
Definition: wingdi.h:484
#define PAN_FAMILYTYPE_INDEX
Definition: wingdi.h:454
#define PAN_FAMILY_DECORATIVE
Definition: wingdi.h:469
#define PAN_SERIF_PERP_SANS
Definition: wingdi.h:482
#define PAN_SERIF_FLARED
Definition: wingdi.h:483
#define PAN_FAMILY_SCRIPT
Definition: wingdi.h:468
#define PAN_SERIF_OBTUSE_COVE
Definition: wingdi.h:472
#define PAN_ANY
Definition: wingdi.h:465
#define FF_SWISS
Definition: wingdi.h:452

Referenced by ftGdiGetTextMetricsW(), and IntGetOutlineTextMetrics().

◆ FindBestFontFromList()

static __inline VOID FindBestFontFromList ( FONTOBJ **  FontObj,
ULONG MatchPenalty,
const LOGFONTW LogFont,
const PLIST_ENTRY  Head 
)
static

Definition at line 5751 of file freetype.c.

5754{
5755 ULONG Penalty;
5757 PFONT_ENTRY CurrentEntry;
5758 FONTGDI *FontGDI;
5759 OUTLINETEXTMETRICW *Otm = NULL;
5760 UINT OtmSize, OldOtmSize = 0;
5761 FT_Face Face;
5762
5763 ASSERT(FontObj);
5764 ASSERT(MatchPenalty);
5765 ASSERT(LogFont);
5766 ASSERT(Head);
5767
5768 /* Start with a pretty big buffer */
5769 OldOtmSize = 0x200;
5770 Otm = ExAllocatePoolWithTag(PagedPool, OldOtmSize, GDITAG_TEXT);
5771
5772 /* get the FontObj of lowest penalty */
5773 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
5774 {
5775 CurrentEntry = CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry);
5776
5777 FontGDI = CurrentEntry->Font;
5778 ASSERT(FontGDI);
5779 Face = FontGDI->SharedFace->Face;
5780
5781 /* get text metrics */
5783 OtmSize = IntGetOutlineTextMetrics(FontGDI, 0, NULL, TRUE);
5784 if (OtmSize > OldOtmSize)
5785 {
5786 if (Otm)
5789 }
5790
5791 /* update FontObj if lowest penalty */
5792 if (Otm)
5793 {
5795 IntRequestFontSize(NULL, FontGDI, LogFont->lfWidth, LogFont->lfHeight);
5796
5798 OtmSize = IntGetOutlineTextMetrics(FontGDI, OtmSize, Otm, TRUE);
5799 if (!OtmSize)
5800 continue;
5801
5802 OldOtmSize = OtmSize;
5803
5804 Penalty = GetFontPenalty(LogFont, Otm, Face->style_name);
5805 if (*MatchPenalty == MAXULONG || Penalty < *MatchPenalty)
5806 {
5807 *FontObj = GDIToObj(FontGDI, FONT);
5808 *MatchPenalty = Penalty;
5809 }
5810 }
5811 }
5812
5813 if (Otm)
5815}
#define NULL
Definition: types.h:112
#define GDIToObj(ClipGDI, Type)
Definition: engobjects.h:185
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
static UINT GetFontPenalty(const LOGFONTW *LogFont, const OUTLINETEXTMETRICW *Otm, const char *style_name)
Definition: freetype.c:5405
static FT_Error IntRequestFontSize(PDC dc, PFONTGDI FontGDI, LONG lfWidth, LONG lfHeight)
Definition: freetype.c:4080
INT FASTCALL IntGetOutlineTextMetrics(PFONTGDI FontGDI, UINT Size, OUTLINETEXTMETRICW *Otm, BOOL bLocked)
Definition: freetype.c:3139
unsigned int UINT
Definition: ndis.h:50
base of all file and directory entries
Definition: entries.h:83
FT_String * style_name
Definition: freetype.h:1039
LONG lfHeight
Definition: dimm.idl:59
LONG lfWidth
Definition: dimm.idl:60
Definition: font.h:5
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define MAXULONG
Definition: typedefs.h:251
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define GDITAG_TEXT
Definition: tags.h:172

Referenced by IntRealizeFont().

◆ FontFamilyFillInfo()

static void FASTCALL FontFamilyFillInfo ( PFONTFAMILYINFO  Info,
LPCWSTR  FaceName,
LPCWSTR  FullName,
PFONTGDI  FontGDI 
)
static

Definition at line 3443 of file freetype.c.

3445{
3446 ANSI_STRING StyleA;
3447 UNICODE_STRING StyleW;
3448 TT_OS2 *pOS2;
3450 CHARSETINFO CharSetInfo;
3451 unsigned i, Size;
3452 OUTLINETEXTMETRICW *Otm;
3453 LOGFONTW *Lf;
3454 TEXTMETRICW *TM;
3455 NEWTEXTMETRICW *Ntm;
3456 DWORD fs0;
3458 PSHARED_FACE SharedFace = FontGDI->SharedFace;
3459 FT_Face Face = SharedFace->Face;
3460 UNICODE_STRING NameW;
3461
3462 RtlInitUnicodeString(&NameW, NULL);
3465 Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL, TRUE);
3466 if (!Size)
3467 return;
3469 if (!Otm)
3470 return;
3472 Size = IntGetOutlineTextMetrics(FontGDI, Size, Otm, TRUE);
3473 if (!Size)
3474 {
3476 return;
3477 }
3478
3479 Lf = &Info->EnumLogFontEx.elfLogFont;
3480 TM = &Otm->otmTextMetrics;
3481
3482 Lf->lfHeight = TM->tmHeight;
3483 Lf->lfWidth = TM->tmAveCharWidth;
3484 Lf->lfWeight = TM->tmWeight;
3485 Lf->lfItalic = TM->tmItalic;
3486 Lf->lfPitchAndFamily = (TM->tmPitchAndFamily & 0xf1) + 1;
3487 Lf->lfCharSet = TM->tmCharSet;
3491
3492 Ntm = &Info->NewTextMetricEx.ntmTm;
3493 Ntm->tmHeight = TM->tmHeight;
3494 Ntm->tmAscent = TM->tmAscent;
3495 Ntm->tmDescent = TM->tmDescent;
3498 Ntm->tmAveCharWidth = TM->tmAveCharWidth;
3499 Ntm->tmMaxCharWidth = TM->tmMaxCharWidth;
3500 Ntm->tmWeight = TM->tmWeight;
3501 Ntm->tmOverhang = TM->tmOverhang;
3504 Ntm->tmFirstChar = TM->tmFirstChar;
3505 Ntm->tmLastChar = TM->tmLastChar;
3506 Ntm->tmDefaultChar = TM->tmDefaultChar;
3507 Ntm->tmBreakChar = TM->tmBreakChar;
3508 Ntm->tmItalic = TM->tmItalic;
3509 Ntm->tmUnderlined = TM->tmUnderlined;
3510 Ntm->tmStruckOut = TM->tmStruckOut;
3512 Ntm->tmCharSet = TM->tmCharSet;
3513 Ntm->ntmFlags = TM->tmItalic ? NTM_ITALIC : 0;
3514
3515 if (550 < TM->tmWeight) Ntm->ntmFlags |= NTM_BOLD;
3516
3517 if (0 == Ntm->ntmFlags) Ntm->ntmFlags = NTM_REGULAR;
3518
3519 Info->FontType = (0 != (TM->tmPitchAndFamily & TMPF_TRUETYPE)
3520 ? TRUETYPE_FONTTYPE : 0);
3521
3522 if (0 == (TM->tmPitchAndFamily & TMPF_VECTOR))
3523 Info->FontType |= RASTER_FONTTYPE;
3524
3525
3526 /* face name */
3527 if (!FaceName)
3528 FaceName = (WCHAR*)((ULONG_PTR)Otm + (ULONG_PTR)Otm->otmpFamilyName);
3529
3530 RtlStringCbCopyW(Lf->lfFaceName, sizeof(Lf->lfFaceName), FaceName);
3531
3532 /* full name */
3533 if (!FullName)
3534 FullName = (WCHAR*)((ULONG_PTR) Otm + (ULONG_PTR)Otm->otmpFaceName);
3535
3536 RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
3537 sizeof(Info->EnumLogFontEx.elfFullName),
3538 FullName);
3539
3540 RtlInitAnsiString(&StyleA, Face->style_name);
3541 StyleW.Buffer = Info->EnumLogFontEx.elfStyle;
3542 StyleW.MaximumLength = sizeof(Info->EnumLogFontEx.elfStyle);
3543 status = RtlAnsiStringToUnicodeString(&StyleW, &StyleA, FALSE);
3544 if (!NT_SUCCESS(status))
3545 {
3547 return;
3548 }
3549 Info->EnumLogFontEx.elfScript[0] = UNICODE_NULL;
3550
3551 pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
3552
3553 if (!pOS2)
3554 {
3556 return;
3557 }
3558
3559 Ntm->ntmSizeEM = Otm->otmEMSquare;
3561 Ntm->ntmAvgWidth = 0;
3562
3564
3565 fs.fsCsb[0] = pOS2->ulCodePageRange1;
3566 fs.fsCsb[1] = pOS2->ulCodePageRange2;
3567 fs.fsUsb[0] = pOS2->ulUnicodeRange1;
3568 fs.fsUsb[1] = pOS2->ulUnicodeRange2;
3569 fs.fsUsb[2] = pOS2->ulUnicodeRange3;
3570 fs.fsUsb[3] = pOS2->ulUnicodeRange4;
3571
3572 if (0 == pOS2->version)
3573 {
3574 FT_UInt Dummy;
3575
3576 if (FT_Get_First_Char(Face, &Dummy) < 0x100)
3577 fs.fsCsb[0] |= FS_LATIN1;
3578 else
3579 fs.fsCsb[0] |= FS_SYMBOL;
3580 }
3581
3582 if (fs.fsCsb[0] == 0)
3583 {
3584 /* Let's see if we can find any interesting cmaps */
3585 for (i = 0; i < (UINT)Face->num_charmaps; i++)
3586 {
3587 switch (Face->charmaps[i]->encoding)
3588 {
3589 case FT_ENCODING_UNICODE:
3590 case FT_ENCODING_APPLE_ROMAN:
3591 fs.fsCsb[0] |= FS_LATIN1;
3592 break;
3593 case FT_ENCODING_MS_SYMBOL:
3594 fs.fsCsb[0] |= FS_SYMBOL;
3595 break;
3596 default:
3597 break;
3598 }
3599 }
3600 }
3601
3602 for (i = 0; i < MAXTCIINDEX; i++)
3603 {
3604 fs0 = 1L << i;
3605 if (fs.fsCsb[0] & fs0)
3606 {
3607 if (!IntTranslateCharsetInfo(&fs0, &CharSetInfo, TCI_SRCFONTSIG))
3608 {
3609 CharSetInfo.ciCharset = DEFAULT_CHARSET;
3610 }
3611 if (DEFAULT_CHARSET != CharSetInfo.ciCharset)
3612 {
3613 if (g_ElfScripts[i])
3614 wcscpy(Info->EnumLogFontEx.elfScript, g_ElfScripts[i]);
3615 else
3616 {
3617 DPRINT1("Unknown elfscript for bit %u\n", i);
3618 }
3619 }
3620 }
3621 }
3622 Info->NewTextMetricEx.ntmFontSig = fs;
3623}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ULONG_PTR
Definition: config.h:101
unsigned long DWORD
Definition: ntddk_ex.h:95
static PWCHAR g_ElfScripts[32]
Definition: freetype.c:354
#define MAXTCIINDEX
Definition: freetype.c:381
static BOOLEAN IntTranslateCharsetInfo(PDWORD Src, LPCHARSETINFO Cs, DWORD Flags)
Definition: freetype.c:2775
FT_Get_First_Char(FT_Face face, FT_UInt *agindex)
Definition: ftobjs.c:3760
unsigned int FT_UInt
Definition: fttypes.h:231
#define fs
Definition: i386-dis.c:444
if(dx< 0)
Definition: linetemp.h:194
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define UNICODE_NULL
NTSTRSAFEAPI RtlStringCbCopyW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:174
wcscpy
BYTE lfOutPrecision
Definition: dimm.idl:68
BYTE lfItalic
Definition: dimm.idl:64
LONG lfWeight
Definition: dimm.idl:63
BYTE lfClipPrecision
Definition: dimm.idl:69
BYTE lfCharSet
Definition: dimm.idl:67
BYTE lfQuality
Definition: dimm.idl:70
BYTE lfPitchAndFamily
Definition: dimm.idl:71
FT_UShort version
Definition: tttables.h:377
FT_ULong ulUnicodeRange1
Definition: tttables.h:396
FT_ULong ulCodePageRange1
Definition: tttables.h:414
FT_ULong ulUnicodeRange3
Definition: tttables.h:398
FT_ULong ulUnicodeRange2
Definition: tttables.h:397
FT_ULong ulCodePageRange2
Definition: tttables.h:415
FT_ULong ulUnicodeRange4
Definition: tttables.h:399
TEXTMETRICW otmTextMetrics
Definition: wingdi.h:2960
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: ffs.h:70
Definition: ps.c:97
UINT ciCharset
Definition: wingdi.h:1992
UINT ntmCellHeight
Definition: wingdi.h:3112
WCHAR tmFirstChar
Definition: wingdi.h:3101
LONG tmDigitizedAspectX
Definition: wingdi.h:3099
LONG tmInternalLeading
Definition: wingdi.h:3093
WCHAR tmDefaultChar
Definition: wingdi.h:3103
LONG tmMaxCharWidth
Definition: wingdi.h:3096
LONG tmAveCharWidth
Definition: wingdi.h:3095
WCHAR tmBreakChar
Definition: wingdi.h:3104
LONG tmExternalLeading
Definition: wingdi.h:3094
LONG tmDigitizedAspectY
Definition: wingdi.h:3100
BYTE tmPitchAndFamily
Definition: wingdi.h:3108
WCHAR tmLastChar
Definition: wingdi.h:3102
FT_Get_Sfnt_Table(FT_Face face, FT_Sfnt_Tag tag)
Definition: ftobjs.c:4176
#define ft_sfnt_os2
Definition: tttables.h:638
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
#define NTM_ITALIC
Definition: wingdi.h:1315
#define TRUETYPE_FONTTYPE
Definition: wingdi.h:1109
#define DEFAULT_CHARSET
Definition: wingdi.h:384
#define RASTER_FONTTYPE
Definition: wingdi.h:1107
#define FS_SYMBOL
Definition: wingdi.h:575
#define NTM_REGULAR
Definition: wingdi.h:1317
#define PROOF_QUALITY
Definition: wingdi.h:438
#define FS_LATIN1
Definition: wingdi.h:560
#define CLIP_DEFAULT_PRECIS
Definition: wingdi.h:426
#define NTM_BOLD
Definition: wingdi.h:1316
#define TCI_SRCFONTSIG
Definition: wingdi.h:963
#define OUT_OUTLINE_PRECIS
Definition: wingdi.h:423
_In_ PSTRING FullName
Definition: rtlfuncs.h:1665
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by GetFontFamilyInfoForList(), and IntGdiGetFontResourceInfo().

◆ FontLink_AddCache()

static VOID FontLink_AddCache ( _In_ PFONTLINK_CACHE  pCache)
inlinestatic

Definition at line 215 of file freetype.c.

217{
219
220 /* Add the new cache entry to the top of the cache list */
222 InsertHeadList(&g_FontLinkCache, &pCache->ListEntry);
223
224 /* If there are too many cache entries in the list, remove the oldest one at the bottom */
226 {
227 ASSERT(!IsListEmpty(&g_FontLinkCache));
228 Entry = RemoveTailList(&g_FontLinkCache);
230 pCache = CONTAINING_RECORD(Entry, FONTLINK_CACHE, ListEntry);
231 FontLink_Chain_Free(&pCache->Chain);
233 }
234}
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveTailList(ListHead)
Definition: env_spec_w32.h:975
static VOID FontLink_Chain_Free(_Inout_ PFONTLINK_CHAIN pChain)
Definition: freetype.c:194
static LONG g_nFontLinkCacheCount
Definition: freetype.c:69
#define MAX_FONTLINK_CACHE
Definition: freetype.c:67

Referenced by FontLink_Chain_Finish().

◆ FontLink_Chain_Dump()

static VOID FontLink_Chain_Dump ( _In_ PFONTLINK_CHAIN  pChain)
inlinestatic

Definition at line 4343 of file freetype.c.

4345{
4346#if 0
4347 PLIST_ENTRY Entry, Head;
4348 PFONTLINK pFontLink;
4349 INT iLink = 0;
4350
4351 DPRINT1("%S, %p, %p\n", pChain->LogFont.lfFaceName, pChain->pBaseTextObj, pChain->pDefFace);
4352
4353 Head = &pChain->FontLinkList;
4354 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
4355 {
4356 pFontLink = CONTAINING_RECORD(Entry, FONTLINK, ListEntry);
4357 DPRINT1("FontLink #%d: %p, %d, %S, %p, %p\n",
4358 iLink, pFontLink, pFontLink->bIgnore, pFontLink->LogFont.lfFaceName,
4359 pFontLink->pFontGDI, pFontLink->SharedFace);
4360 ++iLink;
4361 }
4362#endif
4363}
int32_t INT
Definition: typedefs.h:58

Referenced by FontLink_Chain_FindGlyph().

◆ FontLink_Chain_FindGlyph()

static UINT FontLink_Chain_FindGlyph ( _Inout_ PFONTLINK_CHAIN  pChain,
_Out_ PFONT_CACHE_ENTRY  pCache,
_Inout_ FT_Face pFace,
_In_ UINT  code,
_In_ BOOL  fCodeAsIndex 
)
static

Search the target glyph and update the current font info.

Returns
The glyph index

Definition at line 4368 of file freetype.c.

4374{
4375 PFONTLINK pFontLink;
4376 PLIST_ENTRY Entry, Head;
4377 UINT index;
4378 FT_Face face;
4379
4380 // Try the default font at first
4381 index = get_glyph_index_flagged(pChain->pDefFace, code, fCodeAsIndex);
4382 if (index)
4383 {
4384 DPRINT("code: 0x%08X, index: 0x%08X, fCodeAsIndex:%d\n", code, index, fCodeAsIndex);
4385 pCache->Hashed.Face = *pFace = pChain->pDefFace;
4386 return index; // The glyph is found on the default font
4387 }
4388
4389 if (!FontLink_Chain_IsPopulated(pChain)) // The chain is not populated yet
4390 {
4392 FontLink_Chain_Dump(pChain);
4393 }
4394
4395 // Now the chain is populated. Looking for the target glyph...
4396 Head = &pChain->FontLinkList;
4397 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
4398 {
4399 pFontLink = CONTAINING_RECORD(Entry, FONTLINK, ListEntry);
4400 if (!FontLink_PrepareFontInfo(pFontLink))
4401 continue; // This link is not useful, check the next one
4402
4403 face = pFontLink->SharedFace->Face;
4405 if (!index)
4406 continue; // The glyph does not exist, continue searching
4407
4408 // The target glyph is found in the chain
4409 DPRINT("code: 0x%08X, index: 0x%08X\n", code, index);
4410 pCache->Hashed.Face = *pFace = face;
4411 FT_Set_Transform(face, &pCache->Hashed.matTransform, NULL);
4412 return index;
4413 }
4414
4415 // No target glyph found in the chain: use default glyph
4417 index = get_glyph_index(*pFace, code);
4418 DPRINT("code: 0x%08X, index: 0x%08X\n", code, index);
4419 pCache->Hashed.Face = *pFace = pChain->pDefFace;
4420 return index;
4421}
#define index(s, c)
Definition: various.h:29
WORD face[3]
Definition: mesh.c:4747
static FT_UInt FASTCALL get_glyph_index_flagged(FT_Face face, FT_ULong code, BOOL fCodeAsIndex)
Definition: freetype.c:4337
static BOOL FontLink_PrepareFontInfo(_Inout_ PFONTLINK pFontLink)
Definition: freetype.c:460
static DWORD s_chFontLinkDefaultChar
Definition: freetype.c:60
static VOID FontLink_Chain_Dump(_In_ PFONTLINK_CHAIN pChain)
Definition: freetype.c:4343
static NTSTATUS FontLink_Chain_Populate(_Inout_ PFONTLINK_CHAIN pChain)
Definition: freetype.c:1407
static BOOL FontLink_Chain_IsPopulated(const FONTLINK_CHAIN *pChain)
Definition: freetype.c:188
static FT_UInt FASTCALL get_glyph_index(FT_Face ft_face, UINT glyph)
Definition: freetype.c:4322
FT_Set_Transform(FT_Face face, FT_Matrix *matrix, FT_Vector *delta)
Definition: ftobjs.c:689
GLuint index
Definition: glext.h:6031
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
#define DPRINT
Definition: sndvol32.h:73
Definition: inflate.c:139

Referenced by IntExtTextOutW(), IntGetTextDisposition(), and TextIntGetTextExtentPoint().

◆ FontLink_Chain_FindLink()

static PFONTLINK FontLink_Chain_FindLink ( PFONTLINK_CHAIN  pChain,
PLOGFONTW  plf 
)
inlinestatic

Definition at line 1348 of file freetype.c.

1351{
1352 PLIST_ENTRY Entry, Head = &pChain->FontLinkList;
1353 PFONTLINK pLink;
1354
1355 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
1356 {
1357 pLink = CONTAINING_RECORD(Entry, FONTLINK, ListEntry);
1358 if (RtlEqualMemory(&pLink->LogFont, plf, sizeof(*plf)))
1359 return pLink;
1360 }
1361
1362 return NULL;
1363}
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18

Referenced by FontLink_Create().

◆ FontLink_Chain_Finish()

static VOID FontLink_Chain_Finish ( _Inout_ PFONTLINK_CHAIN  pChain)
inlinestatic

Add the chain to the cache (g_FontLinkCache) if the chain had been populated.

Parameters
pChainThe chain.

Definition at line 239 of file freetype.c.

241{
242 PFONTLINK_CACHE pCache;
243
244 if (!FontLink_Chain_IsPopulated(pChain))
245 return; // The chain is not populated yet
246
248 if (!pCache)
249 return; // Out of memory
250
251 pCache->LogFont = pChain->LogFont;
252 pCache->Chain = *pChain;
253 IntRebaseList(&pCache->Chain.FontLinkList, &pChain->FontLinkList);
254
255 FontLink_AddCache(pCache);
256}
static VOID FontLink_AddCache(_In_ PFONTLINK_CACHE pCache)
Definition: freetype.c:215
VOID IntRebaseList(_Inout_ PLIST_ENTRY pNewHead, _Inout_ PLIST_ENTRY pOldHead)
Definition: utils.c:30

Referenced by IntExtTextOutW(), and TextIntGetTextExtentPoint().

◆ FontLink_Chain_Free()

static VOID FontLink_Chain_Free ( _Inout_ PFONTLINK_CHAIN  pChain)
static

Definition at line 194 of file freetype.c.

196{
198 PFONTLINK pLink;
199
200 if (!FontLink_Chain_IsPopulated(pChain)) // The chain is not populated yet
201 return;
202
203 if (pChain->pszzFontLink)
204 ExFreePoolWithTag(pChain->pszzFontLink, TAG_FONT);
205
206 while (!IsListEmpty(&pChain->FontLinkList))
207 {
208 Entry = RemoveHeadList(&pChain->FontLinkList);
209 pLink = CONTAINING_RECORD(Entry, FONTLINK, ListEntry);
210 FontLink_Destroy(pLink);
211 }
212}
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
static VOID FontLink_Destroy(_Inout_ PFONTLINK pLink)
Definition: freetype.c:182

Referenced by FontLink_AddCache(), and FontLink_CleanupCache().

◆ FontLink_Chain_Init()

static VOID FontLink_Chain_Init ( _Out_ PFONTLINK_CHAIN  pChain,
_Inout_ PTEXTOBJ  pTextObj,
_In_ FT_Face  face 
)
inlinestatic

Definition at line 1228 of file freetype.c.

1232{
1233 RtlZeroMemory(pChain, sizeof(*pChain));
1234 pChain->pBaseTextObj = pTextObj;
1235 pChain->pDefFace = face;
1237}

Referenced by IntExtTextOutW(), and TextIntGetTextExtentPoint().

◆ FontLink_Chain_IsPopulated()

static BOOL FontLink_Chain_IsPopulated ( const FONTLINK_CHAIN pChain)
inlinestatic

Definition at line 188 of file freetype.c.

189{
190 return pChain->LogFont.lfFaceName[0];
191}

Referenced by FontLink_Chain_FindGlyph(), FontLink_Chain_Finish(), FontLink_Chain_Free(), FontLink_Chain_Init(), and FontLink_Chain_Populate().

◆ FontLink_Chain_LoadReg()

static NTSTATUS FontLink_Chain_LoadReg ( _Inout_ PFONTLINK_CHAIN  pChain,
_Inout_ PLOGFONTW  pLF 
)
static

Definition at line 1257 of file freetype.c.

1260{
1262 HKEY hKey;
1263 DWORD cbData;
1264 WCHAR szzFontLink[512];
1265 SIZE_T FontLinkSize;
1266 PZZWSTR pszzFontLink = NULL;
1267
1268 ASSERT(pLF->lfFaceName[0]);
1269
1270 // Open the registry key
1272 L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink",
1273 &hKey);
1274 if (!NT_SUCCESS(Status))
1275 return Status;
1276
1277 // Load the FontLink entry
1278 cbData = sizeof(szzFontLink);
1279 Status = RegQueryValue(hKey, pLF->lfFaceName, REG_MULTI_SZ, szzFontLink, &cbData);
1280 if (!NT_SUCCESS(Status) &&
1282 {
1283 // Retry with substituted
1285 cbData = sizeof(szzFontLink);
1286 Status = RegQueryValue(hKey, pLF->lfFaceName, REG_MULTI_SZ, szzFontLink, &cbData);
1287 }
1288
1290 {
1291 // Buffer is too small. Retry with larger buffer
1292 if (cbData >= 2 * sizeof(WCHAR)) // Sanity check
1293 {
1294 FontLinkSize = cbData;
1295 pszzFontLink = ExAllocatePoolWithTag(PagedPool, FontLinkSize, TAG_FONT);
1296 if (!pszzFontLink)
1297 {
1298 ZwClose(hKey); // Close the registry key
1299 return STATUS_NO_MEMORY;
1300 }
1301 Status = RegQueryValue(hKey, pLF->lfFaceName, REG_MULTI_SZ, pszzFontLink, &cbData);
1302 if (!NT_SUCCESS(Status))
1303 {
1304 ExFreePoolWithTag(pszzFontLink, TAG_FONT);
1305 pszzFontLink = NULL;
1306 }
1307 }
1308 }
1309
1310 ZwClose(hKey); // Close the registry key
1311
1312 if (!NT_SUCCESS(Status)) // Failed to get registry value
1313 {
1314 // Use default value
1315 ASSERT(sizeof(szzFontLink) >= sizeof(s_szzDefFontLink));
1316 ASSERT(sizeof(szzFontLink) >= sizeof(s_szzDefFixedFontLink));
1317 if (!(pLF->lfPitchAndFamily & FIXED_PITCH))
1318 RtlCopyMemory(szzFontLink, s_szzDefFontLink, sizeof(s_szzDefFontLink));
1319 else
1321 }
1322
1323 if (pszzFontLink)
1324 {
1325 // Ensure double-NUL-terminated
1326 ASSERT(FontLinkSize / sizeof(WCHAR) >= 2);
1327 pszzFontLink[FontLinkSize / sizeof(WCHAR) - 1] = UNICODE_NULL;
1328 pszzFontLink[FontLinkSize / sizeof(WCHAR) - 2] = UNICODE_NULL;
1329 }
1330 else
1331 {
1332 // Ensure double-NUL-terminated
1333 szzFontLink[_countof(szzFontLink) - 1] = UNICODE_NULL;
1334 szzFontLink[_countof(szzFontLink) - 2] = UNICODE_NULL;
1335
1336 FontLinkSize = SZZ_GetSize(szzFontLink);
1337 pszzFontLink = ExAllocatePoolWithTag(PagedPool, FontLinkSize, TAG_FONT);
1338 if (!pszzFontLink)
1339 return STATUS_NO_MEMORY;
1340 RtlCopyMemory(pszzFontLink, szzFontLink, FontLinkSize);
1341 }
1342 pChain->pszzFontLink = pszzFontLink;
1343
1344 return STATUS_SUCCESS;
1345}
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define L(x)
Definition: resources.c:13
static const WCHAR s_szzDefFixedFontLink[]
Definition: freetype.c:1248
static BOOL SubstituteFontRecurse(PLOGFONTW pLogFont)
Definition: freetype.c:1192
static const WCHAR s_szzDefFontLink[]
Definition: freetype.c:1240
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define REG_MULTI_SZ
Definition: nt_native.h:1504
_NullNull_terminated_ WCHAR * PZZWSTR
Definition: ntbasedef.h:432
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define _countof(array)
Definition: sndvol32.h:70
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
SIZE_T SZZ_GetSize(_In_ PCZZWSTR pszz)
Definition: utils.c:15
#define FIXED_PITCH
Definition: wingdi.h:444
#define RegOpenKey
Definition: winreg.h:551
#define RegQueryValue
Definition: winreg.h:555

Referenced by FontLink_Chain_Populate().

◆ FontLink_Chain_Populate()

static NTSTATUS FontLink_Chain_Populate ( _Inout_ PFONTLINK_CHAIN  pChain)
static

Definition at line 1407 of file freetype.c.

1409{
1411 PFONTLINK pLink;
1412 LOGFONTW lfBase;
1413 PTEXTOBJ pTextObj = pChain->pBaseTextObj;
1414 PFONTGDI pFontGDI;
1415 PWSTR pszLink;
1416 PFONTLINK_CACHE pLinkCache;
1417 WCHAR szEntry[MAX_PATH];
1418 BOOL bFixCharSet;
1419
1420 InitializeListHead(&pChain->FontLinkList);
1421
1422 lfBase = pTextObj->logfont.elfEnumLogfontEx.elfLogFont;
1423 pFontGDI = ObjToGDI(pTextObj->Font, FONT);
1424 lfBase.lfHeight = pFontGDI->lfHeight;
1425 lfBase.lfWidth = pFontGDI->lfWidth;
1426
1427 // Use pTextObj->TextFace if lfFaceName was empty
1428 if (!lfBase.lfFaceName[0])
1429 {
1430 ASSERT(pTextObj->TextFace[0]);
1431 RtlStringCchCopyW(lfBase.lfFaceName, _countof(lfBase.lfFaceName), pTextObj->TextFace);
1432 }
1433
1434 // Fix lfCharSet
1435 switch (lfBase.lfCharSet)
1436 {
1437 case ANSI_CHARSET: bFixCharSet = !s_fFontLinkUseAnsi; break;
1438 case OEM_CHARSET: bFixCharSet = !s_fFontLinkUseOem; break;
1439 case SYMBOL_CHARSET: bFixCharSet = !s_fFontLinkUseSymbol; break;
1440 default: bFixCharSet = TRUE; break;
1441 }
1442 if (bFixCharSet)
1443 lfBase.lfCharSet = DEFAULT_CHARSET;
1444
1445 // Use cache if any
1446 pLinkCache = FontLink_FindCache(&lfBase);
1447 if (pLinkCache)
1448 {
1449 RemoveEntryList(&pLinkCache->ListEntry);
1450 *pChain = pLinkCache->Chain;
1451 IntRebaseList(&pChain->FontLinkList, &pLinkCache->Chain.FontLinkList);
1452 ExFreePoolWithTag(pLinkCache, TAG_FONT);
1453 return STATUS_SUCCESS;
1454 }
1455
1456 pChain->LogFont = lfBase;
1457
1458 // Load FontLink entry from registry
1459 Status = FontLink_Chain_LoadReg(pChain, &pChain->LogFont);
1460 if (!NT_SUCCESS(Status))
1461 return Status;
1462
1463 pszLink = pChain->pszzFontLink;
1464 while (*pszLink)
1465 {
1466 DPRINT("pszLink: '%S'\n", pszLink);
1467 pLink = FontLink_Create(pChain, &lfBase, pszLink);
1468 if (pLink)
1469 InsertTailList(&pChain->FontLinkList, &pLink->ListEntry);
1470 pszLink += wcslen(pszLink) + 1;
1471 }
1472
1473 // Use default settings (if any)
1475 {
1477 RtlStringCchCatW(szEntry, _countof(szEntry), L",");
1479 DPRINT("szEntry: '%S'\n", szEntry);
1480 pLink = FontLink_Create(pChain, &lfBase, szEntry);
1481 if (pLink)
1482 InsertTailList(&pChain->FontLinkList, &pLink->ListEntry);
1483 }
1484
1486 return Status;
1487}
#define MAX_PATH
Definition: compat.h:34
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
#define ObjToGDI(ClipObj, Type)
Definition: engobjects.h:184
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int BOOL
Definition: ntddk_ex.h:94
static WCHAR s_szDefFontLinkFileName[MAX_PATH]
Definition: freetype.c:61
static BOOL s_fFontLinkUseAnsi
Definition: freetype.c:63
static PFONTLINK FontLink_Create(_Inout_ PFONTLINK_CHAIN pChain, _In_ const LOGFONTW *plfBase, _In_ LPCWSTR pszLink)
Definition: freetype.c:1366
static WCHAR s_szDefFontLinkFontName[MAX_PATH]
Definition: freetype.c:62
static NTSTATUS FontLink_Chain_LoadReg(_Inout_ PFONTLINK_CHAIN pChain, _Inout_ PLOGFONTW pLF)
Definition: freetype.c:1257
static BOOL s_fFontLinkUseOem
Definition: freetype.c:64
static BOOL s_fFontLinkUseSymbol
Definition: freetype.c:65
static PFONTLINK_CACHE FontLink_FindCache(_In_ const LOGFONTW *pLogFont)
Definition: freetype.c:259
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
NTSTRSAFEAPI RtlStringCchCatW(_Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:601
LONG lfHeight
Definition: engobjects.h:166
Definition: text.h:60
WCHAR TextFace[LF_FACESIZE]
Definition: text.h:67
ENUMLOGFONTEXDVW logfont
Definition: text.h:70
FONTOBJ * Font
Definition: text.h:66
ENUMLOGFONTEXW elfEnumLogfontEx
Definition: wingdi.h:3225
uint16_t * PWSTR
Definition: typedefs.h:56
#define ANSI_CHARSET
Definition: wingdi.h:383
#define OEM_CHARSET
Definition: wingdi.h:400
#define SYMBOL_CHARSET
Definition: wingdi.h:385

Referenced by FontLink_Chain_FindGlyph().

◆ FontLink_CleanupCache()

static VOID FontLink_CleanupCache ( VOID  )
inlinestatic

Definition at line 274 of file freetype.c.

275{
277 PFONTLINK_CACHE pLinkCache;
278
279 while (!IsListEmpty(&g_FontLinkCache))
280 {
281 Entry = RemoveHeadList(&g_FontLinkCache);
282 pLinkCache = CONTAINING_RECORD(Entry, FONTLINK_CACHE, ListEntry);
283 FontLink_Chain_Free(&pLinkCache->Chain);
284 ExFreePoolWithTag(pLinkCache, TAG_FONT);
285 }
286
288}

Referenced by FreeFontSupport().

◆ FontLink_Create()

static PFONTLINK FontLink_Create ( _Inout_ PFONTLINK_CHAIN  pChain,
_In_ const LOGFONTW plfBase,
_In_ LPCWSTR  pszLink 
)
inlinestatic

Definition at line 1366 of file freetype.c.

1370{
1371 LPWSTR pch0, pch1;
1372 LOGFONTW lf;
1373 PFONTLINK pLink;
1374
1375 lf = *plfBase;
1376
1377 // pszLink: "<FontFileName>,<FaceName>[,...]"
1378 pch0 = wcschr(pszLink, L',');
1379 if (!pch0)
1380 {
1381 DPRINT1("%S\n", pszLink);
1382 return NULL; // Invalid FontLink data
1383 }
1384 ++pch0;
1385
1386 pch1 = wcschr(pch0, L',');
1387 if (pch1)
1388 RtlStringCchCopyNW(lf.lfFaceName, _countof(lf.lfFaceName), pch0, pch1 - pch0);
1389 else
1391
1393 DPRINT("lfFaceName: %S\n", lf.lfFaceName);
1394
1395 if (RtlEqualMemory(plfBase, &lf, sizeof(lf)) || FontLink_Chain_FindLink(pChain, &lf))
1396 return NULL; // Already exists
1397
1398 pLink = ExAllocatePoolZero(PagedPool, sizeof(FONTLINK), TAG_FONT);
1399 if (!pLink)
1400 return NULL; // Out of memory
1401
1402 pLink->LogFont = lf;
1403 return pLink;
1404}
#define wcschr
Definition: compat.h:17
static PFONTLINK FontLink_Chain_FindLink(PFONTLINK_CHAIN pChain, PLOGFONTW plf)
Definition: freetype.c:1348
FORCEINLINE PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
NTSTRSAFEAPI RtlStringCchCopyNW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_reads_or_z_(cchToCopy) STRSAFE_LPCWSTR pszSrc, _In_ size_t cchToCopy)
Definition: ntstrsafe.h:363
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by FontLink_Chain_Populate().

◆ FontLink_Destroy()

static VOID FontLink_Destroy ( _Inout_ PFONTLINK  pLink)
inlinestatic

Definition at line 182 of file freetype.c.

183{
185}

Referenced by FontLink_Chain_Free().

◆ FontLink_FindCache()

static PFONTLINK_CACHE FontLink_FindCache ( _In_ const LOGFONTW pLogFont)
inlinestatic

Definition at line 259 of file freetype.c.

261{
263 PFONTLINK_CACHE pLinkCache;
264 for (Entry = g_FontLinkCache.Flink; Entry != &g_FontLinkCache; Entry = Entry->Flink)
265 {
266 pLinkCache = CONTAINING_RECORD(Entry, FONTLINK_CACHE, ListEntry);
267 if (RtlEqualMemory(&pLinkCache->LogFont, pLogFont, sizeof(LOGFONTW)))
268 return pLinkCache;
269 }
270 return NULL;
271}

Referenced by FontLink_Chain_Populate().

◆ FontLink_LoadDefaultCharset()

static NTSTATUS FontLink_LoadDefaultCharset ( VOID  )
inlinestatic

Definition at line 136 of file freetype.c.

137{
139 HKEY hKey;
141 WCHAR szValue[8];
142
143 // Set the default values
145
146 // Open the registry key
148 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\FontAssoc\\Associated Charset",
149 &hKey);
150 if (!NT_SUCCESS(Status))
151 return Status;
152
153 cbData = sizeof(szValue);
154 Status = RegQueryValue(hKey, L"ANSI(00)", REG_SZ, szValue, &cbData);
155 if (NT_SUCCESS(Status))
156 {
157 szValue[_countof(szValue) - 1] = UNICODE_NULL; // Avoid buffer overrun
158 s_fFontLinkUseAnsi = !_wcsicmp(szValue, L"YES");
159 }
160
161 cbData = sizeof(szValue);
162 Status = RegQueryValue(hKey, L"OEM(FF)", REG_SZ, szValue, &cbData);
163 if (NT_SUCCESS(Status))
164 {
165 szValue[_countof(szValue) - 1] = UNICODE_NULL; // Avoid buffer overrun
166 s_fFontLinkUseOem = !_wcsicmp(szValue, L"YES");
167 }
168
169 cbData = sizeof(szValue);
170 Status = RegQueryValue(hKey, L"SYMBOL(02)", REG_SZ, szValue, &cbData);
171 if (NT_SUCCESS(Status))
172 {
173 szValue[_countof(szValue) - 1] = UNICODE_NULL; // Avoid buffer overrun
174 s_fFontLinkUseSymbol = !_wcsicmp(szValue, L"YES");
175 }
176
177 ZwClose(hKey); // Close the registry key
178 return STATUS_SUCCESS;
179}
#define REG_SZ
Definition: layer.c:22

Referenced by InitFontSupport().

◆ FontLink_LoadDefaultFonts()

static NTSTATUS FontLink_LoadDefaultFonts ( VOID  )
inlinestatic

Definition at line 98 of file freetype.c.

99{
101 HKEY hKey;
103 WCHAR szValue[MAX_PATH];
104
105 // Set the default values
107
108 // Open the registry key
110 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\FontAssoc\\Associated DefaultFonts",
111 &hKey);
112 if (!NT_SUCCESS(Status))
113 return Status;
114
115 cbData = sizeof(szValue);
116 Status = RegQueryValue(hKey, L"AssocSystemFont", REG_SZ, szValue, &cbData);
117 if (NT_SUCCESS(Status))
118 {
119 szValue[_countof(szValue) - 1] = UNICODE_NULL; // Avoid buffer overrun
121 }
122
123 cbData = sizeof(szValue);
124 Status = RegQueryValue(hKey, L"FontPackage", REG_SZ, szValue, &cbData);
125 if (NT_SUCCESS(Status))
126 {
127 szValue[_countof(szValue) - 1] = UNICODE_NULL; // Avoid buffer overrun
129 }
130
131 ZwClose(hKey); // Close the registry key
132 return STATUS_SUCCESS;
133}

Referenced by InitFontSupport().

◆ FontLink_LoadSettings()

static NTSTATUS FontLink_LoadSettings ( VOID  )
inlinestatic

Definition at line 72 of file freetype.c.

73{
75 HKEY hKey;
76 DWORD cbData, dwValue;
77
78 // Set the default values
80
81 // Open the registry key
83 L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontLink",
84 &hKey);
85 if (!NT_SUCCESS(Status))
86 return Status;
87
88 cbData = sizeof(dwValue);
89 Status = RegQueryValue(hKey, L"FontLinkDefaultChar", REG_DWORD, &dwValue, &cbData);
90 if (NT_SUCCESS(Status) && cbData == sizeof(dwValue))
92
93 ZwClose(hKey); // Close the registry key
94 return STATUS_SUCCESS;
95}
#define FONTLINK_DEFAULT_CHAR
Definition: freetype.c:58
#define REG_DWORD
Definition: sdbapi.c:615

Referenced by InitFontSupport().

◆ FontLink_PrepareFontInfo()

static BOOL FontLink_PrepareFontInfo ( _Inout_ PFONTLINK  pFontLink)
static

Definition at line 460 of file freetype.c.

462{
464
465 if (pFontLink->bIgnore)
466 return FALSE;
467 if (pFontLink->SharedFace)
468 return TRUE;
469
470 PSHARED_FACE SharedFace = IntRealizeFont(&pFontLink->LogFont, NULL);
471 if (!SharedFace) // Not found?
472 {
473 pFontLink->bIgnore = TRUE;
474 return FALSE;
475 }
476
477 pFontLink->SharedFace = SharedFace;
478 return TRUE;
479}
PSHARED_FACE IntRealizeFont(const LOGFONTW *pLogFont, _Inout_opt_ PTEXTOBJ TextObj)
Definition: freetype.c:6003

Referenced by FontLink_Chain_FindGlyph().

◆ FontLookUp_Add()

static void FontLookUp_Add ( const LOGFONTW LogFont,
PSHARED_FACE  SharedFace,
FONTOBJ pFontObj 
)
static

Definition at line 5974 of file freetype.c.

5975{
5977
5978 if (s_FontLookupCacheCount >= MAX_FONT_LOOKUP_CACHE) // Too many cached entries?
5979 {
5980 // Remove tail one
5981 PLIST_ENTRY OldestEntry = RemoveTailList(&s_FontLookupCacheList);
5982 PFONT_LOOKUP_CACHE pOldCache = CONTAINING_RECORD(OldestEntry, FONT_LOOKUP_CACHE, ListEntry);
5983 FontLookUp_Destroy(pOldCache);
5985 }
5986
5987 // Add new cache entry
5989 if (pEntry)
5990 {
5991 // Populate
5992 RtlCopyMemory(&pEntry->LogFont, LogFont, sizeof(*LogFont));
5993 pEntry->SharedFace = SharedFace;
5994 SharedFace_AddRef(SharedFace);
5995 pEntry->pFontObj = pFontObj;
5996 // Add to head
5997 InsertHeadList(&s_FontLookupCacheList, &pEntry->ListEntry);
5999 }
6000}
static void FontLookUp_Destroy(PFONT_LOOKUP_CACHE pCache)
Definition: freetype.c:950
static void SharedFace_AddRef(PSHARED_FACE Ptr)
Definition: freetype.c:536
static ULONG s_FontLookupCacheCount
Definition: freetype.c:300
#define MAX_FONT_LOOKUP_CACHE
Definition: freetype.c:299
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484

Referenced by IntRealizeFont().

◆ FontLookUp_Cleanup()

static void FontLookUp_Cleanup ( _In_ BOOL  bDoLock,
_Inout_opt_ PSHARED_FACE  SharedFace 
)
static

Definition at line 958 of file freetype.c.

961{
962 if (bDoLock)
964
965 PLIST_ENTRY pHead = &s_FontLookupCacheList, pEntry;
966 PFONT_LOOKUP_CACHE pCache;
967
968 if (SharedFace)
969 {
970 for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink)
971 {
972 pCache = CONTAINING_RECORD(pEntry, FONT_LOOKUP_CACHE, ListEntry);
973 if (pCache->SharedFace == SharedFace)
974 {
975 RemoveEntryList(&pCache->ListEntry);
976 FontLookUp_Destroy(pCache);
978 }
979 }
980 }
981 else
982 {
983 while (!IsListEmpty(pHead))
984 {
985 pEntry = RemoveHeadList(pHead);
986 pCache = CONTAINING_RECORD(pEntry, FONT_LOOKUP_CACHE, ListEntry);
987 FontLookUp_Destroy(pCache);
988 }
990 }
991
992 if (bDoLock)
994}
#define IntUnLockFreeType()
Definition: freetype.c:343
#define IntLockFreeType()
Definition: freetype.c:337
PSHARED_FACE SharedFace
Definition: freetype.c:294
LIST_ENTRY ListEntry
Definition: freetype.c:292

Referenced by FreeFontSupport(), IntGdiAddFontResourceEx(), and IntGdiRemoveFontResourceSingle().

◆ FontLookUp_Destroy()

static void FontLookUp_Destroy ( PFONT_LOOKUP_CACHE  pCache)
static

Definition at line 950 of file freetype.c.

Referenced by FontLookUp_Add(), and FontLookUp_Cleanup().

◆ FontLookUp_LookUp()

static PFONT_LOOKUP_CACHE FontLookUp_LookUp ( const LOGFONTW pLogFont)
static

Definition at line 5954 of file freetype.c.

5955{
5957
5958 PLIST_ENTRY Entry, pHead = &s_FontLookupCacheList;
5959 for (Entry = pHead->Flink; Entry != pHead; Entry = Entry->Flink)
5960 {
5962 if (RtlEqualMemory(&pEntry->LogFont, pLogFont, sizeof(*pLogFont)))
5963 {
5964 // Move to head
5965 RemoveEntryList(&pEntry->ListEntry);
5966 InsertHeadList(&s_FontLookupCacheList, &pEntry->ListEntry);
5967 return pEntry;
5968 }
5969 }
5970 return NULL;
5971}

Referenced by IntRealizeFont().

◆ FreeFontSupport()

VOID FASTCALL FreeFontSupport ( VOID  )

Definition at line 1039 of file freetype.c.

1040{
1041 PLIST_ENTRY pHead, pEntry;
1042 PFONT_CACHE_ENTRY pFontCache;
1043 PFONTSUBST_ENTRY pSubstEntry;
1044 PFONT_ENTRY pFontEntry;
1045
1046 // Cleanup the FontLink cache
1048
1049 // Cleanup FONT_LOOKUP_CACHE
1051
1052 // Free font cache list
1053 pHead = &g_FontCacheListHead;
1054 while (!IsListEmpty(pHead))
1055 {
1056 pEntry = RemoveHeadList(pHead);
1057 pFontCache = CONTAINING_RECORD(pEntry, FONT_CACHE_ENTRY, ListEntry);
1058 RemoveCachedEntry(pFontCache);
1059 }
1060
1061 // Free font subst list
1062 pHead = &g_FontSubstListHead;
1063 while (!IsListEmpty(pHead))
1064 {
1065 pEntry = RemoveHeadList(pHead);
1066 pSubstEntry = CONTAINING_RECORD(pEntry, FONTSUBST_ENTRY, ListEntry);
1067 ExFreePoolWithTag(pSubstEntry, TAG_FONT);
1068 }
1069
1070 // Free font list
1071 pHead = &g_FontListHead;
1072 while (!IsListEmpty(pHead))
1073 {
1074 pEntry = RemoveHeadList(pHead);
1075 pFontEntry = CONTAINING_RECORD(pEntry, FONT_ENTRY, ListEntry);
1076 CleanupFontEntry(pFontEntry);
1077 }
1078
1080 {
1083 }
1084
1087}
FT_Library g_FreeTypeLibrary
Definition: freetype.c:318
static VOID FontLink_CleanupCache(VOID)
Definition: freetype.c:274
static void FontLookUp_Cleanup(_In_ BOOL bDoLock, _Inout_opt_ PSHARED_FACE SharedFace)
Definition: freetype.c:958
static __inline VOID FASTCALL CleanupFontEntry(PFONT_ENTRY FontEntry)
Definition: freetype.c:653
static void RemoveCachedEntry(PFONT_CACHE_ENTRY Entry)
Definition: freetype.c:544
FT_Done_Library(FT_Library library)
Definition: ftobjs.c:5353
Definition: font.h:77
Definition: font.h:56
#define TAG_INTERNAL_SYNC
Definition: tags.h:18

Referenced by _Function_class_().

◆ FT_FixedFromFIXED()

static __inline FT_Fixed FT_FixedFromFIXED ( FIXED  f)
static

Definition at line 672 of file freetype.c.

673{
674 return (FT_Fixed)((long)f.value << 16 | (unsigned long)f.fract);
675}
GLfloat f
Definition: glext.h:7540
#define long
Definition: qsort.c:33

Referenced by ftGdiGetGlyphOutline().

◆ ftGdiGetFontData()

DWORD FASTCALL ftGdiGetFontData ( PFONTGDI  FontGdi,
DWORD  Table,
DWORD  Offset,
PVOID  Buffer,
DWORD  Size 
)

Definition at line 5363 of file freetype.c.

5369{
5371 FT_Face Face = FontGdi->SharedFace->Face;
5372
5374
5375 if (FT_IS_SFNT(Face))
5376 {
5377 if (Table)
5378 Table = Table >> 24 | Table << 24 | (Table >> 8 & 0xFF00) |
5379 (Table << 8 & 0xFF0000);
5380
5381 if (!Buffer) Size = 0;
5382
5383 if (Buffer && Size)
5384 {
5386 FT_ULong Needed = 0;
5387
5388 Error = FT_Load_Sfnt_Table(Face, Table, Offset, NULL, &Needed);
5389
5390 if ( !Error && Needed < Size) Size = Needed;
5391 }
5392 if (!FT_Load_Sfnt_Table(Face, Table, Offset, Buffer, &Size))
5393 Result = Size;
5394 }
5395
5397
5398 return Result;
5399}
BOOL Error
Definition: chkdsk.c:66
Definition: bufpool.h:45
unsigned long FT_ULong
Definition: fttypes.h:253
int FT_Error
Definition: fttypes.h:299
ASMGENDATA Table[]
Definition: genincdata.c:61
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
FT_Load_Sfnt_Table(FT_Face face, FT_ULong tag, FT_Long offset, FT_Byte *buffer, FT_ULong *length)
Definition: ftobjs.c:4197
#define GDI_ERROR
Definition: wingdi.h:1309
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by NtGdiGetFontData().

◆ ftGdiGetGlyphOutline()

ULONG FASTCALL ftGdiGetGlyphOutline ( PDC  dc,
WCHAR  wch,
UINT  iFormat,
LPGLYPHMETRICS  pgm,
ULONG  cjBuf,
PVOID  pvBuf,
const MAT2 pmat2,
BOOL  bIgnoreRotation 
)

Definition at line 4428 of file freetype.c.

4437{
4438 PDC_ATTR pdcattr;
4439 PTEXTOBJ TextObj;
4440 PFONTGDI FontGDI;
4441 HFONT hFont = 0;
4442 GLYPHMETRICS gm;
4443 ULONG Size;
4444 FT_Face ft_face;
4445 FT_UInt glyph_index;
4446 DWORD width, height, pitch, needed = 0;
4447 FT_Bitmap ft_bitmap;
4449 INT left, right, top = 0, bottom = 0;
4451 FLOATOBJ eM11, widthRatio, eTemp;
4452 FT_Matrix mat, transMat = identityMat;
4453 BOOL needsTransform = FALSE;
4454 INT orientation;
4455 LONG aveWidth;
4456 INT adv, lsb, bbx; /* These three hold to widths of the unrotated chars */
4457 OUTLINETEXTMETRICW *potm;
4458 XFORMOBJ xo;
4459 XFORML xform;
4460 LOGFONTW *plf;
4461
4462 DPRINT("%u, %08x, %p, %08lx, %p, %p\n", wch, iFormat, pgm,
4463 cjBuf, pvBuf, pmat2);
4464
4465 pdcattr = dc->pdcattr;
4466
4467 XFORMOBJ_vInit(&xo, &dc->pdcattr->mxWorldToDevice);
4468 XFORMOBJ_iGetXform(&xo, &xform);
4469 FLOATOBJ_SetFloat(&eM11, xform.eM11);
4470
4471 hFont = pdcattr->hlfntNew;
4472 TextObj = RealizeFontInit(hFont);
4473
4474 if (!TextObj)
4475 {
4477 return GDI_ERROR;
4478 }
4479 FontGDI = ObjToGDI(TextObj->Font, FONT);
4480 ft_face = FontGDI->SharedFace->Face;
4481
4482 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
4483 aveWidth = FT_IS_SCALABLE(ft_face) ? abs(plf->lfWidth) : 0;
4484 orientation = FT_IS_SCALABLE(ft_face) ? plf->lfOrientation : 0;
4485
4487 Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL, FALSE);
4488 if (!Size)
4489 {
4490 TEXTOBJ_UnlockText(TextObj);
4492 return GDI_ERROR;
4493 }
4495 if (!potm)
4496 {
4497 TEXTOBJ_UnlockText(TextObj);
4499 return GDI_ERROR;
4500 }
4502 Size = IntGetOutlineTextMetrics(FontGDI, Size, potm, FALSE);
4503 if (!Size)
4504 {
4506 TEXTOBJ_UnlockText(TextObj);
4508 return GDI_ERROR;
4509 }
4510
4512 TextIntUpdateSize(dc, TextObj, FontGDI, FALSE);
4514 FT_Set_Transform(ft_face, &mat, NULL);
4515
4516 TEXTOBJ_UnlockText(TextObj);
4517
4518 glyph_index = get_glyph_index_flagged(ft_face, wch, (iFormat & GGO_GLYPH_INDEX));
4519 iFormat &= ~GGO_GLYPH_INDEX;
4520
4521 if (orientation || (iFormat != GGO_METRICS && iFormat != GGO_BITMAP) || aveWidth || pmat2)
4522 load_flags |= FT_LOAD_NO_BITMAP;
4523
4524 if (iFormat & GGO_UNHINTED)
4525 {
4526 load_flags |= FT_LOAD_NO_HINTING;
4527 iFormat &= ~GGO_UNHINTED;
4528 }
4529
4530 error = FT_Load_Glyph(ft_face, glyph_index, load_flags);
4531 if (error)
4532 {
4533 DPRINT1("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index);
4535 if (potm) ExFreePoolWithTag(potm, GDITAG_TEXT);
4536 return GDI_ERROR;
4537 }
4539
4540 FLOATOBJ_Set1(&widthRatio);
4541 if (aveWidth && potm)
4542 {
4543 // widthRatio = aveWidth * eM11 / potm->otmTextMetrics.tmAveCharWidth
4544 FLOATOBJ_SetLong(&widthRatio, aveWidth);
4545 FLOATOBJ_Mul(&widthRatio, &eM11);
4547 }
4548
4549 //left = (INT)(ft_face->glyph->metrics.horiBearingX * widthRatio) & -64;
4550 FLOATOBJ_SetLong(&eTemp, ft_face->glyph->metrics.horiBearingX);
4551 FLOATOBJ_Mul(&eTemp, &widthRatio);
4552 left = FLOATOBJ_GetLong(&eTemp) & -64;
4553
4554 //right = (INT)((ft_face->glyph->metrics.horiBearingX +
4555 // ft_face->glyph->metrics.width) * widthRatio + 63) & -64;
4556 FLOATOBJ_SetLong(&eTemp, ft_face->glyph->metrics.horiBearingX * ft_face->glyph->metrics.width);
4557 FLOATOBJ_Mul(&eTemp, &widthRatio);
4558 FLOATOBJ_AddLong(&eTemp, 63);
4559 right = FLOATOBJ_GetLong(&eTemp) & -64;
4560
4561 //adv = (INT)((ft_face->glyph->metrics.horiAdvance * widthRatio) + 63) >> 6;
4562 FLOATOBJ_SetLong(&eTemp, ft_face->glyph->metrics.horiAdvance);
4563 FLOATOBJ_Mul(&eTemp, &widthRatio);
4564 FLOATOBJ_AddLong(&eTemp, 63);
4565 adv = FLOATOBJ_GetLong(&eTemp) >> 6;
4566
4567 lsb = left >> 6;
4568 bbx = (right - left) >> 6;
4569
4570 DPRINT("Advance = %d, lsb = %d, bbx = %d\n",adv, lsb, bbx);
4571
4573
4574 /* Width scaling transform */
4575 if (!FLOATOBJ_Equal1(&widthRatio))
4576 {
4577 FT_Matrix scaleMat;
4578
4579 eTemp = widthRatio;
4580 FLOATOBJ_MulLong(&eTemp, 1 << 16);
4581
4582 scaleMat.xx = FLOATOBJ_GetLong(&eTemp);
4583 scaleMat.xy = 0;
4584 scaleMat.yx = 0;
4585 scaleMat.yy = INT_TO_FIXED(1);
4586 FT_Matrix_Multiply(&scaleMat, &transMat);
4587 needsTransform = TRUE;
4588 }
4589
4590 /* World transform */
4591 {
4592 FT_Matrix ftmatrix;
4594
4595 /* Create a freetype matrix, by converting to 16.16 fixpoint format */
4596 IntMatrixFromMx(&ftmatrix, pmx);
4597
4598 if (memcmp(&ftmatrix, &identityMat, sizeof(identityMat)) != 0)
4599 {
4600 FT_Matrix_Multiply(&ftmatrix, &transMat);
4601 needsTransform = TRUE;
4602 }
4603 }
4604
4605 /* Rotation transform */
4606 if (orientation)
4607 {
4608 FT_Matrix rotationMat;
4609 DPRINT("Rotation Trans!\n");
4610 IntEscapeMatrix(&rotationMat, orientation);
4611 FT_Matrix_Multiply(&rotationMat, &transMat);
4612 needsTransform = TRUE;
4613 }
4614
4615 /* Extra transformation specified by caller */
4616 if (pmat2)
4617 {
4618 FT_Matrix extraMat;
4619 DPRINT("MAT2 Matrix Trans!\n");
4620 extraMat.xx = FT_FixedFromFIXED(pmat2->eM11);
4621 extraMat.xy = FT_FixedFromFIXED(pmat2->eM21);
4622 extraMat.yx = FT_FixedFromFIXED(pmat2->eM12);
4623 extraMat.yy = FT_FixedFromFIXED(pmat2->eM22);
4624 FT_Matrix_Multiply(&extraMat, &transMat);
4625 needsTransform = TRUE;
4626 }
4627
4628 if (potm) ExFreePoolWithTag(potm, GDITAG_TEXT); /* It looks like we are finished with potm ATM. */
4629
4630 if (!needsTransform)
4631 {
4632 DPRINT("No Need to be Transformed!\n");
4633 top = (ft_face->glyph->metrics.horiBearingY + 63) & -64;
4634 bottom = (ft_face->glyph->metrics.horiBearingY -
4635 ft_face->glyph->metrics.height) & -64;
4636 gm.gmCellIncX = adv;
4637 gm.gmCellIncY = 0;
4638 }
4639 else
4640 {
4641 INT xc, yc;
4642 FT_Vector vec;
4643 for (xc = 0; xc < 2; xc++)
4644 {
4645 for (yc = 0; yc < 2; yc++)
4646 {
4647 vec.x = (ft_face->glyph->metrics.horiBearingX +
4648 xc * ft_face->glyph->metrics.width);
4649 vec.y = ft_face->glyph->metrics.horiBearingY -
4650 yc * ft_face->glyph->metrics.height;
4651 DPRINT("Vec %ld,%ld\n", vec.x, vec.y);
4652 FT_Vector_Transform(&vec, &transMat);
4653 if (xc == 0 && yc == 0)
4654 {
4655 left = right = vec.x;
4656 top = bottom = vec.y;
4657 }
4658 else
4659 {
4660 if (vec.x < left) left = vec.x;
4661 else if (vec.x > right) right = vec.x;
4662 if (vec.y < bottom) bottom = vec.y;
4663 else if (vec.y > top) top = vec.y;
4664 }
4665 }
4666 }
4667 left = left & -64;
4668 right = (right + 63) & -64;
4669 bottom = bottom & -64;
4670 top = (top + 63) & -64;
4671
4672 DPRINT("Transformed box: (%d,%d - %d,%d)\n", left, top, right, bottom);
4673 vec.x = ft_face->glyph->metrics.horiAdvance;
4674 vec.y = 0;
4675 FT_Vector_Transform(&vec, &transMat);
4676 gm.gmCellIncX = (vec.x+63) >> 6;
4677 gm.gmCellIncY = -((vec.y+63) >> 6);
4678 }
4679 gm.gmBlackBoxX = (right - left) >> 6;
4680 gm.gmBlackBoxY = (top - bottom) >> 6;
4681 gm.gmptGlyphOrigin.x = left >> 6;
4682 gm.gmptGlyphOrigin.y = top >> 6;
4683
4684 DPRINT("CX %d CY %d BBX %u BBY %u GOX %d GOY %d\n",
4685 gm.gmCellIncX, gm.gmCellIncY,
4686 gm.gmBlackBoxX, gm.gmBlackBoxY,
4688
4690
4691 if (iFormat == GGO_METRICS)
4692 {
4693 DPRINT("GGO_METRICS Exit!\n");
4694 *pgm = gm;
4695 return 1; /* FIXME */
4696 }
4697
4698 if (ft_face->glyph->format != ft_glyph_format_outline && iFormat != GGO_BITMAP)
4699 {
4700 DPRINT1("Loaded a bitmap\n");
4701 return GDI_ERROR;
4702 }
4703
4704 switch (iFormat)
4705 {
4706 case GGO_BITMAP:
4707 {
4708 width = gm.gmBlackBoxX;
4709 height = gm.gmBlackBoxY;
4710 pitch = ((width + 31) >> 5) << 2;
4711 needed = pitch * height;
4712
4713 if (!pvBuf || !cjBuf) break;
4714 if (!needed) return GDI_ERROR; /* empty glyph */
4715 if (needed > cjBuf)
4716 return GDI_ERROR;
4717
4718 switch (ft_face->glyph->format)
4719 {
4721 {
4722 BYTE *src = ft_face->glyph->bitmap.buffer, *dst = pvBuf;
4723 INT w = min( pitch, (ft_face->glyph->bitmap.width + 7) >> 3 );
4724 INT h = min( height, ft_face->glyph->bitmap.rows );
4725 while (h--)
4726 {
4728 src += ft_face->glyph->bitmap.pitch;
4729 dst += pitch;
4730 }
4731 break;
4732 }
4733
4735 {
4736 ft_bitmap.width = width;
4737 ft_bitmap.rows = height;
4738 ft_bitmap.pitch = pitch;
4739 ft_bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
4740 ft_bitmap.buffer = pvBuf;
4741
4743 if (needsTransform)
4744 {
4745 FT_Outline_Transform(&ft_face->glyph->outline, &transMat);
4746 }
4747 FT_Outline_Translate(&ft_face->glyph->outline, -left, -bottom );
4748 /* Note: FreeType will only set 'black' bits for us. */
4749 RtlZeroMemory(pvBuf, needed);
4750 FT_Outline_Get_Bitmap(g_FreeTypeLibrary, &ft_face->glyph->outline, &ft_bitmap);
4752 break;
4753 }
4754
4755 default:
4756 DPRINT1("Loaded glyph format %x\n", ft_face->glyph->format);
4757 return GDI_ERROR;
4758 }
4759
4760 break;
4761 }
4762
4763 case GGO_GRAY2_BITMAP:
4764 case GGO_GRAY4_BITMAP:
4765 case GGO_GRAY8_BITMAP:
4766 {
4767 unsigned int mult, row, col;
4768 BYTE *start, *ptr;
4769
4770 width = gm.gmBlackBoxX;
4771 height = gm.gmBlackBoxY;
4772 pitch = (width + 3) / 4 * 4;
4773 needed = pitch * height;
4774
4775 if (!pvBuf || !cjBuf) break;
4776 if (!needed) return GDI_ERROR; /* empty glyph */
4777 if (needed > cjBuf)
4778 return GDI_ERROR;
4779
4780 switch (ft_face->glyph->format)
4781 {
4783 {
4784 BYTE *src = ft_face->glyph->bitmap.buffer, *dst = pvBuf;
4785 INT h = min( height, ft_face->glyph->bitmap.rows );
4786 INT x;
4787 while (h--)
4788 {
4789 for (x = 0; (UINT)x < pitch; x++)
4790 {
4791 if (x < ft_face->glyph->bitmap.width)
4792 dst[x] = (src[x / 8] & (1 << ( (7 - (x % 8))))) ? 0xff : 0;
4793 else
4794 dst[x] = 0;
4795 }
4796 src += ft_face->glyph->bitmap.pitch;
4797 dst += pitch;
4798 }
4799 break;
4800 }
4802 {
4803 ft_bitmap.width = width;
4804 ft_bitmap.rows = height;
4805 ft_bitmap.pitch = pitch;
4806 ft_bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
4807 ft_bitmap.buffer = pvBuf;
4808
4810 if (needsTransform)
4811 {
4812 FT_Outline_Transform(&ft_face->glyph->outline, &transMat);
4813 }
4814 FT_Outline_Translate(&ft_face->glyph->outline, -left, -bottom );
4815 RtlZeroMemory(ft_bitmap.buffer, cjBuf);
4816 FT_Outline_Get_Bitmap(g_FreeTypeLibrary, &ft_face->glyph->outline, &ft_bitmap);
4818
4820 mult = 4;
4821 else if (iFormat == GGO_GRAY4_BITMAP)
4822 mult = 16;
4823 else if (iFormat == GGO_GRAY8_BITMAP)
4824 mult = 64;
4825 else
4826 {
4827 return GDI_ERROR;
4828 }
4829
4830 start = pvBuf;
4831 for (row = 0; row < height; row++)
4832 {
4833 ptr = start;
4834 for (col = 0; col < width; col++, ptr++)
4835 {
4836 *ptr = (((int)*ptr) * mult + 128) / 256;
4837 }
4838 start += pitch;
4839 }
4840
4841 break;
4842 }
4843 default:
4844 DPRINT1("Loaded glyph format %x\n", ft_face->glyph->format);
4845 return GDI_ERROR;
4846 }
4847
4848 break;
4849 }
4850
4851 case GGO_NATIVE:
4852 {
4853 FT_Outline *outline = &ft_face->glyph->outline;
4854
4855 if (cjBuf == 0) pvBuf = NULL; /* This is okay, need cjBuf to allocate. */
4856
4858 if (needsTransform && pvBuf) FT_Outline_Transform(outline, &transMat);
4859
4861
4862 if (!pvBuf || !cjBuf)
4863 {
4865 break;
4866 }
4867 if (needed > cjBuf)
4868 {
4870 return GDI_ERROR;
4871 }
4874 break;
4875 }
4876
4877 case GGO_BEZIER:
4878 {
4879 FT_Outline *outline = &ft_face->glyph->outline;
4880 if (cjBuf == 0) pvBuf = NULL;
4881
4882 if (needsTransform && pvBuf)
4883 {
4885 FT_Outline_Transform(outline, &transMat);
4887 }
4889
4890 if (!pvBuf || !cjBuf)
4891 break;
4892 if (needed > cjBuf)
4893 return GDI_ERROR;
4894
4896 break;
4897 }
4898
4899 default:
4900 DPRINT1("Unsupported format %u\n", iFormat);
4901 return GDI_ERROR;
4902 }
4903
4904 DPRINT("ftGdiGetGlyphOutline END and needed %lu\n", needed);
4905
4906 if (gm.gmBlackBoxX == 0)
4907 gm.gmBlackBoxX = 1;
4908 if (gm.gmBlackBoxY == 0)
4909 gm.gmBlackBoxY = 1;
4910
4911 *pgm = gm;
4912 return needed;
4913}
HFONT hFont
Definition: main.c:53
FORCEINLINE PMATRIX DC_pmxWorldToDevice(PDC pdc)
Definition: coord.h:135
HDC dc
Definition: cylfrac.c:34
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define abs(i)
Definition: fconv.c:206
#define FLOATOBJ_Set1(fo)
Definition: floatobj.h:119
#define FLOATOBJ_Equal1(pf)
Definition: floatobj.h:105
BOOL FASTCALL TextIntUpdateSize(PDC dc, PTEXTOBJ TextObj, PFONTGDI FontGDI, BOOL bDoLock)
Definition: freetype.c:4219
#define ASSERT_FREETYPE_LOCK_NOT_HELD()
Definition: freetype.c:334
static unsigned int get_bezier_glyph_outline(FT_Outline *outline, unsigned int buflen, char *buf)
Definition: freetype.c:3955
static unsigned int get_native_glyph_outline(FT_Outline *outline, unsigned int buflen, char *buf)
Definition: freetype.c:3882
static VOID FASTCALL IntMatrixFromMx(FT_Matrix *pmat, const MATRIX *pmx)
Definition: freetype.c:1102
static VOID FASTCALL IntEscapeMatrix(FT_Matrix *pmat, LONG lfEscapement)
Definition: freetype.c:1089
static const FT_Matrix identityMat
Definition: freetype.c:313
static __inline FT_Fixed FT_FixedFromFIXED(FIXED f)
Definition: freetype.c:672
FT_Load_Glyph(FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags)
Definition: ftobjs.c:796
#define FT_LOAD_NO_BITMAP
Definition: freetype.h:3025
#define FT_LOAD_NO_HINTING
Definition: freetype.h:3023
#define FT_LOAD_DEFAULT
Definition: freetype.h:3021
#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
Definition: freetype.h:3030
FT_Vector_Transform(FT_Vector *vector, const FT_Matrix *matrix)
Definition: ftoutln.c:683
FT_Vector * vec
Definition: ftbbox.c:469
#define INT_TO_FIXED(x)
Definition: ftcalc.h:448
FT_Matrix_Multiply(const FT_Matrix *a, FT_Matrix *b)
Definition: ftcalc.c:660
#define ft_glyph_format_bitmap
Definition: ftimage.h:759
@ FT_PIXEL_MODE_MONO
Definition: ftimage.h:183
@ FT_PIXEL_MODE_GRAY
Definition: ftimage.h:184
#define ft_glyph_format_outline
Definition: ftimage.h:760
FT_Outline_Translate(const FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
Definition: ftoutln.c:507
FT_Outline_Get_Bitmap(FT_Library library, FT_Outline *outline, const FT_Bitmap *abitmap)
Definition: ftoutln.c:656
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:706
signed int FT_Int
Definition: fttypes.h:220
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum src
Definition: glext.h:6340
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLdouble GLdouble right
Definition: glext.h:10859
GLint left
Definition: glext.h:7726
GLenum GLenum dst
Definition: glext.h:6340
GLint GLint bottom
Definition: glext.h:7726
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define error(str)
Definition: mkdosfs.c:1605
static PVOID ptr
Definition: dispmode.c:27
static const MAT2 mat
Definition: font.c:66
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define min(a, b)
Definition: monoChain.cc:55
long LONG
Definition: pedump.c:60
unsigned int width
Definition: ftimage.h:263
unsigned char * buffer
Definition: ftimage.h:265
unsigned char pixel_mode
Definition: ftimage.h:267
unsigned int rows
Definition: ftimage.h:262
int pitch
Definition: ftimage.h:264
FT_GlyphSlot glyph
Definition: freetype.h:1065
FT_Bitmap bitmap
Definition: freetype.h:1886
FT_Outline outline
Definition: freetype.h:1890
FT_Glyph_Metrics metrics
Definition: freetype.h:1879
FT_Glyph_Format format
Definition: freetype.h:1884
FT_Fixed xx
Definition: fttypes.h:392
FT_Fixed yx
Definition: fttypes.h:393
FT_Fixed yy
Definition: fttypes.h:393
FT_Fixed xy
Definition: fttypes.h:392
FT_Pos x
Definition: ftimage.h:77
FT_Pos y
Definition: ftimage.h:78
LONG lfOrientation
Definition: dimm.idl:62
HANDLE hlfntNew
Definition: ntgdihdl.h:330
short gmCellIncX
Definition: wingdi.h:2891
UINT gmBlackBoxY
Definition: wingdi.h:2889
UINT gmBlackBoxX
Definition: wingdi.h:2888
short gmCellIncY
Definition: wingdi.h:2892
POINT gmptGlyphOrigin
Definition: wingdi.h:2890
FIXED eM22
Definition: wingdi.h:2922
FIXED eM21
Definition: wingdi.h:2921
FIXED eM11
Definition: wingdi.h:2919
FIXED eM12
Definition: wingdi.h:2920
FLOATL eM11
Definition: winddi.h:1234
Definition: mesh.c:5330
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
PTEXTOBJ FASTCALL RealizeFontInit(_In_ HFONT hFont)
Definition: font.c:433
FORCEINLINE VOID TEXTOBJ_UnlockText(PLFONT plfnt)
Definition: text.h:96
#define FLOATOBJ_DivLong(pf, l)
Definition: winddi.h:2829
_In_ DWORD cjBuf
Definition: winddi.h:3827
FLOAT FLOATOBJ
Definition: winddi.h:677
#define FLOATOBJ_Mul(pf, pf1)
Definition: winddi.h:2824
#define FLOATOBJ_MulLong(pf, l)
Definition: winddi.h:2826
#define FLOATOBJ_GetLong(pf)
Definition: winddi.h:2817
#define FLOATOBJ_SetFloat(pf, f)
Definition: winddi.h:2814
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
#define FLOATOBJ_SetLong(pf, l)
Definition: winddi.h:2815
_In_ SIZEL _In_ ULONG iFormat
Definition: winddi.h:3468
#define FLOATOBJ_AddLong(pf, l)
Definition: winddi.h:2820
#define ERROR_GEN_FAILURE
Definition: winerror.h:256
#define GGO_GRAY2_BITMAP
Definition: wingdi.h:852
#define GGO_GLYPH_INDEX
Definition: wingdi.h:855
#define GGO_UNHINTED
Definition: wingdi.h:856
#define GGO_GRAY8_BITMAP
Definition: wingdi.h:854
#define GGO_BITMAP
Definition: wingdi.h:849
#define GGO_GRAY4_BITMAP
Definition: wingdi.h:853
#define GGO_NATIVE
Definition: wingdi.h:850
#define GGO_METRICS
Definition: wingdi.h:848
#define GGO_BEZIER
Definition: wingdi.h:851
#define XFORMOBJ_vInit
Definition: xformobj.h:12
#define XFORMOBJ_iGetXform
Definition: xformobj.h:9
unsigned char BYTE
Definition: xxhash.c:193

Referenced by NtGdiGetGlyphOutline(), and PATH_ExtTextOut().

◆ ftGdiGetKerningPairs()

DWORD FASTCALL ftGdiGetKerningPairs ( PFONTGDI  Font,
DWORD  cPairs,
LPKERNINGPAIR  pKerningPair 
)

Definition at line 6464 of file freetype.c.

6467{
6468 DWORD Count = 0;
6469 INT i = 0;
6470 FT_Face face = Font->SharedFace->Face;
6471
6472 if (FT_HAS_KERNING(face) && face->charmap->encoding == FT_ENCODING_UNICODE)
6473 {
6474 FT_UInt previous_index = 0, glyph_index = 0;
6475 FT_ULong char_code, char_previous;
6476 FT_Vector delta;
6477
6478 char_previous = char_code = FT_Get_First_Char(face, &glyph_index);
6479
6481
6482 while (glyph_index)
6483 {
6484 if (previous_index && glyph_index)
6485 {
6486 FT_Get_Kerning(face, previous_index, glyph_index, FT_KERNING_DEFAULT, &delta);
6487
6488 if (pKerningPair && cPairs)
6489 {
6490 pKerningPair[i].wFirst = char_previous;
6491 pKerningPair[i].wSecond = char_code;
6492 pKerningPair[i].iKernAmount = delta.x;
6493 i++;
6494 if (i == cPairs) break;
6495 }
6496 Count++;
6497 }
6498 previous_index = glyph_index;
6499 char_previous = char_code;
6500 char_code = FT_Get_Next_Char(face, char_code, &glyph_index);
6501 }
6503 }
6504 return Count;
6505}
FT_Get_Next_Char(FT_Face face, FT_ULong char_code, FT_UInt *agindex)
Definition: ftobjs.c:3785
FT_Get_Kerning(FT_Face face, FT_UInt left_glyph, FT_UInt right_glyph, FT_UInt kern_mode, FT_Vector *akerning)
Definition: ftobjs.c:3411
@ FT_KERNING_DEFAULT
Definition: freetype.h:3406
#define FT_HAS_KERNING(face)
Definition: freetype.h:1256
int Count
Definition: noreturn.cpp:7
WORD wSecond
Definition: wingdi.h:2911
int iKernAmount
Definition: wingdi.h:2912

Referenced by GreGetKerningPairs(), and NtGdiGetKerningPairs().

◆ ftGdiGetRasterizerCaps()

BOOL FASTCALL ftGdiGetRasterizerCaps ( LPRASTERIZER_STATUS  lprs)

Definition at line 3751 of file freetype.c.

3752{
3753 if ( lprs )
3754 {
3755 lprs->nSize = sizeof(RASTERIZER_STATUS);
3756 lprs->wFlags = TT_AVAILABLE | TT_ENABLED;
3757 lprs->nLanguageID = gusLanguageID;
3758 return TRUE;
3759 }
3761 return FALSE;
3762}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
USHORT gusLanguageID
Definition: init.c:12
#define TT_ENABLED
Definition: wingdi.h:889
struct _RASTERIZER_STATUS RASTERIZER_STATUS
#define TT_AVAILABLE
Definition: wingdi.h:888

Referenced by NtGdiGetRasterizerCaps().

◆ ftGdiGetTextCharsetInfo()

INT FASTCALL ftGdiGetTextCharsetInfo ( PDC  Dc,
LPFONTSIGNATURE  lpSig,
DWORD  dwFlags 
)

Definition at line 5078 of file freetype.c.

5082{
5083 PDC_ATTR pdcattr;
5084 UINT Ret = DEFAULT_CHARSET;
5085 INT i;
5086 HFONT hFont;
5087 PTEXTOBJ TextObj;
5088 PFONTGDI FontGdi;
5090 TT_OS2 *pOS2;
5091 FT_Face Face;
5092 CHARSETINFO csi;
5093 DWORD cp, fs0;
5094 USHORT usACP, usOEM;
5095
5096 pdcattr = Dc->pdcattr;
5097 hFont = pdcattr->hlfntNew;
5098 TextObj = RealizeFontInit(hFont);
5099
5100 if (!TextObj)
5101 {
5103 return Ret;
5104 }
5105 FontGdi = ObjToGDI(TextObj->Font, FONT);
5106 Face = FontGdi->SharedFace->Face;
5107 TEXTOBJ_UnlockText(TextObj);
5108
5109 memset(&fs, 0, sizeof(FONTSIGNATURE));
5111 pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
5112 if (NULL != pOS2)
5113 {
5114 fs.fsCsb[0] = pOS2->ulCodePageRange1;
5115 fs.fsCsb[1] = pOS2->ulCodePageRange2;
5116 fs.fsUsb[0] = pOS2->ulUnicodeRange1;
5117 fs.fsUsb[1] = pOS2->ulUnicodeRange2;
5118 fs.fsUsb[2] = pOS2->ulUnicodeRange3;
5119 fs.fsUsb[3] = pOS2->ulUnicodeRange4;
5120 if (pOS2->version == 0)
5121 {
5122 FT_UInt dummy;
5123
5124 if (FT_Get_First_Char( Face, &dummy ) < 0x100)
5125 fs.fsCsb[0] |= FS_LATIN1;
5126 else
5127 fs.fsCsb[0] |= FS_SYMBOL;
5128 }
5129 }
5130 pOS2 = NULL;
5132 DPRINT("Csb 1=%x 0=%x\n", fs.fsCsb[1],fs.fsCsb[0]);
5133 if (fs.fsCsb[0] == 0)
5134 { /* Let's see if we can find any interesting cmaps */
5135 for (i = 0; i < Face->num_charmaps; i++)
5136 {
5137 switch (Face->charmaps[i]->encoding)
5138 {
5139 case FT_ENCODING_UNICODE:
5140 case FT_ENCODING_APPLE_ROMAN:
5141 fs.fsCsb[0] |= FS_LATIN1;
5142 break;
5143 case FT_ENCODING_MS_SYMBOL:
5144 fs.fsCsb[0] |= FS_SYMBOL;
5145 break;
5146 default:
5147 break;
5148 }
5149 }
5150 }
5151 if (lpSig)
5152 {
5153 RtlCopyMemory(lpSig, &fs, sizeof(FONTSIGNATURE));
5154 }
5155
5156 RtlGetDefaultCodePage(&usACP, &usOEM);
5157 cp = usACP;
5158
5160 if (csi.fs.fsCsb[0] & fs.fsCsb[0])
5161 {
5162 DPRINT("Hit 1\n");
5163 Ret = csi.ciCharset;
5164 goto Exit;
5165 }
5166
5167 for (i = 0; i < MAXTCIINDEX; i++)
5168 {
5169 fs0 = 1L << i;
5170 if (fs.fsCsb[0] & fs0)
5171 {
5172 if (IntTranslateCharsetInfo(&fs0, &csi, TCI_SRCFONTSIG))
5173 {
5174 // *cp = csi.ciACP;
5175 DPRINT("Hit 2\n");
5176 Ret = csi.ciCharset;
5177 goto Exit;
5178 }
5179 else
5180 DPRINT1("TCI failing on %x\n", fs0);
5181 }
5182 }
5183Exit:
5184 DPRINT("CharSet %u CodePage %u\n", csi.ciCharset, csi.ciACP);
5185 return (MAKELONG(csi.ciACP, csi.ciCharset));
5186}
POINT cp
Definition: magnifier.c:59
NTSYSAPI VOID NTAPI RtlGetDefaultCodePage(_Out_ PUSHORT AnsiCodePage, _Out_ PUSHORT OemCodePage)
#define memset(x, y, z)
Definition: compat.h:39
static void Exit(void)
Definition: sock.c:1330
FONTSIGNATURE fs
Definition: wingdi.h:1994
DWORD fsCsb[2]
Definition: wingdi.h:1989
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define TCI_SRCCODEPAGE
Definition: wingdi.h:962

Referenced by DC_InitHack(), IntGetFontLanguageInfo(), NtGdiGetCharSet(), and NtGdiGetTextCharsetInfo().

◆ ftGdiGetTextMetricsW()

BOOL FASTCALL ftGdiGetTextMetricsW ( HDC  hDC,
PTMW_INTERNAL  ptmwi 
)

Definition at line 5265 of file freetype.c.

5268{
5269 PDC dc;
5270 PDC_ATTR pdcattr;
5271 PTEXTOBJ TextObj;
5272 PFONTGDI FontGDI;
5273 FT_Face Face;
5274 TT_OS2 *pOS2;
5275 TT_HoriHeader *pHori;
5277 ULONG Error;
5279 LOGFONTW *plf;
5280
5281 if (!ptmwi)
5282 {
5284 return FALSE;
5285 }
5286 RtlZeroMemory(ptmwi, sizeof(TMW_INTERNAL));
5287
5288 if (!(dc = DC_LockDc(hDC)))
5289 {
5291 return FALSE;
5292 }
5293 pdcattr = dc->pdcattr;
5294 TextObj = RealizeFontInit(pdcattr->hlfntNew);
5295 if (NULL != TextObj)
5296 {
5297 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
5298 FontGDI = ObjToGDI(TextObj->Font, FONT);
5299
5300 Face = FontGDI->SharedFace->Face;
5301
5302 // NOTE: GetTextMetrics simply ignores lfEscapement and XFORM.
5304 Error = IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight);
5305 FT_Set_Transform(Face, NULL, NULL);
5306
5308
5309 if (0 != Error)
5310 {
5311 DPRINT1("Error in setting pixel sizes: %u\n", Error);
5313 }
5314 else
5315 {
5317
5319
5320 Error = FT_Get_WinFNT_Header(Face, &Win);
5321 pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
5322 pHori = FT_Get_Sfnt_Table(Face, ft_sfnt_hhea);
5323
5324 if (!pOS2 && Error)
5325 {
5326 DPRINT1("Can't find OS/2 table - not TT font?\n");
5328 }
5329
5330 if (!pHori && Error)
5331 {
5332 DPRINT1("Can't find HHEA table - not TT font?\n");
5334 }
5335
5336 if (NT_SUCCESS(Status))
5337 {
5338 FillTM(&ptmwi->TextMetric, FontGDI, pOS2, pHori, (Error ? NULL : &Win));
5339
5340 /* FIXME: Fill Diff member */
5341 }
5342
5344 }
5345 TEXTOBJ_UnlockText(TextObj);
5346 }
5347 else
5348 {
5350 }
5351 DC_UnlockDc(dc);
5352
5353 if (!NT_SUCCESS(Status))
5354 {
5356 return FALSE;
5357 }
5358 return TRUE;
5359}
static HDC hDC
Definition: 3dtext.c:33
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:238
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:220
static void FASTCALL FillTM(TEXTMETRICW *TM, PFONTGDI FontGDI, TT_OS2 *pOS2, TT_HoriHeader *pHori, FT_WinFNT_HeaderRec *pFNT)
Definition: freetype.c:2837
FT_Get_WinFNT_Header(FT_Face face, FT_WinFNT_HeaderRec *aheader)
Definition: ftwinfnt.c:28
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:559
Definition: polytest.cpp:41
TEXTMETRICW TextMetric
Definition: ntgdityp.h:370
#define ft_sfnt_hhea
Definition: tttables.h:639
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31

Referenced by GreGetTextMetricsW(), IntGetCharDimensions(), and NtGdiGetTextMetricsW().

◆ ftGdiRealizationInfo()

BOOL FASTCALL ftGdiRealizationInfo ( PFONTGDI  Font,
PREALIZATION_INFO  Info 
)

Definition at line 6445 of file freetype.c.

6446{
6447 if (FT_HAS_FIXED_SIZES(Font->SharedFace->Face))
6448 Info->iTechnology = RI_TECH_BITMAP;
6449 else
6450 {
6451 if (FT_IS_SCALABLE(Font->SharedFace->Face))
6452 Info->iTechnology = RI_TECH_SCALABLE;
6453 else
6454 Info->iTechnology = RI_TECH_FIXED;
6455 }
6456 Info->iUniq = Font->FontObj.iUniq;
6457 Info->dwUnknown = -1;
6458 return TRUE;
6459}
#define FT_HAS_FIXED_SIZES(face)
Definition: freetype.h:1320
#define RI_TECH_SCALABLE
Definition: ntgdityp.h:273
#define RI_TECH_FIXED
Definition: ntgdityp.h:272
#define RI_TECH_BITMAP
Definition: ntgdityp.h:271

Referenced by NtGdiGetRealizationInfo().

◆ ftGetFontUnicodeRanges()

DWORD FASTCALL ftGetFontUnicodeRanges ( PFONTGDI  Font,
PGLYPHSET  glyphset 
)

Definition at line 5191 of file freetype.c.

5192{
5193 DWORD size = 0;
5194 DWORD num_ranges = 0;
5195 FT_Face face = Font->SharedFace->Face;
5196
5197 if (face->charmap == NULL)
5198 {
5199 DPRINT1("FIXME: No charmap selected! This is a BUG!\n");
5200 return 0;
5201 }
5202
5203 if (face->charmap->encoding == FT_ENCODING_UNICODE)
5204 {
5205 FT_UInt glyph_code = 0;
5206 FT_ULong char_code, char_code_prev;
5207
5208 char_code_prev = char_code = FT_Get_First_Char(face, &glyph_code);
5209
5210 DPRINT("Face encoding FT_ENCODING_UNICODE, number of glyphs %ld, first glyph %u, first char %04lx\n",
5211 face->num_glyphs, glyph_code, char_code);
5212
5213 if (!glyph_code) return 0;
5214
5215 if (glyphset)
5216 {
5217 glyphset->ranges[0].wcLow = (USHORT)char_code;
5218 glyphset->ranges[0].cGlyphs = 0;
5219 glyphset->cGlyphsSupported = 0;
5220 }
5221
5222 num_ranges = 1;
5223 while (glyph_code)
5224 {
5225 if (char_code < char_code_prev)
5226 {
5227 DPRINT1("Expected increasing char code from FT_Get_Next_Char\n");
5228 return 0;
5229 }
5230 if (char_code - char_code_prev > 1)
5231 {
5232 num_ranges++;
5233 if (glyphset)
5234 {
5235 glyphset->ranges[num_ranges - 1].wcLow = (USHORT)char_code;
5236 glyphset->ranges[num_ranges - 1].cGlyphs = 1;
5237 glyphset->cGlyphsSupported++;
5238 }
5239 }
5240 else if (glyphset)
5241 {
5242 glyphset->ranges[num_ranges - 1].cGlyphs++;
5243 glyphset->cGlyphsSupported++;
5244 }
5245 char_code_prev = char_code;
5246 char_code = FT_Get_Next_Char(face, char_code, &glyph_code);
5247 }
5248 }
5249 else
5250 DPRINT1("Encoding %i not supported\n", face->charmap->encoding);
5251
5252 size = sizeof(GLYPHSET) + sizeof(WCRANGE) * (num_ranges - 1);
5253 if (glyphset)
5254 {
5255 glyphset->cbThis = size;
5256 glyphset->cRanges = num_ranges;
5257 glyphset->flAccel = 0;
5258 }
5259 return size;
5260}
GLsizeiptr size
Definition: glext.h:5919

Referenced by NtGdiGetFontUnicodeRanges().

◆ FTVectorToPOINTFX()

static __inline void FTVectorToPOINTFX ( FT_Vector vec,
POINTFX pt 
)
static

Definition at line 658 of file freetype.c.

659{
660 pt->x.value = vec->x >> 6;
661 pt->x.fract = (vec->x & 0x3f) << 10;
662 pt->x.fract |= ((pt->x.fract >> 6) | (pt->x.fract >> 12));
663 pt->y.value = vec->y >> 6;
664 pt->y.fract = (vec->y & 0x3f) << 10;
665 pt->y.fract |= ((pt->y.fract >> 6) | (pt->y.fract >> 12));
666}
#define pt(x, y)
Definition: drawing.c:79
char * value
Definition: compiler.c:67

Referenced by get_bezier_glyph_outline(), and get_native_glyph_outline().

◆ get_bezier_glyph_outline()

static unsigned int get_bezier_glyph_outline ( FT_Outline outline,
unsigned int  buflen,
char buf 
)
static

Definition at line 3955 of file freetype.c.

3956{
3957 /* Convert the quadratic Beziers to cubic Beziers.
3958 The parametric eqn for a cubic Bezier is, from PLRM:
3959 r(t) = at^3 + bt^2 + ct + r0
3960 with the control points:
3961 r1 = r0 + c/3
3962 r2 = r1 + (c + b)/3
3963 r3 = r0 + c + b + a
3964
3965 A quadratic Bezier has the form:
3966 p(t) = (1-t)^2 p0 + 2(1-t)t p1 + t^2 p2
3967
3968 So equating powers of t leads to:
3969 r1 = 2/3 p1 + 1/3 p0
3970 r2 = 2/3 p1 + 1/3 p2
3971 and of course r0 = p0, r3 = p2
3972 */
3973 int contour, point = 0, first_pt;
3974 TTPOLYGONHEADER *pph;
3975 TTPOLYCURVE *ppc;
3976 DWORD pph_start, cpfx, type;
3977 FT_Vector cubic_control[4];
3978 unsigned int needed = 0;
3979
3980 for (contour = 0; contour < outline->n_contours; contour++)
3981 {
3982 pph_start = needed;
3983 pph = (TTPOLYGONHEADER *)(buf + needed);
3984 first_pt = point;
3985 if (buf)
3986 {
3987 pph->dwType = TT_POLYGON_TYPE;
3988 FTVectorToPOINTFX(&outline->points[point], &pph->pfxStart);
3989 }
3990 needed += sizeof(*pph);
3991 point++;
3992 while (point <= outline->contours[contour])
3993 {
3994 ppc = (TTPOLYCURVE *)(buf + needed);
3995 type = (outline->tags[point] & FT_Curve_Tag_On) ?
3997 cpfx = 0;
3998 do
3999 {
4000 if (type == TT_PRIM_LINE)
4001 {
4002 if (buf)
4003 FTVectorToPOINTFX(&outline->points[point], &ppc->apfx[cpfx]);
4004 cpfx++;
4005 point++;
4006 }
4007 else
4008 {
4009 /* Unlike QSPLINEs, CSPLINEs always have their endpoint
4010 so cpfx = 3n */
4011
4012 /* FIXME: Possible optimization in endpoint calculation
4013 if there are two consecutive curves */
4014 cubic_control[0] = outline->points[point-1];
4015 if (!(outline->tags[point-1] & FT_Curve_Tag_On))
4016 {
4017 cubic_control[0].x += outline->points[point].x + 1;
4018 cubic_control[0].y += outline->points[point].y + 1;
4019 cubic_control[0].x >>= 1;
4020 cubic_control[0].y >>= 1;
4021 }
4022 if (point+1 > outline->contours[contour])
4023 cubic_control[3] = outline->points[first_pt];
4024 else
4025 {
4026 cubic_control[3] = outline->points[point+1];
4027 if (!(outline->tags[point+1] & FT_Curve_Tag_On))
4028 {
4029 cubic_control[3].x += outline->points[point].x + 1;
4030 cubic_control[3].y += outline->points[point].y + 1;
4031 cubic_control[3].x >>= 1;
4032 cubic_control[3].y >>= 1;
4033 }
4034 }
4035 /* r1 = 1/3 p0 + 2/3 p1
4036 r2 = 1/3 p2 + 2/3 p1 */
4037 cubic_control[1].x = (2 * outline->points[point].x + 1) / 3;
4038 cubic_control[1].y = (2 * outline->points[point].y + 1) / 3;
4039 cubic_control[2] = cubic_control[1];
4040 cubic_control[1].x += (cubic_control[0].x + 1) / 3;
4041 cubic_control[1].y += (cubic_control[0].y + 1) / 3;
4042 cubic_control[2].x += (cubic_control[3].x + 1) / 3;
4043 cubic_control[2].y += (cubic_control[3].y + 1) / 3;
4044 if (buf)
4045 {
4046 FTVectorToPOINTFX(&cubic_control[1], &ppc->apfx[cpfx]);
4047 FTVectorToPOINTFX(&cubic_control[2], &ppc->apfx[cpfx+1]);
4048 FTVectorToPOINTFX(&cubic_control[3], &ppc->apfx[cpfx+2]);
4049 }
4050 cpfx += 3;
4051 point++;
4052 }
4053 } while (point <= outline->contours[contour] &&
4054 (outline->tags[point] & FT_Curve_Tag_On) ==
4055 (outline->tags[point-1] & FT_Curve_Tag_On));
4056 /* At the end of a contour Windows adds the start point,
4057 but only for Beziers and we've already done that.
4058 */
4059 if (point <= outline->contours[contour] &&
4060 outline->tags[point] & FT_Curve_Tag_On)
4061 {
4062 /* This is the closing pt of a bezier, but we've already
4063 added it, so just inc point and carry on */
4064 point++;
4065 }
4066 if (buf)
4067 {
4068 ppc->wType = type;
4069 ppc->cpfx = cpfx;
4070 }
4071 needed += sizeof(*ppc) + (cpfx - 1) * sizeof(POINTFX);
4072 }
4073 if (buf)
4074 pph->cb = needed - pph_start;
4075 }
4076 return needed;
4077}
POINTL point
Definition: edittest.c:50
static __inline void FTVectorToPOINTFX(FT_Vector *vec, POINTFX *pt)
Definition: freetype.c:658
#define FT_Curve_Tag_On
Definition: ftimage.h:478
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
POINTFX apfx[1]
Definition: wingdi.h:3160
POINTFX pfxStart
Definition: wingdi.h:3165
#define TT_PRIM_CSPLINE
Definition: wingdi.h:1321
#define TT_POLYGON_TYPE
Definition: wingdi.h:1318
#define TT_PRIM_LINE
Definition: wingdi.h:1319

Referenced by ftGdiGetGlyphOutline().

◆ get_glyph_index()

static FT_UInt FASTCALL get_glyph_index ( FT_Face  ft_face,
UINT  glyph 
)
inlinestatic

Definition at line 4322 of file freetype.c.

4323{
4324 FT_UInt ret;
4325
4326 if (face_has_symbol_charmap(ft_face))
4327 {
4328 ret = get_glyph_index_symbol(ft_face, glyph);
4329 if (ret != 0)
4330 return ret;
4331 }
4332
4333 return FT_Get_Char_Index(ft_face, glyph);
4334}
return ret
Definition: mutex.c:146
static FT_UInt FASTCALL get_glyph_index_symbol(FT_Face ft_face, UINT glyph)
Definition: freetype.c:4308
FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
Definition: ftobjs.c:3731

Referenced by FontLink_Chain_FindGlyph(), get_glyph_index_flagged(), and NtGdiGetGlyphIndicesW().

◆ get_glyph_index_flagged()

static FT_UInt FASTCALL get_glyph_index_flagged ( FT_Face  face,
FT_ULong  code,
BOOL  fCodeAsIndex 
)
inlinestatic

Definition at line 4337 of file freetype.c.

4338{
4339 return (fCodeAsIndex ? code : get_glyph_index(face, code));
4340}

Referenced by FontLink_Chain_FindGlyph(), ftGdiGetGlyphOutline(), GreGetCharABCWidthsW(), and GreGetCharWidthW().

◆ get_glyph_index_symbol()

static FT_UInt FASTCALL get_glyph_index_symbol ( FT_Face  ft_face,
UINT  glyph 
)
inlinestatic

Definition at line 4308 of file freetype.c.

4309{
4310 FT_UInt ret;
4311
4312 if (glyph < 0x100) glyph += 0xf000;
4313 /* there are a number of old pre-Unicode "broken" TTFs, which
4314 do have symbols at U+00XX instead of U+f0XX */
4315 if (!(ret = FT_Get_Char_Index(ft_face, glyph)))
4316 ret = FT_Get_Char_Index(ft_face, glyph - 0xf000);
4317
4318 return ret;
4319}

Referenced by get_glyph_index().

◆ get_native_glyph_outline()

static unsigned int get_native_glyph_outline ( FT_Outline outline,
unsigned int  buflen,
char buf 
)
static

Definition at line 3882 of file freetype.c.

3883{
3884 TTPOLYGONHEADER *pph;
3885 TTPOLYCURVE *ppc;
3886 int needed = 0, point = 0, contour, first_pt;
3887 unsigned int pph_start, cpfx;
3888 DWORD type;
3889
3890 for (contour = 0; contour < outline->n_contours; contour++)
3891 {
3892 /* Ignore contours containing one point */
3893 if (point == outline->contours[contour])
3894 {
3895 point++;
3896 continue;
3897 }
3898
3899 pph_start = needed;
3900 pph = (TTPOLYGONHEADER *)(buf + needed);
3901 first_pt = point;
3902 if (buf)
3903 {
3904 pph->dwType = TT_POLYGON_TYPE;
3905 FTVectorToPOINTFX(&outline->points[point], &pph->pfxStart);
3906 }
3907 needed += sizeof(*pph);
3908 point++;
3909 while (point <= outline->contours[contour])
3910 {
3911 ppc = (TTPOLYCURVE *)(buf + needed);
3912 type = (outline->tags[point] & FT_Curve_Tag_On) ?
3914 cpfx = 0;
3915 do
3916 {
3917 if (buf)
3918 FTVectorToPOINTFX(&outline->points[point], &ppc->apfx[cpfx]);
3919 cpfx++;
3920 point++;
3921 } while (point <= outline->contours[contour] &&
3922 (outline->tags[point] & FT_Curve_Tag_On) ==
3923 (outline->tags[point-1] & FT_Curve_Tag_On));
3924 /* At the end of a contour Windows adds the start point, but
3925 only for Beziers */
3926 if (point > outline->contours[contour] &&
3927 !(outline->tags[point-1] & FT_Curve_Tag_On))
3928 {
3929 if (buf)
3930 FTVectorToPOINTFX(&outline->points[first_pt], &ppc->apfx[cpfx]);
3931 cpfx++;
3932 }
3933 else if (point <= outline->contours[contour] &&
3934 outline->tags[point] & FT_Curve_Tag_On)
3935 {
3936 /* add closing pt for bezier */
3937 if (buf)
3938 FTVectorToPOINTFX(&outline->points[point], &ppc->apfx[cpfx]);
3939 cpfx++;
3940 point++;
3941 }
3942 if (buf)
3943 {
3944 ppc->wType = type;
3945 ppc->cpfx = cpfx;
3946 }
3947 needed += sizeof(*ppc) + (cpfx - 1) * sizeof(POINTFX);
3948 }
3949 if (buf)
3950 pph->cb = needed - pph_start;
3951 }
3952 return needed;
3953}
#define TT_PRIM_QSPLINE
Definition: wingdi.h:1320

Referenced by ftGdiGetGlyphOutline().

◆ GetFontFamilyInfoForList()

static BOOLEAN FASTCALL GetFontFamilyInfoForList ( const LOGFONTW LogFont,
PFONTFAMILYINFO  Info,
LPCWSTR  NominalName,
LONG pCount,
LONG  MaxCount,
PLIST_ENTRY  Head 
)
static

Definition at line 3626 of file freetype.c.

3632{
3634 PFONT_ENTRY CurrentEntry;
3635 FONTGDI *FontGDI;
3636 FONTFAMILYINFO InfoEntry;
3637 LONG Count = *pCount;
3638
3639 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
3640 {
3641 CurrentEntry = CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry);
3642 FontGDI = CurrentEntry->Font;
3643 ASSERT(FontGDI);
3644
3645 if (LogFont->lfCharSet != DEFAULT_CHARSET &&
3646 LogFont->lfCharSet != FontGDI->CharSet)
3647 {
3648 continue; /* charset mismatch */
3649 }
3650
3651 /* get one info entry */
3652 FontFamilyFillInfo(&InfoEntry, NULL, NULL, FontGDI);
3653
3654 if (LogFont->lfFaceName[0] != UNICODE_NULL)
3655 {
3656 /* check name */
3657 if (_wcsnicmp(LogFont->lfFaceName,
3659 RTL_NUMBER_OF(LogFont->lfFaceName) - 1) != 0 &&
3660 _wcsnicmp(LogFont->lfFaceName,
3661 InfoEntry.EnumLogFontEx.elfFullName,
3662 RTL_NUMBER_OF(LogFont->lfFaceName) - 1) != 0)
3663 {
3664 continue;
3665 }
3666 }
3667
3668 if (NominalName)
3669 {
3670 /* store the nominal name */
3672 sizeof(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName),
3673 NominalName);
3674 }
3675
3676 /* store one entry to Info */
3677 if (0 <= Count && Count < MaxCount)
3678 {
3679 RtlCopyMemory(&Info[Count], &InfoEntry, sizeof(InfoEntry));
3680 }
3681 Count++;
3682 }
3683
3684 *pCount = Count;
3685
3686 return TRUE;
3687}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:195
static void FASTCALL FontFamilyFillInfo(PFONTFAMILYINFO Info, LPCWSTR FaceName, LPCWSTR FullName, PFONTGDI FontGDI)
Definition: freetype.c:3443
WCHAR elfFullName[LF_FULLFACESIZE]
Definition: wingdi.h:3149
WCHAR lfFaceName[LF_FACESIZE]
Definition: wingdi.h:2356

Referenced by GetFontFamilyInfoForSubstitutes(), and IntGetFontFamilyInfo().

◆ GetFontFamilyInfoForSubstitutes()

static BOOLEAN FASTCALL GetFontFamilyInfoForSubstitutes ( const LOGFONTW LogFont,
PFONTFAMILYINFO  Info,
LONG pCount,
LONG  MaxCount 
)
static

Definition at line 3690 of file freetype.c.

3694{
3695 PLIST_ENTRY pEntry, pHead = &g_FontSubstListHead;
3696 PFONTSUBST_ENTRY pCurrentEntry;
3697 PUNICODE_STRING pFromW, pToW;
3698 LOGFONTW lf = *LogFont;
3700
3701 for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink)
3702 {
3703 pCurrentEntry = CONTAINING_RECORD(pEntry, FONTSUBST_ENTRY, ListEntry);
3704
3705 pFromW = &pCurrentEntry->FontNames[FONTSUBST_FROM];
3706 if (LogFont->lfFaceName[0] != UNICODE_NULL)
3707 {
3708 /* check name */
3709 if (_wcsicmp(LogFont->lfFaceName, pFromW->Buffer) != 0)
3710 continue; /* mismatch */
3711 }
3712
3713 pToW = &pCurrentEntry->FontNames[FONTSUBST_TO];
3714 if (RtlEqualUnicodeString(pFromW, pToW, TRUE) &&
3715 pCurrentEntry->CharSets[FONTSUBST_FROM] ==
3716 pCurrentEntry->CharSets[FONTSUBST_TO])
3717 {
3718 /* identical mapping */
3719 continue;
3720 }
3721
3722 /* substitute and get the real name */
3723 IntUnicodeStringToBuffer(lf.lfFaceName, sizeof(lf.lfFaceName), pFromW);
3725 if (LogFont->lfCharSet != DEFAULT_CHARSET && LogFont->lfCharSet != lf.lfCharSet)
3726 continue;
3727
3728 /* search in global fonts */
3730 GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount, &g_FontListHead);
3731
3732 /* search in private fonts */
3733 IntLockProcessPrivateFonts(Win32Process);
3734 GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount,
3735 &Win32Process->PrivateFontListHead);
3736 IntUnLockProcessPrivateFonts(Win32Process);
3738
3739 if (LogFont->lfFaceName[0] != UNICODE_NULL)
3740 {
3741 /* it's already matched to the exact name and charset if the name
3742 was specified at here, then so don't scan more for another name */
3743 break;
3744 }
3745 }
3746
3747 return TRUE;
3748}
static BOOLEAN FASTCALL GetFontFamilyInfoForList(const LOGFONTW *LogFont, PFONTFAMILYINFO Info, LPCWSTR NominalName, LONG *pCount, LONG MaxCount, PLIST_ENTRY Head)
Definition: freetype.c:3626
#define FONTSUBST_FROM
Definition: font.h:69
#define FONTSUBST_TO
Definition: font.h:70
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
UNICODE_STRING FontNames[FONTSUBST_FROM_AND_TO]
Definition: font.h:79
BYTE CharSets[FONTSUBST_FROM_AND_TO]
Definition: font.h:80
LIST_ENTRY PrivateFontListHead
Definition: win32.h:285
#define IntLockProcessPrivateFonts(W32Process)
Definition: text.h:164
#define IntUnLockProcessPrivateFonts(W32Process)
Definition: text.h:167
VOID IntUnicodeStringToBuffer(_Out_ LPWSTR pszBuffer, _In_ SIZE_T cbBuffer, _In_ const UNICODE_STRING *pString)
Definition: utils.c:165

Referenced by IntGetFontFamilyInfo().

◆ GetFontPenalty()

static UINT GetFontPenalty ( const LOGFONTW LogFont,
const OUTLINETEXTMETRICW Otm,
const char style_name 
)
static

Definition at line 5405 of file freetype.c.

5408{
5409 ULONG Penalty = 0;
5410 BYTE Byte;
5411 LONG Long;
5412 BOOL fNeedScaling = FALSE;
5413 const BYTE UserCharSet = IntCharSetFromLangID(gusLanguageID);
5414 const TEXTMETRICW * TM = &Otm->otmTextMetrics;
5415 WCHAR* ActualNameW;
5416
5417 ASSERT(Otm);
5418 ASSERT(LogFont);
5419
5420 /* FIXME: IntSizeSynth Penalty 20 */
5421 /* FIXME: SmallPenalty Penalty 1 */
5422 /* FIXME: FaceNameSubst Penalty 500 */
5423
5424 Byte = LogFont->lfCharSet;
5425
5426 if (Byte != TM->tmCharSet)
5427 {
5429 {
5430 /* CharSet Penalty 65000 */
5431 /* Requested charset does not match the candidate's. */
5432 GOT_PENALTY("CharSet", 65000);
5433 }
5434 else
5435 {
5436 if (UserCharSet != TM->tmCharSet)
5437 {
5438 /* UNDOCUMENTED: Not user language */
5439 GOT_PENALTY("UNDOCUMENTED:NotUserLanguage", 100);
5440
5441 if (ANSI_CHARSET != TM->tmCharSet)
5442 {
5443 /* UNDOCUMENTED: Not ANSI charset */
5444 GOT_PENALTY("UNDOCUMENTED:NotAnsiCharSet", 100);
5445 }
5446 }
5447 }
5448 }
5449
5450 Byte = LogFont->lfOutPrecision;
5451 switch (Byte)
5452 {
5453 case OUT_DEFAULT_PRECIS:
5454 /* nothing to do */
5455 break;
5456 case OUT_DEVICE_PRECIS:
5457 if (!(TM->tmPitchAndFamily & TMPF_DEVICE) ||
5459 {
5460 /* OutputPrecision Penalty 19000 */
5461 /* Requested OUT_STROKE_PRECIS, but the device can't do it
5462 or the candidate is not a vector font. */
5463 GOT_PENALTY("OutputPrecision", 19000);
5464 }
5465 break;
5466 default:
5468 {
5469 /* OutputPrecision Penalty 19000 */
5470 /* Or OUT_STROKE_PRECIS not requested, and the candidate
5471 is a vector font that requires GDI support. */
5472 GOT_PENALTY("OutputPrecision", 19000);
5473 }
5474 break;
5475 }
5476
5477 Byte = (LogFont->lfPitchAndFamily & 0x0F);
5478 if (Byte == DEFAULT_PITCH)
5480 if (Byte == FIXED_PITCH)
5481 {
5483 {
5484 /* FixedPitch Penalty 15000 */
5485 /* Requested a fixed pitch font, but the candidate is a
5486 variable pitch font. */
5487 GOT_PENALTY("FixedPitch", 15000);
5488 }
5489 }
5490 if (Byte == VARIABLE_PITCH)
5491 {
5493 {
5494 /* PitchVariable Penalty 350 */
5495 /* Requested a variable pitch font, but the candidate is not a
5496 variable pitch font. */
5497 GOT_PENALTY("PitchVariable", 350);
5498 }
5499 }
5500
5501 Byte = (LogFont->lfPitchAndFamily & 0x0F);
5502 if (Byte == DEFAULT_PITCH)
5503 {
5505 {
5506 /* DefaultPitchFixed Penalty 1 */
5507 /* Requested DEFAULT_PITCH, but the candidate is fixed pitch. */
5508 GOT_PENALTY("DefaultPitchFixed", 1);
5509 }
5510 }
5511
5512 ActualNameW = (WCHAR*)((ULONG_PTR)Otm + (ULONG_PTR)Otm->otmpFamilyName);
5513
5514 if (LogFont->lfFaceName[0] != UNICODE_NULL)
5515 {
5516 BOOL Found = FALSE;
5517
5518 /* localized family name */
5519 if (!Found)
5520 {
5521 Found = (_wcsicmp(LogFont->lfFaceName, ActualNameW) == 0);
5522 }
5523 /* localized full name */
5524 if (!Found)
5525 {
5526 ActualNameW = (WCHAR*)((ULONG_PTR)Otm + (ULONG_PTR)Otm->otmpFaceName);
5527 Found = (_wcsicmp(LogFont->lfFaceName, ActualNameW) == 0);
5528 }
5529 if (!Found)
5530 {
5531 /* FaceName Penalty 10000 */
5532 /* Requested a face name, but the candidate's face name
5533 does not match. */
5534 GOT_PENALTY("FaceName", 10000);
5535 }
5536 }
5537
5538 Byte = (LogFont->lfPitchAndFamily & 0xF0);
5539 if (Byte != FF_DONTCARE)
5540 {
5541 if (Byte != (TM->tmPitchAndFamily & 0xF0))
5542 {
5543 /* Family Penalty 9000 */
5544 /* Requested a family, but the candidate's family is different. */
5545 GOT_PENALTY("Family", 9000);
5546 }
5547 }
5548
5549 if ((TM->tmPitchAndFamily & 0xF0) == FF_DONTCARE)
5550 {
5551 /* FamilyUnknown Penalty 8000 */
5552 /* Requested a family, but the candidate has no family. */
5553 GOT_PENALTY("FamilyUnknown", 8000);
5554 }
5555
5556 /* Is the candidate a non-vector font? */
5558 {
5559 /* Is lfHeight specified? */
5560 if (LogFont->lfHeight != 0)
5561 {
5562 if (labs(LogFont->lfHeight) < TM->tmHeight)
5563 {
5564 /* HeightBigger Penalty 600 */
5565 /* The candidate is a nonvector font and is bigger than the
5566 requested height. */
5567 GOT_PENALTY("HeightBigger", 600);
5568 /* HeightBiggerDifference Penalty 150 */
5569 /* The candidate is a raster font and is larger than the
5570 requested height. Penalty * height difference */
5571 GOT_PENALTY("HeightBiggerDifference", 150 * labs(TM->tmHeight - labs(LogFont->lfHeight)));
5572
5573 fNeedScaling = TRUE;
5574 }
5575 if (TM->tmHeight < labs(LogFont->lfHeight))
5576 {
5577 /* HeightSmaller Penalty 150 */
5578 /* The candidate is a raster font and is smaller than the
5579 requested height. Penalty * height difference */
5580 GOT_PENALTY("HeightSmaller", 150 * labs(TM->tmHeight - labs(LogFont->lfHeight)));
5581
5582 fNeedScaling = TRUE;
5583 }
5584 }
5585 }
5586
5587 switch (LogFont->lfPitchAndFamily & 0xF0)
5588 {
5589 case FF_ROMAN: case FF_MODERN: case FF_SWISS:
5590 switch (TM->tmPitchAndFamily & 0xF0)
5591 {
5592 case FF_DECORATIVE: case FF_SCRIPT:
5593 /* FamilyUnlikely Penalty 50 */
5594 /* Requested a roman/modern/swiss family, but the
5595 candidate is decorative/script. */
5596 GOT_PENALTY("FamilyUnlikely", 50);
5597 break;
5598 default:
5599 break;
5600 }
5601 break;
5602 case FF_DECORATIVE: case FF_SCRIPT:
5603 switch (TM->tmPitchAndFamily & 0xF0)
5604 {
5605 case FF_ROMAN: case FF_MODERN: case FF_SWISS:
5606 /* FamilyUnlikely Penalty 50 */
5607 /* Or requested decorative/script, and the candidate is
5608 roman/modern/swiss. */
5609 GOT_PENALTY("FamilyUnlikely", 50);
5610 break;
5611 default:
5612 break;
5613 }
5614 default:
5615 break;
5616 }
5617
5618 if (LogFont->lfWidth != 0)
5619 {
5620 if (LogFont->lfWidth != TM->tmAveCharWidth)
5621 {
5622 /* Width Penalty 50 */
5623 /* Requested a nonzero width, but the candidate's width
5624 doesn't match. Penalty * width difference */
5625 GOT_PENALTY("Width", 50 * labs(LogFont->lfWidth - TM->tmAveCharWidth));
5626
5628 fNeedScaling = TRUE;
5629 }
5630 }
5631
5632 if (fNeedScaling)
5633 {
5634 /* SizeSynth Penalty 50 */
5635 /* The candidate is a raster font that needs scaling by GDI. */
5636 GOT_PENALTY("SizeSynth", 50);
5637 }
5638
5639 if (!LogFont->lfItalic && TM->tmItalic)
5640 {
5641 /* Italic Penalty 4 */
5642 /* Requested font and candidate font do not agree on italic status,
5643 and the desired result cannot be simulated. */
5644 /* Adjusted to 40 to satisfy (Oblique Penalty > Book Penalty). */
5645 GOT_PENALTY("Italic", 40);
5646 }
5647 else if (LogFont->lfItalic && !TM->tmItalic)
5648 {
5649 /* ItalicSim Penalty 1 */
5650 /* Requested italic font but the candidate is not italic,
5651 although italics can be simulated. */
5652 GOT_PENALTY("ItalicSim", 1);
5653 }
5654
5655 if (LogFont->lfOutPrecision == OUT_TT_PRECIS)
5656 {
5657 if (!(TM->tmPitchAndFamily & TMPF_TRUETYPE))
5658 {
5659 /* NotTrueType Penalty 4 */
5660 /* Requested OUT_TT_PRECIS, but the candidate is not a
5661 TrueType font. */
5662 GOT_PENALTY("NotTrueType", 4);
5663 }
5664 }
5665
5666 Long = LogFont->lfWeight;
5667 if (LogFont->lfWeight == FW_DONTCARE)
5668 Long = FW_NORMAL;
5669 if (Long != TM->tmWeight)
5670 {
5671 /* Weight Penalty 3 */
5672 /* The candidate's weight does not match the requested weight.
5673 Penalty * (weight difference/10) */
5674 GOT_PENALTY("Weight", 3 * (labs(Long - TM->tmWeight) / 10));
5675 }
5676
5677 if (!LogFont->lfUnderline && TM->tmUnderlined)
5678 {
5679 /* Underline Penalty 3 */
5680 /* Requested font has no underline, but the candidate is
5681 underlined. */
5682 GOT_PENALTY("Underline", 3);
5683 }
5684
5685 if (!LogFont->lfStrikeOut && TM->tmStruckOut)
5686 {
5687 /* StrikeOut Penalty 3 */
5688 /* Requested font has no strike-out, but the candidate is
5689 struck out. */
5690 GOT_PENALTY("StrikeOut", 3);
5691 }
5692
5693 /* Is the candidate a non-vector font? */
5695 {
5696 if (LogFont->lfHeight != 0 && TM->tmHeight < LogFont->lfHeight)
5697 {
5698 /* VectorHeightSmaller Penalty 2 */
5699 /* Candidate is a vector font that is smaller than the
5700 requested height. Penalty * height difference */
5701 GOT_PENALTY("VectorHeightSmaller", 2 * labs(TM->tmHeight - LogFont->lfHeight));
5702 }
5703 if (LogFont->lfHeight != 0 && TM->tmHeight > LogFont->lfHeight)
5704 {
5705 /* VectorHeightBigger Penalty 1 */
5706 /* Candidate is a vector font that is bigger than the
5707 requested height. Penalty * height difference */
5708 GOT_PENALTY("VectorHeightBigger", 1 * labs(TM->tmHeight - LogFont->lfHeight));
5709 }
5710 }
5711
5712 if (!(TM->tmPitchAndFamily & TMPF_DEVICE))
5713 {
5714 /* DeviceFavor Penalty 2 */
5715 /* Extra penalty for all nondevice fonts. */
5716 GOT_PENALTY("DeviceFavor", 2);
5717 }
5718
5719 if (TM->tmAveCharWidth >= 5 && TM->tmHeight >= 5)
5720 {
5721 if (TM->tmAveCharWidth / TM->tmHeight >= 3)
5722 {
5723 /* Aspect Penalty 30 */
5724 /* The aspect rate is >= 3. It seems like a bad font. */
5725 GOT_PENALTY("Aspect", ((TM->tmAveCharWidth / TM->tmHeight) - 2) * 30);
5726 }
5727 else if (TM->tmHeight / TM->tmAveCharWidth >= 3)
5728 {
5729 /* Aspect Penalty 30 */
5730 /* The aspect rate is >= 3. It seems like a bad font. */
5731 GOT_PENALTY("Aspect", ((TM->tmHeight / TM->tmAveCharWidth) - 2) * 30);
5732 }
5733 }
5734
5735 if (Penalty < 200)
5736 {
5737 DPRINT("WARNING: Penalty:%ld < 200: RequestedNameW:%ls, "
5738 "ActualNameW:%ls, lfCharSet:%d, lfWeight:%ld, "
5739 "tmCharSet:%d, tmWeight:%ld\n",
5740 Penalty, LogFont->lfFaceName, ActualNameW,
5741 LogFont->lfCharSet, LogFont->lfWeight,
5742 TM->tmCharSet, TM->tmWeight);
5743 }
5744
5745 return Penalty; /* success */
5746}
return Found
Definition: dirsup.c:1270
unsigned char Byte
Definition: zlib.h:37
_ACRTIMP __msvcrt_long __cdecl labs(__msvcrt_long)
Definition: math.c:680
#define GOT_PENALTY(name, value)
Definition: freetype.c:5401
long Long
Definition: ftraster.c:311
BYTE lfStrikeOut
Definition: dimm.idl:66
BYTE lfUnderline
Definition: dimm.idl:65
BYTE IntCharSetFromLangID(_In_ LANGID LangID)
Definition: utils.c:82
#define DEFAULT_PITCH
Definition: wingdi.h:443
#define VARIABLE_PITCH
Definition: wingdi.h:445
#define OUT_DEVICE_PRECIS
Definition: wingdi.h:420
#define TMPF_DEVICE
Definition: wingdi.h:1314
#define OUT_DEFAULT_PRECIS
Definition: wingdi.h:415
#define OUT_TT_PRECIS
Definition: wingdi.h:419
#define FW_NORMAL
Definition: wingdi.h:373

Referenced by FindBestFontFromList().

◆ GreExtTextOutW()

BOOL APIENTRY GreExtTextOutW ( _In_ HDC  hDC,
_In_ INT  XStart,
_In_ INT  YStart,
_In_ UINT  fuOptions,
_In_opt_ PRECTL  lprc,
_In_reads_opt_(Count) PCWCH  String,
_In_ INT  Count,
_In_opt_ const INT Dx,
_In_ DWORD  dwCodePage 
)

Definition at line 7291 of file freetype.c.

7301{
7302 BOOL bResult;
7303 DC *dc;
7304
7305 // TODO: Write test-cases to exactly match real Windows in different
7306 // bad parameters (e.g. does Windows check the DC or the RECT first?).
7307 dc = DC_LockDc(hDC);
7308 if (!dc)
7309 {
7311 return FALSE;
7312 }
7313
7314 bResult = IntExtTextOutW( dc,
7315 XStart,
7316 YStart,
7317 fuOptions,
7318 lprc,
7319 String,
7320 Count,
7321 Dx,
7322 dwCodePage );
7323
7324 DC_UnlockDc(dc);
7325
7326 return bResult;
7327}
BOOL APIENTRY IntExtTextOutW(_In_ PDC dc, _In_ INT XStart, _In_ INT YStart, _In_ UINT fuOptions, _In_opt_ PRECTL lprc, _In_reads_opt_(Count) PCWCH String, _In_ INT Count, _In_opt_ const INT *Dx, _In_ DWORD dwCodePage)
Definition: freetype.c:6742
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2439
_In_ int _Inout_ LPRECT lprc
Definition: winuser.h:4619

Referenced by GreTextOutW(), IntPaintDesktop(), and NtGdiExtTextOutW().

◆ GreGetCharABCWidthsW()

BOOL APIENTRY GreGetCharABCWidthsW ( _In_ HDC  hDC,
_In_ UINT  FirstChar,
_In_ UINT  Count,
_In_reads_opt_(Count) PCWCH  Safepwch,
_In_ FLONG  fl,
_Out_writes_bytes_(Count *sizeof(ABC)) PVOID  SafeBuffer 
)

Definition at line 7488 of file freetype.c.

7495{
7496 PABC SafeBuffI;
7497 PABCFLOAT SafeBuffF;
7498 PDC dc;
7499 PDC_ATTR pdcattr;
7500 PTEXTOBJ TextObj;
7501 PFONTGDI FontGDI;
7502 FT_Face face;
7503 UINT i, glyph_index;
7504 HFONT hFont = NULL;
7505 PLOGFONTW plf;
7506
7507 dc = DC_LockDc(hDC);
7508 if (dc == NULL)
7509 {
7511 return FALSE;
7512 }
7513
7514 pdcattr = dc->pdcattr;
7515 hFont = pdcattr->hlfntNew;
7516 TextObj = RealizeFontInit(hFont);
7517
7518 DC_UnlockDc(dc);
7519
7520 if (TextObj == NULL)
7521 {
7523 return FALSE;
7524 }
7525
7526 FontGDI = ObjToGDI(TextObj->Font, FONT);
7527
7528 face = FontGDI->SharedFace->Face;
7530 {
7531 TEXTOBJ_UnlockText(TextObj);
7533 return FALSE;
7534 }
7535
7536 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
7537
7538 // NOTE: GetCharABCWidths simply ignores lfEscapement and XFORM.
7540 IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight);
7542
7543 if (!fl)
7544 SafeBuffF = SafeBuffer;
7545 else
7546 SafeBuffI = SafeBuffer;
7547
7548 for (i = FirstChar; i < FirstChar+Count; i++)
7549 {
7550 int adv, lsb, bbx, left, right;
7551
7552 if (Safepwch)
7553 glyph_index = get_glyph_index_flagged(face, Safepwch[i - FirstChar], (fl & GCABCW_INDICES));
7554 else
7555 glyph_index = get_glyph_index_flagged(face, i, (fl & GCABCW_INDICES));
7556
7557 FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
7558
7559 left = (INT)face->glyph->metrics.horiBearingX & -64;
7560 right = (INT)((face->glyph->metrics.horiBearingX + face->glyph->metrics.width) + 63) & -64;
7561 adv = (face->glyph->advance.x + 32) >> 6;
7562
7563// int test = (INT)(face->glyph->metrics.horiAdvance + 63) >> 6;
7564// DPRINT1("Advance Wine %d and Advance Ros %d\n",test, adv ); /* It's the same! */
7565
7566 lsb = left >> 6;
7567 bbx = (right - left) >> 6;
7568 /*
7569 DPRINT1("lsb %d and bbx %d\n", lsb, bbx );
7570 */
7571 if (!fl)
7572 {
7573 SafeBuffF[i - FirstChar].abcfA = (FLOAT) lsb;
7574 SafeBuffF[i - FirstChar].abcfB = (FLOAT) bbx;
7575 SafeBuffF[i - FirstChar].abcfC = (FLOAT) (adv - lsb - bbx);
7576 }
7577 else
7578 {
7579 SafeBuffI[i - FirstChar].abcA = lsb;
7580 SafeBuffI[i - FirstChar].abcB = bbx;
7581 SafeBuffI[i - FirstChar].abcC = adv - lsb - bbx;
7582 }
7583 }
7584
7586 TEXTOBJ_UnlockText(TextObj);
7587
7588 return TRUE;
7589}
static BOOL FASTCALL IntSelectFaceCharmap(FT_Face face)
Definition: freetype.c:7452
#define FLOAT
Definition: i386-dis.c:525
#define GCABCW_INDICES
Definition: ntgdityp.h:210
#define INT
Definition: polytest.cpp:20
FLOAT abcfA
Definition: wingdi.h:1862
FLOAT abcfC
Definition: wingdi.h:1864
FLOAT abcfB
Definition: wingdi.h:1863
Definition: wingdi.h:1856
int abcA
Definition: wingdi.h:1857
UINT abcB
Definition: wingdi.h:1858
int abcC
Definition: wingdi.h:1859
LONG lfWidth
Definition: wingdi.h:2344
LONG lfHeight
Definition: wingdi.h:2343
_In_ FLONG fl
Definition: winddi.h:1279

Referenced by NtGdiGetCharABCWidthsW().

◆ GreGetCharWidthW()

BOOL APIENTRY GreGetCharWidthW ( _In_ HDC  hDC,
_In_ UINT  FirstChar,
_In_ UINT  Count,
_In_reads_opt_(Count) PCWCH  Safepwc,
_In_ FLONG  fl,
_Out_writes_bytes_(Count *sizeof(INT)) PVOID  Buffer 
)

Definition at line 7595 of file freetype.c.

7602{
7603 PDC dc;
7604 PDC_ATTR pdcattr;
7605 PTEXTOBJ TextObj;
7606 PFONTGDI FontGDI;
7607 FT_Face face;
7608 UINT i, glyph_index;
7609 HFONT hFont = 0;
7610 LOGFONTW *plf;
7611 PINT SafeBuffI;
7612 PFLOAT SafeBuffF;
7613
7614 dc = DC_LockDc(hDC);
7615 if (dc == NULL)
7616 {
7618 return FALSE;
7619 }
7620
7621 pdcattr = dc->pdcattr;
7622 hFont = pdcattr->hlfntNew;
7623 TextObj = RealizeFontInit(hFont);
7624 DC_UnlockDc(dc);
7625
7626 if (TextObj == NULL)
7627 {
7629 return FALSE;
7630 }
7631
7632 FontGDI = ObjToGDI(TextObj->Font, FONT);
7633
7634 face = FontGDI->SharedFace->Face;
7636 {
7637 TEXTOBJ_UnlockText(TextObj);
7639 return FALSE;
7640 }
7641
7642 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
7643
7644 // NOTE: GetCharWidth simply ignores lfEscapement and XFORM.
7646 IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight);
7648
7649 if (!fl)
7650 SafeBuffF = (PFLOAT)Buffer;
7651 else
7652 SafeBuffI = (PINT)Buffer;
7653
7654 for (i = FirstChar; i < FirstChar+Count; i++)
7655 {
7656 if (Safepwc)
7657 glyph_index = get_glyph_index_flagged(face, Safepwc[i - FirstChar], (fl & GCW_INDICES));
7658 else
7659 glyph_index = get_glyph_index_flagged(face, i, (fl & GCW_INDICES));
7660
7661 FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
7662
7663 if (!fl)
7664 SafeBuffF[i - FirstChar] = (FLOAT) ((face->glyph->advance.x + 32) >> 6);
7665 else
7666 SafeBuffI[i - FirstChar] = (face->glyph->advance.x + 32) >> 6;
7667 }
7668
7670 TEXTOBJ_UnlockText(TextObj);
7671
7672 return TRUE;
7673}
FLOAT * PFLOAT
Definition: minwindef.h:147
int * PINT
Definition: minwindef.h:150
#define GCW_INDICES
Definition: ntgdityp.h:206

Referenced by NtGdiGetCharWidthW().

◆ InitFontSupport()

BOOL FASTCALL InitFontSupport ( VOID  )

Definition at line 997 of file freetype.c.

998{
999 ULONG ulError;
1000
1002
1004 if (g_FreeTypeLock == NULL)
1005 {
1006 return FALSE;
1007 }
1009
1011 if (ulError)
1012 {
1013 DPRINT1("FT_Init_FreeType failed with error code 0x%x\n", ulError);
1014 return FALSE;
1015 }
1016
1018 {
1019 DPRINT1("Fonts registry is empty.\n");
1020
1021 /* Load font(s) with writing registry */
1023 }
1024
1025 IntLoadFontSubstList(&g_FontSubstListHead);
1026
1027#if 0
1028 DumpFontInfo(TRUE);
1029#endif
1030
1034
1035 return TRUE;
1036}
#define NonPagedPool
Definition: env_spec_w32.h:307
BOOL FASTCALL IntLoadFontSubstList(PLIST_ENTRY pHead)
Definition: freetype.c:803
static UINT g_FontCacheNumEntries
Definition: freetype.c:352
VOID FASTCALL IntLoadSystemFonts(VOID)
Definition: freetype.c:1495
static NTSTATUS FontLink_LoadDefaultCharset(VOID)
Definition: freetype.c:136
static NTSTATUS FontLink_LoadSettings(VOID)
Definition: freetype.c:72
static NTSTATUS FontLink_LoadDefaultFonts(VOID)
Definition: freetype.c:98
BOOL FASTCALL IntLoadFontsInRegistry(VOID)
Definition: freetype.c:2376
FT_Init_FreeType(FT_Library *alibrary)
Definition: ftinit.c:199
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
FAST_MUTEX
Definition: extypes.h:17

Referenced by InitializeGreCSRSS().

◆ IntAddNameFromFamInfo()

static VOID IntAddNameFromFamInfo ( LPWSTR  psz,
FONTFAMILYINFO FamInfo 
)
static

Definition at line 6164 of file freetype.c.

6165{
6167 if (FamInfo->EnumLogFontEx.elfStyle[0] &&
6168 _wcsicmp(FamInfo->EnumLogFontEx.elfStyle, L"Regular") != 0)
6169 {
6170 wcscat(psz, L" ");
6171 wcscat(psz, FamInfo->EnumLogFontEx.elfStyle);
6172 }
6173}
wcscat

Referenced by IntGdiGetFontResourceInfo().

◆ IntCharSetFromCodePage()

BYTE FASTCALL IntCharSetFromCodePage ( UINT  uCodePage)

Definition at line 430 of file freetype.c.

431{
432 UINT i;
433
434 if (uCodePage == CP_OEMCP)
435 return OEM_CHARSET;
436
437 if (uCodePage == CP_MACCP)
438 return MAC_CHARSET;
439
440 for (i = 0; i < MAXTCIINDEX; ++i)
441 {
442 if (g_FontTci[i].ciACP == 0)
443 continue;
444
445 if (g_FontTci[i].ciACP == uCodePage)
446 return g_FontTci[i].ciCharset;
447 }
448
449 return DEFAULT_CHARSET;
450}
#define CP_OEMCP
Definition: freetype.c:424
static const CHARSETINFO g_FontTci[MAXTCIINDEX]
Definition: freetype.c:382
#define CP_MACCP
Definition: freetype.c:425
#define MAC_CHARSET
Definition: wingdi.h:403

Referenced by CreateStockFonts().

◆ IntDeleteRegFontEntries()

VOID IntDeleteRegFontEntries ( _In_ PCWSTR  pszFileName,
_In_ DWORD  dwFlags 
)

Definition at line 2235 of file freetype.c.

2236{
2238 HKEY hKey;
2239 WCHAR szName[MAX_PATH], szValue[MAX_PATH];
2240 ULONG dwIndex, NameLength, ValueSize, dwType;
2241
2243 if (!NT_SUCCESS(Status))
2244 return;
2245
2246 for (dwIndex = 0;;)
2247 {
2248 NameLength = RTL_NUMBER_OF(szName);
2249 ValueSize = sizeof(szValue);
2250 Status = RegEnumValueW(hKey, dwIndex, szName, &NameLength, &dwType, szValue, &ValueSize);
2251 if (!NT_SUCCESS(Status))
2252 break;
2253
2254 if (dwType != REG_SZ || _wcsicmp(szValue, pszFileName) != 0)
2255 {
2256 ++dwIndex;
2257 continue;
2258 }
2259
2260 /* Delete the found value */
2262 if (!NT_SUCCESS(Status))
2263 break;
2264 }
2265
2266 ZwClose(hKey);
2267}
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2830
UNICODE_STRING g_FontRegPath
Definition: freetype.c:321
static const WCHAR szName[]
Definition: powrprof.c:45
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:44

Referenced by IntGdiRemoveFontResourceSingle().

◆ IntEnableFontRendering()

VOID FASTCALL IntEnableFontRendering ( BOOL  Enable)

Definition at line 2706 of file freetype.c.

2707{
2709}
static BOOL g_RenderingEnabled
Definition: freetype.c:329
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142

◆ IntEscapeMatrix()

static VOID FASTCALL IntEscapeMatrix ( FT_Matrix pmat,
LONG  lfEscapement 
)
static

Definition at line 1089 of file freetype.c.

1090{
1091 FT_Vector vecAngle;
1092 /* Convert the angle in tenths of degrees into degrees as a 16.16 fixed-point value */
1093 FT_Angle angle = INT_TO_FIXED(lfEscapement) / 10;
1094 FT_Vector_Unit(&vecAngle, angle);
1095 pmat->xx = vecAngle.x;
1096 pmat->xy = -vecAngle.y;
1097 pmat->yx = -pmat->xy;
1098 pmat->yy = pmat->xx;
1099}
FT_BEGIN_HEADER typedef FT_Fixed FT_Angle
Definition: fttrigon.h:52
FT_Vector_Unit(FT_Vector *vec, FT_Angle angle)
Definition: fttrigon.c:360
GLfloat angle
Definition: glext.h:10853

Referenced by ftGdiGetGlyphOutline(), and IntExtTextOutW().

◆ IntExtTextOutW()

BOOL APIENTRY IntExtTextOutW ( _In_ PDC  dc,
_In_ INT  XStart,
_In_ INT  YStart,
_In_ UINT  fuOptions,
_In_opt_ PRECTL  lprc,
_In_reads_opt_(Count) PCWCH  String,
_In_ INT  Count,
_In_opt_ const INT Dx,
_In_ DWORD  dwCodePage 
)

Definition at line 6742 of file freetype.c.

6752{
6753 /*
6754 * FIXME:
6755 * Call EngTextOut, which does the real work (calling DrvTextOut where
6756 * appropriate)
6757 */
6758
6759 PDC_ATTR pdcattr;
6760 SURFOBJ *psoDest, *psoGlyph;
6761 SURFACE *psurf;
6762 INT glyph_index, i;
6763 FT_Face face;
6764 FT_BitmapGlyph realglyph;
6765 LONGLONG X64, Y64, RealXStart64, RealYStart64, DeltaX64, DeltaY64;
6766 ULONG previous;
6767 RECTL DestRect, MaskRect;
6768 HBITMAP hbmGlyph;
6769 SIZEL glyphSize;
6770 FONTOBJ *FontObj;
6771 PFONTGDI FontGDI;
6772 PTEXTOBJ TextObj = NULL;
6773 EXLATEOBJ exloRGB2Dst, exloDst2RGB;
6774 POINT Start;
6775 PMATRIX pmxWorldToDevice;
6776 FT_Vector delta, vecAscent64, vecDescent64, vec;
6777 LOGFONTW *plf;
6778 BOOL use_kerning, bResult, DoBreak;
6780 FT_Matrix mat;
6781 BOOL bNoTransform;
6782 DWORD ch0, ch1;
6783 const DWORD del = 0x7f, nbsp = 0xa0; // DEL is ASCII DELETE and nbsp is a non-breaking space
6784 FONTLINK_CHAIN Chain;
6785 SIZE spaceWidth;
6786
6787 /* Check if String is valid */
6788 if (Count > 0xFFFF || (Count > 0 && String == NULL))
6789 {
6791 return FALSE;
6792 }
6793
6794 if (PATH_IsPathOpen(dc->dclevel))
6795 {
6796 return PATH_ExtTextOut(dc,
6797 XStart, YStart,
6798 fuOptions,
6799 lprc,
6800 String, Count,
6801 Dx);
6802 }
6803
6805
6806 if (!dc->dclevel.pSurface)
6807 {
6808 /* Memory DC with no surface selected */
6809 bResult = TRUE;
6810 goto Cleanup;
6811 }
6812
6813 pdcattr = dc->pdcattr;
6814 if (pdcattr->flTextAlign & TA_UPDATECP)
6815 {
6816 Start.x = pdcattr->ptlCurrent.x;
6817 Start.y = pdcattr->ptlCurrent.y;
6818 }
6819 else
6820 {
6821 Start.x = XStart;
6822 Start.y = YStart;
6823 }
6824
6825 IntLPtoDP(dc, &Start, 1);
6826 RealXStart64 = ((LONGLONG)Start.x + dc->ptlDCOrig.x) << 6;
6827 RealYStart64 = ((LONGLONG)Start.y + dc->ptlDCOrig.y) << 6;
6828
6829 MaskRect.left = 0;
6830 MaskRect.top = 0;
6831
6832 psurf = dc->dclevel.pSurface;
6833 psoDest = &psurf->SurfObj;
6834
6835 if (pdcattr->iGraphicsMode == GM_ADVANCED)
6836 pmxWorldToDevice = DC_pmxWorldToDevice(dc);
6837 else
6838 pmxWorldToDevice = (PMATRIX)&gmxWorldToDeviceDefault;
6839
6840 if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
6842
6843 if (lprc && (fuOptions & (ETO_CLIPPED | ETO_OPAQUE)))
6844 {
6845 IntLPtoDP(dc, (POINT*)lprc, 2);
6846 lprc->left += dc->ptlDCOrig.x;
6847 lprc->top += dc->ptlDCOrig.y;
6848 lprc->right += dc->ptlDCOrig.x;
6849 lprc->bottom += dc->ptlDCOrig.y;
6850 }
6851
6852 if (lprc && (fuOptions & ETO_OPAQUE))
6853 {
6855 lprc->left, lprc->top,
6856 lprc->right - lprc->left, lprc->bottom - lprc->top,
6857 &dc->eboBackground.BrushObject);
6858 fuOptions &= ~ETO_OPAQUE;
6859 }
6860 else
6861 {
6862 if (pdcattr->jBkMode == OPAQUE)
6863 {
6864 fuOptions |= ETO_OPAQUE;
6865 }
6866 }
6867
6868 TextObj = RealizeFontInit(pdcattr->hlfntNew);
6869 if (TextObj == NULL)
6870 {
6871 bResult = FALSE;
6872 goto Cleanup;
6873 }
6874
6875 FontObj = TextObj->Font;
6876 ASSERT(FontObj);
6877 FontGDI = ObjToGDI(FontObj, FONT);
6878 ASSERT(FontGDI);
6879
6881 Cache.Hashed.Face = face = FontGDI->SharedFace->Face;
6882
6883 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
6884 Cache.Hashed.lfHeight = plf->lfHeight;
6885 Cache.Hashed.lfWidth = plf->lfWidth;
6886 Cache.Hashed.Aspect.Emu.Bold = EMUBOLD_NEEDED(FontGDI->OriginalWeight, plf->lfWeight);
6887 Cache.Hashed.Aspect.Emu.Italic = (plf->lfItalic && !FontGDI->OriginalItalic);
6888
6890 Cache.Hashed.Aspect.RenderMode = (BYTE)IntGetFontRenderMode(plf);
6891 else
6892 Cache.Hashed.Aspect.RenderMode = (BYTE)FT_RENDER_MODE_MONO;
6893
6894 if (!TextIntUpdateSize(dc, TextObj, FontGDI, FALSE))
6895 {
6897 bResult = FALSE;
6898 goto Cleanup;
6899 }
6900
6901 FontLink_Chain_Init(&Chain, TextObj, face);
6902
6903 /* Apply lfEscapement */
6904 if (FT_IS_SCALABLE(face) && plf->lfEscapement != 0)
6905 IntEscapeMatrix(&Cache.Hashed.matTransform, plf->lfEscapement);
6906 else
6907 Cache.Hashed.matTransform = identityMat;
6908
6909 /* Apply the world transformation */
6910 IntMatrixFromMx(&mat, pmxWorldToDevice);
6911 FT_Matrix_Multiply(&mat, &Cache.Hashed.matTransform);
6912 FT_Set_Transform(face, &Cache.Hashed.matTransform, NULL);
6913
6914 /* Is there no transformation? */
6915 bNoTransform = ((mat.xy == 0) && (mat.yx == 0) &&
6916 (mat.xx == (1 << 16)) && (mat.yy == (1 << 16)));
6917
6918 /* Calculate the ascent point and the descent point */
6919 vecAscent64.x = 0;
6920 vecAscent64.y = (FontGDI->tmAscent << 6);
6921 FT_Vector_Transform(&vecAscent64, &Cache.Hashed.matTransform);
6922 vecDescent64.x = 0;
6923 vecDescent64.y = -(FontGDI->tmDescent << 6);
6924 FT_Vector_Transform(&vecDescent64, &Cache.Hashed.matTransform);
6925
6926 /* Process the vertical alignment and fix the real starting point. */
6927#define VALIGN_MASK (TA_TOP | TA_BASELINE | TA_BOTTOM)
6928 if ((pdcattr->flTextAlign & VALIGN_MASK) == TA_BASELINE)
6929 {
6930 NOTHING;
6931 }
6932 else if ((pdcattr->flTextAlign & VALIGN_MASK) == TA_BOTTOM)
6933 {
6934 RealXStart64 -= vecDescent64.x;
6935 RealYStart64 += vecDescent64.y;
6936 }
6937 else /* TA_TOP */
6938 {
6939 RealXStart64 -= vecAscent64.x;
6940 RealYStart64 += vecAscent64.y;
6941 }
6942#undef VALIGN_MASK
6943
6944 use_kerning = FT_HAS_KERNING(face);
6945
6946 /* Calculate the text width if necessary */
6947 if ((fuOptions & ETO_OPAQUE) || (pdcattr->flTextAlign & (TA_CENTER | TA_RIGHT)))
6948 {
6949 if (!IntGetTextDisposition(&DeltaX64, &DeltaY64, String, Count, Dx, &Cache,
6950 fuOptions, bNoTransform, &Chain))
6951 {
6952 FontLink_Chain_Finish(&Chain);
6954 bResult = FALSE;
6955 goto Cleanup;
6956 }
6957
6958 /* Adjust the horizontal position by horizontal alignment */
6959 if ((pdcattr->flTextAlign & TA_CENTER) == TA_CENTER)
6960 {
6961 RealXStart64 -= DeltaX64 / 2;
6962 RealYStart64 -= DeltaY64 / 2;
6963 }
6964 else if ((pdcattr->flTextAlign & TA_RIGHT) == TA_RIGHT)
6965 {
6966 RealXStart64 -= DeltaX64;
6967 RealYStart64 -= DeltaY64;
6968 }
6969
6970 /* Fill background */
6971 if (fuOptions & ETO_OPAQUE)
6972 {
6973 INT X0 = (RealXStart64 + vecAscent64.x + 32) >> 6;
6974 INT Y0 = (RealYStart64 - vecAscent64.y + 32) >> 6;
6975 INT DX = (DeltaX64 >> 6);
6976 if (Cache.Hashed.matTransform.xy == 0 && Cache.Hashed.matTransform.yx == 0)
6977 {
6978 INT CY = (vecAscent64.y - vecDescent64.y + 32) >> 6;
6979 IntEngFillBox(dc, X0, Y0, DX, CY, &dc->eboBackground.BrushObject);
6980 }
6981 else
6982 {
6983 INT DY = (DeltaY64 >> 6);
6984 INT X1 = ((RealXStart64 + vecDescent64.x + 32) >> 6);
6985 INT Y1 = ((RealYStart64 - vecDescent64.y + 32) >> 6);
6986 POINT Points[4] =
6987 {
6988 { X0, Y0 },
6989 { X0 + DX, Y0 + DY },
6990 { X1 + DX, Y1 + DY },
6991 { X1, Y1 },
6992 };
6993 IntEngFillPolygon(dc, Points, 4, &dc->eboBackground.BrushObject);
6994 }
6995 }
6996 }
6997
6998 EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0);
6999 EXLATEOBJ_vInitialize(&exloDst2RGB, psurf->ppal, &gpalRGB, 0, 0, 0);
7000
7001 if (pdcattr->ulDirty_ & DIRTY_TEXT)
7003
7004 /*
7005 * The main rendering loop.
7006 */
7007 X64 = RealXStart64;
7008 Y64 = RealYStart64;
7009 previous = 0;
7010 DoBreak = FALSE;
7011 bResult = TRUE; /* Assume success */
7012 for (i = 0; i < Count; ++i)
7013 {
7014 ch0 = *String++;
7015 if (IS_HIGH_SURROGATE(ch0))
7016 {
7017 ++i;
7018 if (i >= Count)
7019 break;
7020
7021 ch1 = *String++;
7022 if (IS_LOW_SURROGATE(ch1))
7023 ch0 = Utf32FromSurrogatePair(ch0, ch1);
7024 }
7025
7026 glyph_index = FontLink_Chain_FindGlyph(&Chain, &Cache, &face, ch0,
7027 (fuOptions & ETO_GLYPH_INDEX));
7028 Cache.Hashed.GlyphIndex = glyph_index;
7029
7030 realglyph = IntGetRealGlyph(&Cache);
7031 if (!realglyph)
7032 {
7033 bResult = FALSE;
7034 break;
7035 }
7036
7037 /* retrieve kerning distance and move pen position */
7038 if (use_kerning && previous && glyph_index && NULL == Dx)
7039 {
7040 FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
7041 X64 += delta.x;
7042 Y64 -= delta.y;
7043 }
7044
7045 DPRINT("X64, Y64: %I64d, %I64d\n", X64, Y64);
7046 DPRINT("Advance: %d, %d\n", realglyph->root.advance.x, realglyph->root.advance.y);
7047
7048 glyphSize.cx = realglyph->bitmap.width;
7049 glyphSize.cy = realglyph->bitmap.rows;
7050
7051 /* Do chars > space & not DEL & not nbsp have a glyphSize.cx of zero? */
7052 if (ch0 > L' ' && ch0 != del && ch0 != nbsp && glyphSize.cx == 0)
7053 {
7054 DPRINT1("WARNING: family_name '%s' WChar 0x%04x has a glyphSize.cx of zero\n",
7055 face->family_name, ch0);
7056 }
7057
7058 /* Don't ignore spaces or non-breaking spaces when computing offset.
7059 * This completes the fix of CORE-11787. */
7060 if ((pdcattr->flTextAlign & TA_UPDATECP) && glyphSize.cx == 0 &&
7061 (ch0 == L' ' || ch0 == nbsp)) // Space chars needing x-dim widths
7062 {
7064 /* Get the width of the space character */
7065 TextIntGetTextExtentPoint(dc, TextObj, L" ", 1, 0, NULL, NULL, &spaceWidth, 0);
7067 glyphSize.cx = spaceWidth.cx;
7068 realglyph->left = 0;
7069 }
7070
7071 MaskRect.right = realglyph->bitmap.width;
7072 MaskRect.bottom = realglyph->bitmap.rows;
7073
7074 DestRect.left = ((X64 + 32) >> 6) + realglyph->left;
7075 DestRect.right = DestRect.left + glyphSize.cx;
7076 DestRect.top = ((Y64 + 32) >> 6) - realglyph->top;
7077 DestRect.bottom = DestRect.top + glyphSize.cy;
7078
7079 /* Check if the bitmap has any pixels */
7080 if ((glyphSize.cx != 0) && (glyphSize.cy != 0))
7081 {
7082 /*
7083 * We should create the bitmap out of the loop at the biggest possible
7084 * glyph size. Then use memset with 0 to clear it and sourcerect to
7085 * limit the work of the transbitblt.
7086 */
7087 hbmGlyph = EngCreateBitmap(glyphSize, realglyph->bitmap.pitch,
7089 realglyph->bitmap.buffer);
7090 if (!hbmGlyph)
7091 {
7092 DPRINT1("WARNING: EngCreateBitmap() failed!\n");
7093 bResult = FALSE;
7094 break;
7095 }
7096
7097 psoGlyph = EngLockSurface((HSURF)hbmGlyph);
7098 if (!psoGlyph)
7099 {
7100 EngDeleteSurface((HSURF)hbmGlyph);
7101 DPRINT1("WARNING: EngLockSurface() failed!\n");
7102 bResult = FALSE;
7103 break;
7104 }
7105
7106 /*
7107 * Use the font data as a mask to paint onto the DCs surface using a
7108 * brush.
7109 */
7110 if (lprc && (fuOptions & ETO_CLIPPED))
7111 {
7112 // We do the check '>=' instead of '>' to possibly save an iteration
7113 // through this loop, since it's breaking after the drawing is done,
7114 // and x is always incremented.
7115 if (DestRect.right >= lprc->right)
7116 {
7117 DestRect.right = lprc->right;
7118 DoBreak = TRUE;
7119 }
7120
7121 if (DestRect.bottom >= lprc->bottom)
7122 {
7123 DestRect.bottom = lprc->bottom;
7124 }
7125 }
7126
7127 if (!IntEngMaskBlt(psoDest,
7128 psoGlyph,
7129 (CLIPOBJ *)&dc->co,
7130 &exloRGB2Dst.xlo,
7131 &exloDst2RGB.xlo,
7132 &DestRect,
7133 (PPOINTL)&MaskRect,
7134 &dc->eboText.BrushObject,
7135 &g_PointZero))
7136 {
7137 DPRINT1("Failed to MaskBlt a glyph!\n");
7138 }
7139
7140 EngUnlockSurface(psoGlyph);
7141 EngDeleteSurface((HSURF)hbmGlyph);
7142 }
7143
7144 if (DoBreak)
7145 break;
7146
7147 if (NULL == Dx)
7148 {
7149 X64 += realglyph->root.advance.x >> 10;
7150 Y64 -= realglyph->root.advance.y >> 10;
7151 }
7152 else if (fuOptions & ETO_PDY)
7153 {
7154 vec.x = (Dx[2 * i + 0] << 6);
7155 vec.y = (Dx[2 * i + 1] << 6);
7156 if (!bNoTransform)
7157 FT_Vector_Transform(&vec, &Cache.Hashed.matTransform);
7158 X64 += vec.x;
7159 Y64 -= vec.y;
7160 }
7161 else
7162 {
7163 vec.x = (Dx[i] << 6);
7164 vec.y = 0;
7165 if (!bNoTransform)
7166 FT_Vector_Transform(&vec, &Cache.Hashed.matTransform);
7167 X64 += vec.x;
7168 Y64 -= vec.y;
7169 }
7170
7171 DPRINT("New X64, New Y64: %I64d, %I64d\n", X64, Y64);
7172
7173 previous = glyph_index;
7174 }
7175 /* Don't update position if String == NULL. Fixes CORE-19721. */
7176 if ((pdcattr->flTextAlign & TA_UPDATECP) && String)
7177 pdcattr->ptlCurrent.x = DestRect.right - dc->ptlDCOrig.x;
7178
7179 if (plf->lfUnderline || plf->lfStrikeOut) /* Underline or strike-out? */
7180 {
7181 /* Calculate the position and the thickness */
7182 INT underline_position, thickness;
7183 FT_Vector vecA64, vecB64;
7184
7185 DeltaX64 = X64 - RealXStart64;
7186 DeltaY64 = Y64 - RealYStart64;
7187
7188 if (!face->units_per_EM)
7189 {
7191 thickness = 1;
7192 }
7193 else
7194 {
7196 face->underline_position * face->size->metrics.y_ppem / face->units_per_EM;
7197 thickness =
7198 face->underline_thickness * face->size->metrics.y_ppem / face->units_per_EM;
7199 if (thickness <= 0)
7200 thickness = 1;
7201 }
7202
7203 if (plf->lfUnderline) /* Draw underline */
7204 {
7205 vecA64.x = 0;
7206 vecA64.y = (-underline_position - thickness / 2) << 6;
7207 vecB64.x = 0;
7208 vecB64.y = vecA64.y + (thickness << 6);
7209 FT_Vector_Transform(&vecA64, &Cache.Hashed.matTransform);
7210 FT_Vector_Transform(&vecB64, &Cache.Hashed.matTransform);
7211 {
7212 INT X0 = (RealXStart64 - vecA64.x + 32) >> 6;
7213 INT Y0 = (RealYStart64 + vecA64.y + 32) >> 6;
7214 INT DX = (DeltaX64 >> 6);
7215 if (Cache.Hashed.matTransform.xy == 0 && Cache.Hashed.matTransform.yx == 0)
7216 {
7217 INT CY = (vecB64.y - vecA64.y + 32) >> 6;
7218 IntEngFillBox(dc, X0, Y0, DX, CY, &dc->eboText.BrushObject);
7219 }
7220 else
7221 {
7222 INT DY = (DeltaY64 >> 6);
7223 INT X1 = X0 + ((vecA64.x - vecB64.x + 32) >> 6);
7224 INT Y1 = Y0 + ((vecB64.y - vecA64.y + 32) >> 6);
7225 POINT Points[4] =
7226 {
7227 { X0, Y0 },
7228 { X0 + DX, Y0 + DY },
7229 { X1 + DX, Y1 + DY },
7230 { X1, Y1 },
7231 };
7232 IntEngFillPolygon(dc, Points, 4, &dc->eboText.BrushObject);
7233 }
7234 }
7235 }
7236
7237 if (plf->lfStrikeOut) /* Draw strike-out */
7238 {
7239 vecA64.x = 0;
7240 vecA64.y = -(FontGDI->tmAscent << 6) / 3;
7241 vecB64.x = 0;
7242 vecB64.y = vecA64.y + (thickness << 6);
7243 FT_Vector_Transform(&vecA64, &Cache.Hashed.matTransform);
7244 FT_Vector_Transform(&vecB64, &Cache.Hashed.matTransform);
7245 {
7246 INT X0 = (RealXStart64 - vecA64.x + 32) >> 6;
7247 INT Y0 = (RealYStart64 + vecA64.y + 32) >> 6;
7248 INT DX = (DeltaX64 >> 6);
7249 if (Cache.Hashed.matTransform.xy == 0 && Cache.Hashed.matTransform.yx == 0)
7250 {
7251 INT CY = (vecB64.y - vecA64.y + 32) >> 6;
7252 IntEngFillBox(dc, X0, Y0, DX, CY, &dc->eboText.BrushObject);
7253 }
7254 else
7255 {
7256 INT DY = (DeltaY64 >> 6);
7257 INT X1 = X0 + ((vecA64.x - vecB64.x + 32) >> 6);
7258 INT Y1 = Y0 + ((vecB64.y - vecA64.y + 32) >> 6);
7259 POINT Points[4] =
7260 {
7261 { X0, Y0 },
7262 { X0 + DX, Y0 + DY },
7263 { X1 + DX, Y1 + DY },
7264 { X1, Y1 },
7265 };
7266 IntEngFillPolygon(dc, Points, 4, &dc->eboText.BrushObject);
7267 }
7268 }
7269 }
7270 }
7271
7272 FontLink_Chain_Finish(&Chain);
7273
7275
7276 EXLATEOBJ_vCleanup(&exloRGB2Dst);
7277 EXLATEOBJ_vCleanup(&exloDst2RGB);
7278
7279Cleanup:
7281
7282 if (TextObj != NULL)
7283 TEXTOBJ_UnlockText(TextObj);
7284
7285 return bResult;
7286}
static VOID del(LPHIST_ENTRY item)
Definition: history.c:199
static BOOLEAN IntLPtoDP(DC *pdc, PPOINTL ppt, UINT count)
Definition: coord.h:182
VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdcDest, const RECT *rcDest, PDC pdcSrc, const RECT *rcSrc)
Definition: dclife.c:505
VOID FASTCALL DC_vFinishBlit(PDC pdc1, PDC pdc2)
Definition: dclife.c:614
VOID FASTCALL DC_vUpdateTextBrush(PDC pdc)
Definition: dcobjs.c:108
VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc)
Definition: dcobjs.c:126
static const WCHAR Cleanup[]
Definition: register.c:80
BOOL FASTCALL TextIntGetTextExtentPoint(_In_ PDC dc, _In_ PTEXTOBJ TextObj, _In_reads_(Count) PCWCH String, _In_ INT Count, _In_ ULONG MaxExtent, _Out_ PINT Fit, _Out_writes_to_opt_(Count, *Fit) PINT Dx, _Out_ PSIZE Size, _In_ FLONG fl)
Definition: freetype.c:4956
static UINT FontLink_Chain_FindGlyph(_Inout_ PFONTLINK_CHAIN pChain, _Out_ PFONT_CACHE_ENTRY pCache, _Inout_ FT_Face *pFace, _In_ UINT code, _In_ BOOL fCodeAsIndex)
Definition: freetype.c:4368
static BOOL IntGetTextDisposition(_Out_ LONGLONG *pX64, _Out_ LONGLONG *pY64, _In_reads_(Count) PCWCH String, _In_ INT Count, _In_opt_ const INT *Dx, _Inout_ PFONT_CACHE_ENTRY Cache, _In_ UINT fuOptions, _In_ BOOL bNoTransform, _Inout_ PFONTLINK_CHAIN pChain)
Definition: freetype.c:6656
#define EMUBOLD_NEEDED(original, request)
Definition: freetype.c:308
static FT_BitmapGlyph IntGetRealGlyph(IN OUT PFONT_CACHE_ENTRY Cache)
Definition: freetype.c:4916
#define VALIGN_MASK
BOOL FASTCALL IntIsFontRenderingEnabled(VOID)
Definition: freetype.c:2700
#define gmxWorldToDeviceDefault
Definition: freetype.c:316
static VOID FontLink_Chain_Finish(_Inout_ PFONTLINK_CHAIN pChain)
Definition: freetype.c:239
static VOID FontLink_Chain_Init(_Out_ PFONTLINK_CHAIN pChain, _Inout_ PTEXTOBJ pTextObj, _In_ FT_Face face)
Definition: freetype.c:1228
FT_Render_Mode FASTCALL IntGetFontRenderMode(LOGFONTW *logfont)
Definition: freetype.c:2712
@ FT_RENDER_MODE_MONO
Definition: freetype.h:3251
return pTarget Start()
#define DX
Definition: i386-dis.c:425
#define NOTHING
Definition: input_list.c:10
static HBITMAP
Definition: button.c:44
#define DIRTY_TEXT
Definition: ntgdihdl.h:125
#define DIRTY_BACKGROUND
Definition: ntgdihdl.h:126
struct _MATRIX * PMATRIX
#define PATH_IsPathOpen(dclevel)
Definition: path.h:72
Definition: fatfs.h:173
FT_Bitmap bitmap
Definition: ftglyph.h:172
FT_GlyphRec root
Definition: ftglyph.h:169
FT_Vector advance
Definition: ftglyph.h:117
LONG lfEscapement
Definition: dimm.idl:61
long bottom
Definition: polytest.cpp:53
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
long left
Definition: polytest.cpp:53
POINTL ptlCurrent
Definition: ntgdihdl.h:311
BYTE jBkMode
Definition: ntgdihdl.h:308
INT iGraphicsMode
Definition: ntgdihdl.h:306
ULONG ulDirty_
Definition: ntgdihdl.h:294
FLONG flTextAlign
Definition: ntgdihdl.h:324
XLATEOBJ xlo
Definition: xlateobj.h:21
LONG y
Definition: windef.h:130
LONG x
Definition: windef.h:129
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
SURFOBJ SurfObj
Definition: surface.h:8
struct _PALETTE *const ppal
Definition: surface.h:11
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
T1_FIELD_DICT_FONTDICT T1_FIELD_DICT_FONTDICT T1_FIELD_DICT_FONTDICT underline_position
Definition: t1tokens.h:40
int64_t LONGLONG
Definition: typedefs.h:68
Definition: compat.h:2255
BOOL APIENTRY IntEngMaskBlt(_Inout_ SURFOBJ *psoDest, _In_ SURFOBJ *psoMask, _In_ CLIPOBJ *pco, _In_ XLATEOBJ *pxloDest, _In_ XLATEOBJ *pxloSource, _In_ RECTL *prclDest, _In_ POINTL *pptlMask, _In_ BRUSHOBJ *pbo, _In_ POINTL *pptlBrushOrg)
Definition: bitblt.c:1103
PALETTE gpalRGB
Definition: palette.c:20
BOOL FASTCALL PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECTL *lprc, LPCWSTR str, UINT count, const INT *dx)
Definition: path.c:2357
VOID APIENTRY IntEngFillPolygon(IN OUT PDC dc, IN POINTL *pPoints, IN UINT cPoints, IN BRUSHOBJ *BrushObj)
Definition: utils.c:254
VOID FASTCALL IntEngFillBox(IN OUT PDC dc, IN INT X, IN INT Y, IN INT Width, IN INT Height, IN BRUSHOBJ *BrushObj)
Definition: utils.c:209
POINTL g_PointZero
Definition: utils.c:12
static DWORD Utf32FromSurrogatePair(_In_ DWORD ch0, _In_ DWORD ch1)
Definition: utils.h:47
#define BMF_8BPP
Definition: winddi.h:357
ENGAPI BOOL APIENTRY EngDeleteSurface(_In_ _Post_ptr_invalid_ HSURF hsurf)
Definition: surface.c:567
ENGAPI SURFOBJ *APIENTRY EngLockSurface(_In_ HSURF hsurf)
Definition: surface.c:607
ENGAPI HBITMAP APIENTRY EngCreateBitmap(_In_ SIZEL sizl, _In_ LONG lWidth, _In_ ULONG iFormat, _In_ FLONG fl, _In_opt_ PVOID pvBits)
#define BMF_TOPDOWN
Definition: winddi.h:1180
typedef HSURF(APIENTRY FN_DrvEnableSurface)(_In_ DHPDEV dhpdev)
ENGAPI VOID APIENTRY EngUnlockSurface(_In_ _Post_ptr_invalid_ SURFOBJ *pso)
Definition: surface.c:628
#define GM_ADVANCED
Definition: wingdi.h:865
#define TA_UPDATECP
Definition: wingdi.h:936
#define TA_RIGHT
Definition: wingdi.h:933
#define ETO_CLIPPED
Definition: wingdi.h:648
#define ETO_OPAQUE
Definition: wingdi.h:647
#define OPAQUE
Definition: wingdi.h:949
#define ETO_PDY
Definition: wingdi.h:657
#define TA_BOTTOM
Definition: wingdi.h:929
#define TA_BASELINE
Definition: wingdi.h:928
#define TA_CENTER
Definition: wingdi.h:931
#define IS_HIGH_SURROGATE(ch)
Definition: winnls.h:752
#define IS_LOW_SURROGATE(ch)
Definition: winnls.h:753
VOID NTAPI EXLATEOBJ_vInitialize(_Out_ PEXLATEOBJ pexlo, _In_opt_ PALETTE *ppalSrc, _In_opt_ PALETTE *ppalDst, _In_ COLORREF crSrcBackColor, _In_ COLORREF crDstBackColor, _In_ COLORREF crDstForeColor)
Definition: xlateobj.c:491
VOID NTAPI EXLATEOBJ_vCleanup(_Inout_ PEXLATEOBJ pexlo)
Definition: xlateobj.c:894

Referenced by GreExtTextOutW().

◆ IntFindGlyphCache()

static FT_BitmapGlyph IntFindGlyphCache ( IN const FONT_CACHE_ENTRY pCache)
static

Definition at line 3780 of file freetype.c.

3781{
3782 PLIST_ENTRY CurrentEntry;
3783 PFONT_CACHE_ENTRY FontEntry;
3784 DWORD dwHash = pCache->dwHash;
3785
3787
3788 for (CurrentEntry = g_FontCacheListHead.Flink;
3789 CurrentEntry != &g_FontCacheListHead;
3790 CurrentEntry = CurrentEntry->Flink)
3791 {
3792 FontEntry = CONTAINING_RECORD(CurrentEntry, FONT_CACHE_ENTRY, ListEntry);
3793 if (FontEntry->dwHash == dwHash &&
3794 FontEntry->Hashed.GlyphIndex == pCache->Hashed.GlyphIndex &&
3795 FontEntry->Hashed.Face == pCache->Hashed.Face &&
3796 FontEntry->Hashed.lfHeight == pCache->Hashed.lfHeight &&
3797 FontEntry->Hashed.lfWidth == pCache->Hashed.lfWidth &&
3798 FontEntry->Hashed.AspectValue == pCache->Hashed.AspectValue &&
3799 memcmp(&FontEntry->Hashed.matTransform, &pCache->Hashed.matTransform,
3800 sizeof(FT_Matrix)) == 0)
3801 {
3802 break;
3803 }
3804 }
3805
3806 if (CurrentEntry == &g_FontCacheListHead)
3807 {
3808 return NULL;
3809 }
3810
3811 RemoveEntryList(CurrentEntry);
3812 InsertHeadList(&g_FontCacheListHead, CurrentEntry);
3813 return FontEntry->BitmapGlyph;
3814}
FT_BitmapGlyph BitmapGlyph
Definition: font.h:58
FONT_CACHE_HASHED Hashed
Definition: font.h:60
DWORD dwHash
Definition: font.h:59
LONG lfHeight
Definition: font.h:44
LONG lfWidth
Definition: font.h:45
INT GlyphIndex
Definition: font.h:42
FT_Face Face
Definition: font.h:43
FT_Matrix matTransform
Definition: font.h:50
DWORD AspectValue
Definition: font.h:47

Referenced by IntGetRealGlyph().

◆ IntFontType()

static VOID FASTCALL IntFontType ( PFONTGDI  Font)
static

Definition at line 5820 of file freetype.c.

5821{
5822 PS_FontInfoRec psfInfo;
5823 FT_ULong tmp_size = 0;
5824 FT_Face Face = Font->SharedFace->Face;
5825
5827
5828 if (FT_HAS_MULTIPLE_MASTERS(Face))
5829 Font->FontObj.flFontType |= FO_MULTIPLEMASTER;
5830 if (FT_HAS_VERTICAL(Face))
5831 Font->FontObj.flFontType |= FO_VERT_FACE;
5832 if (!FT_IS_SCALABLE(Face))
5833 Font->FontObj.flFontType |= FO_TYPE_RASTER;
5834 if (FT_IS_SFNT(Face))
5835 {
5836 Font->FontObj.flFontType |= FO_TYPE_TRUETYPE;
5838 Font->FontObj.flFontType |= FO_POSTSCRIPT;
5839 }
5840 if (!FT_Get_PS_Font_Info(Face, &psfInfo ))
5841 {
5842 Font->FontObj.flFontType |= FO_POSTSCRIPT;
5843 }
5844 /* Check for the presence of the 'CFF ' table to check if the font is Type1 */
5845 if (!FT_Load_Sfnt_Table(Face, TTAG_CFF, 0, NULL, &tmp_size))
5846 {
5847 Font->FontObj.flFontType |= (FO_CFF|FO_POSTSCRIPT);
5848 }
5849}
#define FT_HAS_MULTIPLE_MASTERS(face)
Definition: freetype.h:1361
#define FT_HAS_VERTICAL(face)
Definition: freetype.h:1242
FT_Get_PS_Font_Info(FT_Face face, PS_FontInfo afont_info)
FT_BEGIN_HEADER struct PS_FontInfoRec_ PS_FontInfoRec
#define ft_sfnt_post
Definition: tttables.h:641
#define TTAG_CFF
Definition: tttags.h:44
#define FO_TYPE_TRUETYPE
Definition: winddi.h:737
#define FO_CFF
Definition: winddi.h:747
#define FO_MULTIPLEMASTER
Definition: winddi.h:749
#define FO_POSTSCRIPT
Definition: winddi.h:748
#define FO_VERT_FACE
Definition: winddi.h:750
#define FO_TYPE_RASTER
Definition: winddi.h:735

Referenced by IntPopulateFontGdi().

◆ IntFreeFontNames()

static __inline void FASTCALL IntFreeFontNames ( FONT_NAMES Names)
static

Definition at line 3126 of file freetype.c.

3127{
3128 RtlFreeUnicodeString(&Names->FamilyNameW);
3129 RtlFreeUnicodeString(&Names->FaceNameW);
3130 RtlFreeUnicodeString(&Names->StyleNameW);
3131 RtlFreeUnicodeString(&Names->FullNameW);
3132}
PWSTR Names[]

Referenced by IntGetOutlineTextMetrics().

◆ IntGdiAddFontMemResource()

HANDLE FASTCALL IntGdiAddFontMemResource ( PVOID  Buffer,
DWORD  dwSize,
PDWORD  pNumAdded 
)

Definition at line 2528 of file freetype.c.

2529{
2530 HANDLE Ret = NULL;
2532 PFONT_ENTRY_COLL_MEM EntryCollection;
2533 INT FaceCount;
2534
2536 if (!BufferCopy)
2537 {
2538 *pNumAdded = 0;
2539 return NULL;
2540 }
2541 RtlCopyMemory(BufferCopy, Buffer, dwSize);
2542
2543 RtlZeroMemory(&LoadFont, sizeof(LoadFont));
2544 LoadFont.Memory = SharedMem_Create(BufferCopy, dwSize, FALSE);
2545 LoadFont.Characteristics = FR_PRIVATE | FR_NOT_ENUM;
2546 RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
2548
2549 RtlFreeUnicodeString(&LoadFont.RegValueName);
2550
2551 /* Release our copy */
2555
2556 if (FaceCount > 0)
2557 {
2558 EntryCollection = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY_COLL_MEM), TAG_FONT);
2559 if (EntryCollection)
2560 {
2562 EntryCollection->Entry = LoadFont.PrivateEntry;
2564 IntLockProcessPrivateFonts(Win32Process);
2565 EntryCollection->Handle = ULongToHandle(++Win32Process->PrivateMemFontHandleCount);
2566 InsertTailList(&Win32Process->PrivateMemFontListHead, &EntryCollection->ListEntry);
2567 IntUnLockProcessPrivateFonts(Win32Process);
2569 Ret = EntryCollection->Handle;
2570 }
2571 }
2572 *pNumAdded = FaceCount;
2573
2574 return Ret;
2575}
#define ULongToHandle(h)
Definition: basetsd.h:75
BOOL LoadFont(LPWSTR lpCmdLine)
static INT FASTCALL IntGdiLoadFontByIndexFromMemory(PGDI_LOAD_FONT pLoadFont, FT_Long FontIndex)
Definition: freetype.c:1940
static PSHARED_MEM SharedMem_Create(PBYTE Buffer, ULONG BufferSize, BOOL IsMapping)
Definition: freetype.c:520
static void SharedMem_Release(PSHARED_MEM Ptr)
Definition: freetype.c:577
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
Definition: font.h:20
FONT_ENTRY_MEM * Entry
Definition: font.h:23
LIST_ENTRY ListEntry
Definition: font.h:21
HANDLE Handle
Definition: font.h:22
LIST_ENTRY PrivateMemFontListHead
Definition: win32.h:286
UINT PrivateMemFontHandleCount
Definition: win32.h:287

Referenced by NtGdiAddFontMemResourceEx().

◆ IntGdiAddFontResourceEx()

INT FASTCALL IntGdiAddFontResourceEx ( _In_ PCUNICODE_STRING  FileName,
_In_ DWORD  cFiles,
_In_ DWORD  Characteristics,
_In_ DWORD  dwFlags 
)

Definition at line 2193 of file freetype.c.

2198{
2199 PWSTR pchFile = FileName->Buffer;
2200 SIZE_T cchFile;
2201 INT ret = 0;
2202
2203 while (cFiles--)
2204 {
2205 _SEH2_TRY
2206 {
2207 cchFile = wcslen(pchFile);
2208 }
2210 {
2211 _SEH2_YIELD(return FALSE);
2212 }
2213 _SEH2_END;
2214
2215 UNICODE_STRING ustrPathName;
2216 ustrPathName.Length = (USHORT)(cchFile * sizeof(WCHAR));
2217 ustrPathName.MaximumLength = ustrPathName.Length + sizeof(WCHAR);
2218 ustrPathName.Buffer = pchFile;
2219
2220 INT count = IntGdiAddFontResourceSingle(&ustrPathName, Characteristics, dwFlags);
2221 if (!count)
2222 return 0;
2223 ret += count;
2224
2225 pchFile += cchFile + 1;
2226 }
2227
2228 /* Prepare for better LOGFONT-to-face matching */
2230
2231 return ret;
2232}
static INT FASTCALL IntGdiAddFontResourceSingle(_In_ PCUNICODE_STRING FileName, _In_ DWORD Characteristics, _In_ DWORD dwFlags)
Definition: freetype.c:1994
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:184

Referenced by IntLoadFontsInRegistry(), IntLoadSystemFonts(), and NtGdiAddFontResourceW().

◆ IntGdiAddFontResourceSingle()

static INT FASTCALL IntGdiAddFontResourceSingle ( _In_ PCUNICODE_STRING  FileName,
_In_ DWORD  Characteristics,
_In_ DWORD  dwFlags 
)
static

Definition at line 1994 of file freetype.c.

1998{
2001 PVOID Buffer = NULL;
2004 SIZE_T ViewSize = 0, Length;
2005 LARGE_INTEGER SectionSize;
2008 INT FontCount;
2010 UNICODE_STRING PathName;
2011 LPWSTR pszBuffer;
2013 static const UNICODE_STRING TrueTypePostfix = RTL_CONSTANT_STRING(L" (TrueType)");
2014
2015 /* Build PathName */
2017 {
2018 Length = DosPathPrefix.Length + FileName->Length + sizeof(UNICODE_NULL);
2020 if (!pszBuffer)
2021 return 0; /* failure */
2022
2023 RtlInitEmptyUnicodeString(&PathName, pszBuffer, Length);
2026 }
2027 else
2028 {
2030 if (!NT_SUCCESS(Status))
2031 return 0; /* failure */
2032 }
2033
2034 /* Open the font file */
2038 &FileHandle,
2041 &Iosb,
2044 if (!NT_SUCCESS(Status))
2045 {
2046 DPRINT1("Could not load font file: %wZ\n", &PathName);
2047 RtlFreeUnicodeString(&PathName);
2048 return 0;
2049 }
2050
2053 if (!NT_SUCCESS(Status))
2054 {
2055 DPRINT1("ObReferenceObjectByHandle failed.\n");
2057 RtlFreeUnicodeString(&PathName);
2058 return 0;
2059 }
2060
2061 SectionSize.QuadPart = 0LL;
2064 NULL, &SectionSize, PAGE_READONLY,
2066 if (!NT_SUCCESS(Status))
2067 {
2068 DPRINT1("Could not map file: %wZ\n", &PathName);
2071 RtlFreeUnicodeString(&PathName);
2072 return 0;
2073 }
2075
2077 if (!NT_SUCCESS(Status))
2078 {
2079 DPRINT1("Could not map file: %wZ\n", &PathName);
2082 RtlFreeUnicodeString(&PathName);
2083 return 0;
2084 }
2085
2086 RtlZeroMemory(&LoadFont, sizeof(LoadFont));
2087 LoadFont.pFileName = &PathName;
2089 LoadFont.Characteristics = Characteristics;
2090 RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
2091 LoadFont.CharSet = DEFAULT_CHARSET;
2092 FontCount = IntGdiLoadFontByIndexFromMemory(&LoadFont, -1);
2093
2094 /* Release our copy */
2098
2100
2102
2103 /* Save the loaded font name into the registry */
2104 if (FontCount > 0 && (dwFlags & AFRX_WRITE_REGISTRY))
2105 {
2106 UNICODE_STRING NewString;
2107 SIZE_T Length;
2108 PWCHAR pszBuffer;
2109 LPCWSTR CharSetName;
2110 if (LoadFont.IsTrueType)
2111 {
2112 /* Append " (TrueType)" */
2113 Length = LoadFont.RegValueName.Length + TrueTypePostfix.Length + sizeof(UNICODE_NULL);
2115 if (pszBuffer)
2116 {
2117 RtlInitEmptyUnicodeString(&NewString, pszBuffer, Length);
2118 NewString.Buffer[0] = UNICODE_NULL;
2119 RtlAppendUnicodeStringToString(&NewString, &LoadFont.RegValueName);
2120 RtlAppendUnicodeStringToString(&NewString, &TrueTypePostfix);
2121 RtlFreeUnicodeString(&LoadFont.RegValueName);
2122 LoadFont.RegValueName = NewString;
2123 }
2124 else
2125 {
2126 // FIXME!
2127 }
2128 }
2129 else if (LoadFont.CharSet != DEFAULT_CHARSET)
2130 {
2131 /* Append " (CharSetName)" */
2132 CharSetName = IntNameFromCharSet(LoadFont.CharSet);
2133 Length = LoadFont.RegValueName.Length +
2134 (wcslen(CharSetName) + 3) * sizeof(WCHAR) +
2135 sizeof(UNICODE_NULL);
2136
2138 if (pszBuffer)
2139 {
2140 RtlInitEmptyUnicodeString(&NewString, pszBuffer, Length);
2141 NewString.Buffer[0] = UNICODE_NULL;
2142 RtlAppendUnicodeStringToString(&NewString, &LoadFont.RegValueName);
2143 RtlAppendUnicodeToString(&NewString, L" (");
2144 RtlAppendUnicodeToString(&NewString, CharSetName);
2145 RtlAppendUnicodeToString(&NewString, L")");
2146 RtlFreeUnicodeString(&LoadFont.RegValueName);
2147 LoadFont.RegValueName = NewString;
2148 }
2149 else
2150 {
2151 // FIXME!
2152 }
2153 }
2154
2157 NULL, NULL);
2158 Status = ZwOpenKey(&KeyHandle, KEY_WRITE, &ObjectAttributes);
2159 if (NT_SUCCESS(Status))
2160 {
2162 LPWSTR pFileName;
2163
2165 {
2166 pFileName = PathName.Buffer;
2167 }
2168 else
2169 {
2170 pFileName = wcsrchr(PathName.Buffer, L'\\');
2171 }
2172
2173 if (pFileName)
2174 {
2176 {
2177 pFileName++;
2178 }
2179 DataSize = (wcslen(pFileName) + 1) * sizeof(WCHAR);
2180 ZwSetValueKey(KeyHandle, &LoadFont.RegValueName, 0, REG_SZ,
2181 pFileName, DataSize);
2182 }
2184 }
2185 }
2186 RtlFreeUnicodeString(&LoadFont.RegValueName);
2187
2188 RtlFreeUnicodeString(&PathName);
2189 return FontCount;
2190}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define TAG_USTR
Definition: libsupp.c:997
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define PAGE_READONLY
Definition: compat.h:138
#define SECTION_MAP_READ
Definition: compat.h:139
#define wcsrchr
Definition: compat.h:16
#define FILE_SHARE_READ
Definition: compat.h:136
return Iosb
Definition: create.c:4403
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
static const UNICODE_STRING DosPathPrefix
Definition: freetype.c:1990
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define KernelMode
Definition: asm.h:38
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
#define SEC_COMMIT
Definition: mmtypes.h:100
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define SECTION_QUERY
Definition: nt_native.h:1290
#define KEY_WRITE
Definition: nt_native.h:1034
#define FILE_GENERIC_READ
Definition: nt_native.h:653
#define STANDARD_RIGHTS_REQUIRED
Definition: nt_native.h:63
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSTATUS NTAPI MmMapViewInSystemSpace(IN PVOID SectionObject, OUT PVOID *MappedBase, IN OUT PSIZE_T ViewSize)
Definition: section.c:4498
NTSTATUS NTAPI MmCreateSection(OUT PVOID *Section, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT FileObject OPTIONAL)
Definition: section.c:4671
#define LL
Definition: tui.h:166
uint16_t * PWCHAR
Definition: typedefs.h:56
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
NTSTATUS IntDuplicateUnicodeString(IN ULONG Flags, IN PCUNICODE_STRING SourceString, OUT PUNICODE_STRING DestinationString)
Definition: registry.c:361
#define AFRX_WRITE_REGISTRY
Definition: text.h:104
#define AFRX_DOS_DEVICE_PATH
Definition: text.h:106
#define AFRX_ALTERNATIVE_PATH
Definition: text.h:105
LPCWSTR FASTCALL IntNameFromCharSet(_In_ BYTE CharSet)
Definition: utils.c:54
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by IntGdiAddFontResourceEx().

◆ IntGdiCleanupMemEntry()

VOID FASTCALL IntGdiCleanupMemEntry ( PFONT_ENTRY_MEM  Head)

Definition at line 2578 of file freetype.c.

2579{
2581 PFONT_ENTRY_MEM FontEntry;
2582
2583 while (!IsListEmpty(&Head->ListEntry))
2584 {
2585 Entry = RemoveHeadList(&Head->ListEntry);
2586 FontEntry = CONTAINING_RECORD(Entry, FONT_ENTRY_MEM, ListEntry);
2587
2588 CleanupFontEntry(FontEntry->Entry);
2589 ExFreePoolWithTag(FontEntry, TAG_FONT);
2590 }
2591
2592 CleanupFontEntry(Head->Entry);
2594}
Definition: font.h:14
LIST_ENTRY ListEntry
Definition: font.h:15
FONT_ENTRY * Entry
Definition: font.h:16

Referenced by IntGdiCleanupPrivateFontsForProcess(), and IntGdiRemoveFontMemResource().

◆ IntGdiCleanupPrivateFontsForProcess()

VOID FASTCALL IntGdiCleanupPrivateFontsForProcess ( VOID  )

Definition at line 2650 of file freetype.c.

2651{
2654 PFONT_ENTRY_COLL_MEM EntryCollection;
2655
2656 DPRINT("IntGdiCleanupPrivateFontsForProcess()\n");
2657 do {
2658 Entry = NULL;
2659 EntryCollection = NULL;
2660
2662 IntLockProcessPrivateFonts(Win32Process);
2663 if (!IsListEmpty(&Win32Process->PrivateMemFontListHead))
2664 {
2665 Entry = Win32Process->PrivateMemFontListHead.Flink;
2666 EntryCollection = CONTAINING_RECORD(Entry, FONT_ENTRY_COLL_MEM, ListEntry);
2667 UnlinkFontMemCollection(EntryCollection);
2668 }
2669 IntUnLockProcessPrivateFonts(Win32Process);
2671
2672 if (EntryCollection)
2673 {
2674 IntGdiCleanupMemEntry(EntryCollection->Entry);
2675 ExFreePoolWithTag(EntryCollection, TAG_FONT);
2676 }
2677 else
2678 {
2679 /* No Mem fonts anymore, see if we have any other private fonts left */
2680 Entry = NULL;
2682 IntLockProcessPrivateFonts(Win32Process);
2683 if (!IsListEmpty(&Win32Process->PrivateFontListHead))
2684 {
2685 Entry = RemoveHeadList(&Win32Process->PrivateFontListHead);
2686 }
2687 IntUnLockProcessPrivateFonts(Win32Process);
2689
2690 if (Entry)
2691 {
2693 }
2694 }
2695
2696 } while (Entry);
2697}
VOID FASTCALL IntGdiCleanupMemEntry(PFONT_ENTRY_MEM Head)
Definition: freetype.c:2578
static VOID FASTCALL UnlinkFontMemCollection(PFONT_ENTRY_COLL_MEM Collection)
Definition: freetype.c:2597

Referenced by GdiProcessDestroy().

◆ IntGdiGetFontResourceInfo()

BOOL FASTCALL IntGdiGetFontResourceInfo ( PUNICODE_STRING  FileName,
PVOID  pBuffer,
DWORD pdwBytes,
DWORD  dwType 
)

Definition at line 6177 of file freetype.c.

6182{
6183 UNICODE_STRING EntryFileName;
6184 POBJECT_NAME_INFORMATION NameInfo1 = NULL, NameInfo2 = NULL;
6185 PLIST_ENTRY ListEntry;
6186 PFONT_ENTRY FontEntry;
6187 ULONG Size, i, Count;
6188 LPBYTE pbBuffer;
6189 BOOL IsEqual;
6190 FONTFAMILYINFO *FamInfo;
6191 const ULONG MaxFamInfo = 64;
6192 const ULONG MAX_FAM_INFO_BYTES = sizeof(FONTFAMILYINFO) * MaxFamInfo;
6193 BOOL bSuccess;
6194 const ULONG NAMEINFO_SIZE = sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR);
6195
6196 DPRINT("IntGdiGetFontResourceInfo: dwType == %lu\n", dwType);
6197
6198 do
6199 {
6200 /* Create buffer for full path name */
6201 NameInfo1 = ExAllocatePoolWithTag(PagedPool, NAMEINFO_SIZE, TAG_FINF);
6202 if (!NameInfo1)
6203 break;
6204
6205 /* Get the full path name */
6206 if (!IntGetFullFileName(NameInfo1, NAMEINFO_SIZE, FileName))
6207 break;
6208
6209 /* Create a buffer for the entries' names */
6210 NameInfo2 = ExAllocatePoolWithTag(PagedPool, NAMEINFO_SIZE, TAG_FINF);
6211 if (!NameInfo2)
6212 break;
6213
6214 FamInfo = ExAllocatePoolWithTag(PagedPool, MAX_FAM_INFO_BYTES, TAG_FINF);
6215 } while (0);
6216
6217 if (!NameInfo1 || !NameInfo2 || !FamInfo)
6218 {
6219 if (NameInfo2)
6220 ExFreePoolWithTag(NameInfo2, TAG_FINF);
6221
6222 if (NameInfo1)
6223 ExFreePoolWithTag(NameInfo1, TAG_FINF);
6224
6226 return FALSE;
6227 }
6228
6229 Count = 0;
6230
6231 /* Try to find the pathname in the global font list */
6233 for (ListEntry = g_FontListHead.Flink; ListEntry != &g_FontListHead;
6234 ListEntry = ListEntry->Flink)
6235 {
6236 FontEntry = CONTAINING_RECORD(ListEntry, FONT_ENTRY, ListEntry);
6237 if (FontEntry->Font->Filename == NULL)
6238 continue;
6239
6240 RtlInitUnicodeString(&EntryFileName , FontEntry->Font->Filename);
6241 if (!IntGetFullFileName(NameInfo2, NAMEINFO_SIZE, &EntryFileName))
6242 continue;
6243
6244 if (!RtlEqualUnicodeString(&NameInfo1->Name, &NameInfo2->Name, FALSE))
6245 continue;
6246
6247 IsEqual = FALSE;
6248 FontFamilyFillInfo(&FamInfo[Count], FontEntry->FaceName.Buffer,
6249 NULL, FontEntry->Font);
6250 for (i = 0; i < Count; ++i)
6251 {
6252 if (EqualFamilyInfo(&FamInfo[i], &FamInfo[Count]))
6253 {
6254 IsEqual = TRUE;
6255 break;
6256 }
6257 }
6258 if (!IsEqual)
6259 {
6260 /* Found */
6261 ++Count;
6262 if (Count >= MaxFamInfo)
6263 break;
6264 }
6265 }
6267
6268 /* Free the buffers */
6269 ExFreePoolWithTag(NameInfo1, TAG_FINF);
6270 ExFreePoolWithTag(NameInfo2, TAG_FINF);
6271
6272 if (Count == 0 && dwType != 5)
6273 {
6274 /* Font could not be found in system table
6275 dwType == 5 will still handle this */
6276 ExFreePoolWithTag(FamInfo, TAG_FINF);
6277 return FALSE;
6278 }
6279
6280 bSuccess = FALSE;
6281 switch (dwType)
6282 {
6283 case 0: /* FIXME: Returns 1 or 2, don't know what this is atm */
6284 Size = sizeof(DWORD);
6285 if (*pdwBytes == 0)
6286 {
6287 *pdwBytes = Size;
6288 bSuccess = TRUE;
6289 }
6290 else if (pBuffer)
6291 {
6292 if (*pdwBytes >= Size)
6293 {
6294 *(DWORD*)pBuffer = Count;
6295 }
6296 *pdwBytes = Size;
6297 bSuccess = TRUE;
6298 }
6299 break;
6300
6301 case 1: /* copy the font title */
6302 /* calculate the required size */
6303 Size = 0;
6304 for (i = 0; i < Count; ++i)
6305 {
6306 if (i > 0)
6307 Size += 3; /* " & " */
6308 Size += wcslen(FamInfo[i].EnumLogFontEx.elfLogFont.lfFaceName);
6309 if (FamInfo[i].EnumLogFontEx.elfStyle[0] &&
6310 _wcsicmp(FamInfo[i].EnumLogFontEx.elfStyle, L"Regular") != 0)
6311 {
6312 Size += 1 + wcslen(FamInfo[i].EnumLogFontEx.elfStyle);
6313 }
6314 }
6315 Size += 2; /* "\0\0" */
6316 Size *= sizeof(WCHAR);
6317
6318 if (*pdwBytes == 0)
6319 {
6320 *pdwBytes = Size;
6321 bSuccess = TRUE;
6322 }
6323 else if (pBuffer)
6324 {
6325 if (*pdwBytes >= Size)
6326 {
6327 /* store font title to buffer */
6328 WCHAR *psz = pBuffer;
6329 *psz = 0;
6330 for (i = 0; i < Count; ++i)
6331 {
6332 if (i > 0)
6333 wcscat(psz, L" & ");
6334 IntAddNameFromFamInfo(psz, &FamInfo[i]);
6335 }
6336 psz[wcslen(psz) + 1] = UNICODE_NULL;
6337 *pdwBytes = Size;
6338 bSuccess = TRUE;
6339 }
6340 else
6341 {
6342 *pdwBytes = 1024; /* this is confirmed value */
6343 }
6344 }
6345 break;
6346
6347 case 2: /* Copy an array of LOGFONTW */
6348 Size = Count * sizeof(LOGFONTW);
6349 if (*pdwBytes == 0)
6350 {
6351 *pdwBytes = Size;
6352 bSuccess = TRUE;
6353 }
6354 else if (pBuffer)
6355 {
6356 if (*pdwBytes >= Size)
6357 {
6358 pbBuffer = (LPBYTE)pBuffer;
6359 for (i = 0; i < Count; ++i)
6360 {
6361 FamInfo[i].EnumLogFontEx.elfLogFont.lfWidth = 0;
6362 RtlCopyMemory(pbBuffer, &FamInfo[i].EnumLogFontEx.elfLogFont, sizeof(LOGFONTW));
6363 pbBuffer += sizeof(LOGFONTW);
6364 }
6365 }
6366 *pdwBytes = Size;
6367 bSuccess = TRUE;
6368 }
6369 else
6370 {
6371 *pdwBytes = 1024; /* this is confirmed value */
6372 }
6373 break;
6374
6375 case 3:
6376 Size = sizeof(DWORD);
6377 if (*pdwBytes == 0)
6378 {
6379 *pdwBytes = Size;
6380 bSuccess = TRUE;
6381 }
6382 else if (pBuffer)
6383 {
6384 if (*pdwBytes >= Size)
6385 {
6386 /* FIXME: What exactly is copied here? */
6387 *(DWORD*)pBuffer = 1;
6388 }
6389 *pdwBytes = Size;
6390 bSuccess = TRUE;
6391 }
6392 break;
6393
6394 case 4: /* full file path */
6395 if (FileName->Length >= 4 * sizeof(WCHAR))
6396 {
6397 /* The beginning of FileName is \??\ */
6398 LPWSTR pch = FileName->Buffer + 4;
6399 DWORD Length = FileName->Length - 4 * sizeof(WCHAR);
6400
6401 Size = Length + sizeof(WCHAR);
6402 if (*pdwBytes == 0)
6403 {
6404 *pdwBytes = Size;
6405 bSuccess = TRUE;
6406 }
6407 else if (pBuffer)
6408 {
6409 if (*pdwBytes >= Size)
6410 {
6412 }
6413 *pdwBytes = Size;
6414 bSuccess = TRUE;
6415 }
6416 }
6417 break;
6418
6419 case 5: /* Looks like a BOOL that is copied, TRUE, if the font was not found */
6420 Size = sizeof(BOOL);
6421 if (*pdwBytes == 0)
6422 {
6423 *pdwBytes = Size;
6424 bSuccess = TRUE;
6425 }
6426 else if (pBuffer)
6427 {
6428 if (*pdwBytes >= Size)
6429 {
6430 *(BOOL*)pBuffer = Count == 0;
6431 }
6432 *pdwBytes = Size;
6433 bSuccess = TRUE;
6434 }
6435 break;
6436 }
6437 ExFreePoolWithTag(FamInfo, TAG_FINF);
6438
6439 return bSuccess;
6440}
@ IsEqual
Definition: fatprocs.h:1887
static BOOL FASTCALL IntGetFullFileName(POBJECT_NAME_INFORMATION NameInfo, ULONG Size, PUNICODE_STRING FileName)
Definition: freetype.c:6100
static BOOL EqualFamilyInfo(const FONTFAMILYINFO *pInfo1, const FONTFAMILYINFO *pInfo2)
Definition: freetype.c:6143
static VOID IntAddNameFromFamInfo(LPWSTR psz, FONTFAMILYINFO *FamInfo)
Definition: freetype.c:6164
static PWSTR PDWORD pdwBytes
Definition: layerapi.c:35
#define pch(ap)
Definition: match.c:418
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
struct tagFONTFAMILYINFO FONTFAMILYINFO
PVOID pBuffer
UNICODE_STRING Name
Definition: nt_native.h:1273
unsigned char * LPBYTE
Definition: typedefs.h:53
#define TAG_FINF
Definition: text.h:3

Referenced by NtGdiGetFontResourceInfoInternalW().

◆ IntGdiLoadFontByIndexFromMemory()

static INT FASTCALL IntGdiLoadFontByIndexFromMemory ( PGDI_LOAD_FONT  pLoadFont,
FT_Long  FontIndex 
)
static

Definition at line 1940 of file freetype.c.

1941{
1943 FT_Face Face;
1944 FT_Long iFace, num_faces;
1945 PSHARED_FACE SharedFace;
1946 INT FaceCount = 0;
1947
1949
1950 /* Load a face from memory */
1952 pLoadFont->Memory->Buffer, pLoadFont->Memory->BufferSize,
1953 ((FontIndex == -1) ? 0 : FontIndex), &Face);
1954 if (Error)
1955 {
1956 if (Error == FT_Err_Unknown_File_Format)
1957 DPRINT1("Unknown font file format\n");
1958 else
1959 DPRINT1("Error reading font (error code: %d)\n", Error);
1961 return 0; /* Failure */
1962 }
1963
1964 pLoadFont->IsTrueType = FT_IS_SFNT(Face);
1965 num_faces = Face->num_faces;
1966 SharedFace = SharedFace_Create(Face, pLoadFont->Memory);
1967
1969
1970 if (!SharedFace)
1971 {
1972 DPRINT1("SharedFace_Create failed\n");
1974 return 0; /* Failure */
1975 }
1976
1977 if (FontIndex == -1)
1978 {
1979 for (iFace = 1; iFace < num_faces; ++iFace)
1980 {
1982 }
1983 FontIndex = 0;
1984 }
1985
1986 FaceCount += IntGdiLoadFontsFromMemory(pLoadFont, SharedFace, FontIndex, -1);
1987 return FaceCount;
1988}
static PSHARED_FACE SharedFace_Create(FT_Face Face, PSHARED_MEM Memory)
Definition: freetype.c:501
static INT FASTCALL IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont, PSHARED_FACE SharedFace, FT_Long FontIndex, INT CharSetIndex)
Definition: freetype.c:1649
FT_New_Memory_Face(FT_Library library, const FT_Byte *file_base, FT_Long file_size, FT_Long face_index, FT_Face *aface)
Definition: ftobjs.c:1493
signed long FT_Long
Definition: fttypes.h:242
FT_Long num_faces
Definition: freetype.h:1030
PSHARED_MEM Memory
Definition: font.h:87
BOOL IsTrueType
Definition: font.h:90
ULONG BufferSize
Definition: engobjects.h:120
PVOID Buffer
Definition: engobjects.h:119
_In_ ULONG_PTR _In_ ULONG iFace
Definition: winddi.h:3836

Referenced by IntGdiAddFontMemResource(), IntGdiAddFontResourceSingle(), and IntGdiLoadFontByIndexFromMemory().

◆ IntGdiLoadFontsFromMemory()

static INT FASTCALL IntGdiLoadFontsFromMemory ( PGDI_LOAD_FONT  pLoadFont,
PSHARED_FACE  SharedFace,
FT_Long  FontIndex,
INT  CharSetIndex 
)
static

Definition at line 1649 of file freetype.c.

1651{
1654 FONT_ENTRY_MEM* PrivateEntry = NULL;
1655 FONTGDI * FontGDI;
1657 FT_Face Face;
1659 FT_WinFNT_HeaderRec WinFNT;
1660 INT FaceCount = 0, CharSetCount = 0;
1661 PUNICODE_STRING pFileName = pLoadFont->pFileName;
1662 DWORD Characteristics = pLoadFont->Characteristics;
1663 PUNICODE_STRING pValueName = &pLoadFont->RegValueName;
1664 TT_OS2 * pOS2;
1665 INT BitIndex;
1666 FT_UShort os2_version;
1667 FT_ULong os2_ulCodePageRange1;
1668 FT_UShort os2_usWeightClass;
1669
1670 ASSERT(SharedFace != NULL);
1671 ASSERT(FontIndex != -1);
1672
1674 Face = SharedFace->Face;
1675 SharedFace_AddRef(SharedFace);
1677
1678 /* allocate a FONT_ENTRY */
1680 if (!Entry)
1681 {
1682 SharedFace_Release(SharedFace, TRUE);
1684 return 0; /* failure */
1685 }
1686
1687 /* allocate a FONTGDI */
1688 FontGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(FONTGDI), GDITAG_RFONT);
1689 if (!FontGDI)
1690 {
1691 SharedFace_Release(SharedFace, TRUE);
1694 return 0; /* failure */
1695 }
1696
1697 /* set file name */
1698 if (pFileName)
1699 {
1701 pFileName->Length + sizeof(UNICODE_NULL),
1702 GDITAG_PFF);
1703 if (FontGDI->Filename == NULL)
1704 {
1705 EngFreeMem(FontGDI);
1706 SharedFace_Release(SharedFace, TRUE);
1709 return 0; /* failure */
1710 }
1711
1712 RtlCopyMemory(FontGDI->Filename, pFileName->Buffer, pFileName->Length);
1713 FontGDI->Filename[pFileName->Length / sizeof(WCHAR)] = UNICODE_NULL;
1714 }
1715 else
1716 {
1717 FontGDI->Filename = NULL;
1718
1719 PrivateEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY_MEM), TAG_FONT);
1720 if (!PrivateEntry)
1721 {
1722 if (FontGDI->Filename)
1724 EngFreeMem(FontGDI);
1725 SharedFace_Release(SharedFace, TRUE);
1728 return 0; /* failure */
1729 }
1730
1731 PrivateEntry->Entry = Entry;
1732 if (pLoadFont->PrivateEntry)
1733 {
1734 InsertTailList(&pLoadFont->PrivateEntry->ListEntry, &PrivateEntry->ListEntry);
1735 }
1736 else
1737 {
1738 InitializeListHead(&PrivateEntry->ListEntry);
1739 pLoadFont->PrivateEntry = PrivateEntry;
1740 }
1741 }
1742
1743 /* set face */
1744 FontGDI->SharedFace = SharedFace;
1745 FontGDI->CharSet = ANSI_CHARSET;
1746 FontGDI->OriginalItalic = FALSE;
1747 FontGDI->RequestItalic = FALSE;
1748 FontGDI->OriginalWeight = FW_DONTCARE;
1749 FontGDI->RequestWeight = FW_NORMAL;
1750
1752 pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
1753 if (pOS2)
1754 {
1755 FontGDI->OriginalItalic = !!(pOS2->fsSelection & 0x1);
1756 FontGDI->OriginalWeight = pOS2->usWeightClass;
1757 }
1758 else
1759 {
1760 Error = FT_Get_WinFNT_Header(Face, &WinFNT);
1761 if (!Error)
1762 {
1763 FontGDI->OriginalItalic = !!WinFNT.italic;
1764 FontGDI->OriginalWeight = WinFNT.weight;
1765 }
1766 }
1768
1771 if (NT_SUCCESS(Status))
1772 {
1773 if (Face->style_name && Face->style_name[0] &&
1774 strcmp(Face->style_name, "Regular") != 0)
1775 {
1778 if (!NT_SUCCESS(Status))
1779 {
1780 RtlFreeUnicodeString(&Entry->FaceName);
1781 }
1782 }
1783 else
1784 {
1785 RtlInitUnicodeString(&Entry->StyleName, NULL);
1786 }
1787 }
1788 if (!NT_SUCCESS(Status))
1789 {
1790 if (PrivateEntry)
1791 {
1792 if (pLoadFont->PrivateEntry == PrivateEntry)
1793 {
1794 pLoadFont->PrivateEntry = NULL;
1795 }
1796 else
1797 {
1798 RemoveEntryList(&PrivateEntry->ListEntry);
1799 }
1800 ExFreePoolWithTag(PrivateEntry, TAG_FONT);
1801 }
1802 if (FontGDI->Filename)
1804 EngFreeMem(FontGDI);
1805 SharedFace_Release(SharedFace, TRUE);
1807 return 0;
1808 }
1809
1810 os2_version = 0;
1812 pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
1813 if (pOS2)
1814 {
1815 os2_version = pOS2->version;
1816 os2_ulCodePageRange1 = pOS2->ulCodePageRange1;
1817 os2_usWeightClass = pOS2->usWeightClass;
1818 }
1820
1821 if (pOS2 && os2_version >= 1)
1822 {
1823 /* get charset and weight from OS/2 header */
1824
1825 /* Make sure we do not use this pointer anymore */
1826 pOS2 = NULL;
1827
1828 for (BitIndex = 0; BitIndex < MAXTCIINDEX; ++BitIndex)
1829 {
1830 if (os2_ulCodePageRange1 & (1 << BitIndex))
1831 {
1832 if (g_FontTci[BitIndex].ciCharset == DEFAULT_CHARSET)
1833 continue;
1834
1835 if ((CharSetIndex == -1 && CharSetCount == 0) ||
1836 CharSetIndex == CharSetCount)
1837 {
1838 FontGDI->CharSet = g_FontTci[BitIndex].ciCharset;
1839 }
1840
1841 ++CharSetCount;
1842 }
1843 }
1844
1845 /* set actual weight */
1846 FontGDI->OriginalWeight = os2_usWeightClass;
1847 }
1848 else
1849 {
1850 /* get charset from WinFNT header */
1852 Error = FT_Get_WinFNT_Header(Face, &WinFNT);
1853 if (!Error)
1854 {
1855 FontGDI->CharSet = WinFNT.charset;
1856 }
1858 }
1859
1860 ++FaceCount;
1861 DPRINT("Font loaded: %s (%s)\n",
1862 Face->family_name ? Face->family_name : "<NULL>",
1863 Face->style_name ? Face->style_name : "<NULL>");
1864 DPRINT("Num glyphs: %d\n", Face->num_glyphs);
1865 DPRINT("CharSet: %d\n", FontGDI->CharSet);
1866
1867 /* Add this font resource to the font table */
1868 Entry->Font = FontGDI;
1869 Entry->NotEnum = (Characteristics & FR_NOT_ENUM);
1870
1872 if (Characteristics & FR_PRIVATE)
1873 {
1874 /* private font */
1876 IntLockProcessPrivateFonts(Win32Process);
1877 InsertTailList(&Win32Process->PrivateFontListHead, &Entry->ListEntry);
1878 IntUnLockProcessPrivateFonts(Win32Process);
1879 }
1880 else
1881 {
1882 /* global font */
1883 InsertTailList(&g_FontListHead, &Entry->ListEntry);
1884 }
1886
1887 if (CharSetIndex == -1)
1888 {
1889 INT i;
1890 USHORT NameLength = Entry->FaceName.Length;
1891
1892 if (Entry->StyleName.Length)
1893 NameLength += Entry->StyleName.Length + sizeof(WCHAR);
1894
1895 if (pLoadFont->RegValueName.Length == 0)
1896 {
1897 pValueName->Length = 0;
1898 pValueName->MaximumLength = NameLength + sizeof(WCHAR);
1900 pValueName->MaximumLength,
1901 TAG_USTR);
1902 pValueName->Buffer[0] = UNICODE_NULL;
1903 RtlAppendUnicodeStringToString(pValueName, &Entry->FaceName);
1904 }
1905 else
1906 {
1907 UNICODE_STRING NewString;
1908 USHORT Length = pValueName->Length + 3 * sizeof(WCHAR) + NameLength;
1909 NewString.Length = 0;
1910 NewString.MaximumLength = Length + sizeof(WCHAR);
1912 NewString.MaximumLength,
1913 TAG_USTR);
1914 NewString.Buffer[0] = UNICODE_NULL;
1915
1916 RtlAppendUnicodeStringToString(&NewString, pValueName);
1917 RtlAppendUnicodeToString(&NewString, L" & ");
1918 RtlAppendUnicodeStringToString(&NewString, &Entry->FaceName);
1919
1920 RtlFreeUnicodeString(pValueName);
1921 *pValueName = NewString;
1922 }
1923 if (Entry->StyleName.Length)
1924 {
1925 RtlAppendUnicodeToString(pValueName, L" ");
1926 RtlAppendUnicodeStringToString(pValueName, &Entry->StyleName);
1927 }
1928
1929 for (i = 1; i < CharSetCount; ++i)
1930 {
1931 /* Do not count charsets as loaded 'faces' */
1932 IntGdiLoadFontsFromMemory(pLoadFont, SharedFace, FontIndex, i);
1933 }
1934 }
1935
1936 return FaceCount; /* Number of loaded faces */
1937}
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
@ AnsiString
Definition: dnslib.h:19
unsigned short FT_UShort
Definition: fttypes.h:209
#define FL_ZERO_MEMORY
Definition: polytest.cpp:58
void * EngAllocMem(int zero, unsigned long size, int tag=0)
Definition: polytest.cpp:70
FT_Long num_glyphs
Definition: freetype.h:1036
FT_String * family_name
Definition: freetype.h:1038
FT_UShort weight
Definition: ftwinfnt.h:198
PUNICODE_STRING pFileName
Definition: font.h:86
PFONT_ENTRY_MEM PrivateEntry
Definition: font.h:92
UNICODE_STRING RegValueName
Definition: font.h:89
DWORD Characteristics
Definition: font.h:88
FT_UShort fsSelection
Definition: tttables.h:403
FT_UShort usWeightClass
Definition: tttables.h:379
@ FT_SFNT_OS2
Definition: tttables.h:624
#define GDITAG_RFONT
Definition: tags.h:92

Referenced by IntGdiLoadFontByIndexFromMemory(), and IntGdiLoadFontsFromMemory().

◆ IntGdiRemoveFontMemResource()

BOOL FASTCALL IntGdiRemoveFontMemResource ( HANDLE  hMMFont)

Definition at line 2614 of file freetype.c.

2615{
2617 PFONT_ENTRY_COLL_MEM CurrentEntry;
2618 PFONT_ENTRY_COLL_MEM EntryCollection = NULL;
2620
2622 IntLockProcessPrivateFonts(Win32Process);
2623 for (Entry = Win32Process->PrivateMemFontListHead.Flink;
2624 Entry != &Win32Process->PrivateMemFontListHead;
2625 Entry = Entry->Flink)
2626 {
2627 CurrentEntry = CONTAINING_RECORD(Entry, FONT_ENTRY_COLL_MEM, ListEntry);
2628
2629 if (CurrentEntry->Handle == hMMFont)
2630 {
2631 EntryCollection = CurrentEntry;
2632 UnlinkFontMemCollection(CurrentEntry);
2633 break;
2634 }
2635 }
2636 IntUnLockProcessPrivateFonts(Win32Process);
2638
2639 if (EntryCollection)
2640 {
2641 IntGdiCleanupMemEntry(EntryCollection->Entry);
2642 ExFreePoolWithTag(EntryCollection, TAG_FONT);
2643 return TRUE;
2644 }
2645 return FALSE;
2646}

Referenced by NtGdiRemoveFontMemResourceEx().

◆ IntGdiRemoveFontResource()

BOOL FASTCALL IntGdiRemoveFontResource ( _In_ PCUNICODE_STRING  FileName,
_In_ DWORD  cFiles,
_In_ DWORD  dwFlags 
)

Definition at line 2340 of file freetype.c.

2344{
2345 PWSTR pchFile = FileName->Buffer;
2346 SIZE_T cchFile;
2347
2348 while (cFiles--)
2349 {
2350 _SEH2_TRY
2351 {
2352 cchFile = wcslen(pchFile);
2353 }
2355 {
2356 _SEH2_YIELD(return FALSE);
2357 }
2358 _SEH2_END;
2359
2360 UNICODE_STRING ustrPathName;
2361 ustrPathName.Length = (USHORT)(cchFile * sizeof(WCHAR));
2362 ustrPathName.MaximumLength = ustrPathName.Length + sizeof(WCHAR);
2363 ustrPathName.Buffer = pchFile;
2364
2366 if (!ret)
2367 return FALSE;
2368
2369 pchFile += cchFile + 1;
2370 }
2371
2372 return TRUE;
2373}
static BOOL FASTCALL IntGdiRemoveFontResourceSingle(_In_ PCUNICODE_STRING FileName, _In_ DWORD dwFlags)
Definition: freetype.c:2270

Referenced by NtGdiRemoveFontResourceW().

◆ IntGdiRemoveFontResourceSingle()

static BOOL FASTCALL IntGdiRemoveFontResourceSingle ( _In_ PCUNICODE_STRING  FileName,
_In_ DWORD  dwFlags 
)
static

Definition at line 2270 of file freetype.c.

2273{
2274 BOOL ret = FALSE;
2275 UNICODE_STRING PathName;
2276 PLIST_ENTRY CurrentEntry, NextEntry;
2277 PFONT_ENTRY FontEntry;
2278 PFONTGDI FontGDI;
2279 PWSTR pszBuffer, pszFileTitle;
2280 SIZE_T Length;
2282
2283 /* Build PathName */
2285 {
2286 Length = DosPathPrefix.Length + FileName->Length + sizeof(UNICODE_NULL);
2288 if (!pszBuffer)
2289 return FALSE; /* Failure */
2290
2291 RtlInitEmptyUnicodeString(&PathName, pszBuffer, Length);
2294 }
2295 else
2296 {
2298 if (!NT_SUCCESS(Status))
2299 return FALSE; /* Failure */
2300 }
2301
2302 pszFileTitle = PathName.Buffer;
2304 pszFileTitle = PathFindFileNameW(PathName.Buffer);
2305
2306 if (!pszFileTitle || !*pszFileTitle)
2307 {
2308 RtlFreeUnicodeString(&PathName);
2309 return FALSE; /* Failure */
2310 }
2311
2312 /* Delete font entries that matches PathName */
2314 for (CurrentEntry = g_FontListHead.Flink;
2315 CurrentEntry != &g_FontListHead;
2316 CurrentEntry = NextEntry)
2317 {
2318 FontEntry = CONTAINING_RECORD(CurrentEntry, FONT_ENTRY, ListEntry);
2319 NextEntry = CurrentEntry->Flink;
2320
2321 FontGDI = FontEntry->Font;
2322 ASSERT(FontGDI);
2323 if (FontGDI->Filename && _wcsicmp(FontGDI->Filename, pszFileTitle) == 0)
2324 {
2326 RemoveEntryList(&FontEntry->ListEntry);
2327 CleanupFontEntry(FontEntry);
2329 IntDeleteRegFontEntries(pszFileTitle, dwFlags);
2330 ret = TRUE;
2331 }
2332 }
2334
2335 RtlFreeUnicodeString(&PathName);
2336 return ret;
2337}
WCHAR *WINAPI PathFindFileNameW(const WCHAR *path)
Definition: path.c:1701
VOID IntDeleteRegFontEntries(_In_ PCWSTR pszFileName, _In_ DWORD dwFlags)
Definition: freetype.c:2235
LIST_ENTRY ListEntry
Definition: font.h:6

Referenced by IntGdiRemoveFontResource().

◆ IntGetBitmapGlyphWithCache()

static FT_BitmapGlyph IntGetBitmapGlyphWithCache ( IN OUT PFONT_CACHE_ENTRY  Cache,
IN FT_GlyphSlot  GlyphSlot 
)
static

Definition at line 3817 of file freetype.c.

3820{
3821 FT_Glyph GlyphCopy;
3822 INT error;
3823 PFONT_CACHE_ENTRY NewEntry;
3824 FT_Bitmap AlignedBitmap;
3825 FT_BitmapGlyph BitmapGlyph;
3826
3828
3829 error = FT_Get_Glyph(GlyphSlot, &GlyphCopy);
3830 if (error)
3831 {
3832 DPRINT1("Failure caching glyph.\n");
3833 return NULL;
3834 };
3835
3836 error = FT_Glyph_To_Bitmap(&GlyphCopy, Cache->Hashed.Aspect.RenderMode, 0, 1);
3837 if (error)
3838 {
3839 FT_Done_Glyph(GlyphCopy);
3840 DPRINT1("Failure rendering glyph.\n");
3841 return NULL;
3842 };
3843
3845 if (!NewEntry)
3846 {
3847 DPRINT1("Alloc failure caching glyph.\n");
3848 FT_Done_Glyph(GlyphCopy);
3849 return NULL;
3850 }
3851
3852 BitmapGlyph = (FT_BitmapGlyph)GlyphCopy;
3853 FT_Bitmap_New(&AlignedBitmap);
3854 if (FT_Bitmap_Convert_ReactOS_Hack(GlyphSlot->library, &BitmapGlyph->bitmap,
3855 &AlignedBitmap, 4, TRUE))
3856 {
3857 DPRINT1("Conversion failed\n");
3858 ExFreePoolWithTag(NewEntry, TAG_FONT);
3859 FT_Bitmap_Done(GlyphSlot->library, &AlignedBitmap);
3860 FT_Done_Glyph((FT_Glyph)BitmapGlyph);
3861 return NULL;
3862 }
3863
3864 FT_Bitmap_Done(GlyphSlot->library, &BitmapGlyph->bitmap);
3865 BitmapGlyph->bitmap = AlignedBitmap;
3866
3867 NewEntry->BitmapGlyph = BitmapGlyph;
3868 NewEntry->dwHash = Cache->dwHash;
3869 NewEntry->Hashed = Cache->Hashed;
3870
3871 InsertHeadList(&g_FontCacheListHead, &NewEntry->ListEntry);
3873 {
3874 NewEntry = CONTAINING_RECORD(g_FontCacheListHead.Blink, FONT_CACHE_ENTRY, ListEntry);
3875 RemoveCachedEntry(NewEntry);
3876 }
3877
3878 return BitmapGlyph;
3879}
#define MAX_FONT_CACHE
Definition: freetype.c:349
FT_Bitmap_New(FT_Bitmap *abitmap)
Definition: ftbitmap.c:53
FT_Bitmap_Done(FT_Library library, FT_Bitmap *bitmap)
Definition: ftbitmap.c:1197
FT_Done_Glyph(FT_Glyph glyph)
Definition: ftglyph.c:641
FT_Glyph_To_Bitmap(FT_Glyph *the_glyph, FT_Render_Mode render_mode, FT_Vector *origin, FT_Bool destroy)
Definition: ftglyph.c:536
FT_Get_Glyph(FT_GlyphSlot slot, FT_Glyph *aglyph)
Definition: ftglyph.c:401
struct FT_BitmapGlyphRec_ * FT_BitmapGlyph
Definition: ftglyph.h:131
LIST_ENTRY ListEntry
Definition: font.h:57

Referenced by IntGetRealGlyph().

◆ IntGetCharSet()

UINT FASTCALL IntGetCharSet ( INT  nIndex,
FT_ULong  CodePageRange1 
)

Definition at line 1621 of file freetype.c.

1622{
1623 UINT BitIndex, CharSet;
1624 UINT nCount = 0;
1625
1626 if (CodePageRange1 == 0)
1627 return (nIndex < 0) ? 1 : DEFAULT_CHARSET;
1628
1629 for (BitIndex = 0; BitIndex < MAXTCIINDEX; ++BitIndex)
1630 {
1631 if (CodePageRange1 & (1 << BitIndex))
1632 {
1633 CharSet = g_FontTci[BitIndex].ciCharset;
1634 if ((nIndex >= 0) && (nCount == (UINT)nIndex))
1635 {
1636 return CharSet;
1637 }
1638 ++nCount;
1639 }
1640 }
1641
1642 return (nIndex < 0) ? nCount : ANSI_CHARSET;
1643}
static void CharSet(RTF_Info *info)
Definition: reader.c:2400

◆ IntGetFontDefaultChar()

static BOOL IntGetFontDefaultChar ( _In_ FT_Face  Face,
_Out_ PWCHAR  pDefChar 
)
static

Definition at line 7675 of file freetype.c.

7676{
7677 TT_OS2 *pOS2;
7678 FT_WinFNT_HeaderRec WinFNT;
7680
7682
7683 if (FT_IS_SFNT(Face)) // TrueType / OpenType
7684 {
7686 pOS2 = FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
7687 if (pOS2)
7688 *pDefChar = pOS2->usDefaultChar;
7690 return !!pOS2;
7691 }
7692
7693 if (!FT_IS_SCALABLE(Face)) // *.fon / *.fnt
7694 {
7696 error = FT_Get_WinFNT_Header(Face, &WinFNT);
7698 if (!error)
7699 *pDefChar = WinFNT.default_char;
7700 return !error;
7701 }
7702
7703 *pDefChar = 0; // .notdef
7704 return TRUE;
7705}
FT_UShort usDefaultChar
Definition: tttables.h:421

Referenced by NtGdiGetGlyphIndicesW().

◆ IntGetFontFamilyInfo()

LONG FASTCALL IntGetFontFamilyInfo ( HDC  Dc,
const LOGFONTW SafeLogFont,
PFONTFAMILYINFO  SafeInfo,
LONG  InfoCount 
)

Definition at line 6515 of file freetype.c.

6519{
6520 LONG AvailCount = 0;
6521 PPROCESSINFO Win32Process;
6522
6523 /* Enumerate font families in the global list */
6525 if (!GetFontFamilyInfoForList(SafeLogFont, SafeInfo, NULL, &AvailCount,
6526 InfoCount, &g_FontListHead))
6527 {
6529 return -1;
6530 }
6531
6532 /* Enumerate font families in the process local list */
6533 Win32Process = PsGetCurrentProcessWin32Process();
6534 IntLockProcessPrivateFonts(Win32Process);
6535 if (!GetFontFamilyInfoForList(SafeLogFont, SafeInfo, NULL, &AvailCount, InfoCount,
6536 &Win32Process->PrivateFontListHead))
6537 {
6538 IntUnLockProcessPrivateFonts(Win32Process);
6540 return -1;
6541 }
6542 IntUnLockProcessPrivateFonts(Win32Process);
6544
6545 /* Enumerate font families in the registry */
6546 if (!GetFontFamilyInfoForSubstitutes(SafeLogFont, SafeInfo, &AvailCount, InfoCount))
6547 {
6548 return -1;
6549 }
6550
6551 return AvailCount;
6552}
static BOOLEAN FASTCALL GetFontFamilyInfoForSubstitutes(const LOGFONTW *LogFont, PFONTFAMILYINFO Info, LONG *pCount, LONG MaxCount)
Definition: freetype.c:3690

Referenced by NtGdiGetFontFamilyInfo().

◆ IntGetFontLocalizedName()

static NTSTATUS IntGetFontLocalizedName ( PUNICODE_STRING  pNameW,
PSHARED_FACE  SharedFace,
FT_UShort  NameID,
FT_UShort  LangID 
)
static

Definition at line 3299 of file freetype.c.

3301{
3303 INT i, Count, BestIndex, Score, BestScore;
3306 ANSI_STRING AnsiName;
3308 FT_Face Face = SharedFace->Face;
3309
3310 RtlFreeUnicodeString(pNameW);
3311
3312 /* select cache */
3314 Cache = &SharedFace->EnglishUS;
3315 else
3316 Cache = &SharedFace->UserLanguage;
3317
3318 /* use cache if available */
3319 if (NameID == TT_NAME_ID_FONT_FAMILY && Cache->FontFamily.Buffer)
3320 return IntDuplicateUnicodeString(&Cache->FontFamily, pNameW);
3321 if (NameID == TT_NAME_ID_FULL_NAME && Cache->FullName.Buffer)
3322 return IntDuplicateUnicodeString(&Cache->FullName, pNameW);
3323
3324 BestIndex = -1;
3325 BestScore = 0;
3326
3328 for (i = 0; i < Count; ++i)
3329 {
3330 Error = FT_Get_Sfnt_Name(Face, i, &Name);
3331 if (Error)
3332 continue; /* failure */
3333
3334 if (Name.name_id != NameID)
3335 continue; /* mismatched */
3336
3337 if (Name.platform_id != TT_PLATFORM_MICROSOFT ||
3338 (Name.encoding_id != TT_MS_ID_UNICODE_CS &&
3339 Name.encoding_id != TT_MS_ID_SYMBOL_CS))
3340 {
3341 continue; /* not Microsoft Unicode name */
3342 }
3343
3344 if (Name.string == NULL || Name.string_len == 0 ||
3345 (Name.string[0] == 0 && Name.string[1] == 0))
3346 {
3347 continue; /* invalid string */
3348 }
3349
3350 if (Name.language_id == LangID)
3351 {
3352 Score = 30;
3353 BestIndex = i;
3354 break; /* best match */
3355 }
3356 else if (PRIMARYLANGID(Name.language_id) == PRIMARYLANGID(LangID))
3357 {
3358 Score = 20;
3359 }
3360 else if (PRIMARYLANGID(Name.language_id) == LANG_ENGLISH)
3361 {
3362 Score = 10;
3363 }
3364 else
3365 {
3366 Score = 0;
3367 }
3368
3369 if (Score > BestScore)
3370 {
3371 BestScore = Score;
3372 BestIndex = i;
3373 }
3374 }
3375
3376 if (BestIndex >= 0)
3377 {
3378 /* store the best name */
3379 Error = (Score == 30) ? 0 : FT_Get_Sfnt_Name(Face, BestIndex, &Name);
3380 if (!Error)
3381 {
3382 /* NOTE: Name.string is not null-terminated */
3383 UNICODE_STRING Tmp;
3384 Tmp.Buffer = (PWCH)Name.string;
3385 Tmp.Length = Tmp.MaximumLength = Name.string_len;
3386
3387 pNameW->Length = 0;
3388 pNameW->MaximumLength = Name.string_len + sizeof(WCHAR);
3390
3391 if (pNameW->Buffer)
3392 {
3393 Status = RtlAppendUnicodeStringToString(pNameW, &Tmp);
3394 if (Status == STATUS_SUCCESS)
3395 {
3396 /* Convert UTF-16 big endian to little endian */
3397 IntSwapEndian(pNameW->Buffer, pNameW->Length);
3398 }
3399 }
3400 else
3401 {
3403 }
3404 }
3405 }
3406
3407 if (!NT_SUCCESS(Status))
3408 {
3409 /* defaulted */
3410 if (NameID == TT_NAME_ID_FONT_SUBFAMILY)
3411 {
3412 RtlInitAnsiString(&AnsiName, Face->style_name);
3413 Status = RtlAnsiStringToUnicodeString(pNameW, &AnsiName, TRUE);
3414 }
3415 else
3416 {
3417 RtlInitAnsiString(&AnsiName, Face->family_name);
3418 Status = RtlAnsiStringToUnicodeString(pNameW, &AnsiName, TRUE);
3419 }
3420 }
3421
3422 if (NT_SUCCESS(Status))
3423 {
3424 /* make cache */
3425 if (NameID == TT_NAME_ID_FONT_FAMILY)
3426 {
3428 if (!Cache->FontFamily.Buffer)
3429 IntDuplicateUnicodeString(pNameW, &Cache->FontFamily);
3430 }
3431 else if (NameID == TT_NAME_ID_FULL_NAME)
3432 {
3434 if (!Cache->FullName.Buffer)
3435 IntDuplicateUnicodeString(pNameW, &Cache->FullName);
3436 }
3437 }
3438
3439 return Status;
3440}
LPWSTR Name
Definition: desk.c:124
#define TT_MS_ID_UNICODE_CS
Definition: font.c:1181
#define TT_MS_ID_SYMBOL_CS
Definition: font.c:1180
FT_Get_Sfnt_Name_Count(FT_Face face)
Definition: ftsnames.c:148
FT_BEGIN_HEADER struct FT_SfntName_ FT_SfntName
FT_Get_Sfnt_Name(FT_Face face, FT_UInt idx, FT_SfntName *aname)
Definition: ftsnames.c:157
#define TT_NAME_ID_FULL_NAME
Definition: font.c:3539
#define TT_NAME_ID_FONT_FAMILY
Definition: font.c:3536
#define TT_NAME_ID_FONT_SUBFAMILY
Definition: font.c:3537
WCHAR * PWCH
Definition: ntbasedef.h:422
#define LANG_ENGLISH
Definition: nls.h:52
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define STATUS_NOT_FOUND
Definition: shellext.h:72
SHARED_FACE_CACHE UserLanguage
Definition: engobjects.h:136
SHARED_FACE_CACHE EnglishUS
Definition: engobjects.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR _In_opt_ USHORT LangID
Definition: wdfusb.h:1083
VOID IntSwapEndian(_Inout_ LPVOID pvData, _In_ DWORD Size)
Definition: utils.c:125

Referenced by IntInitFontNames(), IntPopulateTextObj(), and MatchFontName().

◆ IntGetFontRenderMode()

FT_Render_Mode FASTCALL IntGetFontRenderMode ( LOGFONTW logfont)

Definition at line 2712 of file freetype.c.

2713{
2714 switch (logfont->lfQuality)
2715 {
2717 break;
2719 return FT_RENDER_MODE_MONO;
2720 case DRAFT_QUALITY:
2721 return FT_RENDER_MODE_LIGHT;
2722 case CLEARTYPE_QUALITY:
2723 if (!gspv.bFontSmoothing)
2724 break;
2726 break;
2727 return FT_RENDER_MODE_LCD;
2728 }
2729 return FT_RENDER_MODE_NORMAL;
2730}
@ FT_RENDER_MODE_NORMAL
Definition: freetype.h:3249
@ FT_RENDER_MODE_LIGHT
Definition: freetype.h:3250
@ FT_RENDER_MODE_LCD
Definition: freetype.h:3252
BOOL bFontSmoothing
Definition: sysparams.h:125
UINT uiFontSmoothingType
Definition: sysparams.h:126
SPIVALUES gspv
Definition: sysparams.c:17
#define ANTIALIASED_QUALITY
Definition: wingdi.h:440
#define DRAFT_QUALITY
Definition: wingdi.h:437
#define CLEARTYPE_QUALITY
Definition: wingdi.h:441
#define NONANTIALIASED_QUALITY
Definition: wingdi.h:439

Referenced by IntExtTextOutW(), and TextIntGetTextExtentPoint().

◆ IntGetFullFileName()

static BOOL FASTCALL IntGetFullFileName ( POBJECT_NAME_INFORMATION  NameInfo,
ULONG  Size,
PUNICODE_STRING  FileName 
)
static

Definition at line 6100 of file freetype.c.

6104{
6107 HANDLE hFile;
6109 ULONG Desired;
6110
6112 FileName,
6114 NULL,
6115 NULL);
6116
6118 &hFile,
6119 0, // FILE_READ_ATTRIBUTES,
6123 0);
6124
6125 if (!NT_SUCCESS(Status))
6126 {
6127 DPRINT("ZwOpenFile() failed (Status = 0x%lx)\n", Status);
6128 return FALSE;
6129 }
6130
6131 Status = ZwQueryObject(hFile, ObjectNameInformation, NameInfo, Size, &Desired);
6132 ZwClose(hFile);
6133 if (!NT_SUCCESS(Status))
6134 {
6135 DPRINT("ZwQueryObject() failed (Status = %lx)\n", Status);
6136 return FALSE;
6137 }
6138
6139 return TRUE;
6140}
@ ObjectNameInformation
Definition: DriverTester.h:55
_In_ HANDLE hFile
Definition: mswsock.h:90
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75

Referenced by IntGdiGetFontResourceInfo().

◆ IntGetHash()

static DWORD IntGetHash ( IN LPCVOID  pv,
IN DWORD  cdw 
)
static

Definition at line 3765 of file freetype.c.

3766{
3767 DWORD dwHash = cdw;
3768 const DWORD *pdw = pv;
3769
3770 while (cdw-- > 0)
3771 {
3772 dwHash *= 3;
3773 dwHash ^= *pdw++;
3774 }
3775
3776 return dwHash;
3777}

Referenced by IntGetRealGlyph().

◆ IntGetOutlineTextMetrics()

INT FASTCALL IntGetOutlineTextMetrics ( PFONTGDI  FontGDI,
UINT  Size,
OUTLINETEXTMETRICW Otm,
BOOL  bLocked 
)

Definition at line 3139 of file freetype.c.

3143{
3144 TT_OS2 *pOS2;
3145 TT_HoriHeader *pHori;
3146 TT_Postscript *pPost;
3147 FT_Fixed XScale, YScale;
3148 FT_WinFNT_HeaderRec WinFNT;
3150 BYTE *pb;
3151 FONT_NAMES FontNames;
3152 PSHARED_FACE SharedFace = FontGDI->SharedFace;
3154 FT_Face Face = SharedFace->Face;
3155
3156 if (bLocked)
3158 else
3160
3162 {
3163 Cache = &SharedFace->EnglishUS;
3164 }
3165 else
3166 {
3167 Cache = &SharedFace->UserLanguage;
3168 }
3169
3170 if (Size == 0 && Cache->OutlineRequiredSize > 0)
3171 {
3172 ASSERT(Otm == NULL);
3173 return Cache->OutlineRequiredSize;
3174 }
3175
3176 if (!bLocked)
3178
3179 IntInitFontNames(&FontNames, SharedFace);
3180 Cache->OutlineRequiredSize = FontNames.OtmSize;
3181
3182 if (Size == 0)
3183 {
3184 ASSERT(Otm == NULL);
3185 IntFreeFontNames(&FontNames);
3186 if (!bLocked)
3188 return Cache->OutlineRequiredSize;
3189 }
3190
3191 ASSERT(Otm != NULL);
3192
3193 if (Size < Cache->OutlineRequiredSize)
3194 {
3195 DPRINT1("Size %u < OutlineRequiredSize %u\n", Size,
3196 Cache->OutlineRequiredSize);
3197 IntFreeFontNames(&FontNames);
3198 if (!bLocked)
3200 return 0; /* failure */
3201 }
3202
3203 XScale = Face->size->metrics.x_scale;
3204 YScale = Face->size->metrics.y_scale;
3205
3206 pOS2 = FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
3207 pHori = FT_Get_Sfnt_Table(Face, FT_SFNT_HHEA);
3208 pPost = FT_Get_Sfnt_Table(Face, FT_SFNT_POST); /* We can live with this failing */
3209 Error = FT_Get_WinFNT_Header(Face, &WinFNT);
3210
3211 if (pOS2 == NULL && Error)
3212 {
3213 if (!bLocked)
3215 DPRINT1("Can't find OS/2 table - not TT font?\n");
3216 IntFreeFontNames(&FontNames);
3217 return 0;
3218 }
3219
3220 if (pHori == NULL && Error)
3221 {
3222 if (!bLocked)
3224 DPRINT1("Can't find HHEA table - not TT font?\n");
3225 IntFreeFontNames(&FontNames);
3226 return 0;
3227 }
3228
3229 Otm->otmSize = Cache->OutlineRequiredSize;
3230
3231 FillTM(&Otm->otmTextMetrics, FontGDI, pOS2, pHori, (Error ? NULL : &WinFNT));
3232
3233 if (!pOS2)
3234 goto skip_os2;
3235
3236 Otm->otmFiller = 0;
3238 Otm->otmfsSelection = pOS2->fsSelection;
3239 Otm->otmfsType = pOS2->fsType;
3240 Otm->otmsCharSlopeRise = pHori->caret_Slope_Rise;
3241 Otm->otmsCharSlopeRun = pHori->caret_Slope_Run;
3242 Otm->otmItalicAngle = 0; /* POST table */
3243 Otm->otmEMSquare = Face->units_per_EM;
3244
3245#define SCALE_X(value) ((FT_MulFix((value), XScale) + 32) >> 6)
3246#define SCALE_Y(value) ((FT_MulFix((value), YScale) + 32) >> 6)
3247
3248 Otm->otmAscent = SCALE_Y(pOS2->sTypoAscender);
3249 Otm->otmDescent = SCALE_Y(pOS2->sTypoDescender);
3250 Otm->otmLineGap = SCALE_Y(pOS2->sTypoLineGap);
3251 Otm->otmsCapEmHeight = SCALE_Y(pOS2->sCapHeight);
3252 Otm->otmsXHeight = SCALE_Y(pOS2->sxHeight);
3253 Otm->otmrcFontBox.left = SCALE_X(Face->bbox.xMin);
3254 Otm->otmrcFontBox.right = SCALE_X(Face->bbox.xMax);
3255 Otm->otmrcFontBox.top = SCALE_Y(Face->bbox.yMax);
3256 Otm->otmrcFontBox.bottom = SCALE_Y(Face->bbox.yMin);
3259 Otm->otmMacLineGap = Otm->otmLineGap;
3260 Otm->otmusMinimumPPEM = 0; /* TT Header */
3271
3272 if (!pPost)
3273 {
3274 Otm->otmsUnderscoreSize = 0;
3275 Otm->otmsUnderscorePosition = 0;
3276 }
3277 else
3278 {
3281 }
3282
3283#undef SCALE_X
3284#undef SCALE_Y
3285
3286skip_os2:
3287 if (!bLocked)
3289
3290 pb = IntStoreFontNames(&FontNames, Otm);
3291 ASSERT(pb - (BYTE*)Otm == Cache->OutlineRequiredSize);
3292
3293 IntFreeFontNames(&FontNames);
3294
3295 return Cache->OutlineRequiredSize;
3296}
BOOLEAN bLocked
Definition: Mke2fs.c:19
#define SCALE_Y(value)
static __inline void FASTCALL IntInitFontNames(FONT_NAMES *Names, PSHARED_FACE SharedFace)
Definition: freetype.c:3066
PBYTE FASTCALL IntStoreFontNames(_In_ const FONT_NAMES *Names, _Out_ OUTLINETEXTMETRICW *Otm)
Definition: freetype.c:3102
#define SCALE_X(value)
static __inline void FASTCALL IntFreeFontNames(FONT_NAMES *Names)
Definition: freetype.c:3126
ULONG OtmSize
Definition: freetype.c:3062
FT_Pos xMin
Definition: ftimage.h:120
FT_Pos yMax
Definition: ftimage.h:121
FT_Pos yMin
Definition: ftimage.h:120
FT_Pos xMax
Definition: ftimage.h:121
FT_BBox bbox
Definition: freetype.h:1052
FT_UShort units_per_EM
Definition: freetype.h:1054
FT_Short caret_Slope_Run
Definition: tttables.h:213
FT_Short caret_Slope_Rise
Definition: tttables.h:212
FT_Short sTypoDescender
Definition: tttables.h:407
FT_Short ySuperscriptYSize
Definition: tttables.h:387
FT_Short sxHeight
Definition: tttables.h:419
FT_Short yStrikeoutSize
Definition: tttables.h:390
FT_Short ySubscriptXSize
Definition: tttables.h:382
FT_Short sTypoLineGap
Definition: tttables.h:408
FT_Short sTypoAscender
Definition: tttables.h:406
FT_Short ySuperscriptXSize
Definition: tttables.h:386
FT_Short ySubscriptYOffset
Definition: tttables.h:385
FT_Short ySuperscriptYOffset
Definition: tttables.h:389
FT_Short ySubscriptXOffset
Definition: tttables.h:384
FT_Short yStrikeoutPosition
Definition: tttables.h:391
FT_Short sCapHeight
Definition: tttables.h:420
FT_UShort fsType
Definition: tttables.h:381
FT_Short ySuperscriptXOffset
Definition: tttables.h:388
FT_Short ySubscriptYSize
Definition: tttables.h:383
FT_Short underlineThickness
Definition: tttables.h:455
FT_Short underlinePosition
Definition: tttables.h:454
PANOSE otmPanoseNumber
Definition: wingdi.h:2962
POINT otmptSuperscriptOffset
Definition: wingdi.h:2982
POINT otmptSuperscriptSize
Definition: wingdi.h:2981
POINT otmptSubscriptSize
Definition: wingdi.h:2979
int otmsStrikeoutPosition
Definition: wingdi.h:2984
int otmsUnderscorePosition
Definition: wingdi.h:2986
POINT otmptSubscriptOffset
Definition: wingdi.h:2980
UINT otmsStrikeoutSize
Definition: wingdi.h:2983
@ FT_SFNT_HHEA
Definition: tttables.h:625
@ FT_SFNT_POST
Definition: tttables.h:627
#define PANOSE_COUNT
Definition: wingdi.h:453

Referenced by FindBestFontFromList(), FontFamilyFillInfo(), ftGdiGetGlyphOutline(), and NtGdiGetOutlineTextMetricsInternalW().

◆ IntGetRealGlyph()

static FT_BitmapGlyph IntGetRealGlyph ( IN OUT PFONT_CACHE_ENTRY  Cache)
static

Definition at line 4916 of file freetype.c.

4918{
4919 INT error;
4920 FT_GlyphSlot glyph;
4921 FT_BitmapGlyph realglyph;
4922
4924
4925 Cache->dwHash = IntGetHash(&Cache->Hashed, sizeof(Cache->Hashed) / sizeof(DWORD));
4926
4927 realglyph = IntFindGlyphCache(Cache);
4928 if (realglyph)
4929 return realglyph;
4930
4931 error = FT_Load_Glyph(Cache->Hashed.Face, Cache->Hashed.GlyphIndex, FT_LOAD_DEFAULT);
4932 if (error)
4933 {
4934 DPRINT1("WARNING: Failed to load and render glyph! [index: %d]\n", Cache->Hashed.GlyphIndex);
4935 return NULL;
4936 }
4937
4938 glyph = Cache->Hashed.Face->glyph;
4939
4940 if (Cache->Hashed.Aspect.Emu.Bold)
4941 FT_GlyphSlot_Embolden(glyph); /* Emulate Bold */
4942
4943 if (Cache->Hashed.Aspect.Emu.Italic)
4944 FT_GlyphSlot_Oblique(glyph); /* Emulate Italic */
4945
4946 realglyph = IntGetBitmapGlyphWithCache(Cache, glyph);
4947
4948 if (!realglyph)
4949 DPRINT1("Failed to render glyph! [index: %d]\n", Cache->Hashed.GlyphIndex);
4950
4951 return realglyph;
4952}
static DWORD IntGetHash(IN LPCVOID pv, IN DWORD cdw)
Definition: freetype.c:3765
static FT_BitmapGlyph IntFindGlyphCache(IN const FONT_CACHE_ENTRY *pCache)
Definition: freetype.c:3780
static FT_BitmapGlyph IntGetBitmapGlyphWithCache(IN OUT PFONT_CACHE_ENTRY Cache, IN FT_GlyphSlot GlyphSlot)
Definition: freetype.c:3817
FT_BEGIN_HEADER FT_GlyphSlot_Embolden(FT_GlyphSlot slot)
Definition: ftsynth.c:89
FT_GlyphSlot_Oblique(FT_GlyphSlot slot)
Definition: ftsynth.c:47

Referenced by IntExtTextOutW(), IntGetTextDisposition(), and TextIntGetTextExtentPoint().

◆ IntGetTextDisposition()

static BOOL IntGetTextDisposition ( _Out_ LONGLONG pX64,
_Out_ LONGLONG pY64,
_In_reads_(Count) PCWCH  String,
_In_ INT  Count,
_In_opt_ const INT Dx,
_Inout_ PFONT_CACHE_ENTRY  Cache,
_In_ UINT  fuOptions,
_In_ BOOL  bNoTransform,
_Inout_ PFONTLINK_CHAIN  pChain 
)
static

Definition at line 6656 of file freetype.c.

6666{
6667 LONGLONG X64 = 0, Y64 = 0;
6668 INT i, glyph_index;
6669 FT_BitmapGlyph realglyph;
6670 FT_Face face = Cache->Hashed.Face;
6671 BOOL use_kerning = FT_HAS_KERNING(face);
6672 ULONG previous = 0;
6673 FT_Vector delta, vec;
6674 DWORD ch0, ch1;
6675
6677
6678 for (i = 0; i < Count; ++i)
6679 {
6680 ch0 = *String++;
6681 if (IS_HIGH_SURROGATE(ch0))
6682 {
6683 ++i;
6684 if (i >= Count)
6685 return TRUE;
6686
6687 ch1 = *String++;
6688 if (IS_LOW_SURROGATE(ch1))
6689 ch0 = Utf32FromSurrogatePair(ch0, ch1);
6690 }
6691
6692 glyph_index = FontLink_Chain_FindGlyph(pChain, Cache, &face, ch0,
6693 (fuOptions & ETO_GLYPH_INDEX));
6694 Cache->Hashed.GlyphIndex = glyph_index;
6695
6696 realglyph = IntGetRealGlyph(Cache);
6697 if (!realglyph)
6698 return FALSE;
6699
6700 /* Retrieve kerning distance */
6701 if (use_kerning && previous && glyph_index)
6702 {
6703 FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
6704 X64 += delta.x;
6705 Y64 -= delta.y;
6706 }
6707
6708 if (NULL == Dx)
6709 {
6710 X64 += realglyph->root.advance.x >> 10;
6711 Y64 -= realglyph->root.advance.y >> 10;
6712 }
6713 else if (fuOptions & ETO_PDY)
6714 {
6715 vec.x = (Dx[2 * i + 0] << 6);
6716 vec.y = (Dx[2 * i + 1] << 6);
6717 if (!bNoTransform)
6718 FT_Vector_Transform(&vec, &Cache->Hashed.matTransform);
6719 X64 += vec.x;
6720 Y64 -= vec.y;
6721 }
6722 else
6723 {
6724 vec.x = (Dx[i] << 6);
6725 vec.y = 0;
6726 if (!bNoTransform)
6727 FT_Vector_Transform(&vec, &Cache->Hashed.matTransform);
6728 X64 += vec.x;
6729 Y64 -= vec.y;
6730 }
6731
6732 previous = glyph_index;
6733 }
6734
6735 *pX64 = X64;
6736 *pY64 = Y64;
6737 return TRUE;
6738}

Referenced by IntExtTextOutW().

◆ IntInitFontNames()

static __inline void FASTCALL IntInitFontNames ( FONT_NAMES Names,
PSHARED_FACE  SharedFace 
)
static

Definition at line 3066 of file freetype.c.

3067{
3068 ULONG OtmSize;
3069
3070 RtlInitUnicodeString(&Names->FamilyNameW, NULL);
3071 RtlInitUnicodeString(&Names->FaceNameW, NULL);
3072 RtlInitUnicodeString(&Names->StyleNameW, NULL);
3073 RtlInitUnicodeString(&Names->FullNameW, NULL);
3074
3075 /* family name */
3077 /* face name */
3079 /* style name */
3081 /* unique name (full name) */
3083
3084 /* Calculate the size of OUTLINETEXTMETRICW with extra data */
3085 OtmSize = sizeof(OUTLINETEXTMETRICW) +
3086 Names->FamilyNameW.Length + sizeof(UNICODE_NULL) +
3087 Names->FaceNameW.Length + sizeof(UNICODE_NULL) +
3088 Names->StyleNameW.Length + sizeof(UNICODE_NULL) +
3089 Names->FullNameW.Length + sizeof(UNICODE_NULL);
3090 Names->OtmSize = OtmSize;
3091}
static NTSTATUS IntGetFontLocalizedName(PUNICODE_STRING pNameW, PSHARED_FACE SharedFace, FT_UShort NameID, FT_UShort LangID)
Definition: freetype.c:3299
#define TT_NAME_ID_UNIQUE_ID
Definition: font.c:3538
struct _OUTLINETEXTMETRICW OUTLINETEXTMETRICW

Referenced by IntGetOutlineTextMetrics().

◆ IntIsFontRenderingEnabled()

BOOL FASTCALL IntIsFontRenderingEnabled ( VOID  )

Definition at line 2700 of file freetype.c.

2701{
2702 return (gpsi->BitsPixel > 8) && g_RenderingEnabled;
2703}
PSERVERINFO gpsi
Definition: imm.c:18

Referenced by IntExtTextOutW(), and TextIntGetTextExtentPoint().

◆ IntLoadFontsInRegistry()

BOOL FASTCALL IntLoadFontsInRegistry ( VOID  )

Definition at line 2376 of file freetype.c.

2377{
2381 KEY_FULL_INFORMATION KeyFullInfo;
2382 ULONG i, Length;
2383 UNICODE_STRING FontTitleW, FileNameW;
2384 SIZE_T InfoSize;
2385 LPBYTE InfoBuffer;
2387 LPWSTR pchPath;
2389 INT nFontCount = 0;
2390 DWORD dwFlags;
2391
2392 /* open registry key */
2395 NULL, NULL);
2396 Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
2397 if (!NT_SUCCESS(Status))
2398 {
2399 DPRINT1("ZwOpenKey failed: 0x%08X\n", Status);
2400 return FALSE; /* failure */
2401 }
2402
2403 /* query count of values */
2404 Status = ZwQueryKey(KeyHandle, KeyFullInformation,
2405 &KeyFullInfo, sizeof(KeyFullInfo), &Length);
2406 if (!NT_SUCCESS(Status))
2407 {
2408 DPRINT1("ZwQueryKey failed: 0x%08X\n", Status);
2410 return FALSE; /* failure */
2411 }
2412
2413 /* allocate buffer */
2414 InfoSize = (MAX_PATH + 256) * sizeof(WCHAR);
2415 InfoBuffer = ExAllocatePoolWithTag(PagedPool, InfoSize, TAG_FONT);
2416 if (!InfoBuffer)
2417 {
2418 DPRINT1("ExAllocatePoolWithTag failed\n");
2420 return FALSE;
2421 }
2422
2423 /* for each value */
2424 for (i = 0; i < KeyFullInfo.Values; ++i)
2425 {
2426 /* get value name */
2427 Status = ZwEnumerateValueKey(KeyHandle, i, KeyValueFullInformation,
2428 InfoBuffer, InfoSize, &Length);
2430 {
2431 /* too short buffer */
2432 ExFreePoolWithTag(InfoBuffer, TAG_FONT);
2433 InfoSize *= 2;
2434 InfoBuffer = ExAllocatePoolWithTag(PagedPool, InfoSize, TAG_FONT);
2435 if (!InfoBuffer)
2436 {
2437 DPRINT1("ExAllocatePoolWithTag failed\n");
2438 break;
2439 }
2440 /* try again */
2441 Status = ZwEnumerateValueKey(KeyHandle, i, KeyValueFullInformation,
2442 InfoBuffer, InfoSize, &Length);
2443 }
2444 if (!NT_SUCCESS(Status))
2445 {
2446 DPRINT1("ZwEnumerateValueKey failed: 0x%08X\n", Status);
2447 break; /* failure */
2448 }
2449
2450 /* create FontTitleW string */
2451 pInfo = (PKEY_VALUE_FULL_INFORMATION)InfoBuffer;
2452 Length = pInfo->NameLength / sizeof(WCHAR);
2453 pInfo->Name[Length] = UNICODE_NULL; /* truncate */
2454 if (!RtlCreateUnicodeString(&FontTitleW, pInfo->Name))
2455 {
2457 DPRINT1("RtlCreateUnicodeString failed\n");
2458 break; /* failure */
2459 }
2460
2461 /* query value */
2462 Status = ZwQueryValueKey(KeyHandle, &FontTitleW, KeyValueFullInformation,
2463 InfoBuffer, InfoSize, &Length);
2465 {
2466 /* too short buffer */
2467 ExFreePoolWithTag(InfoBuffer, TAG_FONT);
2468 InfoSize *= 2;
2469 InfoBuffer = ExAllocatePoolWithTag(PagedPool, InfoSize, TAG_FONT);
2470 if (!InfoBuffer)
2471 {
2472 DPRINT1("ExAllocatePoolWithTag failed\n");
2473 break;
2474 }
2475 /* try again */
2476 Status = ZwQueryValueKey(KeyHandle, &FontTitleW, KeyValueFullInformation,
2477 InfoBuffer, InfoSize, &Length);
2478 }
2479 pInfo = (PKEY_VALUE_FULL_INFORMATION)InfoBuffer;
2480 if (!NT_SUCCESS(Status) || !pInfo->DataLength)
2481 {
2482 DPRINT1("ZwQueryValueKey failed: 0x%08X\n", Status);
2483 RtlFreeUnicodeString(&FontTitleW);
2484 break; /* failure */
2485 }
2486
2487 /* Build pchPath */
2488 pchPath = (LPWSTR)((PUCHAR)pInfo + pInfo->DataOffset);
2489 Length = pInfo->DataLength / sizeof(WCHAR);
2490 pchPath[Length] = UNICODE_NULL; /* truncate */
2491
2492 /* Load font(s) without writing registry */
2493 if (PathIsRelativeW(pchPath))
2494 {
2495 dwFlags = 0;
2497 L"\\SystemRoot\\Fonts\\%s", pchPath);
2498 }
2499 else
2500 {
2502 Status = RtlStringCbCopyW(szPath, sizeof(szPath), pchPath);
2503 }
2504
2505 if (NT_SUCCESS(Status))
2506 {
2507 RtlCreateUnicodeString(&FileNameW, szPath);
2508 nFontCount += IntGdiAddFontResourceEx(&FileNameW, 1, 0, dwFlags);
2509 RtlFreeUnicodeString(&FileNameW);
2510 }
2511
2512 RtlFreeUnicodeString(&FontTitleW);
2513 }
2514
2515 /* close now */
2517
2518 /* free memory block */
2519 if (InfoBuffer)
2520 {
2521 ExFreePoolWithTag(InfoBuffer, TAG_FONT);
2522 }
2523
2524 return (KeyFullInfo.Values != 0 && nFontCount != 0);
2525}
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
BOOL WINAPI PathIsRelativeW(const WCHAR *path)
Definition: path.c:1030
INT FASTCALL IntGdiAddFontResourceEx(_In_ PCUNICODE_STRING FileName, _In_ DWORD cFiles, _In_ DWORD Characteristics, _In_ DWORD dwFlags)
Definition: freetype.c:2193
LPCWSTR szPath
Definition: env.c:37
@ KeyFullInformation
Definition: nt_native.h:1136
@ KeyValueFullInformation
Definition: nt_native.h:1184
#define KEY_READ
Definition: nt_native.h:1026
struct _KEY_VALUE_FULL_INFORMATION * PKEY_VALUE_FULL_INFORMATION
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by InitFontSupport().

◆ IntLoadFontSubstList()

BOOL FASTCALL IntLoadFontSubstList ( PLIST_ENTRY  pHead)

Definition at line 803 of file freetype.c.

804{
808 KEY_FULL_INFORMATION KeyFullInfo;
809 ULONG i, Length;
810 UNICODE_STRING FromW, ToW;
811 BYTE InfoBuffer[128];
813 BYTE CharSets[FONTSUBST_FROM_AND_TO];
814 LPWSTR pch;
816
817 /* the FontSubstitutes registry key */
818 static UNICODE_STRING FontSubstKey =
819 RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\"
820 L"Microsoft\\Windows NT\\CurrentVersion\\"
821 L"FontSubstitutes");
822
823 /* open registry key */
826 NULL, NULL);
827 Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
828 if (!NT_SUCCESS(Status))
829 {
830 DPRINT("ZwOpenKey failed: 0x%08X\n", Status);
831 return FALSE; /* failure */
832 }
833
834 /* query count of values */
835 Status = ZwQueryKey(KeyHandle, KeyFullInformation,
836 &KeyFullInfo, sizeof(KeyFullInfo), &Length);
837 if (!NT_SUCCESS(Status))
838 {
839 DPRINT("ZwQueryKey failed: 0x%08X\n", Status);
841 return FALSE; /* failure */
842 }
843
844 /* for each value */
845 for (i = 0; i < KeyFullInfo.Values; ++i)
846 {
847 /* get value name */
848 Status = ZwEnumerateValueKey(KeyHandle, i, KeyValueFullInformation,
849 InfoBuffer, sizeof(InfoBuffer), &Length);
850 if (!NT_SUCCESS(Status))
851 {
852 DPRINT("ZwEnumerateValueKey failed: 0x%08X\n", Status);
853 break; /* failure */
854 }
855
856 /* create FromW string */
857 pInfo = (PKEY_VALUE_FULL_INFORMATION)InfoBuffer;
858 Length = pInfo->NameLength / sizeof(WCHAR);
859 pInfo->Name[Length] = UNICODE_NULL; /* truncate */
860 if (!RtlCreateUnicodeString(&FromW, pInfo->Name))
861 {
863 DPRINT("RtlCreateUnicodeString failed\n");
864 break; /* failure */
865 }
866
867 /* query value */
868 Status = ZwQueryValueKey(KeyHandle, &FromW, KeyValueFullInformation,
869 InfoBuffer, sizeof(InfoBuffer), &Length);
870 pInfo = (PKEY_VALUE_FULL_INFORMATION)InfoBuffer;
871 if (!NT_SUCCESS(Status) || !pInfo->DataLength)
872 {
873 DPRINT("ZwQueryValueKey failed: 0x%08X\n", Status);
874 RtlFreeUnicodeString(&FromW);
875 break; /* failure */
876 }
877
878 /* create ToW string */
879 pch = (LPWSTR)((PUCHAR)pInfo + pInfo->DataOffset);
880 Length = pInfo->DataLength / sizeof(WCHAR);
881 pch[Length] = UNICODE_NULL; /* truncate */
882 if (!RtlCreateUnicodeString(&ToW, pch))
883 {
885 DPRINT("RtlCreateUnicodeString failed\n");
886 RtlFreeUnicodeString(&FromW);
887 break; /* failure */
888 }
889
890 /* does charset exist? (from) */
892 pch = wcsrchr(FromW.Buffer, L',');
893 if (pch)
894 {
895 /* truncate */
896 *pch = UNICODE_NULL;
897 FromW.Length = (pch - FromW.Buffer) * sizeof(WCHAR);
898 /* parse charset number */
899 CharSets[FONTSUBST_FROM] = (BYTE)_wtoi(pch + 1);
900 }
901
902 /* does charset exist? (to) */
903 CharSets[FONTSUBST_TO] = DEFAULT_CHARSET;
904 pch = wcsrchr(ToW.Buffer, L',');
905 if (pch)
906 {
907 /* truncate */
908 *pch = UNICODE_NULL;
909 ToW.Length = (pch - ToW.Buffer) * sizeof(WCHAR);
910 /* parse charset number */
911 CharSets[FONTSUBST_TO] = (BYTE)_wtoi(pch + 1);
912 }
913
914 /* is it identical? */
915 if (RtlEqualUnicodeString(&FromW, &ToW, TRUE) &&
916 CharSets[FONTSUBST_FROM] == CharSets[FONTSUBST_TO])
917 {
918 RtlFreeUnicodeString(&FromW);
920 continue;
921 }
922
923 /* allocate an entry */
925 if (pEntry == NULL)
926 {
927 DPRINT("ExAllocatePoolWithTag failed\n");
928 RtlFreeUnicodeString(&FromW);
930 break; /* failure */
931 }
932
933 /* store to *pEntry */
934 pEntry->FontNames[FONTSUBST_FROM] = FromW;
935 pEntry->FontNames[FONTSUBST_TO] = ToW;
936 pEntry->CharSets[FONTSUBST_FROM] = CharSets[FONTSUBST_FROM];
937 pEntry->CharSets[FONTSUBST_TO] = CharSets[FONTSUBST_TO];
938
939 /* insert pEntry to *pHead */
940 InsertTailList(pHead, &pEntry->ListEntry);
941 }
942
943 /* close now */
945
946 return NT_SUCCESS(Status);
947}
_ACRTIMP int __cdecl _wtoi(const wchar_t *)
Definition: wcs.c:2773
#define FONTSUBST_FROM_AND_TO
Definition: font.h:71

Referenced by InitFontSupport().

◆ IntLoadSystemFonts()

VOID FASTCALL IntLoadSystemFonts ( VOID  )

Definition at line 1495 of file freetype.c.

1496{
1498 UNICODE_STRING Directory, FileName, TempString;
1500 HANDLE hDirectory;
1501 BYTE *DirInfoBuffer;
1503 BOOLEAN bRestartScan = TRUE;
1505 INT i;
1506 static UNICODE_STRING SearchPatterns[] =
1507 {
1508 RTL_CONSTANT_STRING(L"*.ttf"),
1509 RTL_CONSTANT_STRING(L"*.ttc"),
1510 RTL_CONSTANT_STRING(L"*.otf"),
1511 RTL_CONSTANT_STRING(L"*.otc"),
1512 RTL_CONSTANT_STRING(L"*.fon"),
1513 RTL_CONSTANT_STRING(L"*.fnt")
1514 };
1515 static UNICODE_STRING IgnoreFiles[] =
1516 {
1519 };
1520
1521 RtlInitUnicodeString(&Directory, L"\\SystemRoot\\Fonts\\");
1522
1525 &Directory,
1527 NULL,
1528 NULL);
1529
1531 &hDirectory,
1534 &Iosb,
1537
1538 if (NT_SUCCESS(Status))
1539 {
1540 for (i = 0; i < _countof(SearchPatterns); ++i)
1541 {
1542 DirInfoBuffer = ExAllocatePoolWithTag(PagedPool, 0x4000, TAG_FONT);
1543 if (DirInfoBuffer == NULL)
1544 {
1545 ZwClose(hDirectory);
1546 return;
1547 }
1548
1550 if (FileName.Buffer == NULL)
1551 {
1552 ExFreePoolWithTag(DirInfoBuffer, TAG_FONT);
1553 ZwClose(hDirectory);
1554 return;
1555 }
1556 FileName.Length = 0;
1557 FileName.MaximumLength = MAX_PATH * sizeof(WCHAR);
1558
1559 while (1)
1560 {
1561 Status = ZwQueryDirectoryFile(
1562 hDirectory,
1563 NULL,
1564 NULL,
1565 NULL,
1566 &Iosb,
1567 DirInfoBuffer,
1568 0x4000,
1570 FALSE,
1571 &SearchPatterns[i],
1572 bRestartScan);
1573
1575 {
1576 break;
1577 }
1578
1579 DirInfo = (PFILE_DIRECTORY_INFORMATION)DirInfoBuffer;
1580 while (1)
1581 {
1582 SIZE_T ign;
1583
1584 TempString.Buffer = DirInfo->FileName;
1585 TempString.Length = TempString.MaximumLength = DirInfo->FileNameLength;
1586
1587 /* Should we ignore this file? */
1588 for (ign = 0; ign < _countof(IgnoreFiles); ++ign)
1589 {
1590 /* Yes.. */
1591 if (RtlEqualUnicodeString(IgnoreFiles + ign, &TempString, FALSE))
1592 break;
1593 }
1594
1595 /* If we tried all Ignore patterns and there was no match, try to create a font */
1596 if (ign == _countof(IgnoreFiles))
1597 {
1601 DPRINT1("ERR: Failed to load %wZ\n", &FileName);
1602 }
1603
1604 if (DirInfo->NextEntryOffset == 0)
1605 break;
1606
1607 DirInfo = (PFILE_DIRECTORY_INFORMATION)((ULONG_PTR)DirInfo + DirInfo->NextEntryOffset);
1608 }
1609
1610 bRestartScan = FALSE;
1611 }
1612
1614 ExFreePoolWithTag(DirInfoBuffer, TAG_FONT);
1615 }
1616 ZwClose(hDirectory);
1617 }
1618}
@ IgnoreFiles
Definition: ACListISF.cpp:75
unsigned char BOOLEAN
Definition: actypes.h:127
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
struct _FileName FileName
Definition: fatprocs.h:897
@ FileDirectoryInformation
Definition: from_kernel.h:62
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
base for all directory entries
Definition: entries.h:138
WCHAR FileName[ANYSIZE_ARRAY]
Definition: winternl.h:1466
#define STATUS_NO_MORE_FILES
Definition: udferr_usr.h:128
struct _FILE_DIRECTORY_INFORMATION * PFILE_DIRECTORY_INFORMATION

Referenced by InitFontSupport().

◆ IntMatrixFromMx()

static VOID FASTCALL IntMatrixFromMx ( FT_Matrix pmat,
const MATRIX pmx 
)
static

Definition at line 1102 of file freetype.c.

1103{
1104 FLOATOBJ ef;
1105
1106 /* Create a freetype matrix, by converting to 16.16 fixpoint format */
1107 ef = pmx->efM11;
1108 FLOATOBJ_MulLong(&ef, 0x00010000);
1109 pmat->xx = FLOATOBJ_GetLong(&ef);
1110
1111 ef = pmx->efM21;
1112 FLOATOBJ_MulLong(&ef, 0x00010000);
1113 pmat->xy = -FLOATOBJ_GetLong(&ef); /* (*1) See below */
1114
1115 ef = pmx->efM12;
1116 FLOATOBJ_MulLong(&ef, 0x00010000);
1117 pmat->yx = -FLOATOBJ_GetLong(&ef); /* (*1) See below */
1118
1119 ef = pmx->efM22;
1120 FLOATOBJ_MulLong(&ef, 0x00010000);
1121 pmat->yy = FLOATOBJ_GetLong(&ef);
1122
1123 // (*1): Y direction is mirrored as follows:
1124 //
1125 // [ M11 -M12 ] [ X ] [ M11*X + M12*Y ]
1126 // [ ] * [ ] == [ ]
1127 // [ -M21 M22 ] [ -Y ] [ -(M21*X + M22*Y) ].
1128}

Referenced by ftGdiGetGlyphOutline(), and IntExtTextOutW().

◆ IntPopulateFontGdi()

static void IntPopulateFontGdi ( PFONTGDI  FontGdi,
const FONTOBJ pFontObj,
const LOGFONTW pLogFont 
)
static

Definition at line 5938 of file freetype.c.

5939{
5941
5942 IntFontType(FontGdi);
5943 FontGdi->flType = pFontObj->flFontType;
5944 FontGdi->RequestUnderline = pLogFont->lfUnderline ? 0xFF : 0;
5945 FontGdi->RequestStrikeOut = pLogFont->lfStrikeOut ? 0xFF : 0;
5946 FontGdi->RequestItalic = pLogFont->lfItalic ? 0xFF : 0;
5947 if (pLogFont->lfWeight != FW_DONTCARE)
5948 FontGdi->RequestWeight = pLogFont->lfWeight;
5949 else
5950 FontGdi->RequestWeight = FW_NORMAL;
5951}
static VOID FASTCALL IntFontType(PFONTGDI Font)
Definition: freetype.c:5820
FLONG flType
Definition: engobjects.h:142
FLONG flFontType
Definition: winddi.h:765

Referenced by IntRealizeFont().

◆ IntPopulateTextObj()

static void IntPopulateTextObj ( PTEXTOBJ  TextObj,
PFONTGDI  FontGdi,
FONTOBJ pFontObj,
const LOGFONTW pLogFont,
PLOGFONTW  SubstitutedLogFont 
)
static

Definition at line 5901 of file freetype.c.

5907{
5909
5910 TextObj->Font = pFontObj;
5911 TextObj->TextFace[0] = UNICODE_NULL;
5912
5913 PSHARED_FACE SharedFace = FontGdi->SharedFace;
5914 if (MatchFontNames(SharedFace, SubstitutedLogFont->lfFaceName))
5915 {
5916 RtlStringCchCopyW(TextObj->TextFace, _countof(TextObj->TextFace), pLogFont->lfFaceName);
5917 }
5918 else
5919 {
5923 if (NT_SUCCESS(Status))
5924 {
5925 /* truncated copy */
5926 IntUnicodeStringToBuffer(TextObj->TextFace, sizeof(TextObj->TextFace), &Name);
5928 }
5929 }
5930
5931 // Need hdev, when freetype is loaded need to create DEVOBJ for
5932 // Consumer and Producer.
5933 TextObj->Font->iUniq = 1; // Now it can be cached.
5934 TextObj->fl |= TEXTOBJECT_INIT;
5935}
static BOOL MatchFontNames(PSHARED_FACE SharedFace, LPCWSTR lfFaceName)
Definition: freetype.c:5875
ULONG iUniq
Definition: winddi.h:762
FLONG fl
Definition: text.h:65
#define TEXTOBJECT_INIT
Definition: text.h:56

Referenced by IntRealizeFont().

◆ IntRealizeFont()

PSHARED_FACE IntRealizeFont ( const LOGFONTW pLogFont,
_Inout_opt_ PTEXTOBJ  TextObj 
)

Definition at line 6003 of file freetype.c.

6004{
6006
6007 LOGFONTW LogFont = *pLogFont;
6008 RtlZeroMemory(&LogFont.lfFaceName, sizeof(LogFont.lfFaceName));
6009 RtlStringCchCopyW(LogFont.lfFaceName, _countof(LogFont.lfFaceName), pLogFont->lfFaceName);
6010 pLogFont = &LogFont;
6011
6012 /* Substitute */
6013 LOGFONTW SubstitutedLogFont = *pLogFont;
6014 SubstituteFontRecurse(&SubstitutedLogFont);
6015 DPRINT("Font '%S,%u' is substituted by '%S,%u'.\n",
6016 pLogFont->lfFaceName, pLogFont->lfCharSet,
6017 SubstitutedLogFont.lfFaceName, SubstitutedLogFont.lfCharSet);
6018
6019 FONTOBJ *pFontObj;
6020 PFONT_LOOKUP_CACHE pLookUp = FontLookUp_LookUp(pLogFont);
6021 if (pLookUp)
6022 {
6023 pFontObj = pLookUp->pFontObj;
6024 }
6025 else
6026 {
6027 ULONG MatchPenalty = 0xFFFFFFFF;
6029
6030 /* Search private fonts */
6031 IntLockProcessPrivateFonts(Win32Process);
6032 FindBestFontFromList(&pFontObj, &MatchPenalty, &SubstitutedLogFont,
6033 &Win32Process->PrivateFontListHead);
6034 IntUnLockProcessPrivateFonts(Win32Process);
6035
6036 /* Search system fonts */
6037 FindBestFontFromList(&pFontObj, &MatchPenalty, &SubstitutedLogFont, &g_FontListHead);
6038 }
6039
6040 if (!pFontObj)
6041 {
6042 DPRINT1("Request font %S not found, no fonts loaded at all\n", pLogFont->lfFaceName);
6043 return NULL;
6044 }
6045
6046 PFONTGDI pFontGDI = ObjToGDI(pFontObj, FONT);
6047
6048 if (TextObj)
6049 IntPopulateTextObj(TextObj, pFontGDI, pFontObj, pLogFont, &SubstitutedLogFont);
6050
6051 IntPopulateFontGdi(pFontGDI, pFontObj, pLogFont);
6052
6053 if (!pLookUp)
6054 FontLookUp_Add(pLogFont, pFontGDI->SharedFace, pFontObj);
6055
6056 return pFontGDI->SharedFace;
6057}
static PFONT_LOOKUP_CACHE FontLookUp_LookUp(const LOGFONTW *pLogFont)
Definition: freetype.c:5954
static void FontLookUp_Add(const LOGFONTW *LogFont, PSHARED_FACE SharedFace, FONTOBJ *pFontObj)
Definition: freetype.c:5974
static void IntPopulateFontGdi(PFONTGDI FontGdi, const FONTOBJ *pFontObj, const LOGFONTW *pLogFont)
Definition: freetype.c:5938
static __inline VOID FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, const LOGFONTW *LogFont, const PLIST_ENTRY Head)
Definition: freetype.c:5751
static void IntPopulateTextObj(PTEXTOBJ TextObj, PFONTGDI FontGdi, FONTOBJ *pFontObj, const LOGFONTW *pLogFont, PLOGFONTW SubstitutedLogFont)
Definition: freetype.c:5901
FONTOBJ * pFontObj
Definition: freetype.c:295

Referenced by FontLink_PrepareFontInfo(), and TextIntRealizeFont().

◆ IntRequestFontSize()

static FT_Error IntRequestFontSize ( PDC  dc,
PFONTGDI  FontGDI,
LONG  lfWidth,
LONG  lfHeight 
)
static

Definition at line 4080 of file freetype.c.

4081{
4084 FT_Face face = FontGDI->SharedFace->Face;
4085 TT_OS2 *pOS2;
4086 TT_HoriHeader *pHori;
4087 FT_WinFNT_HeaderRec WinFNT;
4088 LONG Ascent, Descent, Sum, EmHeight;
4089
4090 lfWidth = abs(lfWidth);
4091 if (lfHeight == 0)
4092 {
4093 if (lfWidth == 0)
4094 {
4095 DPRINT("lfHeight and lfWidth are zero.\n");
4096 lfHeight = -16;
4097 }
4098 else
4099 {
4100 lfHeight = lfWidth;
4101 }
4102 }
4103
4104 if (lfHeight == -1)
4105 lfHeight = -2;
4106
4107 if (FontGDI->Magic == FONTGDI_MAGIC &&
4108 FontGDI->lfHeight == lfHeight &&
4109 FontGDI->lfWidth == lfWidth)
4110 {
4111 return 0; /* Cached */
4112 }
4113
4117
4118 if (!pOS2 || !pHori)
4119 {
4120 error = FT_Get_WinFNT_Header(face, &WinFNT);
4121 if (error)
4122 {
4123 DPRINT1("%s: Failed to request font size.\n", face->family_name);
4124 return error;
4125 }
4126
4127 FontGDI->tmHeight = WinFNT.pixel_height;
4128 FontGDI->tmAscent = WinFNT.ascent;
4129 FontGDI->tmDescent = FontGDI->tmHeight - FontGDI->tmAscent;
4130 FontGDI->tmInternalLeading = WinFNT.internal_leading;
4131 FontGDI->Magic = FONTGDI_MAGIC;
4132 FontGDI->lfHeight = lfHeight;
4133 FontGDI->lfWidth = lfWidth;
4134 return 0;
4135 }
4136
4137 /*
4138 * NOTE: We cast TT_OS2.usWinAscent and TT_OS2.usWinDescent to signed FT_Short.
4139 * Why? See: https://learn.microsoft.com/en-us/typography/opentype/spec/os2#uswindescent
4140 *
4141 * > usWinDescent is "usually" a positive value ...
4142 *
4143 * We can read it as "not always". See CORE-14994.
4144 * See also: https://learn.microsoft.com/en-us/typography/opentype/spec/os2#fsselection
4145 */
4146#define FM_SEL_USE_TYPO_METRICS 0x80
4147 if (lfHeight > 0)
4148 {
4149 /* case (A): lfHeight is positive */
4150 Sum = (FT_Short)pOS2->usWinAscent + (FT_Short)pOS2->usWinDescent;
4151 if (Sum == 0 || (pOS2->fsSelection & FM_SEL_USE_TYPO_METRICS))
4152 {
4153 Ascent = pHori->Ascender;
4154 Descent = -pHori->Descender;
4155 Sum = Ascent + Descent;
4156 }
4157 else
4158 {
4159 Ascent = (FT_Short)pOS2->usWinAscent;
4160 Descent = (FT_Short)pOS2->usWinDescent;
4161 }
4162
4163 FontGDI->tmAscent = FT_MulDiv(lfHeight, Ascent, Sum);
4164 FontGDI->tmDescent = FT_MulDiv(lfHeight, Descent, Sum);
4165 FontGDI->tmHeight = FontGDI->tmAscent + FontGDI->tmDescent;
4166 FontGDI->tmInternalLeading = FontGDI->tmHeight - FT_MulDiv(lfHeight, face->units_per_EM, Sum);
4167 }
4168 else if (lfHeight < 0)
4169 {
4170 /* case (B): lfHeight is negative */
4172 {
4173 FontGDI->tmAscent = FT_MulDiv(-lfHeight, pHori->Ascender, face->units_per_EM);
4174 FontGDI->tmDescent = FT_MulDiv(-lfHeight, -pHori->Descender, face->units_per_EM);
4175 }
4176 else
4177 {
4178 FontGDI->tmAscent = FT_MulDiv(-lfHeight, (FT_Short)pOS2->usWinAscent, face->units_per_EM);
4179 FontGDI->tmDescent = FT_MulDiv(-lfHeight, (FT_Short)pOS2->usWinDescent, face->units_per_EM);
4180 }
4181 FontGDI->tmHeight = FontGDI->tmAscent + FontGDI->tmDescent;
4182 FontGDI->tmInternalLeading = FontGDI->tmHeight + lfHeight;
4183 }
4184#undef FM_SEL_USE_TYPO_METRICS
4185
4186 FontGDI->Magic = FONTGDI_MAGIC;
4187 FontGDI->lfHeight = lfHeight;
4188 FontGDI->lfWidth = lfWidth;
4189
4190 EmHeight = FontGDI->tmHeight - FontGDI->tmInternalLeading;
4191 EmHeight = max(EmHeight, 1);
4192 EmHeight = min(EmHeight, USHORT_MAX);
4193
4194#if 1
4195 /* I think this is wrong implementation but its test result is better. */
4196 if (lfWidth != 0)
4197 req.width = FT_MulDiv(lfWidth, face->units_per_EM, pOS2->xAvgCharWidth) << 6;
4198#else
4199 /* I think this is correct implementation but it is mismatching to the
4200 other metric functions. The test result is bad. */
4201 if (lfWidth != 0)
4202 req.width = (FT_MulDiv(lfWidth, 96 * 5, 72 * 3) << 6); /* ??? FIXME */
4203#endif
4204 else
4205 req.width = 0;
4206
4207 /* HACK: We do not handle small widths well, so just use zero for these. See CORE-19870. */
4208 if (lfWidth < 10)
4209 req.width = 0;
4210
4212 req.height = (EmHeight << 6);
4213 req.horiResolution = 0;
4214 req.vertResolution = 0;
4215 return FT_Request_Size(face, &req);
4216}
#define FONTGDI_MAGIC
Definition: engobjects.h:171
#define FM_SEL_USE_TYPO_METRICS
@ FT_SIZE_REQUEST_TYPE_NOMINAL
Definition: freetype.h:2552
FT_Request_Size(FT_Face face, FT_Size_Request req)
Definition: ftobjs.c:3256
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:415
#define USHORT_MAX
Definition: intsafe.h:147
FT_UInt horiResolution
Definition: freetype.h:2607
FT_Size_Request_Type type
Definition: freetype.h:2604
FT_UInt vertResolution
Definition: freetype.h:2608
LONG tmHeight
Definition: engobjects.h:161
LONG Magic
Definition: engobjects.h:165

Referenced by FindBestFontFromList(), ftGdiGetTextMetricsW(), GreGetCharABCWidthsW(), GreGetCharWidthW(), and TextIntUpdateSize().

◆ IntSelectFaceCharmap()

static BOOL FASTCALL IntSelectFaceCharmap ( FT_Face  face)
static

Definition at line 7452 of file freetype.c.

7453{
7454 if (face->charmap)
7455 return TRUE;
7456
7457 FT_CharMap charmap, found = NULL;
7458 for (UINT i = 0; i < (UINT)face->num_charmaps; i++)
7459 {
7460 charmap = face->charmaps[i];
7461 if (charmap->encoding != 0)
7462 {
7463 found = charmap;
7464 break;
7465 }
7466 }
7467
7468 if (!found && FT_IS_SFNT(face)) // Not found and (TrueType or OpenType)?
7469 {
7470 DPRINT1("WARNING: Could not find desired charmap!\n");
7471 return FALSE;
7472 }
7473
7474 if (found)
7475 {
7477 FT_Set_Charmap(face, found);
7479 }
7480
7481 return TRUE;
7482}
FT_Set_Charmap(FT_Face face, FT_CharMap charmap)
Definition: ftobjs.c:3564

Referenced by GreGetCharABCWidthsW(), and GreGetCharWidthW().

◆ IntStoreFontNames()

PBYTE FASTCALL IntStoreFontNames ( _In_ const FONT_NAMES Names,
_Out_ OUTLINETEXTMETRICW Otm 
)

Definition at line 3102 of file freetype.c.

3103{
3104 PBYTE pb = (PBYTE)Otm + sizeof(OUTLINETEXTMETRICW);
3105
3106 /* family name */
3107 Otm->otmpFamilyName = (LPSTR)(pb - (BYTE*) Otm);
3108 pb += IntStoreName(&Names->FamilyNameW, pb);
3109
3110 /* face name */
3111 Otm->otmpFaceName = (LPSTR)(pb - (BYTE*) Otm);
3112 pb += IntStoreName(&Names->FaceNameW, pb);
3113
3114 /* style name */
3115 Otm->otmpStyleName = (LPSTR)(pb - (BYTE*) Otm);
3116 pb += IntStoreName(&Names->StyleNameW, pb);
3117
3118 /* unique name (full name) */
3119 Otm->otmpFullName = (LPSTR)(pb - (BYTE*) Otm);
3120 pb += IntStoreName(&Names->FullNameW, pb);
3121
3122 return pb;
3123}
static SIZE_T FASTCALL IntStoreName(_In_ const UNICODE_STRING *pName, _Out_ PBYTE pb)
Definition: freetype.c:3094
BYTE * PBYTE
Definition: pedump.c:66
char * LPSTR
Definition: xmlstorage.h:182

Referenced by IntGetOutlineTextMetrics().

◆ IntStoreName()

static SIZE_T FASTCALL IntStoreName ( _In_ const UNICODE_STRING pName,
_Out_ PBYTE  pb 
)
inlinestatic

Definition at line 3094 of file freetype.c.

3095{
3096 RtlCopyMemory(pb, pName->Buffer, pName->Length);
3097 *(WCHAR*)&pb[pName->Length] = UNICODE_NULL;
3098 return pName->Length + sizeof(UNICODE_NULL);
3099}
static LPSTR pName
Definition: security.c:116

Referenced by IntStoreFontNames().

◆ IntTranslateCharsetInfo()

static BOOLEAN IntTranslateCharsetInfo ( PDWORD  Src,
LPCHARSETINFO  Cs,
DWORD  Flags 
)
static

Definition at line 2775 of file freetype.c.

2781{
2782 int Index = 0;
2783
2784 switch (Flags)
2785 {
2786 case TCI_SRCFONTSIG:
2787 while (Index < MAXTCIINDEX && 0 == (*Src >> Index & 0x0001))
2788 {
2789 Index++;
2790 }
2791 break;
2792 case TCI_SRCCODEPAGE:
2793 while (Index < MAXTCIINDEX && *Src != g_FontTci[Index].ciACP)
2794 {
2795 Index++;
2796 }
2797 break;
2798 case TCI_SRCCHARSET:
2799 while (Index < MAXTCIINDEX && *Src != g_FontTci[Index].ciCharset)
2800 {
2801 Index++;
2802 }
2803 break;
2804 case TCI_SRCLOCALE:
2806 return FALSE;
2807 default:
2808 return FALSE;
2809 }
2810
2811 if (Index >= MAXTCIINDEX || DEFAULT_CHARSET == g_FontTci[Index].ciCharset)
2812 {
2813 return FALSE;
2814 }
2815
2816 RtlCopyMemory(Cs, &g_FontTci[Index], sizeof(CHARSETINFO));
2817
2818 return TRUE;
2819}
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
_In_ WDFCOLLECTION _In_ ULONG Index
#define TCI_SRCLOCALE
Definition: wingdi.h:964
#define TCI_SRCCHARSET
Definition: wingdi.h:961
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by FontFamilyFillInfo(), and ftGdiGetTextCharsetInfo().

◆ MatchFontName()

static BOOL MatchFontName ( PSHARED_FACE  SharedFace,
PUNICODE_STRING  Name1,
FT_UShort  NameID,
FT_UShort  LangID 
)
static

Definition at line 5852 of file freetype.c.

5853{
5856
5858 Status = IntGetFontLocalizedName(&Name2, SharedFace, NameID, LangID);
5859
5860 if (NT_SUCCESS(Status))
5861 {
5862 if (RtlCompareUnicodeString(Name1, &Name2, TRUE) == 0)
5863 {
5865 return TRUE;
5866 }
5867
5869 }
5870
5871 return FALSE;
5872}
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
_Must_inspect_result_ _In_ PCUNICODE_STRING Name2
Definition: fsrtlfuncs.h:796

Referenced by MatchFontNames().

◆ MatchFontNames()

static BOOL MatchFontNames ( PSHARED_FACE  SharedFace,
LPCWSTR  lfFaceName 
)
static

Definition at line 5875 of file freetype.c.

5876{
5877 UNICODE_STRING Name1;
5878
5879 if (lfFaceName[0] == UNICODE_NULL)
5880 return FALSE;
5881
5882 RtlInitUnicodeString(&Name1, lfFaceName);
5883
5884 if (MatchFontName(SharedFace, &Name1, TT_NAME_ID_FONT_FAMILY, LANG_ENGLISH) ||
5885 MatchFontName(SharedFace, &Name1, TT_NAME_ID_FULL_NAME, LANG_ENGLISH))
5886 {
5887 return TRUE;
5888 }
5890 {
5891 if (MatchFontName(SharedFace, &Name1, TT_NAME_ID_FONT_FAMILY, gusLanguageID) ||
5892 MatchFontName(SharedFace, &Name1, TT_NAME_ID_FULL_NAME, gusLanguageID))
5893 {
5894 return TRUE;
5895 }
5896 }
5897 return FALSE;
5898}
static BOOL MatchFontName(PSHARED_FACE SharedFace, PUNICODE_STRING Name1, FT_UShort NameID, FT_UShort LangID)
Definition: freetype.c:5852

Referenced by IntPopulateTextObj().

◆ NtGdiExtTextOutW()

BOOL APIENTRY NtGdiExtTextOutW ( _In_ HDC  hDC,
_In_ INT  XStart,
_In_ INT  YStart,
_In_ UINT  fuOptions,
_In_opt_ LPCRECT  UnsafeRect,
_In_reads_opt_(Count) PCWCH  UnsafeString,
_In_range_(0, 0xFFFF) UINT  Count,
_In_reads_opt_(_Inexpressible_(cwc)) const INT UnsafeDx,
_In_ DWORD  dwCodePage 
)

Definition at line 7333 of file freetype.c.

7343{
7344 BOOL Result = FALSE;
7346 RECTL SafeRect;
7347 BYTE LocalBuffer[STACK_TEXT_BUFFER_SIZE];
7348 PVOID Buffer = LocalBuffer;
7349 LPCWSTR SafeString = NULL;
7350 PINT SafeDx = NULL;
7351 ULONG BufSize, StringSize, DxSize = 0;
7352
7353 /* Check if String is valid */
7354 if ((Count > 0xFFFF) || (Count > 0 && UnsafeString == NULL))
7355 {
7357 return FALSE;
7358 }
7359
7360 if (Count > 0)
7361 {
7362 /* Calculate buffer size for string and Dx values */
7363 BufSize = StringSize = Count * sizeof(WCHAR);
7364 if (UnsafeDx)
7365 {
7366 /* If ETO_PDY is specified, we have pairs of INTs */
7367 DxSize = (Count * sizeof(INT)) * ((fuOptions & ETO_PDY) ? 2 : 1);
7368 BufSize += DxSize;
7369 }
7370
7371 /* Check if our local buffer is large enough */
7372 if (BufSize > sizeof(LocalBuffer))
7373 {
7374 /* It's not, allocate a temp buffer */
7376 if (!Buffer)
7377 {
7378 return FALSE;
7379 }
7380 }
7381
7382 /* Probe and copy user mode data to the buffer */
7383 _SEH2_TRY
7384 {
7385 /* Put the Dx before the String to assure alignment of 4 */
7386 SafeString = (LPCWSTR)(((ULONG_PTR)Buffer) + DxSize);
7387
7388 /* Probe and copy the string */
7389 ProbeForRead(UnsafeString, StringSize, 1);
7390 RtlCopyMemory((PVOID)SafeString, UnsafeString, StringSize);
7391
7392 /* If we have Dx values... */
7393 if (UnsafeDx)
7394 {
7395 /* ... probe and copy them */
7396 SafeDx = Buffer;
7397 ProbeForRead(UnsafeDx, DxSize, 1);
7398 RtlCopyMemory(SafeDx, UnsafeDx, DxSize);
7399 }
7400 }
7402 {
7404 }
7405 _SEH2_END
7406 if (!NT_SUCCESS(Status))
7407 {
7408 goto cleanup;
7409 }
7410 }
7411
7412 /* If we have a rect, copy it */
7413 if (UnsafeRect)
7414 {
7415 _SEH2_TRY
7416 {
7417 ProbeForRead(UnsafeRect, sizeof(RECT), 1);
7418 SafeRect = *UnsafeRect;
7419 }
7421 {
7423 }
7424 _SEH2_END
7425 if (!NT_SUCCESS(Status))
7426 {
7427 goto cleanup;
7428 }
7429 }
7430
7431 /* Finally call the internal routine */
7433 XStart,
7434 YStart,
7435 fuOptions,
7436 &SafeRect,
7437 SafeString,
7438 Count,
7439 SafeDx,
7440 dwCodePage);
7441
7442cleanup:
7443 /* If we allocated a buffer, free it */
7444 if (Buffer != LocalBuffer)
7445 {
7447 }
7448
7449 return Result;
7450}
#define BufSize
Definition: FsRtlTunnel.c:28
static void cleanup(void)
Definition: main.c:1335
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
BOOL APIENTRY GreExtTextOutW(_In_ HDC hDC, _In_ INT XStart, _In_ INT YStart, _In_ UINT fuOptions, _In_opt_ PRECTL lprc, _In_reads_opt_(Count) PCWCH String, _In_ INT Count, _In_opt_ const INT *Dx, _In_ DWORD dwCodePage)
Definition: freetype.c:7291
#define STACK_TEXT_BUFFER_SIZE
Definition: freetype.c:7329
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:181

◆ NtGdiGetFontFamilyInfo()

LONG NTAPI NtGdiGetFontFamilyInfo ( _In_ HDC  Dc,
_In_ const LOGFONTW UnsafeLogFont,
_Out_ PFONTFAMILYINFO  UnsafeInfo,
_Inout_ PLONG  UnsafeInfoCount 
)

Definition at line 6555 of file freetype.c.

6560{
6562 LOGFONTW LogFont;
6564 LONG GotCount, AvailCount, SafeInfoCount;
6566
6567 if (UnsafeLogFont == NULL || UnsafeInfo == NULL || UnsafeInfoCount == NULL)
6568 {
6570 return -1;
6571 }
6572
6573 Status = MmCopyFromCaller(&SafeInfoCount, UnsafeInfoCount, sizeof(SafeInfoCount));
6574 if (!NT_SUCCESS(Status))
6575 {
6577 return -1;
6578 }
6579 GotCount = 0;
6580 Status = MmCopyToCaller(UnsafeInfoCount, &GotCount, sizeof(*UnsafeInfoCount));
6581 if (!NT_SUCCESS(Status))
6582 {
6584 return -1;
6585 }
6586 Status = MmCopyFromCaller(&LogFont, UnsafeLogFont, sizeof(LOGFONTW));
6587 if (!NT_SUCCESS(Status))
6588 {
6590 return -1;
6591 }
6592 if (SafeInfoCount <= 0)
6593 {
6595 return -1;
6596 }
6597
6598 /* Allocate space for a safe copy */
6599 Status = RtlULongMult(SafeInfoCount, sizeof(FONTFAMILYINFO), &DataSize);
6601 {
6602 DPRINT1("Overflowed.\n");
6604 return -1;
6605 }
6607 if (Info == NULL)
6608 {
6610 return -1;
6611 }
6612
6613 /* Retrieve the information */
6614 AvailCount = IntGetFontFamilyInfo(Dc, &LogFont, Info, SafeInfoCount);
6615 GotCount = min(AvailCount, SafeInfoCount);
6616 SafeInfoCount = AvailCount;
6617
6618 /* Return data to caller */
6619 if (GotCount > 0)
6620 {
6621 Status = RtlULongMult(GotCount, sizeof(FONTFAMILYINFO), &DataSize);
6623 {
6624 DPRINT1("Overflowed.\n");
6627 return -1;
6628 }
6629 Status = MmCopyToCaller(UnsafeInfo, Info, DataSize);
6630 if (!NT_SUCCESS(Status))
6631 {
6634 return -1;
6635 }
6636 Status = MmCopyToCaller(UnsafeInfoCount, &SafeInfoCount, sizeof(*UnsafeInfoCount));
6637 if (!NT_SUCCESS(Status))
6638 {
6641 return -1;
6642 }
6643 }
6644
6646
6647 return GotCount;
6648}
#define LONG_MAX
Definition: limits.h:30
LONG FASTCALL IntGetFontFamilyInfo(HDC Dc, const LOGFONTW *SafeLogFont, PFONTFAMILYINFO SafeInfo, LONG InfoCount)
Definition: freetype.c:6515
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
#define MmCopyFromCaller
Definition: polytest.cpp:29

Referenced by IntEnumFontFamilies().

◆ NtGdiGetGlyphIndicesW()

__kernel_entry W32KAPI DWORD APIENTRY NtGdiGetGlyphIndicesW ( _In_ HDC  hdc,
_In_reads_opt_(cwc) PCWCH  pwc,
_In_ INT  cwc,
_Out_writes_opt_(cwc) PWORD  pgi,
_In_ DWORD  iMode 
)

Definition at line 7717 of file freetype.c.

7723{
7724 PDC dc;
7725 PDC_ATTR pdcattr;
7726 PTEXTOBJ TextObj;
7727 PFONTGDI FontGDI;
7728 HFONT hFont = NULL;
7730 INT i;
7731 WCHAR DefChar = 0xffff;
7732 PWORD Buffer = NULL;
7733 WORD StackBuffer[40];
7734 size_t pwcSize;
7735 PWSTR Safepwc = NULL;
7736 WCHAR pwcStack[40];
7737 LPCWSTR UnSafepwc = pwc;
7738 LPWORD UnSafepgi = pgi;
7739 FT_Face Face;
7740
7741 if (cwc < 0)
7742 {
7743 DPRINT1("cwc < 0\n");
7744 return GDI_ERROR;
7745 }
7746
7747 if (!UnSafepwc && !UnSafepgi && cwc > 0)
7748 {
7749 DPRINT1("!UnSafepwc && !UnSafepgi && cwc > 0\n");
7750 return GDI_ERROR;
7751 }
7752
7753 if (!UnSafepwc != !UnSafepgi)
7754 {
7755 DPRINT1("UnSafepwc == %p, UnSafepgi = %p\n", UnSafepwc, UnSafepgi);
7756 return GDI_ERROR;
7757 }
7758
7759 /* Get FontGDI */
7760 dc = DC_LockDc(hdc);
7761 if (!dc)
7762 {
7763 DPRINT1("!DC_LockDC\n");
7764 return GDI_ERROR;
7765 }
7766 pdcattr = dc->pdcattr;
7767 hFont = pdcattr->hlfntNew;
7768 TextObj = RealizeFontInit(hFont);
7769 DC_UnlockDc(dc);
7770 if (!TextObj)
7771 {
7772 DPRINT1("!TextObj\n");
7773 return GDI_ERROR;
7774 }
7775 FontGDI = ObjToGDI(TextObj->Font, FONT);
7776 Face = FontGDI->SharedFace->Face;
7777 TEXTOBJ_UnlockText(TextObj);
7778
7779 if (cwc == 0)
7780 {
7781 if (!UnSafepwc && !UnSafepgi)
7782 return Face->num_glyphs;
7783
7785 goto ErrorRet;
7786 }
7787
7788 // Allocate Buffer and Safepwc
7789 pwcSize = cwc * sizeof(WORD);
7790 if (pwcSize <= sizeof(StackBuffer) && pwcSize <= sizeof(pwcStack))
7791 {
7792 // Stack is faster than dynamic allocation
7793 Buffer = StackBuffer;
7794 Safepwc = pwcStack;
7795 }
7796 else // Dynamic allocation
7797 {
7799 Safepwc = ExAllocatePoolWithTag(PagedPool, pwcSize, GDITAG_TEXT);
7800 if (!Buffer || !Safepwc)
7801 {
7803 goto ErrorRet;
7804 }
7805 }
7806
7807 /* Get DefChar */
7808 if (!(iMode & GGI_MARK_NONEXISTING_GLYPHS) && IntGetFontDefaultChar(Face, &DefChar))
7809 {
7811 DefChar = get_glyph_index(Face, DefChar); // Convert to glyph index
7813 }
7814
7815 Status = MmCopyFromCaller(Safepwc, UnSafepwc, pwcSize);
7816 if (!NT_SUCCESS(Status))
7817 {
7818 DPRINT1("Status: %08lX\n", Status);
7819 goto ErrorRet;
7820 }
7821
7822 /* Get glyph indeces */
7823 // NOTE: Windows GetGlyphIndices doesn't support Surrogate Pairs.
7825 for (i = 0; i < cwc; i++)
7826 {
7827 Buffer[i] = get_glyph_index(Face, Safepwc[i]);
7828 if (Buffer[i] == 0)
7829 Buffer[i] = DefChar;
7830 }
7832
7833 Status = MmCopyToCaller(UnSafepgi, Buffer, cwc * sizeof(WORD));
7834
7835ErrorRet:
7836 if (Buffer && Buffer != StackBuffer)
7838 if (Safepwc && Safepwc != pwcStack)
7840
7841 if (NT_SUCCESS(Status))
7842 return cwc;
7843
7844 return GDI_ERROR;
7845}
unsigned short WORD
Definition: ntddk_ex.h:93
static BOOL IntGetFontDefaultChar(_In_ FT_Face Face, _Out_ PWCHAR pDefChar)
Definition: freetype.c:7675
HDC hdc
Definition: main.c:9
static LPCSTR INT LPWORD pgi
Definition: font.c:51
WORD * PWORD
Definition: pedump.c:67
uint16_t * LPWORD
Definition: typedefs.h:56
_In_ ULONG iMode
Definition: winddi.h:3520
#define GGI_MARK_NONEXISTING_GLYPHS
Definition: wingdi.h:1085

Referenced by GetCharacterPlacementW(), and GetGlyphIndicesA().

◆ RemoveCachedEntry()

static void RemoveCachedEntry ( PFONT_CACHE_ENTRY  Entry)
static

◆ RemoveCacheEntries()

static void RemoveCacheEntries ( FT_Face  Face)
static

Definition at line 556 of file freetype.c.

557{
558 PLIST_ENTRY CurrentEntry, NextEntry;
559 PFONT_CACHE_ENTRY FontEntry;
560
562
563 for (CurrentEntry = g_FontCacheListHead.Flink;
564 CurrentEntry != &g_FontCacheListHead;
565 CurrentEntry = NextEntry)
566 {
567 FontEntry = CONTAINING_RECORD(CurrentEntry, FONT_CACHE_ENTRY, ListEntry);
568 NextEntry = CurrentEntry->Flink;
569
570 if (FontEntry->Hashed.Face == Face)
571 {
572 RemoveCachedEntry(FontEntry);
573 }
574 }
575}

Referenced by SharedFace_Release().

◆ RTL_STATIC_LIST_HEAD() [1/5]

static RTL_STATIC_LIST_HEAD ( g_FontCacheListHead  )
static

◆ RTL_STATIC_LIST_HEAD() [2/5]

static RTL_STATIC_LIST_HEAD ( g_FontLinkCache  )
static

◆ RTL_STATIC_LIST_HEAD() [3/5]

static RTL_STATIC_LIST_HEAD ( g_FontListHead  )
static

◆ RTL_STATIC_LIST_HEAD() [4/5]

static RTL_STATIC_LIST_HEAD ( g_FontSubstListHead  )
static

◆ RTL_STATIC_LIST_HEAD() [5/5]

static RTL_STATIC_LIST_HEAD ( s_FontLookupCacheList  )
static

◆ SharedFace_AddRef()

static void SharedFace_AddRef ( PSHARED_FACE  Ptr)
static

Definition at line 536 of file freetype.c.

537{
539
540 ++Ptr->RefCount;
541}
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898

Referenced by FontLookUp_Add(), and IntGdiLoadFontsFromMemory().

◆ SharedFace_Create()

static PSHARED_FACE SharedFace_Create ( FT_Face  Face,
PSHARED_MEM  Memory 
)
static

Definition at line 501 of file freetype.c.

502{
505 if (Ptr)
506 {
507 Ptr->Face = Face;
508 Ptr->RefCount = 1;
509 Ptr->Memory = Memory;
510 SharedFaceCache_Init(&Ptr->EnglishUS);
511 SharedFaceCache_Init(&Ptr->UserLanguage);
512
514 DPRINT("Creating SharedFace for %s\n", Face->family_name ? Face->family_name : "<NULL>");
515 }
516 return Ptr;
517}
static void SharedMem_AddRef(PSHARED_MEM Ptr)
Definition: freetype.c:485
static void SharedFaceCache_Init(PSHARED_FACE_CACHE Cache)
Definition: freetype.c:493
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG _In_ _Out_ WDFMEMORY * Memory
Definition: wdfmemory.h:169

Referenced by IntGdiLoadFontByIndexFromMemory().

◆ SharedFace_Release()

static void SharedFace_Release ( PSHARED_FACE  Ptr,
BOOL  bDoLock 
)
static

Definition at line 605 of file freetype.c.

606{
607 if (bDoLock)
609
610 ASSERT(Ptr->RefCount > 0);
611
612 if (Ptr->RefCount <= 0)
613 return;
614
615 --Ptr->RefCount;
616 if (Ptr->RefCount == 0)
617 {
618 DPRINT("Releasing SharedFace for %s\n", Ptr->Face->family_name ? Ptr->Face->family_name : "<NULL>");
619 RemoveCacheEntries(Ptr->Face);
620 FT_Done_Face(Ptr->Face);
621 SharedMem_Release(Ptr->Memory);
622 SharedFaceCache_Release(&Ptr->EnglishUS);
623 SharedFaceCache_Release(&Ptr->UserLanguage);
625 }
626
627 if (bDoLock)
629}
static void RemoveCacheEntries(FT_Face Face)
Definition: freetype.c:556
static void SharedFaceCache_Release(PSHARED_FACE_CACHE Cache)
Definition: freetype.c:598
FT_Done_Face(FT_Face face)
Definition: ftobjs.c:2783

Referenced by CleanupFontEntryEx(), FontLookUp_Destroy(), and IntGdiLoadFontsFromMemory().

◆ SharedFaceCache_Init()

static void SharedFaceCache_Init ( PSHARED_FACE_CACHE  Cache)
static

Definition at line 493 of file freetype.c.

494{
495 Cache->OutlineRequiredSize = 0;
496 RtlInitUnicodeString(&Cache->FontFamily, NULL);
497 RtlInitUnicodeString(&Cache->FullName, NULL);
498}

Referenced by SharedFace_Create().

◆ SharedFaceCache_Release()

static void SharedFaceCache_Release ( PSHARED_FACE_CACHE  Cache)
static

Definition at line 598 of file freetype.c.

599{
600 RtlFreeUnicodeString(&Cache->FontFamily);
601 RtlFreeUnicodeString(&Cache->FullName);
602}

Referenced by SharedFace_Release().

◆ SharedMem_AddRef()

static void SharedMem_AddRef ( PSHARED_MEM  Ptr)
static

Definition at line 485 of file freetype.c.

486{
488
489 ++Ptr->RefCount;
490}

Referenced by SharedFace_Create().

◆ SharedMem_Create()

static PSHARED_MEM SharedMem_Create ( PBYTE  Buffer,
ULONG  BufferSize,
BOOL  IsMapping 
)
static

Definition at line 520 of file freetype.c.

521{
524 if (Ptr)
525 {
526 Ptr->Buffer = Buffer;
527 Ptr->BufferSize = BufferSize;
528 Ptr->RefCount = 1;
529 Ptr->IsMapping = IsMapping;
530 DPRINT("Creating SharedMem for %p (%i, %p)\n", Buffer, IsMapping, Ptr);
531 }
532 return Ptr;
533}
#define BufferSize
Definition: mmc.h:75

Referenced by IntGdiAddFontMemResource(), and IntGdiAddFontResourceSingle().

◆ SharedMem_Release()

static void SharedMem_Release ( PSHARED_MEM  Ptr)
static

Definition at line 577 of file freetype.c.

578{
580 ASSERT(Ptr->RefCount > 0);
581
582 if (Ptr->RefCount <= 0)
583 return;
584
585 --Ptr->RefCount;
586 if (Ptr->RefCount == 0)
587 {
588 DPRINT("Releasing SharedMem for %p (%i, %p)\n", Ptr->Buffer, Ptr->IsMapping, Ptr);
589 if (Ptr->IsMapping)
591 else
594 }
595}
NTSTATUS NTAPI MmUnmapViewInSystemSpace(IN PVOID MappedBase)
Definition: section.c:2765

Referenced by IntGdiAddFontMemResource(), IntGdiAddFontResourceSingle(), and SharedFace_Release().

◆ SubstituteFontByList()

static BOOL SubstituteFontByList ( PLIST_ENTRY  pHead,
PUNICODE_STRING  pOutputName,
PUNICODE_STRING  pInputName,
BYTE  RequestedCharSet,
BYTE  CharSetMap[FONTSUBST_FROM_AND_TO] 
)
static

Definition at line 1131 of file freetype.c.

1136{
1137 PLIST_ENTRY pListEntry;
1138 PFONTSUBST_ENTRY pSubstEntry;
1139 BYTE CharSets[FONTSUBST_FROM_AND_TO];
1140
1141 CharSetMap[FONTSUBST_FROM] = DEFAULT_CHARSET;
1142 CharSetMap[FONTSUBST_TO] = RequestedCharSet;
1143
1144 /* for each list entry */
1145 for (pListEntry = pHead->Flink;
1146 pListEntry != pHead;
1147 pListEntry = pListEntry->Flink)
1148 {
1149 pSubstEntry = CONTAINING_RECORD(pListEntry, FONTSUBST_ENTRY, ListEntry);
1150
1151 CharSets[FONTSUBST_FROM] = pSubstEntry->CharSets[FONTSUBST_FROM];
1152
1153 if (CharSets[FONTSUBST_FROM] != DEFAULT_CHARSET &&
1154 CharSets[FONTSUBST_FROM] != RequestedCharSet)
1155 {
1156 continue; /* not matched */
1157 }
1158
1159 /* does charset number exist? (to) */
1160 if (pSubstEntry->CharSets[FONTSUBST_TO] != DEFAULT_CHARSET)
1161 {
1162 CharSets[FONTSUBST_TO] = pSubstEntry->CharSets[FONTSUBST_TO];
1163 }
1164 else
1165 {
1166 CharSets[FONTSUBST_TO] = RequestedCharSet;
1167 }
1168
1169 /* does font name match? */
1171 pInputName, TRUE))
1172 {
1173 continue; /* not matched */
1174 }
1175
1176 /* update *pOutputName */
1177 *pOutputName = pSubstEntry->FontNames[FONTSUBST_TO];
1178
1179 if (CharSetMap[FONTSUBST_FROM] == DEFAULT_CHARSET)
1180 {
1181 /* update CharSetMap */
1182 CharSetMap[FONTSUBST_FROM] = CharSets[FONTSUBST_FROM];
1183 CharSetMap[FONTSUBST_TO] = CharSets[FONTSUBST_TO];
1184 }
1185 return TRUE; /* success */
1186 }
1187
1188 return FALSE;
1189}

Referenced by SubstituteFontRecurse().

◆ SubstituteFontRecurse()

static BOOL SubstituteFontRecurse ( PLOGFONTW  pLogFont)
static

Definition at line 1192 of file freetype.c.

1193{
1194 UINT RecurseCount = 5;
1195 UNICODE_STRING OutputNameW = { 0 };
1196 BYTE CharSetMap[FONTSUBST_FROM_AND_TO];
1197 BOOL Found;
1198 UNICODE_STRING InputNameW;
1199
1200 if (pLogFont->lfFaceName[0] == UNICODE_NULL)
1201 return FALSE;
1202
1203 RtlInitUnicodeString(&InputNameW, pLogFont->lfFaceName);
1204
1205 while (RecurseCount-- > 0)
1206 {
1207 Found = SubstituteFontByList(&g_FontSubstListHead,
1208 &OutputNameW, &InputNameW,
1209 pLogFont->lfCharSet, CharSetMap);
1210 if (!Found)
1211 break;
1212
1213 IntUnicodeStringToBuffer(pLogFont->lfFaceName, sizeof(pLogFont->lfFaceName), &OutputNameW);
1214 RtlInitUnicodeString(&InputNameW, pLogFont->lfFaceName);
1215
1216 if (CharSetMap[FONTSUBST_FROM] == DEFAULT_CHARSET ||
1217 CharSetMap[FONTSUBST_FROM] == pLogFont->lfCharSet)
1218 {
1219 pLogFont->lfCharSet = CharSetMap[FONTSUBST_TO];
1220 }
1221 }
1222
1223 return TRUE; /* success */
1224}
static BOOL SubstituteFontByList(PLIST_ENTRY pHead, PUNICODE_STRING pOutputName, PUNICODE_STRING pInputName, BYTE RequestedCharSet, BYTE CharSetMap[FONTSUBST_FROM_AND_TO])
Definition: freetype.c:1131
BYTE lfCharSet
Definition: wingdi.h:2351

Referenced by FontLink_Chain_LoadReg(), FontLink_Create(), GetFontFamilyInfoForSubstitutes(), and IntRealizeFont().

◆ TextIntCreateFontIndirect()

NTSTATUS FASTCALL TextIntCreateFontIndirect ( CONST LPLOGFONTW  lf,
HFONT NewFont 
)

Definition at line 2733 of file freetype.c.

2734{
2735 PLFONT plfont;
2736 LOGFONTW *plf;
2737
2738 ASSERT(lf);
2739 plfont = LFONT_AllocFontWithHandle();
2740 if (!plfont)
2741 {
2742 return STATUS_NO_MEMORY;
2743 }
2744
2745 ExInitializePushLock(&plfont->lock);
2746 *NewFont = plfont->BaseObject.hHmgr;
2747 plf = &plfont->logfont.elfEnumLogfontEx.elfLogFont;
2748 RtlCopyMemory(plf, lf, sizeof(LOGFONTW));
2749 if (lf->lfEscapement != lf->lfOrientation)
2750 {
2751 /* This should really depend on whether GM_ADVANCED is set */
2752 plf->lfOrientation = plf->lfEscapement;
2753 }
2754 LFONT_UnlockFont(plfont);
2755
2756 return STATUS_SUCCESS;
2757}
HGDIOBJ hHmgr(VOID)
Definition: baseobj.hpp:95
#define ExInitializePushLock
Definition: ex.h:1016
BASEOBJECT BaseObject
Definition: text.h:63
EX_PUSH_LOCK lock
Definition: text.h:71
#define LFONT_UnlockFont(plfnt)
Definition: text.h:79
#define LFONT_AllocFontWithHandle()
Definition: text.h:76

Referenced by CreateStockFonts(), and UserDrawCaptionText().

◆ TextIntGetTextExtentPoint()

BOOL FASTCALL TextIntGetTextExtentPoint ( _In_ PDC  dc,
_In_ PTEXTOBJ  TextObj,
_In_reads_(Count) PCWCH  String,
_In_ INT  Count,
_In_ ULONG  MaxExtent,
_Out_ PINT  Fit,
_Out_writes_to_opt_(Count, *Fit) PINT  Dx,
_Out_ PSIZE  Size,
_In_ FLONG  fl 
)

Definition at line 4956 of file freetype.c.

4966{
4967 PFONTGDI FontGDI;
4968 FT_BitmapGlyph realglyph;
4969 INT glyph_index, i, previous, nTenthsOfDegrees;
4970 ULONGLONG TotalWidth64 = 0;
4971 LOGFONTW *plf;
4972 BOOL use_kerning, bVerticalWriting;
4973 LONG ascender, descender;
4975 DWORD ch0, ch1;
4976 FONTLINK_CHAIN Chain;
4977
4978 FontGDI = ObjToGDI(TextObj->Font, FONT);
4979
4980 Cache.Hashed.Face = FontGDI->SharedFace->Face;
4981 if (NULL != Fit)
4982 {
4983 *Fit = 0;
4984 }
4985
4986 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
4987 Cache.Hashed.lfHeight = plf->lfHeight;
4988 Cache.Hashed.lfWidth = plf->lfWidth;
4989 Cache.Hashed.Aspect.Emu.Bold = EMUBOLD_NEEDED(FontGDI->OriginalWeight, plf->lfWeight);
4990 Cache.Hashed.Aspect.Emu.Italic = (plf->lfItalic && !FontGDI->OriginalItalic);
4991
4992 // Check vertical writing (tategaki)
4993 nTenthsOfDegrees = IntNormalizeAngle(plf->lfEscapement - plf->lfOrientation);
4994 bVerticalWriting = ((nTenthsOfDegrees == 90 * 10) || (nTenthsOfDegrees == 270 * 10));
4995
4997 Cache.Hashed.Aspect.RenderMode = (BYTE)IntGetFontRenderMode(plf);
4998 else
4999 Cache.Hashed.Aspect.RenderMode = (BYTE)FT_RENDER_MODE_MONO;
5000
5001 // NOTE: GetTextExtentPoint32 simply ignores lfEscapement and XFORM.
5003 TextIntUpdateSize(dc, TextObj, FontGDI, FALSE);
5004 Cache.Hashed.matTransform = identityMat;
5005 FT_Set_Transform(Cache.Hashed.Face, NULL, NULL);
5006
5007 FontLink_Chain_Init(&Chain, TextObj, Cache.Hashed.Face);
5008
5009 use_kerning = FT_HAS_KERNING(Cache.Hashed.Face);
5010 previous = 0;
5011
5012 for (i = 0; i < Count; i++)
5013 {
5014 ch0 = *String++;
5015 if (IS_HIGH_SURROGATE(ch0))
5016 {
5017 ++i;
5018 if (i >= Count)
5019 break;
5020
5021 ch1 = *String++;
5022 if (IS_LOW_SURROGATE(ch1))
5023 ch0 = Utf32FromSurrogatePair(ch0, ch1);
5024 }
5025
5026 glyph_index = FontLink_Chain_FindGlyph(&Chain, &Cache, &Cache.Hashed.Face, ch0,
5027 (fl & GTEF_INDICES));
5028 Cache.Hashed.GlyphIndex = glyph_index;
5029
5030 realglyph = IntGetRealGlyph(&Cache);
5031 if (!realglyph)
5032 break;
5033
5034 /* Retrieve kerning distance */
5035 if (use_kerning && previous && glyph_index)
5036 {
5037 FT_Vector delta;
5038 FT_Get_Kerning(Cache.Hashed.Face, previous, glyph_index, 0, &delta);
5039 TotalWidth64 += delta.x;
5040 }
5041
5042 TotalWidth64 += realglyph->root.advance.x >> 10;
5043
5044 if (((TotalWidth64 + 32) >> 6) <= MaxExtent && NULL != Fit)
5045 {
5046 *Fit = i + 1;
5047 }
5048 if (NULL != Dx)
5049 {
5050 Dx[i] = (TotalWidth64 + 32) >> 6;
5051 }
5052
5053 previous = glyph_index;
5054 }
5055 ASSERT(FontGDI->Magic == FONTGDI_MAGIC);
5056 ascender = FontGDI->tmAscent; /* Units above baseline */
5057 descender = FontGDI->tmDescent; /* Units below baseline */
5059
5060 if (bVerticalWriting)
5061 {
5062 Size->cx = ascender + descender;
5063 Size->cy = (TotalWidth64 + 32) >> 6;
5064 }
5065 else
5066 {
5067 Size->cx = (TotalWidth64 + 32) >> 6;
5068 Size->cy = ascender + descender;
5069 }
5070
5071 FontLink_Chain_Finish(&Chain);
5072
5073 return TRUE;
5074}
#define GTEF_INDICES
Definition: ntgdityp.h:213
uint64_t ULONGLONG
Definition: typedefs.h:67
LONG IntNormalizeAngle(_In_ LONG nTenthsOfDegrees)
Definition: utils.c:46

Referenced by GreGetTextExtentExW(), GreGetTextExtentW(), IntExtTextOutW(), IntGetCharDimensions(), and NtGdiGetTextExtentExW().

◆ TextIntRealizeFont()

NTSTATUS FASTCALL TextIntRealizeFont ( HFONT  FontHandle,
PTEXTOBJ  pTextObj 
)

Definition at line 6061 of file freetype.c.

6062{
6063 PTEXTOBJ TextObj;
6064 PSHARED_FACE SharedFace;
6065
6066 if (!pTextObj)
6067 {
6068 TextObj = TEXTOBJ_LockText(FontHandle);
6069 if (NULL == TextObj)
6070 {
6071 return STATUS_INVALID_HANDLE;
6072 }
6073
6074 if (TextObj->fl & TEXTOBJECT_INIT)
6075 {
6076 TEXTOBJ_UnlockText(TextObj);
6077 return STATUS_SUCCESS;
6078 }
6079 }
6080 else
6081 {
6082 TextObj = pTextObj;
6083 }
6084
6086 SharedFace = IntRealizeFont(&TextObj->logfont.elfEnumLogfontEx.elfLogFont, TextObj);
6088
6089 if (!pTextObj)
6090 TEXTOBJ_UnlockText(TextObj);
6091
6092 ASSERT((!!SharedFace ^ (NULL == TextObj->Font)) != 0);
6093
6094 return SharedFace ? STATUS_SUCCESS : STATUS_NOT_FOUND;
6095}
FORCEINLINE PTEXTOBJ TEXTOBJ_LockText(HFONT hfont)
Definition: text.h:83

Referenced by DC_hSelectFont(), DC_InitHack(), FontGetObject(), and RealizeFontInit().

◆ TextIntUpdateSize()

BOOL FASTCALL TextIntUpdateSize ( PDC  dc,
PTEXTOBJ  TextObj,
PFONTGDI  FontGDI,
BOOL  bDoLock 
)

Definition at line 4219 of file freetype.c.

4223{
4224 FT_Face face;
4225 INT error, n;
4226 FT_CharMap charmap, found;
4227 LOGFONTW *plf;
4228
4229 if (bDoLock)
4231
4232 face = FontGDI->SharedFace->Face;
4233 if (face->charmap == NULL)
4234 {
4235 DPRINT("WARNING: No charmap selected!\n");
4236 DPRINT("This font face has %d charmaps\n", face->num_charmaps);
4237
4238 found = NULL;
4239 for (n = 0; n < face->num_charmaps; n++)
4240 {
4241 charmap = face->charmaps[n];
4242 if (charmap->encoding == FT_ENCODING_UNICODE)
4243 {
4244 found = charmap;
4245 break;
4246 }
4247 }
4248 if (!found)
4249 {
4250 for (n = 0; n < face->num_charmaps; n++)
4251 {
4252 charmap = face->charmaps[n];
4253 if (charmap->platform_id == TT_PLATFORM_APPLE_UNICODE)
4254 {
4255 found = charmap;
4256 break;
4257 }
4258 }
4259 }
4260 if (!found)
4261 {
4262 for (n = 0; n < face->num_charmaps; n++)
4263 {
4264 charmap = face->charmaps[n];
4265 if (charmap->encoding == FT_ENCODING_MS_SYMBOL)
4266 {
4267 found = charmap;
4268 break;
4269 }
4270 }
4271 }
4272 if (!found && face->num_charmaps > 0)
4273 {
4274 found = face->charmaps[0];
4275 }
4276 if (!found)
4277 {
4278 DPRINT1("WARNING: Could not find desired charmap!\n");
4279 }
4280 else
4281 {
4282 DPRINT("Found charmap encoding: %i\n", found->encoding);
4283 error = FT_Set_Charmap(face, found);
4284 if (error)
4285 {
4286 DPRINT1("WARNING: Could not set the charmap!\n");
4287 }
4288 }
4289 }
4290
4291 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
4292
4293 error = IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight);
4294
4295 if (bDoLock)
4297
4298 if (error)
4299 {
4300 DPRINT1("Error in setting pixel sizes: %d\n", error);
4301 return FALSE;
4302 }
4303
4304 return TRUE;
4305}
#define TT_PLATFORM_APPLE_UNICODE
Definition: font.c:1172
GLdouble n
Definition: glext.h:7729

Referenced by ftGdiGetGlyphOutline(), IntExtTextOutW(), NtGdiGetOutlineTextMetricsInternalW(), and TextIntGetTextExtentPoint().

◆ UnlinkFontMemCollection()

static VOID FASTCALL UnlinkFontMemCollection ( PFONT_ENTRY_COLL_MEM  Collection)
static

Definition at line 2597 of file freetype.c.

2598{
2599 PFONT_ENTRY_MEM FontMemEntry = Collection->Entry;
2600 PLIST_ENTRY ListEntry;
2601 RemoveEntryList(&Collection->ListEntry);
2602
2603 do {
2604 /* Also unlink the FONT_ENTRY stuff from the PrivateFontListHead */
2605 RemoveEntryList(&FontMemEntry->Entry->ListEntry);
2606
2607 ListEntry = FontMemEntry->ListEntry.Flink;
2608 FontMemEntry = CONTAINING_RECORD(ListEntry, FONT_ENTRY_MEM, ListEntry);
2609
2610 } while (FontMemEntry != Collection->Entry);
2611}
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ WDFCOLLECTION Collection
Definition: wdfregistry.h:374

Referenced by IntGdiCleanupPrivateFontsForProcess(), and IntGdiRemoveFontMemResource().

Variable Documentation

◆ DosPathPrefix

const UNICODE_STRING DosPathPrefix = RTL_CONSTANT_STRING(L"\\??\\")
static

Definition at line 1990 of file freetype.c.

Referenced by IntGdiAddFontResourceSingle(), and IntGdiRemoveFontResourceSingle().

◆ g_ElfScripts

PWCHAR g_ElfScripts[32]
static
Initial value:
=
{
L"Western",
L"Central_European",
L"Cyrillic",
L"Greek",
L"Turkish",
L"Hebrew",
L"Arabic",
L"Baltic",
L"Vietnamese",
L"Thai",
L"Japanese",
L"CHINESE_GB2312",
L"Hangul",
L"CHINESE_BIG5",
L"Hangul(Johab)",
L"Symbol"
}

Definition at line 354 of file freetype.c.

Referenced by FontFamilyFillInfo().

◆ g_FontCacheNumEntries

UINT g_FontCacheNumEntries
static

Definition at line 352 of file freetype.c.

Referenced by InitFontSupport(), IntGetBitmapGlyphWithCache(), and RemoveCachedEntry().

◆ g_FontRegPath

UNICODE_STRING g_FontRegPath
Initial value:
=
RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts")

Definition at line 321 of file freetype.c.

Referenced by IntDeleteRegFontEntries(), IntGdiAddFontResourceSingle(), and IntLoadFontsInRegistry().

◆ g_FontTci

◆ g_FreeTypeLibrary

FT_Library g_FreeTypeLibrary

◆ g_FreeTypeLock

PFAST_MUTEX g_FreeTypeLock
static

Definition at line 326 of file freetype.c.

Referenced by FreeFontSupport(), and InitFontSupport().

◆ g_nFontLinkCacheCount

LONG g_nFontLinkCacheCount = 0
static

Definition at line 69 of file freetype.c.

Referenced by FontLink_AddCache(), and FontLink_CleanupCache().

◆ g_RenderingEnabled

BOOL g_RenderingEnabled = TRUE
static

Definition at line 329 of file freetype.c.

Referenced by IntEnableFontRendering(), and IntIsFontRenderingEnabled().

◆ gmxWorldToDeviceDefault

const MATRIX gmxWorldToDeviceDefault
extern

Definition at line 20 of file dclife.c.

◆ gmxWorldToPageDefault

const MATRIX gmxWorldToPageDefault
extern

Definition at line 36 of file dclife.c.

Referenced by DC_vInitDc().

◆ identityMat

const FT_Matrix identityMat = {(1 << 16), 0, 0, (1 << 16)}
static

Definition at line 313 of file freetype.c.

Referenced by ftGdiGetGlyphOutline(), IntExtTextOutW(), and TextIntGetTextExtentPoint().

◆ s_chFontLinkDefaultChar

DWORD s_chFontLinkDefaultChar = FONTLINK_DEFAULT_CHAR
static

Definition at line 60 of file freetype.c.

Referenced by FontLink_Chain_FindGlyph(), and FontLink_LoadSettings().

◆ s_fFontLinkUseAnsi

BOOL s_fFontLinkUseAnsi = FALSE
static

Definition at line 63 of file freetype.c.

Referenced by FontLink_Chain_Populate(), and FontLink_LoadDefaultCharset().

◆ s_fFontLinkUseOem

BOOL s_fFontLinkUseOem = FALSE
static

Definition at line 64 of file freetype.c.

Referenced by FontLink_Chain_Populate(), and FontLink_LoadDefaultCharset().

◆ s_fFontLinkUseSymbol

BOOL s_fFontLinkUseSymbol = FALSE
static

Definition at line 65 of file freetype.c.

Referenced by FontLink_Chain_Populate(), and FontLink_LoadDefaultCharset().

◆ s_FontLookupCacheCount

ULONG s_FontLookupCacheCount = 0
static

Definition at line 300 of file freetype.c.

Referenced by FontLookUp_Add(), and FontLookUp_Cleanup().

◆ s_szDefFontLinkFileName

WCHAR s_szDefFontLinkFileName[MAX_PATH] = L""
static

Definition at line 61 of file freetype.c.

Referenced by FontLink_Chain_Populate(), and FontLink_LoadDefaultFonts().

◆ s_szDefFontLinkFontName

WCHAR s_szDefFontLinkFontName[MAX_PATH] = L""
static

Definition at line 62 of file freetype.c.

Referenced by FontLink_Chain_Populate(), and FontLink_LoadDefaultFonts().

◆ s_szzDefFixedFontLink

const WCHAR s_szzDefFixedFontLink[]
static
Initial value:
=
L"cour.ttf,Courier New\0"
L"msgothic.ttc,MS Gothic\0"
L"mingliu.ttc,MingLiU\0"
L"simsun.ttc,NSimSun\0"
L"gulim.ttc,GulimChe\0"
L"\0"

Definition at line 1248 of file freetype.c.

Referenced by FontLink_Chain_LoadReg().

◆ s_szzDefFontLink

const WCHAR s_szzDefFontLink[]
static
Initial value:
=
L"tahoma.ttf,Tahoma\0"
L"msgothic.ttc,MS UI Gothic\0"
L"mingliu.ttc,PMingLiU\0"
L"simsun.ttc,SimSun\0"
L"gulim.ttc,Gulim\0"
L"\0"

Definition at line 1240 of file freetype.c.

Referenced by FontLink_Chain_LoadReg().