dwrite: Implement GetCaretMetrics().
This commit is contained in:
parent
fbeb829584
commit
8f9bca9103
|
@ -127,8 +127,9 @@ extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,UINT32*,DWRITE_FONT_
|
|||
extern HRESULT opentype_get_font_table(IDWriteFontFileStream*,DWRITE_FONT_FACE_TYPE,UINT32,UINT32,const void**,void**,UINT32*,BOOL*) DECLSPEC_HIDDEN;
|
||||
extern void opentype_cmap_get_glyphindex(void*,UINT32,UINT16*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT opentype_cmap_get_unicode_ranges(void*,UINT32,DWRITE_UNICODE_RANGE*,UINT32*) DECLSPEC_HIDDEN;
|
||||
extern void opentype_get_font_properties(const void*,const void*,DWRITE_FONT_STRETCH*,DWRITE_FONT_WEIGHT*,DWRITE_FONT_STYLE*) DECLSPEC_HIDDEN;
|
||||
extern void opentype_get_font_metrics(IDWriteFontFileStream*,DWRITE_FONT_FACE_TYPE,UINT32,DWRITE_FONT_METRICS1*) DECLSPEC_HIDDEN;
|
||||
extern void opentype_get_font_properties(IDWriteFontFileStream*,DWRITE_FONT_FACE_TYPE,UINT32,DWRITE_FONT_STRETCH*,
|
||||
DWRITE_FONT_WEIGHT*,DWRITE_FONT_STYLE*) 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_typographic_features(IDWriteFontFace*,UINT32,UINT32,UINT32,UINT32*,DWRITE_FONT_FEATURE_TAG*) DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ struct dwrite_fontface {
|
|||
USHORT simulations;
|
||||
DWRITE_FONT_FACE_TYPE type;
|
||||
DWRITE_FONT_METRICS1 metrics;
|
||||
DWRITE_CARET_METRICS caret;
|
||||
|
||||
struct dwrite_fonttable cmap;
|
||||
DWRITE_GLYPH_METRICS *glyphs[GLYPH_MAX/GLYPH_BLOCK_SIZE];
|
||||
|
@ -597,7 +598,8 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace2 *
|
|||
static void WINAPI dwritefontface1_GetCaretMetrics(IDWriteFontFace2 *iface, DWRITE_CARET_METRICS *metrics)
|
||||
{
|
||||
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
|
||||
FIXME("(%p)->(%p): stub\n", This, metrics);
|
||||
TRACE("(%p)->(%p)\n", This, metrics);
|
||||
*metrics = This->caret;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dwritefontface1_GetUnicodeRanges(IDWriteFontFace2 *iface, UINT32 max_count,
|
||||
|
@ -771,38 +773,11 @@ static const IDWriteFontFace2Vtbl dwritefontfacevtbl = {
|
|||
dwritefontface2_GetRecommendedRenderingMode
|
||||
};
|
||||
|
||||
static void get_font_properties_from_stream(IDWriteFontFileStream *stream, DWRITE_FONT_FACE_TYPE face_type,
|
||||
UINT32 face_index, DWRITE_FONT_METRICS1 *metrics, DWRITE_FONT_STRETCH *stretch, DWRITE_FONT_WEIGHT *weight,
|
||||
DWRITE_FONT_STYLE *style)
|
||||
{
|
||||
const void *tt_os2 = NULL, *tt_head = NULL;
|
||||
void *os2_context, *head_context;
|
||||
DWRITE_FONT_STRETCH fontstretch;
|
||||
DWRITE_FONT_WEIGHT fontweight;
|
||||
DWRITE_FONT_STYLE fontstyle;
|
||||
|
||||
opentype_get_font_table(stream, face_type, face_index, MS_OS2_TAG, &tt_os2, &os2_context, NULL, NULL);
|
||||
opentype_get_font_table(stream, face_type, face_index, MS_HEAD_TAG, &tt_head, &head_context, NULL, NULL);
|
||||
|
||||
if (!stretch) stretch = &fontstretch;
|
||||
if (!weight) weight = &fontweight;
|
||||
if (!style) style = &fontstyle;
|
||||
|
||||
opentype_get_font_properties(tt_os2, tt_head, stretch, weight, style);
|
||||
opentype_get_font_metrics(stream, face_type, face_index, metrics);
|
||||
|
||||
if (tt_os2)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, os2_context);
|
||||
if (tt_head)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, head_context);
|
||||
}
|
||||
|
||||
HRESULT convert_fontface_to_logfont(IDWriteFontFace *face, LOGFONTW *logfont)
|
||||
{
|
||||
DWRITE_FONT_SIMULATIONS simulations;
|
||||
DWRITE_FONT_FACE_TYPE face_type;
|
||||
IDWriteFontFileStream *stream;
|
||||
DWRITE_FONT_METRICS1 metrics;
|
||||
DWRITE_FONT_STRETCH stretch;
|
||||
DWRITE_FONT_STYLE style;
|
||||
DWRITE_FONT_WEIGHT weight;
|
||||
|
@ -825,7 +800,7 @@ HRESULT convert_fontface_to_logfont(IDWriteFontFace *face, LOGFONTW *logfont)
|
|||
|
||||
index = IDWriteFontFace_GetIndex(face);
|
||||
face_type = IDWriteFontFace_GetType(face);
|
||||
get_font_properties_from_stream(stream, face_type, index, &metrics, &stretch, &weight, &style);
|
||||
opentype_get_font_properties(stream, face_type, index, &stretch, &weight, &style);
|
||||
IDWriteFontFileStream_Release(stream);
|
||||
|
||||
simulations = IDWriteFontFace_GetSimulations(face);
|
||||
|
@ -1670,8 +1645,8 @@ static HRESULT init_font_data(IDWriteFactory2 *factory, IDWriteFontFile *file, U
|
|||
opentype_get_font_table(stream, face_type, face_index, MS_OS2_TAG, &tt_os2, &os2_context, NULL, NULL);
|
||||
opentype_get_font_table(stream, face_type, face_index, MS_HEAD_TAG, &tt_head, &head_context, NULL, NULL);
|
||||
|
||||
opentype_get_font_properties(tt_os2, tt_head, &data->stretch, &data->weight, &data->style);
|
||||
opentype_get_font_metrics(stream, face_type, face_index, &data->metrics);
|
||||
opentype_get_font_properties(stream, face_type, face_index, &data->stretch, &data->weight, &data->style);
|
||||
opentype_get_font_metrics(stream, face_type, face_index, &data->metrics, NULL);
|
||||
|
||||
if (tt_os2)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, os2_context);
|
||||
|
@ -2216,7 +2191,14 @@ HRESULT create_fontface(DWRITE_FONT_FACE_TYPE facetype, UINT32 files_number, IDW
|
|||
IDWriteFontFile_AddRef(font_files[i]);
|
||||
}
|
||||
|
||||
get_font_properties_from_stream(fontface->streams[0], facetype, index, &fontface->metrics, NULL, NULL, NULL);
|
||||
opentype_get_font_metrics(fontface->streams[0], facetype, index, &fontface->metrics, &fontface->caret);
|
||||
if (simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE) {
|
||||
/* TODO: test what happens if caret is already slanted */
|
||||
if (fontface->caret.slopeRise == 1) {
|
||||
fontface->caret.slopeRise = fontface->metrics.designUnitsPerEm;
|
||||
fontface->caret.slopeRun = fontface->caret.slopeRise / 3;
|
||||
}
|
||||
}
|
||||
|
||||
*ret = &fontface->IDWriteFontFace2_iface;
|
||||
return S_OK;
|
||||
|
|
|
@ -950,7 +950,7 @@ HRESULT opentype_cmap_get_unicode_ranges(void *data, UINT32 max_count, DWRITE_UN
|
|||
}
|
||||
|
||||
void opentype_get_font_metrics(IDWriteFontFileStream *stream, DWRITE_FONT_FACE_TYPE face_type, UINT32 face_index,
|
||||
DWRITE_FONT_METRICS1 *metrics)
|
||||
DWRITE_FONT_METRICS1 *metrics, DWRITE_CARET_METRICS *caret)
|
||||
{
|
||||
void *os2_context, *head_context, *post_context, *hhea_context;
|
||||
const TT_OS2_V2 *tt_os2;
|
||||
|
@ -973,6 +973,19 @@ void opentype_get_font_metrics(IDWriteFontFileStream *stream, DWRITE_FONT_FACE_T
|
|||
metrics->glyphBoxBottom = GET_BE_WORD(tt_head->yMin);
|
||||
}
|
||||
|
||||
if (caret) {
|
||||
if (tt_hhea) {
|
||||
caret->slopeRise = GET_BE_WORD(tt_hhea->caretSlopeRise);
|
||||
caret->slopeRun = GET_BE_WORD(tt_hhea->caretSlopeRun);
|
||||
caret->offset = GET_BE_WORD(tt_hhea->caretOffset);
|
||||
}
|
||||
else {
|
||||
caret->slopeRise = 0;
|
||||
caret->slopeRun = 0;
|
||||
caret->offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (tt_os2) {
|
||||
USHORT version = GET_BE_WORD(tt_os2->version);
|
||||
|
||||
|
@ -1040,10 +1053,15 @@ void opentype_get_font_metrics(IDWriteFontFileStream *stream, DWRITE_FONT_FACE_T
|
|||
IDWriteFontFileStream_ReleaseFileFragment(stream, hhea_context);
|
||||
}
|
||||
|
||||
void opentype_get_font_properties(const void *os2, const void *head, DWRITE_FONT_STRETCH *stretch, DWRITE_FONT_WEIGHT *weight, DWRITE_FONT_STYLE *style)
|
||||
void opentype_get_font_properties(IDWriteFontFileStream *stream, DWRITE_FONT_FACE_TYPE type, UINT32 index,
|
||||
DWRITE_FONT_STRETCH *stretch, DWRITE_FONT_WEIGHT *weight, DWRITE_FONT_STYLE *style)
|
||||
{
|
||||
TT_OS2_V2 *tt_os2 = (TT_OS2_V2*)os2;
|
||||
TT_HEAD *tt_head = (TT_HEAD*)head;
|
||||
void *os2_context, *head_context;
|
||||
const TT_OS2_V2 *tt_os2;
|
||||
const TT_HEAD *tt_head;
|
||||
|
||||
opentype_get_font_table(stream, type, index, MS_OS2_TAG, (const void**)&tt_os2, &os2_context, NULL, NULL);
|
||||
opentype_get_font_table(stream, type, index, MS_HEAD_TAG, (const void**)&tt_head, &head_context, NULL, NULL);
|
||||
|
||||
/* default stretch, weight and style to normal */
|
||||
*stretch = DWRITE_FONT_STRETCH_NORMAL;
|
||||
|
@ -1064,6 +1082,11 @@ void opentype_get_font_properties(const void *os2, const void *head, DWRITE_FONT
|
|||
if (macStyle & 0x0002)
|
||||
*style = DWRITE_FONT_STYLE_ITALIC;
|
||||
}
|
||||
|
||||
if (tt_os2)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, os2_context);
|
||||
if (tt_head)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, head_context);
|
||||
}
|
||||
|
||||
static UINT get_name_record_codepage(enum OPENTYPE_PLATFORM_ID platform, USHORT encoding)
|
||||
|
|
|
@ -2074,19 +2074,15 @@ static void test_GetFontFromFontFace(void)
|
|||
IDWriteFactory_Release(factory);
|
||||
}
|
||||
|
||||
static void test_GetFirstMatchingFont(void)
|
||||
static IDWriteFont *get_tahoma_instance(IDWriteFactory *factory, DWRITE_FONT_STYLE style)
|
||||
{
|
||||
DWRITE_FONT_SIMULATIONS simulations;
|
||||
IDWriteFontCollection *collection;
|
||||
IDWriteFont *font, *font2;
|
||||
IDWriteFontFamily *family;
|
||||
IDWriteFactory *factory;
|
||||
IDWriteFont *font;
|
||||
UINT32 index;
|
||||
BOOL exists;
|
||||
HRESULT hr;
|
||||
|
||||
factory = create_factory();
|
||||
|
||||
hr = IDWriteFactory_GetSystemFontCollection(factory, &collection, FALSE);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
|
||||
|
@ -2100,26 +2096,31 @@ static void test_GetFirstMatchingFont(void)
|
|||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
|
||||
hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &font);
|
||||
DWRITE_FONT_STRETCH_NORMAL, style, &font);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
|
||||
hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL, &font2);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
return font;
|
||||
}
|
||||
|
||||
static void test_GetFirstMatchingFont(void)
|
||||
{
|
||||
DWRITE_FONT_SIMULATIONS simulations;
|
||||
IDWriteFont *font, *font2;
|
||||
IDWriteFactory *factory;
|
||||
|
||||
factory = create_factory();
|
||||
|
||||
font = get_tahoma_instance(factory, DWRITE_FONT_STYLE_NORMAL);
|
||||
font2 = get_tahoma_instance(factory, DWRITE_FONT_STYLE_NORMAL);
|
||||
ok(font != font2, "got %p, %p\n", font, font2);
|
||||
IDWriteFont_Release(font);
|
||||
IDWriteFont_Release(font2);
|
||||
|
||||
hr = IDWriteFontFamily_GetFirstMatchingFont(family, DWRITE_FONT_WEIGHT_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_ITALIC, &font);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
|
||||
font = get_tahoma_instance(factory, DWRITE_FONT_STYLE_ITALIC);
|
||||
simulations = IDWriteFont_GetSimulations(font);
|
||||
ok(simulations == DWRITE_FONT_SIMULATIONS_OBLIQUE, "%d\n", simulations);
|
||||
|
||||
IDWriteFont_Release(font);
|
||||
IDWriteFont_Release(font2);
|
||||
IDWriteFontFamily_Release(family);
|
||||
IDWriteFontCollection_Release(collection);
|
||||
|
||||
IDWriteFactory_Release(factory);
|
||||
}
|
||||
|
||||
|
@ -2955,6 +2956,81 @@ static void test_GetEudcFontCollection(void)
|
|||
IDWriteFactory1_Release(factory1);
|
||||
}
|
||||
|
||||
static void test_GetCaretMetrics(void)
|
||||
{
|
||||
DWRITE_FONT_METRICS1 metrics;
|
||||
IDWriteFontFace1 *fontface1;
|
||||
DWRITE_CARET_METRICS caret;
|
||||
IDWriteFontFace *fontface;
|
||||
IDWriteFactory *factory;
|
||||
IDWriteFontFile *file;
|
||||
IDWriteFont *font;
|
||||
HRESULT hr;
|
||||
|
||||
create_testfontfile(test_fontfile);
|
||||
factory = create_factory();
|
||||
|
||||
hr = IDWriteFactory_CreateFontFileReference(factory, test_fontfile, NULL, &file);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
|
||||
hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
IDWriteFontFile_Release(file);
|
||||
|
||||
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace1, (void**)&fontface1);
|
||||
IDWriteFontFace_Release(fontface);
|
||||
if (hr != S_OK) {
|
||||
win_skip("GetCaretMetrics() is not supported.\n");
|
||||
IDWriteFactory_Release(factory);
|
||||
DeleteFileW(test_fontfile);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&caret, 0xcc, sizeof(caret));
|
||||
IDWriteFontFace1_GetCaretMetrics(fontface1, &caret);
|
||||
ok(caret.slopeRise == 1, "got %d\n", caret.slopeRise);
|
||||
ok(caret.slopeRun == 0, "got %d\n", caret.slopeRun);
|
||||
ok(caret.offset == 0, "got %d\n", caret.offset);
|
||||
IDWriteFontFace1_Release(fontface1);
|
||||
|
||||
/* now with Tahoma Normal */
|
||||
font = get_tahoma_instance(factory, DWRITE_FONT_STYLE_NORMAL);
|
||||
hr = IDWriteFont_CreateFontFace(font, &fontface);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
IDWriteFont_Release(font);
|
||||
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace1, (void**)&fontface1);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
IDWriteFontFace_Release(fontface);
|
||||
|
||||
memset(&caret, 0xcc, sizeof(caret));
|
||||
IDWriteFontFace1_GetCaretMetrics(fontface1, &caret);
|
||||
ok(caret.slopeRise == 1, "got %d\n", caret.slopeRise);
|
||||
ok(caret.slopeRun == 0, "got %d\n", caret.slopeRun);
|
||||
ok(caret.offset == 0, "got %d\n", caret.offset);
|
||||
IDWriteFontFace1_Release(fontface1);
|
||||
|
||||
/* simulated italic */
|
||||
font = get_tahoma_instance(factory, DWRITE_FONT_STYLE_ITALIC);
|
||||
hr = IDWriteFont_CreateFontFace(font, &fontface);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
IDWriteFont_Release(font);
|
||||
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace1, (void**)&fontface1);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
IDWriteFontFace_Release(fontface);
|
||||
|
||||
IDWriteFontFace1_GetMetrics(fontface1, &metrics);
|
||||
|
||||
memset(&caret, 0xcc, sizeof(caret));
|
||||
IDWriteFontFace1_GetCaretMetrics(fontface1, &caret);
|
||||
ok(caret.slopeRise == metrics.designUnitsPerEm, "got %d\n", caret.slopeRise);
|
||||
ok(caret.slopeRun > 0, "got %d\n", caret.slopeRun);
|
||||
ok(caret.offset == 0, "got %d\n", caret.offset);
|
||||
IDWriteFontFace1_Release(fontface1);
|
||||
|
||||
IDWriteFactory_Release(factory);
|
||||
DeleteFileW(test_fontfile);
|
||||
}
|
||||
|
||||
START_TEST(font)
|
||||
{
|
||||
IDWriteFactory *factory;
|
||||
|
@ -2993,6 +3069,7 @@ START_TEST(font)
|
|||
test_IsMonospacedFont();
|
||||
test_GetGlyphRunOutline();
|
||||
test_GetEudcFontCollection();
|
||||
test_GetCaretMetrics();
|
||||
|
||||
IDWriteFactory_Release(factory);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue