void QFontEngineDirectWrite::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); for (int i=0; i<nglyphs; ++i) { glyphIndices[i] = glyphs[i]; glyphOffsets[i].advanceOffset = positions[i].x.toReal(); glyphOffsets[i].ascenderOffset = -positions[i].y.toReal(); glyphAdvances[i] = 0.0; } GeometrySink geometrySink(path); HRESULT hr = m_directWriteFontFace->GetGlyphRunOutline( fontDef.pixelSize, glyphIndices.data(), glyphAdvances.data(), glyphOffsets.data(), nglyphs, false, flags & QTextItem::RightToLeft, &geometrySink ); if (FAILED(hr)) qErrnoWarning("QFontEngineDirectWrite::addGlyphsToPath: GetGlyphRunOutline failed"); }
void QFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags) const { if (m_directWriteFontFace == 0) return; QVarLengthArray<UINT16> glyphIndices(glyphs->numGlyphs); // ### Caching? for(int i=0; i<glyphs->numGlyphs; i++) glyphIndices[i] = UINT16(glyphs->glyphs[i]); QVarLengthArray<DWRITE_GLYPH_METRICS> glyphMetrics(glyphIndices.size()); HRESULT hr = m_directWriteFontFace->GetDesignGlyphMetrics(glyphIndices.data(), glyphIndices.size(), glyphMetrics.data()); if (SUCCEEDED(hr)) { for (int i=0; i<glyphs->numGlyphs; ++i) { glyphs->advances_x[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth); if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) glyphs->advances_x[i] = glyphs->advances_x[i].round(); glyphs->advances_y[i] = 0; } } else { qErrnoWarning("QFontEngineDirectWrite::recalcAdvances: GetDesignGlyphMetrics failed"); } }
bool QFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::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 & QTextEngine::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; if (!(flags & QTextEngine::GlyphIndicesOnly)) recalcAdvances(glyphs, 0); return true; } else { qErrnoWarning("QFontEngineDirectWrite::stringToCMap: GetGlyphIndicesW failed"); } } return false; }
bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const { Q_ASSERT(glyphs->numGlyphs >= *nglyphs); if (*nglyphs < len) { *nglyphs = len; return false; } QVarLengthArray<UINT32> codePoints(len); int actualLength = 0; QStringIterator it(str, str + len); while (it.hasNext()) codePoints[actualLength++] = it.next(); 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; }
bool QFontEngineDirectWrite::canRender(const QChar *string, int len) { QVarLengthArray<UINT32> codePoints(len); int actualLength = 0; for (int i=0; i<len; ++i, actualLength++) codePoints[actualLength] = getChar(string, i, len); QVarLengthArray<UINT16> glyphIndices(actualLength); HRESULT hr = m_directWriteFontFace->GetGlyphIndices(codePoints.data(), actualLength, glyphIndices.data()); if (FAILED(hr)) { qErrnoWarning(hr, "QFontEngineDirectWrite::canRender: GetGlyphIndices failed"); return false; } else { for (int i=0; i<glyphIndices.size(); ++i) { if (glyphIndices.at(i) == 0) return false; } return true; } }
bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const { if (*nglyphs < len) { *nglyphs = len; 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; }