⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qfontsubset.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      << quint16(0)// quint16  unitsPerEm  Valid range is from 16 to 16384. This value should be a power of 2 for fonts that have TrueType outlines.      << quint16(2048)// qint64  created  Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer      << head.created// qint64  modified  Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer      << head.modified// qint16  xMin  For all glyph bounding boxes.// qint16  yMin  For all glyph bounding boxes.// qint16  xMax  For all glyph bounding boxes.// qint16  yMax  For all glyph bounding boxes.      << head.xMin      << head.yMin      << head.xMax      << head.yMax// quint16  macStyle  Bit 0: Bold (if set to 1);// Bit 1: Italic (if set to 1)// Bit 2: Underline (if set to 1)// Bit 3: Outline (if set to 1)// Bit 4: Shadow (if set to 1)// Bit 5: Condensed (if set to 1)// Bit 6: Extended (if set to 1)// Bits 7-15: Reserved (set to 0).      << head.macStyle// quint16  lowestRecPPEM  Smallest readable size in pixels.      << quint16(6) // just a wild guess// qint16  fontDirectionHint   0: Fully mixed directional glyphs;      << qint16(0)// 1: Only strongly left to right;// 2: Like 1 but also contains neutrals;// -1: Only strongly right to left;// -2: Like -1 but also contains neutrals. 1// qint16  indexToLocFormat  0 for short offsets, 1 for long.      << head.indexToLocFormat// qint16  glyphDataFormat  0 for current format.      << qint16(0);    Q_ASSERT(s.offset() == head_size);    return t;}static QTtfTable generateHhea(const qttf_hhea_table &hhea){    const int hhea_size = 36;    QTtfTable t;    t.tag = MAKE_TAG('h', 'h', 'e', 'a');    t.data.resize(hhea_size);    QTtfStream s(t.data);// qint32  Table version number  0x00010000 for version 1.0.    s << qint32(0x00010000)// qint16  Ascender  Typographic ascent.  (Distance from baseline of highest ascender)      << hhea.ascender// qint16  Descender  Typographic descent.  (Distance from baseline of lowest descender)      << hhea.descender// qint16  LineGap  Typographic line gap.// Negative LineGap values are treated as zero// in Windows 3.1, System 6, and// System 7.      << hhea.lineGap// quint16  advanceWidthMax  Maximum advance width value in 'hmtx' table.      << hhea.maxAdvanceWidth// qint16  minLeftSideBearing  Minimum left sidebearing value in 'hmtx' table.      << hhea.minLeftSideBearing// qint16  minRightSideBearing  Minimum right sidebearing value; calculated as Min(aw - lsb - (xMax - xMin)).      << hhea.minRightSideBearing// qint16  xMaxExtent  Max(lsb + (xMax - xMin)).      << hhea.xMaxExtent// qint16  caretSlopeRise  Used to calculate the slope of the cursor (rise/run); 1 for vertical.      << qint16(1)// qint16  caretSlopeRun  0 for vertical.      << qint16(0)// qint16  caretOffset  The amount by which a slanted highlight on a glyph needs to be shifted to produce the best appearance. Set to 0 for non-slanted fonts      << qint16(0)// qint16  (reserved)  set to 0      << qint16(0)// qint16  (reserved)  set to 0      << qint16(0)// qint16  (reserved)  set to 0      << qint16(0)// qint16  (reserved)  set to 0      << qint16(0)// qint16  metricDataFormat  0 for current format.      << qint16(0)// quint16  numberOfHMetrics  Number of hMetric entries in 'hmtx' table      << hhea.numberOfHMetrics;    Q_ASSERT(s.offset() == hhea_size);    return t;}static QTtfTable generateMaxp(const qttf_maxp_table &maxp){    const int maxp_size = 32;    QTtfTable t;    t.tag = MAKE_TAG('m', 'a', 'x', 'p');    t.data.resize(maxp_size);    QTtfStream s(t.data);// qint32  Table version number  0x00010000 for version 1.0.    s << qint32(0x00010000)// quint16  numGlyphs  The number of glyphs in the font.      << maxp.numGlyphs// quint16  maxPoints  Maximum points in a non-composite glyph.      << maxp.maxPoints// quint16  maxContours  Maximum contours in a non-composite glyph.      << maxp.maxContours// quint16  maxCompositePoints  Maximum points in a composite glyph.      << maxp.maxCompositePoints// quint16  maxCompositeContours  Maximum contours in a composite glyph.      << maxp.maxCompositeContours// quint16  maxZones  1 if instructions do not use the twilight zone (Z0), or 2 if instructions do use Z0; should be set to 2 in most cases.      << quint16(1) // we do not embed instructions// quint16  maxTwilightPoints  Maximum points used in Z0.      << quint16(0)// quint16  maxStorage  Number of Storage Area locations.      << quint16(0)// quint16  maxFunctionDefs  Number of FDEFs.      << quint16(0)// quint16  maxInstructionDefs  Number of IDEFs.      << quint16(0)// quint16  maxStackElements  Maximum stack depth2.      << quint16(0)// quint16  maxSizeOfInstructions  Maximum byte count for glyph instructions.      << quint16(0)// quint16  maxComponentElements  Maximum number of components referenced at "top level" for any composite glyph.      << maxp.maxComponentElements// quint16  maxComponentDepth  Maximum levels of recursion; 1 for simple components.      << maxp.maxComponentDepth;    Q_ASSERT(s.offset() == maxp_size);    return t;}struct QTtfNameRecord {    quint16 nameId;    QString value;};static QTtfTable generateName(const QList<QTtfNameRecord> &name);static QTtfTable generateName(const qttf_name_table &name){    QList<QTtfNameRecord> list;    QTtfNameRecord rec;    rec.nameId = 0;    rec.value = name.copyright;    list.append(rec);    rec.nameId = 1;    rec.value = name.family;    list.append(rec);    rec.nameId = 2;    rec.value = name.subfamily;    list.append(rec);    rec.nameId = 4;    rec.value = name.family;    if (name.subfamily != QLatin1String("Regular"))        rec.value += QLatin1Char(' ') + name.subfamily;    list.append(rec);    rec.nameId = 6;    rec.value = name.postscript_name;    list.append(rec);    return generateName(list);}// ####### should probably generate Macintosh/Roman name entries as wellstatic QTtfTable generateName(const QList<QTtfNameRecord> &name){    const int char_size = 2;    QTtfTable t;    t.tag = MAKE_TAG('n', 'a', 'm', 'e');    const int name_size = 6 + 12*name.size();    int string_size = 0;    for (int i = 0; i < name.size(); ++i) {        string_size += name.at(i).value.length()*char_size;    }    t.data.resize(name_size + string_size);    QTtfStream s(t.data);// quint16  format  Format selector (=0).    s << quint16(0)// quint16  count  Number of name records.      << quint16(name.size())// quint16  stringOffset  Offset to start of string storage (from start of table).      << quint16(name_size);// NameRecord  nameRecord[count]  The name records where count is the number of records.// (Variable)    int off = 0;    for (int i = 0; i < name.size(); ++i) {        int len = name.at(i).value.length()*char_size;// quint16  platformID  Platform ID.// quint16  encodingID  Platform-specific encoding ID.// quint16  languageID  Language ID.        s << quint16(3)          << quint16(1)          << quint16(0x0409) // en_US// quint16  nameId  Name ID.          << name.at(i).nameId// quint16  length  String length (in bytes).          << quint16(len)// quint16  offset  String offset from start of storage area (in bytes).          << quint16(off);        off += len;    }    for (int i = 0; i < name.size(); ++i) {        const QString &n = name.at(i).value;        const ushort *uc = n.utf16();        for (int i = 0; i < n.length(); ++i) {            s << quint16(*uc);            ++uc;        }    }    return t;}enum Flags {    OffCurve = 0,    OnCurve = (1 << 0),    XShortVector = (1 << 1),    YShortVector = (1 << 2),    Repeat = (1 << 3),    XSame = (1 << 4),    XShortPositive = (1 << 4),    YSame = (1 << 5),    YShortPositive = (1 << 5)};struct TTF_POINT {    qint16 x;    qint16 y;    quint8 flags;};Q_DECLARE_TYPEINFO(TTF_POINT, Q_PRIMITIVE_TYPE);static void convertPath(const QPainterPath &path, QList<TTF_POINT> *points, QList<int> *endPoints, qreal ppem){    int numElements = path.elementCount();    for (int i = 0; i < numElements - 1; ++i) {        const QPainterPath::Element &e = path.elementAt(i);        TTF_POINT p;        p.x = qRound(e.x * 2048. / ppem);        p.y = qRound(-e.y * 2048. / ppem);        switch(e.type) {        case QPainterPath::MoveToElement:            if (i != 0) {                // see if start and end points of the last contour agree                int start = endPoints->size() ? endPoints->at(endPoints->size()-1) - 1 : 0;                int end = points->size() - 1;                if (points->at(end).x == points->at(start).x                    && points->at(end).y == points->at(start).y)                    points->takeLast();                endPoints->append(points->size() - 1);            }            // fall through        case QPainterPath::LineToElement:            p.flags = OnCurve;            break;        case QPainterPath::CurveToElement: {            // cubic bezier curve, we need to reduce to a list of quadratic curves            TTF_POINT list[3*16 + 4]; // we need max 16 subdivisions            list[3] = points->at(points->size() - 1);            list[2] = p;            const QPainterPath::Element &e2 = path.elementAt(++i);            list[1].x = qRound(e2.x * 2048. / ppem);            list[1].y = qRound(-e2.y * 2048. / ppem);            const QPainterPath::Element &e3 = path.elementAt(++i);            list[0].x = qRound(e3.x * 2048. / ppem);            list[0].y = qRound(-e3.y * 2048. / ppem);            TTF_POINT *base = list;            bool try_reduce = points->size() > 1                              && points->at(points->size() - 1).flags == OnCurve                              && points->at(points->size() - 2).flags == OffCurve;//             qDebug("generating beziers:");            while (base >= list) {                const int split_limit = 3;//                 {//                     qDebug("iteration:");//                     TTF_POINT *x = list;//                     while (x <= base + 3) {//                         qDebug() << "    " << QPoint(x->x, x->y);//                         ++x;//                     }//                 }                Q_ASSERT(base - list < 3*16 + 1);                // first see if we can easily reduce the cubic to a quadratic bezier curve                int i1_x = base[1].x + ((base[1].x - base[0].x) >> 1);                int i1_y = base[1].y + ((base[1].y - base[0].y) >> 1);                int i2_x = base[2].x + ((base[2].x - base[3].x) >> 1);                int i2_y = base[2].y + ((base[2].y - base[3].y) >> 1);//                 qDebug() << "checking: i1=" << QPoint(i1_x, i1_y) << " i2=" << QPoint(i2_x, i2_y);                if (qAbs(i1_x - i2_x) <= split_limit && qAbs(i1_y - i2_y) <= split_limit) {                    // got a quadratic bezier curve                    TTF_POINT np;                    np.x = (i1_x + i2_x) >> 1;                    np.y = (i1_y + i2_y) >> 1;                    if (try_reduce) {                        // see if we can optimise out the last onCurve point                        int mx = (points->at(points->size() - 2).x + base[2].x) >> 1;                        int my = (points->at(points->size() - 2).y + base[2].y) >> 1;                        if (qAbs(mx - base[3].x) <= split_limit && qAbs(my = base[3].y) <= split_limit)                            points->takeLast();                        try_reduce = false;                    }                    np.flags = OffCurve;                    points->append(np);//                     qDebug() << "   appending offcurve point " << QPoint(np.x, np.y);                    base -= 3;                } else {                    // need to split//                     qDebug() << "  -> splitting";                    qint16 a, b, c, d;                    base[6].x = base[3].x;                    c = base[1].x;                    d = base[2].x;                    base[1].x = a = ( base[0].x + c ) >> 1;                    base[5].x = b = ( base[3].x + d ) >> 1;                    c = ( c + d ) >> 1;                    base[2].x = a = ( a + c ) >> 1;                    base[4].x = b = ( b + c ) >> 1;                    base[3].x = ( a + b ) >> 1;                    base[6].y = base[3].y;                    c = base[1].y;                    d = base[2].y;                    base[1].y = a = ( base[0].y + c ) >> 1;                    base[5].y = b = ( base[3].y + d ) >> 1;                    c = ( c + d ) >> 1;                    base[2].y = a = ( a + c ) >> 1;                    base[4].y = b = ( b + c ) >> 1;                    base[3].y = ( a + b ) >> 1;                    base += 3;                }            }            p = list[0];            p.flags = OnCurve;            break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -