dwrite: Implement GetAlphaTextureBounds().
This commit is contained in:
parent
2c6eca8682
commit
b50416aa5f
|
@ -124,7 +124,7 @@ extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *refer
|
|||
extern HRESULT create_localfontfileloader(IDWriteLocalFontFileLoader** iface) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_fontface(DWRITE_FONT_FACE_TYPE,UINT32,IDWriteFontFile* const*,UINT32,DWRITE_FONT_SIMULATIONS,IDWriteFontFace2**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_font_collection(IDWriteFactory2*,IDWriteFontFileEnumerator*,BOOL,IDWriteFontCollection**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_glyphrunanalysis(DWRITE_RENDERING_MODE,DWRITE_GLYPH_RUN const*,IDWriteGlyphRunAnalysis**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_glyphrunanalysis(DWRITE_RENDERING_MODE,DWRITE_GLYPH_RUN const*,FLOAT,IDWriteGlyphRunAnalysis**) DECLSPEC_HIDDEN;
|
||||
extern BOOL is_system_collection(IDWriteFontCollection*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT get_local_refkey(const WCHAR*,const FILETIME*,void**,UINT32*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT get_filestream_from_file(IDWriteFontFile*,IDWriteFontFileStream**) DECLSPEC_HIDDEN;
|
||||
|
@ -188,6 +188,7 @@ extern UINT16 freetype_get_glyphcount(IDWriteFontFace2*) DECLSPEC_HIDDEN;
|
|||
extern UINT16 freetype_get_glyphindex(IDWriteFontFace2*,UINT32) DECLSPEC_HIDDEN;
|
||||
extern BOOL freetype_has_kerning_pairs(IDWriteFontFace2*) DECLSPEC_HIDDEN;
|
||||
extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2*,UINT16,UINT16) DECLSPEC_HIDDEN;
|
||||
extern void freetype_get_glyph_bbox(IDWriteFontFace2*,FLOAT,UINT16,BOOL,RECT*) DECLSPEC_HIDDEN;
|
||||
|
||||
/* Glyph shaping */
|
||||
enum SCRIPT_JUSTIFY
|
||||
|
|
|
@ -106,15 +106,22 @@ struct dwrite_fonttable {
|
|||
BOOL exists;
|
||||
};
|
||||
|
||||
enum runanalysis_readystate {
|
||||
RUNANALYSIS_BOUNDS = 1 << 0,
|
||||
};
|
||||
|
||||
struct dwrite_glyphrunanalysis {
|
||||
IDWriteGlyphRunAnalysis IDWriteGlyphRunAnalysis_iface;
|
||||
LONG ref;
|
||||
|
||||
DWRITE_RENDERING_MODE rendering_mode;
|
||||
DWRITE_GLYPH_RUN run;
|
||||
FLOAT ppdip;
|
||||
UINT16 *glyphs;
|
||||
FLOAT *advances;
|
||||
DWRITE_GLYPH_OFFSET *offsets;
|
||||
RECT bounds;
|
||||
UINT8 ready;
|
||||
};
|
||||
|
||||
#define GLYPH_BLOCK_SHIFT 8
|
||||
|
@ -2904,11 +2911,16 @@ static ULONG WINAPI glyphrunanalysis_Release(IDWriteGlyphRunAnalysis *iface)
|
|||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI glyphrunanalysis_GetAlphaTextureBounds(IDWriteGlyphRunAnalysis *iface, DWRITE_TEXTURE_TYPE type, RECT* bounds)
|
||||
static HRESULT WINAPI glyphrunanalysis_GetAlphaTextureBounds(IDWriteGlyphRunAnalysis *iface, DWRITE_TEXTURE_TYPE type, RECT *bounds)
|
||||
{
|
||||
struct dwrite_glyphrunanalysis *This = impl_from_IDWriteGlyphRunAnalysis(iface);
|
||||
IDWriteFontFace2 *fontface2;
|
||||
BOOL nohint, is_rtl;
|
||||
FLOAT origin_x;
|
||||
HRESULT hr;
|
||||
UINT32 i;
|
||||
|
||||
FIXME("(%p)->(%d %p): stub\n", This, type, bounds);
|
||||
TRACE("(%p)->(%d %p)\n", This, type, bounds);
|
||||
|
||||
if ((UINT32)type > DWRITE_TEXTURE_CLEARTYPE_3x1) {
|
||||
memset(bounds, 0, sizeof(*bounds));
|
||||
|
@ -2921,7 +2933,46 @@ static HRESULT WINAPI glyphrunanalysis_GetAlphaTextureBounds(IDWriteGlyphRunAnal
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOTIMPL;
|
||||
if (This->ready & RUNANALYSIS_BOUNDS) {
|
||||
*bounds = This->bounds;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (This->run.isSideways)
|
||||
FIXME("sideways runs are not supported.\n");
|
||||
|
||||
hr = IDWriteFontFace_QueryInterface(This->run.fontFace, &IID_IDWriteFontFace2, (void**)&fontface2);
|
||||
if (FAILED(hr))
|
||||
WARN("failed to get IDWriteFontFace2, 0x%08x\n", hr);
|
||||
|
||||
nohint = This->rendering_mode == DWRITE_RENDERING_MODE_NATURAL || This->rendering_mode == DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC;
|
||||
|
||||
/* Start with empty bounds at (0,0) origin, returned bounds are not translated back to (0,0), e.g. for
|
||||
RTL run negative left bound is returned, same goes for vertical direction - top bound will be negative
|
||||
for any non-zero glyph ascender */
|
||||
origin_x = 0.0;
|
||||
is_rtl = This->run.bidiLevel & 1;
|
||||
for (i = 0; i < This->run.glyphCount; i++) {
|
||||
const DWRITE_GLYPH_OFFSET *offset = &This->offsets[i];
|
||||
FLOAT advance = This->advances[i];
|
||||
RECT bbox;
|
||||
|
||||
freetype_get_glyph_bbox(fontface2, This->run.fontEmSize * This->ppdip, This->run.glyphIndices[i], nohint, &bbox);
|
||||
|
||||
if (is_rtl)
|
||||
OffsetRect(&bbox, origin_x - offset->advanceOffset - advance, -offset->ascenderOffset);
|
||||
else
|
||||
OffsetRect(&bbox, origin_x + offset->advanceOffset, offset->ascenderOffset);
|
||||
|
||||
UnionRect(&This->bounds, &This->bounds, &bbox);
|
||||
origin_x += is_rtl ? -advance : advance;
|
||||
}
|
||||
|
||||
IDWriteFontFace2_Release(fontface2);
|
||||
|
||||
This->ready |= RUNANALYSIS_BOUNDS;
|
||||
*bounds = This->bounds;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI glyphrunanalysis_CreateAlphaTexture(IDWriteGlyphRunAnalysis *iface, DWRITE_TEXTURE_TYPE type,
|
||||
|
@ -2977,7 +3028,7 @@ static const struct IDWriteGlyphRunAnalysisVtbl glyphrunanalysisvtbl = {
|
|||
glyphrunanalysis_GetAlphaBlendParams
|
||||
};
|
||||
|
||||
HRESULT create_glyphrunanalysis(DWRITE_RENDERING_MODE rendering_mode, DWRITE_GLYPH_RUN const *run, IDWriteGlyphRunAnalysis **ret)
|
||||
HRESULT create_glyphrunanalysis(DWRITE_RENDERING_MODE rendering_mode, DWRITE_GLYPH_RUN const *run, FLOAT ppdip, IDWriteGlyphRunAnalysis **ret)
|
||||
{
|
||||
struct dwrite_glyphrunanalysis *analysis;
|
||||
|
||||
|
@ -2994,6 +3045,9 @@ HRESULT create_glyphrunanalysis(DWRITE_RENDERING_MODE rendering_mode, DWRITE_GLY
|
|||
analysis->IDWriteGlyphRunAnalysis_iface.lpVtbl = &glyphrunanalysisvtbl;
|
||||
analysis->ref = 1;
|
||||
analysis->rendering_mode = rendering_mode;
|
||||
analysis->ready = 0;
|
||||
analysis->ppdip = ppdip;
|
||||
SetRectEmpty(&analysis->bounds);
|
||||
analysis->run = *run;
|
||||
IDWriteFontFace_AddRef(analysis->run.fontFace);
|
||||
analysis->glyphs = heap_alloc(run->glyphCount*sizeof(*run->glyphIndices));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* FreeType integration
|
||||
*
|
||||
* Copyright 2014 Nikolay Sivov for CodeWeavers
|
||||
* Copyright 2014-2015 Nikolay Sivov for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -54,6 +54,7 @@ static void *ft_handle = NULL;
|
|||
static FT_Library library = 0;
|
||||
static FTC_Manager cache_manager = 0;
|
||||
static FTC_CMapCache cmap_cache = 0;
|
||||
static FTC_ImageCache image_cache = 0;
|
||||
typedef struct
|
||||
{
|
||||
FT_Int major;
|
||||
|
@ -64,6 +65,7 @@ typedef struct
|
|||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL
|
||||
MAKE_FUNCPTR(FT_Done_FreeType);
|
||||
MAKE_FUNCPTR(FT_Get_Kerning);
|
||||
MAKE_FUNCPTR(FT_Glyph_Get_CBox);
|
||||
MAKE_FUNCPTR(FT_Init_FreeType);
|
||||
MAKE_FUNCPTR(FT_Library_Version);
|
||||
MAKE_FUNCPTR(FT_Load_Glyph);
|
||||
|
@ -71,6 +73,8 @@ MAKE_FUNCPTR(FT_New_Memory_Face);
|
|||
MAKE_FUNCPTR(FT_Outline_Transform);
|
||||
MAKE_FUNCPTR(FTC_CMapCache_Lookup);
|
||||
MAKE_FUNCPTR(FTC_CMapCache_New);
|
||||
MAKE_FUNCPTR(FTC_ImageCache_Lookup);
|
||||
MAKE_FUNCPTR(FTC_ImageCache_New);
|
||||
MAKE_FUNCPTR(FTC_Manager_New);
|
||||
MAKE_FUNCPTR(FTC_Manager_Done);
|
||||
MAKE_FUNCPTR(FTC_Manager_LookupFace);
|
||||
|
@ -137,6 +141,7 @@ BOOL init_freetype(void)
|
|||
#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(ft_handle, #f, NULL, 0)) == NULL){WARN("Can't find symbol %s\n", #f); goto sym_not_found;}
|
||||
LOAD_FUNCPTR(FT_Done_FreeType)
|
||||
LOAD_FUNCPTR(FT_Get_Kerning)
|
||||
LOAD_FUNCPTR(FT_Glyph_Get_CBox)
|
||||
LOAD_FUNCPTR(FT_Init_FreeType)
|
||||
LOAD_FUNCPTR(FT_Library_Version)
|
||||
LOAD_FUNCPTR(FT_Load_Glyph)
|
||||
|
@ -144,6 +149,8 @@ BOOL init_freetype(void)
|
|||
LOAD_FUNCPTR(FT_Outline_Transform)
|
||||
LOAD_FUNCPTR(FTC_CMapCache_Lookup)
|
||||
LOAD_FUNCPTR(FTC_CMapCache_New)
|
||||
LOAD_FUNCPTR(FTC_ImageCache_Lookup)
|
||||
LOAD_FUNCPTR(FTC_ImageCache_New)
|
||||
LOAD_FUNCPTR(FTC_Manager_New)
|
||||
LOAD_FUNCPTR(FTC_Manager_Done)
|
||||
LOAD_FUNCPTR(FTC_Manager_LookupFace)
|
||||
|
@ -161,7 +168,8 @@ BOOL init_freetype(void)
|
|||
|
||||
/* init cache manager */
|
||||
if (pFTC_Manager_New(library, 0, 0, 0, &face_requester, NULL, &cache_manager) != 0 ||
|
||||
pFTC_CMapCache_New(cache_manager, &cmap_cache) != 0) {
|
||||
pFTC_CMapCache_New(cache_manager, &cmap_cache) != 0 ||
|
||||
pFTC_ImageCache_New(cache_manager, &image_cache) != 0) {
|
||||
|
||||
ERR("Failed to init FreeType cache\n");
|
||||
pFTC_Manager_Done(cache_manager);
|
||||
|
@ -456,6 +464,29 @@ INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2 *fontface, UINT16 le
|
|||
return adjustment;
|
||||
}
|
||||
|
||||
void freetype_get_glyph_bbox(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 index, BOOL nohint, RECT *ret)
|
||||
{
|
||||
FTC_ImageTypeRec imagetype;
|
||||
FT_BBox bbox = { 0 };
|
||||
FT_Glyph glyph;
|
||||
|
||||
imagetype.face_id = fontface;
|
||||
imagetype.width = 0;
|
||||
imagetype.height = emSize;
|
||||
imagetype.flags = nohint ? FT_LOAD_NO_HINTING : FT_LOAD_DEFAULT;
|
||||
|
||||
EnterCriticalSection(&freetype_cs);
|
||||
if (pFTC_ImageCache_Lookup(image_cache, &imagetype, index, &glyph, NULL) == 0)
|
||||
pFT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &bbox);
|
||||
LeaveCriticalSection(&freetype_cs);
|
||||
|
||||
/* flip Y axis */
|
||||
ret->left = bbox.xMin;
|
||||
ret->right = bbox.xMax;
|
||||
ret->top = -bbox.yMax;
|
||||
ret->bottom = -bbox.yMin;
|
||||
}
|
||||
|
||||
#else /* HAVE_FREETYPE */
|
||||
|
||||
BOOL init_freetype(void)
|
||||
|
@ -507,4 +538,9 @@ INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2 *fontface, UINT16 le
|
|||
return 0;
|
||||
}
|
||||
|
||||
void freetype_get_glyph_bbox(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 index, BOOL nohint, RECT *ret)
|
||||
{
|
||||
ret->left = ret->right = ret->top = ret->bottom = 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_FREETYPE */
|
||||
|
|
|
@ -1076,10 +1076,10 @@ static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory2 *ifac
|
|||
{
|
||||
struct dwritefactory *This = impl_from_IDWriteFactory2(iface);
|
||||
|
||||
TRACE("(%p)->(%p %f %p %d %d %f %f %p)\n", This, run, ppdip, transform, rendering_mode,
|
||||
TRACE("(%p)->(%p %.2f %p %d %d %f %f %p)\n", This, run, ppdip, transform, rendering_mode,
|
||||
measuring_mode, baseline_x, baseline_y, analysis);
|
||||
|
||||
return create_glyphrunanalysis(rendering_mode, run, analysis);
|
||||
return create_glyphrunanalysis(rendering_mode, run, ppdip, analysis);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefactory1_GetEudcFontCollection(IDWriteFactory2 *iface, IDWriteFontCollection **collection,
|
||||
|
|
|
@ -3500,10 +3500,9 @@ static void test_CreateGlyphRunAnalysis(void)
|
|||
if (rendermodes[i] == DWRITE_RENDERING_MODE_ALIASED) {
|
||||
memset(&rect, 0, sizeof(rect));
|
||||
hr = IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis, DWRITE_TEXTURE_ALIASED_1x1, &rect);
|
||||
todo_wine {
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
ok(!IsRectEmpty(&rect), "got empty rect\n");
|
||||
}
|
||||
|
||||
rect.left = rect.top = 0;
|
||||
rect.bottom = rect.right = 1;
|
||||
hr = IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis, DWRITE_TEXTURE_CLEARTYPE_3x1, &rect);
|
||||
|
@ -3519,11 +3518,9 @@ static void test_CreateGlyphRunAnalysis(void)
|
|||
|
||||
memset(&rect, 0, sizeof(rect));
|
||||
hr = IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis, DWRITE_TEXTURE_CLEARTYPE_3x1, &rect);
|
||||
todo_wine {
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
ok(!IsRectEmpty(&rect), "got empty rect\n");
|
||||
}
|
||||
}
|
||||
|
||||
IDWriteGlyphRunAnalysis_Release(analysis);
|
||||
}
|
||||
|
@ -3542,10 +3539,7 @@ static void test_CreateGlyphRunAnalysis(void)
|
|||
|
||||
memset(&rect, 0, sizeof(rect));
|
||||
hr = IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis, DWRITE_TEXTURE_ALIASED_1x1, &rect);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
if (hr != S_OK)
|
||||
break;
|
||||
|
||||
hr = IDWriteFontFace_GetGdiCompatibleGlyphMetrics(run.fontFace, run.fontEmSize, 1.0, NULL,
|
||||
DWRITE_MEASURING_MODE_GDI_CLASSIC, run.glyphIndices, 1, &gm, run.isSideways);
|
||||
|
@ -3557,8 +3551,8 @@ static void test_CreateGlyphRunAnalysis(void)
|
|||
|
||||
rect.right -= rect.left;
|
||||
rect.bottom -= rect.top;
|
||||
ok(abs(bboxX - rect.right) <= 1, "%.0f: bbox width %d, from metrics %d\n", run.fontEmSize, rect.right, bboxX);
|
||||
ok(abs(bboxY - rect.bottom) <= 1, "%.0f: bbox height %d, from metrics %d\n", run.fontEmSize, rect.bottom, bboxY);
|
||||
ok(abs(bboxX - rect.right) <= 2, "%.0f: bbox width %d, from metrics %d\n", run.fontEmSize, rect.right, bboxX);
|
||||
ok(abs(bboxY - rect.bottom) <= 2, "%.0f: bbox height %d, from metrics %d\n", run.fontEmSize, rect.bottom, bboxY);
|
||||
|
||||
IDWriteGlyphRunAnalysis_Release(analysis);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue