Use metrics returned by GetGlyphOutline in GGO_METRICS mode

GetGlyphOutline Windows API returns wrong values when used with an
OpenType PS font and in GGO_NATIVE mode. It causes problem when
exporting to PDF. The fix changes the GetGlyphOutline call to use
GGO_METRICS instead.

Task-number: QTBUG-12799
Change-Id: I47d6d16b6e7819b51bc444420ada4a47d5f24f4e
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
This commit is contained in:
lasconic 2014-09-18 09:44:03 +02:00 committed by Nicolas Froment
parent a614bc6e39
commit 4aba2d07d2

View File

@ -800,13 +800,34 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
mat.eM11.fract = mat.eM22.fract = 0; mat.eM11.fract = mat.eM22.fract = 0;
mat.eM21.value = mat.eM12.value = 0; mat.eM21.value = mat.eM12.value = 0;
mat.eM21.fract = mat.eM12.fract = 0; mat.eM21.fract = mat.eM12.fract = 0;
GLYPHMETRICS gMetric;
memset(&gMetric, 0, sizeof(GLYPHMETRICS));
#ifndef Q_OS_WINCE
if (metric) {
// If metrics requested, retrieve first using GGO_METRICS, because the returned
// values are incorrect for OpenType PS fonts if obtained at the same time as the
// glyph paths themselves (ie. with GGO_NATIVE as the format).
uint format = GGO_METRICS;
if (ttf)
format |= GGO_GLYPH_INDEX;
int res = GetGlyphOutline(hdc, glyph, format, &gMetric, 0, 0, &mat);
if (res == GDI_ERROR) {
return false;
}
// #### obey scale
*metric = glyph_metrics_t(gMetric.gmptGlyphOrigin.x, -gMetric.gmptGlyphOrigin.y,
(int)gMetric.gmBlackBoxX, (int)gMetric.gmBlackBoxY,
gMetric.gmCellIncX, gMetric.gmCellIncY);
}
#endif
uint glyphFormat = GGO_NATIVE; uint glyphFormat = GGO_NATIVE;
if (ttf) if (ttf)
glyphFormat |= GGO_GLYPH_INDEX; glyphFormat |= GGO_GLYPH_INDEX;
GLYPHMETRICS gMetric;
memset(&gMetric, 0, sizeof(GLYPHMETRICS));
int bufferSize = GDI_ERROR; int bufferSize = GDI_ERROR;
bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat);
if ((DWORD)bufferSize == GDI_ERROR) { if ((DWORD)bufferSize == GDI_ERROR) {
@ -821,12 +842,14 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc,
return false; return false;
} }
if(metric) { #ifdef Q_OS_WINCE
if (metric) {
// #### obey scale // #### obey scale
*metric = glyph_metrics_t(gMetric.gmptGlyphOrigin.x, -gMetric.gmptGlyphOrigin.y, *metric = glyph_metrics_t(gMetric.gmptGlyphOrigin.x, -gMetric.gmptGlyphOrigin.y,
(int)gMetric.gmBlackBoxX, (int)gMetric.gmBlackBoxY, (int)gMetric.gmBlackBoxX, (int)gMetric.gmBlackBoxY,
gMetric.gmCellIncX, gMetric.gmCellIncY); gMetric.gmCellIncX, gMetric.gmCellIncY);
} }
#endif
int offset = 0; int offset = 0;
int headerOffset = 0; int headerOffset = 0;