dwrite: Improve returned design glyph metrics.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
45361bb65e
commit
421c83cd7b
|
@ -164,12 +164,69 @@ struct fontface_desc
|
|||
struct dwrite_font_data *font_data; /* could be NULL when face is created directly with IDWriteFactory::CreateFontFace() */
|
||||
};
|
||||
|
||||
struct dwrite_fonttable
|
||||
{
|
||||
const BYTE *data;
|
||||
void *context;
|
||||
UINT32 size;
|
||||
BOOL exists;
|
||||
};
|
||||
|
||||
struct fontfacecached
|
||||
{
|
||||
struct list entry;
|
||||
IDWriteFontFace4 *fontface;
|
||||
};
|
||||
|
||||
#define GLYPH_BLOCK_SHIFT 8
|
||||
#define GLYPH_BLOCK_SIZE (1UL << GLYPH_BLOCK_SHIFT)
|
||||
#define GLYPH_BLOCK_MASK (GLYPH_BLOCK_SIZE - 1)
|
||||
#define GLYPH_MAX 65536
|
||||
|
||||
struct dwrite_fontface
|
||||
{
|
||||
IDWriteFontFace4 IDWriteFontFace4_iface;
|
||||
LONG ref;
|
||||
|
||||
IDWriteFontFileStream *stream;
|
||||
IDWriteFontFile **files;
|
||||
UINT32 file_count;
|
||||
UINT32 index;
|
||||
|
||||
IDWriteFactory5 *factory;
|
||||
struct fontfacecached *cached;
|
||||
|
||||
USHORT simulations;
|
||||
DWRITE_FONT_FACE_TYPE type;
|
||||
DWRITE_FONT_METRICS1 metrics;
|
||||
DWRITE_CARET_METRICS caret;
|
||||
struct
|
||||
{
|
||||
unsigned int ascent;
|
||||
unsigned int descent;
|
||||
} typo_metrics;
|
||||
INT charmap;
|
||||
UINT16 flags;
|
||||
|
||||
struct dwrite_fonttable cmap;
|
||||
struct dwrite_fonttable vdmx;
|
||||
struct dwrite_fonttable gasp;
|
||||
struct dwrite_fonttable cpal;
|
||||
struct dwrite_fonttable colr;
|
||||
DWRITE_GLYPH_METRICS *glyphs[GLYPH_MAX/GLYPH_BLOCK_SIZE];
|
||||
|
||||
DWRITE_FONT_STYLE style;
|
||||
DWRITE_FONT_STRETCH stretch;
|
||||
DWRITE_FONT_WEIGHT weight;
|
||||
DWRITE_PANOSE panose;
|
||||
FONTSIGNATURE fontsig;
|
||||
UINT32 glyph_image_formats;
|
||||
|
||||
struct scriptshaping_cache *shaping_cache;
|
||||
|
||||
LOGFONTW lf;
|
||||
};
|
||||
|
||||
extern HRESULT create_numbersubstitution(DWRITE_NUMBER_SUBSTITUTION_METHOD,const WCHAR *locale,BOOL,IDWriteNumberSubstitution**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT create_textformat(const WCHAR*,IDWriteFontCollection*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH,
|
||||
FLOAT,const WCHAR*,IDWriteTextFormat**) DECLSPEC_HIDDEN;
|
||||
|
@ -241,14 +298,6 @@ struct file_stream_desc {
|
|||
UINT32 face_index;
|
||||
};
|
||||
|
||||
struct dwrite_fonttable
|
||||
{
|
||||
const BYTE *data;
|
||||
void *context;
|
||||
UINT32 size;
|
||||
BOOL exists;
|
||||
};
|
||||
|
||||
extern const void* get_fontface_table(IDWriteFontFace4 *fontface, UINT32 tag,
|
||||
struct dwrite_fonttable *table) DECLSPEC_HIDDEN;
|
||||
|
||||
|
@ -258,6 +307,8 @@ extern HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *t
|
|||
DWRITE_UNICODE_RANGE *ranges, unsigned int *count) DECLSPEC_HIDDEN;
|
||||
extern void opentype_get_font_properties(struct file_stream_desc*,struct dwrite_font_props*) DECLSPEC_HIDDEN;
|
||||
extern void opentype_get_font_metrics(struct file_stream_desc*,DWRITE_FONT_METRICS1*,DWRITE_CARET_METRICS*) DECLSPEC_HIDDEN;
|
||||
extern void opentype_get_font_typo_metrics(struct file_stream_desc *stream_desc, unsigned int *ascent,
|
||||
unsigned int *descent) DECLSPEC_HIDDEN;
|
||||
extern HRESULT opentype_get_font_info_strings(const void*,DWRITE_INFORMATIONAL_STRING_ID,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT opentype_get_font_familyname(struct file_stream_desc*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
|
||||
extern HRESULT opentype_get_font_facename(struct file_stream_desc*,WCHAR*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
|
||||
|
@ -317,7 +368,9 @@ struct dwrite_glyphbitmap
|
|||
|
||||
extern BOOL init_freetype(void) DECLSPEC_HIDDEN;
|
||||
extern void release_freetype(void) DECLSPEC_HIDDEN;
|
||||
extern HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace4*,UINT16,UINT16,DWRITE_GLYPH_METRICS*) DECLSPEC_HIDDEN;
|
||||
|
||||
extern HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph,
|
||||
DWRITE_GLYPH_METRICS *metrics) DECLSPEC_HIDDEN;
|
||||
extern void freetype_notify_cacheremove(IDWriteFontFace4*) DECLSPEC_HIDDEN;
|
||||
extern BOOL freetype_is_monospaced(IDWriteFontFace4*) DECLSPEC_HIDDEN;
|
||||
extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, float emsize, UINT16 const *glyphs,
|
||||
|
|
|
@ -207,44 +207,6 @@ enum fontface_flags {
|
|||
FONTFACE_HAS_VERTICAL_VARIANTS = 1 << 3
|
||||
};
|
||||
|
||||
struct dwrite_fontface {
|
||||
IDWriteFontFace4 IDWriteFontFace4_iface;
|
||||
LONG ref;
|
||||
|
||||
IDWriteFontFileStream *stream;
|
||||
IDWriteFontFile **files;
|
||||
UINT32 file_count;
|
||||
UINT32 index;
|
||||
|
||||
IDWriteFactory5 *factory;
|
||||
struct fontfacecached *cached;
|
||||
|
||||
USHORT simulations;
|
||||
DWRITE_FONT_FACE_TYPE type;
|
||||
DWRITE_FONT_METRICS1 metrics;
|
||||
DWRITE_CARET_METRICS caret;
|
||||
INT charmap;
|
||||
UINT16 flags;
|
||||
|
||||
struct dwrite_fonttable cmap;
|
||||
struct dwrite_fonttable vdmx;
|
||||
struct dwrite_fonttable gasp;
|
||||
struct dwrite_fonttable cpal;
|
||||
struct dwrite_fonttable colr;
|
||||
DWRITE_GLYPH_METRICS *glyphs[GLYPH_MAX/GLYPH_BLOCK_SIZE];
|
||||
|
||||
DWRITE_FONT_STYLE style;
|
||||
DWRITE_FONT_STRETCH stretch;
|
||||
DWRITE_FONT_WEIGHT weight;
|
||||
DWRITE_PANOSE panose;
|
||||
FONTSIGNATURE fontsig;
|
||||
UINT32 glyph_image_formats;
|
||||
|
||||
struct scriptshaping_cache *shaping_cache;
|
||||
|
||||
LOGFONTW lf;
|
||||
};
|
||||
|
||||
struct dwrite_fontfile {
|
||||
IDWriteFontFile IDWriteFontFile_iface;
|
||||
LONG ref;
|
||||
|
@ -636,11 +598,11 @@ static UINT16 WINAPI dwritefontface_GetGlyphCount(IDWriteFontFace4 *iface)
|
|||
static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace4 *iface,
|
||||
UINT16 const *glyphs, UINT32 glyph_count, DWRITE_GLYPH_METRICS *ret, BOOL is_sideways)
|
||||
{
|
||||
struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
|
||||
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace4(iface);
|
||||
unsigned int i;
|
||||
HRESULT hr;
|
||||
UINT32 i;
|
||||
|
||||
TRACE("(%p)->(%p %u %p %d)\n", This, glyphs, glyph_count, ret, is_sideways);
|
||||
TRACE("%p, %p, %u, %p, %d.\n", iface, glyphs, glyph_count, ret, is_sideways);
|
||||
|
||||
if (!glyphs)
|
||||
return E_INVALIDARG;
|
||||
|
@ -651,10 +613,10 @@ static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace4 *ifa
|
|||
for (i = 0; i < glyph_count; i++) {
|
||||
DWRITE_GLYPH_METRICS metrics;
|
||||
|
||||
hr = get_cached_glyph_metrics(This, glyphs[i], &metrics);
|
||||
hr = get_cached_glyph_metrics(fontface, glyphs[i], &metrics);
|
||||
if (hr != S_OK) {
|
||||
freetype_get_design_glyph_metrics(iface, This->metrics.designUnitsPerEm, glyphs[i], &metrics);
|
||||
hr = set_cached_glyph_metrics(This, glyphs[i], &metrics);
|
||||
freetype_get_design_glyph_metrics(fontface, glyphs[i], &metrics);
|
||||
hr = set_cached_glyph_metrics(fontface, glyphs[i], &metrics);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
|
@ -4505,6 +4467,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
|
|||
stream_desc.face_type = desc->face_type;
|
||||
stream_desc.face_index = desc->index;
|
||||
opentype_get_font_metrics(&stream_desc, &fontface->metrics, &fontface->caret);
|
||||
opentype_get_font_typo_metrics(&stream_desc, &fontface->typo_metrics.ascent, &fontface->typo_metrics.descent);
|
||||
if (desc->simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE) {
|
||||
/* TODO: test what happens if caret is already slanted */
|
||||
if (fontface->caret.slopeRise == 1) {
|
||||
|
|
|
@ -263,14 +263,14 @@ void freetype_notify_cacheremove(IDWriteFontFace4 *fontface)
|
|||
LeaveCriticalSection(&freetype_cs);
|
||||
}
|
||||
|
||||
HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace4 *fontface, UINT16 unitsperEm, UINT16 glyph, DWRITE_GLYPH_METRICS *ret)
|
||||
HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *ret)
|
||||
{
|
||||
FTC_ScalerRec scaler;
|
||||
FT_Size size;
|
||||
|
||||
scaler.face_id = fontface;
|
||||
scaler.width = unitsperEm;
|
||||
scaler.height = unitsperEm;
|
||||
scaler.face_id = &fontface->IDWriteFontFace4_iface;
|
||||
scaler.width = fontface->metrics.designUnitsPerEm;
|
||||
scaler.height = fontface->metrics.designUnitsPerEm;
|
||||
scaler.pixel = 1;
|
||||
scaler.x_res = 0;
|
||||
scaler.y_res = 0;
|
||||
|
@ -278,22 +278,23 @@ HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace4 *fontface, UINT16 uni
|
|||
EnterCriticalSection(&freetype_cs);
|
||||
if (pFTC_Manager_LookupSize(cache_manager, &scaler, &size) == 0) {
|
||||
if (pFT_Load_Glyph(size->face, glyph, FT_LOAD_NO_SCALE) == 0) {
|
||||
USHORT simulations = IDWriteFontFace4_GetSimulations(fontface);
|
||||
FT_Glyph_Metrics *metrics = &size->face->glyph->metrics;
|
||||
|
||||
ret->leftSideBearing = metrics->horiBearingX;
|
||||
ret->advanceWidth = metrics->horiAdvance;
|
||||
ret->rightSideBearing = metrics->horiAdvance - metrics->horiBearingX - metrics->width;
|
||||
ret->topSideBearing = metrics->vertBearingY;
|
||||
|
||||
ret->advanceHeight = metrics->vertAdvance;
|
||||
ret->bottomSideBearing = metrics->vertAdvance - metrics->vertBearingY - metrics->height;
|
||||
ret->verticalOriginY = metrics->height + metrics->vertBearingY;
|
||||
ret->verticalOriginY = fontface->typo_metrics.ascent;
|
||||
ret->topSideBearing = fontface->typo_metrics.ascent - metrics->horiBearingY;
|
||||
ret->bottomSideBearing = metrics->vertAdvance - metrics->height - ret->topSideBearing;
|
||||
|
||||
/* Adjust in case of bold simulation, glyphs without contours are ignored. */
|
||||
if (simulations & DWRITE_FONT_SIMULATIONS_BOLD && size->face->glyph->format == FT_GLYPH_FORMAT_OUTLINE &&
|
||||
size->face->glyph->outline.n_contours != 0) {
|
||||
if (fontface->simulations & DWRITE_FONT_SIMULATIONS_BOLD &&
|
||||
size->face->glyph->format == FT_GLYPH_FORMAT_OUTLINE && size->face->glyph->outline.n_contours)
|
||||
{
|
||||
if (ret->advanceWidth)
|
||||
ret->advanceWidth += (unitsperEm + 49) / 50;
|
||||
ret->advanceWidth += (fontface->metrics.designUnitsPerEm + 49) / 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -929,7 +930,7 @@ void freetype_notify_cacheremove(IDWriteFontFace4 *fontface)
|
|||
{
|
||||
}
|
||||
|
||||
HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace4 *fontface, UINT16 unitsperEm, UINT16 glyph, DWRITE_GLYPH_METRICS *ret)
|
||||
HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *ret)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
|
|
@ -1553,6 +1553,27 @@ HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *cmap, un
|
|||
return *count > max_count ? E_NOT_SUFFICIENT_BUFFER : S_OK;
|
||||
}
|
||||
|
||||
void opentype_get_font_typo_metrics(struct file_stream_desc *stream_desc, unsigned int *ascent, unsigned int *descent)
|
||||
{
|
||||
const TT_OS2_V2 *data;
|
||||
unsigned int size;
|
||||
void *context;
|
||||
|
||||
opentype_get_font_table(stream_desc, MS_OS2_TAG, (const void **)&data, &context, &size, NULL);
|
||||
|
||||
*ascent = *descent = 0;
|
||||
|
||||
if (size >= FIELD_OFFSET(TT_OS2_V2, sTypoLineGap))
|
||||
{
|
||||
SHORT value = GET_BE_WORD(data->sTypoDescender);
|
||||
*ascent = GET_BE_WORD(data->sTypoAscender);
|
||||
*descent = value < 0 ? -value : 0;
|
||||
}
|
||||
|
||||
if (data)
|
||||
IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, context);
|
||||
}
|
||||
|
||||
void opentype_get_font_metrics(struct file_stream_desc *stream_desc, DWRITE_FONT_METRICS1 *metrics, DWRITE_CARET_METRICS *caret)
|
||||
{
|
||||
void *os2_context, *head_context, *post_context, *hhea_context;
|
||||
|
|
Loading…
Reference in New Issue