dwrite: Fix lineGap metric using 'hhea' table values.
This commit is contained in:
parent
188bfd6fd4
commit
82e66b4b47
|
@ -116,7 +116,7 @@ extern HRESULT opentype_get_font_table(IDWriteFontFileStream*,DWRITE_FONT_FACE_T
|
|||
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(const void*,const void*,const void*,DWRITE_FONT_METRICS1*) DECLSPEC_HIDDEN;
|
||||
extern void opentype_get_font_metrics(IDWriteFontFileStream*,DWRITE_FONT_FACE_TYPE,UINT32,DWRITE_FONT_METRICS1*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT opentype_get_font_strings_from_id(const void*,DWRITE_INFORMATIONAL_STRING_ID,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
|
||||
|
||||
/* BiDi helpers */
|
||||
|
|
|
@ -28,7 +28,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
|
|||
|
||||
#define MS_HEAD_TAG DWRITE_MAKE_OPENTYPE_TAG('h','e','a','d')
|
||||
#define MS_OS2_TAG DWRITE_MAKE_OPENTYPE_TAG('O','S','/','2')
|
||||
#define MS_POST_TAG DWRITE_MAKE_OPENTYPE_TAG('p','o','s','t')
|
||||
#define MS_CMAP_TAG DWRITE_MAKE_OPENTYPE_TAG('c','m','a','p')
|
||||
#define MS_NAME_TAG DWRITE_MAKE_OPENTYPE_TAG('n','a','m','e')
|
||||
|
||||
|
@ -584,29 +583,26 @@ static void get_font_properties_from_stream(IDWriteFontFileStream *stream, DWRIT
|
|||
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, *tt_post = NULL;
|
||||
void *os2_context, *head_context, *post_context;
|
||||
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);
|
||||
opentype_get_font_table(stream, face_type, face_index, MS_POST_TAG, &tt_post, &post_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(tt_os2, tt_head, tt_post, metrics);
|
||||
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);
|
||||
if (tt_post)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, post_context);
|
||||
}
|
||||
|
||||
HRESULT convert_fontface_to_logfont(IDWriteFontFace *face, LOGFONTW *logfont)
|
||||
|
@ -1458,8 +1454,8 @@ static HRESULT get_filestream_from_file(IDWriteFontFile *file, IDWriteFontFileSt
|
|||
|
||||
static HRESULT init_font_data(IDWriteFactory *factory, IDWriteFontFile *file, UINT32 face_index, DWRITE_FONT_FACE_TYPE face_type, struct dwrite_font_data *data)
|
||||
{
|
||||
void *os2_context, *head_context, *post_context;
|
||||
const void *tt_os2 = NULL, *tt_head = NULL, *tt_post = NULL;
|
||||
void *os2_context, *head_context;
|
||||
const void *tt_os2 = NULL, *tt_head = NULL;
|
||||
IDWriteFontFileStream *stream;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -1476,17 +1472,14 @@ static HRESULT init_font_data(IDWriteFactory *factory, IDWriteFontFile *file, UI
|
|||
|
||||
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_table(stream, face_type, face_index, MS_POST_TAG, &tt_post, &post_context, NULL, NULL);
|
||||
|
||||
opentype_get_font_properties(tt_os2, tt_head, &data->stretch, &data->weight, &data->style);
|
||||
opentype_get_font_metrics(tt_os2, tt_head, tt_post, &data->metrics);
|
||||
opentype_get_font_metrics(stream, face_type, face_index, &data->metrics);
|
||||
|
||||
if (tt_os2)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, os2_context);
|
||||
if (tt_head)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, head_context);
|
||||
if (tt_post)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, post_context);
|
||||
IDWriteFontFileStream_Release(stream);
|
||||
|
||||
return S_OK;
|
||||
|
|
|
@ -24,8 +24,12 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
|
||||
|
||||
#define MS_TTCF_TAG DWRITE_MAKE_OPENTYPE_TAG('t','t','c','f')
|
||||
#define MS_HEAD_TAG DWRITE_MAKE_OPENTYPE_TAG('h','e','a','d')
|
||||
#define MS_HHEA_TAG DWRITE_MAKE_OPENTYPE_TAG('h','h','e','a')
|
||||
#define MS_OTTO_TAG DWRITE_MAKE_OPENTYPE_TAG('O','T','T','O')
|
||||
#define MS_OS2_TAG DWRITE_MAKE_OPENTYPE_TAG('O','S','/','2')
|
||||
#define MS_POST_TAG DWRITE_MAKE_OPENTYPE_TAG('p','o','s','t')
|
||||
#define MS_TTCF_TAG DWRITE_MAKE_OPENTYPE_TAG('t','t','c','f')
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define GET_BE_WORD(x) (x)
|
||||
|
@ -183,6 +187,24 @@ typedef struct
|
|||
USHORT usBreakChar;
|
||||
USHORT usMaxContext;
|
||||
} TT_OS2_V2;
|
||||
|
||||
typedef struct {
|
||||
ULONG version;
|
||||
SHORT ascender;
|
||||
SHORT descender;
|
||||
SHORT linegap;
|
||||
USHORT advanceWidthMax;
|
||||
SHORT minLeftSideBearing;
|
||||
SHORT minRightSideBearing;
|
||||
SHORT xMaxExtent;
|
||||
SHORT caretSlopeRise;
|
||||
SHORT caretSlopeRun;
|
||||
SHORT caretOffset;
|
||||
SHORT reserved[4];
|
||||
SHORT metricDataFormat;
|
||||
USHORT numberOfHMetrics;
|
||||
} TT_HHEA;
|
||||
|
||||
#include "poppack.h"
|
||||
|
||||
enum OS2_FSSELECTION {
|
||||
|
@ -871,14 +893,22 @@ HRESULT opentype_cmap_get_unicode_ranges(void *data, UINT32 max_count, DWRITE_UN
|
|||
return *count > max_count ? E_NOT_SUFFICIENT_BUFFER : S_OK;
|
||||
}
|
||||
|
||||
void opentype_get_font_metrics(const void *os2, const void *head, const void *post, DWRITE_FONT_METRICS1 *metrics)
|
||||
void opentype_get_font_metrics(IDWriteFontFileStream *stream, DWRITE_FONT_FACE_TYPE face_type, UINT32 face_index,
|
||||
DWRITE_FONT_METRICS1 *metrics)
|
||||
{
|
||||
TT_OS2_V2 *tt_os2 = (TT_OS2_V2*)os2;
|
||||
TT_HEAD *tt_head = (TT_HEAD*)head;
|
||||
TT_POST *tt_post = (TT_POST*)post;
|
||||
void *os2_context, *head_context, *post_context, *hhea_context;
|
||||
const TT_OS2_V2 *tt_os2;
|
||||
const TT_HEAD *tt_head;
|
||||
const TT_POST *tt_post;
|
||||
const TT_HHEA *tt_hhea;
|
||||
|
||||
memset(metrics, 0, sizeof(*metrics));
|
||||
|
||||
opentype_get_font_table(stream, face_type, face_index, MS_OS2_TAG, (const void**)&tt_os2, &os2_context, NULL, NULL);
|
||||
opentype_get_font_table(stream, face_type, face_index, MS_HEAD_TAG, (const void**)&tt_head, &head_context, NULL, NULL);
|
||||
opentype_get_font_table(stream, face_type, face_index, MS_POST_TAG, (const void**)&tt_post, &post_context, NULL, NULL);
|
||||
opentype_get_font_table(stream, face_type, face_index, MS_HHEA_TAG, (const void**)&tt_hhea, &hhea_context, NULL, NULL);
|
||||
|
||||
if (tt_head) {
|
||||
metrics->designUnitsPerEm = GET_BE_WORD(tt_head->unitsPerEm);
|
||||
metrics->glyphBoxLeft = GET_BE_WORD(tt_head->xMin);
|
||||
|
@ -890,11 +920,19 @@ void opentype_get_font_metrics(const void *os2, const void *head, const void *po
|
|||
if (tt_os2) {
|
||||
USHORT version = GET_BE_WORD(tt_os2->version);
|
||||
|
||||
metrics->ascent = GET_BE_WORD(tt_os2->usWinAscent);
|
||||
metrics->descent = GET_BE_WORD(tt_os2->usWinDescent);
|
||||
/* FIXME: sTypoLineGap should only be used when USE_TYPO_METRICS is set,
|
||||
if not set this value is probably derived from other metrics */
|
||||
metrics->lineGap = GET_BE_WORD(tt_os2->sTypoLineGap);
|
||||
metrics->ascent = GET_BE_WORD(tt_os2->usWinAscent);
|
||||
metrics->descent = GET_BE_WORD(tt_os2->usWinDescent);
|
||||
|
||||
/* line gap is estimated using two sets of ascender/descender values and 'hhea' line gap */
|
||||
if (tt_hhea) {
|
||||
SHORT descender = (SHORT)GET_BE_WORD(tt_hhea->descender);
|
||||
INT32 linegap;
|
||||
|
||||
linegap = GET_BE_WORD(tt_hhea->ascender) + abs(descender) + GET_BE_WORD(tt_hhea->linegap) -
|
||||
metrics->ascent - metrics->descent;
|
||||
metrics->lineGap = linegap > 0 ? linegap : 0;
|
||||
}
|
||||
|
||||
metrics->strikethroughPosition = GET_BE_WORD(tt_os2->yStrikeoutPosition);
|
||||
metrics->strikethroughThickness = GET_BE_WORD(tt_os2->yStrikeoutSize);
|
||||
metrics->subscriptPositionX = GET_BE_WORD(tt_os2->ySubscriptXOffset);
|
||||
|
@ -935,6 +973,15 @@ void opentype_get_font_metrics(const void *os2, const void *head, const void *po
|
|||
metrics->xHeight = metrics->designUnitsPerEm / 2;
|
||||
if (metrics->capHeight == 0)
|
||||
metrics->capHeight = metrics->designUnitsPerEm * 7 / 10;
|
||||
|
||||
if (tt_os2)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, os2_context);
|
||||
if (tt_head)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, head_context);
|
||||
if (tt_post)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream, post_context);
|
||||
if (tt_hhea)
|
||||
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)
|
||||
|
|
|
@ -1053,7 +1053,6 @@ if (0) /* crashes on native */
|
|||
ok(metrics.designUnitsPerEm != 0, "designUnitsPerEm %u\n", metrics.designUnitsPerEm);
|
||||
ok(metrics.ascent != 0, "ascent %u\n", metrics.ascent);
|
||||
ok(metrics.descent != 0, "descent %u\n", metrics.descent);
|
||||
todo_wine
|
||||
ok(metrics.lineGap == 0, "lineGap %d\n", metrics.lineGap);
|
||||
ok(metrics.capHeight, "capHeight %u\n", metrics.capHeight);
|
||||
ok(metrics.xHeight != 0, "xHeight %u\n", metrics.xHeight);
|
||||
|
@ -1071,7 +1070,6 @@ todo_wine
|
|||
ok(metrics.designUnitsPerEm != 0, "designUnitsPerEm %u\n", metrics.designUnitsPerEm);
|
||||
ok(metrics.ascent != 0, "ascent %u\n", metrics.ascent);
|
||||
ok(metrics.descent != 0, "descent %u\n", metrics.descent);
|
||||
todo_wine
|
||||
ok(metrics.lineGap == 0, "lineGap %d\n", metrics.lineGap);
|
||||
ok(metrics.capHeight, "capHeight %u\n", metrics.capHeight);
|
||||
ok(metrics.xHeight != 0, "xHeight %u\n", metrics.xHeight);
|
||||
|
@ -1091,7 +1089,6 @@ todo_wine
|
|||
ok(metrics1.designUnitsPerEm != 0, "designUnitsPerEm %u\n", metrics1.designUnitsPerEm);
|
||||
ok(metrics1.ascent != 0, "ascent %u\n", metrics1.ascent);
|
||||
ok(metrics1.descent != 0, "descent %u\n", metrics1.descent);
|
||||
todo_wine
|
||||
ok(metrics1.lineGap == 0, "lineGap %d\n", metrics1.lineGap);
|
||||
ok(metrics1.capHeight, "capHeight %u\n", metrics1.capHeight);
|
||||
ok(metrics1.xHeight != 0, "xHeight %u\n", metrics1.xHeight);
|
||||
|
@ -1120,7 +1117,6 @@ todo_wine
|
|||
ok(metrics1.designUnitsPerEm != 0, "designUnitsPerEm %u\n", metrics1.designUnitsPerEm);
|
||||
ok(metrics1.ascent != 0, "ascent %u\n", metrics1.ascent);
|
||||
ok(metrics1.descent != 0, "descent %u\n", metrics1.descent);
|
||||
todo_wine
|
||||
ok(metrics1.lineGap == 0, "lineGap %d\n", metrics1.lineGap);
|
||||
ok(metrics1.capHeight, "capHeight %u\n", metrics1.capHeight);
|
||||
ok(metrics1.xHeight != 0, "xHeight %u\n", metrics1.xHeight);
|
||||
|
|
Loading…
Reference in New Issue