Created
February 20, 2020 13:44
-
-
Save ebraminio/e2d18feea65adaaeff6d6e041b7a3161 to your computer and use it in GitHub Desktop.
Test GetGlyphRunOutline
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// gcc -DHB_NO_MT c.cc -ldwrite && a.exe | |
// But it gives some apparently random number... | |
// M0,0 C0,0 0,-536870912 0,0 C0,0 -1610612736,0 0,0 L0,0 L0,0 C1073741824... | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <windows.h> | |
#include <DWrite_1.h> | |
#include <d2d1.h> | |
// Borrowed from NativeFontResourceDWrite.cpp of Mozilla but only load one font | |
class DWriteFontFileLoader : public IDWriteFontFileLoader | |
{ | |
private: | |
IDWriteFontFileStream *mFontFileStream; | |
public: | |
DWriteFontFileLoader(IDWriteFontFileStream *fontFileStream) | |
{ mFontFileStream = fontFileStream; } | |
// IUnknown interface | |
IFACEMETHOD(QueryInterface) (IID const &iid, OUT void **ppObject) | |
{ return S_OK; } | |
IFACEMETHOD_(ULONG, AddRef) () { return 1; } | |
IFACEMETHOD_(ULONG, Release)() { return 1; } | |
// IDWriteFontFileLoader methods | |
virtual HRESULT STDMETHODCALLTYPE | |
CreateStreamFromKey(void const *fontFileReferenceKey, | |
uint32_t fontFileReferenceKeySize, | |
OUT IDWriteFontFileStream **fontFileStream) | |
{ | |
*fontFileStream = mFontFileStream; | |
return S_OK; | |
} | |
}; | |
class DWriteFontFileStream : public IDWriteFontFileStream | |
{ | |
private: | |
uint8_t *mData; | |
uint32_t mSize; | |
public: | |
DWriteFontFileStream(uint8_t *aData, uint32_t aSize) | |
{ | |
mData = aData; | |
mSize = aSize; | |
} | |
// IUnknown interface | |
IFACEMETHOD(QueryInterface) (IID const &iid, OUT void **ppObject) | |
{ return S_OK; } | |
IFACEMETHOD_(ULONG, AddRef) () { return 1; } | |
IFACEMETHOD_(ULONG, Release)() { return 1; } | |
// IDWriteFontFileStream methods | |
virtual HRESULT STDMETHODCALLTYPE | |
ReadFileFragment(void const **fragmentStart, | |
UINT64 fileOffset, | |
UINT64 fragmentSize, | |
OUT void **fragmentContext) | |
{ | |
// We are required to do bounds checking. | |
if (fileOffset + fragmentSize > mSize) | |
return E_FAIL; | |
// truncate the 64 bit fileOffset to size_t sized index into mData | |
size_t index = static_cast<size_t>(fileOffset); | |
// We should be alive for the duration of this. | |
*fragmentStart = &mData[index]; | |
*fragmentContext = nullptr; | |
return S_OK; | |
} | |
virtual void STDMETHODCALLTYPE | |
ReleaseFileFragment(void *fragmentContext) {} | |
virtual HRESULT STDMETHODCALLTYPE | |
GetFileSize(OUT UINT64 *fileSize) | |
{ | |
*fileSize = mSize; | |
return S_OK; | |
} | |
virtual HRESULT STDMETHODCALLTYPE | |
GetLastWriteTime(OUT UINT64 *lastWriteTime) { return E_NOTIMPL; } | |
}; | |
class GeometrySink : public IDWriteGeometrySink | |
{ | |
public: | |
// IUnknown interface | |
IFACEMETHOD(QueryInterface) (IID const &iid, OUT void **ppObject) | |
{ return S_OK; } | |
IFACEMETHOD_(ULONG, AddRef) () { return 1; } | |
IFACEMETHOD_(ULONG, Release)() { return 1; } | |
GeometrySink() {} | |
void STDMETHODCALLTYPE AddBeziers(_In_ const D2D1_BEZIER_SEGMENT *beziers, unsigned int beziersCount) | |
{ | |
for (unsigned i = 0; i < beziersCount; ++i) | |
printf("C%d,%d %d,%d %d,%d ", beziers[i].point1.x, beziers[i].point1.y, | |
beziers[i].point2.x, beziers[i].point2.y, beziers[i].point3.x, beziers[i].point3.y); | |
} | |
void STDMETHODCALLTYPE AddLines(_In_ const D2D1_POINT_2F *points, unsigned int pointsCount) | |
{ | |
for (unsigned i = 0; i < pointsCount; ++i) | |
printf("L%d,%d ", points[i].x, points[i].y); | |
} | |
void STDMETHODCALLTYPE BeginFigure(D2D1_POINT_2F startPoint, D2D1_FIGURE_BEGIN figureBegin) | |
{ | |
printf("M%d,%d ", startPoint.x, startPoint.y); | |
} | |
void STDMETHODCALLTYPE EndFigure(D2D1_FIGURE_END figureEnd) | |
{ | |
printf("Z"); | |
} | |
HRESULT STDMETHODCALLTYPE Close() | |
{ | |
return S_OK; | |
} | |
void STDMETHODCALLTYPE SetFillMode(D2D1_FILL_MODE fillMode) | |
{ | |
// Interesting! Maybe we should one also | |
} | |
void STDMETHODCALLTYPE SetSegmentFlags(D2D1_PATH_SEGMENT vertexFlags) | |
{ | |
} | |
}; | |
int main() | |
{ | |
FILE *f = fopen("c:\\windows\\Fonts\\tahoma.ttf", "rb"); | |
fseek(f, 0, SEEK_END); | |
unsigned file_size = ftell(f); | |
rewind(f); | |
void *file_data = malloc(file_size); | |
fread(file_data, 1, file_size, f); | |
fclose(f); | |
IDWriteFactory *dwriteFactory; | |
DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), | |
(IUnknown **)&dwriteFactory); | |
HRESULT hr; | |
DWriteFontFileStream *fontFileStream = new DWriteFontFileStream((uint8_t *)file_data, file_size); | |
DWriteFontFileLoader *fontFileLoader = new DWriteFontFileLoader(fontFileStream); | |
dwriteFactory->RegisterFontFileLoader(fontFileLoader); | |
IDWriteFontFile *fontFile; | |
uint64_t fontFileKey = 0; | |
dwriteFactory->CreateCustomFontFileReference(&fontFileKey, sizeof(fontFileKey), | |
fontFileLoader, &fontFile); | |
BOOL isSupported; | |
DWRITE_FONT_FILE_TYPE fileType; | |
DWRITE_FONT_FACE_TYPE faceType; | |
uint32_t numberOfFaces; | |
hr = fontFile->Analyze(&isSupported, &fileType, &faceType, &numberOfFaces); | |
IDWriteFontFace *fontFace; | |
dwriteFactory->CreateFontFace(faceType, 1, &fontFile, 0, | |
DWRITE_FONT_SIMULATIONS_NONE, &fontFace); | |
uint16_t a = 12; | |
IDWriteGeometrySink *sink = new GeometrySink(); | |
fontFace->GetGlyphRunOutline(128, &a, 0, 0, 1, false, false, sink); | |
delete sink; | |
delete fontFileStream; | |
delete fontFileLoader; | |
free (file_data); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment