mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 12:06:32 +00:00
dwrite: Initial implementation of ComputeGlyphOrigins().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
764ee72641
commit
e258917a43
2 changed files with 143 additions and 4 deletions
|
@ -21,6 +21,7 @@
|
|||
#define COBJMACROS
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
@ -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,
|
||||
|
@ -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 = {
|
||||
|
|
|
@ -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;
|
||||
|
@ -6917,6 +6981,7 @@ START_TEST(font)
|
|||
test_font_properties();
|
||||
test_HasVerticalGlyphVariants();
|
||||
test_HasKerningPairs();
|
||||
test_ComputeGlyphOrigins();
|
||||
|
||||
IDWriteFactory_Release(factory);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue