From affdd9d00cd708d3cd337b5841e96af20dcb75c6 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 10 Apr 2013 02:51:27 +0300 Subject: 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 Reviewed-by: Konstantin Ritt --- .../windows/qwindowsfontenginedirectwrite.cpp | 141 ++++++++++----------- .../windows/qwindowsfontenginedirectwrite.h | 2 - 2 files changed, 64 insertions(+), 79 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index 5b6ce695d8..0f769f3f16 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -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; - - 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); - } + DWRITE_FONT_METRICS metrics; + + 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); } 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(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(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 codePoints(len); - for (int i=0; i glyphIndices(len); - HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(), - len, - glyphIndices.data()); + QVarLengthArray 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); + } - if (SUCCEEDED(hr)) { - for (int i=0; iglyphs[i] = glyphIndices[i]; + QVarLengthArray glyphIndices(actualLength); + HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(), actualLength, + glyphIndices.data()); + if (FAILED(hr)) { + qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__); + return false; + } - *nglyphs = len; - glyphs->numGlyphs = len; + for (int i = 0; i < actualLength; ++i) + glyphs->glyphs[i] = glyphIndices.at(i); - if (!(flags & GlyphIndicesOnly)) - recalcAdvances(glyphs, 0); + *nglyphs = actualLength; + glyphs->numGlyphs = actualLength; - return true; - } else { - qErrnoWarning("%s: GetGlyphIndicesW failed", __FUNCTION__); - } - } + if (!(flags & GlyphIndicesOnly)) + recalcAdvances(glyphs, 0); - return false; + return true; } void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const { - if (m_directWriteFontFace == 0) - return; - QVarLengthArray 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 glyphIndices(nglyphs); QVarLengthArray glyphOffsets(nglyphs); QVarLengthArray 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