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

📄 qfontengine_ft.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 4 页
字号:
                    c[2] = (2*c[1] + c[3])/3;                    c[1] = (2*c[1] + c[0])/3;                }                break;            }//             qDebug() << "cubicTo" << c[1] << c[2] << c[3];            path->cubicTo(c[1], c[2], c[3]);            c[0] = c[3];            n = 1;        }        if (n == 1) {//             qDebug() << "closeSubpath";            path->closeSubpath();        } else {            c[3] = start;            if (n == 2) {                c[2] = (2*c[1] + c[3])/3;                c[1] = (2*c[1] + c[0])/3;            }//             qDebug() << "cubicTo" << c[1] << c[2] << c[3];            path->cubicTo(c[1], c[2], c[3]);        }        ++i;    }}extern void qt_addBitmapToPath(qreal x0, qreal y0, const uchar *image_data, int bpl, int w, int h, QPainterPath *path);void QFreetypeFace::addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool){    if (slot->format != FT_GLYPH_FORMAT_BITMAP        || slot->bitmap.pixel_mode != FT_PIXEL_MODE_MONO)        return;    QPointF cp = point.toPointF();    qt_addBitmapToPath(cp.x() + TRUNC(slot->metrics.horiBearingX), cp.y() - TRUNC(slot->metrics.horiBearingY),                       slot->bitmap.buffer, slot->bitmap.pitch, slot->bitmap.width, slot->bitmap.rows, path);}QFontEngineFT::Glyph::~Glyph(){    delete [] data;}static const uint subpixel_filter[3][3] = {    { 180, 60, 16 },    { 38, 180, 38 },    { 16, 60, 180 }};QFontEngineFT::QFontEngineFT(const QFontDef &fd){    _openType = 0;    fontDef = fd;    matrix.xx = 0x10000;    matrix.yy = 0x10000;    matrix.xy = 0;    matrix.yx = 0;    cache_cost = 100;    kerning_pairs_loaded = false;    transform = false;    antialias = true;    default_load_flags = 0;    subpixelType = Subpixel_None;    defaultGlyphFormat = Format_None;    canUploadGlyphsToServer = false;}QFontEngineFT::~QFontEngineFT(){#ifndef QT_NO_OPENTYPE    delete _openType;    _openType = 0;#endif    if (freetype)        freetype->release(face_id);}void QFontEngineFT::freeGlyphSets(){    freeServerGlyphSet(defaultGlyphSet.id);    for (int i = 0; i < transformedGlyphSets.count(); ++i)        freeServerGlyphSet(transformedGlyphSets.at(i).id);}bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat defaultFormat){    defaultGlyphFormat = defaultFormat;    this->antialias = antialias;    face_id = faceId;    freetype = QFreetypeFace::getFace(face_id);    if (!freetype) {        xsize = 0;        ysize = 0;        return false;    }    symbol = freetype->symbol_map != 0;    PS_FontInfoRec psrec;    // don't assume that type1 fonts are symbol fonts by default    if (FT_Get_PS_Font_Info(freetype->face, &psrec) == FT_Err_Ok) {        symbol = bool(fontDef.family.contains(QLatin1String("symbol"), Qt::CaseInsensitive));    }    lbearing = rbearing = SHRT_MIN;    freetype->computeSize(fontDef, &xsize, &ysize, &outline_drawing);    FT_Face face = lockFace();    //underline metrics    if (FT_IS_SCALABLE(face)) {        line_thickness =  QFixed::fromFixed(FT_MulFix(face->underline_thickness, face->size->metrics.y_scale));        underline_position = QFixed::fromFixed(-FT_MulFix(face->underline_position, face->size->metrics.y_scale));        bool fake_oblique = (fontDef.style != QFont::StyleNormal) && !(face->style_flags & FT_STYLE_FLAG_ITALIC);        if (fake_oblique)            matrix.xy = 0x10000*3/10;        FT_Set_Transform(face, &matrix, 0);        if (fake_oblique)            transform = true;    } else {        // copied from QFontEngineQPF        // ad hoc algorithm        int score = fontDef.weight * fontDef.pixelSize;        line_thickness = score / 700;        // looks better with thicker line for small pointsizes        if (line_thickness < 2 && score >= 1050)            line_thickness = 2;        underline_position =  ((line_thickness * 2) + 3) / 6;    }    if (line_thickness < 1)        line_thickness = 1;    metrics = face->size->metrics;    unlockFace();    fsType = freetype->fsType();    defaultGlyphSet.id = allocateServerGlyphSet();    return true;}QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, GlyphFormat format) const{//     Q_ASSERT(freetype->lock == 1);    bool uploadToServer = false;    if (format == Format_None) {        if (defaultGlyphFormat != Format_None) {            format = defaultGlyphFormat;            if (canUploadGlyphsToServer)                uploadToServer = true;        } else {            format = Format_Mono;        }    }    Glyph *g = set->glyph_data.value(glyph);    if (g && g->format == format) {        if (uploadToServer && !g->uploadedToServer) {            set->glyph_data[glyph] = 0;            delete g;            g = 0;        } else {            return g;        }    }    QFontEngineFT::GlyphInfo info;    Q_ASSERT(format != Format_None);    bool hsubpixel = false;    int vfactor = 1;    int load_flags = FT_LOAD_DEFAULT | default_load_flags;    if (outline_drawing) {        load_flags = FT_LOAD_NO_BITMAP;    } else if (format == Format_Mono) {        load_flags |= FT_LOAD_TARGET_MONO;    } else if (format == Format_A32) {        if (subpixelType == QFontEngineFT::Subpixel_RGB || subpixelType == QFontEngineFT::Subpixel_BGR) {            load_flags |= FT_LOAD_TARGET_LCD;            hsubpixel = true;        } else if (subpixelType == QFontEngineFT::Subpixel_VRGB || subpixelType == QFontEngineFT::Subpixel_VBGR) {            load_flags |= FT_LOAD_TARGET_LCD_V;            vfactor = 3;        }    }#ifndef Q_WS_QWS    if (format != Format_Mono)        load_flags |= FT_LOAD_NO_BITMAP;#endif    bool transform = this->transform                     || set->transformationMatrix.xx != 0x10000                     || set->transformationMatrix.yy != 0x10000                     || set->transformationMatrix.xy != 0                     || set->transformationMatrix.yx != 0;    if (transform)        load_flags |= FT_LOAD_NO_BITMAP;    FT_Face face = freetype->face;    FT_Error err = FT_Load_Glyph(face, glyph, load_flags);    if (err && (load_flags & FT_LOAD_NO_BITMAP)) {        load_flags &= ~FT_LOAD_NO_BITMAP;        err = FT_Load_Glyph(face, glyph, load_flags);    }    if (err == FT_Err_Too_Few_Arguments) {        // this is an error in the bytecode interpreter, just try to run without it        load_flags |= FT_LOAD_FORCE_AUTOHINT;        err = FT_Load_Glyph(face, glyph, load_flags);    }    if (err != FT_Err_Ok)        qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph);    if (outline_drawing)        return 0;    FT_GlyphSlot slot = face->glyph;    FT_Matrix matrix = freetype->matrix;    int left  = slot->metrics.horiBearingX;    int right = slot->metrics.horiBearingX + slot->metrics.width;    int top    = slot->metrics.horiBearingY;    int bottom = slot->metrics.horiBearingY - slot->metrics.height;    if(transform && slot->format != FT_GLYPH_FORMAT_BITMAP) {        int l, r, t, b;        FT_Vector vector;        vector.x = left;        vector.y = top;        FT_Vector_Transform(&vector, &matrix);        l = r = vector.x;        t = b = vector.y;        vector.x = right;        vector.y = top;        FT_Vector_Transform(&vector, &matrix);        if (l > vector.x) l = vector.x;        if (r < vector.x) r = vector.x;        if (t < vector.y) t = vector.y;        if (b > vector.y) b = vector.y;        vector.x = right;        vector.y = bottom;        FT_Vector_Transform(&vector, &matrix);        if (l > vector.x) l = vector.x;        if (r < vector.x) r = vector.x;        if (t < vector.y) t = vector.y;        if (b > vector.y) b = vector.y;        vector.x = left;        vector.y = bottom;        FT_Vector_Transform(&vector, &matrix);        if (l > vector.x) l = vector.x;        if (r < vector.x) r = vector.x;        if (t < vector.y) t = vector.y;        if (b > vector.y) b = vector.y;        left = l;        right = r;        top = t;        bottom = b;    }    left = FLOOR(left);    right = CEIL(right);    bottom = FLOOR(bottom);    top = CEIL(top);    int hpixels = TRUNC(right - left);    if (hsubpixel)        hpixels = hpixels*3 + 8;    info.width = hpixels;    info.height = TRUNC(top - bottom);    info.x = -TRUNC(left);    info.y = TRUNC(top);    info.xOff = TRUNC(ROUND(slot->advance.x));    info.yOff = 0;    if (hsubpixel) {        info.width /= 3;        info.x += 1;    }    int pitch = (format == Format_Mono ? ((info.width + 31) & ~31) >> 3 :                 (format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4));    int size = pitch * info.height;    uchar *glyph_buffer = new uchar[size];    if (slot->format == FT_GLYPH_FORMAT_OUTLINE) {        FT_Bitmap bitmap;        bitmap.rows = info.height*vfactor;        bitmap.width = hpixels;        bitmap.pitch = format == Format_Mono ? (((info.width + 31) & ~31) >> 3) : ((bitmap.width + 3) & ~3);        if (!hsubpixel && vfactor == 1)            bitmap.buffer = glyph_buffer;        else            bitmap.buffer = new uchar[bitmap.rows*bitmap.pitch];        memset(bitmap.buffer, 0, bitmap.rows*bitmap.pitch);        bitmap.pixel_mode = format == Format_Mono ? ft_pixel_mode_mono : ft_pixel_mode_grays;        FT_Matrix matrix;        matrix.xx = (hsubpixel ? 3 : 1) << 16;        matrix.yy = vfactor << 16;        matrix.yx = matrix.xy = 0;        FT_Outline_Transform(&slot->outline, &matrix);        FT_Outline_Translate (&slot->outline, (hsubpixel ? -3*left +(4<<6) : -left), -bottom*vfactor);        FT_Outline_Get_Bitmap(library, &slot->outline, &bitmap);        if (hsubpixel) {            Q_ASSERT (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);            Q_ASSERT(antialias);            const uchar *src = bitmap.buffer;            uchar *convoluted = new uchar[bitmap.rows*bitmap.pitch];            uchar *c = convoluted;            // convolute the bitmap with a triangle filter to get rid of color fringes            // If we take account for a gamma value of 2, we end up with            // weights of 1, 4, 9, 4, 1. We use an approximation of 1, 3, 8, 3, 1 here,            // as this nicely sums up to 16 :)            int h = info.height;            while (h--) {                c[0] = c[1] = 0;                //                for (int x = 2; x < bitmap.width - 2; ++x) {                    uint sum = src[x-2] + 3*src[x-1] + 8*src[x] + 3*src[x+1] + src[x+2];                    c[x] = (uchar) (sum >> 4);                }                c[bitmap.width - 2] = c[bitmap.width -1] = 0;                src += bitmap.pitch;                c += bitmap.pitch;            }            uint *dst = (uint *)glyph_buffer;            src = convoluted;            h = info.height;            if (subpixelType == QFontEngineFT::Subpixel_RGB) {                while (h--) {                    uint *dd = dst;                    for (int x = 1; x < bitmap.width - 1; x += 3) {                        uint red = src[x];                        uint green = src[x+1];                        uint blue = src[x+2];                        uint alpha = green;                        uint res = (alpha << 24) + (red << 16) + (green << 8) + blue;                        *dd = res;                        ++dd;                    }                    dst += info.width;                    src += bitmap.pitch;                }            } else {                while (h--) {                    uint *dd = dst;                    for (int x = 1; x < bitmap.width - 1; x += 3) {                        uint blue = src[x];                        uint green = src[x+1];                        uint red = src[x+2];                        uint alpha = green;                        uint res = (alpha << 24) + (red << 16) + (green << 8) + blue;                        *dd = res;                        ++dd;                    }                    dst += info.width;                    src += bitmap.pitch;                }            }            delete [] convoluted;            delete [] bitmap.buffer;        } else if (vfactor != 1) {            uchar *src = bitmap.buffer;            size = info.width * 4 * info.height;            uint *dst = (uint *)glyph_buffer;            int h = info.height;            if (subpixelType == QFontEngineFT::Subpixel_VRGB) {                while (h--) {                    for (int x = 0; x < info.width; x++) {                        uint red = src[x];                        uint green = src[x+bitmap.pitch];                        uint blue = src[x+2*bitmap.pitch];                        uint high = (red*subpixel_filter[0][0] + green*subpixel_filter[0][1] + blue*subpixel_filter[0][2]) >> 8;                        uint mid = (red*subpixel_filter[1][0] + green*subpixel_filter[1][1] + blue*subpixel_filter[1][2]) >> 8;                        uint low = (red*subpixel_filter[2][0] + green*subpixel_filter[2][1] + blue*subpixel_filter[2][2]) >> 8;                        uint res = (mid << 24) + (high << 16) + (mid << 8) + low;                        dst[x] = res;                    }                    dst += info.width;                    src += 3*bitmap.pitch;                }

⌨️ 快捷键说明

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