progwrp/dwrite.c
2025-12-13 23:37:26 +01:00

915 lines
24 KiB
C

#include "progwrp.h"
#include "export.h"
#include "implementations.h"
#include "com_lite.h"
#include <strsafe.h>
int _fltused = 0;
BOOL WINAPI IIDCMP(REFIID x, REFIID y)
{
int i;
if ((x->Data1 == y->Data1) && (x->Data2 == y->Data2) && (x->Data3 == y->Data3))
{
for (i = 0; i < 8; i++)
if (x->Data4[i] != y->Data4[i])
return FALSE;
return TRUE;
}
else
return FALSE;
}
ULONG WINAPI AddRef_DW(pIDWriteFontLite this)
{
return InterlockedIncrement(&this->RefCount);
}
ULONG WINAPI Release_DW(pIDWriteFontLite this)
{
ULONG Result = InterlockedDecrement(&this->RefCount);
if (!Result)
{
HeapFree(GetProcessHeap(), 0, this->Vtbl);
HeapFree(GetProcessHeap(), 0, this);
}
return Result;
}
ULONG WINAPI GetSimulations(pIDWriteFontLite this)
{
return 0;
}
HRESULT WINAPI DWrite_QueryInterface(
ULONG_PTR this,
REFIID riid,
void** ppvObject
)
{
IID IDWriteFactory = { 0xb859ee5a, 0xd838,0x4b5b, 0xa2, 0xe8, 0x1a, 0xdc, 0x7d, 0x93, 0xdb, 0x48 };
IID IDWriteFactory1 = { 0x30572f99, 0xdac6, 0x41db, 0xa1, 0x6e, 0x48, 0x63, 0x07, 0xe6, 0x06a };
if (!ppvObject)
return E_POINTER;
if (IIDCMP(riid, &IDWriteFactory))
{
*ppvObject = this;
return S_OK;
}
return E_FAIL;
}
HRESULT WINAPI TryGetFontTable(
pIDWriteFontFaceLite this,
UINT32 openTypeTableTag,
const void** tableData,
UINT32* tableSize,
void** tableContext,
BOOL* exists
)
{
HDC hdc;
HFONT hf, hfo;
if (!tableData || !tableSize || !tableContext || !exists)
return E_INVALIDARG;
hdc = CreateCompatibleDC(NULL);
hf = CreateFontIndirectW(&this->lf);
hfo = SelectObject(hdc, hf);
if (GetFontData(hdc, openTypeTableTag, 0, *tableData, *tableSize) == GDI_ERROR)
*exists = FALSE;
else
*exists = TRUE;
SelectObject(hdc, hfo);
DeleteObject(hf);
DeleteDC(hdc);
return S_OK;
}
HRESULT WINAPI ReleaseFontTable(
pIDWriteFontFaceLite this,
void* tableContext
)
{
return S_OK;
}
UINT16 WINAPI GetGlyphCount(
pIDWriteFontFaceLite this
)
{
HDC hdc;
HFONT hf, hfo;
GLYPHSET gs;
hdc = CreateCompatibleDC(NULL);
hf = CreateFontIndirectW(&this->lf);
hfo = SelectObject(hdc, hf);
GetFontUnicodeRanges(hdc, &gs);
SelectObject(hdc, hfo);
DeleteObject(hf);
DeleteDC(hdc);
return gs.cGlyphsSupported;
}
typedef struct _DWRITE_FONT_METRICS {
UINT16 designUnitsPerEm;
UINT16 ascent;
UINT16 descent;
INT16 lineGap;
UINT16 capHeight;
UINT16 xHeight;
INT16 underlinePosition;
UINT16 underlineThickness;
INT16 strikethroughPosition;
UINT16 strikethroughThickness;
} DWRITE_FONT_METRICS, *PDWRITE_FONT_METRICS;
typedef struct _DWRITE_GLYPH_METRICS {
INT32 leftSideBearing;
UINT32 advanceWidth;
INT32 rightSideBearing;
INT32 topSideBearing;
UINT32 advanceHeight;
INT32 bottomSideBearing;
INT32 verticalOriginY;
}DWRITE_GLYPH_METRICS, *PDWRITE_GLYPH_METRICS;
VOID WINAPI GetMetrics(
pIDWriteFontFaceLite this,
DWRITE_FONT_METRICS* fontFaceMetrics
)
{
fontFaceMetrics->designUnitsPerEm = 1;
fontFaceMetrics->ascent = this->tm.tmAscent;
fontFaceMetrics->descent = this->tm.tmDescent;
}
HRESULT WINAPI GetDesignGlyphMetrics(
pIDWriteFontFaceLite this,
UINT16 const* glyphIndices,
UINT32 glyphCount,
DWRITE_GLYPH_METRICS* glyphMetrics,
BOOL isSideways
)
{
return S_OK;
}
HRESULT WINAPI GetGlyphIndices_DW(
pIDWriteFontFaceLite this,
UINT32 const* codePoints,
UINT32 codePointCount,
UINT16* glyphIndices
)
{
HDC hdc;
HFONT hf, hfo;
GLYPHSET gs;
DWORD result;
hdc = CreateCompatibleDC(NULL);
hf = CreateFontIndirectW(&this->lf);
hfo = SelectObject(hdc, hf);
result = GetGlyphIndicesW(hdc, codePoints, codePointCount, glyphIndices, 0);
SelectObject(hdc, hfo);
DeleteObject(hf);
DeleteDC(hdc);
if (result == GDI_ERROR)
return E_FAIL;
return S_OK;
}
HRESULT WINAPI CreateFontFace(
pIDWriteFontLite this,
pIDWriteFontFaceLite* fontFace
)
{
pIDWriteFontFaceLite NewFontCol;
*fontFace = (pIDWriteFontFaceLite)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteFontFaceLite));
NewFontCol = *fontFace;
NewFontCol->Vtbl = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteFontFaceLiteTbl));
if (!NewFontCol->Vtbl)
{
return E_FAIL;
}
NewFontCol->lf = this->lf;
NewFontCol->tm = this->tm;
NewFontCol->Vtbl->IUnknown.pfnQueryInterface = DWrite_QueryInterface;
NewFontCol->Vtbl->IUnknown.pfnAddRef = AddRef_DW;
AddRef_DW(NewFontCol);
NewFontCol->Vtbl->IUnknown.pfnRelease = Release_DW;
NewFontCol->Vtbl->pfnGetGlyphCount = GetGlyphCount;
NewFontCol->Vtbl->pfnTryGetFontTable = TryGetFontTable;
NewFontCol->Vtbl->pfnReleaseFontTable = ReleaseFontTable;
NewFontCol->Vtbl->pfnGetMetrics = GetMetrics;
NewFontCol->Vtbl->pfnGetGlyphIndices = GetGlyphIndices_DW;
NewFontCol->Vtbl->pfnGetDesignGlyphMetrics = GetDesignGlyphMetrics;
return S_OK;
}
typedef struct
{
PCWSTR familyName;
UINT32* index;
} ENUMFAMILYNAME, * PENUMFAMILYNAME;
int CALLBACK EnumFamilyName(
const LOGFONTW* lpelfe,
const TEXTMETRICW* lpntme,
DWORD FontType,
PENUMFAMILYNAME lParam
)
{
int i = 0;
while (lParam->familyName[i] != L'\0')
{
if (lpelfe->lfFaceName[i] == L'\0' ||
lpelfe->lfFaceName[i] != lParam->familyName[i])
return 1;
++i;
}
if ((lParam->familyName[i] == L'\0') && lpelfe->lfFaceName[i] != L'\0')
return 1;
++*lParam->index;
return 0;
}
typedef struct
{
UINT32 currentindex;
UINT32 finalindex;
PCWSTR finalstr;
} ENUMFAMILYIDX, * PENUMFAMILYIDX;
int CALLBACK EnumFamilyIdx(
const LOGFONTW* lpelfe,
const TEXTMETRICW* lpntme,
DWORD FontType,
PENUMFAMILYIDX lParam
)
{
if (lParam->currentindex == lParam->finalindex)
{
lParam->finalstr = (PCWSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 32 * sizeof(WCHAR));
StringCchCopyW(lParam->finalstr, 32, lpelfe->lfFaceName);
return 0;
}
++lParam->currentindex;
return 1;
}
HRESULT WINAPI FindFamilyName(
ULONG_PTR this,
PCWSTR familyName,
UINT32* index,
BOOL* exists
)
{
HDC hdc;
LOGFONTW lf;
ENUMFAMILYNAME pfname;
if (!familyName || !index || !exists)
return E_INVALIDARG;
pfname.familyName = familyName;
pfname.index = index;
*pfname.index = 0;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfFaceName[0] = L'\0';
lf.lfPitchAndFamily = 0;
hdc = CreateCompatibleDC(NULL);
if (EnumFontFamiliesExW(hdc, &lf, EnumFamilyName, &pfname, 0) != 0)
{
*exists = FALSE;
*index = UINT_MAX;
}
else
*exists = TRUE;
DeleteDC(hdc);
return S_OK;
}
typedef struct
{
LOGFONTW lf;
TEXTMETRICW tm;
DWORD FontType;
ULONG weight;
ULONG stretch;
ULONG style;
} FONTDATA, *PFONTDATA;
ULONG WINAPI GetStretch(ULONG_PTR this)
{
return 5;
}
ULONG WINAPI GetStyle(pIDWriteFontLite this)
{
if (this->lf.lfItalic)
return 2;
return 0;
}
ULONG WINAPI GetWeight(pIDWriteFontLite this)
{
return this->lf.lfWeight;
}
typedef struct
{
LOGFONTW lf;
TEXTMETRICW tm;
DWORD FontType;
UINT32 currentindex;
UINT32 finalindex;
} ENUMFONTLISTIDX, * PENUMFONTLISTIDX;
int CALLBACK EnumFontListIdx(
const LOGFONTW* lpelfe,
const TEXTMETRICW* lpntme,
DWORD FontType,
PENUMFONTLISTIDX lParam
)
{
if (lParam->currentindex == lParam->finalindex)
{
memcpy(&lParam->lf, lpelfe, sizeof(LOGFONTW));
memcpy(&lParam->tm, lpntme, sizeof(TEXTMETRICW));
lParam->FontType = FontType;
return 0;
}
++lParam->currentindex;
return 1;
}
int CALLBACK EnumFamilyFontMatch(
const LOGFONTW* lpelfe,
const TEXTMETRICW* lpntme,
DWORD FontType,
PFONTDATA lParam
)
/*
Here is how we will determine the best-matching font, options ranking from best to worst:
-all three attributes matching
-two attributes matching
-one attribute matching
-first font enumerated
As a better font is found, the option will be revised.
*/
{
if (lParam->lf.lfFaceName == L'\0')
{
memcpy(&lParam->lf, lpelfe, sizeof(LOGFONTW));
memcpy(&lParam->tm, lpntme, sizeof(TEXTMETRICW));
lParam->FontType = FontType;
}
if (lParam->weight == lpelfe->lfWeight)
return 0;
return 1;
}
HRESULT WINAPI GetFont(
pIDWriteFontListLite this,
UINT32 index,
pIDWriteFontLite* matchingFont
)
// At the end of the IDWriteFontFamily interface, I have added a pointer to a string containing the "font family" name.
// It will be used to iterate through all the fonts to find the one best suited to create a DWriteFont object.
{
pIDWriteFontLite NewFontCol;
HDC hdc;
LOGFONTW lf;
FONTDATA fd;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfFaceName[0] = L'\0';
lf.lfPitchAndFamily = 0;
hdc = CreateCompatibleDC(NULL);
EnumFontFamiliesExW(hdc, &lf, EnumFontListIdx, &fd, 0);
DeleteDC(hdc);
*matchingFont = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteFontLite));
NewFontCol = *matchingFont;
NewFontCol->Vtbl = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteFontLiteTbl));
if (!NewFontCol->Vtbl)
{
return E_FAIL;
}
NewFontCol->lf = fd.lf;
NewFontCol->tm = fd.tm;
NewFontCol->Vtbl->IUnknown.pfnQueryInterface = DWrite_QueryInterface;
NewFontCol->Vtbl->IUnknown.pfnAddRef = AddRef_DW;
AddRef_DW(NewFontCol);
NewFontCol->Vtbl->IUnknown.pfnRelease = Release_DW;
NewFontCol->Vtbl->pfnGetSimulations = GetSimulations;
NewFontCol->Vtbl->pfnCreateFontFace = CreateFontFace;
NewFontCol->Vtbl->pfnGetStyle = GetStyle;
NewFontCol->Vtbl->pfnGetWeight = GetWeight;
NewFontCol->Vtbl->pfnGetStretch = GetStretch;
return S_OK;
}
HRESULT WINAPI GetFirstMatchingFont(
pIDWriteFontFamilyLite this,
ULONG weight,
ULONG stretch,
ULONG style,
pIDWriteFontLite* matchingFont
)
// At the end of the IDWriteFontFamily interface, I have added a pointer to a string containing the "font family" name.
// It will be used to iterate through all the fonts to find the one best suited to create a DWriteFont object.
{
pIDWriteFontLite NewFontCol;
HDC hdc;
LOGFONTW lf;
FONTDATA fd;
lf.lfCharSet = DEFAULT_CHARSET;
StringCchCopyW(&lf.lfFaceName, 32, this->FontFamilyStr);
lf.lfPitchAndFamily = 0;
hdc = CreateCompatibleDC(NULL);
EnumFontFamiliesExW(hdc, &lf, EnumFamilyFontMatch, &fd, 0);
DeleteDC(hdc);
*matchingFont = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteFontLite));
NewFontCol = *matchingFont;
NewFontCol->Vtbl = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteFontLiteTbl));
if (!NewFontCol->Vtbl)
{
return E_FAIL;
}
NewFontCol->lf = fd.lf;
NewFontCol->tm = fd.tm;
NewFontCol->Vtbl->IUnknown.pfnQueryInterface = DWrite_QueryInterface;
NewFontCol->Vtbl->IUnknown.pfnAddRef = AddRef_DW;
AddRef_DW(NewFontCol);
NewFontCol->Vtbl->IUnknown.pfnRelease = Release_DW;
NewFontCol->Vtbl->pfnGetSimulations = GetSimulations;
NewFontCol->Vtbl->pfnCreateFontFace = CreateFontFace;
NewFontCol->Vtbl->pfnGetStyle = GetStyle;
NewFontCol->Vtbl->pfnGetWeight = GetWeight;
NewFontCol->Vtbl->pfnGetStretch = GetStretch;
return S_OK;
}
UINT32 WINAPI GetFontCount(
pIDWriteFontListLite this
)
{
return 1;
}
HRESULT WINAPI GetFontFamily(
ULONG_PTR this,
UINT32 index,
pIDWriteFontFamilyLite* fontFamily
)
{
HDC hdc;
LOGFONTW lf;
ENUMFAMILYIDX pfi;
int result;
pfi.currentindex = 0;
pfi.finalindex = index;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfFaceName[0] = L'\0';
lf.lfPitchAndFamily = 0;
hdc = CreateCompatibleDC(NULL);
result = EnumFontFamiliesExW(hdc, &lf, EnumFamilyIdx, &pfi, 0);
DeleteDC(hdc);
if (result)
return E_FAIL;
pIDWriteFontFamilyLite NewFontFam;
*fontFamily = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteFontFamilyLite));
NewFontFam = *fontFamily;
NewFontFam->Vtbl = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteFontFamilyLiteTbl));
if (!NewFontFam->Vtbl)
{
return E_FAIL;
}
NewFontFam->Vtbl->IDWriteFontList.IUnknown.pfnQueryInterface = DWrite_QueryInterface;
NewFontFam->Vtbl->IDWriteFontList.IUnknown.pfnAddRef = AddRef_DW;
AddRef_DW(NewFontFam);
NewFontFam->Vtbl->IDWriteFontList.IUnknown.pfnRelease = Release_DW;
NewFontFam->Vtbl->pfnGetFirstMatchingFont = GetFirstMatchingFont;
NewFontFam->Vtbl->IDWriteFontList.pfnGetFont = GetFont;
NewFontFam->Vtbl->IDWriteFontList.pfnGetFontCount = GetFontCount;
NewFontFam->FontFamilyStr = pfi.finalstr;
return S_OK;
}
UINT32 WINAPI GetFontFamilyCount(pIDWriteFontCollectionLite this)
{
return 1;
}
HRESULT WINAPI GetSystemFontCollection(
pIDWriteFactoryLite this,
pIDWriteFontCollectionLite* fontCollection,
BOOL checkForUpdates
)
{
pIDWriteFontCollectionLite NewFontCol;
*fontCollection = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteFontCollectionLite));
NewFontCol = *fontCollection;
NewFontCol->Vtbl = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteFontCollectionLiteTbl));
if (!NewFontCol->Vtbl)
{
return E_FAIL;
}
NewFontCol->Vtbl->IUnknown.pfnQueryInterface = DWrite_QueryInterface;
NewFontCol->Vtbl->IUnknown.pfnAddRef = AddRef_DW;
AddRef_DW(NewFontCol);
NewFontCol->Vtbl->IUnknown.pfnRelease = Release_DW;
NewFontCol->Vtbl->pfnGetFontFamily = GetFontFamily;
NewFontCol->Vtbl->pfnFindFamilyName = FindFamilyName;
NewFontCol->Vtbl->pfnGetFontFamilyCount = GetFontFamilyCount;
return S_OK;
}
/// <summary>
/// Optional adjustment to a glyph's position. A glyph offset changes the position of a glyph without affecting
/// the pen position. Offsets are in logical, pre-transform units.
/// </summary>
typedef struct DWRITE_GLYPH_OFFSET
{
/// <summary>
/// Offset in the advance direction of the run. A positive advance offset moves the glyph to the right
/// (in pre-transform coordinates) if the run is left-to-right or to the left if the run is right-to-left.
/// </summary>
FLOAT advanceOffset;
/// <summary>
/// Offset in the ascent direction, i.e., the direction ascenders point. A positive ascender offset moves
/// the glyph up (in pre-transform coordinates).
/// </summary>
FLOAT ascenderOffset;
}DWRITE_GLYPH_OFFSET;
typedef struct DWRITE_GLYPH_RUN
{
/// <summary>
/// The physical font face to draw with.
/// </summary>
pIDWriteFontFaceLite fontFace;
/// <summary>
/// Logical size of the font in DIPs, not points (equals 1/96 inch).
/// </summary>
FLOAT fontEmSize;
/// <summary>
/// The number of glyphs.
/// </summary>
UINT32 glyphCount;
/// <summary>
/// The indices to render.
/// </summary>
_Field_size_(glyphCount) UINT16 const* glyphIndices;
/// <summary>
/// Glyph advance widths.
/// </summary>
_Field_size_opt_(glyphCount) FLOAT const* glyphAdvances;
/// <summary>
/// Glyph offsets.
/// </summary>
_Field_size_opt_(glyphCount) DWRITE_GLYPH_OFFSET const* glyphOffsets;
/// <summary>
/// If true, specifies that glyphs are rotated 90 degrees to the left and
/// vertical metrics are used. Vertical writing is achieved by specifying
/// isSideways = true and rotating the entire run 90 degrees to the right
/// via a rotate transform.
/// </summary>
BOOL isSideways;
/// <summary>
/// The implicit resolved bidi level of the run. Odd levels indicate
/// right-to-left languages like Hebrew and Arabic, while even levels
/// indicate left-to-right languages like English and Japanese (when
/// written horizontally). For right-to-left languages, the text origin
/// is on the right, and text should be drawn to the left.
/// </summary>
UINT32 bidiLevel;
}DWRITE_GLYPH_RUN;
/// <summary>
/// The DWRITE_MATRIX structure specifies the graphics transform to be applied
/// to rendered glyphs.
/// </summary>
typedef struct DWRITE_MATRIX
{
/// <summary>
/// Horizontal scaling / cosine of rotation
/// </summary>
FLOAT m11;
/// <summary>
/// Vertical shear / sine of rotation
/// </summary>
FLOAT m12;
/// <summary>
/// Horizontal shear / negative sine of rotation
/// </summary>
FLOAT m21;
/// <summary>
/// Vertical scaling / cosine of rotation
/// </summary>
FLOAT m22;
/// <summary>
/// Horizontal shift (always orthogonal regardless of rotation)
/// </summary>
FLOAT dx;
/// <summary>
/// Vertical shift (always orthogonal regardless of rotation)
/// </summary>
FLOAT dy;
}DWRITE_MATRIX;
/// <summary>
/// Represents a method of rendering glyphs.
/// </summary>
typedef enum DWRITE_RENDERING_MODE
{
/// <summary>
/// Specifies that the rendering mode is determined automatically based on the font and size.
/// </summary>
DWRITE_RENDERING_MODE_DEFAULT,
/// <summary>
/// Specifies that no antialiasing is performed. Each pixel is either set to the foreground
/// color of the text or retains the color of the background.
/// </summary>
DWRITE_RENDERING_MODE_ALIASED,
/// <summary>
/// Specifies that antialiasing is performed in the horizontal direction and the appearance
/// of glyphs is layout-compatible with GDI using CLEARTYPE_QUALITY. Use DWRITE_MEASURING_MODE_GDI_CLASSIC
/// to get glyph advances. The antialiasing may be either ClearType or grayscale depending on
/// the text antialiasing mode.
/// </summary>
DWRITE_RENDERING_MODE_GDI_CLASSIC,
/// <summary>
/// Specifies that antialiasing is performed in the horizontal direction and the appearance
/// of glyphs is layout-compatible with GDI using CLEARTYPE_NATURAL_QUALITY. Glyph advances
/// are close to the font design advances, but are still rounded to whole pixels. Use
/// DWRITE_MEASURING_MODE_GDI_NATURAL to get glyph advances. The antialiasing may be either
/// ClearType or grayscale depending on the text antialiasing mode.
/// </summary>
DWRITE_RENDERING_MODE_GDI_NATURAL,
/// <summary>
/// Specifies that antialiasing is performed in the horizontal direction. This rendering
/// mode allows glyphs to be positioned with subpixel precision and is therefore suitable
/// for natural (i.e., resolution-independent) layout. The antialiasing may be either
/// ClearType or grayscale depending on the text antialiasing mode.
/// </summary>
DWRITE_RENDERING_MODE_NATURAL,
/// <summary>
/// Similar to natural mode except that antialiasing is performed in both the horizontal
/// and vertical directions. This is typically used at larger sizes to make curves and
/// diagonal lines look smoother. The antialiasing may be either ClearType or grayscale
/// depending on the text antialiasing mode.
/// </summary>
DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC,
/// <summary>
/// Specifies that rendering should bypass the rasterizer and use the outlines directly.
/// This is typically used at very large sizes.
/// </summary>
DWRITE_RENDERING_MODE_OUTLINE,
// The following names are obsolete, but are kept as aliases to avoid breaking existing code.
// Each of these rendering modes may result in either ClearType or grayscale antialiasing
// depending on the DWRITE_TEXT_ANTIALIASING_MODE.
DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC = DWRITE_RENDERING_MODE_GDI_CLASSIC,
DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL = DWRITE_RENDERING_MODE_GDI_NATURAL,
DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL = DWRITE_RENDERING_MODE_NATURAL,
DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC = DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC
}DWRITE_RENDERING_MODE, *PDWRITE_RENDERING_MODE;
#define DWRITE_MEASURING_MODE ULONG
#define DWRITE_TEXTURE_TYPE ULONG
#define DWRITE_FONT_WEIGHT ULONG
#define DWRITE_FONT_STYLE ULONG
#define DWRITE_FONT_STRETCH ULONG
HRESULT WINAPI GetAlphaBlendParams(
pIDWriteGlyphRunAnalysisLite this,
PVOID renderingParams,
FLOAT* blendGamma,
FLOAT* blendEnhancedContrast,
FLOAT* blendClearTypeLevel
)
{
*blendGamma = 3.0f;
*blendEnhancedContrast = 2.0f;
//*blendClearTypeLevel = 0.0;
return S_OK;
}
HRESULT WINAPI GetAlphaTextureBounds(
pIDWriteGlyphRunAnalysisLite this,
DWRITE_TEXTURE_TYPE textureType,
RECT* textureBounds
)
{
textureBounds->bottom = 2.0;
textureBounds->right = 2.0;
return S_OK;
}
HRESULT WINAPI Draw(
pIDWriteTextLayoutLite this,
void* clientDrawingContext,
void* renderer,
FLOAT originX,
FLOAT originY
)
{
return S_OK;
}
HRESULT WINAPI SetFontCollection(
pIDWriteTextLayoutLite this,
pIDWriteFontCollectionLite fontCollection,
ULONG textRange
)
{
return S_OK;
}
HRESULT WINAPI CreateTextFormat(
pIDWriteFactoryLite this,
WCHAR const* fontFamilyName,
IDWriteFontCollectionLite* fontCollection,
DWRITE_FONT_WEIGHT fontWeight,
DWRITE_FONT_STYLE fontStyle,
DWRITE_FONT_STRETCH fontStretch,
FLOAT fontSize,
WCHAR const* localeName,
pIDWriteTextFormatLite* textFormat
)
{
pIDWriteTextFormatLite NewFontCol;
*textFormat = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteTextFormatLite));
NewFontCol = *textFormat;
NewFontCol->Vtbl = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteTextFormatLiteTbl));
if (!NewFontCol->Vtbl)
{
return E_FAIL;
}
NewFontCol->Vtbl->IUnknown.pfnQueryInterface = DWrite_QueryInterface;
NewFontCol->Vtbl->IUnknown.pfnAddRef = AddRef_DW;
AddRef_DW(NewFontCol);
NewFontCol->Vtbl->IUnknown.pfnRelease = Release_DW;
return S_OK;
}
HRESULT WINAPI CreateTextLayout(
pIDWriteFactoryLite this,
WCHAR const* string,
UINT32 stringLength,
IDWriteTextFormatLite* textFormat,
FLOAT maxWidth,
FLOAT maxHeight,
pIDWriteTextLayoutLite* textLayout
)
{
pIDWriteTextLayoutLite NewFontCol;
*textLayout = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteTextLayoutLite));
NewFontCol = *textLayout;
NewFontCol->Vtbl = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteTextLayoutLiteTbl));
if (!NewFontCol->Vtbl)
{
return E_FAIL;
}
NewFontCol->Vtbl->IDWriteTextFormat.IUnknown.pfnQueryInterface = DWrite_QueryInterface;
NewFontCol->Vtbl->IDWriteTextFormat.IUnknown.pfnAddRef = AddRef_DW;
AddRef_DW(NewFontCol);
NewFontCol->Vtbl->IDWriteTextFormat.IUnknown.pfnRelease = Release_DW;
NewFontCol->Vtbl->pfnDraw = Draw;
NewFontCol->Vtbl->pfnSetFontCollection = SetFontCollection;
return S_OK;
}
HRESULT WINAPI CreateGlyphRunAnalysis(
pIDWriteFactoryLite this,
DWRITE_GLYPH_RUN const* glyphRun,
FLOAT pixelsPerDip,
DWRITE_MATRIX const* transform,
DWRITE_RENDERING_MODE renderingMode,
DWRITE_MEASURING_MODE measuringMode,
FLOAT baselineOriginX,
FLOAT baselineOriginY,
pIDWriteGlyphRunAnalysisLite* glyphRunAnalysis
)
{
pIDWriteGlyphRunAnalysisLite NewFontCol;
*glyphRunAnalysis = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteGlyphRunAnalysisLite));
NewFontCol = *glyphRunAnalysis;
NewFontCol->Vtbl = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteGlyphRunAnalysisLiteTbl));
if (!NewFontCol->Vtbl)
{
return E_FAIL;
}
NewFontCol->Vtbl->IUnknown.pfnQueryInterface = DWrite_QueryInterface;
NewFontCol->Vtbl->IUnknown.pfnAddRef = AddRef_DW;
AddRef_DW(NewFontCol);
NewFontCol->Vtbl->IUnknown.pfnRelease = Release_DW;
NewFontCol->Vtbl->pfnGetAlphaBlendParams = GetAlphaBlendParams;
NewFontCol->Vtbl->pfnGetAlphaTextureBounds = GetAlphaTextureBounds;
return S_OK;
}
HRESULT RegisterFontCollectionLoader(
pIDWriteFactoryLite this,
PVOID fontCollectionLoader
)
{
return S_OK;
}
HRESULT RegisterFontFileLoader(
pIDWriteFactoryLite this,
PVOID fontFileLoader
)
{
return S_OK;
}
HRESULT WINAPI Implementation_DWriteCreateFactory(
ULONG factoryType,
REFIID iid,
IUnknown** factory
)
{
pIDWriteFactoryLite IDWriteFactoryLite;
IID IDWriteFactory = { 0xb859ee5a, 0xd838,0x4b5b, 0xa2, 0xe8, 0x1a, 0xdc, 0x7d, 0x93, 0xdb, 0x48 };
IID IDWriteFactory1 = { 0x30572f99, 0xdac6, 0x41db, 0xa1, 0x6e, 0x48, 0x63, 0x07, 0xe6, 0x06a };
if (IIDCMP(iid, &IDWriteFactory))
{
*factory = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteFactoryLite));
IDWriteFactoryLite = *factory;
IDWriteFactoryLite->Vtbl = (void*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDWriteFactoryLiteTbl));
if (!IDWriteFactoryLite->Vtbl)
{
return E_FAIL;
}
IDWriteFactoryLite->Vtbl->IUnknown.pfnQueryInterface = DWrite_QueryInterface;
IDWriteFactoryLite->Vtbl->IUnknown.pfnAddRef = AddRef_DW;
AddRef_DW(IDWriteFactoryLite);
IDWriteFactoryLite->Vtbl->IUnknown.pfnRelease = Release_DW;
IDWriteFactoryLite->Vtbl->pfnGetSystemFontCollection = GetSystemFontCollection;
IDWriteFactoryLite->Vtbl->pfnCreateGlyphRunAnalysis = CreateGlyphRunAnalysis;
IDWriteFactoryLite->Vtbl->pfnCreateTextLayout = CreateTextLayout;
IDWriteFactoryLite->Vtbl->pfnCreateTextFormat = CreateTextFormat;
IDWriteFactoryLite->Vtbl->pfnRegisterFontCollectionLoader = RegisterFontCollectionLoader;
IDWriteFactoryLite->Vtbl->pfnRegisterFontFileLoader = RegisterFontFileLoader;
return S_OK;
}
if (IIDCMP(iid, &IDWriteFactory1))
{
return S_OK;
}
return E_NOTIMPL;
}