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
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;
......
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