Commit 0ed0fd05 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

dwrite: Request one glyph outline at a time in GetGlyphRunOutline().

parent 6f9e1e07
...@@ -463,9 +463,8 @@ extern void release_freetype(void) DECLSPEC_HIDDEN; ...@@ -463,9 +463,8 @@ extern void release_freetype(void) DECLSPEC_HIDDEN;
extern HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, extern HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph,
DWRITE_GLYPH_METRICS *metrics) DECLSPEC_HIDDEN; DWRITE_GLYPH_METRICS *metrics) DECLSPEC_HIDDEN;
extern void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN; extern void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emsize, UINT16 const *glyphs, extern HRESULT freetype_get_glyph_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 glyph,
float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl, D2D1_POINT_2F origin, IDWriteGeometrySink *sink) DECLSPEC_HIDDEN;
IDWriteGeometrySink *sink) DECLSPEC_HIDDEN;
extern UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN; extern UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap_desc) DECLSPEC_HIDDEN; extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap_desc) DECLSPEC_HIDDEN;
extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN; extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
......
...@@ -827,16 +827,49 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface, ...@@ -827,16 +827,49 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface,
UINT16 const *glyphs, FLOAT const* advances, DWRITE_GLYPH_OFFSET const *offsets, UINT16 const *glyphs, FLOAT const* advances, DWRITE_GLYPH_OFFSET const *offsets,
UINT32 count, BOOL is_sideways, BOOL is_rtl, IDWriteGeometrySink *sink) UINT32 count, BOOL is_sideways, BOOL is_rtl, IDWriteGeometrySink *sink)
{ {
D2D1_POINT_2F *origins, baseline_origin = { 0 };
DWRITE_GLYPH_RUN run;
unsigned int i;
HRESULT hr;
TRACE("%p, %.8e, %p, %p, %p, %u, %d, %d, %p.\n", iface, emSize, glyphs, advances, offsets, TRACE("%p, %.8e, %p, %p, %p, %u, %d, %d, %p.\n", iface, emSize, glyphs, advances, offsets,
count, is_sideways, is_rtl, sink); count, is_sideways, is_rtl, sink);
if (!glyphs || !sink) if (!glyphs || !sink)
return E_INVALIDARG; return E_INVALIDARG;
if (is_sideways) if (!count)
FIXME("sideways mode is not supported.\n"); return S_OK;
return freetype_get_glyphrun_outline(iface, emSize, glyphs, advances, offsets, count, is_rtl, sink); run.fontFace = (IDWriteFontFace *)iface;
run.fontEmSize = emSize;
run.glyphCount = count;
run.glyphIndices = glyphs;
run.glyphAdvances = advances;
run.glyphOffsets = offsets;
run.isSideways = is_sideways;
run.bidiLevel = is_rtl ? 1 : 0;
if (!(origins = heap_alloc(sizeof(*origins) * count)))
return E_OUTOFMEMORY;
if (FAILED(hr = compute_glyph_origins(&run, DWRITE_MEASURING_MODE_NATURAL, baseline_origin, NULL, origins)))
{
heap_free(origins);
return hr;
}
ID2D1SimplifiedGeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
for (i = 0; i < count; ++i)
{
if (FAILED(hr = freetype_get_glyph_outline(iface, emSize, glyphs[i], origins[i], sink)))
WARN("Failed to get glyph outline for glyph %u.\n", glyphs[i]);
}
heap_free(origins);
return S_OK;
} }
static DWRITE_RENDERING_MODE fontface_renderingmode_from_measuringmode(DWRITE_MEASURING_MODE measuring, static DWRITE_RENDERING_MODE fontface_renderingmode_from_measuringmode(DWRITE_MEASURING_MODE measuring,
......
...@@ -464,20 +464,14 @@ static void embolden_glyph(FT_Glyph glyph, FLOAT emsize) ...@@ -464,20 +464,14 @@ static void embolden_glyph(FT_Glyph glyph, FLOAT emsize)
embolden_glyph_outline(&outline_glyph->outline, emsize); embolden_glyph_outline(&outline_glyph->outline, emsize);
} }
HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 const *glyphs, HRESULT freetype_get_glyph_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 glyph,
float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl, D2D1_POINT_2F origin, IDWriteGeometrySink *sink)
IDWriteGeometrySink *sink)
{ {
FTC_ScalerRec scaler; FTC_ScalerRec scaler;
USHORT simulations; USHORT simulations;
HRESULT hr = S_OK; HRESULT hr = S_OK;
FT_Size size; FT_Size size;
if (!count)
return S_OK;
ID2D1SimplifiedGeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
simulations = IDWriteFontFace5_GetSimulations(fontface); simulations = IDWriteFontFace5_GetSimulations(fontface);
scaler.face_id = fontface; scaler.face_id = fontface;
...@@ -490,56 +484,22 @@ HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize, ...@@ -490,56 +484,22 @@ HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize,
EnterCriticalSection(&freetype_cs); EnterCriticalSection(&freetype_cs);
if (pFTC_Manager_LookupSize(cache_manager, &scaler, &size) == 0) if (pFTC_Manager_LookupSize(cache_manager, &scaler, &size) == 0)
{ {
D2D1_POINT_2F origin; if (pFT_Load_Glyph(size->face, glyph, FT_LOAD_NO_BITMAP) == 0)
unsigned int i;
origin.x = origin.y = 0.0f;
for (i = 0; i < count; ++i)
{ {
if (pFT_Load_Glyph(size->face, glyphs[i], FT_LOAD_NO_BITMAP) == 0) FT_Outline *outline = &size->face->glyph->outline;
{ FT_Matrix m;
FLOAT ft_advance = size->face->glyph->metrics.horiAdvance >> 6;
FT_Outline *outline = &size->face->glyph->outline; if (simulations & DWRITE_FONT_SIMULATIONS_BOLD)
D2D1_POINT_2F glyph_origin; embolden_glyph_outline(outline, emSize);
FT_Matrix m;
m.xx = 1 << 16;
if (simulations & DWRITE_FONT_SIMULATIONS_BOLD) m.xy = simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE ? (1 << 16) / 3 : 0;
embolden_glyph_outline(outline, emSize); m.yx = 0;
m.yy = -(1 << 16); /* flip Y axis */
m.xx = 1 << 16;
m.xy = simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE ? (1 << 16) / 3 : 0; pFT_Outline_Transform(outline, &m);
m.yx = 0;
m.yy = -(1 << 16); /* flip Y axis */ decompose_outline(outline, origin, sink);
pFT_Outline_Transform(outline, &m);
glyph_origin = origin;
if (is_rtl)
{
glyph_origin.x -= ft_advance;
if (offsets)
{
glyph_origin.x -= offsets[i].advanceOffset;
glyph_origin.y -= offsets[i].ascenderOffset;
}
origin.x -= advances ? advances[i] : ft_advance;
}
else
{
if (offsets)
{
glyph_origin.x += offsets[i].advanceOffset;
glyph_origin.y -= offsets[i].ascenderOffset;
}
origin.x += advances ? advances[i] : ft_advance;
}
decompose_outline(outline, glyph_origin, sink);
}
} }
} }
else else
...@@ -837,9 +797,8 @@ HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT ...@@ -837,9 +797,8 @@ HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT
return E_NOTIMPL; return E_NOTIMPL;
} }
HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 const *glyphs, HRESULT freetype_get_glyph_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 glyph,
float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl, D2D1_POINT_2F origin, IDWriteGeometrySink *sink)
IDWriteGeometrySink *sink)
{ {
return E_NOTIMPL; return E_NOTIMPL;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment