ReactOS 0.4.17-dev-218-g5635d24
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 (PFONTGDI FontGDI, LONG lfWidth, LONG lfHeight)
 
static FT_Error IntRequestFontSizeEx (FT_Face face, const LOGFONTW *plf)
 
BOOL FASTCALL TextIntUpdateSize (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 5414 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 7256 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 5959 of file freetype.c.

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

5767{
5768 ULONG Penalty;
5770 PFONT_ENTRY CurrentEntry;
5771 FONTGDI *FontGDI;
5772 OUTLINETEXTMETRICW *Otm = NULL;
5773 UINT OtmSize, OldOtmSize = 0;
5774 FT_Face Face;
5775
5776 ASSERT(FontObj);
5777 ASSERT(MatchPenalty);
5778 ASSERT(LogFont);
5779 ASSERT(Head);
5780
5781 /* Start with a pretty big buffer */
5782 OldOtmSize = 0x200;
5783 Otm = ExAllocatePoolWithTag(PagedPool, OldOtmSize, GDITAG_TEXT);
5784
5785 /* get the FontObj of lowest penalty */
5786 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
5787 {
5788 CurrentEntry = CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry);
5789
5790 FontGDI = CurrentEntry->Font;
5791 ASSERT(FontGDI);
5792 Face = FontGDI->SharedFace->Face;
5793
5794 /* get text metrics */
5796 OtmSize = IntGetOutlineTextMetrics(FontGDI, 0, NULL, TRUE);
5797 if (OtmSize > OldOtmSize)
5798 {
5799 if (Otm)
5802 }
5803
5804 /* update FontObj if lowest penalty */
5805 if (Otm)
5806 {
5808 IntRequestFontSize(FontGDI, LogFont->lfWidth, LogFont->lfHeight);
5809
5811 OtmSize = IntGetOutlineTextMetrics(FontGDI, OtmSize, Otm, TRUE);
5812 if (!OtmSize)
5813 continue;
5814
5815 OldOtmSize = OtmSize;
5816
5817 Penalty = GetFontPenalty(LogFont, Otm, Face->style_name);
5818 if (*MatchPenalty == MAXULONG || Penalty < *MatchPenalty)
5819 {
5820 *FontObj = GDIToObj(FontGDI, FONT);
5821 *MatchPenalty = Penalty;
5822 }
5823 }
5824 }
5825
5826 if (Otm)
5828}
#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:5418
static FT_Error IntRequestFontSize(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:5216
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 4337 of file freetype.c.

4339{
4340#if 0
4341 PLIST_ENTRY Entry, Head;
4342 PFONTLINK pFontLink;
4343 INT iLink = 0;
4344
4345 DPRINT1("%S, %p, %p\n", pChain->LogFont.lfFaceName, pChain->pBaseTextObj, pChain->pDefFace);
4346
4347 Head = &pChain->FontLinkList;
4348 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
4349 {
4350 pFontLink = CONTAINING_RECORD(Entry, FONTLINK, ListEntry);
4351 DPRINT1("FontLink #%d: %p, %d, %S, %p, %p\n",
4352 iLink, pFontLink, pFontLink->bIgnore, pFontLink->LogFont.lfFaceName,
4353 pFontLink->pFontGDI, pFontLink->SharedFace);
4354 ++iLink;
4355 }
4356#endif
4357}
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 4381 of file freetype.c.

4387{
4388 PFONTLINK pFontLink;
4389 PLIST_ENTRY Entry, Head;
4390 UINT index;
4391 FT_Face face;
4392
4393 // Try the default font at first
4394 index = get_glyph_index_flagged(pChain->pDefFace, code, fCodeAsIndex);
4395 if (index)
4396 {
4397 DPRINT("code: 0x%08X, index: 0x%08X, fCodeAsIndex:%d\n", code, index, fCodeAsIndex);
4398 pCache->Hashed.Face = *pFace = pChain->pDefFace;
4399 return index; // The glyph is found on the default font
4400 }
4401
4402 if (!FontLink_Chain_IsPopulated(pChain)) // The chain is not populated yet
4403 {
4405 FontLink_Chain_Dump(pChain);
4406 }
4407
4408 // Now the chain is populated. Looking for the target glyph...
4409 Head = &pChain->FontLinkList;
4410 for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
4411 {
4412 pFontLink = CONTAINING_RECORD(Entry, FONTLINK, ListEntry);
4413 if (!FontLink_PrepareFontInfo(pFontLink))
4414 continue; // This link is not useful, check the next one
4415
4416 face = pFontLink->SharedFace->Face;
4418 if (!index)
4419 continue; // The glyph does not exist, continue searching
4420
4421 // The target glyph is found in the chain
4422 DPRINT("code: 0x%08X, index: 0x%08X\n", code, index);
4423 pCache->Hashed.Face = *pFace = face;
4424 if (IntNeedRequestFontSize(pChain, face, Entry))
4425 IntRequestFontSizeEx(face, &pChain->LogFont);
4426 FT_Set_Transform(face, &pCache->Hashed.matTransform, NULL);
4427 return index;
4428 }
4429
4430 // No target glyph found in the chain: use default glyph
4432 index = get_glyph_index(*pFace, code);
4433 DPRINT("code: 0x%08X, index: 0x%08X\n", code, index);
4434 pCache->Hashed.Face = *pFace = pChain->pDefFace;
4435 return index;
4436}
#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:4331
static BOOL IntNeedRequestFontSize(PFONTLINK_CHAIN pChain, FT_Face face, PLIST_ENTRY TargetEntry)
Definition: freetype.c:4360
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:4337
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:4316
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:24
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 DPRINT("szName: %S\n", szName);
938 DPRINT("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:5764
static BOOL MatchFontName(PSHARED_FACE SharedFace, PUNICODE_STRING Name1, FT_UShort NameID, FT_UShort LangID)
Definition: freetype.c:5865
#define TT_NAME_ID_FONT_FAMILY
Definition: font.c:3578
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 5376 of file freetype.c.

5382{
5384 FT_Face Face = FontGdi->SharedFace->Face;
5385
5387
5388 if (FT_IS_SFNT(Face))
5389 {
5390 if (Table)
5391 Table = Table >> 24 | Table << 24 | (Table >> 8 & 0xFF00) |
5392 (Table << 8 & 0xFF0000);
5393
5394 if (!Buffer) Size = 0;
5395
5396 if (Buffer && Size)
5397 {
5399 FT_ULong Needed = 0;
5400
5401 Error = FT_Load_Sfnt_Table(Face, Table, Offset, NULL, &Needed);
5402
5403 if ( !Error && Needed < Size) Size = Needed;
5404 }
5405 if (!FT_Load_Sfnt_Table(Face, Table, Offset, Buffer, &Size))
5406 Result = Size;
5407 }
5408
5410
5411 return Result;
5412}
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 4443 of file freetype.c.

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

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

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

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

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

◆ ftGdiRealizationInfo()

BOOL FASTCALL ftGdiRealizationInfo ( PFONTGDI  Font,
PREALIZATION_INFO  Info 
)

Definition at line 6375 of file freetype.c.

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

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

4317{
4318 FT_UInt ret;
4319
4320 if (face_has_symbol_charmap(ft_face))
4321 {
4322 ret = get_glyph_index_symbol(ft_face, glyph);
4323 if (ret != 0)
4324 return ret;
4325 }
4326
4327 return FT_Get_Char_Index(ft_face, glyph);
4328}
return ret
Definition: mutex.c:146
static FT_UInt FASTCALL get_glyph_index_symbol(FT_Face ft_face, UINT glyph)
Definition: freetype.c:4302
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 4331 of file freetype.c.

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

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

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

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

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

7228{
7229 BOOL bResult;
7230 DC *dc;
7231
7232 // TODO: Write test-cases to exactly match real Windows in different
7233 // bad parameters (e.g. does Windows check the DC or the RECT first?).
7234 dc = DC_LockDc(hDC);
7235 if (!dc)
7236 {
7238 return FALSE;
7239 }
7240
7241 bResult = IntExtTextOutW( dc,
7242 XStart,
7243 YStart,
7244 fuOptions,
7245 lprc,
7246 String,
7247 Count,
7248 Dx,
7249 dwCodePage );
7250
7251 DC_UnlockDc(dc);
7252
7253 return bResult;
7254}
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:6672
_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 7415 of file freetype.c.

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

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

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

5981{
5983 if (FamInfo->EnumLogFontEx.elfStyle[0] &&
5984 _wcsicmp(FamInfo->EnumLogFontEx.elfStyle, L"Regular") != 0)
5985 {
5986 wcscat(psz, L" ");
5987 wcscat(psz, FamInfo->EnumLogFontEx.elfStyle);
5988 }
5989}
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 6672 of file freetype.c.

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

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

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

7603{
7604 TT_OS2 *pOS2;
7605 FT_WinFNT_HeaderRec WinFNT;
7607
7609
7610 if (FT_IS_SFNT(Face)) // TrueType / OpenType
7611 {
7613 pOS2 = FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
7614 if (pOS2)
7615 *pDefChar = pOS2->usDefaultChar;
7617 return !!pOS2;
7618 }
7619
7620 if (!FT_IS_SCALABLE(Face)) // *.fon / *.fnt
7621 {
7623 error = FT_Get_WinFNT_Header(Face, &WinFNT);
7625 if (!error)
7626 *pDefChar = WinFNT.default_char;
7627 return !error;
7628 }
7629
7630 *pDefChar = 0; // .notdef
7631 return TRUE;
7632}
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 6445 of file freetype.c.

6449{
6450 LONG AvailCount = 0;
6451 PPROCESSINFO Win32Process;
6452
6453 /* Enumerate font families in the global list */
6455 if (!GetFontFamilyInfoForList(SafeLogFont, SafeInfo, NULL, &AvailCount,
6456 InfoCount, &g_FontListHead))
6457 {
6459 return -1;
6460 }
6461
6462 /* Enumerate font families in the process local list */
6463 Win32Process = PsGetCurrentProcessWin32Process();
6464 IntLockProcessPrivateFonts(Win32Process);
6465 if (!GetFontFamilyInfoForList(SafeLogFont, SafeInfo, NULL, &AvailCount, InfoCount,
6466 &Win32Process->PrivateFontListHead))
6467 {
6468 IntUnLockProcessPrivateFonts(Win32Process);
6470 return -1;
6471 }
6472 IntUnLockProcessPrivateFonts(Win32Process);
6474
6475 /* Enumerate font families in the registry */
6476 if (!GetFontFamilyInfoForSubstitutes(SafeLogFont, SafeInfo, &AvailCount, InfoCount))
6477 {
6478 return -1;
6479 }
6480
6481 return AvailCount;
6482}
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:1139
#define TT_MS_ID_SYMBOL_CS
Definition: font.c:1138
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:3581
#define TT_NAME_ID_FONT_SUBFAMILY
Definition: font.c:3579
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 5916 of file freetype.c.

5920{
5923 HANDLE hFile;
5925 ULONG Desired;
5926
5928 FileName,
5930 NULL,
5931 NULL);
5932
5934 &hFile,
5935 0, // FILE_READ_ATTRIBUTES,
5939 0);
5940
5941 if (!NT_SUCCESS(Status))
5942 {
5943 DPRINT("ZwOpenFile() failed (Status = 0x%lx)\n", Status);
5944 return FALSE;
5945 }
5946
5947 Status = ZwQueryObject(hFile, ObjectNameInformation, NameInfo, Size, &Desired);
5948 ZwClose(hFile);
5949 if (!NT_SUCCESS(Status))
5950 {
5951 DPRINT("ZwQueryObject() failed (Status = %lx)\n", Status);
5952 return FALSE;
5953 }
5954
5955 return TRUE;
5956}
@ 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:100

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

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

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

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:3580
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 4360 of file freetype.c.

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

Referenced by FontLink_Chain_FindGlyph().

◆ IntRequestFontSize()

static FT_Error IntRequestFontSize ( 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 7379 of file freetype.c.

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

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

5866{
5869
5871 Status = IntGetFontLocalizedName(&Name2, SharedFace, NameID, LangID);
5872
5873 if (NT_SUCCESS(Status))
5874 {
5875 if (RtlCompareUnicodeString(Name1, &Name2, TRUE) == 0)
5876 {
5878 return TRUE;
5879 }
5880
5882 }
5883
5884 return FALSE;
5885}
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 5888 of file freetype.c.

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

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

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

6490{
6492 LOGFONTW LogFont;
6494 LONG GotCount, AvailCount, SafeInfoCount;
6496
6497 if (UnsafeLogFont == NULL || UnsafeInfo == NULL || UnsafeInfoCount == NULL)
6498 {
6500 return -1;
6501 }
6502
6503 Status = MmCopyFromCaller(&SafeInfoCount, UnsafeInfoCount, sizeof(SafeInfoCount));
6504 if (!NT_SUCCESS(Status))
6505 {
6507 return -1;
6508 }
6509 GotCount = 0;
6510 Status = MmCopyToCaller(UnsafeInfoCount, &GotCount, sizeof(*UnsafeInfoCount));
6511 if (!NT_SUCCESS(Status))
6512 {
6514 return -1;
6515 }
6516 Status = MmCopyFromCaller(&LogFont, UnsafeLogFont, sizeof(LOGFONTW));
6517 if (!NT_SUCCESS(Status))
6518 {
6520 return -1;
6521 }
6522 if (SafeInfoCount <= 0)
6523 {
6525 return -1;
6526 }
6527
6528 /* Allocate space for a safe copy */
6529 Status = RtlULongMult(SafeInfoCount, sizeof(FONTFAMILYINFO), &DataSize);
6531 {
6532 DPRINT1("Overflowed.\n");
6534 return -1;
6535 }
6537 if (Info == NULL)
6538 {
6540 return -1;
6541 }
6542
6543 /* Retrieve the information */
6544 AvailCount = IntGetFontFamilyInfo(Dc, &LogFont, Info, SafeInfoCount);
6545 GotCount = min(AvailCount, SafeInfoCount);
6546 SafeInfoCount = AvailCount;
6547
6548 /* Return data to caller */
6549 if (GotCount > 0)
6550 {
6551 Status = RtlULongMult(GotCount, sizeof(FONTFAMILYINFO), &DataSize);
6553 {
6554 DPRINT1("Overflowed.\n");
6557 return -1;
6558 }
6559 Status = MmCopyToCaller(UnsafeInfo, Info, DataSize);
6560 if (!NT_SUCCESS(Status))
6561 {
6564 return -1;
6565 }
6566 Status = MmCopyToCaller(UnsafeInfoCount, &SafeInfoCount, sizeof(*UnsafeInfoCount));
6567 if (!NT_SUCCESS(Status))
6568 {
6571 return -1;
6572 }
6573 }
6574
6576
6577 return GotCount;
6578}
#define LONG_MAX
Definition: limits.h:30
LONG FASTCALL IntGetFontFamilyInfo(HDC Dc, const LOGFONTW *SafeLogFont, PFONTFAMILYINFO SafeInfo, LONG InfoCount)
Definition: freetype.c:6445
#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:2770

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

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

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

Definition at line 4212 of file freetype.c.

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