Commit 421c83cd authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

dwrite: Improve returned design glyph metrics.

parent 45361bb6
...@@ -164,12 +164,69 @@ struct fontface_desc ...@@ -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_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 fontfacecached
{ {
struct list entry; struct list entry;
IDWriteFontFace4 *fontface; 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_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, extern HRESULT create_textformat(const WCHAR*,IDWriteFontCollection*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH,
FLOAT,const WCHAR*,IDWriteTextFormat**) DECLSPEC_HIDDEN; FLOAT,const WCHAR*,IDWriteTextFormat**) DECLSPEC_HIDDEN;
...@@ -241,14 +298,6 @@ struct file_stream_desc { ...@@ -241,14 +298,6 @@ struct file_stream_desc {
UINT32 face_index; 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, extern const void* get_fontface_table(IDWriteFontFace4 *fontface, UINT32 tag,
struct dwrite_fonttable *table) DECLSPEC_HIDDEN; struct dwrite_fonttable *table) DECLSPEC_HIDDEN;
...@@ -258,6 +307,8 @@ extern HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *t ...@@ -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; 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_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_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_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_familyname(struct file_stream_desc*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
extern HRESULT opentype_get_font_facename(struct file_stream_desc*,WCHAR*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN; extern HRESULT opentype_get_font_facename(struct file_stream_desc*,WCHAR*,IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
...@@ -317,7 +368,9 @@ struct dwrite_glyphbitmap ...@@ -317,7 +368,9 @@ struct dwrite_glyphbitmap
extern BOOL init_freetype(void) DECLSPEC_HIDDEN; extern BOOL init_freetype(void) DECLSPEC_HIDDEN;
extern void release_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 void freetype_notify_cacheremove(IDWriteFontFace4*) DECLSPEC_HIDDEN;
extern BOOL freetype_is_monospaced(IDWriteFontFace4*) DECLSPEC_HIDDEN; extern BOOL freetype_is_monospaced(IDWriteFontFace4*) DECLSPEC_HIDDEN;
extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, float emsize, UINT16 const *glyphs, extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, float emsize, UINT16 const *glyphs,
......
...@@ -207,44 +207,6 @@ enum fontface_flags { ...@@ -207,44 +207,6 @@ enum fontface_flags {
FONTFACE_HAS_VERTICAL_VARIANTS = 1 << 3 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 { struct dwrite_fontfile {
IDWriteFontFile IDWriteFontFile_iface; IDWriteFontFile IDWriteFontFile_iface;
LONG ref; LONG ref;
...@@ -636,11 +598,11 @@ static UINT16 WINAPI dwritefontface_GetGlyphCount(IDWriteFontFace4 *iface) ...@@ -636,11 +598,11 @@ static UINT16 WINAPI dwritefontface_GetGlyphCount(IDWriteFontFace4 *iface)
static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace4 *iface, static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace4 *iface,
UINT16 const *glyphs, UINT32 glyph_count, DWRITE_GLYPH_METRICS *ret, BOOL is_sideways) 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; 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) if (!glyphs)
return E_INVALIDARG; return E_INVALIDARG;
...@@ -651,10 +613,10 @@ static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace4 *ifa ...@@ -651,10 +613,10 @@ static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace4 *ifa
for (i = 0; i < glyph_count; i++) { for (i = 0; i < glyph_count; i++) {
DWRITE_GLYPH_METRICS metrics; 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) { if (hr != S_OK) {
freetype_get_design_glyph_metrics(iface, This->metrics.designUnitsPerEm, glyphs[i], &metrics); freetype_get_design_glyph_metrics(fontface, glyphs[i], &metrics);
hr = set_cached_glyph_metrics(This, glyphs[i], &metrics); hr = set_cached_glyph_metrics(fontface, glyphs[i], &metrics);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
} }
...@@ -4505,6 +4467,7 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li ...@@ -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_type = desc->face_type;
stream_desc.face_index = desc->index; stream_desc.face_index = desc->index;
opentype_get_font_metrics(&stream_desc, &fontface->metrics, &fontface->caret); 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) { if (desc->simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE) {
/* TODO: test what happens if caret is already slanted */ /* TODO: test what happens if caret is already slanted */
if (fontface->caret.slopeRise == 1) { if (fontface->caret.slopeRise == 1) {
......
...@@ -263,14 +263,14 @@ void freetype_notify_cacheremove(IDWriteFontFace4 *fontface) ...@@ -263,14 +263,14 @@ void freetype_notify_cacheremove(IDWriteFontFace4 *fontface)
LeaveCriticalSection(&freetype_cs); 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; FTC_ScalerRec scaler;
FT_Size size; FT_Size size;
scaler.face_id = fontface; scaler.face_id = &fontface->IDWriteFontFace4_iface;
scaler.width = unitsperEm; scaler.width = fontface->metrics.designUnitsPerEm;
scaler.height = unitsperEm; scaler.height = fontface->metrics.designUnitsPerEm;
scaler.pixel = 1; scaler.pixel = 1;
scaler.x_res = 0; scaler.x_res = 0;
scaler.y_res = 0; scaler.y_res = 0;
...@@ -278,22 +278,23 @@ HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace4 *fontface, UINT16 uni ...@@ -278,22 +278,23 @@ HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace4 *fontface, UINT16 uni
EnterCriticalSection(&freetype_cs); EnterCriticalSection(&freetype_cs);
if (pFTC_Manager_LookupSize(cache_manager, &scaler, &size) == 0) { if (pFTC_Manager_LookupSize(cache_manager, &scaler, &size) == 0) {
if (pFT_Load_Glyph(size->face, glyph, FT_LOAD_NO_SCALE) == 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; FT_Glyph_Metrics *metrics = &size->face->glyph->metrics;
ret->leftSideBearing = metrics->horiBearingX; ret->leftSideBearing = metrics->horiBearingX;
ret->advanceWidth = metrics->horiAdvance; ret->advanceWidth = metrics->horiAdvance;
ret->rightSideBearing = metrics->horiAdvance - metrics->horiBearingX - metrics->width; ret->rightSideBearing = metrics->horiAdvance - metrics->horiBearingX - metrics->width;
ret->topSideBearing = metrics->vertBearingY;
ret->advanceHeight = metrics->vertAdvance; ret->advanceHeight = metrics->vertAdvance;
ret->bottomSideBearing = metrics->vertAdvance - metrics->vertBearingY - metrics->height; ret->verticalOriginY = fontface->typo_metrics.ascent;
ret->verticalOriginY = metrics->height + metrics->vertBearingY; 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. */ /* 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 && if (fontface->simulations & DWRITE_FONT_SIMULATIONS_BOLD &&
size->face->glyph->outline.n_contours != 0) { size->face->glyph->format == FT_GLYPH_FORMAT_OUTLINE && size->face->glyph->outline.n_contours)
{
if (ret->advanceWidth) 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) ...@@ -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; return E_NOTIMPL;
} }
......
...@@ -1553,6 +1553,27 @@ HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *cmap, un ...@@ -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; 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 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; void *os2_context, *head_context, *post_context, *hhea_context;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment