bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const { if (*nglyphs < len) { *nglyphs = len; return false; } *nglyphs = getGlyphIndexes(str, len, glyphs, flags & QTextEngine::RightToLeft); if (flags & QTextEngine::GlyphIndicesOnly) return true; recalcAdvances(glyphs, flags); return true; }
bool QWindowsFontEngine::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; } glyphs->numGlyphs = *nglyphs; *nglyphs = getGlyphIndexes(str, len, glyphs); if (!(flags & GlyphIndicesOnly)) recalcAdvances(glyphs, flags); return true; }
bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const { if (*nglyphs < len) { *nglyphs = len; return false; } #if defined(DEBUG_FONTENGINE) QSet<QChar> seenGlyphs; #endif const uchar *cmap = externalCMap ? externalCMap : (fontData + cmapOffset); bool mirrored = flags & QTextEngine::RightToLeft; int glyph_pos = 0; if (symbol) { for (int i = 0; i < len; ++i) { unsigned int uc = getChar(str, i, len); if (mirrored) uc = QChar::mirroredChar(uc); glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc); if(!glyphs->glyphs[glyph_pos] && uc < 0x100) glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000); ++glyph_pos; } } else { for (int i = 0; i < len; ++i) { unsigned int uc = getChar(str, i, len); if (mirrored) uc = QChar::mirroredChar(uc); glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc); #if 0 && defined(DEBUG_FONTENGINE) QChar c(uc); if (!findGlyph(glyphs[glyph_pos].glyph) && !seenGlyphs.contains(c)) qDebug() << "glyph for character" << c << '/' << hex << uc << "is" << dec << glyphs[glyph_pos].glyph; seenGlyphs.insert(c); #endif ++glyph_pos; } } *nglyphs = glyph_pos; glyphs->numGlyphs = glyph_pos; recalcAdvances(glyphs, flags); return true; }
bool QFontEngineQPF2::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; } #if defined(DEBUG_FONTENGINE) QSet<QChar> seenGlyphs; #endif int glyph_pos = 0; if (symbol) { QStringIterator it(str, str + len); while (it.hasNext()) { const uint uc = it.next(); glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc); if(!glyphs->glyphs[glyph_pos] && uc < 0x100) glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc + 0xf000); ++glyph_pos; } } else { QStringIterator it(str, str + len); while (it.hasNext()) { const uint uc = it.next(); glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, cmapSize, uc); #if 0 && defined(DEBUG_FONTENGINE) QChar c(uc); if (!findGlyph(glyphs[glyph_pos].glyph) && !seenGlyphs.contains(c)) qDebug() << "glyph for character" << c << '/' << hex << uc << "is" << dec << glyphs[glyph_pos].glyph; seenGlyphs.insert(c); #endif ++glyph_pos; } } *nglyphs = glyph_pos; glyphs->numGlyphs = glyph_pos; if (!(flags & GlyphIndicesOnly)) recalcAdvances(glyphs, flags); return true; }
bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const { if (*nglyphs < len) { *nglyphs = len; return false; } HB_Glyph *g = glyphs->glyphs; const unsigned char* cmap = m_extensions->cmap(); for (int i = 0; i < len; ++i) { const unsigned int uc = getChar(characters, i, len); *g++ = QFontEngine::getTrueTypeGlyphIndex(cmap, uc); } glyphs->numGlyphs = g - glyphs->glyphs; *nglyphs = glyphs->numGlyphs; if (flags & QTextEngine::GlyphIndicesOnly) return true; recalcAdvances(glyphs, flags); 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; }
bool QFontEngineXLFD::stringToCMap(const QChar *s, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const { if (*nglyphs < len) { *nglyphs = len; return false; } // filter out surrogates, we can't handle them anyway with XLFD fonts QVarLengthArray<ushort> _s(len); QChar *str = (QChar *)_s.data(); for (int i = 0; i < len; ++i) { if (s[i].isHighSurrogate() && i < len-1 && s[i+1].isLowSurrogate()) { *str = QChar(); ++i; } else { *str = s[i]; } ++str; } len = str - (QChar *)_s.data(); str = (QChar *)_s.data(); bool mirrored = flags & QTextEngine::RightToLeft; if (_codec) { bool haveNbsp = false; for (int i = 0; i < len; i++) if (str[i].unicode() == 0xa0) { haveNbsp = true; break; } QVarLengthArray<unsigned short> ch(len); QChar *chars = (QChar *)ch.data(); if (haveNbsp || mirrored) { for (int i = 0; i < len; i++) chars[i] = (str[i].unicode() == 0xa0 ? 0x20 : (mirrored ? QChar::mirroredChar(str[i].unicode()) : str[i].unicode())); } else { for (int i = 0; i < len; i++) chars[i] = str[i].unicode(); } QTextCodec::ConverterState state; state.flags = QTextCodec::ConvertInvalidToNull; QByteArray ba = _codec->fromUnicode(chars, len, &state); if (ba.length() == 2*len) { // double byte encoding const uchar *data = (const uchar *)ba.constData(); for (int i = 0; i < len; i++) { glyphs->glyphs[i] = ((ushort)data[0] << 8) + data[1]; data += 2; } } else { const uchar *data = (const uchar *)ba.constData(); for (int i = 0; i < len; i++) glyphs->glyphs[i] = (ushort)data[i]; } } else { int i = len; const QChar *c = str + len; if (mirrored) { while (c != str) glyphs->glyphs[--i] = (--c)->unicode() == 0xa0 ? 0x20 : QChar::mirroredChar(c->unicode()); } else { while (c != str) glyphs->glyphs[--i] = (--c)->unicode() == 0xa0 ? 0x20 : c->unicode(); } } *nglyphs = len; glyphs->numGlyphs = len; if (!(flags & QTextEngine::GlyphIndicesOnly)) recalcAdvances(glyphs, flags); return true; }