dwrite: Implement GetGdiCompatibleMetrics().
This commit is contained in:
parent
119af47683
commit
849bb99b76
|
@ -139,6 +139,7 @@ extern void opentype_get_font_properties(IDWriteFontFileStream*,DWRITE_FONT_FACE
|
||||||
extern void opentype_get_font_metrics(IDWriteFontFileStream*,DWRITE_FONT_FACE_TYPE,UINT32,DWRITE_FONT_METRICS1*,DWRITE_CARET_METRICS*) DECLSPEC_HIDDEN;
|
extern void opentype_get_font_metrics(IDWriteFontFileStream*,DWRITE_FONT_FACE_TYPE,UINT32,DWRITE_FONT_METRICS1*,DWRITE_CARET_METRICS*) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT opentype_get_font_strings_from_id(const void*,DWRITE_INFORMATIONAL_STRING_ID,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
|
extern HRESULT opentype_get_font_strings_from_id(const void*,DWRITE_INFORMATIONAL_STRING_ID,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT opentype_get_typographic_features(IDWriteFontFace*,UINT32,UINT32,UINT32,UINT32*,DWRITE_FONT_FEATURE_TAG*) DECLSPEC_HIDDEN;
|
extern HRESULT opentype_get_typographic_features(IDWriteFontFace*,UINT32,UINT32,UINT32,UINT32*,DWRITE_FONT_FEATURE_TAG*) DECLSPEC_HIDDEN;
|
||||||
|
extern BOOL opentype_get_vdmx_size(const void*,INT,UINT16*,UINT16*) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* BiDi helpers */
|
/* BiDi helpers */
|
||||||
extern HRESULT bidi_computelevels(const WCHAR*,UINT32,UINT8,UINT8*,UINT8*) DECLSPEC_HIDDEN;
|
extern HRESULT bidi_computelevels(const WCHAR*,UINT32,UINT8,UINT8*,UINT8*) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#define COBJMACROS
|
#define COBJMACROS
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
|
||||||
#define MS_OS2_TAG DWRITE_MAKE_OPENTYPE_TAG('O','S','/','2')
|
#define MS_OS2_TAG DWRITE_MAKE_OPENTYPE_TAG('O','S','/','2')
|
||||||
#define MS_CMAP_TAG DWRITE_MAKE_OPENTYPE_TAG('c','m','a','p')
|
#define MS_CMAP_TAG DWRITE_MAKE_OPENTYPE_TAG('c','m','a','p')
|
||||||
#define MS_NAME_TAG DWRITE_MAKE_OPENTYPE_TAG('n','a','m','e')
|
#define MS_NAME_TAG DWRITE_MAKE_OPENTYPE_TAG('n','a','m','e')
|
||||||
|
#define MS_VDMX_TAG DWRITE_MAKE_OPENTYPE_TAG('V','D','M','X')
|
||||||
|
|
||||||
static const IID IID_issystemcollection = {0x14d88047,0x331f,0x4cd3,{0xbc,0xa8,0x3e,0x67,0x99,0xaf,0x34,0x75}};
|
static const IID IID_issystemcollection = {0x14d88047,0x331f,0x4cd3,{0xbc,0xa8,0x3e,0x67,0x99,0xaf,0x34,0x75}};
|
||||||
|
|
||||||
|
@ -96,6 +98,7 @@ struct dwrite_fonttable {
|
||||||
void *data;
|
void *data;
|
||||||
void *context;
|
void *context;
|
||||||
UINT32 size;
|
UINT32 size;
|
||||||
|
BOOL exists;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dwrite_glyphrunanalysis {
|
struct dwrite_glyphrunanalysis {
|
||||||
|
@ -123,6 +126,7 @@ struct dwrite_fontface {
|
||||||
DWRITE_CARET_METRICS caret;
|
DWRITE_CARET_METRICS caret;
|
||||||
|
|
||||||
struct dwrite_fonttable cmap;
|
struct dwrite_fonttable cmap;
|
||||||
|
struct dwrite_fonttable vdmx;
|
||||||
DWRITE_GLYPH_METRICS *glyphs[GLYPH_MAX/GLYPH_BLOCK_SIZE];
|
DWRITE_GLYPH_METRICS *glyphs[GLYPH_MAX/GLYPH_BLOCK_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -166,6 +170,11 @@ static inline struct dwrite_glyphrunanalysis *impl_from_IDWriteGlyphRunAnalysis(
|
||||||
return CONTAINING_RECORD(iface, struct dwrite_glyphrunanalysis, IDWriteGlyphRunAnalysis_iface);
|
return CONTAINING_RECORD(iface, struct dwrite_glyphrunanalysis, IDWriteGlyphRunAnalysis_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const char *debugstr_tag(UINT32 tag)
|
||||||
|
{
|
||||||
|
return wine_dbg_sprintf("%c%c%c%c", tag >> 24, (tag >> 16) & 0xff, (tag >> 8) & 0xff, tag & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT get_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *metrics)
|
static HRESULT get_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *metrics)
|
||||||
{
|
{
|
||||||
static const DWRITE_GLYPH_METRICS nil;
|
static const DWRITE_GLYPH_METRICS nil;
|
||||||
|
@ -191,22 +200,32 @@ static HRESULT set_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void* get_fontface_cmap(struct dwrite_fontface *fontface)
|
static void* get_fontface_table(struct dwrite_fontface *fontface, UINT32 tag, struct dwrite_fonttable *table)
|
||||||
{
|
{
|
||||||
BOOL exists = FALSE;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (fontface->cmap.data)
|
if (table->data || !table->exists)
|
||||||
return fontface->cmap.data;
|
return table->data;
|
||||||
|
|
||||||
hr = IDWriteFontFace2_TryGetFontTable(&fontface->IDWriteFontFace2_iface, MS_CMAP_TAG, (const void**)&fontface->cmap.data,
|
table->exists = FALSE;
|
||||||
&fontface->cmap.size, &fontface->cmap.context, &exists);
|
hr = IDWriteFontFace2_TryGetFontTable(&fontface->IDWriteFontFace2_iface, tag, (const void**)&table->data,
|
||||||
if (FAILED(hr) || !exists) {
|
&table->size, &table->context, &table->exists);
|
||||||
ERR("Font does not have a CMAP table\n");
|
if (FAILED(hr) || !table->exists) {
|
||||||
|
WARN("Font does not have a %s table\n", debugstr_tag(tag));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fontface->cmap.data;
|
return table->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void* get_fontface_cmap(struct dwrite_fontface *fontface)
|
||||||
|
{
|
||||||
|
return get_fontface_table(fontface, MS_CMAP_TAG, &fontface->cmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void* get_fontface_vdmx(struct dwrite_fontface *fontface)
|
||||||
|
{
|
||||||
|
return get_fontface_table(fontface, MS_VDMX_TAG, &fontface->vdmx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void release_font_data(struct dwrite_font_data *data)
|
static void release_font_data(struct dwrite_font_data *data)
|
||||||
|
@ -281,6 +300,8 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace2 *iface)
|
||||||
|
|
||||||
if (This->cmap.context)
|
if (This->cmap.context)
|
||||||
IDWriteFontFace2_ReleaseFontTable(iface, This->cmap.context);
|
IDWriteFontFace2_ReleaseFontTable(iface, This->cmap.context);
|
||||||
|
if (This->vdmx.context)
|
||||||
|
IDWriteFontFace2_ReleaseFontTable(iface, This->vdmx.context);
|
||||||
for (i = 0; i < This->file_count; i++) {
|
for (i = 0; i < This->file_count; i++) {
|
||||||
if (This->streams[i])
|
if (This->streams[i])
|
||||||
IDWriteFontFileStream_Release(This->streams[i]);
|
IDWriteFontFileStream_Release(This->streams[i]);
|
||||||
|
@ -573,16 +594,8 @@ static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace
|
||||||
static HRESULT WINAPI dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace2 *iface, FLOAT emSize, FLOAT pixels_per_dip,
|
static HRESULT WINAPI dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace2 *iface, FLOAT emSize, FLOAT pixels_per_dip,
|
||||||
DWRITE_MATRIX const *transform, DWRITE_FONT_METRICS *metrics)
|
DWRITE_MATRIX const *transform, DWRITE_FONT_METRICS *metrics)
|
||||||
{
|
{
|
||||||
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
|
|
||||||
DWRITE_FONT_METRICS1 metrics1;
|
DWRITE_FONT_METRICS1 metrics1;
|
||||||
HRESULT hr;
|
HRESULT hr = IDWriteFontFace2_GetGdiCompatibleMetrics(iface, emSize, pixels_per_dip, transform, &metrics1);
|
||||||
|
|
||||||
TRACE("(%p)->(%.2f %.2f %p %p)\n", This, emSize, pixels_per_dip, transform, metrics);
|
|
||||||
|
|
||||||
hr = IDWriteFontFace2_GetGdiCompatibleMetrics(iface, emSize, pixels_per_dip, transform, &metrics1);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
memcpy(metrics, &metrics1, sizeof(*metrics));
|
memcpy(metrics, &metrics1, sizeof(*metrics));
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
@ -604,12 +617,65 @@ static void WINAPI dwritefontface1_GetMetrics(IDWriteFontFace2 *iface, DWRITE_FO
|
||||||
*metrics = This->metrics;
|
*metrics = This->metrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int round_metric(FLOAT metric)
|
||||||
|
{
|
||||||
|
return (int)floor(metric + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace2 *iface, FLOAT em_size, FLOAT pixels_per_dip,
|
static HRESULT WINAPI dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace2 *iface, FLOAT em_size, FLOAT pixels_per_dip,
|
||||||
const DWRITE_MATRIX *transform, DWRITE_FONT_METRICS1 *metrics)
|
const DWRITE_MATRIX *m, DWRITE_FONT_METRICS1 *metrics)
|
||||||
{
|
{
|
||||||
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
|
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
|
||||||
FIXME("(%p)->(%f %f %p %p): stub\n", This, em_size, pixels_per_dip, transform, metrics);
|
const DWRITE_FONT_METRICS1 *design = &This->metrics;
|
||||||
return E_NOTIMPL;
|
UINT16 ascent, descent;
|
||||||
|
FLOAT scale;
|
||||||
|
|
||||||
|
TRACE("(%p)->(%.2f %.2f %p %p)\n", This, em_size, pixels_per_dip, m, metrics);
|
||||||
|
|
||||||
|
if (pixels_per_dip <= 0.0) {
|
||||||
|
memset(metrics, 0, sizeof(*metrics));
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
em_size *= pixels_per_dip;
|
||||||
|
if (m && m->m22 != 0.0)
|
||||||
|
em_size *= fabs(m->m22);
|
||||||
|
|
||||||
|
scale = em_size / design->designUnitsPerEm;
|
||||||
|
if (!opentype_get_vdmx_size(get_fontface_vdmx(This), em_size, &ascent, &descent)) {
|
||||||
|
ascent = round_metric(design->ascent * scale);
|
||||||
|
descent = round_metric(design->descent * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SCALE_METRIC(x) metrics->x = round_metric(round_metric((design->x) * scale) / scale)
|
||||||
|
metrics->designUnitsPerEm = design->designUnitsPerEm;
|
||||||
|
metrics->ascent = round_metric(ascent / scale);
|
||||||
|
metrics->descent = round_metric(descent / scale);
|
||||||
|
|
||||||
|
SCALE_METRIC(lineGap);
|
||||||
|
SCALE_METRIC(capHeight);
|
||||||
|
SCALE_METRIC(xHeight);
|
||||||
|
SCALE_METRIC(underlinePosition);
|
||||||
|
SCALE_METRIC(underlineThickness);
|
||||||
|
SCALE_METRIC(strikethroughPosition);
|
||||||
|
SCALE_METRIC(strikethroughThickness);
|
||||||
|
SCALE_METRIC(glyphBoxLeft);
|
||||||
|
SCALE_METRIC(glyphBoxTop);
|
||||||
|
SCALE_METRIC(glyphBoxRight);
|
||||||
|
SCALE_METRIC(glyphBoxBottom);
|
||||||
|
SCALE_METRIC(subscriptPositionX);
|
||||||
|
SCALE_METRIC(subscriptPositionY);
|
||||||
|
SCALE_METRIC(subscriptSizeX);
|
||||||
|
SCALE_METRIC(subscriptSizeY);
|
||||||
|
SCALE_METRIC(superscriptPositionX);
|
||||||
|
SCALE_METRIC(superscriptPositionY);
|
||||||
|
SCALE_METRIC(superscriptSizeX);
|
||||||
|
SCALE_METRIC(superscriptSizeY);
|
||||||
|
|
||||||
|
metrics->hasTypographicMetrics = design->hasTypographicMetrics;
|
||||||
|
#undef SCALE_METRIC
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WINAPI dwritefontface1_GetCaretMetrics(IDWriteFontFace2 *iface, DWRITE_CARET_METRICS *metrics)
|
static void WINAPI dwritefontface1_GetCaretMetrics(IDWriteFontFace2 *iface, DWRITE_CARET_METRICS *metrics)
|
||||||
|
@ -2216,9 +2282,10 @@ HRESULT create_fontface(DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDW
|
||||||
fontface->ref = 1;
|
fontface->ref = 1;
|
||||||
fontface->type = facetype;
|
fontface->type = facetype;
|
||||||
fontface->file_count = files_number;
|
fontface->file_count = files_number;
|
||||||
fontface->cmap.data = NULL;
|
memset(&fontface->cmap, 0, sizeof(fontface->cmap));
|
||||||
fontface->cmap.context = NULL;
|
memset(&fontface->vdmx, 0, sizeof(fontface->vdmx));
|
||||||
fontface->cmap.size = 0;
|
fontface->cmap.exists = TRUE;
|
||||||
|
fontface->vdmx.exists = TRUE;
|
||||||
fontface->index = index;
|
fontface->index = index;
|
||||||
fontface->simulations = simulations;
|
fontface->simulations = simulations;
|
||||||
memset(fontface->glyphs, 0, sizeof(fontface->glyphs));
|
memset(fontface->glyphs, 0, sizeof(fontface->glyphs));
|
||||||
|
|
|
@ -238,6 +238,35 @@ typedef struct {
|
||||||
TT_NameRecord nameRecord[1];
|
TT_NameRecord nameRecord[1];
|
||||||
} TT_NAME_V0;
|
} TT_NAME_V0;
|
||||||
|
|
||||||
|
struct VDMX_Header
|
||||||
|
{
|
||||||
|
WORD version;
|
||||||
|
WORD numRecs;
|
||||||
|
WORD numRatios;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VDMX_Ratio
|
||||||
|
{
|
||||||
|
BYTE bCharSet;
|
||||||
|
BYTE xRatio;
|
||||||
|
BYTE yStartRatio;
|
||||||
|
BYTE yEndRatio;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VDMX_group
|
||||||
|
{
|
||||||
|
WORD recs;
|
||||||
|
BYTE startsz;
|
||||||
|
BYTE endsz;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VDMX_vTable
|
||||||
|
{
|
||||||
|
WORD yPelHeight;
|
||||||
|
SHORT yMax;
|
||||||
|
SHORT yMin;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CHAR FeatureTag[4];
|
CHAR FeatureTag[4];
|
||||||
WORD Feature;
|
WORD Feature;
|
||||||
|
@ -1288,3 +1317,63 @@ HRESULT opentype_get_typographic_features(IDWriteFontFace *fontface, UINT32 scri
|
||||||
|
|
||||||
return *count > max_tagcount ? E_NOT_SUFFICIENT_BUFFER : S_OK;
|
return *count > max_tagcount ? E_NOT_SUFFICIENT_BUFFER : S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct VDMX_group *find_vdmx_group(const struct VDMX_Header *hdr)
|
||||||
|
{
|
||||||
|
WORD num_ratios, i, group_offset = 0;
|
||||||
|
struct VDMX_Ratio *ratios = (struct VDMX_Ratio*)(hdr + 1);
|
||||||
|
BYTE dev_x_ratio = 1, dev_y_ratio = 1;
|
||||||
|
|
||||||
|
num_ratios = GET_BE_WORD(hdr->numRatios);
|
||||||
|
|
||||||
|
for (i = 0; i < num_ratios; i++) {
|
||||||
|
|
||||||
|
if (!ratios[i].bCharSet) continue;
|
||||||
|
|
||||||
|
if ((ratios[i].xRatio == 0 && ratios[i].yStartRatio == 0 &&
|
||||||
|
ratios[i].yEndRatio == 0) ||
|
||||||
|
(ratios[i].xRatio == dev_x_ratio && ratios[i].yStartRatio <= dev_y_ratio &&
|
||||||
|
ratios[i].yEndRatio >= dev_y_ratio))
|
||||||
|
{
|
||||||
|
group_offset = GET_BE_WORD(*((WORD *)(ratios + num_ratios) + i));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (group_offset)
|
||||||
|
return (const struct VDMX_group *)((BYTE *)hdr + group_offset);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL opentype_get_vdmx_size(const void *data, INT emsize, UINT16 *ascent, UINT16 *descent)
|
||||||
|
{
|
||||||
|
const struct VDMX_Header *hdr = (const struct VDMX_Header*)data;
|
||||||
|
const struct VDMX_group *group = find_vdmx_group(hdr);
|
||||||
|
const struct VDMX_vTable *tables;
|
||||||
|
WORD recs, i;
|
||||||
|
|
||||||
|
if (!data)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
group = find_vdmx_group(hdr);
|
||||||
|
if (!group)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
recs = GET_BE_WORD(group->recs);
|
||||||
|
if (emsize < group->startsz || emsize >= group->endsz) return FALSE;
|
||||||
|
|
||||||
|
tables = (const struct VDMX_vTable *)(group + 1);
|
||||||
|
for (i = 0; i < recs; i++) {
|
||||||
|
WORD ppem = GET_BE_WORD(tables[i].yPelHeight);
|
||||||
|
if (ppem > emsize) {
|
||||||
|
FIXME("interpolate %d\n", emsize);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ppem == emsize) {
|
||||||
|
*ascent = (SHORT)GET_BE_WORD(tables[i].yMax);
|
||||||
|
*descent = -(SHORT)GET_BE_WORD(tables[i].yMin);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
|
@ -3606,8 +3606,8 @@ static void test_GetGdiCompatibleMetrics_face(IDWriteFontFace *face)
|
||||||
{
|
{
|
||||||
IDWriteFontFace1 *fontface1 = NULL;
|
IDWriteFontFace1 *fontface1 = NULL;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
DWRITE_FONT_METRICS design_metrics;
|
DWRITE_FONT_METRICS design_metrics, comp_metrics;
|
||||||
DWRITE_FONT_METRICS1 design_metrics1;
|
DWRITE_FONT_METRICS1 design_metrics1, expected;
|
||||||
FLOAT emsize, scale;
|
FLOAT emsize, scale;
|
||||||
int ascent, descent;
|
int ascent, descent;
|
||||||
const struct VDMX_Header *vdmx;
|
const struct VDMX_Header *vdmx;
|
||||||
|
@ -3615,6 +3615,7 @@ static void test_GetGdiCompatibleMetrics_face(IDWriteFontFace *face)
|
||||||
void *vdmx_ctx;
|
void *vdmx_ctx;
|
||||||
BOOL exists;
|
BOOL exists;
|
||||||
const struct VDMX_group *vdmx_group = NULL;
|
const struct VDMX_group *vdmx_group = NULL;
|
||||||
|
DWRITE_MATRIX m;
|
||||||
|
|
||||||
hr = IDWriteFontFace_QueryInterface(face, &IID_IDWriteFontFace1, (void**)&fontface1);
|
hr = IDWriteFontFace_QueryInterface(face, &IID_IDWriteFontFace1, (void**)&fontface1);
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
|
@ -3634,16 +3635,59 @@ static void test_GetGdiCompatibleMetrics_face(IDWriteFontFace *face)
|
||||||
else
|
else
|
||||||
vdmx_group = find_vdmx_group(vdmx);
|
vdmx_group = find_vdmx_group(vdmx);
|
||||||
|
|
||||||
|
/* zero pixels per dip */
|
||||||
|
memset(&comp_metrics, 0xcc, sizeof(comp_metrics));
|
||||||
|
memset(&expected, 0, sizeof(expected));
|
||||||
|
hr = IDWriteFontFace_GetGdiCompatibleMetrics(face, 5.0, 0.0, NULL, &comp_metrics);
|
||||||
|
ok(hr == E_INVALIDARG, "got %08x\n", hr);
|
||||||
|
test_metrics_cmp(5.0, &comp_metrics, &expected);
|
||||||
|
|
||||||
|
memset(&comp_metrics, 0xcc, sizeof(comp_metrics));
|
||||||
|
hr = IDWriteFontFace_GetGdiCompatibleMetrics(face, 5.0, -1.0, NULL, &comp_metrics);
|
||||||
|
ok(hr == E_INVALIDARG, "got %08x\n", hr);
|
||||||
|
test_metrics_cmp(5.0, &comp_metrics, &expected);
|
||||||
|
|
||||||
|
memset(&m, 0, sizeof(m));
|
||||||
|
/* zero matrix m22 */
|
||||||
|
m.m22 = 1.0;
|
||||||
|
hr = IDWriteFontFace_GetGdiCompatibleMetrics(face, 5.0, 1.0, NULL, (DWRITE_FONT_METRICS*)&expected);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
hr = IDWriteFontFace_GetGdiCompatibleMetrics(face, 5.0, 1.0, &m, &comp_metrics);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
test_metrics_cmp(5.0, &comp_metrics, &expected);
|
||||||
|
|
||||||
|
m.m22 = -1.0;
|
||||||
|
hr = IDWriteFontFace_GetGdiCompatibleMetrics(face, 5.0, 1.0, &m, &comp_metrics);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
test_metrics_cmp(5.0, &comp_metrics, &expected);
|
||||||
|
|
||||||
|
/* pixels per dip == 2 */
|
||||||
|
hr = IDWriteFontFace_GetGdiCompatibleMetrics(face, 10.0, 1.0, NULL, (DWRITE_FONT_METRICS*)&expected);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
hr = IDWriteFontFace_GetGdiCompatibleMetrics(face, 5.0, 2.0, NULL, &comp_metrics);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
test_metrics_cmp(5.0, &comp_metrics, &expected);
|
||||||
|
|
||||||
|
/* pixels per dip == 2, m22 == 3.0 */
|
||||||
|
hr = IDWriteFontFace_GetGdiCompatibleMetrics(face, 30.0, 1.0, NULL, (DWRITE_FONT_METRICS*)&expected);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
|
||||||
|
m.m22 = 3.0;
|
||||||
|
hr = IDWriteFontFace_GetGdiCompatibleMetrics(face, 5.0, 2.0, &m, &comp_metrics);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
test_metrics_cmp(5.0, &comp_metrics, &expected);
|
||||||
|
m.m22 = -3.0;
|
||||||
|
hr = IDWriteFontFace_GetGdiCompatibleMetrics(face, 5.0, 2.0, &m, &comp_metrics);
|
||||||
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
|
test_metrics_cmp(5.0, &comp_metrics, &expected);
|
||||||
|
|
||||||
for (emsize = 5; emsize <= design_metrics.designUnitsPerEm; emsize++)
|
for (emsize = 5; emsize <= design_metrics.designUnitsPerEm; emsize++)
|
||||||
{
|
{
|
||||||
DWRITE_FONT_METRICS1 comp_metrics1, expected;
|
DWRITE_FONT_METRICS1 comp_metrics1, expected;
|
||||||
DWRITE_FONT_METRICS comp_metrics;
|
|
||||||
|
|
||||||
if (fontface1) {
|
if (fontface1) {
|
||||||
hr = IDWriteFontFace1_GetGdiCompatibleMetrics(fontface1, emsize, 1.0, NULL, &comp_metrics1);
|
hr = IDWriteFontFace1_GetGdiCompatibleMetrics(fontface1, emsize, 1.0, NULL, &comp_metrics1);
|
||||||
todo_wine
|
|
||||||
ok(hr == S_OK, "got %08x\n", hr);
|
ok(hr == S_OK, "got %08x\n", hr);
|
||||||
if (hr != S_OK) return;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
hr = IDWriteFontFace_GetGdiCompatibleMetrics(face, emsize, 1.0, NULL, &comp_metrics);
|
hr = IDWriteFontFace_GetGdiCompatibleMetrics(face, emsize, 1.0, NULL, &comp_metrics);
|
||||||
|
|
Loading…
Reference in New Issue