ReactOS 0.4.16-dev-2604-g747b3c0
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_ENTRY
 
struct  _FONTLINK_CHAIN
 
struct  FONT_NAMES
 

Macros

#define NDEBUG
 
#define FONTLINK_DEFAULT_CHAR   0x30FB
 
#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 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_ENTRY FONTLINK_ENTRY
 
typedef struct _FONTLINK_ENTRYPFONTLINK_ENTRY
 
typedef struct _FONTLINK_CHAIN FONTLINK_CHAIN
 
typedef struct _FONTLINK_CHAINPFONTLINK_CHAIN
 
typedef struct FONT_NAMES FONT_NAMES
 
typedef struct FONT_NAMESLPFONT_NAMES
 

Functions

static RTL_STATIC_LIST_HEAD (g_FontLinkEntries)
 
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 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)
 
static BOOL MatchFontName (PSHARED_FACE SharedFace, PUNICODE_STRING Name1, FT_UShort NameID, FT_UShort LangID)
 
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 NTSTATUS FontLink_AddEntry (LPCWSTR lfFaceName, PZZWSTR pszzFontLink)
 
static void FontLink_DeleteEntries (VOID)
 
static NTSTATUS FontLink_PopulateEntries (VOID)
 
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 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 PFONTLINK_ENTRY FontLink_FindEntry (const LOGFONTW *pLogFont)
 
static NTSTATUS FontLink_Chain_FindEntry (_Inout_ PFONTLINK_CHAIN pChain, _Inout_ PLOGFONTW pLF)
 
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)
 
static FT_Error IntRequestFontSizeEx (FT_Face face, const LOGFONTW *plf)
 
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 BOOL IntNeedRequestFontSize (PFONTLINK_CHAIN pChain, FT_Face face, PLIST_ENTRY TargetEntry)
 
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 MatchFontNames (PSHARED_FACE SharedFace, LPCWSTR lfFaceName)
 
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)
 
NTSTATUS FASTCALL TextIntRealizeFont (HFONT FontHandle, PTEXTOBJ pTextObj)
 
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)
 
DWORD APIENTRY GreGetGlyphIndicesW (_In_ HDC hdc, _In_reads_opt_(cwc) PCWCH pwc, _In_ INT cwc, _Out_writes_opt_(cwc) PWORD pgi, _In_ DWORD iMode, _In_ BOOL bSubset)
 

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
 
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 192 of file freetype.c.

◆ ASSERT_FREETYPE_LOCK_HELD

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

Definition at line 219 of file freetype.c.

◆ ASSERT_FREETYPE_LOCK_NOT_HELD

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

Definition at line 222 of file freetype.c.

◆ CP_MACCP

#define CP_MACCP   2

Definition at line 313 of file freetype.c.

◆ CP_OEMCP

#define CP_OEMCP   1

Definition at line 312 of file freetype.c.

◆ CP_SYMBOL

#define CP_SYMBOL   42

Definition at line 268 of file freetype.c.

◆ EMUBOLD_NEEDED

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

Definition at line 196 of file freetype.c.

◆ FM_SEL_USE_TYPO_METRICS [1/2]

#define FM_SEL_USE_TYPO_METRICS   0x80

◆ FM_SEL_USE_TYPO_METRICS [2/2]

#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 204 of file freetype.c.

◆ GOT_PENALTY

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

Definition at line 5415 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:214

Definition at line 225 of file freetype.c.

◆ IntUnLockFreeType

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

Definition at line 231 of file freetype.c.

◆ MAX_FONT_CACHE

#define MAX_FONT_CACHE   256

Definition at line 237 of file freetype.c.

◆ MAXTCIINDEX

#define MAXTCIINDEX   32

Definition at line 269 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 1529 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 7257 of file freetype.c.

◆ VALIGN_MASK

#define VALIGN_MASK   (TA_TOP | TA_BASELINE | TA_BOTTOM)

Typedef Documentation

◆ FONT_NAMES

◆ FONTLINK

◆ FONTLINK_CHAIN

◆ FONTLINK_ENTRY

◆ LPFONT_NAMES

◆ PFONTLINK

◆ PFONTLINK_CHAIN

◆ PFONTLINK_ENTRY

Function Documentation

◆ CleanupFontEntry()

static __inline VOID FASTCALL CleanupFontEntry ( PFONT_ENTRY  FontEntry)
static

Definition at line 573 of file freetype.c.

574{
575 CleanupFontEntryEx(FontEntry, FontEntry->Font);
576}
static VOID FASTCALL CleanupFontEntryEx(PFONT_ENTRY FontEntry, PFONTGDI FontGDI)
Definition: freetype.c:553
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 553 of file freetype.c.

554{
555 // PFONTGDI FontGDI = FontEntry->Font;
556 PSHARED_FACE SharedFace = FontGDI->SharedFace;
557
558 if (FontGDI->Filename)
560
561 if (FontEntry->StyleName.Buffer)
562 RtlFreeUnicodeString(&FontEntry->StyleName);
563
564 if (FontEntry->FaceName.Buffer)
565 RtlFreeUnicodeString(&FontEntry->FaceName);
566
567 EngFreeMem(FontGDI);
568 SharedFace_Release(SharedFace, TRUE);
569 ExFreePoolWithTag(FontEntry, TAG_FONT);
570}
#define TRUE
Definition: types.h:120
static void SharedFace_Release(PSHARED_FACE Ptr, BOOL bDoLock)
Definition: freetype.c:523
#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 5960 of file freetype.c.

5961{
5962 const ENUMLOGFONTEXW *pLog1 = &pInfo1->EnumLogFontEx;
5963 const ENUMLOGFONTEXW *pLog2 = &pInfo2->EnumLogFontEx;
5964 const LOGFONTW *plf1 = &pLog1->elfLogFont;
5965 const LOGFONTW *plf2 = &pLog2->elfLogFont;
5966
5967 if (_wcsicmp(plf1->lfFaceName, plf2->lfFaceName) != 0)
5968 {
5969 return FALSE;
5970 }
5971
5972 if (_wcsicmp(pLog1->elfStyle, pLog2->elfStyle) != 0)
5973 {
5974 return FALSE;
5975 }
5976
5977 return TRUE;
5978}
#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 2700 of file freetype.c.

2701{
2702 int i;
2703
2704 for(i = 0; i < ft_face->num_charmaps; i++)
2705 {
2706 if (ft_face->charmaps[i]->platform_id == TT_PLATFORM_MICROSOFT &&
2707 ft_face->charmaps[i]->encoding == FT_ENCODING_MS_SYMBOL)
2708 {
2709 return TRUE;
2710 }
2711 }
2712 return FALSE;
2713}
#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 2716 of file freetype.c.

2719{
2720 FT_Fixed XScale, YScale;
2721 int Ascent, Descent;
2722 FT_Face Face = FontGDI->SharedFace->Face;
2723
2725
2726 XScale = Face->size->metrics.x_scale;
2727 YScale = Face->size->metrics.y_scale;
2728
2729 if (pFNT)
2730 {
2731 TM->tmHeight = pFNT->pixel_height;
2732 TM->tmAscent = pFNT->ascent;
2733 TM->tmDescent = TM->tmHeight - TM->tmAscent;
2736 TM->tmAveCharWidth = pFNT->avg_width;
2737 TM->tmMaxCharWidth = pFNT->max_width;
2738 TM->tmOverhang = 0;
2741 TM->tmFirstChar = pFNT->first_char;
2742 TM->tmLastChar = pFNT->last_char;
2743 TM->tmDefaultChar = pFNT->default_char + pFNT->first_char;
2744 TM->tmBreakChar = pFNT->break_char + pFNT->first_char;
2746 TM->tmWeight = FontGDI->RequestWeight;
2747 TM->tmItalic = FontGDI->RequestItalic;
2748 TM->tmUnderlined = FontGDI->RequestUnderline;
2749 TM->tmStruckOut = FontGDI->RequestStrikeOut;
2750 TM->tmCharSet = FontGDI->CharSet;
2751 return;
2752 }
2753
2754 ASSERT(pOS2);
2755 if (!pOS2)
2756 return;
2757
2758 if ((FT_Short)pOS2->usWinAscent + (FT_Short)pOS2->usWinDescent == 0)
2759 {
2760 Ascent = pHori->Ascender;
2761 Descent = -pHori->Descender;
2762 }
2763 else
2764 {
2765 Ascent = (FT_Short)pOS2->usWinAscent;
2766 Descent = (FT_Short)pOS2->usWinDescent;
2767 }
2768
2769 TM->tmAscent = FontGDI->tmAscent;
2770 TM->tmDescent = FontGDI->tmDescent;
2771 TM->tmHeight = TM->tmAscent + TM->tmDescent;
2772 TM->tmInternalLeading = FontGDI->tmInternalLeading;
2773
2774 /* MSDN says:
2775 * el = MAX(0, LineGap - ((WinAscent + WinDescent) - (Ascender - Descender)))
2776 */
2777 TM->tmExternalLeading = max(0, (FT_MulFix(pHori->Line_Gap
2778 - ((Ascent + Descent)
2779 - (pHori->Ascender - pHori->Descender)),
2780 YScale) + 32) >> 6);
2781 if (FontGDI->lfWidth != 0)
2782 TM->tmAveCharWidth = FontGDI->lfWidth;
2783 else
2784 TM->tmAveCharWidth = (FT_MulFix(pOS2->xAvgCharWidth, XScale) + 32) >> 6;
2785
2786 if (TM->tmAveCharWidth == 0)
2787 TM->tmAveCharWidth = 1;
2788
2789 /* Correct forumla to get the maxcharwidth from unicode and ansi font */
2790 TM->tmMaxCharWidth = (FT_MulFix(Face->max_advance_width, XScale) + 32) >> 6;
2791
2792 if (FontGDI->OriginalWeight != FW_DONTCARE &&
2793 FontGDI->OriginalWeight > FontGDI->RequestWeight)
2794 {
2795 TM->tmWeight = FontGDI->OriginalWeight;
2796 }
2797 else
2798 {
2799 TM->tmWeight = FontGDI->RequestWeight;
2800 }
2801
2802 TM->tmOverhang = 0;
2803 TM->tmDigitizedAspectX = 96;
2804 TM->tmDigitizedAspectY = 96;
2805 if (face_has_symbol_charmap(Face) ||
2806 (pOS2->usFirstCharIndex >= 0xf000 && pOS2->usFirstCharIndex < 0xf100))
2807 {
2808 USHORT cpOEM, cpAnsi;
2809
2810 EngGetCurrentCodePage(&cpOEM, &cpAnsi);
2811 TM->tmFirstChar = 0;
2812 switch(cpAnsi)
2813 {
2814 case 1257: /* Baltic */
2815 TM->tmLastChar = 0xf8fd;
2816 break;
2817 default:
2818 TM->tmLastChar = 0xf0ff;
2819 }
2820 TM->tmBreakChar = 0x20;
2821 TM->tmDefaultChar = 0x1f;
2822 }
2823 else
2824 {
2825 TM->tmFirstChar = pOS2->usFirstCharIndex; /* Should be the first char in the cmap */
2826 TM->tmLastChar = pOS2->usLastCharIndex; /* Should be min(cmap_last, os2_last) */
2827
2828 if(pOS2->usFirstCharIndex <= 1)
2829 TM->tmBreakChar = pOS2->usFirstCharIndex + 2;
2830 else if (pOS2->usFirstCharIndex > 0xff)
2831 TM->tmBreakChar = 0x20;
2832 else
2833 TM->tmBreakChar = pOS2->usFirstCharIndex;
2834 TM->tmDefaultChar = TM->tmBreakChar - 1;
2835 }
2836
2837 if (FontGDI->OriginalItalic || FontGDI->RequestItalic)
2838 {
2839 TM->tmItalic = 0xFF;
2840 }
2841 else
2842 {
2843 TM->tmItalic = 0;
2844 }
2845 TM->tmUnderlined = (FontGDI->RequestUnderline ? 0xFF : 0);
2846 TM->tmStruckOut = (FontGDI->RequestStrikeOut ? 0xFF : 0);
2847
2848 if (!FT_IS_FIXED_WIDTH(Face))
2849 {
2850 switch (pOS2->panose[PAN_PROPORTION_INDEX])
2851 {
2853 TM->tmPitchAndFamily = 0;
2854 break;
2855 default:
2857 break;
2858 }
2859 }
2860 else
2861 {
2862 TM->tmPitchAndFamily = 0;
2863 }
2864
2865 switch (pOS2->panose[PAN_FAMILYTYPE_INDEX])
2866 {
2867 case PAN_FAMILY_SCRIPT:
2869 break;
2872 break;
2873
2874 case PAN_ANY:
2875 case PAN_NO_FIT:
2877 case PAN_FAMILY_PICTORIAL: /* Symbol fonts get treated as if they were text */
2878 /* Which is clearly not what the panose spec says. */
2879 if (TM->tmPitchAndFamily == 0) /* Fixed */
2880 {
2882 }
2883 else
2884 {
2885 switch (pOS2->panose[PAN_SERIFSTYLE_INDEX])
2886 {
2887 case PAN_ANY:
2888 case PAN_NO_FIT:
2889 default:
2891 break;
2892
2893 case PAN_SERIF_COVE:
2897 case PAN_SERIF_SQUARE:
2898 case PAN_SERIF_THIN:
2899 case PAN_SERIF_BONE:
2901 case PAN_SERIF_TRIANGLE:
2903 break;
2904
2908 case PAN_SERIF_FLARED:
2909 case PAN_SERIF_ROUNDED:
2911 break;
2912 }
2913 }
2914 break;
2915 default:
2917 }
2918
2919 if (FT_IS_SCALABLE(Face))
2920 {
2922 }
2923 if (FT_IS_SFNT(Face))
2924 {
2926 }
2927
2928 TM->tmCharSet = FontGDI->CharSet;
2929}
static BOOL face_has_symbol_charmap(FT_Face ft_face)
Definition: freetype.c:2700
#define ASSERT_FREETYPE_LOCK_HELD()
Definition: freetype.c:219
#define _TMPF_VARIABLE_PITCH
Definition: freetype.c:192
#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 5765 of file freetype.c.

5768{
5769 ULONG Penalty;
5771 PFONT_ENTRY CurrentEntry;
5772 FONTGDI *FontGDI;
5773 OUTLINETEXTMETRICW *Otm = NULL;
5774 UINT OtmSize, OldOtmSize = 0;
5775 FT_Face Face;
5776
5777 ASSERT(FontObj);
5778 ASSERT(MatchPenalty);
5779 ASSERT(LogFont);
5780 ASSERT(Head);
5781
5782 /* Start with a pretty big buffer */
5783 OldOtmSize = 0x200;
5784 Otm = ExAllocatePoolWithTag(PagedPool, OldOtmSize, GDITAG_TEXT);
5785
5786 /* get the FontObj of lowest penalty */
5787 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
5788 {
5789 CurrentEntry = CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry);
5790
5791 FontGDI = CurrentEntry->Font;
5792 ASSERT(FontGDI);
5793 Face = FontGDI->SharedFace->Face;
5794
5795 /* get text metrics */
5797 OtmSize = IntGetOutlineTextMetrics(FontGDI, 0, NULL, TRUE);
5798 if (OtmSize > OldOtmSize)
5799 {
5800 if (Otm)
5803 }
5804
5805 /* update FontObj if lowest penalty */
5806 if (Otm)
5807 {
5809 IntRequestFontSize(NULL, FontGDI, LogFont->lfWidth, LogFont->lfHeight);
5810
5812 OtmSize = IntGetOutlineTextMetrics(FontGDI, OtmSize, Otm, TRUE);
5813 if (!OtmSize)
5814 continue;
5815
5816 OldOtmSize = OtmSize;
5817
5818 Penalty = GetFontPenalty(LogFont, Otm, Face->style_name);
5819 if (*MatchPenalty == MAXULONG || Penalty < *MatchPenalty)
5820 {
5821 *FontObj = GDIToObj(FontGDI, FONT);
5822 *MatchPenalty = Penalty;
5823 }
5824 }
5825 }
5826
5827 if (Otm)
5829}
#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:5419
static FT_Error IntRequestFontSize(PDC dc, PFONTGDI FontGDI, LONG lfWidth, LONG lfHeight)
Definition: freetype.c:3959
INT FASTCALL IntGetOutlineTextMetrics(PFONTGDI FontGDI, UINT Size, OUTLINETEXTMETRICW *Otm, BOOL bLocked)
Definition: freetype.c:3018
unsigned int UINT
Definition: ndis.h:50
Entry
Definition: section.c:5210
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 FontLink_PrepareFontInfo(), and TextIntRealizeFont().

◆ FontFamilyFillInfo()

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

Definition at line 3322 of file freetype.c.

3324{
3325 ANSI_STRING StyleA;
3326 UNICODE_STRING StyleW;
3327 TT_OS2 *pOS2;
3329 CHARSETINFO CharSetInfo;
3330 unsigned i, Size;
3331 OUTLINETEXTMETRICW *Otm;
3332 LOGFONTW *Lf;
3333 TEXTMETRICW *TM;
3334 NEWTEXTMETRICW *Ntm;
3335 DWORD fs0;
3337 PSHARED_FACE SharedFace = FontGDI->SharedFace;
3338 FT_Face Face = SharedFace->Face;
3339 UNICODE_STRING NameW;
3340
3341 RtlInitUnicodeString(&NameW, NULL);
3344 Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL, TRUE);
3345 if (!Size)
3346 return;
3348 if (!Otm)
3349 return;
3351 Size = IntGetOutlineTextMetrics(FontGDI, Size, Otm, TRUE);
3352 if (!Size)
3353 {
3355 return;
3356 }
3357
3358 Lf = &Info->EnumLogFontEx.elfLogFont;
3359 TM = &Otm->otmTextMetrics;
3360
3361 Lf->lfHeight = TM->tmHeight;
3362 Lf->lfWidth = TM->tmAveCharWidth;
3363 Lf->lfWeight = TM->tmWeight;
3364 Lf->lfItalic = TM->tmItalic;
3365 Lf->lfPitchAndFamily = (TM->tmPitchAndFamily & 0xf1) + 1;
3366 Lf->lfCharSet = TM->tmCharSet;
3370
3371 Ntm = &Info->NewTextMetricEx.ntmTm;
3372 Ntm->tmHeight = TM->tmHeight;
3373 Ntm->tmAscent = TM->tmAscent;
3374 Ntm->tmDescent = TM->tmDescent;
3377 Ntm->tmAveCharWidth = TM->tmAveCharWidth;
3378 Ntm->tmMaxCharWidth = TM->tmMaxCharWidth;
3379 Ntm->tmWeight = TM->tmWeight;
3380 Ntm->tmOverhang = TM->tmOverhang;
3383 Ntm->tmFirstChar = TM->tmFirstChar;
3384 Ntm->tmLastChar = TM->tmLastChar;
3385 Ntm->tmDefaultChar = TM->tmDefaultChar;
3386 Ntm->tmBreakChar = TM->tmBreakChar;
3387 Ntm->tmItalic = TM->tmItalic;
3388 Ntm->tmUnderlined = TM->tmUnderlined;
3389 Ntm->tmStruckOut = TM->tmStruckOut;
3391 Ntm->tmCharSet = TM->tmCharSet;
3392 Ntm->ntmFlags = TM->tmItalic ? NTM_ITALIC : 0;
3393
3394 if (550 < TM->tmWeight) Ntm->ntmFlags |= NTM_BOLD;
3395
3396 if (0 == Ntm->ntmFlags) Ntm->ntmFlags = NTM_REGULAR;
3397
3398 Info->FontType = (0 != (TM->tmPitchAndFamily & TMPF_TRUETYPE)
3399 ? TRUETYPE_FONTTYPE : 0);
3400
3401 if (0 == (TM->tmPitchAndFamily & TMPF_VECTOR))
3402 Info->FontType |= RASTER_FONTTYPE;
3403
3404
3405 /* face name */
3406 if (!FaceName)
3407 FaceName = (WCHAR*)((ULONG_PTR)Otm + (ULONG_PTR)Otm->otmpFamilyName);
3408
3409 RtlStringCbCopyW(Lf->lfFaceName, sizeof(Lf->lfFaceName), FaceName);
3410
3411 /* full name */
3412 if (!FullName)
3413 FullName = (WCHAR*)((ULONG_PTR) Otm + (ULONG_PTR)Otm->otmpFaceName);
3414
3415 RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
3416 sizeof(Info->EnumLogFontEx.elfFullName),
3417 FullName);
3418
3419 RtlInitAnsiString(&StyleA, Face->style_name);
3420 StyleW.Buffer = Info->EnumLogFontEx.elfStyle;
3421 StyleW.MaximumLength = sizeof(Info->EnumLogFontEx.elfStyle);
3422 status = RtlAnsiStringToUnicodeString(&StyleW, &StyleA, FALSE);
3423 if (!NT_SUCCESS(status))
3424 {
3426 return;
3427 }
3428 Info->EnumLogFontEx.elfScript[0] = UNICODE_NULL;
3429
3430 pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
3431
3432 if (!pOS2)
3433 {
3435 return;
3436 }
3437
3438 Ntm->ntmSizeEM = Otm->otmEMSquare;
3440 Ntm->ntmAvgWidth = 0;
3441
3443
3444 fs.fsCsb[0] = pOS2->ulCodePageRange1;
3445 fs.fsCsb[1] = pOS2->ulCodePageRange2;
3446 fs.fsUsb[0] = pOS2->ulUnicodeRange1;
3447 fs.fsUsb[1] = pOS2->ulUnicodeRange2;
3448 fs.fsUsb[2] = pOS2->ulUnicodeRange3;
3449 fs.fsUsb[3] = pOS2->ulUnicodeRange4;
3450
3451 if (0 == pOS2->version)
3452 {
3453 FT_UInt Dummy;
3454
3455 if (FT_Get_First_Char(Face, &Dummy) < 0x100)
3456 fs.fsCsb[0] |= FS_LATIN1;
3457 else
3458 fs.fsCsb[0] |= FS_SYMBOL;
3459 }
3460
3461 if (fs.fsCsb[0] == 0)
3462 {
3463 /* Let's see if we can find any interesting cmaps */
3464 for (i = 0; i < (UINT)Face->num_charmaps; i++)
3465 {
3466 switch (Face->charmaps[i]->encoding)
3467 {
3468 case FT_ENCODING_UNICODE:
3469 case FT_ENCODING_APPLE_ROMAN:
3470 fs.fsCsb[0] |= FS_LATIN1;
3471 break;
3472 case FT_ENCODING_MS_SYMBOL:
3473 fs.fsCsb[0] |= FS_SYMBOL;
3474 break;
3475 default:
3476 break;
3477 }
3478 }
3479 }
3480
3481 for (i = 0; i < MAXTCIINDEX; i++)
3482 {
3483 fs0 = 1L << i;
3484 if (fs.fsCsb[0] & fs0)
3485 {
3486 if (!IntTranslateCharsetInfo(&fs0, &CharSetInfo, TCI_SRCFONTSIG))
3487 {
3488 CharSetInfo.ciCharset = DEFAULT_CHARSET;
3489 }
3490 if (DEFAULT_CHARSET != CharSetInfo.ciCharset)
3491 {
3492 if (g_ElfScripts[i])
3493 wcscpy(Info->EnumLogFontEx.elfScript, g_ElfScripts[i]);
3494 else
3495 {
3496 DPRINT1("Unknown elfscript for bit %u\n", i);
3497 }
3498 }
3499 }
3500 }
3501 Info->NewTextMetricEx.ntmFontSig = fs;
3502}
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:242
#define MAXTCIINDEX
Definition: freetype.c:269
static BOOLEAN IntTranslateCharsetInfo(PDWORD Src, LPCHARSETINFO Cs, DWORD Flags)
Definition: freetype.c:2654
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
short WCHAR
Definition: pedump.c:58
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

Referenced by GetFontFamilyInfoForList(), and IntGdiGetFontResourceInfo().

◆ FontLink_AddEntry()

static NTSTATUS FontLink_AddEntry ( LPCWSTR  lfFaceName,
PZZWSTR  pszzFontLink 
)
static

Definition at line 875 of file freetype.c.

876{
877 SIZE_T FontLinkSize = SZZ_GetSize(pszzFontLink);
878 PZZWSTR pszz = ExAllocatePoolWithTag(PagedPool, FontLinkSize, TAG_FONT);
879 if (!pszz)
880 return STATUS_NO_MEMORY;
881 RtlCopyMemory(pszz, pszzFontLink, FontLinkSize);
882
884 if (!pEntry)
885 {
887 return STATUS_NO_MEMORY;
888 }
889
890 pEntry->pszzFontLink = pszz;
891 RtlStringCchCopyW(pEntry->lfFaceName, _countof(pEntry->lfFaceName), lfFaceName);
892 InsertHeadList(&g_FontLinkEntries, &pEntry->ListEntry);
893 return STATUS_SUCCESS;
894}
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define InsertHeadList(ListHead, Entry)
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
_NullNull_terminated_ WCHAR * PZZWSTR
Definition: ntbasedef.h:432
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _countof(array)
Definition: sndvol32.h:70
Definition: freetype.c:43
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

Referenced by FontLink_PopulateEntries().

◆ FontLink_Chain_Dump()

static VOID FontLink_Chain_Dump ( _In_ PFONTLINK_CHAIN  pChain)
inlinestatic

Definition at line 4338 of file freetype.c.

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

Referenced by FontLink_Chain_FindGlyph().

◆ FontLink_Chain_FindEntry()

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

Definition at line 1283 of file freetype.c.

1286{
1288 if (!pEntry)
1289 {
1290 if (!(pLF->lfPitchAndFamily & FIXED_PITCH))
1291 pChain->pszzFontLink = s_szzDefFontLink;
1292 else
1293 pChain->pszzFontLink = s_szzDefFixedFontLink;
1294 return STATUS_SUCCESS;
1295 }
1296
1297 pChain->pszzFontLink = pEntry->pszzFontLink;
1298 return STATUS_SUCCESS;
1299}
static const WCHAR s_szzDefFixedFontLink[]
Definition: freetype.c:1196
static PFONTLINK_ENTRY FontLink_FindEntry(const LOGFONTW *pLogFont)
Definition: freetype.c:1264
static const WCHAR s_szzDefFontLink[]
Definition: freetype.c:1188
#define FIXED_PITCH
Definition: wingdi.h:444

Referenced by FontLink_Chain_Populate().

◆ 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 4382 of file freetype.c.

4388{
4389 PFONTLINK pFontLink;
4390 PLIST_ENTRY Entry, Head;
4391 UINT index;
4392 FT_Face face;
4393
4394 // Try the default font at first
4395 index = get_glyph_index_flagged(pChain->pDefFace, code, fCodeAsIndex);
4396 if (index)
4397 {
4398 DPRINT("code: 0x%08X, index: 0x%08X, fCodeAsIndex:%d\n", code, index, fCodeAsIndex);
4399 pCache->Hashed.Face = *pFace = pChain->pDefFace;
4400 return index; // The glyph is found on the default font
4401 }
4402
4403 if (!FontLink_Chain_IsPopulated(pChain)) // The chain is not populated yet
4404 {
4406 FontLink_Chain_Dump(pChain);
4407 }
4408
4409 // Now the chain is populated. Looking for the target glyph...
4410 Head = &pChain->FontLinkList;
4411 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
4412 {
4413 pFontLink = CONTAINING_RECORD(Entry, FONTLINK, ListEntry);
4414 if (!FontLink_PrepareFontInfo(pFontLink))
4415 continue; // This link is not useful, check the next one
4416
4417 face = pFontLink->SharedFace->Face;
4419 if (!index)
4420 continue; // The glyph does not exist, continue searching
4421
4422 // The target glyph is found in the chain
4423 DPRINT("code: 0x%08X, index: 0x%08X\n", code, index);
4424 pCache->Hashed.Face = *pFace = face;
4425 if (IntNeedRequestFontSize(pChain, face, Entry))
4426 IntRequestFontSizeEx(face, &pChain->LogFont);
4427 FT_Set_Transform(face, &pCache->Hashed.matTransform, NULL);
4428 return index;
4429 }
4430
4431 // No target glyph found in the chain: use default glyph
4433 index = get_glyph_index(*pFace, code);
4434 DPRINT("code: 0x%08X, index: 0x%08X\n", code, index);
4435 pCache->Hashed.Face = *pFace = pChain->pDefFace;
4436 return index;
4437}
#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:4332
static BOOL IntNeedRequestFontSize(PFONTLINK_CHAIN pChain, FT_Face face, PLIST_ENTRY TargetEntry)
Definition: freetype.c:4361
static FT_Error IntRequestFontSizeEx(FT_Face face, const LOGFONTW *plf)
Definition: freetype.c:4091
static BOOL FontLink_PrepareFontInfo(_Inout_ PFONTLINK pFontLink)
Definition: freetype.c:349
static DWORD s_chFontLinkDefaultChar
Definition: freetype.c:61
static VOID FontLink_Chain_Dump(_In_ PFONTLINK_CHAIN pChain)
Definition: freetype.c:4338
static NTSTATUS FontLink_Chain_Populate(_Inout_ PFONTLINK_CHAIN pChain)
Definition: freetype.c:1302
static BOOL FontLink_Chain_IsPopulated(const FONTLINK_CHAIN *pChain)
Definition: freetype.c:185
static FT_UInt FASTCALL get_glyph_index(FT_Face ft_face, UINT glyph)
Definition: freetype.c:4317
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 1205 of file freetype.c.

1208{
1209 PLIST_ENTRY Entry, Head = &pChain->FontLinkList;
1210 PFONTLINK pLink;
1211
1212 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
1213 {
1214 pLink = CONTAINING_RECORD(Entry, FONTLINK, ListEntry);
1215 if (RtlEqualMemory(&pLink->LogFont, plf, sizeof(*plf)))
1216 return pLink;
1217 }
1218
1219 return NULL;
1220}
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18

Referenced by FontLink_Create().

◆ FontLink_Chain_Init()

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

Definition at line 1176 of file freetype.c.

1180{
1181 RtlZeroMemory(pChain, sizeof(*pChain));
1182 pChain->pBaseTextObj = pTextObj;
1183 pChain->pDefFace = face;
1185}

Referenced by IntExtTextOutW(), and TextIntGetTextExtentPoint().

◆ FontLink_Chain_IsPopulated()

static BOOL FontLink_Chain_IsPopulated ( const FONTLINK_CHAIN pChain)
inlinestatic

Definition at line 185 of file freetype.c.

186{
187 return pChain->LogFont.lfFaceName[0];
188}

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

◆ FontLink_Chain_Populate()

static NTSTATUS FontLink_Chain_Populate ( _Inout_ PFONTLINK_CHAIN  pChain)
static

Definition at line 1302 of file freetype.c.

1304{
1306 PFONTLINK pLink;
1307 LOGFONTW lfBase;
1308 PTEXTOBJ pTextObj = pChain->pBaseTextObj;
1309 PFONTGDI pFontGDI;
1310 PCWSTR pszLink;
1311 WCHAR szEntry[MAX_PATH];
1312 BOOL bFixCharSet;
1313
1314 InitializeListHead(&pChain->FontLinkList);
1315
1316 lfBase = pTextObj->logfont.elfEnumLogfontEx.elfLogFont;
1317 pFontGDI = ObjToGDI(pTextObj->Font, FONT);
1318 lfBase.lfHeight = pFontGDI->lfHeight;
1319 lfBase.lfWidth = pFontGDI->lfWidth;
1320
1321 // Use pTextObj->TextFace if lfFaceName was empty
1322 if (!lfBase.lfFaceName[0])
1323 {
1324 ASSERT(pTextObj->TextFace[0]);
1325 RtlStringCchCopyW(lfBase.lfFaceName, _countof(lfBase.lfFaceName), pTextObj->TextFace);
1326 }
1327
1328 // Fix lfCharSet
1329 switch (lfBase.lfCharSet)
1330 {
1331 case ANSI_CHARSET: bFixCharSet = !s_fFontLinkUseAnsi; break;
1332 case OEM_CHARSET: bFixCharSet = !s_fFontLinkUseOem; break;
1333 case SYMBOL_CHARSET: bFixCharSet = !s_fFontLinkUseSymbol; break;
1334 default: bFixCharSet = TRUE; break;
1335 }
1336 if (bFixCharSet)
1337 lfBase.lfCharSet = DEFAULT_CHARSET;
1338
1339 pChain->LogFont = lfBase;
1340
1341 // Load FontLink entry
1342 Status = FontLink_Chain_FindEntry(pChain, &pChain->LogFont);
1343 if (!NT_SUCCESS(Status))
1344 return Status;
1345
1346 pszLink = pChain->pszzFontLink;
1347 while (*pszLink)
1348 {
1349 DPRINT("pszLink: '%S'\n", pszLink);
1350 pLink = FontLink_Create(pChain, &lfBase, pszLink);
1351 if (pLink)
1352 InsertTailList(&pChain->FontLinkList, &pLink->ListEntry);
1353 pszLink += wcslen(pszLink) + 1;
1354 }
1355
1356 // Use default settings (if any)
1358 {
1360 RtlStringCchCatW(szEntry, _countof(szEntry), L",");
1362 DPRINT("szEntry: '%S'\n", szEntry);
1363 pLink = FontLink_Create(pChain, &lfBase, szEntry);
1364 if (pLink)
1365 InsertTailList(&pChain->FontLinkList, &pLink->ListEntry);
1366 }
1367
1369 return Status;
1370}
#define MAX_PATH
Definition: compat.h:34
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
#define L(x)
Definition: resources.c:13
#define ObjToGDI(ClipObj, Type)
Definition: engobjects.h:184
#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:62
static BOOL s_fFontLinkUseAnsi
Definition: freetype.c:64
static PFONTLINK FontLink_Create(_Inout_ PFONTLINK_CHAIN pChain, _In_ const LOGFONTW *plfBase, _In_ LPCWSTR pszLink)
Definition: freetype.c:1223
static NTSTATUS FontLink_Chain_FindEntry(_Inout_ PFONTLINK_CHAIN pChain, _Inout_ PLOGFONTW pLF)
Definition: freetype.c:1283
static WCHAR s_szDefFontLinkFontName[MAX_PATH]
Definition: freetype.c:63
static BOOL s_fFontLinkUseOem
Definition: freetype.c:65
static BOOL s_fFontLinkUseSymbol
Definition: freetype.c:66
Status
Definition: gdiplustypes.h:25
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
const uint16_t * PCWSTR
Definition: typedefs.h:57
#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_Create()

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

Definition at line 1223 of file freetype.c.

1227{
1228 LPWSTR pch0, pch1;
1229 LOGFONTW lf;
1230 PFONTLINK pLink;
1231
1232 lf = *plfBase;
1233
1234 // pszLink: "<FontFileName>,<FaceName>[,...]"
1235 pch0 = wcschr(pszLink, L',');
1236 if (!pch0)
1237 {
1238 DPRINT1("%S\n", pszLink);
1239 return NULL; // Invalid FontLink data
1240 }
1241 ++pch0;
1242
1243 pch1 = wcschr(pch0, L',');
1244 if (pch1)
1245 RtlStringCchCopyNW(lf.lfFaceName, _countof(lf.lfFaceName), pch0, pch1 - pch0);
1246 else
1248
1250 DPRINT("lfFaceName: %S\n", lf.lfFaceName);
1251
1252 if (RtlEqualMemory(plfBase, &lf, sizeof(lf)) || FontLink_Chain_FindLink(pChain, &lf))
1253 return NULL; // Already exists
1254
1255 pLink = ExAllocatePoolZero(PagedPool, sizeof(FONTLINK), TAG_FONT);
1256 if (!pLink)
1257 return NULL; // Out of memory
1258
1259 pLink->LogFont = lf;
1260 return pLink;
1261}
#define wcschr
Definition: compat.h:17
static PFONTLINK FontLink_Chain_FindLink(PFONTLINK_CHAIN pChain, PLOGFONTW plf)
Definition: freetype.c:1205
static BOOL SubstituteFontRecurse(PLOGFONTW pLogFont)
Definition: freetype.c:1140
static 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
uint16_t * LPWSTR
Definition: typedefs.h:56

Referenced by FontLink_Chain_Populate().

◆ FontLink_DeleteEntries()

static void FontLink_DeleteEntries ( VOID  )
static

Definition at line 896 of file freetype.c.

897{
900
901 for (Entry = g_FontLinkEntries.Flink; Entry != &g_FontLinkEntries; Entry = Entry->Flink)
902 {
904 ExFreePoolWithTag(pEntry->pszzFontLink, TAG_FONT);
906 }
907}

Referenced by FreeFontSupport().

◆ FontLink_Destroy()

static VOID FontLink_Destroy ( _Inout_ PFONTLINK  pLink)
inlinestatic

Definition at line 179 of file freetype.c.

180{
182}

◆ FontLink_FindEntry()

static PFONTLINK_ENTRY FontLink_FindEntry ( const LOGFONTW pLogFont)
static

Definition at line 1264 of file freetype.c.

1265{
1268 LOGFONTW lf = *pLogFont;
1269
1271
1272 for (Entry = g_FontLinkEntries.Flink; Entry != &g_FontLinkEntries; Entry = Entry->Flink)
1273 {
1275 if (!_wcsicmp(pEntry->lfFaceName, lf.lfFaceName))
1276 return pEntry;
1277 }
1278
1279 return NULL;
1280}

Referenced by FontLink_Chain_FindEntry().

◆ FontLink_LoadDefaultCharset()

static NTSTATUS FontLink_LoadDefaultCharset ( VOID  )
inlinestatic

Definition at line 133 of file freetype.c.

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

Referenced by InitFontSupport().

◆ FontLink_LoadDefaultFonts()

static NTSTATUS FontLink_LoadDefaultFonts ( VOID  )
inlinestatic

Definition at line 95 of file freetype.c.

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

Referenced by InitFontSupport().

◆ FontLink_LoadSettings()

static NTSTATUS FontLink_LoadSettings ( VOID  )
inlinestatic

Definition at line 69 of file freetype.c.

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

Referenced by InitFontSupport().

◆ FontLink_PopulateEntries()

static NTSTATUS FontLink_PopulateEntries ( VOID  )
static

Definition at line 909 of file freetype.c.

910{
912 HKEY hKey;
913 DWORD cchName, cbData, dwType;
914 WCHAR szName[LF_FACESIZE], szzFontLink[300];
915
916 // Open the registry key
918 L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontLink\\SystemLink",
919 &hKey);
920 if (!NT_SUCCESS(Status))
921 return Status;
922
923 for (DWORD dwIndex = 0;; ++dwIndex)
924 {
926 cbData = sizeof(szzFontLink);
927 Status = RegEnumValueW(hKey, dwIndex, szName, &cchName, &dwType, szzFontLink, &cbData);
928 if (!NT_SUCCESS(Status))
929 break;
930 if (dwType != REG_MULTI_SZ)
931 continue;
932
933 // Ensure double-NUL-terminated
934 szzFontLink[_countof(szzFontLink) - 1] = UNICODE_NULL;
935 szzFontLink[_countof(szzFontLink) - 2] = UNICODE_NULL;
936
937 DPRINT1("szName: %S\n", szName);
938 DPRINT1("szzFontLink: %S\n", szzFontLink);
939
940 FontLink_AddEntry(szName, szzFontLink);
941 }
942
943 ZwClose(hKey); // Close the registry key
944 return STATUS_SUCCESS;
945}
#define LF_FACESIZE
Definition: dimm.idl:39
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
static NTSTATUS FontLink_AddEntry(LPCWSTR lfFaceName, PZZWSTR pszzFontLink)
Definition: freetype.c:875
#define REG_MULTI_SZ
Definition: nt_native.h:1504
static const WCHAR szName[]
Definition: powrprof.c:45
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName
Definition: winbase.h:2521

Referenced by InitFontSupport().

◆ FontLink_PrepareFontInfo()

static BOOL FontLink_PrepareFontInfo ( _Inout_ PFONTLINK  pFontLink)
static

Definition at line 349 of file freetype.c.

351{
352 FONTOBJ *pFontObj;
353 ULONG MatchPenalty;
354 UNICODE_STRING FaceName;
355 PPROCESSINFO Win32Process;
356 PFONTGDI pFontGDI;
357
359
360 if (pFontLink->bIgnore)
361 return FALSE;
362
363 if (pFontLink->SharedFace)
364 return TRUE;
365
366 MatchPenalty = MAXULONG;
367 pFontObj = NULL;
368
369 // Search private fonts
370 Win32Process = PsGetCurrentProcessWin32Process();
371 FindBestFontFromList(&pFontObj, &MatchPenalty, &pFontLink->LogFont,
372 &Win32Process->PrivateFontListHead);
373
374 // Search system fonts
375 FindBestFontFromList(&pFontObj, &MatchPenalty, &pFontLink->LogFont,
376 &g_FontListHead);
377
378 if (!pFontObj) // Not found?
379 {
380 pFontLink->bIgnore = TRUE;
381 return FALSE;
382 }
383
384 pFontGDI = ObjToGDI(pFontObj, FONT);
385 pFontLink->SharedFace = pFontGDI->SharedFace;
386
387 // FontLink uses family name
388 RtlInitUnicodeString(&FaceName, pFontLink->LogFont.lfFaceName);
389 if (!MatchFontName(pFontLink->SharedFace, &FaceName, TT_NAME_ID_FONT_FAMILY, LANG_ENGLISH) &&
390 !MatchFontName(pFontLink->SharedFace, &FaceName, TT_NAME_ID_FONT_FAMILY, gusLanguageID))
391 {
392 pFontLink->bIgnore = TRUE;
393 return FALSE;
394 }
395
396 return TRUE;
397}
static __inline VOID FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, const LOGFONTW *LogFont, const PLIST_ENTRY Head)
Definition: freetype.c:5765
static BOOL MatchFontName(PSHARED_FACE SharedFace, PUNICODE_STRING Name1, FT_UShort NameID, FT_UShort LangID)
Definition: freetype.c:5866
#define TT_NAME_ID_FONT_FAMILY
Definition: font.c:3536
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
#define LANG_ENGLISH
Definition: nls.h:52
LIST_ENTRY PrivateFontListHead
Definition: win32.h:285
USHORT gusLanguageID
Definition: init.c:12

Referenced by FontLink_Chain_FindGlyph(), and IntNeedRequestFontSize().

◆ FreeFontSupport()

VOID FASTCALL FreeFontSupport ( VOID  )

Definition at line 991 of file freetype.c.

992{
993 PLIST_ENTRY pHead, pEntry;
994 PFONT_CACHE_ENTRY pFontCache;
995 PFONTSUBST_ENTRY pSubstEntry;
996 PFONT_ENTRY pFontEntry;
997
998 // Free font cache list
999 pHead = &g_FontCacheListHead;
1000 while (!IsListEmpty(pHead))
1001 {
1002 pEntry = RemoveHeadList(pHead);
1003 pFontCache = CONTAINING_RECORD(pEntry, FONT_CACHE_ENTRY, ListEntry);
1004 RemoveCachedEntry(pFontCache);
1005 }
1006
1007 // Free font subst list
1008 pHead = &g_FontSubstListHead;
1009 while (!IsListEmpty(pHead))
1010 {
1011 pEntry = RemoveHeadList(pHead);
1012 pSubstEntry = CONTAINING_RECORD(pEntry, FONTSUBST_ENTRY, ListEntry);
1013 ExFreePoolWithTag(pSubstEntry, TAG_FONT);
1014 }
1015
1016 // Free font list
1017 pHead = &g_FontListHead;
1018 while (!IsListEmpty(pHead))
1019 {
1020 pEntry = RemoveHeadList(pHead);
1021 pFontEntry = CONTAINING_RECORD(pEntry, FONT_ENTRY, ListEntry);
1022 CleanupFontEntry(pFontEntry);
1023 }
1024
1026
1028 {
1031 }
1032
1035}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
FT_Library g_FreeTypeLibrary
Definition: freetype.c:206
static void FontLink_DeleteEntries(VOID)
Definition: freetype.c:896
static __inline VOID FASTCALL CleanupFontEntry(PFONT_ENTRY FontEntry)
Definition: freetype.c:573
static void RemoveCachedEntry(PFONT_CACHE_ENTRY Entry)
Definition: freetype.c:462
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 592 of file freetype.c.

593{
594 return (FT_Fixed)((long)f.value << 16 | (unsigned long)f.fract);
595}
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 5377 of file freetype.c.

5383{
5385 FT_Face Face = FontGdi->SharedFace->Face;
5386
5388
5389 if (FT_IS_SFNT(Face))
5390 {
5391 if (Table)
5392 Table = Table >> 24 | Table << 24 | (Table >> 8 & 0xFF00) |
5393 (Table << 8 & 0xFF0000);
5394
5395 if (!Buffer) Size = 0;
5396
5397 if (Buffer && Size)
5398 {
5400 FT_ULong Needed = 0;
5401
5402 Error = FT_Load_Sfnt_Table(Face, Table, Offset, NULL, &Needed);
5403
5404 if ( !Error && Needed < Size) Size = Needed;
5405 }
5406 if (!FT_Load_Sfnt_Table(Face, Table, Offset, Buffer, &Size))
5407 Result = Size;
5408 }
5409
5411
5412 return Result;
5413}
BOOL Error
Definition: chkdsk.c:66
Definition: bufpool.h:45
#define IntUnLockFreeType()
Definition: freetype.c:231
#define IntLockFreeType()
Definition: freetype.c:225
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 4444 of file freetype.c.

4453{
4454 PDC_ATTR pdcattr;
4455 PTEXTOBJ TextObj;
4456 PFONTGDI FontGDI;
4457 HFONT hFont = 0;
4458 GLYPHMETRICS gm;
4459 ULONG Size;
4460 FT_Face ft_face;
4461 FT_UInt glyph_index;
4462 DWORD width, height, pitch, needed = 0;
4463 FT_Bitmap ft_bitmap;
4465 INT left, right, top = 0, bottom = 0;
4467 FLOATOBJ eM11, widthRatio, eTemp;
4468 FT_Matrix mat, transMat = identityMat;
4469 BOOL needsTransform = FALSE;
4470 INT orientation;
4471 LONG aveWidth;
4472 INT adv, lsb, bbx; /* These three hold to widths of the unrotated chars */
4473 OUTLINETEXTMETRICW *potm;
4474 XFORMOBJ xo;
4475 XFORML xform;
4476 LOGFONTW *plf;
4477
4478 DPRINT("%u, %08x, %p, %08lx, %p, %p\n", wch, iFormat, pgm,
4479 cjBuf, pvBuf, pmat2);
4480
4481 pdcattr = dc->pdcattr;
4482
4483 XFORMOBJ_vInit(&xo, &dc->pdcattr->mxWorldToDevice);
4484 XFORMOBJ_iGetXform(&xo, &xform);
4485 FLOATOBJ_SetFloat(&eM11, xform.eM11);
4486
4487 hFont = pdcattr->hlfntNew;
4488 TextObj = RealizeFontInit(hFont);
4489
4490 if (!TextObj)
4491 {
4493 return GDI_ERROR;
4494 }
4495 FontGDI = ObjToGDI(TextObj->Font, FONT);
4496 ft_face = FontGDI->SharedFace->Face;
4497
4498 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
4499 aveWidth = FT_IS_SCALABLE(ft_face) ? abs(plf->lfWidth) : 0;
4500 orientation = FT_IS_SCALABLE(ft_face) ? plf->lfOrientation : 0;
4501
4503 Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL, FALSE);
4504 if (!Size)
4505 {
4506 TEXTOBJ_UnlockText(TextObj);
4508 return GDI_ERROR;
4509 }
4511 if (!potm)
4512 {
4513 TEXTOBJ_UnlockText(TextObj);
4515 return GDI_ERROR;
4516 }
4518 Size = IntGetOutlineTextMetrics(FontGDI, Size, potm, FALSE);
4519 if (!Size)
4520 {
4522 TEXTOBJ_UnlockText(TextObj);
4524 return GDI_ERROR;
4525 }
4526
4528 TextIntUpdateSize(dc, TextObj, FontGDI, FALSE);
4530 FT_Set_Transform(ft_face, &mat, NULL);
4531
4532 TEXTOBJ_UnlockText(TextObj);
4533
4534 glyph_index = get_glyph_index_flagged(ft_face, wch, (iFormat & GGO_GLYPH_INDEX));
4535 iFormat &= ~GGO_GLYPH_INDEX;
4536
4537 if (orientation || (iFormat != GGO_METRICS && iFormat != GGO_BITMAP) || aveWidth || pmat2)
4538 load_flags |= FT_LOAD_NO_BITMAP;
4539
4540 if (iFormat & GGO_UNHINTED)
4541 {
4542 load_flags |= FT_LOAD_NO_HINTING;
4543 iFormat &= ~GGO_UNHINTED;
4544 }
4545
4546 error = FT_Load_Glyph(ft_face, glyph_index, load_flags);
4547 if (error)
4548 {
4549 DPRINT1("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index);
4551 if (potm) ExFreePoolWithTag(potm, GDITAG_TEXT);
4552 return GDI_ERROR;
4553 }
4555
4556 FLOATOBJ_Set1(&widthRatio);
4557 if (aveWidth && potm)
4558 {
4559 // widthRatio = aveWidth * eM11 / potm->otmTextMetrics.tmAveCharWidth
4560 FLOATOBJ_SetLong(&widthRatio, aveWidth);
4561 FLOATOBJ_Mul(&widthRatio, &eM11);
4563 }
4564
4565 //left = (INT)(ft_face->glyph->metrics.horiBearingX * widthRatio) & -64;
4566 FLOATOBJ_SetLong(&eTemp, ft_face->glyph->metrics.horiBearingX);
4567 FLOATOBJ_Mul(&eTemp, &widthRatio);
4568 left = FLOATOBJ_GetLong(&eTemp) & -64;
4569
4570 //right = (INT)((ft_face->glyph->metrics.horiBearingX +
4571 // ft_face->glyph->metrics.width) * widthRatio + 63) & -64;
4572 FLOATOBJ_SetLong(&eTemp, ft_face->glyph->metrics.horiBearingX * ft_face->glyph->metrics.width);
4573 FLOATOBJ_Mul(&eTemp, &widthRatio);
4574 FLOATOBJ_AddLong(&eTemp, 63);
4575 right = FLOATOBJ_GetLong(&eTemp) & -64;
4576
4577 //adv = (INT)((ft_face->glyph->metrics.horiAdvance * widthRatio) + 63) >> 6;
4578 FLOATOBJ_SetLong(&eTemp, ft_face->glyph->metrics.horiAdvance);
4579 FLOATOBJ_Mul(&eTemp, &widthRatio);
4580 FLOATOBJ_AddLong(&eTemp, 63);
4581 adv = FLOATOBJ_GetLong(&eTemp) >> 6;
4582
4583 lsb = left >> 6;
4584 bbx = (right - left) >> 6;
4585
4586 DPRINT("Advance = %d, lsb = %d, bbx = %d\n",adv, lsb, bbx);
4587
4589
4590 /* Width scaling transform */
4591 if (!FLOATOBJ_Equal1(&widthRatio))
4592 {
4593 FT_Matrix scaleMat;
4594
4595 eTemp = widthRatio;
4596 FLOATOBJ_MulLong(&eTemp, 1 << 16);
4597
4598 scaleMat.xx = FLOATOBJ_GetLong(&eTemp);
4599 scaleMat.xy = 0;
4600 scaleMat.yx = 0;
4601 scaleMat.yy = INT_TO_FIXED(1);
4602 FT_Matrix_Multiply(&scaleMat, &transMat);
4603 needsTransform = TRUE;
4604 }
4605
4606 /* World transform */
4607 {
4608 FT_Matrix ftmatrix;
4610
4611 /* Create a freetype matrix, by converting to 16.16 fixpoint format */
4612 IntMatrixFromMx(&ftmatrix, pmx);
4613
4614 if (memcmp(&ftmatrix, &identityMat, sizeof(identityMat)) != 0)
4615 {
4616 FT_Matrix_Multiply(&ftmatrix, &transMat);
4617 needsTransform = TRUE;
4618 }
4619 }
4620
4621 /* Rotation transform */
4622 if (orientation)
4623 {
4624 FT_Matrix rotationMat;
4625 DPRINT("Rotation Trans!\n");
4626 IntEscapeMatrix(&rotationMat, orientation);
4627 FT_Matrix_Multiply(&rotationMat, &transMat);
4628 needsTransform = TRUE;
4629 }
4630
4631 /* Extra transformation specified by caller */
4632 if (pmat2)
4633 {
4634 FT_Matrix extraMat;
4635 DPRINT("MAT2 Matrix Trans!\n");
4636 extraMat.xx = FT_FixedFromFIXED(pmat2->eM11);
4637 extraMat.xy = FT_FixedFromFIXED(pmat2->eM21);
4638 extraMat.yx = FT_FixedFromFIXED(pmat2->eM12);
4639 extraMat.yy = FT_FixedFromFIXED(pmat2->eM22);
4640 FT_Matrix_Multiply(&extraMat, &transMat);
4641 needsTransform = TRUE;
4642 }
4643
4644 if (potm) ExFreePoolWithTag(potm, GDITAG_TEXT); /* It looks like we are finished with potm ATM. */
4645
4646 if (!needsTransform)
4647 {
4648 DPRINT("No Need to be Transformed!\n");
4649 top = (ft_face->glyph->metrics.horiBearingY + 63) & -64;
4650 bottom = (ft_face->glyph->metrics.horiBearingY -
4651 ft_face->glyph->metrics.height) & -64;
4652 gm.gmCellIncX = adv;
4653 gm.gmCellIncY = 0;
4654 }
4655 else
4656 {
4657 INT xc, yc;
4658 FT_Vector vec;
4659 for (xc = 0; xc < 2; xc++)
4660 {
4661 for (yc = 0; yc < 2; yc++)
4662 {
4663 vec.x = (ft_face->glyph->metrics.horiBearingX +
4664 xc * ft_face->glyph->metrics.width);
4665 vec.y = ft_face->glyph->metrics.horiBearingY -
4666 yc * ft_face->glyph->metrics.height;
4667 DPRINT("Vec %ld,%ld\n", vec.x, vec.y);
4668 FT_Vector_Transform(&vec, &transMat);
4669 if (xc == 0 && yc == 0)
4670 {
4671 left = right = vec.x;
4672 top = bottom = vec.y;
4673 }
4674 else
4675 {
4676 if (vec.x < left) left = vec.x;
4677 else if (vec.x > right) right = vec.x;
4678 if (vec.y < bottom) bottom = vec.y;
4679 else if (vec.y > top) top = vec.y;
4680 }
4681 }
4682 }
4683 left = left & -64;
4684 right = (right + 63) & -64;
4685 bottom = bottom & -64;
4686 top = (top + 63) & -64;
4687
4688 DPRINT("Transformed box: (%d,%d - %d,%d)\n", left, top, right, bottom);
4689 vec.x = ft_face->glyph->metrics.horiAdvance;
4690 vec.y = 0;
4691 FT_Vector_Transform(&vec, &transMat);
4692 gm.gmCellIncX = (vec.x+63) >> 6;
4693 gm.gmCellIncY = -((vec.y+63) >> 6);
4694 }
4695 gm.gmBlackBoxX = (right - left) >> 6;
4696 gm.gmBlackBoxY = (top - bottom) >> 6;
4697 gm.gmptGlyphOrigin.x = left >> 6;
4698 gm.gmptGlyphOrigin.y = top >> 6;
4699
4700 DPRINT("CX %d CY %d BBX %u BBY %u GOX %d GOY %d\n",
4701 gm.gmCellIncX, gm.gmCellIncY,
4702 gm.gmBlackBoxX, gm.gmBlackBoxY,
4704
4706
4707 if (iFormat == GGO_METRICS)
4708 {
4709 DPRINT("GGO_METRICS Exit!\n");
4710 *pgm = gm;
4711 return 1; /* FIXME */
4712 }
4713
4714 if (ft_face->glyph->format != ft_glyph_format_outline && iFormat != GGO_BITMAP)
4715 {
4716 DPRINT1("Loaded a bitmap\n");
4717 return GDI_ERROR;
4718 }
4719
4720 switch (iFormat)
4721 {
4722 case GGO_BITMAP:
4723 {
4724 width = gm.gmBlackBoxX;
4725 height = gm.gmBlackBoxY;
4726 pitch = ((width + 31) >> 5) << 2;
4727 needed = pitch * height;
4728
4729 if (!pvBuf || !cjBuf) break;
4730 if (!needed) return GDI_ERROR; /* empty glyph */
4731 if (needed > cjBuf)
4732 return GDI_ERROR;
4733
4734 switch (ft_face->glyph->format)
4735 {
4737 {
4738 BYTE *src = ft_face->glyph->bitmap.buffer, *dst = pvBuf;
4739 INT w = min( pitch, (ft_face->glyph->bitmap.width + 7) >> 3 );
4740 INT h = min( height, ft_face->glyph->bitmap.rows );
4741 while (h--)
4742 {
4744 src += ft_face->glyph->bitmap.pitch;
4745 dst += pitch;
4746 }
4747 break;
4748 }
4749
4751 {
4752 ft_bitmap.width = width;
4753 ft_bitmap.rows = height;
4754 ft_bitmap.pitch = pitch;
4755 ft_bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
4756 ft_bitmap.buffer = pvBuf;
4757
4759 if (needsTransform)
4760 {
4761 FT_Outline_Transform(&ft_face->glyph->outline, &transMat);
4762 }
4763 FT_Outline_Translate(&ft_face->glyph->outline, -left, -bottom );
4764 /* Note: FreeType will only set 'black' bits for us. */
4765 RtlZeroMemory(pvBuf, needed);
4766 FT_Outline_Get_Bitmap(g_FreeTypeLibrary, &ft_face->glyph->outline, &ft_bitmap);
4768 break;
4769 }
4770
4771 default:
4772 DPRINT1("Loaded glyph format %x\n", ft_face->glyph->format);
4773 return GDI_ERROR;
4774 }
4775
4776 break;
4777 }
4778
4779 case GGO_GRAY2_BITMAP:
4780 case GGO_GRAY4_BITMAP:
4781 case GGO_GRAY8_BITMAP:
4782 {
4783 unsigned int mult, row, col;
4784 BYTE *start, *ptr;
4785
4786 width = gm.gmBlackBoxX;
4787 height = gm.gmBlackBoxY;
4788 pitch = (width + 3) / 4 * 4;
4789 needed = pitch * height;
4790
4791 if (!pvBuf || !cjBuf) break;
4792 if (!needed) return GDI_ERROR; /* empty glyph */
4793 if (needed > cjBuf)
4794 return GDI_ERROR;
4795
4796 switch (ft_face->glyph->format)
4797 {
4799 {
4800 BYTE *src = ft_face->glyph->bitmap.buffer, *dst = pvBuf;
4801 INT h = min( height, ft_face->glyph->bitmap.rows );
4802 INT x;
4803 while (h--)
4804 {
4805 for (x = 0; (UINT)x < pitch; x++)
4806 {
4807 if (x < ft_face->glyph->bitmap.width)
4808 dst[x] = (src[x / 8] & (1 << ( (7 - (x % 8))))) ? 0xff : 0;
4809 else
4810 dst[x] = 0;
4811 }
4812 src += ft_face->glyph->bitmap.pitch;
4813 dst += pitch;
4814 }
4815 break;
4816 }
4818 {
4819 ft_bitmap.width = width;
4820 ft_bitmap.rows = height;
4821 ft_bitmap.pitch = pitch;
4822 ft_bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
4823 ft_bitmap.buffer = pvBuf;
4824
4826 if (needsTransform)
4827 {
4828 FT_Outline_Transform(&ft_face->glyph->outline, &transMat);
4829 }
4830 FT_Outline_Translate(&ft_face->glyph->outline, -left, -bottom );
4831 RtlZeroMemory(ft_bitmap.buffer, cjBuf);
4832 FT_Outline_Get_Bitmap(g_FreeTypeLibrary, &ft_face->glyph->outline, &ft_bitmap);
4834
4836 mult = 4;
4837 else if (iFormat == GGO_GRAY4_BITMAP)
4838 mult = 16;
4839 else if (iFormat == GGO_GRAY8_BITMAP)
4840 mult = 64;
4841 else
4842 {
4843 return GDI_ERROR;
4844 }
4845
4846 start = pvBuf;
4847 for (row = 0; row < height; row++)
4848 {
4849 ptr = start;
4850 for (col = 0; col < width; col++, ptr++)
4851 {
4852 *ptr = (((int)*ptr) * mult + 128) / 256;
4853 }
4854 start += pitch;
4855 }
4856
4857 break;
4858 }
4859 default:
4860 DPRINT1("Loaded glyph format %x\n", ft_face->glyph->format);
4861 return GDI_ERROR;
4862 }
4863
4864 break;
4865 }
4866
4867 case GGO_NATIVE:
4868 {
4869 FT_Outline *outline = &ft_face->glyph->outline;
4870
4871 if (cjBuf == 0) pvBuf = NULL; /* This is okay, need cjBuf to allocate. */
4872
4874 if (needsTransform && pvBuf) FT_Outline_Transform(outline, &transMat);
4875
4877
4878 if (!pvBuf || !cjBuf)
4879 {
4881 break;
4882 }
4883 if (needed > cjBuf)
4884 {
4886 return GDI_ERROR;
4887 }
4890 break;
4891 }
4892
4893 case GGO_BEZIER:
4894 {
4895 FT_Outline *outline = &ft_face->glyph->outline;
4896 if (cjBuf == 0) pvBuf = NULL;
4897
4898 if (needsTransform && pvBuf)
4899 {
4901 FT_Outline_Transform(outline, &transMat);
4903 }
4905
4906 if (!pvBuf || !cjBuf)
4907 break;
4908 if (needed > cjBuf)
4909 return GDI_ERROR;
4910
4912 break;
4913 }
4914
4915 default:
4916 DPRINT1("Unsupported format %u\n", iFormat);
4917 return GDI_ERROR;
4918 }
4919
4920 DPRINT("ftGdiGetGlyphOutline END and needed %lu\n", needed);
4921
4922 if (gm.gmBlackBoxX == 0)
4923 gm.gmBlackBoxX = 1;
4924 if (gm.gmBlackBoxY == 0)
4925 gm.gmBlackBoxY = 1;
4926
4927 *pgm = gm;
4928 return needed;
4929}
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:4212
#define ASSERT_FREETYPE_LOCK_NOT_HELD()
Definition: freetype.c:222
static unsigned int get_bezier_glyph_outline(FT_Outline *outline, unsigned int buflen, char *buf)
Definition: freetype.c:3834
static unsigned int get_native_glyph_outline(FT_Outline *outline, unsigned int buflen, char *buf)
Definition: freetype.c:3761
static VOID FASTCALL IntMatrixFromMx(FT_Matrix *pmat, const MATRIX *pmx)
Definition: freetype.c:1050
static VOID FASTCALL IntEscapeMatrix(FT_Matrix *pmat, LONG lfEscapement)
Definition: freetype.c:1037
static const FT_Matrix identityMat
Definition: freetype.c:201
static __inline FT_Fixed FT_FixedFromFIXED(FIXED f)
Definition: freetype.c:592
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 6395 of file freetype.c.

6398{
6399 DWORD Count = 0;
6400 INT i = 0;
6401 FT_Face face = Font->SharedFace->Face;
6402
6403 if (FT_HAS_KERNING(face) && face->charmap->encoding == FT_ENCODING_UNICODE)
6404 {
6405 FT_UInt previous_index = 0, glyph_index = 0;
6406 FT_ULong char_code, char_previous;
6407 FT_Vector delta;
6408
6409 char_previous = char_code = FT_Get_First_Char(face, &glyph_index);
6410
6412
6413 while (glyph_index)
6414 {
6415 if (previous_index && glyph_index)
6416 {
6417 FT_Get_Kerning(face, previous_index, glyph_index, FT_KERNING_DEFAULT, &delta);
6418
6419 if (pKerningPair && cPairs)
6420 {
6421 pKerningPair[i].wFirst = char_previous;
6422 pKerningPair[i].wSecond = char_code;
6423 pKerningPair[i].iKernAmount = delta.x;
6424 i++;
6425 if (i == cPairs) break;
6426 }
6427 Count++;
6428 }
6429 previous_index = glyph_index;
6430 char_previous = char_code;
6431 char_code = FT_Get_Next_Char(face, char_code, &glyph_index);
6432 }
6434 }
6435 return Count;
6436}
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 3630 of file freetype.c.

3631{
3632 if ( lprs )
3633 {
3634 lprs->nSize = sizeof(RASTERIZER_STATUS);
3635 lprs->wFlags = TT_AVAILABLE | TT_ENABLED;
3636 lprs->nLanguageID = gusLanguageID;
3637 return TRUE;
3638 }
3640 return FALSE;
3641}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#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 5092 of file freetype.c.

5096{
5097 PDC_ATTR pdcattr;
5098 UINT Ret = DEFAULT_CHARSET;
5099 INT i;
5100 HFONT hFont;
5101 PTEXTOBJ TextObj;
5102 PFONTGDI FontGdi;
5104 TT_OS2 *pOS2;
5105 FT_Face Face;
5106 CHARSETINFO csi;
5107 DWORD cp, fs0;
5108 USHORT usACP, usOEM;
5109
5110 pdcattr = Dc->pdcattr;
5111 hFont = pdcattr->hlfntNew;
5112 TextObj = RealizeFontInit(hFont);
5113
5114 if (!TextObj)
5115 {
5117 return Ret;
5118 }
5119 FontGdi = ObjToGDI(TextObj->Font, FONT);
5120 Face = FontGdi->SharedFace->Face;
5121 TEXTOBJ_UnlockText(TextObj);
5122
5123 memset(&fs, 0, sizeof(FONTSIGNATURE));
5125 pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
5126 if (NULL != pOS2)
5127 {
5128 fs.fsCsb[0] = pOS2->ulCodePageRange1;
5129 fs.fsCsb[1] = pOS2->ulCodePageRange2;
5130 fs.fsUsb[0] = pOS2->ulUnicodeRange1;
5131 fs.fsUsb[1] = pOS2->ulUnicodeRange2;
5132 fs.fsUsb[2] = pOS2->ulUnicodeRange3;
5133 fs.fsUsb[3] = pOS2->ulUnicodeRange4;
5134 if (pOS2->version == 0)
5135 {
5136 FT_UInt dummy;
5137
5138 if (FT_Get_First_Char( Face, &dummy ) < 0x100)
5139 fs.fsCsb[0] |= FS_LATIN1;
5140 else
5141 fs.fsCsb[0] |= FS_SYMBOL;
5142 }
5143 }
5144 pOS2 = NULL;
5146 DPRINT("Csb 1=%x 0=%x\n", fs.fsCsb[1],fs.fsCsb[0]);
5147 if (fs.fsCsb[0] == 0)
5148 { /* Let's see if we can find any interesting cmaps */
5149 for (i = 0; i < Face->num_charmaps; i++)
5150 {
5151 switch (Face->charmaps[i]->encoding)
5152 {
5153 case FT_ENCODING_UNICODE:
5154 case FT_ENCODING_APPLE_ROMAN:
5155 fs.fsCsb[0] |= FS_LATIN1;
5156 break;
5157 case FT_ENCODING_MS_SYMBOL:
5158 fs.fsCsb[0] |= FS_SYMBOL;
5159 break;
5160 default:
5161 break;
5162 }
5163 }
5164 }
5165 if (lpSig)
5166 {
5167 RtlCopyMemory(lpSig, &fs, sizeof(FONTSIGNATURE));
5168 }
5169
5170 RtlGetDefaultCodePage(&usACP, &usOEM);
5171 cp = usACP;
5172
5174 if (csi.fs.fsCsb[0] & fs.fsCsb[0])
5175 {
5176 DPRINT("Hit 1\n");
5177 Ret = csi.ciCharset;
5178 goto Exit;
5179 }
5180
5181 for (i = 0; i < MAXTCIINDEX; i++)
5182 {
5183 fs0 = 1L << i;
5184 if (fs.fsCsb[0] & fs0)
5185 {
5186 if (IntTranslateCharsetInfo(&fs0, &csi, TCI_SRCFONTSIG))
5187 {
5188 // *cp = csi.ciACP;
5189 DPRINT("Hit 2\n");
5190 Ret = csi.ciCharset;
5191 goto Exit;
5192 }
5193 else
5194 DPRINT1("TCI failing on %x\n", fs0);
5195 }
5196 }
5197Exit:
5198 DPRINT("CharSet %u CodePage %u\n", csi.ciCharset, csi.ciACP);
5199 return (MAKELONG(csi.ciACP, csi.ciCharset));
5200}
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 5279 of file freetype.c.

5282{
5283 PDC dc;
5284 PDC_ATTR pdcattr;
5285 PTEXTOBJ TextObj;
5286 PFONTGDI FontGDI;
5287 FT_Face Face;
5288 TT_OS2 *pOS2;
5289 TT_HoriHeader *pHori;
5291 ULONG Error;
5293 LOGFONTW *plf;
5294
5295 if (!ptmwi)
5296 {
5298 return FALSE;
5299 }
5300 RtlZeroMemory(ptmwi, sizeof(TMW_INTERNAL));
5301
5302 if (!(dc = DC_LockDc(hDC)))
5303 {
5305 return FALSE;
5306 }
5307 pdcattr = dc->pdcattr;
5308 TextObj = RealizeFontInit(pdcattr->hlfntNew);
5309 if (NULL != TextObj)
5310 {
5311 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
5312 FontGDI = ObjToGDI(TextObj->Font, FONT);
5313
5314 Face = FontGDI->SharedFace->Face;
5315
5316 // NOTE: GetTextMetrics simply ignores lfEscapement and XFORM.
5318 Error = IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight);
5319 FT_Set_Transform(Face, NULL, NULL);
5320
5322
5323 if (0 != Error)
5324 {
5325 DPRINT1("Error in setting pixel sizes: %u\n", Error);
5327 }
5328 else
5329 {
5331
5333
5334 Error = FT_Get_WinFNT_Header(Face, &Win);
5335 pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2);
5336 pHori = FT_Get_Sfnt_Table(Face, ft_sfnt_hhea);
5337
5338 if (!pOS2 && Error)
5339 {
5340 DPRINT1("Can't find OS/2 table - not TT font?\n");
5342 }
5343
5344 if (!pHori && Error)
5345 {
5346 DPRINT1("Can't find HHEA table - not TT font?\n");
5348 }
5349
5350 if (NT_SUCCESS(Status))
5351 {
5352 FillTM(&ptmwi->TextMetric, FontGDI, pOS2, pHori, (Error ? NULL : &Win));
5353
5354 /* FIXME: Fill Diff member */
5355 }
5356
5358 }
5359 TEXTOBJ_UnlockText(TextObj);
5360 }
5361 else
5362 {
5364 }
5365 DC_UnlockDc(dc);
5366
5367 if (!NT_SUCCESS(Status))
5368 {
5370 return FALSE;
5371 }
5372 return TRUE;
5373}
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:2716
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 6376 of file freetype.c.

6377{
6378 if (FT_HAS_FIXED_SIZES(Font->SharedFace->Face))
6379 Info->iTechnology = RI_TECH_BITMAP;
6380 else
6381 {
6382 if (FT_IS_SCALABLE(Font->SharedFace->Face))
6383 Info->iTechnology = RI_TECH_SCALABLE;
6384 else
6385 Info->iTechnology = RI_TECH_FIXED;
6386 }
6387 Info->iUniq = Font->FontObj.iUniq;
6388 Info->dwUnknown = -1;
6389 return TRUE;
6390}
#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 5205 of file freetype.c.

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

Referenced by NtGdiGetFontUnicodeRanges().

◆ FTVectorToPOINTFX()

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

Definition at line 578 of file freetype.c.

579{
580 pt->x.value = vec->x >> 6;
581 pt->x.fract = (vec->x & 0x3f) << 10;
582 pt->x.fract |= ((pt->x.fract >> 6) | (pt->x.fract >> 12));
583 pt->y.value = vec->y >> 6;
584 pt->y.fract = (vec->y & 0x3f) << 10;
585 pt->y.fract |= ((pt->y.fract >> 6) | (pt->y.fract >> 12));
586}
#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 3834 of file freetype.c.

3835{
3836 /* Convert the quadratic Beziers to cubic Beziers.
3837 The parametric eqn for a cubic Bezier is, from PLRM:
3838 r(t) = at^3 + bt^2 + ct + r0
3839 with the control points:
3840 r1 = r0 + c/3
3841 r2 = r1 + (c + b)/3
3842 r3 = r0 + c + b + a
3843
3844 A quadratic Bezier has the form:
3845 p(t) = (1-t)^2 p0 + 2(1-t)t p1 + t^2 p2
3846
3847 So equating powers of t leads to:
3848 r1 = 2/3 p1 + 1/3 p0
3849 r2 = 2/3 p1 + 1/3 p2
3850 and of course r0 = p0, r3 = p2
3851 */
3852 int contour, point = 0, first_pt;
3853 TTPOLYGONHEADER *pph;
3854 TTPOLYCURVE *ppc;
3855 DWORD pph_start, cpfx, type;
3856 FT_Vector cubic_control[4];
3857 unsigned int needed = 0;
3858
3859 for (contour = 0; contour < outline->n_contours; contour++)
3860 {
3861 pph_start = needed;
3862 pph = (TTPOLYGONHEADER *)(buf + needed);
3863 first_pt = point;
3864 if (buf)
3865 {
3866 pph->dwType = TT_POLYGON_TYPE;
3867 FTVectorToPOINTFX(&outline->points[point], &pph->pfxStart);
3868 }
3869 needed += sizeof(*pph);
3870 point++;
3871 while (point <= outline->contours[contour])
3872 {
3873 ppc = (TTPOLYCURVE *)(buf + needed);
3874 type = (outline->tags[point] & FT_Curve_Tag_On) ?
3876 cpfx = 0;
3877 do
3878 {
3879 if (type == TT_PRIM_LINE)
3880 {
3881 if (buf)
3882 FTVectorToPOINTFX(&outline->points[point], &ppc->apfx[cpfx]);
3883 cpfx++;
3884 point++;
3885 }
3886 else
3887 {
3888 /* Unlike QSPLINEs, CSPLINEs always have their endpoint
3889 so cpfx = 3n */
3890
3891 /* FIXME: Possible optimization in endpoint calculation
3892 if there are two consecutive curves */
3893 cubic_control[0] = outline->points[point-1];
3894 if (!(outline->tags[point-1] & FT_Curve_Tag_On))
3895 {
3896 cubic_control[0].x += outline->points[point].x + 1;
3897 cubic_control[0].y += outline->points[point].y + 1;
3898 cubic_control[0].x >>= 1;
3899 cubic_control[0].y >>= 1;
3900 }
3901 if (point+1 > outline->contours[contour])
3902 cubic_control[3] = outline->points[first_pt];
3903 else
3904 {
3905 cubic_control[3] = outline->points[point+1];
3906 if (!(outline->tags[point+1] & FT_Curve_Tag_On))
3907 {
3908 cubic_control[3].x += outline->points[point].x + 1;
3909 cubic_control[3].y += outline->points[point].y + 1;
3910 cubic_control[3].x >>= 1;
3911 cubic_control[3].y >>= 1;
3912 }
3913 }
3914 /* r1 = 1/3 p0 + 2/3 p1
3915 r2 = 1/3 p2 + 2/3 p1 */
3916 cubic_control[1].x = (2 * outline->points[point].x + 1) / 3;
3917 cubic_control[1].y = (2 * outline->points[point].y + 1) / 3;
3918 cubic_control[2] = cubic_control[1];
3919 cubic_control[1].x += (cubic_control[0].x + 1) / 3;
3920 cubic_control[1].y += (cubic_control[0].y + 1) / 3;
3921 cubic_control[2].x += (cubic_control[3].x + 1) / 3;
3922 cubic_control[2].y += (cubic_control[3].y + 1) / 3;
3923 if (buf)
3924 {
3925 FTVectorToPOINTFX(&cubic_control[1], &ppc->apfx[cpfx]);
3926 FTVectorToPOINTFX(&cubic_control[2], &ppc->apfx[cpfx+1]);
3927 FTVectorToPOINTFX(&cubic_control[3], &ppc->apfx[cpfx+2]);
3928 }
3929 cpfx += 3;
3930 point++;
3931 }
3932 } while (point <= outline->contours[contour] &&
3933 (outline->tags[point] & FT_Curve_Tag_On) ==
3934 (outline->tags[point-1] & FT_Curve_Tag_On));
3935 /* At the end of a contour Windows adds the start point,
3936 but only for Beziers and we've already done that.
3937 */
3938 if (point <= outline->contours[contour] &&
3939 outline->tags[point] & FT_Curve_Tag_On)
3940 {
3941 /* This is the closing pt of a bezier, but we've already
3942 added it, so just inc point and carry on */
3943 point++;
3944 }
3945 if (buf)
3946 {
3947 ppc->wType = type;
3948 ppc->cpfx = cpfx;
3949 }
3950 needed += sizeof(*ppc) + (cpfx - 1) * sizeof(POINTFX);
3951 }
3952 if (buf)
3953 pph->cb = needed - pph_start;
3954 }
3955 return needed;
3956}
POINTL point
Definition: edittest.c:50
static __inline void FTVectorToPOINTFX(FT_Vector *vec, POINTFX *pt)
Definition: freetype.c:578
#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 4317 of file freetype.c.

4318{
4319 FT_UInt ret;
4320
4321 if (face_has_symbol_charmap(ft_face))
4322 {
4323 ret = get_glyph_index_symbol(ft_face, glyph);
4324 if (ret != 0)
4325 return ret;
4326 }
4327
4328 return FT_Get_Char_Index(ft_face, glyph);
4329}
return ret
Definition: mutex.c:146
static FT_UInt FASTCALL get_glyph_index_symbol(FT_Face ft_face, UINT glyph)
Definition: freetype.c:4303
FT_Get_Char_Index(FT_Face face, FT_ULong charcode)
Definition: ftobjs.c:3731

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

◆ get_glyph_index_flagged()

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

Definition at line 4332 of file freetype.c.

4333{
4334 return (fCodeAsIndex ? code : get_glyph_index(face, code));
4335}

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 4303 of file freetype.c.

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

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 3761 of file freetype.c.

3762{
3763 TTPOLYGONHEADER *pph;
3764 TTPOLYCURVE *ppc;
3765 int needed = 0, point = 0, contour, first_pt;
3766 unsigned int pph_start, cpfx;
3767 DWORD type;
3768
3769 for (contour = 0; contour < outline->n_contours; contour++)
3770 {
3771 /* Ignore contours containing one point */
3772 if (point == outline->contours[contour])
3773 {
3774 point++;
3775 continue;
3776 }
3777
3778 pph_start = needed;
3779 pph = (TTPOLYGONHEADER *)(buf + needed);
3780 first_pt = point;
3781 if (buf)
3782 {
3783 pph->dwType = TT_POLYGON_TYPE;
3784 FTVectorToPOINTFX(&outline->points[point], &pph->pfxStart);
3785 }
3786 needed += sizeof(*pph);
3787 point++;
3788 while (point <= outline->contours[contour])
3789 {
3790 ppc = (TTPOLYCURVE *)(buf + needed);
3791 type = (outline->tags[point] & FT_Curve_Tag_On) ?
3793 cpfx = 0;
3794 do
3795 {
3796 if (buf)
3797 FTVectorToPOINTFX(&outline->points[point], &ppc->apfx[cpfx]);
3798 cpfx++;
3799 point++;
3800 } while (point <= outline->contours[contour] &&
3801 (outline->tags[point] & FT_Curve_Tag_On) ==
3802 (outline->tags[point-1] & FT_Curve_Tag_On));
3803 /* At the end of a contour Windows adds the start point, but
3804 only for Beziers */
3805 if (point > outline->contours[contour] &&
3806 !(outline->tags[point-1] & FT_Curve_Tag_On))
3807 {
3808 if (buf)
3809 FTVectorToPOINTFX(&outline->points[first_pt], &ppc->apfx[cpfx]);
3810 cpfx++;
3811 }
3812 else if (point <= outline->contours[contour] &&
3813 outline->tags[point] & FT_Curve_Tag_On)
3814 {
3815 /* add closing pt for bezier */
3816 if (buf)
3817 FTVectorToPOINTFX(&outline->points[point], &ppc->apfx[cpfx]);
3818 cpfx++;
3819 point++;
3820 }
3821 if (buf)
3822 {
3823 ppc->wType = type;
3824 ppc->cpfx = cpfx;
3825 }
3826 needed += sizeof(*ppc) + (cpfx - 1) * sizeof(POINTFX);
3827 }
3828 if (buf)
3829 pph->cb = needed - pph_start;
3830 }
3831 return needed;
3832}
#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 3505 of file freetype.c.

3511{
3513 PFONT_ENTRY CurrentEntry;
3514 FONTGDI *FontGDI;
3515 FONTFAMILYINFO InfoEntry;
3516 LONG Count = *pCount;
3517
3518 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
3519 {
3520 CurrentEntry = CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry);
3521 FontGDI = CurrentEntry->Font;
3522 ASSERT(FontGDI);
3523
3524 if (LogFont->lfCharSet != DEFAULT_CHARSET &&
3525 LogFont->lfCharSet != FontGDI->CharSet)
3526 {
3527 continue; /* charset mismatch */
3528 }
3529
3530 /* get one info entry */
3531 FontFamilyFillInfo(&InfoEntry, NULL, NULL, FontGDI);
3532
3533 if (LogFont->lfFaceName[0] != UNICODE_NULL)
3534 {
3535 /* check name */
3536 if (_wcsnicmp(LogFont->lfFaceName,
3538 RTL_NUMBER_OF(LogFont->lfFaceName) - 1) != 0 &&
3539 _wcsnicmp(LogFont->lfFaceName,
3540 InfoEntry.EnumLogFontEx.elfFullName,
3541 RTL_NUMBER_OF(LogFont->lfFaceName) - 1) != 0)
3542 {
3543 continue;
3544 }
3545 }
3546
3547 if (NominalName)
3548 {
3549 /* store the nominal name */
3551 sizeof(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName),
3552 NominalName);
3553 }
3554
3555 /* store one entry to Info */
3556 if (0 <= Count && Count < MaxCount)
3557 {
3558 RtlCopyMemory(&Info[Count], &InfoEntry, sizeof(InfoEntry));
3559 }
3560 Count++;
3561 }
3562
3563 *pCount = Count;
3564
3565 return TRUE;
3566}
#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:3322
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 3569 of file freetype.c.

3573{
3574 PLIST_ENTRY pEntry, pHead = &g_FontSubstListHead;
3575 PFONTSUBST_ENTRY pCurrentEntry;
3576 PUNICODE_STRING pFromW, pToW;
3577 LOGFONTW lf = *LogFont;
3579
3580 for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink)
3581 {
3582 pCurrentEntry = CONTAINING_RECORD(pEntry, FONTSUBST_ENTRY, ListEntry);
3583
3584 pFromW = &pCurrentEntry->FontNames[FONTSUBST_FROM];
3585 if (LogFont->lfFaceName[0] != UNICODE_NULL)
3586 {
3587 /* check name */
3588 if (_wcsicmp(LogFont->lfFaceName, pFromW->Buffer) != 0)
3589 continue; /* mismatch */
3590 }
3591
3592 pToW = &pCurrentEntry->FontNames[FONTSUBST_TO];
3593 if (RtlEqualUnicodeString(pFromW, pToW, TRUE) &&
3594 pCurrentEntry->CharSets[FONTSUBST_FROM] ==
3595 pCurrentEntry->CharSets[FONTSUBST_TO])
3596 {
3597 /* identical mapping */
3598 continue;
3599 }
3600
3601 /* substitute and get the real name */
3602 IntUnicodeStringToBuffer(lf.lfFaceName, sizeof(lf.lfFaceName), pFromW);
3604 if (LogFont->lfCharSet != DEFAULT_CHARSET && LogFont->lfCharSet != lf.lfCharSet)
3605 continue;
3606
3607 /* search in global fonts */
3609 GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount, &g_FontListHead);
3610
3611 /* search in private fonts */
3612 IntLockProcessPrivateFonts(Win32Process);
3613 GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount,
3614 &Win32Process->PrivateFontListHead);
3615 IntUnLockProcessPrivateFonts(Win32Process);
3617
3618 if (LogFont->lfFaceName[0] != UNICODE_NULL)
3619 {
3620 /* it's already matched to the exact name and charset if the name
3621 was specified at here, then so don't scan more for another name */
3622 break;
3623 }
3624 }
3625
3626 return TRUE;
3627}
static BOOLEAN FASTCALL GetFontFamilyInfoForList(const LOGFONTW *LogFont, PFONTFAMILYINFO Info, LPCWSTR NominalName, LONG *pCount, LONG MaxCount, PLIST_ENTRY Head)
Definition: freetype.c:3505
#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)
UNICODE_STRING FontNames[FONTSUBST_FROM_AND_TO]
Definition: font.h:79
BYTE CharSets[FONTSUBST_FROM_AND_TO]
Definition: font.h:80
#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 5419 of file freetype.c.

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

7229{
7230 BOOL bResult;
7231 DC *dc;
7232
7233 // TODO: Write test-cases to exactly match real Windows in different
7234 // bad parameters (e.g. does Windows check the DC or the RECT first?).
7235 dc = DC_LockDc(hDC);
7236 if (!dc)
7237 {
7239 return FALSE;
7240 }
7241
7242 bResult = IntExtTextOutW( dc,
7243 XStart,
7244 YStart,
7245 fuOptions,
7246 lprc,
7247 String,
7248 Count,
7249 Dx,
7250 dwCodePage );
7251
7252 DC_UnlockDc(dc);
7253
7254 return bResult;
7255}
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:6673
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2439
_In_ int _Inout_ LPRECT lprc
Definition: winuser.h:4620

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 7416 of file freetype.c.

7423{
7424 PABC SafeBuffI;
7425 PABCFLOAT SafeBuffF;
7426 PDC dc;
7427 PDC_ATTR pdcattr;
7428 PTEXTOBJ TextObj;
7429 PFONTGDI FontGDI;
7430 FT_Face face;
7431 UINT i, glyph_index;
7432 HFONT hFont = NULL;
7433 PLOGFONTW plf;
7434
7435 dc = DC_LockDc(hDC);
7436 if (dc == NULL)
7437 {
7439 return FALSE;
7440 }
7441
7442 pdcattr = dc->pdcattr;
7443 hFont = pdcattr->hlfntNew;
7444 TextObj = RealizeFontInit(hFont);
7445
7446 DC_UnlockDc(dc);
7447
7448 if (TextObj == NULL)
7449 {
7451 return FALSE;
7452 }
7453
7454 FontGDI = ObjToGDI(TextObj->Font, FONT);
7455
7456 face = FontGDI->SharedFace->Face;
7458 {
7459 TEXTOBJ_UnlockText(TextObj);
7461 return FALSE;
7462 }
7463
7464 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
7465
7466 // NOTE: GetCharABCWidths simply ignores lfEscapement and XFORM.
7468 IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight);
7470
7471 if (!fl)
7472 SafeBuffF = SafeBuffer;
7473 else
7474 SafeBuffI = SafeBuffer;
7475
7476 for (i = FirstChar; i < FirstChar+Count; i++)
7477 {
7478 int adv, lsb, bbx, left, right;
7479
7480 if (Safepwch)
7481 glyph_index = get_glyph_index_flagged(face, Safepwch[i - FirstChar], (fl & GCABCW_INDICES));
7482 else
7483 glyph_index = get_glyph_index_flagged(face, i, (fl & GCABCW_INDICES));
7484
7485 FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
7486
7487 left = (INT)face->glyph->metrics.horiBearingX & -64;
7488 right = (INT)((face->glyph->metrics.horiBearingX + face->glyph->metrics.width) + 63) & -64;
7489 adv = (face->glyph->advance.x + 32) >> 6;
7490
7491// int test = (INT)(face->glyph->metrics.horiAdvance + 63) >> 6;
7492// DPRINT1("Advance Wine %d and Advance Ros %d\n",test, adv ); /* It's the same! */
7493
7494 lsb = left >> 6;
7495 bbx = (right - left) >> 6;
7496 /*
7497 DPRINT1("lsb %d and bbx %d\n", lsb, bbx );
7498 */
7499 if (!fl)
7500 {
7501 SafeBuffF[i - FirstChar].abcfA = (FLOAT) lsb;
7502 SafeBuffF[i - FirstChar].abcfB = (FLOAT) bbx;
7503 SafeBuffF[i - FirstChar].abcfC = (FLOAT) (adv - lsb - bbx);
7504 }
7505 else
7506 {
7507 SafeBuffI[i - FirstChar].abcA = lsb;
7508 SafeBuffI[i - FirstChar].abcB = bbx;
7509 SafeBuffI[i - FirstChar].abcC = adv - lsb - bbx;
7510 }
7511 }
7512
7514 TEXTOBJ_UnlockText(TextObj);
7515
7516 return TRUE;
7517}
static BOOL FASTCALL IntSelectFaceCharmap(FT_Face face)
Definition: freetype.c:7380
#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 7523 of file freetype.c.

7530{
7531 PDC dc;
7532 PDC_ATTR pdcattr;
7533 PTEXTOBJ TextObj;
7534 PFONTGDI FontGDI;
7535 FT_Face face;
7536 UINT i, glyph_index;
7537 HFONT hFont = 0;
7538 LOGFONTW *plf;
7539 PINT SafeBuffI;
7540 PFLOAT SafeBuffF;
7541
7542 dc = DC_LockDc(hDC);
7543 if (dc == NULL)
7544 {
7546 return FALSE;
7547 }
7548
7549 pdcattr = dc->pdcattr;
7550 hFont = pdcattr->hlfntNew;
7551 TextObj = RealizeFontInit(hFont);
7552 DC_UnlockDc(dc);
7553
7554 if (TextObj == NULL)
7555 {
7557 return FALSE;
7558 }
7559
7560 FontGDI = ObjToGDI(TextObj->Font, FONT);
7561
7562 face = FontGDI->SharedFace->Face;
7564 {
7565 TEXTOBJ_UnlockText(TextObj);
7567 return FALSE;
7568 }
7569
7570 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
7571
7572 // NOTE: GetCharWidth simply ignores lfEscapement and XFORM.
7574 IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight);
7576
7577 if (!fl)
7578 SafeBuffF = (PFLOAT)Buffer;
7579 else
7580 SafeBuffI = (PINT)Buffer;
7581
7582 for (i = FirstChar; i < FirstChar+Count; i++)
7583 {
7584 if (Safepwc)
7585 glyph_index = get_glyph_index_flagged(face, Safepwc[i - FirstChar], (fl & GCW_INDICES));
7586 else
7587 glyph_index = get_glyph_index_flagged(face, i, (fl & GCW_INDICES));
7588
7589 FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
7590
7591 if (!fl)
7592 SafeBuffF[i - FirstChar] = (FLOAT) ((face->glyph->advance.x + 32) >> 6);
7593 else
7594 SafeBuffI[i - FirstChar] = (face->glyph->advance.x + 32) >> 6;
7595 }
7596
7598 TEXTOBJ_UnlockText(TextObj);
7599
7600 return TRUE;
7601}
FLOAT * PFLOAT
Definition: minwindef.h:147
int * PINT
Definition: minwindef.h:150
#define GCW_INDICES
Definition: ntgdityp.h:206

Referenced by NtGdiGetCharWidthW().

◆ GreGetGlyphIndicesW()

DWORD APIENTRY GreGetGlyphIndicesW ( _In_ HDC  hdc,
_In_reads_opt_(cwc) PCWCH  pwc,
_In_ INT  cwc,
_Out_writes_opt_(cwc) PWORD  pgi,
_In_ DWORD  iMode,
_In_ BOOL  bSubset 
)

Definition at line 7636 of file freetype.c.

7643{
7644 // FIXME: bSubset
7645 PDC dc = DC_LockDc(hdc);
7646 if (!dc)
7647 return GDI_ERROR;
7648
7649 PDC_ATTR pdcattr = dc->pdcattr;
7650 HFONT hFont = pdcattr->hlfntNew;
7651 PTEXTOBJ TextObj = RealizeFontInit(hFont);
7652 DC_UnlockDc(dc);
7653
7654 if (!TextObj)
7655 {
7656 DPRINT1("!TextObj\n");
7657 return GDI_ERROR;
7658 }
7659
7660 PFONTGDI FontGDI = ObjToGDI(TextObj->Font, FONT);
7661 FT_Face Face = FontGDI->SharedFace->Face;
7662 TEXTOBJ_UnlockText(TextObj);
7663
7664 if (cwc == 0)
7665 {
7666 // Only the exceptional query case (pwc == NULL && pgi == NULL && iMode == 0)
7667 // should return the number of glyphs. All other cwc == 0 cases must fail.
7668 if (!pwc && !pgi && !iMode)
7669 return Face->num_glyphs; // Returns number of glyphs
7670
7671 return GDI_ERROR;
7672 }
7673
7674 // Get default character
7675 WCHAR DefChar = 0xFFFF;
7676 if (!(iMode & GGI_MARK_NONEXISTING_GLYPHS) && IntGetFontDefaultChar(Face, &DefChar))
7677 {
7679 DefChar = get_glyph_index(Face, DefChar); // Convert to glyph index
7681 }
7682
7683 // Get glyph indices
7684 // NOTE: Windows GetGlyphIndices doesn't support Surrogate Pairs.
7686 for (INT i = 0; i < cwc; i++)
7687 {
7688 pgi[i] = get_glyph_index(Face, pwc[i]);
7689 if (pgi[i] == 0)
7690 pgi[i] = DefChar;
7691 }
7693
7694 return cwc;
7695}
static BOOL IntGetFontDefaultChar(_In_ FT_Face Face, _Out_ PWCHAR pDefChar)
Definition: freetype.c:7603
HDC hdc
Definition: main.c:9
static LPCSTR INT LPWORD pgi
Definition: font.c:51
FT_Long num_glyphs
Definition: freetype.h:1036
_In_ ULONG iMode
Definition: winddi.h:3520
#define GGI_MARK_NONEXISTING_GLYPHS
Definition: wingdi.h:1085

Referenced by NtGdiGetGlyphIndicesWInternal().

◆ InitFontSupport()

BOOL FASTCALL InitFontSupport ( VOID  )

Definition at line 948 of file freetype.c.

949{
950 ULONG ulError;
951
953
955 if (g_FreeTypeLock == NULL)
956 {
957 return FALSE;
958 }
960
962 if (ulError)
963 {
964 DPRINT1("FT_Init_FreeType failed with error code 0x%x\n", ulError);
965 return FALSE;
966 }
967
969 {
970 DPRINT1("Fonts registry is empty.\n");
971
972 /* Load font(s) with writing registry */
974 }
975
976 IntLoadFontSubstList(&g_FontSubstListHead);
977
978#if 0
979 DumpFontInfo(TRUE);
980#endif
981
986
987 return TRUE;
988}
#define NonPagedPool
Definition: env_spec_w32.h:307
BOOL FASTCALL IntLoadFontSubstList(PLIST_ENTRY pHead)
Definition: freetype.c:729
static UINT g_FontCacheNumEntries
Definition: freetype.c:240
VOID FASTCALL IntLoadSystemFonts(VOID)
Definition: freetype.c:1378
static NTSTATUS FontLink_LoadDefaultCharset(VOID)
Definition: freetype.c:133
static NTSTATUS FontLink_PopulateEntries(VOID)
Definition: freetype.c:909
static NTSTATUS FontLink_LoadSettings(VOID)
Definition: freetype.c:69
static NTSTATUS FontLink_LoadDefaultFonts(VOID)
Definition: freetype.c:95
BOOL FASTCALL IntLoadFontsInRegistry(VOID)
Definition: freetype.c:2255
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 5981 of file freetype.c.

5982{
5984 if (FamInfo->EnumLogFontEx.elfStyle[0] &&
5985 _wcsicmp(FamInfo->EnumLogFontEx.elfStyle, L"Regular") != 0)
5986 {
5987 wcscat(psz, L" ");
5988 wcscat(psz, FamInfo->EnumLogFontEx.elfStyle);
5989 }
5990}
wcscat

Referenced by IntGdiGetFontResourceInfo().

◆ IntCharSetFromCodePage()

BYTE FASTCALL IntCharSetFromCodePage ( UINT  uCodePage)

Definition at line 318 of file freetype.c.

319{
320 UINT i;
321
322 if (uCodePage == CP_OEMCP)
323 return OEM_CHARSET;
324
325 if (uCodePage == CP_MACCP)
326 return MAC_CHARSET;
327
328 for (i = 0; i < MAXTCIINDEX; ++i)
329 {
330 if (g_FontTci[i].ciACP == 0)
331 continue;
332
333 if (g_FontTci[i].ciACP == uCodePage)
334 return g_FontTci[i].ciCharset;
335 }
336
337 return DEFAULT_CHARSET;
338}
#define CP_OEMCP
Definition: freetype.c:312
static const CHARSETINFO g_FontTci[MAXTCIINDEX]
Definition: freetype.c:270
#define CP_MACCP
Definition: freetype.c:313
#define MAC_CHARSET
Definition: wingdi.h:403

Referenced by CreateStockFonts().

◆ IntDeleteRegFontEntries()

VOID IntDeleteRegFontEntries ( _In_ PCWSTR  pszFileName,
_In_ DWORD  dwFlags 
)

Definition at line 2115 of file freetype.c.

2116{
2118 HKEY hKey;
2119 WCHAR szName[MAX_PATH], szValue[MAX_PATH];
2120 ULONG dwIndex, NameLength, ValueSize, dwType;
2121
2123 if (!NT_SUCCESS(Status))
2124 return;
2125
2126 for (dwIndex = 0;;)
2127 {
2128 NameLength = RTL_NUMBER_OF(szName);
2129 ValueSize = sizeof(szValue);
2130 Status = RegEnumValueW(hKey, dwIndex, szName, &NameLength, &dwType, szValue, &ValueSize);
2131 if (!NT_SUCCESS(Status))
2132 break;
2133
2134 if (dwType != REG_SZ || _wcsicmp(szValue, pszFileName) != 0)
2135 {
2136 ++dwIndex;
2137 continue;
2138 }
2139
2140 /* Delete the found value */
2142 if (!NT_SUCCESS(Status))
2143 break;
2144 }
2145
2146 ZwClose(hKey);
2147}
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
UNICODE_STRING g_FontRegPath
Definition: freetype.c:209
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:44

Referenced by IntGdiRemoveFontResourceSingle().

◆ IntEnableFontRendering()

VOID FASTCALL IntEnableFontRendering ( BOOL  Enable)

Definition at line 2585 of file freetype.c.

2586{
2588}
static BOOL g_RenderingEnabled
Definition: freetype.c:217
_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 1037 of file freetype.c.

1038{
1039 FT_Vector vecAngle;
1040 /* Convert the angle in tenths of degrees into degrees as a 16.16 fixed-point value */
1041 FT_Angle angle = INT_TO_FIXED(lfEscapement) / 10;
1042 FT_Vector_Unit(&vecAngle, angle);
1043 pmat->xx = vecAngle.x;
1044 pmat->xy = -vecAngle.y;
1045 pmat->yx = -pmat->xy;
1046 pmat->yy = pmat->xx;
1047}
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 6673 of file freetype.c.

6683{
6684 /*
6685 * FIXME:
6686 * Call EngTextOut, which does the real work (calling DrvTextOut where
6687 * appropriate)
6688 */
6689
6690 PDC_ATTR pdcattr;
6691 SURFOBJ *psoDest, *psoGlyph;
6692 SURFACE *psurf;
6693 INT glyph_index, i;
6694 FT_Face face;
6695 FT_BitmapGlyph realglyph;
6696 LONGLONG X64, Y64, RealXStart64, RealYStart64, DeltaX64, DeltaY64;
6697 ULONG previous;
6698 RECTL DestRect, MaskRect;
6699 HBITMAP hbmGlyph;
6700 SIZEL glyphSize;
6701 FONTOBJ *FontObj;
6702 PFONTGDI FontGDI;
6703 PTEXTOBJ TextObj = NULL;
6704 EXLATEOBJ exloRGB2Dst, exloDst2RGB;
6705 POINT Start;
6706 PMATRIX pmxWorldToDevice;
6707 FT_Vector delta, vecAscent64, vecDescent64, vec;
6708 LOGFONTW *plf;
6709 BOOL use_kerning, bResult, DoBreak;
6710 FONT_CACHE_ENTRY Cache;
6711 FT_Matrix mat;
6712 BOOL bNoTransform;
6713 DWORD ch0, ch1;
6714 const DWORD del = 0x7f, nbsp = 0xa0; // DEL is ASCII DELETE and nbsp is a non-breaking space
6715 FONTLINK_CHAIN Chain;
6716 SIZE spaceWidth;
6717
6718 /* Check if String is valid */
6719 if (Count > 0xFFFF || (Count > 0 && String == NULL))
6720 {
6722 return FALSE;
6723 }
6724
6725 if (PATH_IsPathOpen(dc->dclevel))
6726 {
6727 return PATH_ExtTextOut(dc,
6728 XStart, YStart,
6729 fuOptions,
6730 lprc,
6731 String, Count,
6732 Dx);
6733 }
6734
6736
6737 if (!dc->dclevel.pSurface)
6738 {
6739 /* Memory DC with no surface selected */
6740 bResult = TRUE;
6741 goto Cleanup;
6742 }
6743
6744 pdcattr = dc->pdcattr;
6745 if (pdcattr->flTextAlign & TA_UPDATECP)
6746 {
6747 Start.x = pdcattr->ptlCurrent.x;
6748 Start.y = pdcattr->ptlCurrent.y;
6749 }
6750 else
6751 {
6752 Start.x = XStart;
6753 Start.y = YStart;
6754 }
6755
6756 IntLPtoDP(dc, &Start, 1);
6757 RealXStart64 = ((LONGLONG)Start.x + dc->ptlDCOrig.x) << 6;
6758 RealYStart64 = ((LONGLONG)Start.y + dc->ptlDCOrig.y) << 6;
6759
6760 MaskRect.left = 0;
6761 MaskRect.top = 0;
6762
6763 psurf = dc->dclevel.pSurface;
6764 psoDest = &psurf->SurfObj;
6765
6766 if (pdcattr->iGraphicsMode == GM_ADVANCED)
6767 pmxWorldToDevice = DC_pmxWorldToDevice(dc);
6768 else
6769 pmxWorldToDevice = (PMATRIX)&gmxWorldToDeviceDefault;
6770
6771 if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
6773
6774 if (lprc && (fuOptions & (ETO_CLIPPED | ETO_OPAQUE)))
6775 {
6776 IntLPtoDP(dc, (POINT*)lprc, 2);
6777 lprc->left += dc->ptlDCOrig.x;
6778 lprc->top += dc->ptlDCOrig.y;
6779 lprc->right += dc->ptlDCOrig.x;
6780 lprc->bottom += dc->ptlDCOrig.y;
6781 }
6782
6783 if (lprc && (fuOptions & ETO_OPAQUE))
6784 {
6786 lprc->left, lprc->top,
6787 lprc->right - lprc->left, lprc->bottom - lprc->top,
6788 &dc->eboBackground.BrushObject);
6789 fuOptions &= ~ETO_OPAQUE;
6790 }
6791 else
6792 {
6793 if (pdcattr->jBkMode == OPAQUE)
6794 {
6795 fuOptions |= ETO_OPAQUE;
6796 }
6797 }
6798
6799 TextObj = RealizeFontInit(pdcattr->hlfntNew);
6800 if (TextObj == NULL)
6801 {
6802 bResult = FALSE;
6803 goto Cleanup;
6804 }
6805
6806 FontObj = TextObj->Font;
6807 ASSERT(FontObj);
6808 FontGDI = ObjToGDI(FontObj, FONT);
6809 ASSERT(FontGDI);
6810
6812 Cache.Hashed.Face = face = FontGDI->SharedFace->Face;
6813
6814 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
6815 Cache.Hashed.lfHeight = plf->lfHeight;
6816 Cache.Hashed.lfWidth = plf->lfWidth;
6817 Cache.Hashed.Aspect.Emu.Bold = EMUBOLD_NEEDED(FontGDI->OriginalWeight, plf->lfWeight);
6818 Cache.Hashed.Aspect.Emu.Italic = (plf->lfItalic && !FontGDI->OriginalItalic);
6819
6822 else
6824
6825 if (!TextIntUpdateSize(dc, TextObj, FontGDI, FALSE))
6826 {
6828 bResult = FALSE;
6829 goto Cleanup;
6830 }
6831
6832 FontLink_Chain_Init(&Chain, TextObj, face);
6833
6834 /* Apply lfEscapement */
6835 if (FT_IS_SCALABLE(face) && plf->lfEscapement != 0)
6837 else
6839
6840 /* Apply the world transformation */
6841 IntMatrixFromMx(&mat, pmxWorldToDevice);
6844
6845 /* Is there no transformation? */
6846 bNoTransform = ((mat.xy == 0) && (mat.yx == 0) &&
6847 (mat.xx == (1 << 16)) && (mat.yy == (1 << 16)));
6848
6849 /* Calculate the ascent point and the descent point */
6850 vecAscent64.x = 0;
6851 vecAscent64.y = (FontGDI->tmAscent << 6);
6852 FT_Vector_Transform(&vecAscent64, &Cache.Hashed.matTransform);
6853 vecDescent64.x = 0;
6854 vecDescent64.y = -(FontGDI->tmDescent << 6);
6855 FT_Vector_Transform(&vecDescent64, &Cache.Hashed.matTransform);
6856
6857 /* Process the vertical alignment and fix the real starting point. */
6858#define VALIGN_MASK (TA_TOP | TA_BASELINE | TA_BOTTOM)
6859 if ((pdcattr->flTextAlign & VALIGN_MASK) == TA_BASELINE)
6860 {
6861 NOTHING;
6862 }
6863 else if ((pdcattr->flTextAlign & VALIGN_MASK) == TA_BOTTOM)
6864 {
6865 RealXStart64 -= vecDescent64.x;
6866 RealYStart64 += vecDescent64.y;
6867 }
6868 else /* TA_TOP */
6869 {
6870 RealXStart64 -= vecAscent64.x;
6871 RealYStart64 += vecAscent64.y;
6872 }
6873#undef VALIGN_MASK
6874
6875 use_kerning = FT_HAS_KERNING(face);
6876
6877 /* Calculate the text width if necessary */
6878 if ((fuOptions & ETO_OPAQUE) || (pdcattr->flTextAlign & (TA_CENTER | TA_RIGHT)))
6879 {
6880 if (!IntGetTextDisposition(&DeltaX64, &DeltaY64, String, Count, Dx, &Cache,
6881 fuOptions, bNoTransform, &Chain))
6882 {
6884 bResult = FALSE;
6885 goto Cleanup;
6886 }
6887
6888 /* Adjust the horizontal position by horizontal alignment */
6889 if ((pdcattr->flTextAlign & TA_CENTER) == TA_CENTER)
6890 {
6891 RealXStart64 -= DeltaX64 / 2;
6892 RealYStart64 -= DeltaY64 / 2;
6893 }
6894 else if ((pdcattr->flTextAlign & TA_RIGHT) == TA_RIGHT)
6895 {
6896 RealXStart64 -= DeltaX64;
6897 RealYStart64 -= DeltaY64;
6898 }
6899
6900 /* Fill background */
6901 if (fuOptions & ETO_OPAQUE)
6902 {
6903 INT X0 = (RealXStart64 + vecAscent64.x + 32) >> 6;
6904 INT Y0 = (RealYStart64 - vecAscent64.y + 32) >> 6;
6905 INT DX = (DeltaX64 >> 6);
6906 if (Cache.Hashed.matTransform.xy == 0 && Cache.Hashed.matTransform.yx == 0)
6907 {
6908 INT CY = (vecAscent64.y - vecDescent64.y + 32) >> 6;
6909 IntEngFillBox(dc, X0, Y0, DX, CY, &dc->eboBackground.BrushObject);
6910 }
6911 else
6912 {
6913 INT DY = (DeltaY64 >> 6);
6914 INT X1 = ((RealXStart64 + vecDescent64.x + 32) >> 6);
6915 INT Y1 = ((RealYStart64 - vecDescent64.y + 32) >> 6);
6916 POINT Points[4] =
6917 {
6918 { X0, Y0 },
6919 { X0 + DX, Y0 + DY },
6920 { X1 + DX, Y1 + DY },
6921 { X1, Y1 },
6922 };
6923 IntEngFillPolygon(dc, Points, 4, &dc->eboBackground.BrushObject);
6924 }
6925 }
6926 }
6927
6928 EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0);
6929 EXLATEOBJ_vInitialize(&exloDst2RGB, psurf->ppal, &gpalRGB, 0, 0, 0);
6930
6931 if (pdcattr->ulDirty_ & DIRTY_TEXT)
6933
6934 /*
6935 * The main rendering loop.
6936 */
6937 X64 = RealXStart64;
6938 Y64 = RealYStart64;
6939 previous = 0;
6940 DoBreak = FALSE;
6941 bResult = TRUE; /* Assume success */
6942 for (i = 0; i < Count; ++i)
6943 {
6944 ch0 = *String++;
6945 if (IS_HIGH_SURROGATE(ch0))
6946 {
6947 ++i;
6948 if (i >= Count)
6949 break;
6950
6951 ch1 = *String++;
6952 if (IS_LOW_SURROGATE(ch1))
6953 ch0 = Utf32FromSurrogatePair(ch0, ch1);
6954 }
6955
6956 glyph_index = FontLink_Chain_FindGlyph(&Chain, &Cache, &face, ch0,
6957 (fuOptions & ETO_GLYPH_INDEX));
6958 Cache.Hashed.GlyphIndex = glyph_index;
6959
6960 realglyph = IntGetRealGlyph(&Cache);
6961 if (!realglyph)
6962 {
6963 bResult = FALSE;
6964 break;
6965 }
6966
6967 /* retrieve kerning distance and move pen position */
6968 if (use_kerning && previous && glyph_index && NULL == Dx)
6969 {
6970 FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
6971 X64 += delta.x;
6972 Y64 -= delta.y;
6973 }
6974
6975 DPRINT("X64, Y64: %I64d, %I64d\n", X64, Y64);
6976 DPRINT("Advance: %d, %d\n", realglyph->root.advance.x, realglyph->root.advance.y);
6977
6978 glyphSize.cx = realglyph->bitmap.width;
6979 glyphSize.cy = realglyph->bitmap.rows;
6980
6981 /* Do chars > space & not DEL & not nbsp have a glyphSize.cx of zero? */
6982 if (ch0 > L' ' && ch0 != del && ch0 != nbsp && glyphSize.cx == 0)
6983 {
6984 DPRINT1("WARNING: family_name '%s' WChar 0x%04x has a glyphSize.cx of zero\n",
6985 face->family_name, ch0);
6986 }
6987
6988 /* Don't ignore spaces or non-breaking spaces when computing offset.
6989 * This completes the fix of CORE-11787. */
6990 if ((pdcattr->flTextAlign & TA_UPDATECP) && glyphSize.cx == 0 &&
6991 (ch0 == L' ' || ch0 == nbsp)) // Space chars needing x-dim widths
6992 {
6994 /* Get the width of the space character */
6995 TextIntGetTextExtentPoint(dc, TextObj, L" ", 1, 0, NULL, NULL, &spaceWidth, 0);
6997 glyphSize.cx = spaceWidth.cx;
6998 realglyph->left = 0;
6999 }
7000
7001 MaskRect.right = realglyph->bitmap.width;
7002 MaskRect.bottom = realglyph->bitmap.rows;
7003
7004 DestRect.left = ((X64 + 32) >> 6) + realglyph->left;
7005 DestRect.right = DestRect.left + glyphSize.cx;
7006 DestRect.top = ((Y64 + 32) >> 6) - realglyph->top;
7007 DestRect.bottom = DestRect.top + glyphSize.cy;
7008
7009 /* Check if the bitmap has any pixels */
7010 if ((glyphSize.cx != 0) && (glyphSize.cy != 0))
7011 {
7012 /*
7013 * We should create the bitmap out of the loop at the biggest possible
7014 * glyph size. Then use memset with 0 to clear it and sourcerect to
7015 * limit the work of the transbitblt.
7016 */
7017 hbmGlyph = EngCreateBitmap(glyphSize, realglyph->bitmap.pitch,
7019 realglyph->bitmap.buffer);
7020 if (!hbmGlyph)
7021 {
7022 DPRINT1("WARNING: EngCreateBitmap() failed!\n");
7023 bResult = FALSE;
7024 break;
7025 }
7026
7027 psoGlyph = EngLockSurface((HSURF)hbmGlyph);
7028 if (!psoGlyph)
7029 {
7030 EngDeleteSurface((HSURF)hbmGlyph);
7031 DPRINT1("WARNING: EngLockSurface() failed!\n");
7032 bResult = FALSE;
7033 break;
7034 }
7035
7036 /*
7037 * Use the font data as a mask to paint onto the DCs surface using a
7038 * brush.
7039 */
7040 if (lprc && (fuOptions & ETO_CLIPPED))
7041 {
7042 // We do the check '>=' instead of '>' to possibly save an iteration
7043 // through this loop, since it's breaking after the drawing is done,
7044 // and x is always incremented.
7045 if (DestRect.right >= lprc->right)
7046 {
7047 DestRect.right = lprc->right;
7048 DoBreak = TRUE;
7049 }
7050
7051 if (DestRect.bottom >= lprc->bottom)
7052 {
7053 DestRect.bottom = lprc->bottom;
7054 }
7055 }
7056
7057 if (!IntEngMaskBlt(psoDest,
7058 psoGlyph,
7059 (CLIPOBJ *)&dc->co,
7060 &exloRGB2Dst.xlo,
7061 &exloDst2RGB.xlo,
7062 &DestRect,
7063 (PPOINTL)&MaskRect,
7064 &dc->eboText.BrushObject,
7065 &g_PointZero))
7066 {
7067 DPRINT1("Failed to MaskBlt a glyph!\n");
7068 }
7069
7070 EngUnlockSurface(psoGlyph);
7071 EngDeleteSurface((HSURF)hbmGlyph);
7072 }
7073
7074 if (DoBreak)
7075 break;
7076
7077 if (NULL == Dx)
7078 {
7079 X64 += realglyph->root.advance.x >> 10;
7080 Y64 -= realglyph->root.advance.y >> 10;
7081 }
7082 else if (fuOptions & ETO_PDY)
7083 {
7084 vec.x = (Dx[2 * i + 0] << 6);
7085 vec.y = (Dx[2 * i + 1] << 6);
7086 if (!bNoTransform)
7088 X64 += vec.x;
7089 Y64 -= vec.y;
7090 }
7091 else
7092 {
7093 vec.x = (Dx[i] << 6);
7094 vec.y = 0;
7095 if (!bNoTransform)
7097 X64 += vec.x;
7098 Y64 -= vec.y;
7099 }
7100
7101 DPRINT("New X64, New Y64: %I64d, %I64d\n", X64, Y64);
7102
7103 previous = glyph_index;
7104 }
7105 /* Don't update position if String == NULL. Fixes CORE-19721. */
7106 if ((pdcattr->flTextAlign & TA_UPDATECP) && String)
7107 pdcattr->ptlCurrent.x = DestRect.right - dc->ptlDCOrig.x;
7108
7109 if (plf->lfUnderline || plf->lfStrikeOut) /* Underline or strike-out? */
7110 {
7111 /* Calculate the position and the thickness */
7112 INT underline_position, thickness;
7113 FT_Vector vecA64, vecB64;
7114
7115 DeltaX64 = X64 - RealXStart64;
7116 DeltaY64 = Y64 - RealYStart64;
7117
7118 if (!face->units_per_EM)
7119 {
7121 thickness = 1;
7122 }
7123 else
7124 {
7126 face->underline_position * face->size->metrics.y_ppem / face->units_per_EM;
7127 thickness =
7128 face->underline_thickness * face->size->metrics.y_ppem / face->units_per_EM;
7129 if (thickness <= 0)
7130 thickness = 1;
7131 }
7132
7133 if (plf->lfUnderline) /* Draw underline */
7134 {
7135 vecA64.x = 0;
7136 vecA64.y = (-underline_position - thickness / 2) << 6;
7137 vecB64.x = 0;
7138 vecB64.y = vecA64.y + (thickness << 6);
7139 FT_Vector_Transform(&vecA64, &Cache.Hashed.matTransform);
7140 FT_Vector_Transform(&vecB64, &Cache.Hashed.matTransform);
7141 {
7142 INT X0 = (RealXStart64 - vecA64.x + 32) >> 6;
7143 INT Y0 = (RealYStart64 + vecA64.y + 32) >> 6;
7144 INT DX = (DeltaX64 >> 6);
7145 if (Cache.Hashed.matTransform.xy == 0 && Cache.Hashed.matTransform.yx == 0)
7146 {
7147 INT CY = (vecB64.y - vecA64.y + 32) >> 6;
7148 IntEngFillBox(dc, X0, Y0, DX, CY, &dc->eboText.BrushObject);
7149 }
7150 else
7151 {
7152 INT DY = (DeltaY64 >> 6);
7153 INT X1 = X0 + ((vecA64.x - vecB64.x + 32) >> 6);
7154 INT Y1 = Y0 + ((vecB64.y - vecA64.y + 32) >> 6);
7155 POINT Points[4] =
7156 {
7157 { X0, Y0 },
7158 { X0 + DX, Y0 + DY },
7159 { X1 + DX, Y1 + DY },
7160 { X1, Y1 },
7161 };
7162 IntEngFillPolygon(dc, Points, 4, &dc->eboText.BrushObject);
7163 }
7164 }
7165 }
7166
7167 if (plf->lfStrikeOut) /* Draw strike-out */
7168 {
7169 vecA64.x = 0;
7170 vecA64.y = -(FontGDI->tmAscent << 6) / 3;
7171 vecB64.x = 0;
7172 vecB64.y = vecA64.y + (thickness << 6);
7173 FT_Vector_Transform(&vecA64, &Cache.Hashed.matTransform);
7174 FT_Vector_Transform(&vecB64, &Cache.Hashed.matTransform);
7175 {
7176 INT X0 = (RealXStart64 - vecA64.x + 32) >> 6;
7177 INT Y0 = (RealYStart64 + vecA64.y + 32) >> 6;
7178 INT DX = (DeltaX64 >> 6);
7179 if (Cache.Hashed.matTransform.xy == 0 && Cache.Hashed.matTransform.yx == 0)
7180 {
7181 INT CY = (vecB64.y - vecA64.y + 32) >> 6;
7182 IntEngFillBox(dc, X0, Y0, DX, CY, &dc->eboText.BrushObject);
7183 }
7184 else
7185 {
7186 INT DY = (DeltaY64 >> 6);
7187 INT X1 = X0 + ((vecA64.x - vecB64.x + 32) >> 6);
7188 INT Y1 = Y0 + ((vecB64.y - vecA64.y + 32) >> 6);
7189 POINT Points[4] =
7190 {
7191 { X0, Y0 },
7192 { X0 + DX, Y0 + DY },
7193 { X1 + DX, Y1 + DY },
7194 { X1, Y1 },
7195 };
7196 IntEngFillPolygon(dc, Points, 4, &dc->eboText.BrushObject);
7197 }
7198 }
7199 }
7200 }
7201
7203
7204 EXLATEOBJ_vCleanup(&exloRGB2Dst);
7205 EXLATEOBJ_vCleanup(&exloDst2RGB);
7206
7207Cleanup:
7209
7210 if (TextObj != NULL)
7211 TEXTOBJ_UnlockText(TextObj);
7212
7213 return bResult;
7214}
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:4972
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:4382
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:6587
#define EMUBOLD_NEEDED(original, request)
Definition: freetype.c:196
static FT_BitmapGlyph IntGetRealGlyph(IN OUT PFONT_CACHE_ENTRY Cache)
Definition: freetype.c:4932
#define VALIGN_MASK
BOOL FASTCALL IntIsFontRenderingEnabled(VOID)
Definition: freetype.c:2579
#define gmxWorldToDeviceDefault
Definition: freetype.c:204
static VOID FontLink_Chain_Init(_Out_ PFONTLINK_CHAIN pChain, _Inout_ PTEXTOBJ pTextObj, _In_ FT_Face face)
Definition: freetype.c:1176
FT_Render_Mode FASTCALL IntGetFontRenderMode(LOGFONTW *logfont)
Definition: freetype.c:2591
@ 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
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
WORD RenderMode
Definition: font.h:37
struct _FONT_ASPECT::@5453::@5454 Emu
FONT_CACHE_HASHED Hashed
Definition: font.h:60
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
FONT_ASPECT Aspect
Definition: font.h:48
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 3659 of file freetype.c.

3660{
3661 PLIST_ENTRY CurrentEntry;
3662 PFONT_CACHE_ENTRY FontEntry;
3663 DWORD dwHash = pCache->dwHash;
3664
3666
3667 for (CurrentEntry = g_FontCacheListHead.Flink;
3668 CurrentEntry != &g_FontCacheListHead;
3669 CurrentEntry = CurrentEntry->Flink)
3670 {
3671 FontEntry = CONTAINING_RECORD(CurrentEntry, FONT_CACHE_ENTRY, ListEntry);
3672 if (FontEntry->dwHash == dwHash &&
3673 FontEntry->Hashed.GlyphIndex == pCache->Hashed.GlyphIndex &&
3674 FontEntry->Hashed.Face == pCache->Hashed.Face &&
3675 FontEntry->Hashed.lfHeight == pCache->Hashed.lfHeight &&
3676 FontEntry->Hashed.lfWidth == pCache->Hashed.lfWidth &&
3677 FontEntry->Hashed.AspectValue == pCache->Hashed.AspectValue &&
3678 memcmp(&FontEntry->Hashed.matTransform, &pCache->Hashed.matTransform,
3679 sizeof(FT_Matrix)) == 0)
3680 {
3681 break;
3682 }
3683 }
3684
3685 if (CurrentEntry == &g_FontCacheListHead)
3686 {
3687 return NULL;
3688 }
3689
3690 RemoveEntryList(CurrentEntry);
3691 InsertHeadList(&g_FontCacheListHead, CurrentEntry);
3692 return FontEntry->BitmapGlyph;
3693}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
FT_BitmapGlyph BitmapGlyph
Definition: font.h:58
DWORD dwHash
Definition: font.h:59
DWORD AspectValue
Definition: font.h:47

Referenced by IntGetRealGlyph().

◆ IntFontType()

static VOID FASTCALL IntFontType ( PFONTGDI  Font)
static

Definition at line 5834 of file freetype.c.

5835{
5836 PS_FontInfoRec psfInfo;
5837 FT_ULong tmp_size = 0;
5838 FT_Face Face = Font->SharedFace->Face;
5839
5841
5842 if (FT_HAS_MULTIPLE_MASTERS(Face))
5843 Font->FontObj.flFontType |= FO_MULTIPLEMASTER;
5844 if (FT_HAS_VERTICAL(Face))
5845 Font->FontObj.flFontType |= FO_VERT_FACE;
5846 if (!FT_IS_SCALABLE(Face))
5847 Font->FontObj.flFontType |= FO_TYPE_RASTER;
5848 if (FT_IS_SFNT(Face))
5849 {
5850 Font->FontObj.flFontType |= FO_TYPE_TRUETYPE;
5852 Font->FontObj.flFontType |= FO_POSTSCRIPT;
5853 }
5854 if (!FT_Get_PS_Font_Info(Face, &psfInfo ))
5855 {
5856 Font->FontObj.flFontType |= FO_POSTSCRIPT;
5857 }
5858 /* Check for the presence of the 'CFF ' table to check if the font is Type1 */
5859 if (!FT_Load_Sfnt_Table(Face, TTAG_CFF, 0, NULL, &tmp_size))
5860 {
5861 Font->FontObj.flFontType |= (FO_CFF|FO_POSTSCRIPT);
5862 }
5863}
#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 TextIntRealizeFont().

◆ IntFreeFontNames()

static __inline void FASTCALL IntFreeFontNames ( FONT_NAMES Names)
static

Definition at line 3005 of file freetype.c.

3006{
3007 RtlFreeUnicodeString(&Names->FamilyNameW);
3008 RtlFreeUnicodeString(&Names->FaceNameW);
3009 RtlFreeUnicodeString(&Names->StyleNameW);
3010 RtlFreeUnicodeString(&Names->FullNameW);
3011}
PWSTR Names[]

Referenced by IntGetOutlineTextMetrics().

◆ IntGdiAddFontMemResource()

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

Definition at line 2407 of file freetype.c.

2408{
2409 HANDLE Ret = NULL;
2411 PFONT_ENTRY_COLL_MEM EntryCollection;
2412 INT FaceCount;
2413
2415 if (!BufferCopy)
2416 {
2417 *pNumAdded = 0;
2418 return NULL;
2419 }
2420 RtlCopyMemory(BufferCopy, Buffer, dwSize);
2421
2422 RtlZeroMemory(&LoadFont, sizeof(LoadFont));
2423 LoadFont.Memory = SharedMem_Create(BufferCopy, dwSize, FALSE);
2424 LoadFont.Characteristics = FR_PRIVATE | FR_NOT_ENUM;
2425 RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
2427
2428 RtlFreeUnicodeString(&LoadFont.RegValueName);
2429
2430 /* Release our copy */
2434
2435 if (FaceCount > 0)
2436 {
2437 EntryCollection = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY_COLL_MEM), TAG_FONT);
2438 if (EntryCollection)
2439 {
2441 EntryCollection->Entry = LoadFont.PrivateEntry;
2443 IntLockProcessPrivateFonts(Win32Process);
2444 EntryCollection->Handle = ULongToHandle(++Win32Process->PrivateMemFontHandleCount);
2445 InsertTailList(&Win32Process->PrivateMemFontListHead, &EntryCollection->ListEntry);
2446 IntUnLockProcessPrivateFonts(Win32Process);
2448 Ret = EntryCollection->Handle;
2449 }
2450 }
2451 *pNumAdded = FaceCount;
2452
2453 return Ret;
2454}
#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:1823
static PSHARED_MEM SharedMem_Create(PBYTE Buffer, ULONG BufferSize, BOOL IsMapping)
Definition: freetype.c:438
static void SharedMem_Release(PSHARED_MEM Ptr)
Definition: freetype.c:495
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 2076 of file freetype.c.

2081{
2082 PWSTR pchFile = FileName->Buffer;
2083 SIZE_T cchFile;
2084 INT ret = 0;
2085
2086 while (cFiles--)
2087 {
2088 _SEH2_TRY
2089 {
2090 cchFile = wcslen(pchFile);
2091 }
2093 {
2094 _SEH2_YIELD(return FALSE);
2095 }
2096 _SEH2_END;
2097
2098 UNICODE_STRING ustrPathName;
2099 ustrPathName.Length = (USHORT)(cchFile * sizeof(WCHAR));
2100 ustrPathName.MaximumLength = ustrPathName.Length + sizeof(WCHAR);
2101 ustrPathName.Buffer = pchFile;
2102
2103 INT count = IntGdiAddFontResourceSingle(&ustrPathName, Characteristics, dwFlags);
2104 if (!count)
2105 return 0;
2106 ret += count;
2107
2108 pchFile += cchFile + 1;
2109 }
2110
2111 return ret;
2112}
static INT FASTCALL IntGdiAddFontResourceSingle(_In_ PCUNICODE_STRING FileName, _In_ DWORD Characteristics, _In_ DWORD dwFlags)
Definition: freetype.c:1877
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:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
uint16_t * PWSTR
Definition: typedefs.h:56

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 1877 of file freetype.c.

1881{
1884 PVOID Buffer = NULL;
1887 SIZE_T ViewSize = 0, Length;
1888 LARGE_INTEGER SectionSize;
1891 INT FontCount;
1893 UNICODE_STRING PathName;
1894 LPWSTR pszBuffer;
1896 static const UNICODE_STRING TrueTypePostfix = RTL_CONSTANT_STRING(L" (TrueType)");
1897
1898 /* Build PathName */
1900 {
1901 Length = DosPathPrefix.Length + FileName->Length + sizeof(UNICODE_NULL);
1903 if (!pszBuffer)
1904 return 0; /* failure */
1905
1906 RtlInitEmptyUnicodeString(&PathName, pszBuffer, Length);
1909 }
1910 else
1911 {
1913 if (!NT_SUCCESS(Status))
1914 return 0; /* failure */
1915 }
1916
1917 /* Open the font file */
1921 &FileHandle,
1924 &Iosb,
1927 if (!NT_SUCCESS(Status))
1928 {
1929 DPRINT1("Could not load font file: %wZ\n", &PathName);
1930 RtlFreeUnicodeString(&PathName);
1931 return 0;
1932 }
1933
1936 if (!NT_SUCCESS(Status))
1937 {
1938 DPRINT1("ObReferenceObjectByHandle failed.\n");
1940 RtlFreeUnicodeString(&PathName);
1941 return 0;
1942 }
1943
1944 SectionSize.QuadPart = 0LL;
1947 NULL, &SectionSize, PAGE_READONLY,
1949 if (!NT_SUCCESS(Status))
1950 {
1951 DPRINT1("Could not map file: %wZ\n", &PathName);
1954 RtlFreeUnicodeString(&PathName);
1955 return 0;
1956 }
1958
1960 if (!NT_SUCCESS(Status))
1961 {
1962 DPRINT1("Could not map file: %wZ\n", &PathName);
1965 RtlFreeUnicodeString(&PathName);
1966 return 0;
1967 }
1968
1969 RtlZeroMemory(&LoadFont, sizeof(LoadFont));
1970 LoadFont.pFileName = &PathName;
1972 LoadFont.Characteristics = Characteristics;
1973 RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
1974 LoadFont.CharSet = DEFAULT_CHARSET;
1975 FontCount = IntGdiLoadFontByIndexFromMemory(&LoadFont, -1);
1976
1977 /* Release our copy */
1981
1983
1985
1986 /* Save the loaded font name into the registry */
1987 if (FontCount > 0 && (dwFlags & AFRX_WRITE_REGISTRY))
1988 {
1989 UNICODE_STRING NewString;
1990 SIZE_T Length;
1991 PWCHAR pszBuffer;
1992 LPCWSTR CharSetName;
1993 if (LoadFont.IsTrueType)
1994 {
1995 /* Append " (TrueType)" */
1996 Length = LoadFont.RegValueName.Length + TrueTypePostfix.Length + sizeof(UNICODE_NULL);
1998 if (pszBuffer)
1999 {
2000 RtlInitEmptyUnicodeString(&NewString, pszBuffer, Length);
2001 NewString.Buffer[0] = UNICODE_NULL;
2002 RtlAppendUnicodeStringToString(&NewString, &LoadFont.RegValueName);
2003 RtlAppendUnicodeStringToString(&NewString, &TrueTypePostfix);
2004 RtlFreeUnicodeString(&LoadFont.RegValueName);
2005 LoadFont.RegValueName = NewString;
2006 }
2007 else
2008 {
2009 // FIXME!
2010 }
2011 }
2012 else if (LoadFont.CharSet != DEFAULT_CHARSET)
2013 {
2014 /* Append " (CharSetName)" */
2015 CharSetName = IntNameFromCharSet(LoadFont.CharSet);
2016 Length = LoadFont.RegValueName.Length +
2017 (wcslen(CharSetName) + 3) * sizeof(WCHAR) +
2018 sizeof(UNICODE_NULL);
2019
2021 if (pszBuffer)
2022 {
2023 RtlInitEmptyUnicodeString(&NewString, pszBuffer, Length);
2024 NewString.Buffer[0] = UNICODE_NULL;
2025 RtlAppendUnicodeStringToString(&NewString, &LoadFont.RegValueName);
2026 RtlAppendUnicodeToString(&NewString, L" (");
2027 RtlAppendUnicodeToString(&NewString, CharSetName);
2028 RtlAppendUnicodeToString(&NewString, L")");
2029 RtlFreeUnicodeString(&LoadFont.RegValueName);
2030 LoadFont.RegValueName = NewString;
2031 }
2032 else
2033 {
2034 // FIXME!
2035 }
2036 }
2037
2040 NULL, NULL);
2041 Status = ZwOpenKey(&KeyHandle, KEY_WRITE, &ObjectAttributes);
2042 if (NT_SUCCESS(Status))
2043 {
2045 LPWSTR pFileName;
2046
2048 {
2049 pFileName = PathName.Buffer;
2050 }
2051 else
2052 {
2053 pFileName = wcsrchr(PathName.Buffer, L'\\');
2054 }
2055
2056 if (pFileName)
2057 {
2059 {
2060 pFileName++;
2061 }
2062 DataSize = (wcslen(pFileName) + 1) * sizeof(WCHAR);
2063 ZwSetValueKey(KeyHandle, &LoadFont.RegValueName, 0, REG_SZ,
2064 pFileName, DataSize);
2065 }
2067 }
2068 }
2069 RtlFreeUnicodeString(&LoadFont.RegValueName);
2070
2071 RtlFreeUnicodeString(&PathName);
2072 return FontCount;
2073}
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:1873
#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
const uint16_t * LPCWSTR
Definition: typedefs.h:57
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

Referenced by IntGdiAddFontResourceEx().

◆ IntGdiCleanupMemEntry()

VOID FASTCALL IntGdiCleanupMemEntry ( PFONT_ENTRY_MEM  Head)

Definition at line 2457 of file freetype.c.

2458{
2460 PFONT_ENTRY_MEM FontEntry;
2461
2462 while (!IsListEmpty(&Head->ListEntry))
2463 {
2464 Entry = RemoveHeadList(&Head->ListEntry);
2465 FontEntry = CONTAINING_RECORD(Entry, FONT_ENTRY_MEM, ListEntry);
2466
2467 CleanupFontEntry(FontEntry->Entry);
2468 ExFreePoolWithTag(FontEntry, TAG_FONT);
2469 }
2470
2471 CleanupFontEntry(Head->Entry);
2473}
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 2529 of file freetype.c.

2530{
2533 PFONT_ENTRY_COLL_MEM EntryCollection;
2534
2535 DPRINT("IntGdiCleanupPrivateFontsForProcess()\n");
2536 do {
2537 Entry = NULL;
2538 EntryCollection = NULL;
2539
2541 IntLockProcessPrivateFonts(Win32Process);
2542 if (!IsListEmpty(&Win32Process->PrivateMemFontListHead))
2543 {
2544 Entry = Win32Process->PrivateMemFontListHead.Flink;
2545 EntryCollection = CONTAINING_RECORD(Entry, FONT_ENTRY_COLL_MEM, ListEntry);
2546 UnlinkFontMemCollection(EntryCollection);
2547 }
2548 IntUnLockProcessPrivateFonts(Win32Process);
2550
2551 if (EntryCollection)
2552 {
2553 IntGdiCleanupMemEntry(EntryCollection->Entry);
2554 ExFreePoolWithTag(EntryCollection, TAG_FONT);
2555 }
2556 else
2557 {
2558 /* No Mem fonts anymore, see if we have any other private fonts left */
2559 Entry = NULL;
2561 IntLockProcessPrivateFonts(Win32Process);
2562 if (!IsListEmpty(&Win32Process->PrivateFontListHead))
2563 {
2564 Entry = RemoveHeadList(&Win32Process->PrivateFontListHead);
2565 }
2566 IntUnLockProcessPrivateFonts(Win32Process);
2568
2569 if (Entry)
2570 {
2572 }
2573 }
2574
2575 } while (Entry);
2576}
VOID FASTCALL IntGdiCleanupMemEntry(PFONT_ENTRY_MEM Head)
Definition: freetype.c:2457
static VOID FASTCALL UnlinkFontMemCollection(PFONT_ENTRY_COLL_MEM Collection)
Definition: freetype.c:2476

Referenced by GdiProcessDestroy().

◆ IntGdiGetFontResourceInfo()

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

Definition at line 6108 of file freetype.c.

6113{
6114 UNICODE_STRING EntryFileName;
6115 POBJECT_NAME_INFORMATION NameInfo1 = NULL, NameInfo2 = NULL;
6116 PLIST_ENTRY ListEntry;
6117 PFONT_ENTRY FontEntry;
6118 ULONG Size, i, Count;
6119 LPBYTE pbBuffer;
6120 BOOL IsEqual;
6121 FONTFAMILYINFO *FamInfo;
6122 const ULONG MaxFamInfo = 64;
6123 const ULONG MAX_FAM_INFO_BYTES = sizeof(FONTFAMILYINFO) * MaxFamInfo;
6124 BOOL bSuccess;
6125 const ULONG NAMEINFO_SIZE = sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR);
6126
6127 DPRINT("IntGdiGetFontResourceInfo: dwType == %lu\n", dwType);
6128
6129 do
6130 {
6131 /* Create buffer for full path name */
6132 NameInfo1 = ExAllocatePoolWithTag(PagedPool, NAMEINFO_SIZE, TAG_FINF);
6133 if (!NameInfo1)
6134 break;
6135
6136 /* Get the full path name */
6137 if (!IntGetFullFileName(NameInfo1, NAMEINFO_SIZE, FileName))
6138 break;
6139
6140 /* Create a buffer for the entries' names */
6141 NameInfo2 = ExAllocatePoolWithTag(PagedPool, NAMEINFO_SIZE, TAG_FINF);
6142 if (!NameInfo2)
6143 break;
6144
6145 FamInfo = ExAllocatePoolWithTag(PagedPool, MAX_FAM_INFO_BYTES, TAG_FINF);
6146 } while (0);
6147
6148 if (!NameInfo1 || !NameInfo2 || !FamInfo)
6149 {
6150 if (NameInfo2)
6151 ExFreePoolWithTag(NameInfo2, TAG_FINF);
6152
6153 if (NameInfo1)
6154 ExFreePoolWithTag(NameInfo1, TAG_FINF);
6155
6157 return FALSE;
6158 }
6159
6160 Count = 0;
6161
6162 /* Try to find the pathname in the global font list */
6164 for (ListEntry = g_FontListHead.Flink; ListEntry != &g_FontListHead;
6165 ListEntry = ListEntry->Flink)
6166 {
6167 FontEntry = CONTAINING_RECORD(ListEntry, FONT_ENTRY, ListEntry);
6168 if (FontEntry->Font->Filename == NULL)
6169 continue;
6170
6171 RtlInitUnicodeString(&EntryFileName , FontEntry->Font->Filename);
6172 if (!IntGetFullFileName(NameInfo2, NAMEINFO_SIZE, &EntryFileName))
6173 continue;
6174
6175 if (!RtlEqualUnicodeString(&NameInfo1->Name, &NameInfo2->Name, FALSE))
6176 continue;
6177
6178 IsEqual = FALSE;
6179 FontFamilyFillInfo(&FamInfo[Count], FontEntry->FaceName.Buffer,
6180 NULL, FontEntry->Font);
6181 for (i = 0; i < Count; ++i)
6182 {
6183 if (EqualFamilyInfo(&FamInfo[i], &FamInfo[Count]))
6184 {
6185 IsEqual = TRUE;
6186 break;
6187 }
6188 }
6189 if (!IsEqual)
6190 {
6191 /* Found */
6192 ++Count;
6193 if (Count >= MaxFamInfo)
6194 break;
6195 }
6196 }
6198
6199 /* Free the buffers */
6200 ExFreePoolWithTag(NameInfo1, TAG_FINF);
6201 ExFreePoolWithTag(NameInfo2, TAG_FINF);
6202
6203 if (Count == 0 && dwType != 5)
6204 {
6205 /* Font could not be found in system table
6206 dwType == 5 will still handle this */
6207 ExFreePoolWithTag(FamInfo, TAG_FINF);
6208 return FALSE;
6209 }
6210
6211 bSuccess = FALSE;
6212 switch (dwType)
6213 {
6214 case 0: /* FIXME: Returns 1 or 2, don't know what this is atm */
6215 Size = sizeof(DWORD);
6216 if (*pdwBytes == 0)
6217 {
6218 *pdwBytes = Size;
6219 bSuccess = TRUE;
6220 }
6221 else if (pBuffer)
6222 {
6223 if (*pdwBytes >= Size)
6224 {
6225 *(DWORD*)pBuffer = Count;
6226 }
6227 *pdwBytes = Size;
6228 bSuccess = TRUE;
6229 }
6230 break;
6231
6232 case 1: /* copy the font title */
6233 /* calculate the required size */
6234 Size = 0;
6235 for (i = 0; i < Count; ++i)
6236 {
6237 if (i > 0)
6238 Size += 3; /* " & " */
6239 Size += wcslen(FamInfo[i].EnumLogFontEx.elfLogFont.lfFaceName);
6240 if (FamInfo[i].EnumLogFontEx.elfStyle[0] &&
6241 _wcsicmp(FamInfo[i].EnumLogFontEx.elfStyle, L"Regular") != 0)
6242 {
6243 Size += 1 + wcslen(FamInfo[i].EnumLogFontEx.elfStyle);
6244 }
6245 }
6246 Size += 2; /* "\0\0" */
6247 Size *= sizeof(WCHAR);
6248
6249 if (*pdwBytes == 0)
6250 {
6251 *pdwBytes = Size;
6252 bSuccess = TRUE;
6253 }
6254 else if (pBuffer)
6255 {
6256 if (*pdwBytes >= Size)
6257 {
6258 /* store font title to buffer */
6259 WCHAR *psz = pBuffer;
6260 *psz = 0;
6261 for (i = 0; i < Count; ++i)
6262 {
6263 if (i > 0)
6264 wcscat(psz, L" & ");
6265 IntAddNameFromFamInfo(psz, &FamInfo[i]);
6266 }
6267 psz[wcslen(psz) + 1] = UNICODE_NULL;
6268 *pdwBytes = Size;
6269 bSuccess = TRUE;
6270 }
6271 else
6272 {
6273 *pdwBytes = 1024; /* this is confirmed value */
6274 }
6275 }
6276 break;
6277
6278 case 2: /* Copy an array of LOGFONTW */
6279 Size = Count * sizeof(LOGFONTW);
6280 if (*pdwBytes == 0)
6281 {
6282 *pdwBytes = Size;
6283 bSuccess = TRUE;
6284 }
6285 else if (pBuffer)
6286 {
6287 if (*pdwBytes >= Size)
6288 {
6289 pbBuffer = (LPBYTE)pBuffer;
6290 for (i = 0; i < Count; ++i)
6291 {
6292 FamInfo[i].EnumLogFontEx.elfLogFont.lfWidth = 0;
6293 RtlCopyMemory(pbBuffer, &FamInfo[i].EnumLogFontEx.elfLogFont, sizeof(LOGFONTW));
6294 pbBuffer += sizeof(LOGFONTW);
6295 }
6296 }
6297 *pdwBytes = Size;
6298 bSuccess = TRUE;
6299 }
6300 else
6301 {
6302 *pdwBytes = 1024; /* this is confirmed value */
6303 }
6304 break;
6305
6306 case 3:
6307 Size = sizeof(DWORD);
6308 if (*pdwBytes == 0)
6309 {
6310 *pdwBytes = Size;
6311 bSuccess = TRUE;
6312 }
6313 else if (pBuffer)
6314 {
6315 if (*pdwBytes >= Size)
6316 {
6317 /* FIXME: What exactly is copied here? */
6318 *(DWORD*)pBuffer = 1;
6319 }
6320 *pdwBytes = Size;
6321 bSuccess = TRUE;
6322 }
6323 break;
6324
6325 case 4: /* full file path */
6326 if (FileName->Length >= 4 * sizeof(WCHAR))
6327 {
6328 /* The beginning of FileName is \??\ */
6329 LPWSTR pch = FileName->Buffer + 4;
6330 DWORD Length = FileName->Length - 4 * sizeof(WCHAR);
6331
6332 Size = Length + sizeof(WCHAR);
6333 if (*pdwBytes == 0)
6334 {
6335 *pdwBytes = Size;
6336 bSuccess = TRUE;
6337 }
6338 else if (pBuffer)
6339 {
6340 if (*pdwBytes >= Size)
6341 {
6343 }
6344 *pdwBytes = Size;
6345 bSuccess = TRUE;
6346 }
6347 }
6348 break;
6349
6350 case 5: /* Looks like a BOOL that is copied, TRUE, if the font was not found */
6351 Size = sizeof(BOOL);
6352 if (*pdwBytes == 0)
6353 {
6354 *pdwBytes = Size;
6355 bSuccess = TRUE;
6356 }
6357 else if (pBuffer)
6358 {
6359 if (*pdwBytes >= Size)
6360 {
6361 *(BOOL*)pBuffer = Count == 0;
6362 }
6363 *pdwBytes = Size;
6364 bSuccess = TRUE;
6365 }
6366 break;
6367 }
6368 ExFreePoolWithTag(FamInfo, TAG_FINF);
6369
6370 return bSuccess;
6371}
@ IsEqual
Definition: fatprocs.h:1887
static BOOL FASTCALL IntGetFullFileName(POBJECT_NAME_INFORMATION NameInfo, ULONG Size, PUNICODE_STRING FileName)
Definition: freetype.c:5917
static BOOL EqualFamilyInfo(const FONTFAMILYINFO *pInfo1, const FONTFAMILYINFO *pInfo2)
Definition: freetype.c:5960
static VOID IntAddNameFromFamInfo(LPWSTR psz, FONTFAMILYINFO *FamInfo)
Definition: freetype.c:5981
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 1823 of file freetype.c.

1824{
1826 FT_Face Face;
1827 FT_Long iFace, num_faces;
1828 PSHARED_FACE SharedFace;
1829 INT FaceCount = 0;
1830
1832
1833 /* Load a face from memory */
1835 pLoadFont->Memory->Buffer, pLoadFont->Memory->BufferSize,
1836 ((FontIndex == -1) ? 0 : FontIndex), &Face);
1837 if (Error)
1838 {
1839 if (Error == FT_Err_Unknown_File_Format)
1840 DPRINT1("Unknown font file format\n");
1841 else
1842 DPRINT1("Error reading font (error code: %d)\n", Error);
1844 return 0; /* Failure */
1845 }
1846
1847 pLoadFont->IsTrueType = FT_IS_SFNT(Face);
1848 num_faces = Face->num_faces;
1849 SharedFace = SharedFace_Create(Face, pLoadFont->Memory);
1850
1852
1853 if (!SharedFace)
1854 {
1855 DPRINT1("SharedFace_Create failed\n");
1857 return 0; /* Failure */
1858 }
1859
1860 if (FontIndex == -1)
1861 {
1862 for (iFace = 1; iFace < num_faces; ++iFace)
1863 {
1865 }
1866 FontIndex = 0;
1867 }
1868
1869 FaceCount += IntGdiLoadFontsFromMemory(pLoadFont, SharedFace, FontIndex, -1);
1870 return FaceCount;
1871}
static PSHARED_FACE SharedFace_Create(FT_Face Face, PSHARED_MEM Memory)
Definition: freetype.c:419
static INT FASTCALL IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont, PSHARED_FACE SharedFace, FT_Long FontIndex, INT CharSetIndex)
Definition: freetype.c:1532
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 1532 of file freetype.c.

1534{
1537 FONT_ENTRY_MEM* PrivateEntry = NULL;
1538 FONTGDI * FontGDI;
1540 FT_Face Face;
1542 FT_WinFNT_HeaderRec WinFNT;
1543 INT FaceCount = 0, CharSetCount = 0;
1544 PUNICODE_STRING pFileName = pLoadFont->pFileName;
1545 DWORD Characteristics = pLoadFont->Characteristics;
1546 PUNICODE_STRING pValueName = &pLoadFont->RegValueName;
1547 TT_OS2 * pOS2;
1548 INT BitIndex;
1549 FT_UShort os2_version;
1550 FT_ULong os2_ulCodePageRange1;
1551 FT_UShort os2_usWeightClass;
1552
1553 ASSERT(SharedFace != NULL);
1554 ASSERT(FontIndex != -1);
1555
1557 Face = SharedFace->Face;
1558 SharedFace_AddRef(SharedFace);
1560
1561 /* allocate a FONT_ENTRY */
1563 if (!Entry)
1564 {
1565 SharedFace_Release(SharedFace, TRUE);
1567 return 0; /* failure */
1568 }
1569
1570 /* allocate a FONTGDI */
1571 FontGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(FONTGDI), GDITAG_RFONT);
1572 if (!FontGDI)
1573 {
1574 SharedFace_Release(SharedFace, TRUE);
1577 return 0; /* failure */
1578 }
1579
1580 /* set file name */
1581 if (pFileName)
1582 {
1584 pFileName->Length + sizeof(UNICODE_NULL),
1585 GDITAG_PFF);
1586 if (FontGDI->Filename == NULL)
1587 {
1588 EngFreeMem(FontGDI);
1589 SharedFace_Release(SharedFace, TRUE);
1592 return 0; /* failure */
1593 }
1594
1595 RtlCopyMemory(FontGDI->Filename, pFileName->Buffer, pFileName->Length);
1596 FontGDI->Filename[pFileName->Length / sizeof(WCHAR)] = UNICODE_NULL;
1597 }
1598 else
1599 {
1600 FontGDI->Filename = NULL;
1601
1602 PrivateEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY_MEM), TAG_FONT);
1603 if (!PrivateEntry)
1604 {
1605 if (FontGDI->Filename)
1607 EngFreeMem(FontGDI);
1608 SharedFace_Release(SharedFace, TRUE);
1611 return 0; /* failure */
1612 }
1613
1614 PrivateEntry->Entry = Entry;
1615 if (pLoadFont->PrivateEntry)
1616 {
1617 InsertTailList(&pLoadFont->PrivateEntry->ListEntry, &PrivateEntry->ListEntry);
1618 }
1619 else
1620 {
1621 InitializeListHead(&PrivateEntry->ListEntry);
1622 pLoadFont->PrivateEntry = PrivateEntry;
1623 }
1624 }
1625
1626 /* set face */
1627 FontGDI->SharedFace = SharedFace;
1628 FontGDI->CharSet = ANSI_CHARSET;
1629 FontGDI->OriginalItalic = FALSE;
1630 FontGDI->RequestItalic = FALSE;
1631 FontGDI->OriginalWeight = FW_DONTCARE;
1632 FontGDI->RequestWeight = FW_NORMAL;
1633
1635 pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
1636 if (pOS2)
1637 {
1638 FontGDI->OriginalItalic = !!(pOS2->fsSelection & 0x1);
1639 FontGDI->OriginalWeight = pOS2->usWeightClass;
1640 }
1641 else
1642 {
1643 Error = FT_Get_WinFNT_Header(Face, &WinFNT);
1644 if (!Error)
1645 {
1646 FontGDI->OriginalItalic = !!WinFNT.italic;
1647 FontGDI->OriginalWeight = WinFNT.weight;
1648 }
1649 }
1651
1654 if (NT_SUCCESS(Status))
1655 {
1656 if (Face->style_name && Face->style_name[0] &&
1657 strcmp(Face->style_name, "Regular") != 0)
1658 {
1661 if (!NT_SUCCESS(Status))
1662 {
1663 RtlFreeUnicodeString(&Entry->FaceName);
1664 }
1665 }
1666 else
1667 {
1668 RtlInitUnicodeString(&Entry->StyleName, NULL);
1669 }
1670 }
1671 if (!NT_SUCCESS(Status))
1672 {
1673 if (PrivateEntry)
1674 {
1675 if (pLoadFont->PrivateEntry == PrivateEntry)
1676 {
1677 pLoadFont->PrivateEntry = NULL;
1678 }
1679 else
1680 {
1681 RemoveEntryList(&PrivateEntry->ListEntry);
1682 }
1683 ExFreePoolWithTag(PrivateEntry, TAG_FONT);
1684 }
1685 if (FontGDI->Filename)
1687 EngFreeMem(FontGDI);
1688 SharedFace_Release(SharedFace, TRUE);
1690 return 0;
1691 }
1692
1693 os2_version = 0;
1695 pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
1696 if (pOS2)
1697 {
1698 os2_version = pOS2->version;
1699 os2_ulCodePageRange1 = pOS2->ulCodePageRange1;
1700 os2_usWeightClass = pOS2->usWeightClass;
1701 }
1703
1704 if (pOS2 && os2_version >= 1)
1705 {
1706 /* get charset and weight from OS/2 header */
1707
1708 /* Make sure we do not use this pointer anymore */
1709 pOS2 = NULL;
1710
1711 for (BitIndex = 0; BitIndex < MAXTCIINDEX; ++BitIndex)
1712 {
1713 if (os2_ulCodePageRange1 & (1 << BitIndex))
1714 {
1715 if (g_FontTci[BitIndex].ciCharset == DEFAULT_CHARSET)
1716 continue;
1717
1718 if ((CharSetIndex == -1 && CharSetCount == 0) ||
1719 CharSetIndex == CharSetCount)
1720 {
1721 FontGDI->CharSet = g_FontTci[BitIndex].ciCharset;
1722 }
1723
1724 ++CharSetCount;
1725 }
1726 }
1727
1728 /* set actual weight */
1729 FontGDI->OriginalWeight = os2_usWeightClass;
1730 }
1731 else
1732 {
1733 /* get charset from WinFNT header */
1735 Error = FT_Get_WinFNT_Header(Face, &WinFNT);
1736 if (!Error)
1737 {
1738 FontGDI->CharSet = WinFNT.charset;
1739 }
1741 }
1742
1743 ++FaceCount;
1744 DPRINT("Font loaded: %s (%s)\n",
1745 Face->family_name ? Face->family_name : "<NULL>",
1746 Face->style_name ? Face->style_name : "<NULL>");
1747 DPRINT("Num glyphs: %d\n", Face->num_glyphs);
1748 DPRINT("CharSet: %d\n", FontGDI->CharSet);
1749
1750 /* Add this font resource to the font table */
1751 Entry->Font = FontGDI;
1752 Entry->NotEnum = (Characteristics & FR_NOT_ENUM);
1753
1755 if (Characteristics & FR_PRIVATE)
1756 {
1757 /* private font */
1759 IntLockProcessPrivateFonts(Win32Process);
1760 InsertTailList(&Win32Process->PrivateFontListHead, &Entry->ListEntry);
1761 IntUnLockProcessPrivateFonts(Win32Process);
1762 }
1763 else
1764 {
1765 /* global font */
1766 InsertTailList(&g_FontListHead, &Entry->ListEntry);
1767 }
1769
1770 if (CharSetIndex == -1)
1771 {
1772 INT i;
1773 USHORT NameLength = Entry->FaceName.Length;
1774
1775 if (Entry->StyleName.Length)
1776 NameLength += Entry->StyleName.Length + sizeof(WCHAR);
1777
1778 if (pLoadFont->RegValueName.Length == 0)
1779 {
1780 pValueName->Length = 0;
1781 pValueName->MaximumLength = NameLength + sizeof(WCHAR);
1783 pValueName->MaximumLength,
1784 TAG_USTR);
1785 pValueName->Buffer[0] = UNICODE_NULL;
1786 RtlAppendUnicodeStringToString(pValueName, &Entry->FaceName);
1787 }
1788 else
1789 {
1790 UNICODE_STRING NewString;
1791 USHORT Length = pValueName->Length + 3 * sizeof(WCHAR) + NameLength;
1792 NewString.Length = 0;
1793 NewString.MaximumLength = Length + sizeof(WCHAR);
1795 NewString.MaximumLength,
1796 TAG_USTR);
1797 NewString.Buffer[0] = UNICODE_NULL;
1798
1799 RtlAppendUnicodeStringToString(&NewString, pValueName);
1800 RtlAppendUnicodeToString(&NewString, L" & ");
1801 RtlAppendUnicodeStringToString(&NewString, &Entry->FaceName);
1802
1803 RtlFreeUnicodeString(pValueName);
1804 *pValueName = NewString;
1805 }
1806 if (Entry->StyleName.Length)
1807 {
1808 RtlAppendUnicodeToString(pValueName, L" ");
1809 RtlAppendUnicodeStringToString(pValueName, &Entry->StyleName);
1810 }
1811
1812 for (i = 1; i < CharSetCount; ++i)
1813 {
1814 /* Do not count charsets as loaded 'faces' */
1815 IntGdiLoadFontsFromMemory(pLoadFont, SharedFace, FontIndex, i);
1816 }
1817 }
1818
1819 return FaceCount; /* Number of loaded faces */
1820}
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
@ AnsiString
Definition: dnslib.h:19
static void SharedFace_AddRef(PSHARED_FACE Ptr)
Definition: freetype.c:454
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_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 2493 of file freetype.c.

2494{
2496 PFONT_ENTRY_COLL_MEM CurrentEntry;
2497 PFONT_ENTRY_COLL_MEM EntryCollection = NULL;
2499
2501 IntLockProcessPrivateFonts(Win32Process);
2502 for (Entry = Win32Process->PrivateMemFontListHead.Flink;
2503 Entry != &Win32Process->PrivateMemFontListHead;
2504 Entry = Entry->Flink)
2505 {
2506 CurrentEntry = CONTAINING_RECORD(Entry, FONT_ENTRY_COLL_MEM, ListEntry);
2507
2508 if (CurrentEntry->Handle == hMMFont)
2509 {
2510 EntryCollection = CurrentEntry;
2511 UnlinkFontMemCollection(CurrentEntry);
2512 break;
2513 }
2514 }
2515 IntUnLockProcessPrivateFonts(Win32Process);
2517
2518 if (EntryCollection)
2519 {
2520 IntGdiCleanupMemEntry(EntryCollection->Entry);
2521 ExFreePoolWithTag(EntryCollection, TAG_FONT);
2522 return TRUE;
2523 }
2524 return FALSE;
2525}

Referenced by NtGdiRemoveFontMemResourceEx().

◆ IntGdiRemoveFontResource()

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

Definition at line 2219 of file freetype.c.

2223{
2224 PWSTR pchFile = FileName->Buffer;
2225 SIZE_T cchFile;
2226
2227 while (cFiles--)
2228 {
2229 _SEH2_TRY
2230 {
2231 cchFile = wcslen(pchFile);
2232 }
2234 {
2235 _SEH2_YIELD(return FALSE);
2236 }
2237 _SEH2_END;
2238
2239 UNICODE_STRING ustrPathName;
2240 ustrPathName.Length = (USHORT)(cchFile * sizeof(WCHAR));
2241 ustrPathName.MaximumLength = ustrPathName.Length + sizeof(WCHAR);
2242 ustrPathName.Buffer = pchFile;
2243
2245 if (!ret)
2246 return FALSE;
2247
2248 pchFile += cchFile + 1;
2249 }
2250
2251 return TRUE;
2252}
static BOOL FASTCALL IntGdiRemoveFontResourceSingle(_In_ PCUNICODE_STRING FileName, _In_ DWORD dwFlags)
Definition: freetype.c:2150

Referenced by NtGdiRemoveFontResourceW().

◆ IntGdiRemoveFontResourceSingle()

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

Definition at line 2150 of file freetype.c.

2153{
2154 BOOL ret = FALSE;
2155 UNICODE_STRING PathName;
2156 PLIST_ENTRY CurrentEntry, NextEntry;
2157 PFONT_ENTRY FontEntry;
2158 PFONTGDI FontGDI;
2159 PWSTR pszBuffer, pszFileTitle;
2160 SIZE_T Length;
2162
2163 /* Build PathName */
2165 {
2166 Length = DosPathPrefix.Length + FileName->Length + sizeof(UNICODE_NULL);
2168 if (!pszBuffer)
2169 return FALSE; /* Failure */
2170
2171 RtlInitEmptyUnicodeString(&PathName, pszBuffer, Length);
2174 }
2175 else
2176 {
2178 if (!NT_SUCCESS(Status))
2179 return FALSE; /* Failure */
2180 }
2181
2182 pszFileTitle = PathName.Buffer;
2184 pszFileTitle = PathFindFileNameW(PathName.Buffer);
2185
2186 if (!pszFileTitle || !*pszFileTitle)
2187 {
2188 RtlFreeUnicodeString(&PathName);
2189 return FALSE; /* Failure */
2190 }
2191
2192 /* Delete font entries that matches PathName */
2194 for (CurrentEntry = g_FontListHead.Flink;
2195 CurrentEntry != &g_FontListHead;
2196 CurrentEntry = NextEntry)
2197 {
2198 FontEntry = CONTAINING_RECORD(CurrentEntry, FONT_ENTRY, ListEntry);
2199 NextEntry = CurrentEntry->Flink;
2200
2201 FontGDI = FontEntry->Font;
2202 ASSERT(FontGDI);
2203 if (FontGDI->Filename && _wcsicmp(FontGDI->Filename, pszFileTitle) == 0)
2204 {
2205 RemoveEntryList(&FontEntry->ListEntry);
2206 CleanupFontEntry(FontEntry);
2208 IntDeleteRegFontEntries(pszFileTitle, dwFlags);
2209 ret = TRUE;
2210 }
2211 }
2213
2214 RtlFreeUnicodeString(&PathName);
2215 return ret;
2216}
WCHAR *WINAPI PathFindFileNameW(const WCHAR *path)
Definition: path.c:1701
VOID IntDeleteRegFontEntries(_In_ PCWSTR pszFileName, _In_ DWORD dwFlags)
Definition: freetype.c:2115
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 3696 of file freetype.c.

3699{
3700 FT_Glyph GlyphCopy;
3701 INT error;
3702 PFONT_CACHE_ENTRY NewEntry;
3703 FT_Bitmap AlignedBitmap;
3704 FT_BitmapGlyph BitmapGlyph;
3705
3707
3708 error = FT_Get_Glyph(GlyphSlot, &GlyphCopy);
3709 if (error)
3710 {
3711 DPRINT1("Failure caching glyph.\n");
3712 return NULL;
3713 };
3714
3715 error = FT_Glyph_To_Bitmap(&GlyphCopy, Cache->Hashed.Aspect.RenderMode, 0, 1);
3716 if (error)
3717 {
3718 FT_Done_Glyph(GlyphCopy);
3719 DPRINT1("Failure rendering glyph.\n");
3720 return NULL;
3721 };
3722
3724 if (!NewEntry)
3725 {
3726 DPRINT1("Alloc failure caching glyph.\n");
3727 FT_Done_Glyph(GlyphCopy);
3728 return NULL;
3729 }
3730
3731 BitmapGlyph = (FT_BitmapGlyph)GlyphCopy;
3732 FT_Bitmap_New(&AlignedBitmap);
3733 if (FT_Bitmap_Convert_ReactOS_Hack(GlyphSlot->library, &BitmapGlyph->bitmap,
3734 &AlignedBitmap, 4, TRUE))
3735 {
3736 DPRINT1("Conversion failed\n");
3737 ExFreePoolWithTag(NewEntry, TAG_FONT);
3738 FT_Bitmap_Done(GlyphSlot->library, &AlignedBitmap);
3739 FT_Done_Glyph((FT_Glyph)BitmapGlyph);
3740 return NULL;
3741 }
3742
3743 FT_Bitmap_Done(GlyphSlot->library, &BitmapGlyph->bitmap);
3744 BitmapGlyph->bitmap = AlignedBitmap;
3745
3746 NewEntry->BitmapGlyph = BitmapGlyph;
3747 NewEntry->dwHash = Cache->dwHash;
3748 NewEntry->Hashed = Cache->Hashed;
3749
3750 InsertHeadList(&g_FontCacheListHead, &NewEntry->ListEntry);
3752 {
3753 NewEntry = CONTAINING_RECORD(g_FontCacheListHead.Blink, FONT_CACHE_ENTRY, ListEntry);
3754 RemoveCachedEntry(NewEntry);
3755 }
3756
3757 return BitmapGlyph;
3758}
#define MAX_FONT_CACHE
Definition: freetype.c:237
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 1504 of file freetype.c.

1505{
1506 UINT BitIndex, CharSet;
1507 UINT nCount = 0;
1508
1509 if (CodePageRange1 == 0)
1510 return (nIndex < 0) ? 1 : DEFAULT_CHARSET;
1511
1512 for (BitIndex = 0; BitIndex < MAXTCIINDEX; ++BitIndex)
1513 {
1514 if (CodePageRange1 & (1 << BitIndex))
1515 {
1516 CharSet = g_FontTci[BitIndex].ciCharset;
1517 if ((nIndex >= 0) && (nCount == (UINT)nIndex))
1518 {
1519 return CharSet;
1520 }
1521 ++nCount;
1522 }
1523 }
1524
1525 return (nIndex < 0) ? nCount : ANSI_CHARSET;
1526}
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 7603 of file freetype.c.

7604{
7605 TT_OS2 *pOS2;
7606 FT_WinFNT_HeaderRec WinFNT;
7608
7610
7611 if (FT_IS_SFNT(Face)) // TrueType / OpenType
7612 {
7614 pOS2 = FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
7615 if (pOS2)
7616 *pDefChar = pOS2->usDefaultChar;
7618 return !!pOS2;
7619 }
7620
7621 if (!FT_IS_SCALABLE(Face)) // *.fon / *.fnt
7622 {
7624 error = FT_Get_WinFNT_Header(Face, &WinFNT);
7626 if (!error)
7627 *pDefChar = WinFNT.default_char;
7628 return !error;
7629 }
7630
7631 *pDefChar = 0; // .notdef
7632 return TRUE;
7633}
FT_UShort usDefaultChar
Definition: tttables.h:421

Referenced by GreGetGlyphIndicesW().

◆ IntGetFontFamilyInfo()

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

Definition at line 6446 of file freetype.c.

6450{
6451 LONG AvailCount = 0;
6452 PPROCESSINFO Win32Process;
6453
6454 /* Enumerate font families in the global list */
6456 if (!GetFontFamilyInfoForList(SafeLogFont, SafeInfo, NULL, &AvailCount,
6457 InfoCount, &g_FontListHead))
6458 {
6460 return -1;
6461 }
6462
6463 /* Enumerate font families in the process local list */
6464 Win32Process = PsGetCurrentProcessWin32Process();
6465 IntLockProcessPrivateFonts(Win32Process);
6466 if (!GetFontFamilyInfoForList(SafeLogFont, SafeInfo, NULL, &AvailCount, InfoCount,
6467 &Win32Process->PrivateFontListHead))
6468 {
6469 IntUnLockProcessPrivateFonts(Win32Process);
6471 return -1;
6472 }
6473 IntUnLockProcessPrivateFonts(Win32Process);
6475
6476 /* Enumerate font families in the registry */
6477 if (!GetFontFamilyInfoForSubstitutes(SafeLogFont, SafeInfo, &AvailCount, InfoCount))
6478 {
6479 return -1;
6480 }
6481
6482 return AvailCount;
6483}
static BOOLEAN FASTCALL GetFontFamilyInfoForSubstitutes(const LOGFONTW *LogFont, PFONTFAMILYINFO Info, LONG *pCount, LONG MaxCount)
Definition: freetype.c:3569

Referenced by NtGdiGetFontFamilyInfo().

◆ IntGetFontLocalizedName()

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

Definition at line 3178 of file freetype.c.

3180{
3182 INT i, Count, BestIndex, Score, BestScore;
3185 ANSI_STRING AnsiName;
3186 PSHARED_FACE_CACHE Cache;
3187 FT_Face Face = SharedFace->Face;
3188
3189 RtlFreeUnicodeString(pNameW);
3190
3191 /* select cache */
3193 Cache = &SharedFace->EnglishUS;
3194 else
3195 Cache = &SharedFace->UserLanguage;
3196
3197 /* use cache if available */
3198 if (NameID == TT_NAME_ID_FONT_FAMILY && Cache->FontFamily.Buffer)
3199 return IntDuplicateUnicodeString(&Cache->FontFamily, pNameW);
3200 if (NameID == TT_NAME_ID_FULL_NAME && Cache->FullName.Buffer)
3201 return IntDuplicateUnicodeString(&Cache->FullName, pNameW);
3202
3203 BestIndex = -1;
3204 BestScore = 0;
3205
3207 for (i = 0; i < Count; ++i)
3208 {
3209 Error = FT_Get_Sfnt_Name(Face, i, &Name);
3210 if (Error)
3211 continue; /* failure */
3212
3213 if (Name.name_id != NameID)
3214 continue; /* mismatched */
3215
3216 if (Name.platform_id != TT_PLATFORM_MICROSOFT ||
3217 (Name.encoding_id != TT_MS_ID_UNICODE_CS &&
3218 Name.encoding_id != TT_MS_ID_SYMBOL_CS))
3219 {
3220 continue; /* not Microsoft Unicode name */
3221 }
3222
3223 if (Name.string == NULL || Name.string_len == 0 ||
3224 (Name.string[0] == 0 && Name.string[1] == 0))
3225 {
3226 continue; /* invalid string */
3227 }
3228
3229 if (Name.language_id == LangID)
3230 {
3231 Score = 30;
3232 BestIndex = i;
3233 break; /* best match */
3234 }
3235 else if (PRIMARYLANGID(Name.language_id) == PRIMARYLANGID(LangID))
3236 {
3237 Score = 20;
3238 }
3239 else if (PRIMARYLANGID(Name.language_id) == LANG_ENGLISH)
3240 {
3241 Score = 10;
3242 }
3243 else
3244 {
3245 Score = 0;
3246 }
3247
3248 if (Score > BestScore)
3249 {
3250 BestScore = Score;
3251 BestIndex = i;
3252 }
3253 }
3254
3255 if (BestIndex >= 0)
3256 {
3257 /* store the best name */
3258 Error = (Score == 30) ? 0 : FT_Get_Sfnt_Name(Face, BestIndex, &Name);
3259 if (!Error)
3260 {
3261 /* NOTE: Name.string is not null-terminated */
3262 UNICODE_STRING Tmp;
3263 Tmp.Buffer = (PWCH)Name.string;
3264 Tmp.Length = Tmp.MaximumLength = Name.string_len;
3265
3266 pNameW->Length = 0;
3267 pNameW->MaximumLength = Name.string_len + sizeof(WCHAR);
3269
3270 if (pNameW->Buffer)
3271 {
3272 Status = RtlAppendUnicodeStringToString(pNameW, &Tmp);
3273 if (Status == STATUS_SUCCESS)
3274 {
3275 /* Convert UTF-16 big endian to little endian */
3276 IntSwapEndian(pNameW->Buffer, pNameW->Length);
3277 }
3278 }
3279 else
3280 {
3282 }
3283 }
3284 }
3285
3286 if (!NT_SUCCESS(Status))
3287 {
3288 /* defaulted */
3289 if (NameID == TT_NAME_ID_FONT_SUBFAMILY)
3290 {
3291 RtlInitAnsiString(&AnsiName, Face->style_name);
3292 Status = RtlAnsiStringToUnicodeString(pNameW, &AnsiName, TRUE);
3293 }
3294 else
3295 {
3296 RtlInitAnsiString(&AnsiName, Face->family_name);
3297 Status = RtlAnsiStringToUnicodeString(pNameW, &AnsiName, TRUE);
3298 }
3299 }
3300
3301 if (NT_SUCCESS(Status))
3302 {
3303 /* make cache */
3304 if (NameID == TT_NAME_ID_FONT_FAMILY)
3305 {
3307 if (!Cache->FontFamily.Buffer)
3308 IntDuplicateUnicodeString(pNameW, &Cache->FontFamily);
3309 }
3310 else if (NameID == TT_NAME_ID_FULL_NAME)
3311 {
3313 if (!Cache->FullName.Buffer)
3314 IntDuplicateUnicodeString(pNameW, &Cache->FullName);
3315 }
3316 }
3317
3318 return Status;
3319}
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_SUBFAMILY
Definition: font.c:3537
WCHAR * PWCH
Definition: ntbasedef.h:422
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define STATUS_NOT_FOUND
Definition: shellext.h:72
UNICODE_STRING FontFamily
Definition: engobjects.h:127
UNICODE_STRING FullName
Definition: engobjects.h:128
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(), MatchFontName(), and TextIntRealizeFont().

◆ IntGetFontRenderMode()

FT_Render_Mode FASTCALL IntGetFontRenderMode ( LOGFONTW logfont)

Definition at line 2591 of file freetype.c.

2592{
2593 switch (logfont->lfQuality)
2594 {
2596 break;
2598 return FT_RENDER_MODE_MONO;
2599 case DRAFT_QUALITY:
2600 return FT_RENDER_MODE_LIGHT;
2601 case CLEARTYPE_QUALITY:
2602 if (!gspv.bFontSmoothing)
2603 break;
2605 break;
2606 return FT_RENDER_MODE_LCD;
2607 }
2608 return FT_RENDER_MODE_NORMAL;
2609}
@ 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 5917 of file freetype.c.

5921{
5924 HANDLE hFile;
5926 ULONG Desired;
5927
5929 FileName,
5931 NULL,
5932 NULL);
5933
5935 &hFile,
5936 0, // FILE_READ_ATTRIBUTES,
5940 0);
5941
5942 if (!NT_SUCCESS(Status))
5943 {
5944 DPRINT("ZwOpenFile() failed (Status = 0x%lx)\n", Status);
5945 return FALSE;
5946 }
5947
5948 Status = ZwQueryObject(hFile, ObjectNameInformation, NameInfo, Size, &Desired);
5949 ZwClose(hFile);
5950 if (!NT_SUCCESS(Status))
5951 {
5952 DPRINT("ZwQueryObject() failed (Status = %lx)\n", Status);
5953 return FALSE;
5954 }
5955
5956 return TRUE;
5957}
@ 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 3644 of file freetype.c.

3645{
3646 DWORD dwHash = cdw;
3647 const DWORD *pdw = pv;
3648
3649 while (cdw-- > 0)
3650 {
3651 dwHash *= 3;
3652 dwHash ^= *pdw++;
3653 }
3654
3655 return dwHash;
3656}

Referenced by IntGetRealGlyph().

◆ IntGetOutlineTextMetrics()

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

Definition at line 3018 of file freetype.c.

3022{
3023 TT_OS2 *pOS2;
3024 TT_HoriHeader *pHori;
3025 TT_Postscript *pPost;
3026 FT_Fixed XScale, YScale;
3027 FT_WinFNT_HeaderRec WinFNT;
3029 BYTE *pb;
3030 FONT_NAMES FontNames;
3031 PSHARED_FACE SharedFace = FontGDI->SharedFace;
3032 PSHARED_FACE_CACHE Cache;
3033 FT_Face Face = SharedFace->Face;
3034
3035 if (bLocked)
3037 else
3039
3041 {
3042 Cache = &SharedFace->EnglishUS;
3043 }
3044 else
3045 {
3046 Cache = &SharedFace->UserLanguage;
3047 }
3048
3049 if (Size == 0 && Cache->OutlineRequiredSize > 0)
3050 {
3051 ASSERT(Otm == NULL);
3052 return Cache->OutlineRequiredSize;
3053 }
3054
3055 if (!bLocked)
3057
3058 IntInitFontNames(&FontNames, SharedFace);
3059 Cache->OutlineRequiredSize = FontNames.OtmSize;
3060
3061 if (Size == 0)
3062 {
3063 ASSERT(Otm == NULL);
3064 IntFreeFontNames(&FontNames);
3065 if (!bLocked)
3067 return Cache->OutlineRequiredSize;
3068 }
3069
3070 ASSERT(Otm != NULL);
3071
3072 if (Size < Cache->OutlineRequiredSize)
3073 {
3074 DPRINT1("Size %u < OutlineRequiredSize %u\n", Size,
3075 Cache->OutlineRequiredSize);
3076 IntFreeFontNames(&FontNames);
3077 if (!bLocked)
3079 return 0; /* failure */
3080 }
3081
3082 XScale = Face->size->metrics.x_scale;
3083 YScale = Face->size->metrics.y_scale;
3084
3085 pOS2 = FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
3086 pHori = FT_Get_Sfnt_Table(Face, FT_SFNT_HHEA);
3087 pPost = FT_Get_Sfnt_Table(Face, FT_SFNT_POST); /* We can live with this failing */
3088 Error = FT_Get_WinFNT_Header(Face, &WinFNT);
3089
3090 if (pOS2 == NULL && Error)
3091 {
3092 if (!bLocked)
3094 DPRINT1("Can't find OS/2 table - not TT font?\n");
3095 IntFreeFontNames(&FontNames);
3096 return 0;
3097 }
3098
3099 if (pHori == NULL && Error)
3100 {
3101 if (!bLocked)
3103 DPRINT1("Can't find HHEA table - not TT font?\n");
3104 IntFreeFontNames(&FontNames);
3105 return 0;
3106 }
3107
3108 Otm->otmSize = Cache->OutlineRequiredSize;
3109
3110 FillTM(&Otm->otmTextMetrics, FontGDI, pOS2, pHori, (Error ? NULL : &WinFNT));
3111
3112 if (!pOS2)
3113 goto skip_os2;
3114
3115 Otm->otmFiller = 0;
3117 Otm->otmfsSelection = pOS2->fsSelection;
3118 Otm->otmfsType = pOS2->fsType;
3119 Otm->otmsCharSlopeRise = pHori->caret_Slope_Rise;
3120 Otm->otmsCharSlopeRun = pHori->caret_Slope_Run;
3121 Otm->otmItalicAngle = 0; /* POST table */
3122 Otm->otmEMSquare = Face->units_per_EM;
3123
3124#define SCALE_X(value) ((FT_MulFix((value), XScale) + 32) >> 6)
3125#define SCALE_Y(value) ((FT_MulFix((value), YScale) + 32) >> 6)
3126
3127 Otm->otmAscent = SCALE_Y(pOS2->sTypoAscender);
3128 Otm->otmDescent = SCALE_Y(pOS2->sTypoDescender);
3129 Otm->otmLineGap = SCALE_Y(pOS2->sTypoLineGap);
3130 Otm->otmsCapEmHeight = SCALE_Y(pOS2->sCapHeight);
3131 Otm->otmsXHeight = SCALE_Y(pOS2->sxHeight);
3132 Otm->otmrcFontBox.left = SCALE_X(Face->bbox.xMin);
3133 Otm->otmrcFontBox.right = SCALE_X(Face->bbox.xMax);
3134 Otm->otmrcFontBox.top = SCALE_Y(Face->bbox.yMax);
3135 Otm->otmrcFontBox.bottom = SCALE_Y(Face->bbox.yMin);
3138 Otm->otmMacLineGap = Otm->otmLineGap;
3139 Otm->otmusMinimumPPEM = 0; /* TT Header */
3150
3151 if (!pPost)
3152 {
3153 Otm->otmsUnderscoreSize = 0;
3154 Otm->otmsUnderscorePosition = 0;
3155 }
3156 else
3157 {
3160 }
3161
3162#undef SCALE_X
3163#undef SCALE_Y
3164
3165skip_os2:
3166 if (!bLocked)
3168
3169 pb = IntStoreFontNames(&FontNames, Otm);
3170 ASSERT(pb - (BYTE*)Otm == Cache->OutlineRequiredSize);
3171
3172 IntFreeFontNames(&FontNames);
3173
3174 return Cache->OutlineRequiredSize;
3175}
BOOLEAN bLocked
Definition: Mke2fs.c:19
#define SCALE_Y(value)
static __inline void FASTCALL IntInitFontNames(FONT_NAMES *Names, PSHARED_FACE SharedFace)
Definition: freetype.c:2945
PBYTE FASTCALL IntStoreFontNames(_In_ const FONT_NAMES *Names, _Out_ OUTLINETEXTMETRICW *Otm)
Definition: freetype.c:2981
#define SCALE_X(value)
static __inline void FASTCALL IntFreeFontNames(FONT_NAMES *Names)
Definition: freetype.c:3005
ULONG OtmSize
Definition: freetype.c:2941
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 4932 of file freetype.c.

4934{
4935 INT error;
4936 FT_GlyphSlot glyph;
4937 FT_BitmapGlyph realglyph;
4938
4940
4941 Cache->dwHash = IntGetHash(&Cache->Hashed, sizeof(Cache->Hashed) / sizeof(DWORD));
4942
4943 realglyph = IntFindGlyphCache(Cache);
4944 if (realglyph)
4945 return realglyph;
4946
4947 error = FT_Load_Glyph(Cache->Hashed.Face, Cache->Hashed.GlyphIndex, FT_LOAD_DEFAULT);
4948 if (error)
4949 {
4950 DPRINT1("WARNING: Failed to load and render glyph! [index: %d]\n", Cache->Hashed.GlyphIndex);
4951 return NULL;
4952 }
4953
4954 glyph = Cache->Hashed.Face->glyph;
4955
4956 if (Cache->Hashed.Aspect.Emu.Bold)
4957 FT_GlyphSlot_Embolden(glyph); /* Emulate Bold */
4958
4959 if (Cache->Hashed.Aspect.Emu.Italic)
4960 FT_GlyphSlot_Oblique(glyph); /* Emulate Italic */
4961
4962 realglyph = IntGetBitmapGlyphWithCache(Cache, glyph);
4963
4964 if (!realglyph)
4965 DPRINT1("Failed to render glyph! [index: %d]\n", Cache->Hashed.GlyphIndex);
4966
4967 return realglyph;
4968}
static DWORD IntGetHash(IN LPCVOID pv, IN DWORD cdw)
Definition: freetype.c:3644
static FT_BitmapGlyph IntFindGlyphCache(IN const FONT_CACHE_ENTRY *pCache)
Definition: freetype.c:3659
static FT_BitmapGlyph IntGetBitmapGlyphWithCache(IN OUT PFONT_CACHE_ENTRY Cache, IN FT_GlyphSlot GlyphSlot)
Definition: freetype.c:3696
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 6587 of file freetype.c.

6597{
6598 LONGLONG X64 = 0, Y64 = 0;
6599 INT i, glyph_index;
6600 FT_BitmapGlyph realglyph;
6601 FT_Face face = Cache->Hashed.Face;
6602 BOOL use_kerning = FT_HAS_KERNING(face);
6603 ULONG previous = 0;
6604 FT_Vector delta, vec;
6605 DWORD ch0, ch1;
6606
6608
6609 for (i = 0; i < Count; ++i)
6610 {
6611 ch0 = *String++;
6612 if (IS_HIGH_SURROGATE(ch0))
6613 {
6614 ++i;
6615 if (i >= Count)
6616 return TRUE;
6617
6618 ch1 = *String++;
6619 if (IS_LOW_SURROGATE(ch1))
6620 ch0 = Utf32FromSurrogatePair(ch0, ch1);
6621 }
6622
6623 glyph_index = FontLink_Chain_FindGlyph(pChain, Cache, &face, ch0,
6624 (fuOptions & ETO_GLYPH_INDEX));
6625 Cache->Hashed.GlyphIndex = glyph_index;
6626
6627 realglyph = IntGetRealGlyph(Cache);
6628 if (!realglyph)
6629 return FALSE;
6630
6631 /* Retrieve kerning distance */
6632 if (use_kerning && previous && glyph_index)
6633 {
6634 FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
6635 X64 += delta.x;
6636 Y64 -= delta.y;
6637 }
6638
6639 if (NULL == Dx)
6640 {
6641 X64 += realglyph->root.advance.x >> 10;
6642 Y64 -= realglyph->root.advance.y >> 10;
6643 }
6644 else if (fuOptions & ETO_PDY)
6645 {
6646 vec.x = (Dx[2 * i + 0] << 6);
6647 vec.y = (Dx[2 * i + 1] << 6);
6648 if (!bNoTransform)
6649 FT_Vector_Transform(&vec, &Cache->Hashed.matTransform);
6650 X64 += vec.x;
6651 Y64 -= vec.y;
6652 }
6653 else
6654 {
6655 vec.x = (Dx[i] << 6);
6656 vec.y = 0;
6657 if (!bNoTransform)
6658 FT_Vector_Transform(&vec, &Cache->Hashed.matTransform);
6659 X64 += vec.x;
6660 Y64 -= vec.y;
6661 }
6662
6663 previous = glyph_index;
6664 }
6665
6666 *pX64 = X64;
6667 *pY64 = Y64;
6668 return TRUE;
6669}

Referenced by IntExtTextOutW().

◆ IntInitFontNames()

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

Definition at line 2945 of file freetype.c.

2946{
2947 ULONG OtmSize;
2948
2949 RtlInitUnicodeString(&Names->FamilyNameW, NULL);
2950 RtlInitUnicodeString(&Names->FaceNameW, NULL);
2951 RtlInitUnicodeString(&Names->StyleNameW, NULL);
2952 RtlInitUnicodeString(&Names->FullNameW, NULL);
2953
2954 /* family name */
2956 /* face name */
2958 /* style name */
2960 /* unique name (full name) */
2962
2963 /* Calculate the size of OUTLINETEXTMETRICW with extra data */
2964 OtmSize = sizeof(OUTLINETEXTMETRICW) +
2965 Names->FamilyNameW.Length + sizeof(UNICODE_NULL) +
2966 Names->FaceNameW.Length + sizeof(UNICODE_NULL) +
2967 Names->StyleNameW.Length + sizeof(UNICODE_NULL) +
2968 Names->FullNameW.Length + sizeof(UNICODE_NULL);
2969 Names->OtmSize = OtmSize;
2970}
static NTSTATUS IntGetFontLocalizedName(PUNICODE_STRING pNameW, PSHARED_FACE SharedFace, FT_UShort NameID, FT_UShort LangID)
Definition: freetype.c:3178
#define TT_NAME_ID_UNIQUE_ID
Definition: font.c:3538
struct _OUTLINETEXTMETRICW OUTLINETEXTMETRICW

Referenced by IntGetOutlineTextMetrics().

◆ IntIsFontRenderingEnabled()

BOOL FASTCALL IntIsFontRenderingEnabled ( VOID  )

Definition at line 2579 of file freetype.c.

2580{
2581 return (gpsi->BitsPixel > 8) && g_RenderingEnabled;
2582}
PSERVERINFO gpsi
Definition: imm.c:18

Referenced by IntExtTextOutW(), and TextIntGetTextExtentPoint().

◆ IntLoadFontsInRegistry()

BOOL FASTCALL IntLoadFontsInRegistry ( VOID  )

Definition at line 2255 of file freetype.c.

2256{
2260 KEY_FULL_INFORMATION KeyFullInfo;
2261 ULONG i, Length;
2262 UNICODE_STRING FontTitleW, FileNameW;
2263 SIZE_T InfoSize;
2264 LPBYTE InfoBuffer;
2266 LPWSTR pchPath;
2268 INT nFontCount = 0;
2269 DWORD dwFlags;
2270
2271 /* open registry key */
2274 NULL, NULL);
2275 Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
2276 if (!NT_SUCCESS(Status))
2277 {
2278 DPRINT1("ZwOpenKey failed: 0x%08X\n", Status);
2279 return FALSE; /* failure */
2280 }
2281
2282 /* query count of values */
2283 Status = ZwQueryKey(KeyHandle, KeyFullInformation,
2284 &KeyFullInfo, sizeof(KeyFullInfo), &Length);
2285 if (!NT_SUCCESS(Status))
2286 {
2287 DPRINT1("ZwQueryKey failed: 0x%08X\n", Status);
2289 return FALSE; /* failure */
2290 }
2291
2292 /* allocate buffer */
2293 InfoSize = (MAX_PATH + 256) * sizeof(WCHAR);
2294 InfoBuffer = ExAllocatePoolWithTag(PagedPool, InfoSize, TAG_FONT);
2295 if (!InfoBuffer)
2296 {
2297 DPRINT1("ExAllocatePoolWithTag failed\n");
2299 return FALSE;
2300 }
2301
2302 /* for each value */
2303 for (i = 0; i < KeyFullInfo.Values; ++i)
2304 {
2305 /* get value name */
2306 Status = ZwEnumerateValueKey(KeyHandle, i, KeyValueFullInformation,
2307 InfoBuffer, InfoSize, &Length);
2309 {
2310 /* too short buffer */
2311 ExFreePoolWithTag(InfoBuffer, TAG_FONT);
2312 InfoSize *= 2;
2313 InfoBuffer = ExAllocatePoolWithTag(PagedPool, InfoSize, TAG_FONT);
2314 if (!InfoBuffer)
2315 {
2316 DPRINT1("ExAllocatePoolWithTag failed\n");
2317 break;
2318 }
2319 /* try again */
2320 Status = ZwEnumerateValueKey(KeyHandle, i, KeyValueFullInformation,
2321 InfoBuffer, InfoSize, &Length);
2322 }
2323 if (!NT_SUCCESS(Status))
2324 {
2325 DPRINT1("ZwEnumerateValueKey failed: 0x%08X\n", Status);
2326 break; /* failure */
2327 }
2328
2329 /* create FontTitleW string */
2330 pInfo = (PKEY_VALUE_FULL_INFORMATION)InfoBuffer;
2331 Length = pInfo->NameLength / sizeof(WCHAR);
2332 pInfo->Name[Length] = UNICODE_NULL; /* truncate */
2333 if (!RtlCreateUnicodeString(&FontTitleW, pInfo->Name))
2334 {
2336 DPRINT1("RtlCreateUnicodeString failed\n");
2337 break; /* failure */
2338 }
2339
2340 /* query value */
2341 Status = ZwQueryValueKey(KeyHandle, &FontTitleW, KeyValueFullInformation,
2342 InfoBuffer, InfoSize, &Length);
2344 {
2345 /* too short buffer */
2346 ExFreePoolWithTag(InfoBuffer, TAG_FONT);
2347 InfoSize *= 2;
2348 InfoBuffer = ExAllocatePoolWithTag(PagedPool, InfoSize, TAG_FONT);
2349 if (!InfoBuffer)
2350 {
2351 DPRINT1("ExAllocatePoolWithTag failed\n");
2352 break;
2353 }
2354 /* try again */
2355 Status = ZwQueryValueKey(KeyHandle, &FontTitleW, KeyValueFullInformation,
2356 InfoBuffer, InfoSize, &Length);
2357 }
2358 pInfo = (PKEY_VALUE_FULL_INFORMATION)InfoBuffer;
2359 if (!NT_SUCCESS(Status) || !pInfo->DataLength)
2360 {
2361 DPRINT1("ZwQueryValueKey failed: 0x%08X\n", Status);
2362 RtlFreeUnicodeString(&FontTitleW);
2363 break; /* failure */
2364 }
2365
2366 /* Build pchPath */
2367 pchPath = (LPWSTR)((PUCHAR)pInfo + pInfo->DataOffset);
2368 Length = pInfo->DataLength / sizeof(WCHAR);
2369 pchPath[Length] = UNICODE_NULL; /* truncate */
2370
2371 /* Load font(s) without writing registry */
2372 if (PathIsRelativeW(pchPath))
2373 {
2374 dwFlags = 0;
2376 L"\\SystemRoot\\Fonts\\%s", pchPath);
2377 }
2378 else
2379 {
2381 Status = RtlStringCbCopyW(szPath, sizeof(szPath), pchPath);
2382 }
2383
2384 if (NT_SUCCESS(Status))
2385 {
2386 RtlCreateUnicodeString(&FileNameW, szPath);
2387 nFontCount += IntGdiAddFontResourceEx(&FileNameW, 1, 0, dwFlags);
2388 RtlFreeUnicodeString(&FileNameW);
2389 }
2390
2391 RtlFreeUnicodeString(&FontTitleW);
2392 }
2393
2394 /* close now */
2396
2397 /* free memory block */
2398 if (InfoBuffer)
2399 {
2400 ExFreePoolWithTag(InfoBuffer, TAG_FONT);
2401 }
2402
2403 return (KeyFullInfo.Values != 0 && nFontCount != 0);
2404}
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:2076
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
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by InitFontSupport().

◆ IntLoadFontSubstList()

BOOL FASTCALL IntLoadFontSubstList ( PLIST_ENTRY  pHead)

Definition at line 729 of file freetype.c.

730{
734 KEY_FULL_INFORMATION KeyFullInfo;
735 ULONG i, Length;
736 UNICODE_STRING FromW, ToW;
737 BYTE InfoBuffer[128];
739 BYTE CharSets[FONTSUBST_FROM_AND_TO];
740 LPWSTR pch;
742
743 /* the FontSubstitutes registry key */
744 static UNICODE_STRING FontSubstKey =
745 RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\"
746 L"Microsoft\\Windows NT\\CurrentVersion\\"
747 L"FontSubstitutes");
748
749 /* open registry key */
752 NULL, NULL);
753 Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
754 if (!NT_SUCCESS(Status))
755 {
756 DPRINT("ZwOpenKey failed: 0x%08X\n", Status);
757 return FALSE; /* failure */
758 }
759
760 /* query count of values */
761 Status = ZwQueryKey(KeyHandle, KeyFullInformation,
762 &KeyFullInfo, sizeof(KeyFullInfo), &Length);
763 if (!NT_SUCCESS(Status))
764 {
765 DPRINT("ZwQueryKey failed: 0x%08X\n", Status);
767 return FALSE; /* failure */
768 }
769
770 /* for each value */
771 for (i = 0; i < KeyFullInfo.Values; ++i)
772 {
773 /* get value name */
774 Status = ZwEnumerateValueKey(KeyHandle, i, KeyValueFullInformation,
775 InfoBuffer, sizeof(InfoBuffer), &Length);
776 if (!NT_SUCCESS(Status))
777 {
778 DPRINT("ZwEnumerateValueKey failed: 0x%08X\n", Status);
779 break; /* failure */
780 }
781
782 /* create FromW string */
783 pInfo = (PKEY_VALUE_FULL_INFORMATION)InfoBuffer;
784 Length = pInfo->NameLength / sizeof(WCHAR);
785 pInfo->Name[Length] = UNICODE_NULL; /* truncate */
786 if (!RtlCreateUnicodeString(&FromW, pInfo->Name))
787 {
789 DPRINT("RtlCreateUnicodeString failed\n");
790 break; /* failure */
791 }
792
793 /* query value */
794 Status = ZwQueryValueKey(KeyHandle, &FromW, KeyValueFullInformation,
795 InfoBuffer, sizeof(InfoBuffer), &Length);
796 pInfo = (PKEY_VALUE_FULL_INFORMATION)InfoBuffer;
797 if (!NT_SUCCESS(Status) || !pInfo->DataLength)
798 {
799 DPRINT("ZwQueryValueKey failed: 0x%08X\n", Status);
800 RtlFreeUnicodeString(&FromW);
801 break; /* failure */
802 }
803
804 /* create ToW string */
805 pch = (LPWSTR)((PUCHAR)pInfo + pInfo->DataOffset);
806 Length = pInfo->DataLength / sizeof(WCHAR);
807 pch[Length] = UNICODE_NULL; /* truncate */
808 if (!RtlCreateUnicodeString(&ToW, pch))
809 {
811 DPRINT("RtlCreateUnicodeString failed\n");
812 RtlFreeUnicodeString(&FromW);
813 break; /* failure */
814 }
815
816 /* does charset exist? (from) */
818 pch = wcsrchr(FromW.Buffer, L',');
819 if (pch)
820 {
821 /* truncate */
822 *pch = UNICODE_NULL;
823 FromW.Length = (pch - FromW.Buffer) * sizeof(WCHAR);
824 /* parse charset number */
825 CharSets[FONTSUBST_FROM] = (BYTE)_wtoi(pch + 1);
826 }
827
828 /* does charset exist? (to) */
829 CharSets[FONTSUBST_TO] = DEFAULT_CHARSET;
830 pch = wcsrchr(ToW.Buffer, L',');
831 if (pch)
832 {
833 /* truncate */
834 *pch = UNICODE_NULL;
835 ToW.Length = (pch - ToW.Buffer) * sizeof(WCHAR);
836 /* parse charset number */
837 CharSets[FONTSUBST_TO] = (BYTE)_wtoi(pch + 1);
838 }
839
840 /* is it identical? */
841 if (RtlEqualUnicodeString(&FromW, &ToW, TRUE) &&
842 CharSets[FONTSUBST_FROM] == CharSets[FONTSUBST_TO])
843 {
844 RtlFreeUnicodeString(&FromW);
846 continue;
847 }
848
849 /* allocate an entry */
851 if (pEntry == NULL)
852 {
853 DPRINT("ExAllocatePoolWithTag failed\n");
854 RtlFreeUnicodeString(&FromW);
856 break; /* failure */
857 }
858
859 /* store to *pEntry */
860 pEntry->FontNames[FONTSUBST_FROM] = FromW;
861 pEntry->FontNames[FONTSUBST_TO] = ToW;
862 pEntry->CharSets[FONTSUBST_FROM] = CharSets[FONTSUBST_FROM];
863 pEntry->CharSets[FONTSUBST_TO] = CharSets[FONTSUBST_TO];
864
865 /* insert pEntry to *pHead */
866 InsertTailList(pHead, &pEntry->ListEntry);
867 }
868
869 /* close now */
871
872 return NT_SUCCESS(Status);
873}
_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 1378 of file freetype.c.

1379{
1381 UNICODE_STRING Directory, FileName, TempString;
1383 HANDLE hDirectory;
1384 BYTE *DirInfoBuffer;
1386 BOOLEAN bRestartScan = TRUE;
1388 INT i;
1389 static UNICODE_STRING SearchPatterns[] =
1390 {
1391 RTL_CONSTANT_STRING(L"*.ttf"),
1392 RTL_CONSTANT_STRING(L"*.ttc"),
1393 RTL_CONSTANT_STRING(L"*.otf"),
1394 RTL_CONSTANT_STRING(L"*.otc"),
1395 RTL_CONSTANT_STRING(L"*.fon"),
1396 RTL_CONSTANT_STRING(L"*.fnt")
1397 };
1398 static UNICODE_STRING IgnoreFiles[] =
1399 {
1402 };
1403
1404 RtlInitUnicodeString(&Directory, L"\\SystemRoot\\Fonts\\");
1405
1408 &Directory,
1410 NULL,
1411 NULL);
1412
1414 &hDirectory,
1417 &Iosb,
1420
1421 if (NT_SUCCESS(Status))
1422 {
1423 for (i = 0; i < _countof(SearchPatterns); ++i)
1424 {
1425 DirInfoBuffer = ExAllocatePoolWithTag(PagedPool, 0x4000, TAG_FONT);
1426 if (DirInfoBuffer == NULL)
1427 {
1428 ZwClose(hDirectory);
1429 return;
1430 }
1431
1433 if (FileName.Buffer == NULL)
1434 {
1435 ExFreePoolWithTag(DirInfoBuffer, TAG_FONT);
1436 ZwClose(hDirectory);
1437 return;
1438 }
1439 FileName.Length = 0;
1440 FileName.MaximumLength = MAX_PATH * sizeof(WCHAR);
1441
1442 while (1)
1443 {
1444 Status = ZwQueryDirectoryFile(
1445 hDirectory,
1446 NULL,
1447 NULL,
1448 NULL,
1449 &Iosb,
1450 DirInfoBuffer,
1451 0x4000,
1453 FALSE,
1454 &SearchPatterns[i],
1455 bRestartScan);
1456
1458 {
1459 break;
1460 }
1461
1462 DirInfo = (PFILE_DIRECTORY_INFORMATION)DirInfoBuffer;
1463 while (1)
1464 {
1465 SIZE_T ign;
1466
1467 TempString.Buffer = DirInfo->FileName;
1468 TempString.Length = TempString.MaximumLength = DirInfo->FileNameLength;
1469
1470 /* Should we ignore this file? */
1471 for (ign = 0; ign < _countof(IgnoreFiles); ++ign)
1472 {
1473 /* Yes.. */
1474 if (RtlEqualUnicodeString(IgnoreFiles + ign, &TempString, FALSE))
1475 break;
1476 }
1477
1478 /* If we tried all Ignore patterns and there was no match, try to create a font */
1479 if (ign == _countof(IgnoreFiles))
1480 {
1484 DPRINT1("ERR: Failed to load %wZ\n", &FileName);
1485 }
1486
1487 if (DirInfo->NextEntryOffset == 0)
1488 break;
1489
1490 DirInfo = (PFILE_DIRECTORY_INFORMATION)((ULONG_PTR)DirInfo + DirInfo->NextEntryOffset);
1491 }
1492
1493 bRestartScan = FALSE;
1494 }
1495
1497 ExFreePoolWithTag(DirInfoBuffer, TAG_FONT);
1498 }
1499 ZwClose(hDirectory);
1500 }
1501}
@ 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
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3942
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
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 1050 of file freetype.c.

1051{
1052 FLOATOBJ ef;
1053
1054 /* Create a freetype matrix, by converting to 16.16 fixpoint format */
1055 ef = pmx->efM11;
1056 FLOATOBJ_MulLong(&ef, 0x00010000);
1057 pmat->xx = FLOATOBJ_GetLong(&ef);
1058
1059 ef = pmx->efM21;
1060 FLOATOBJ_MulLong(&ef, 0x00010000);
1061 pmat->xy = -FLOATOBJ_GetLong(&ef); /* (*1) See below */
1062
1063 ef = pmx->efM12;
1064 FLOATOBJ_MulLong(&ef, 0x00010000);
1065 pmat->yx = -FLOATOBJ_GetLong(&ef); /* (*1) See below */
1066
1067 ef = pmx->efM22;
1068 FLOATOBJ_MulLong(&ef, 0x00010000);
1069 pmat->yy = FLOATOBJ_GetLong(&ef);
1070
1071 // (*1): Y direction is mirrored as follows:
1072 //
1073 // [ M11 -M12 ] [ X ] [ M11*X + M12*Y ]
1074 // [ ] * [ ] == [ ]
1075 // [ -M21 M22 ] [ -Y ] [ -(M21*X + M22*Y) ].
1076}

Referenced by ftGdiGetGlyphOutline(), and IntExtTextOutW().

◆ IntNeedRequestFontSize()

static BOOL IntNeedRequestFontSize ( PFONTLINK_CHAIN  pChain,
FT_Face  face,
PLIST_ENTRY  TargetEntry 
)
static

Definition at line 4361 of file freetype.c.

4362{
4363 PLIST_ENTRY Entry, Head = &pChain->FontLinkList;
4364 PFONTLINK pFontLink;
4365
4366 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
4367 {
4368 pFontLink = CONTAINING_RECORD(Entry, FONTLINK, ListEntry);
4369 if (!FontLink_PrepareFontInfo(pFontLink))
4370 continue; // This link is not useful, check the next one
4371
4372 if (pFontLink->SharedFace->Face == face || Entry == TargetEntry)
4373 return FALSE;
4374 }
4375
4376 return TRUE;
4377}

Referenced by FontLink_Chain_FindGlyph().

◆ IntRequestFontSize()

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

Definition at line 3959 of file freetype.c.

3960{
3963 FT_Face face = FontGDI->SharedFace->Face;
3964 TT_OS2 *pOS2;
3965 TT_HoriHeader *pHori;
3966 FT_WinFNT_HeaderRec WinFNT;
3967 LONG Ascent, Descent, Sum, EmHeight;
3968
3969 lfWidth = abs(lfWidth);
3970 if (lfHeight == 0)
3971 {
3972 if (lfWidth == 0)
3973 {
3974 DPRINT("lfHeight and lfWidth are zero.\n");
3975 lfHeight = -16;
3976 }
3977 else
3978 {
3979 lfHeight = lfWidth;
3980 }
3981 }
3982
3983 if (lfHeight == -1)
3984 lfHeight = -2;
3985
3989
3990 if (!pOS2 || !pHori)
3991 {
3992 error = FT_Get_WinFNT_Header(face, &WinFNT);
3993 if (error)
3994 {
3995 DPRINT1("%s: Failed to request font size.\n", face->family_name);
3996 return error;
3997 }
3998
3999 FontGDI->tmHeight = WinFNT.pixel_height;
4000 FontGDI->tmAscent = WinFNT.ascent;
4001 FontGDI->tmDescent = FontGDI->tmHeight - FontGDI->tmAscent;
4002 FontGDI->tmInternalLeading = WinFNT.internal_leading;
4003 FontGDI->Magic = FONTGDI_MAGIC;
4004 FontGDI->lfHeight = lfHeight;
4005 FontGDI->lfWidth = lfWidth;
4006 return 0;
4007 }
4008
4009 /*
4010 * NOTE: We cast TT_OS2.usWinAscent and TT_OS2.usWinDescent to signed FT_Short.
4011 * Why? See: https://learn.microsoft.com/en-us/typography/opentype/spec/os2#uswindescent
4012 *
4013 * > usWinDescent is "usually" a positive value ...
4014 *
4015 * We can read it as "not always". See CORE-14994.
4016 * See also: https://learn.microsoft.com/en-us/typography/opentype/spec/os2#fsselection
4017 */
4018#define FM_SEL_USE_TYPO_METRICS 0x80
4019 if (lfHeight > 0)
4020 {
4021 /* case (A): lfHeight is positive */
4022 Sum = (FT_Short)pOS2->usWinAscent + (FT_Short)pOS2->usWinDescent;
4023 if (Sum == 0 || (pOS2->fsSelection & FM_SEL_USE_TYPO_METRICS))
4024 {
4025 Ascent = pHori->Ascender;
4026 Descent = -pHori->Descender;
4027 Sum = Ascent + Descent;
4028 }
4029 else
4030 {
4031 Ascent = (FT_Short)pOS2->usWinAscent;
4032 Descent = (FT_Short)pOS2->usWinDescent;
4033 }
4034
4035 FontGDI->tmAscent = FT_MulDiv(lfHeight, Ascent, Sum);
4036 FontGDI->tmDescent = FT_MulDiv(lfHeight, Descent, Sum);
4037 FontGDI->tmHeight = FontGDI->tmAscent + FontGDI->tmDescent;
4038 FontGDI->tmInternalLeading = FontGDI->tmHeight - FT_MulDiv(lfHeight, face->units_per_EM, Sum);
4039 }
4040 else if (lfHeight < 0)
4041 {
4042 /* case (B): lfHeight is negative */
4044 {
4045 FontGDI->tmAscent = FT_MulDiv(-lfHeight, pHori->Ascender, face->units_per_EM);
4046 FontGDI->tmDescent = FT_MulDiv(-lfHeight, -pHori->Descender, face->units_per_EM);
4047 }
4048 else
4049 {
4050 FontGDI->tmAscent = FT_MulDiv(-lfHeight, (FT_Short)pOS2->usWinAscent, face->units_per_EM);
4051 FontGDI->tmDescent = FT_MulDiv(-lfHeight, (FT_Short)pOS2->usWinDescent, face->units_per_EM);
4052 }
4053 FontGDI->tmHeight = FontGDI->tmAscent + FontGDI->tmDescent;
4054 FontGDI->tmInternalLeading = FontGDI->tmHeight + lfHeight;
4055 }
4056#undef FM_SEL_USE_TYPO_METRICS
4057
4058 FontGDI->Magic = FONTGDI_MAGIC;
4059 FontGDI->lfHeight = lfHeight;
4060 FontGDI->lfWidth = lfWidth;
4061
4062 EmHeight = FontGDI->tmHeight - FontGDI->tmInternalLeading;
4063 EmHeight = max(EmHeight, 1);
4064 EmHeight = min(EmHeight, USHORT_MAX);
4065
4066#if 1
4067 /* I think this is wrong implementation but its test result is better. */
4068 if (lfWidth != 0)
4069 req.width = FT_MulDiv(lfWidth, face->units_per_EM, pOS2->xAvgCharWidth) << 6;
4070#else
4071 /* I think this is correct implementation but it is mismatching to the
4072 other metric functions. The test result is bad. */
4073 if (lfWidth != 0)
4074 req.width = (FT_MulDiv(lfWidth, 96 * 5, 72 * 3) << 6); /* ??? FIXME */
4075#endif
4076 else
4077 req.width = 0;
4078
4079 /* HACK: We do not handle small widths well, so just use zero for these. See CORE-19870. */
4080 if (lfWidth < 10)
4081 req.width = 0;
4082
4084 req.height = (EmHeight << 6);
4085 req.horiResolution = 0;
4086 req.vertResolution = 0;
4087 return FT_Request_Size(face, &req);
4088}
#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().

◆ IntRequestFontSizeEx()

static FT_Error IntRequestFontSizeEx ( FT_Face  face,
const LOGFONTW plf 
)
static

Definition at line 4091 of file freetype.c.

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

Referenced by FontLink_Chain_FindGlyph().

◆ IntSelectFaceCharmap()

static BOOL FASTCALL IntSelectFaceCharmap ( FT_Face  face)
static

Definition at line 7380 of file freetype.c.

7381{
7382 if (face->charmap)
7383 return TRUE;
7384
7385 FT_CharMap charmap, found = NULL;
7386 for (UINT i = 0; i < (UINT)face->num_charmaps; i++)
7387 {
7388 charmap = face->charmaps[i];
7389 if (charmap->encoding != 0)
7390 {
7391 found = charmap;
7392 break;
7393 }
7394 }
7395
7396 if (!found && FT_IS_SFNT(face)) // Not found and (TrueType or OpenType)?
7397 {
7398 DPRINT1("WARNING: Could not find desired charmap!\n");
7399 return FALSE;
7400 }
7401
7402 if (found)
7403 {
7405 FT_Set_Charmap(face, found);
7407 }
7408
7409 return TRUE;
7410}
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 2981 of file freetype.c.

2982{
2983 PBYTE pb = (PBYTE)Otm + sizeof(OUTLINETEXTMETRICW);
2984
2985 /* family name */
2986 Otm->otmpFamilyName = (LPSTR)(pb - (BYTE*) Otm);
2987 pb += IntStoreName(&Names->FamilyNameW, pb);
2988
2989 /* face name */
2990 Otm->otmpFaceName = (LPSTR)(pb - (BYTE*) Otm);
2991 pb += IntStoreName(&Names->FaceNameW, pb);
2992
2993 /* style name */
2994 Otm->otmpStyleName = (LPSTR)(pb - (BYTE*) Otm);
2995 pb += IntStoreName(&Names->StyleNameW, pb);
2996
2997 /* unique name (full name) */
2998 Otm->otmpFullName = (LPSTR)(pb - (BYTE*) Otm);
2999 pb += IntStoreName(&Names->FullNameW, pb);
3000
3001 return pb;
3002}
static SIZE_T FASTCALL IntStoreName(_In_ const UNICODE_STRING *pName, _Out_ PBYTE pb)
Definition: freetype.c:2973
BYTE * PBYTE
Definition: pedump.c:66
char * LPSTR
Definition: typedefs.h:51

Referenced by IntGetOutlineTextMetrics().

◆ IntStoreName()

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

Definition at line 2973 of file freetype.c.

2974{
2975 RtlCopyMemory(pb, pName->Buffer, pName->Length);
2976 *(WCHAR*)&pb[pName->Length] = UNICODE_NULL;
2977 return pName->Length + sizeof(UNICODE_NULL);
2978}
static LPSTR pName
Definition: security.c:116

Referenced by IntStoreFontNames().

◆ IntTranslateCharsetInfo()

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

Definition at line 2654 of file freetype.c.

2660{
2661 int Index = 0;
2662
2663 switch (Flags)
2664 {
2665 case TCI_SRCFONTSIG:
2666 while (Index < MAXTCIINDEX && 0 == (*Src >> Index & 0x0001))
2667 {
2668 Index++;
2669 }
2670 break;
2671 case TCI_SRCCODEPAGE:
2672 while (Index < MAXTCIINDEX && *Src != g_FontTci[Index].ciACP)
2673 {
2674 Index++;
2675 }
2676 break;
2677 case TCI_SRCCHARSET:
2678 while (Index < MAXTCIINDEX && *Src != g_FontTci[Index].ciCharset)
2679 {
2680 Index++;
2681 }
2682 break;
2683 case TCI_SRCLOCALE:
2685 return FALSE;
2686 default:
2687 return FALSE;
2688 }
2689
2690 if (Index >= MAXTCIINDEX || DEFAULT_CHARSET == g_FontTci[Index].ciCharset)
2691 {
2692 return FALSE;
2693 }
2694
2695 RtlCopyMemory(Cs, &g_FontTci[Index], sizeof(CHARSETINFO));
2696
2697 return TRUE;
2698}
#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 5866 of file freetype.c.

5867{
5870
5872 Status = IntGetFontLocalizedName(&Name2, SharedFace, NameID, LangID);
5873
5874 if (NT_SUCCESS(Status))
5875 {
5876 if (RtlCompareUnicodeString(Name1, &Name2, TRUE) == 0)
5877 {
5879 return TRUE;
5880 }
5881
5883 }
5884
5885 return FALSE;
5886}
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 FontLink_PrepareFontInfo(), and MatchFontNames().

◆ MatchFontNames()

static BOOL MatchFontNames ( PSHARED_FACE  SharedFace,
LPCWSTR  lfFaceName 
)
static

Definition at line 5889 of file freetype.c.

5890{
5891 UNICODE_STRING Name1;
5892
5893 if (lfFaceName[0] == UNICODE_NULL)
5894 return FALSE;
5895
5896 RtlInitUnicodeString(&Name1, lfFaceName);
5897
5898 if (MatchFontName(SharedFace, &Name1, TT_NAME_ID_FONT_FAMILY, LANG_ENGLISH) ||
5899 MatchFontName(SharedFace, &Name1, TT_NAME_ID_FULL_NAME, LANG_ENGLISH))
5900 {
5901 return TRUE;
5902 }
5904 {
5905 if (MatchFontName(SharedFace, &Name1, TT_NAME_ID_FONT_FAMILY, gusLanguageID) ||
5906 MatchFontName(SharedFace, &Name1, TT_NAME_ID_FULL_NAME, gusLanguageID))
5907 {
5908 return TRUE;
5909 }
5910 }
5911 return FALSE;
5912}

Referenced by TextIntRealizeFont().

◆ 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 7261 of file freetype.c.

7271{
7272 BOOL Result = FALSE;
7274 RECTL SafeRect;
7275 BYTE LocalBuffer[STACK_TEXT_BUFFER_SIZE];
7276 PVOID Buffer = LocalBuffer;
7277 LPCWSTR SafeString = NULL;
7278 PINT SafeDx = NULL;
7279 ULONG BufSize, StringSize, DxSize = 0;
7280
7281 /* Check if String is valid */
7282 if ((Count > 0xFFFF) || (Count > 0 && UnsafeString == NULL))
7283 {
7285 return FALSE;
7286 }
7287
7288 if (Count > 0)
7289 {
7290 /* Calculate buffer size for string and Dx values */
7291 BufSize = StringSize = Count * sizeof(WCHAR);
7292 if (UnsafeDx)
7293 {
7294 /* If ETO_PDY is specified, we have pairs of INTs */
7295 DxSize = (Count * sizeof(INT)) * ((fuOptions & ETO_PDY) ? 2 : 1);
7296 BufSize += DxSize;
7297 }
7298
7299 /* Check if our local buffer is large enough */
7300 if (BufSize > sizeof(LocalBuffer))
7301 {
7302 /* It's not, allocate a temp buffer */
7304 if (!Buffer)
7305 {
7306 return FALSE;
7307 }
7308 }
7309
7310 /* Probe and copy user mode data to the buffer */
7311 _SEH2_TRY
7312 {
7313 /* Put the Dx before the String to assure alignment of 4 */
7314 SafeString = (LPCWSTR)(((ULONG_PTR)Buffer) + DxSize);
7315
7316 /* Probe and copy the string */
7317 ProbeForRead(UnsafeString, StringSize, 1);
7318 RtlCopyMemory((PVOID)SafeString, UnsafeString, StringSize);
7319
7320 /* If we have Dx values... */
7321 if (UnsafeDx)
7322 {
7323 /* ... probe and copy them */
7324 SafeDx = Buffer;
7325 ProbeForRead(UnsafeDx, DxSize, 1);
7326 RtlCopyMemory(SafeDx, UnsafeDx, DxSize);
7327 }
7328 }
7330 {
7332 }
7333 _SEH2_END
7334 if (!NT_SUCCESS(Status))
7335 {
7336 goto cleanup;
7337 }
7338 }
7339
7340 /* If we have a rect, copy it */
7341 if (UnsafeRect)
7342 {
7343 _SEH2_TRY
7344 {
7345 ProbeForRead(UnsafeRect, sizeof(RECT), 1);
7346 SafeRect = *UnsafeRect;
7347 }
7349 {
7351 }
7352 _SEH2_END
7353 if (!NT_SUCCESS(Status))
7354 {
7355 goto cleanup;
7356 }
7357 }
7358
7359 /* Finally call the internal routine */
7361 XStart,
7362 YStart,
7363 fuOptions,
7364 &SafeRect,
7365 SafeString,
7366 Count,
7367 SafeDx,
7368 dwCodePage);
7369
7370cleanup:
7371 /* If we allocated a buffer, free it */
7372 if (Buffer != LocalBuffer)
7373 {
7375 }
7376
7377 return Result;
7378}
#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:7219
#define STACK_TEXT_BUFFER_SIZE
Definition: freetype.c:7257
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204

◆ NtGdiGetFontFamilyInfo()

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

Definition at line 6486 of file freetype.c.

6491{
6493 LOGFONTW LogFont;
6495 LONG GotCount, AvailCount, SafeInfoCount;
6497
6498 if (UnsafeLogFont == NULL || UnsafeInfo == NULL || UnsafeInfoCount == NULL)
6499 {
6501 return -1;
6502 }
6503
6504 Status = MmCopyFromCaller(&SafeInfoCount, UnsafeInfoCount, sizeof(SafeInfoCount));
6505 if (!NT_SUCCESS(Status))
6506 {
6508 return -1;
6509 }
6510 GotCount = 0;
6511 Status = MmCopyToCaller(UnsafeInfoCount, &GotCount, sizeof(*UnsafeInfoCount));
6512 if (!NT_SUCCESS(Status))
6513 {
6515 return -1;
6516 }
6517 Status = MmCopyFromCaller(&LogFont, UnsafeLogFont, sizeof(LOGFONTW));
6518 if (!NT_SUCCESS(Status))
6519 {
6521 return -1;
6522 }
6523 if (SafeInfoCount <= 0)
6524 {
6526 return -1;
6527 }
6528
6529 /* Allocate space for a safe copy */
6530 Status = RtlULongMult(SafeInfoCount, sizeof(FONTFAMILYINFO), &DataSize);
6532 {
6533 DPRINT1("Overflowed.\n");
6535 return -1;
6536 }
6538 if (Info == NULL)
6539 {
6541 return -1;
6542 }
6543
6544 /* Retrieve the information */
6545 AvailCount = IntGetFontFamilyInfo(Dc, &LogFont, Info, SafeInfoCount);
6546 GotCount = min(AvailCount, SafeInfoCount);
6547 SafeInfoCount = AvailCount;
6548
6549 /* Return data to caller */
6550 if (GotCount > 0)
6551 {
6552 Status = RtlULongMult(GotCount, sizeof(FONTFAMILYINFO), &DataSize);
6554 {
6555 DPRINT1("Overflowed.\n");
6558 return -1;
6559 }
6560 Status = MmCopyToCaller(UnsafeInfo, Info, DataSize);
6561 if (!NT_SUCCESS(Status))
6562 {
6565 return -1;
6566 }
6567 Status = MmCopyToCaller(UnsafeInfoCount, &SafeInfoCount, sizeof(*UnsafeInfoCount));
6568 if (!NT_SUCCESS(Status))
6569 {
6572 return -1;
6573 }
6574 }
6575
6577
6578 return GotCount;
6579}
#define LONG_MAX
Definition: limits.h:30
LONG FASTCALL IntGetFontFamilyInfo(HDC Dc, const LOGFONTW *SafeLogFont, PFONTFAMILYINFO SafeInfo, LONG InfoCount)
Definition: freetype.c:6446
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
#define MmCopyFromCaller
Definition: polytest.cpp:29

Referenced by IntEnumFontFamilies().

◆ RemoveCachedEntry()

static void RemoveCachedEntry ( PFONT_CACHE_ENTRY  Entry)
static

◆ RemoveCacheEntries()

static void RemoveCacheEntries ( FT_Face  Face)
static

Definition at line 474 of file freetype.c.

475{
476 PLIST_ENTRY CurrentEntry, NextEntry;
477 PFONT_CACHE_ENTRY FontEntry;
478
480
481 for (CurrentEntry = g_FontCacheListHead.Flink;
482 CurrentEntry != &g_FontCacheListHead;
483 CurrentEntry = NextEntry)
484 {
485 FontEntry = CONTAINING_RECORD(CurrentEntry, FONT_CACHE_ENTRY, ListEntry);
486 NextEntry = CurrentEntry->Flink;
487
488 if (FontEntry->Hashed.Face == Face)
489 {
490 RemoveCachedEntry(FontEntry);
491 }
492 }
493}

Referenced by SharedFace_Release().

◆ RTL_STATIC_LIST_HEAD() [1/4]

static RTL_STATIC_LIST_HEAD ( g_FontCacheListHead  )
static

◆ RTL_STATIC_LIST_HEAD() [2/4]

static RTL_STATIC_LIST_HEAD ( g_FontLinkEntries  )
static

◆ RTL_STATIC_LIST_HEAD() [3/4]

static RTL_STATIC_LIST_HEAD ( g_FontListHead  )
static

◆ RTL_STATIC_LIST_HEAD() [4/4]

static RTL_STATIC_LIST_HEAD ( g_FontSubstListHead  )
static

◆ SharedFace_AddRef()

static void SharedFace_AddRef ( PSHARED_FACE  Ptr)
static

Definition at line 454 of file freetype.c.

455{
457
458 ++Ptr->RefCount;
459}
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898

Referenced by IntGdiLoadFontsFromMemory().

◆ SharedFace_Create()

static PSHARED_FACE SharedFace_Create ( FT_Face  Face,
PSHARED_MEM  Memory 
)
static

Definition at line 419 of file freetype.c.

420{
423 if (Ptr)
424 {
425 Ptr->Face = Face;
426 Ptr->RefCount = 1;
427 Ptr->Memory = Memory;
428 SharedFaceCache_Init(&Ptr->EnglishUS);
429 SharedFaceCache_Init(&Ptr->UserLanguage);
430
432 DPRINT("Creating SharedFace for %s\n", Face->family_name ? Face->family_name : "<NULL>");
433 }
434 return Ptr;
435}
static void SharedMem_AddRef(PSHARED_MEM Ptr)
Definition: freetype.c:403
static void SharedFaceCache_Init(PSHARED_FACE_CACHE Cache)
Definition: freetype.c:411
_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 523 of file freetype.c.

524{
525 if (bDoLock)
527 else
529
530 ASSERT(Ptr->RefCount > 0);
531
532 if (Ptr->RefCount <= 0)
533 return;
534
535 --Ptr->RefCount;
536 if (Ptr->RefCount == 0)
537 {
538 DPRINT("Releasing SharedFace for %s\n", Ptr->Face->family_name ? Ptr->Face->family_name : "<NULL>");
539 RemoveCacheEntries(Ptr->Face);
540 FT_Done_Face(Ptr->Face);
541 SharedMem_Release(Ptr->Memory);
542 SharedFaceCache_Release(&Ptr->EnglishUS);
543 SharedFaceCache_Release(&Ptr->UserLanguage);
545 }
546
547 if (bDoLock)
549}
static void RemoveCacheEntries(FT_Face Face)
Definition: freetype.c:474
static void SharedFaceCache_Release(PSHARED_FACE_CACHE Cache)
Definition: freetype.c:516
FT_Done_Face(FT_Face face)
Definition: ftobjs.c:2783

Referenced by CleanupFontEntryEx(), and IntGdiLoadFontsFromMemory().

◆ SharedFaceCache_Init()

static void SharedFaceCache_Init ( PSHARED_FACE_CACHE  Cache)
static

Definition at line 411 of file freetype.c.

412{
413 Cache->OutlineRequiredSize = 0;
416}

Referenced by SharedFace_Create().

◆ SharedFaceCache_Release()

static void SharedFaceCache_Release ( PSHARED_FACE_CACHE  Cache)
static

Definition at line 516 of file freetype.c.

517{
520}

Referenced by SharedFace_Release().

◆ SharedMem_AddRef()

static void SharedMem_AddRef ( PSHARED_MEM  Ptr)
static

Definition at line 403 of file freetype.c.

404{
406
407 ++Ptr->RefCount;
408}

Referenced by SharedFace_Create().

◆ SharedMem_Create()

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

Definition at line 438 of file freetype.c.

439{
442 if (Ptr)
443 {
444 Ptr->Buffer = Buffer;
445 Ptr->BufferSize = BufferSize;
446 Ptr->RefCount = 1;
447 Ptr->IsMapping = IsMapping;
448 DPRINT("Creating SharedMem for %p (%i, %p)\n", Buffer, IsMapping, Ptr);
449 }
450 return Ptr;
451}
#define BufferSize
Definition: mmc.h:75

Referenced by IntGdiAddFontMemResource(), and IntGdiAddFontResourceSingle().

◆ SharedMem_Release()

static void SharedMem_Release ( PSHARED_MEM  Ptr)
static

Definition at line 495 of file freetype.c.

496{
498 ASSERT(Ptr->RefCount > 0);
499
500 if (Ptr->RefCount <= 0)
501 return;
502
503 --Ptr->RefCount;
504 if (Ptr->RefCount == 0)
505 {
506 DPRINT("Releasing SharedMem for %p (%i, %p)\n", Ptr->Buffer, Ptr->IsMapping, Ptr);
507 if (Ptr->IsMapping)
509 else
512 }
513}
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 1079 of file freetype.c.

1084{
1085 PLIST_ENTRY pListEntry;
1086 PFONTSUBST_ENTRY pSubstEntry;
1087 BYTE CharSets[FONTSUBST_FROM_AND_TO];
1088
1089 CharSetMap[FONTSUBST_FROM] = DEFAULT_CHARSET;
1090 CharSetMap[FONTSUBST_TO] = RequestedCharSet;
1091
1092 /* for each list entry */
1093 for (pListEntry = pHead->Flink;
1094 pListEntry != pHead;
1095 pListEntry = pListEntry->Flink)
1096 {
1097 pSubstEntry = CONTAINING_RECORD(pListEntry, FONTSUBST_ENTRY, ListEntry);
1098
1099 CharSets[FONTSUBST_FROM] = pSubstEntry->CharSets[FONTSUBST_FROM];
1100
1101 if (CharSets[FONTSUBST_FROM] != DEFAULT_CHARSET &&
1102 CharSets[FONTSUBST_FROM] != RequestedCharSet)
1103 {
1104 continue; /* not matched */
1105 }
1106
1107 /* does charset number exist? (to) */
1108 if (pSubstEntry->CharSets[FONTSUBST_TO] != DEFAULT_CHARSET)
1109 {
1110 CharSets[FONTSUBST_TO] = pSubstEntry->CharSets[FONTSUBST_TO];
1111 }
1112 else
1113 {
1114 CharSets[FONTSUBST_TO] = RequestedCharSet;
1115 }
1116
1117 /* does font name match? */
1119 pInputName, TRUE))
1120 {
1121 continue; /* not matched */
1122 }
1123
1124 /* update *pOutputName */
1125 *pOutputName = pSubstEntry->FontNames[FONTSUBST_TO];
1126
1127 if (CharSetMap[FONTSUBST_FROM] == DEFAULT_CHARSET)
1128 {
1129 /* update CharSetMap */
1130 CharSetMap[FONTSUBST_FROM] = CharSets[FONTSUBST_FROM];
1131 CharSetMap[FONTSUBST_TO] = CharSets[FONTSUBST_TO];
1132 }
1133 return TRUE; /* success */
1134 }
1135
1136 return FALSE;
1137}

Referenced by SubstituteFontRecurse().

◆ SubstituteFontRecurse()

static BOOL SubstituteFontRecurse ( PLOGFONTW  pLogFont)
static

Definition at line 1140 of file freetype.c.

1141{
1142 UINT RecurseCount = 5;
1143 UNICODE_STRING OutputNameW = { 0 };
1144 BYTE CharSetMap[FONTSUBST_FROM_AND_TO];
1145 BOOL Found;
1146 UNICODE_STRING InputNameW;
1147
1148 if (pLogFont->lfFaceName[0] == UNICODE_NULL)
1149 return FALSE;
1150
1151 RtlInitUnicodeString(&InputNameW, pLogFont->lfFaceName);
1152
1153 while (RecurseCount-- > 0)
1154 {
1155 Found = SubstituteFontByList(&g_FontSubstListHead,
1156 &OutputNameW, &InputNameW,
1157 pLogFont->lfCharSet, CharSetMap);
1158 if (!Found)
1159 break;
1160
1161 IntUnicodeStringToBuffer(pLogFont->lfFaceName, sizeof(pLogFont->lfFaceName), &OutputNameW);
1162 RtlInitUnicodeString(&InputNameW, pLogFont->lfFaceName);
1163
1164 if (CharSetMap[FONTSUBST_FROM] == DEFAULT_CHARSET ||
1165 CharSetMap[FONTSUBST_FROM] == pLogFont->lfCharSet)
1166 {
1167 pLogFont->lfCharSet = CharSetMap[FONTSUBST_TO];
1168 }
1169 }
1170
1171 return TRUE; /* success */
1172}
static BOOL SubstituteFontByList(PLIST_ENTRY pHead, PUNICODE_STRING pOutputName, PUNICODE_STRING pInputName, BYTE RequestedCharSet, BYTE CharSetMap[FONTSUBST_FROM_AND_TO])
Definition: freetype.c:1079
BYTE lfCharSet
Definition: wingdi.h:2351

Referenced by FontLink_Create(), FontLink_FindEntry(), GetFontFamilyInfoForSubstitutes(), and TextIntRealizeFont().

◆ TextIntCreateFontIndirect()

NTSTATUS FASTCALL TextIntCreateFontIndirect ( CONST LPLOGFONTW  lf,
HFONT NewFont 
)

Definition at line 2612 of file freetype.c.

2613{
2614 PLFONT plfont;
2615 LOGFONTW *plf;
2616
2617 ASSERT(lf);
2618 plfont = LFONT_AllocFontWithHandle();
2619 if (!plfont)
2620 {
2621 return STATUS_NO_MEMORY;
2622 }
2623
2624 ExInitializePushLock(&plfont->lock);
2625 *NewFont = plfont->BaseObject.hHmgr;
2626 plf = &plfont->logfont.elfEnumLogfontEx.elfLogFont;
2627 RtlCopyMemory(plf, lf, sizeof(LOGFONTW));
2628 if (lf->lfEscapement != lf->lfOrientation)
2629 {
2630 /* This should really depend on whether GM_ADVANCED is set */
2631 plf->lfOrientation = plf->lfEscapement;
2632 }
2633 LFONT_UnlockFont(plfont);
2634
2635 return STATUS_SUCCESS;
2636}
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 4972 of file freetype.c.

4982{
4983 PFONTGDI FontGDI;
4984 FT_BitmapGlyph realglyph;
4985 INT glyph_index, i, previous, nTenthsOfDegrees;
4986 ULONGLONG TotalWidth64 = 0;
4987 LOGFONTW *plf;
4988 BOOL use_kerning, bVerticalWriting;
4989 LONG ascender, descender;
4990 FONT_CACHE_ENTRY Cache;
4991 DWORD ch0, ch1;
4992 FONTLINK_CHAIN Chain;
4993
4994 FontGDI = ObjToGDI(TextObj->Font, FONT);
4995
4996 Cache.Hashed.Face = FontGDI->SharedFace->Face;
4997 if (NULL != Fit)
4998 {
4999 *Fit = 0;
5000 }
5001
5002 plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
5003 Cache.Hashed.lfHeight = plf->lfHeight;
5004 Cache.Hashed.lfWidth = plf->lfWidth;
5005 Cache.Hashed.Aspect.Emu.Bold = EMUBOLD_NEEDED(FontGDI->OriginalWeight, plf->lfWeight);
5006 Cache.Hashed.Aspect.Emu.Italic = (plf->lfItalic && !FontGDI->OriginalItalic);
5007
5008 // Check vertical writing (tategaki)
5009 nTenthsOfDegrees = IntNormalizeAngle(plf->lfEscapement - plf->lfOrientation);
5010 bVerticalWriting = ((nTenthsOfDegrees == 90 * 10) || (nTenthsOfDegrees == 270 * 10));
5011
5014 else
5016
5017 // NOTE: GetTextExtentPoint32 simply ignores lfEscapement and XFORM.
5019 TextIntUpdateSize(dc, TextObj, FontGDI, FALSE);
5022
5023 FontLink_Chain_Init(&Chain, TextObj, Cache.Hashed.Face);
5024
5025 use_kerning = FT_HAS_KERNING(Cache.Hashed.Face);
5026 previous = 0;
5027
5028 for (i = 0; i < Count; i++)
5029 {
5030 ch0 = *String++;
5031 if (IS_HIGH_SURROGATE(ch0))
5032 {
5033 ++i;
5034 if (i >= Count)
5035 break;
5036
5037 ch1 = *String++;
5038 if (IS_LOW_SURROGATE(ch1))
5039 ch0 = Utf32FromSurrogatePair(ch0, ch1);
5040 }
5041
5042 glyph_index = FontLink_Chain_FindGlyph(&Chain, &Cache, &Cache.Hashed.Face, ch0,
5043 (fl & GTEF_INDICES));
5044 Cache.Hashed.GlyphIndex = glyph_index;
5045
5046 realglyph = IntGetRealGlyph(&Cache);
5047 if (!realglyph)
5048 break;
5049
5050 /* Retrieve kerning distance */
5051 if (use_kerning && previous && glyph_index)
5052 {
5053 FT_Vector delta;
5054 FT_Get_Kerning(Cache.Hashed.Face, previous, glyph_index, 0, &delta);
5055 TotalWidth64 += delta.x;
5056 }
5057
5058 TotalWidth64 += realglyph->root.advance.x >> 10;
5059
5060 if (((TotalWidth64 + 32) >> 6) <= MaxExtent && NULL != Fit)
5061 {
5062 *Fit = i + 1;
5063 }
5064 if (NULL != Dx)
5065 {
5066 Dx[i] = (TotalWidth64 + 32) >> 6;
5067 }
5068
5069 previous = glyph_index;
5070 }
5071 ASSERT(FontGDI->Magic == FONTGDI_MAGIC);
5072 ascender = FontGDI->tmAscent; /* Units above baseline */
5073 descender = FontGDI->tmDescent; /* Units below baseline */
5075
5076 if (bVerticalWriting)
5077 {
5078 Size->cx = ascender + descender;
5079 Size->cy = (TotalWidth64 + 32) >> 6;
5080 }
5081 else
5082 {
5083 Size->cx = (TotalWidth64 + 32) >> 6;
5084 Size->cy = ascender + descender;
5085 }
5086
5087 return TRUE;
5088}
#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 5994 of file freetype.c.

5995{
5997 PTEXTOBJ TextObj;
5998 PPROCESSINFO Win32Process;
5999 ULONG MatchPenalty;
6000 LOGFONTW *pLogFont;
6001 LOGFONTW SubstitutedLogFont;
6002
6004
6005 if (!pTextObj)
6006 {
6007 TextObj = TEXTOBJ_LockText(FontHandle);
6008 if (NULL == TextObj)
6009 {
6010 return STATUS_INVALID_HANDLE;
6011 }
6012
6013 if (TextObj->fl & TEXTOBJECT_INIT)
6014 {
6015 TEXTOBJ_UnlockText(TextObj);
6016 return STATUS_SUCCESS;
6017 }
6018 }
6019 else
6020 {
6021 TextObj = pTextObj;
6022 }
6023
6024 pLogFont = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
6025
6026 /* substitute */
6027 SubstitutedLogFont = *pLogFont;
6028 SubstituteFontRecurse(&SubstitutedLogFont);
6029 DPRINT("Font '%S,%u' is substituted by '%S,%u'.\n",
6030 pLogFont->lfFaceName, pLogFont->lfCharSet,
6031 SubstitutedLogFont.lfFaceName, SubstitutedLogFont.lfCharSet);
6032
6033 MatchPenalty = 0xFFFFFFFF;
6034 TextObj->Font = NULL;
6035
6036 Win32Process = PsGetCurrentProcessWin32Process();
6037
6038 /* Search private fonts */
6040 IntLockProcessPrivateFonts(Win32Process);
6041 FindBestFontFromList(&TextObj->Font, &MatchPenalty, &SubstitutedLogFont,
6042 &Win32Process->PrivateFontListHead);
6043 IntUnLockProcessPrivateFonts(Win32Process);
6044
6045 /* Search system fonts */
6046 FindBestFontFromList(&TextObj->Font, &MatchPenalty, &SubstitutedLogFont,
6047 &g_FontListHead);
6049
6050 if (NULL == TextObj->Font)
6051 {
6052 DPRINT1("Request font %S not found, no fonts loaded at all\n",
6053 pLogFont->lfFaceName);
6055 }
6056 else
6057 {
6059 PFONTGDI FontGdi = ObjToGDI(TextObj->Font, FONT);
6060 PSHARED_FACE SharedFace = FontGdi->SharedFace;
6061
6062 TextObj->TextFace[0] = UNICODE_NULL;
6064 if (MatchFontNames(SharedFace, SubstitutedLogFont.lfFaceName))
6065 {
6067 RtlStringCchCopyW(TextObj->TextFace, _countof(TextObj->TextFace), pLogFont->lfFaceName);
6068 }
6069 else
6070 {
6074 if (NT_SUCCESS(Status))
6075 {
6076 /* truncated copy */
6077 IntUnicodeStringToBuffer(TextObj->TextFace, sizeof(TextObj->TextFace), &Name);
6079 }
6080 }
6081
6082 // Need hdev, when freetype is loaded need to create DEVOBJ for
6083 // Consumer and Producer.
6084 TextObj->Font->iUniq = 1; // Now it can be cached.
6085 IntFontType(FontGdi);
6086 FontGdi->flType = TextObj->Font->flFontType;
6087 FontGdi->RequestUnderline = pLogFont->lfUnderline ? 0xFF : 0;
6088 FontGdi->RequestStrikeOut = pLogFont->lfStrikeOut ? 0xFF : 0;
6089 FontGdi->RequestItalic = pLogFont->lfItalic ? 0xFF : 0;
6090 if (pLogFont->lfWeight != FW_DONTCARE)
6091 FontGdi->RequestWeight = pLogFont->lfWeight;
6092 else
6093 FontGdi->RequestWeight = FW_NORMAL;
6094
6095 TextObj->fl |= TEXTOBJECT_INIT;
6097 }
6098
6099 if (!pTextObj) TEXTOBJ_UnlockText(TextObj);
6100
6101 ASSERT((NT_SUCCESS(Status) ^ (NULL == TextObj->Font)) != 0);
6102
6103 return Status;
6104}
static VOID FASTCALL IntFontType(PFONTGDI Font)
Definition: freetype.c:5834
static BOOL MatchFontNames(PSHARED_FACE SharedFace, LPCWSTR lfFaceName)
Definition: freetype.c:5889
FLONG flType
Definition: engobjects.h:142
ULONG iUniq
Definition: winddi.h:762
FLONG flFontType
Definition: winddi.h:765
FLONG fl
Definition: text.h:65
FORCEINLINE PTEXTOBJ TEXTOBJ_LockText(HFONT hfont)
Definition: text.h:83
#define TEXTOBJECT_INIT
Definition: text.h:56

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

◆ TextIntUpdateSize()

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

Definition at line 4212 of file freetype.c.

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

2477{
2478 PFONT_ENTRY_MEM FontMemEntry = Collection->Entry;
2479 PLIST_ENTRY ListEntry;
2480 RemoveEntryList(&Collection->ListEntry);
2481
2482 do {
2483 /* Also unlink the FONT_ENTRY stuff from the PrivateFontListHead */
2484 RemoveEntryList(&FontMemEntry->Entry->ListEntry);
2485
2486 ListEntry = FontMemEntry->ListEntry.Flink;
2487 FontMemEntry = CONTAINING_RECORD(ListEntry, FONT_ENTRY_MEM, ListEntry);
2488
2489 } while (FontMemEntry != Collection->Entry);
2490}
_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 1873 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 242 of file freetype.c.

Referenced by FontFamilyFillInfo().

◆ g_FontCacheNumEntries

UINT g_FontCacheNumEntries
static

Definition at line 240 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 209 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 214 of file freetype.c.

Referenced by FreeFontSupport(), and InitFontSupport().

◆ g_RenderingEnabled

BOOL g_RenderingEnabled = TRUE
static

Definition at line 217 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 201 of file freetype.c.

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

◆ s_chFontLinkDefaultChar

DWORD s_chFontLinkDefaultChar = FONTLINK_DEFAULT_CHAR
static

Definition at line 61 of file freetype.c.

Referenced by FontLink_Chain_FindGlyph(), and FontLink_LoadSettings().

◆ s_fFontLinkUseAnsi

BOOL s_fFontLinkUseAnsi = FALSE
static

Definition at line 64 of file freetype.c.

Referenced by FontLink_Chain_Populate(), and FontLink_LoadDefaultCharset().

◆ s_fFontLinkUseOem

BOOL s_fFontLinkUseOem = FALSE
static

Definition at line 65 of file freetype.c.

Referenced by FontLink_Chain_Populate(), and FontLink_LoadDefaultCharset().

◆ s_fFontLinkUseSymbol

BOOL s_fFontLinkUseSymbol = FALSE
static

Definition at line 66 of file freetype.c.

Referenced by FontLink_Chain_Populate(), and FontLink_LoadDefaultCharset().

◆ s_szDefFontLinkFileName

WCHAR s_szDefFontLinkFileName[MAX_PATH] = L""
static

Definition at line 62 of file freetype.c.

Referenced by FontLink_Chain_Populate(), and FontLink_LoadDefaultFonts().

◆ s_szDefFontLinkFontName

WCHAR s_szDefFontLinkFontName[MAX_PATH] = L""
static

Definition at line 63 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 1196 of file freetype.c.

Referenced by FontLink_Chain_FindEntry().

◆ 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 1188 of file freetype.c.

Referenced by FontLink_Chain_FindEntry().