📄 qfontengine_x11.cpp
字号:
&& s[i].unicode() >= 0xd800 && s[i].unicode() < 0xdc00 && s[i+1].unicode() >= 0xdc00 && s[i].unicode() < 0xe000) { *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[i].glyph = ((ushort)data[0] << 8) + data[1]; data += 2; } } else { const uchar *data = (const uchar *)ba.constData(); for (int i = 0; i < len; i++) glyphs[i].glyph = (ushort)data[i]; } } else { QGlyphLayout *g = glyphs + len; const QChar *c = str + len; if (mirrored) { while (c != str) (--g)->glyph = (--c)->unicode() == 0xa0 ? 0x20 : QChar::mirroredChar(c->unicode()); } else { while (c != str) (--g)->glyph = (--c)->unicode() == 0xa0 ? 0x20 : c->unicode(); } } *nglyphs = len; QGlyphLayout *g = glyphs + len; XCharStruct *xcs; // inlined for better perfomance if (!_fs->per_char) { xcs = &_fs->min_bounds; while (g != glyphs) { --g; const unsigned char r = g->glyph >> 8; const unsigned char c = g->glyph & 0xff; if (r >= _fs->min_byte1 && r <= _fs->max_byte1 && c >= _fs->min_char_or_byte2 && c <= _fs->max_char_or_byte2) { g->advance.x = xcs->width; } else { g->glyph = 0; } } } else if (!_fs->max_byte1) { XCharStruct *base = _fs->per_char - _fs->min_char_or_byte2; while (g != glyphs) { unsigned int gl = (--g)->glyph; xcs = (gl >= _fs->min_char_or_byte2 && gl <= _fs->max_char_or_byte2) ? base + gl : 0; if (!xcs || (!xcs->width && !xcs->ascent && !xcs->descent)) { g->glyph = 0; } else { g->advance.x = xcs->width; } } } else { while (g != glyphs) { xcs = charStruct(_fs, (--g)->glyph); if (!xcs) { g->glyph = 0; } else { g->advance.x = xcs->width; } } } return true;}glyph_metrics_t QFontEngineXLFD::boundingBox(const QGlyphLayout *glyphs, int numGlyphs){ int i; glyph_metrics_t overall; // initialize with line height, we get the same behaviour on all platforms overall.y = -ascent(); overall.height = ascent() + descent() + 1; QFixed ymax; QFixed xmax; for (i = 0; i < numGlyphs; i++) { XCharStruct *xcs = charStruct(_fs, glyphs[i].glyph); if (xcs) { QFixed x = overall.xoff + glyphs[i].offset.x + xcs->lbearing; QFixed y = overall.yoff + glyphs[i].offset.y - xcs->ascent; overall.x = qMin(overall.x, x); overall.y = qMin(overall.y, y); xmax = qMax(xmax, overall.xoff + glyphs[i].offset.x + xcs->rbearing); ymax = qMax(ymax, y + xcs->ascent + xcs->descent); overall.xoff += glyphs[i].advance.x; } else { QFixed size = _fs->ascent; overall.x = qMin(overall.x, overall.xoff); overall.y = qMin(overall.y, overall.yoff - size); ymax = qMax(ymax, overall.yoff); overall.xoff += size; xmax = qMax(xmax, overall.xoff); } } overall.height = qMax(overall.height, ymax - overall.y); overall.width = xmax - overall.x; return overall;}glyph_metrics_t QFontEngineXLFD::boundingBox(glyph_t glyph){ glyph_metrics_t gm; XCharStruct *xcs = charStruct(_fs, glyph); if (xcs) { gm = glyph_metrics_t(xcs->lbearing, -xcs->ascent, xcs->rbearing- xcs->lbearing, xcs->ascent + xcs->descent, xcs->width, 0); } else { QFixed size = ascent(); gm = glyph_metrics_t(0, size, size, size, size, 0); } return gm;}QFixed QFontEngineXLFD::ascent() const{ return _fs->ascent;}QFixed QFontEngineXLFD::descent() const{ return (_fs->descent-1);}QFixed QFontEngineXLFD::leading() const{ QFixed l = QFixed(qMin<int>(_fs->ascent, _fs->max_bounds.ascent) + qMin<int>(_fs->descent, _fs->max_bounds.descent)) * QFixed::fromReal(0.15); return l.ceil();}qreal QFontEngineXLFD::maxCharWidth() const{ return _fs->max_bounds.width;}// Loads the font for the specified scriptstatic inline int maxIndex(XFontStruct *f) { return (((f->max_byte1 - f->min_byte1) * (f->max_char_or_byte2 - f->min_char_or_byte2 + 1)) + f->max_char_or_byte2 - f->min_char_or_byte2);}qreal QFontEngineXLFD::minLeftBearing() const{ if (lbearing == SHRT_MIN) { if (_fs->per_char) { XCharStruct *cs = _fs->per_char; int nc = maxIndex(_fs) + 1; int mx = cs->lbearing; for (int c = 1; c < nc; c++) { // ignore the bearings for characters whose ink is // completely outside the normal bounding box if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) || (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width)) continue; int nmx = cs[c].lbearing; if (nmx < mx) mx = nmx; } ((QFontEngineXLFD *)this)->lbearing = mx; } else ((QFontEngineXLFD *)this)->lbearing = _fs->min_bounds.lbearing; } return lbearing;}qreal QFontEngineXLFD::minRightBearing() const{ if (rbearing == SHRT_MIN) { if (_fs->per_char) { XCharStruct *cs = _fs->per_char; int nc = maxIndex(_fs) + 1; int mx = cs->rbearing; for (int c = 1; c < nc; c++) { // ignore the bearings for characters whose ink is // completely outside the normal bounding box if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) || (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width)) continue; int nmx = cs[c].rbearing; if (nmx < mx) mx = nmx; } ((QFontEngineXLFD *)this)->rbearing = mx; } else ((QFontEngineXLFD *)this)->rbearing = _fs->min_bounds.rbearing; } return rbearing;}const char *QFontEngineXLFD::name() const{ return _name;}bool QFontEngineXLFD::canRender(const QChar *string, int len){ QVarLengthArray<QGlyphLayout, 256> glyphs(len); int nglyphs = len; if (stringToCMap(string, len, glyphs.data(), &nglyphs, 0) == false) { glyphs.resize(nglyphs); stringToCMap(string, len, glyphs.data(), &nglyphs, 0); } bool allExist = true; for (int i = 0; i < nglyphs; i++) { if (!glyphs[i].glyph || !charStruct(_fs, glyphs[i].glyph)) { allExist = false; break; } } return allExist;}void QFontEngineXLFD::addOutlineToPath(qreal x, qreal y, const QGlyphLayout *glyphs, int numGlyphs, QPainterPath *path, QTextItem::RenderFlags flags){ addBitmapFontToPath(x, y, glyphs, numGlyphs, path, flags);}QFontEngine::FaceId QFontEngineXLFD::faceId() const{#ifndef QT_NO_FREETYPE if (face_id.index == -1) { face_id = ::fontFile(_name, &freetype, &synth); if (_codec) face_id.encoding = _codec->mibEnum(); if (freetype) { const_cast<QFontEngineXLFD *>(this)->fsType = freetype->fsType(); } else { QFontEngine::Properties properties = QFontEngine::properties(); face_id.index = 0; face_id.filename = "-" + properties.postscriptName; } }#endif return face_id;}QFontEngine::Properties QFontEngineXLFD::properties() const{ if (face_id.index == -1) (void)faceId();#ifndef QT_NO_FREETYPE if (freetype) return freetype->properties();#endif return QFontEngine::properties();}void QFontEngineXLFD::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics){ if (face_id.index == -1) (void)faceId();#ifndef QT_NO_FREETYPE if (!freetype)#endif { QFontEngine::getUnscaledGlyph(glyph, path, metrics); return; }#ifndef QT_NO_FREETYPE freetype->lock(); FT_Face face = freetype->face; FT_Set_Char_Size(face, face->units_per_EM << 6, face->units_per_EM << 6, 0, 0); freetype->xsize = face->units_per_EM << 6; freetype->ysize = face->units_per_EM << 6; FT_Set_Transform(face, 0, 0); glyph = glyphIndexToFreetypeGlyphIndex(glyph); FT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP); int left = face->glyph->metrics.horiBearingX;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -