Skip to content

Commit

Permalink
dwrite: Initial implementation of ComputeGlyphOrigins().
Browse files Browse the repository at this point in the history
Signed-off-by: Nikolay Sivov <[email protected]>
Signed-off-by: Alexandre Julliard <[email protected]>
  • Loading branch information
nsivov authored and julliard committed Apr 7, 2017
1 parent 764ee72 commit e258917
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 4 deletions.
82 changes: 78 additions & 4 deletions dlls/dwrite/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define COBJMACROS

#include <stdarg.h>
#include <math.h>

#include "windef.h"
#include "winbase.h"
Expand Down Expand Up @@ -1438,14 +1439,86 @@ static HRESULT WINAPI dwritefactory4_TranslateColorGlyphRun(IDWriteFactory4 *ifa
return E_NOTIMPL;
}

static HRESULT compute_glyph_origins(DWRITE_GLYPH_RUN const *run, DWRITE_MEASURING_MODE measuring_mode,
D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform, D2D1_POINT_2F *origins)
{
IDWriteFontFace1 *fontface1 = NULL;
DWRITE_FONT_METRICS metrics;
FLOAT rtl_factor;
UINT32 i;

rtl_factor = run->bidiLevel & 1 ? -1.0f : 1.0f;

if (run->fontFace) {
IDWriteFontFace_GetMetrics(run->fontFace, &metrics);
IDWriteFontFace_QueryInterface(run->fontFace, &IID_IDWriteFontFace1, (void **)&fontface1);
}

for (i = 0; i < run->glyphCount; i++) {
FLOAT advance;

/* Use nominal advances if not provided by caller. */
if (run->glyphAdvances)
advance = rtl_factor * run->glyphAdvances[i];
else {
INT32 a;

advance = 0.0f;
switch (measuring_mode)
{
case DWRITE_MEASURING_MODE_NATURAL:
if (SUCCEEDED(IDWriteFontFace1_GetDesignGlyphAdvances(fontface1, 1, run->glyphIndices + i, &a,
run->isSideways)))
advance = rtl_factor * get_scaled_advance_width(a, run->fontEmSize, &metrics);
break;
case DWRITE_MEASURING_MODE_GDI_CLASSIC:
case DWRITE_MEASURING_MODE_GDI_NATURAL:
if (SUCCEEDED(IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1, run->fontEmSize,
1.0f, transform, measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL,
run->isSideways, 1, run->glyphIndices + i, &a)))
advance = rtl_factor * floorf(a * run->fontEmSize / metrics.designUnitsPerEm + 0.5f);
break;
default:
;
}
}

origins[i] = baseline_origin;

/* Apply offsets. */
if (run->glyphOffsets) {
FLOAT advanceoffset = rtl_factor * run->glyphOffsets[i].advanceOffset;
FLOAT ascenderoffset = -run->glyphOffsets[i].ascenderOffset;

if (run->isSideways) {
origins[i].x += ascenderoffset;
origins[i].y += advanceoffset;
}
else {
origins[i].x += advanceoffset;
origins[i].y += ascenderoffset;
}
}

if (run->isSideways)
baseline_origin.y += advance;
else
baseline_origin.x += advance;
}

if (fontface1)
IDWriteFontFace1_Release(fontface1);
return S_OK;
}

static HRESULT WINAPI dwritefactory4_ComputeGlyphOrigins_(IDWriteFactory4 *iface, DWRITE_GLYPH_RUN const *run,
D2D1_POINT_2F baseline_origin, D2D1_POINT_2F *origins)
{
struct dwritefactory *This = impl_from_IDWriteFactory4(iface);

FIXME("(%p)->(%p %p): stub\n", This, run, origins);
TRACE("(%p)->(%p (%f,%f) %p)\n", This, run, baseline_origin.x, baseline_origin.y, origins);

return E_NOTIMPL;
return compute_glyph_origins(run, DWRITE_MEASURING_MODE_NATURAL, baseline_origin, NULL, origins);
}

static HRESULT WINAPI dwritefactory4_ComputeGlyphOrigins(IDWriteFactory4 *iface, DWRITE_GLYPH_RUN const *run,
Expand All @@ -1454,9 +1527,10 @@ static HRESULT WINAPI dwritefactory4_ComputeGlyphOrigins(IDWriteFactory4 *iface,
{
struct dwritefactory *This = impl_from_IDWriteFactory4(iface);

FIXME("(%p)->(%p %d %p %p): stub\n", This, run, measuring_mode, transform, origins);
TRACE("(%p)->(%p %d (%f,%f) %p %p)\n", This, run, measuring_mode, baseline_origin.x, baseline_origin.y,
transform, origins);

return E_NOTIMPL;
return compute_glyph_origins(run, measuring_mode, baseline_origin, transform, origins);
}

static const struct IDWriteFactory4Vtbl dwritefactoryvtbl = {
Expand Down
65 changes: 65 additions & 0 deletions dlls/dwrite/tests/font.c
Original file line number Diff line number Diff line change
Expand Up @@ -6858,6 +6858,70 @@ static void test_HasKerningPairs(void)
IDWriteFactory_Release(factory);
}

static void test_ComputeGlyphOrigins(void)
{
IDWriteFactory4 *factory4;
IDWriteFactory *factory;
DWRITE_GLYPH_RUN run;
HRESULT hr;
D2D1_POINT_2F origins[2];
D2D1_POINT_2F baseline_origin;
UINT16 glyphs[2];
FLOAT advances[2];
DWRITE_MATRIX m;

factory = create_factory();
hr = IDWriteFactory_QueryInterface(factory, &IID_IDWriteFactory4, (void **)&factory4);
IDWriteFactory_Release(factory);
if (FAILED(hr)) {
win_skip("ComputeGlyphOrigins() is not supported.\n");
return;
}

advances[0] = 10.0f;
advances[1] = 20.0f;

run.fontFace = NULL;
run.fontEmSize = 16.0f;
run.glyphCount = 2;
run.glyphIndices = glyphs;
run.glyphAdvances = advances;
run.glyphOffsets = NULL;
run.isSideways = FALSE;
run.bidiLevel = 0;

baseline_origin.x = 123.0f;
baseline_origin.y = 321.0f;

memset(origins, 0, sizeof(origins));
hr = IDWriteFactory4_ComputeGlyphOrigins_(factory4, &run, baseline_origin, origins);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(origins[0].x == 123.0f && origins[0].y == 321.0f, "origins[0] %f,%f\n", origins[0].x, origins[0].y);
ok(origins[1].x == 133.0f && origins[1].y == 321.0f, "origins[1] %f,%f\n", origins[1].x, origins[1].y);

memset(origins, 0, sizeof(origins));
hr = IDWriteFactory4_ComputeGlyphOrigins(factory4, &run, DWRITE_MEASURING_MODE_NATURAL, baseline_origin,
NULL, origins);
ok(origins[0].x == 123.0f && origins[0].y == 321.0f, "origins[0] %f,%f\n", origins[0].x, origins[0].y);
ok(origins[1].x == 133.0f && origins[1].y == 321.0f, "origins[1] %f,%f\n", origins[1].x, origins[1].y);

/* transform is not applied to returned origins */
m.m11 = 2.0f;
m.m12 = 0.0f;
m.m21 = 0.0f;
m.m22 = 1.0f;
m.dx = 0.0f;
m.dy = 0.0f;

memset(origins, 0, sizeof(origins));
hr = IDWriteFactory4_ComputeGlyphOrigins(factory4, &run, DWRITE_MEASURING_MODE_NATURAL, baseline_origin,
&m, origins);
ok(origins[0].x == 123.0f && origins[0].y == 321.0f, "origins[0] %f,%f\n", origins[0].x, origins[0].y);
ok(origins[1].x == 133.0f && origins[1].y == 321.0f, "origins[1] %f,%f\n", origins[1].x, origins[1].y);

IDWriteFactory4_Release(factory4);
}

START_TEST(font)
{
IDWriteFactory *factory;
Expand Down Expand Up @@ -6917,6 +6981,7 @@ START_TEST(font)
test_font_properties();
test_HasVerticalGlyphVariants();
test_HasKerningPairs();
test_ComputeGlyphOrigins();

IDWriteFactory_Release(factory);
}

0 comments on commit e258917

Please sign in to comment.