Improvements for DirectWrite font engine

- don't check if m_directWriteFontFace is not null, it MUST be initialized
  just in the constructor;
- fix support for surrogate pairs in stringToCMap();
- reorder some affected code for better readability.

Change-Id: Ibdcf7b50f06910e95cefe074f33932b8fbcdcfe1
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
bb10
Konstantin Ritt 2013-04-10 02:51:27 +03:00 committed by The Qt Project
parent 3f58fc00c9
commit affdd9d00c
2 changed files with 67 additions and 82 deletions

View File

@ -215,7 +215,9 @@ QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *di
if (QWindowsContext::verboseFonts)
qDebug("%s %g", __FUNCTION__, pixelSize);
d->directWriteFactory->AddRef();
Q_ASSERT(m_directWriteFontFace);
m_fontEngineData->directWriteFactory->AddRef();
m_directWriteFontFace->AddRef();
fontDef.pixelSize = pixelSize;
@ -236,19 +238,17 @@ QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite()
void QWindowsFontEngineDirectWrite::collectMetrics()
{
if (m_directWriteFontFace != 0) {
DWRITE_FONT_METRICS metrics;
DWRITE_FONT_METRICS metrics;
m_directWriteFontFace->GetMetrics(&metrics);
m_unitsPerEm = metrics.designUnitsPerEm;
m_directWriteFontFace->GetMetrics(&metrics);
m_unitsPerEm = metrics.designUnitsPerEm;
m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
m_descent = DESIGN_TO_LOGICAL(metrics.descent);
m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition);
}
m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness);
m_ascent = DESIGN_TO_LOGICAL(metrics.ascent);
m_descent = DESIGN_TO_LOGICAL(metrics.descent);
m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight);
m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap);
m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition);
}
QFixed QWindowsFontEngineDirectWrite::underlinePosition() const
@ -271,31 +271,24 @@ bool QWindowsFontEngineDirectWrite::getSfntTableData(uint tag, uchar *buffer, ui
{
bool ret = false;
if (m_directWriteFontFace) {
DWORD t = qbswap<quint32>(tag);
const void *tableData = 0;
void *tableContext = 0;
UINT32 tableSize;
BOOL exists;
HRESULT hr = m_directWriteFontFace->TryGetFontTable(
t, &tableData, &tableSize, &tableContext, &exists
);
if (SUCCEEDED(hr)) {
if (exists) {
if (!buffer) {
*length = tableSize;
ret = true;
} else if (*length >= tableSize) {
memcpy(buffer, tableData, tableSize);
ret = true;
}
}
m_directWriteFontFace->ReleaseFontTable(tableContext);
} else {
qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
const void *tableData = 0;
UINT32 tableSize;
void *tableContext = 0;
BOOL exists;
HRESULT hr = m_directWriteFontFace->TryGetFontTable(qbswap<quint32>(tag)
&tableData, &tableSize,
&tableContext, &exists);
if (SUCCEEDED(hr)) {
if (exists) {
ret = true;
if (buffer && *length >= tableSize)
memcpy(buffer, tableData, tableSize);
else
*length = tableSize;
}
m_directWriteFontFace->ReleaseFontTable(tableContext);
} else {
qErrnoWarning("%s: TryGetFontTable failed", __FUNCTION__);
}
return ret;
@ -326,43 +319,43 @@ inline unsigned int getChar(const QChar *str, int &i, const int len)
bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
int *nglyphs, QFontEngine::ShaperFlags flags) const
{
if (m_directWriteFontFace != 0) {
QVarLengthArray<UINT32> codePoints(len);
for (int i=0; i<len; ++i) {
codePoints[i] = getChar(str, i, len);
if (flags & QFontEngine::RightToLeft)
codePoints[i] = QChar::mirroredChar(codePoints[i]);
}
QVarLengthArray<UINT16> glyphIndices(len);
HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(),
len,
glyphIndices.data());
if (SUCCEEDED(hr)) {
for (int i=0; i<len; ++i)
glyphs->glyphs[i] = glyphIndices[i];
*nglyphs = len;
glyphs->numGlyphs = len;
if (!(flags & GlyphIndicesOnly))
recalcAdvances(glyphs, 0);
return true;
} else {
qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
}
if (*nglyphs < len) {
*nglyphs = len;
return false;
}
return false;
QVarLengthArray<UINT32> codePoints(len);
int actualLength = 0;
if (flags & QFontEngine::RightToLeft) {
for (int i = 0; i < len; ++i)
codePoints[actualLength++] = QChar::mirroredChar(getChar(str, i, len));
} else {
for (int i = 0; i < len; ++i)
codePoints[actualLength++] = getChar(str, i, len);
}
QVarLengthArray<UINT16> glyphIndices(actualLength);
HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(), actualLength,
glyphIndices.data());
if (FAILED(hr)) {
qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__);
return false;
}
for (int i = 0; i < actualLength; ++i)
glyphs->glyphs[i] = glyphIndices.at(i);
*nglyphs = actualLength;
glyphs->numGlyphs = actualLength;
if (!(flags & GlyphIndicesOnly))
recalcAdvances(glyphs, 0);
return true;
}
void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const
{
if (m_directWriteFontFace == 0)
return;
QVarLengthArray<UINT16> glyphIndices(glyphs->numGlyphs);
// ### Caching?
@ -390,9 +383,6 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn
void QWindowsFontEngineDirectWrite::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
QPainterPath *path, QTextItem::RenderFlags flags)
{
if (m_directWriteFontFace == 0)
return;
QVarLengthArray<UINT16> glyphIndices(nglyphs);
QVarLengthArray<DWRITE_GLYPH_OFFSET> glyphOffsets(nglyphs);
QVarLengthArray<FLOAT> glyphAdvances(nglyphs);
@ -438,9 +428,6 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(const QGlyphLayout &g
glyph_metrics_t QWindowsFontEngineDirectWrite::boundingBox(glyph_t g)
{
if (m_directWriteFontFace == 0)
return glyph_metrics_t();
UINT16 glyphIndex = g;
DWRITE_GLYPH_METRICS glyphMetrics;
@ -667,14 +654,14 @@ bool QWindowsFontEngineDirectWrite::canRender(const QChar *string, int len)
if (FAILED(hr)) {
qErrnoWarning("%s: GetGlyphIndices failed", __FUNCTION__);
return false;
} else {
for (int i=0; i<glyphIndices.size(); ++i) {
if (glyphIndices.at(i) == 0)
return false;
}
return true;
}
for (int i = 0; i < actualLength; ++i) {
if (glyphIndices.at(i) == 0)
return false;
}
return true;
}
QFontEngine::Type QWindowsFontEngineDirectWrite::type() const

View File

@ -107,8 +107,6 @@ public:
static QString fontNameSubstitute(const QString &familyName);
private:
friend class QRawFontPrivate;
QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
void collectMetrics();