📄 qfontengine_x11.cpp
字号:
metrics = face->size->metrics; unlockFace(); fsType = freetype->fsType();#ifndef QT_NO_XRENDER if (X11->use_xrender) { int format = PictStandardA8; if (!antialias) format = PictStandardA1; else if (subpixel == FC_RGBA_RGB || subpixel == FC_RGBA_BGR || subpixel == FC_RGBA_VRGB || subpixel == FC_RGBA_VBGR) format = PictStandardARGB32; glyphSet = XRenderCreateGlyphSet(X11->display, XRenderFindStandardFormat(X11->display, format)); xglyph_format = format; } else { glyphSet = 0; }#endif _openType = 0;}QFontEngineFT::~QFontEngineFT(){ delete _openType; _openType = 0; freetype->release(face_id); FcPatternDestroy(_pattern); _pattern = 0; qDeleteAll(glyph_data);#ifndef QT_NO_XRENDER if (glyphSet) XRenderFreeGlyphSet(X11->display, glyphSet);#endif}FT_Face QFontEngineFT::lockFace() const{ freetype->lock(); FT_Face face = freetype->face; if (freetype->xsize != xsize || freetype->ysize != ysize) { FT_Set_Char_Size(face, xsize, ysize, 0, 0); freetype->xsize = xsize; freetype->ysize = ysize; } if (freetype->matrix.xx != matrix.xx || freetype->matrix.yy != matrix.yy || freetype->matrix.xy != matrix.xy || freetype->matrix.yx != matrix.yx) { freetype->matrix = matrix; FT_Set_Transform(face, &freetype->matrix, 0); } return face;}void QFontEngineFT::unlockFace() const{ freetype->unlock();}FT_Face QFontEngineFT::non_locked_face() const{ return freetype->face;}static const uint subpixel_filter[3][3] = { { 180, 60, 16 }, { 38, 180, 38 }, { 16, 60, 180 }};QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(uint glyph, GlyphFormat format) const{// Q_ASSERT(freetype->lock == 1); bool add_to_glyphset = false; if (format == Format_None) { format = Format_Mono; if (X11->use_xrender) { add_to_glyphset = true; if (subpixel != FC_RGBA_NONE) format = Format_A32; else if (antialias) format = Format_A8; } } Q_ASSERT(format != Format_None); int hfactor = 1; int vfactor = 1; int load_flags = FT_LOAD_DEFAULT; if (outline_drawing) { load_flags = FT_LOAD_NO_BITMAP|FT_LOAD_NO_HINTING; } else if (format == Format_Mono) { load_flags |= FT_LOAD_TARGET_MONO; } else if (format == Format_A32) { if (subpixel == FC_RGBA_RGB || subpixel == FC_RGBA_BGR) { load_flags |= FT_LOAD_TARGET_LCD; hfactor = 3; } else if (subpixel == FC_RGBA_VRGB || subpixel == FC_RGBA_VBGR) { load_flags |= FT_LOAD_TARGET_LCD_V; vfactor = 3; } } if (format != Format_Mono) load_flags |= FT_LOAD_NO_BITMAP;#ifdef FC_HINT_STYLE if (hint_style == FC_HINT_NONE) load_flags |= FT_LOAD_NO_HINTING; else if (hint_style < FC_HINT_FULL) load_flags |= FT_LOAD_TARGET_LIGHT;#endif#ifdef FT_LOAD_FORCE_AUTOHINT if (autohint) load_flags |= FT_LOAD_FORCE_AUTOHINT;#endif if (transform) load_flags |= FT_LOAD_NO_BITMAP; { Glyph *g = glyph_data.value(glyph); if (g && g->format == format) return g; } 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; 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);#ifndef QT_NO_XRENDER XGlyphInfo info;#else typedef struct _XGlyphInfoDummy { unsigned short width; unsigned short height; short x; short y; short xOff; short yOff; } XGlyphInfoDummy; XGlyphInfoDummy info;#endif info.width = TRUNC(right - left); info.height = TRUNC(top - bottom); info.x = -TRUNC(left); info.y = TRUNC(top); info.xOff = TRUNC(ROUND(slot->advance.x)); info.yOff = 0; 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 * vfactor; uchar *buffer = new uchar[size]; memset (buffer, 0, size); if (slot->format == FT_GLYPH_FORMAT_OUTLINE) { FT_Bitmap bitmap; bitmap.rows = info.height*vfactor; bitmap.width = info.width*hfactor; bitmap.pitch = pitch; bitmap.buffer = buffer; bitmap.pixel_mode = format == Format_Mono ? ft_pixel_mode_mono : ft_pixel_mode_grays; FT_Matrix matrix; matrix.xx = hfactor << 16; matrix.yy = vfactor << 16; matrix.yx = matrix.xy = 0; FT_Outline_Transform(&slot->outline, &matrix); FT_Outline_Translate (&slot->outline, -left*hfactor, -bottom*vfactor); FT_Outline_Get_Bitmap(library, &slot->outline, &bitmap); if (hfactor != 1) { Q_ASSERT (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY); Q_ASSERT(antialias); uchar *src = buffer; size = info.width * 4 * info.height; uchar *newBuf = new uchar[size]; uint *dst = (uint *)newBuf; int h = info.height; if (subpixel == FC_RGBA_RGB) { while (h--) { uint *dd = dst; for (int x = 0; x < bitmap.width; x += 3) { uint red = src[x]; uint green = src[x+1]; uint blue = src[x+2]; 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 = (high << 16) + (mid << 8) + low; *dd = res; ++dd; } dst += info.width; src += bitmap.pitch; } } else { while (h--) { uint *dd = dst; for (int x = 0; x < bitmap.width; x += 3) { uint blue = src[x]; uint green = src[x+1]; uint red = src[x+2]; 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 = (high << 16) + (mid << 8) + low; *dd = res; ++dd; } dst += info.width; src += bitmap.pitch; } } delete [] buffer; buffer = newBuf; } else if (vfactor != 1) { uchar *src = buffer; size = info.width * 4 * info.height; uchar *newBuf = new uchar[size]; uint *dst = (uint *)newBuf; int h = info.height; if (subpixel == FC_RGBA_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 = (high << 16) + (mid << 8) + low; dst[x] = res; } dst += info.width; src += 3*bitmap.pitch; } } else { while (h--) { for (int x = 0; x < info.width; x++) { uint blue = src[x]; uint green = src[x+bitmap.pitch]; uint red = 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 = (high << 16) + (mid << 8) + low; dst[x] = res; } dst += info.width; src += 3*bitmap.pitch; } } delete [] buffer; buffer = newBuf; } } else if (slot->format == FT_GLYPH_FORMAT_BITMAP) { Q_ASSERT(slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO); uchar *src = slot->bitmap.buffer; uchar *dst = buffer; int h = slot->bitmap.rows; if (format == Format_Mono) { int bytes = ((info.width + 7) & ~7) >> 3; while (h--) { memcpy (dst, src, bytes); dst += pitch; src += slot->bitmap.pitch; } } else { if (hfactor != 1 || vfactor != 1) { while (h--) { uint *dd = (uint *)dst; for (int x = 0; x < slot->bitmap.width; x++) { unsigned char a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00); *dd++ = (a << 16) | (a << 8) | a; } dst += pitch; src += slot->bitmap.pitch; } } else { while (h--) { for (int x = 0; x < slot->bitmap.width; x++) { unsigned char a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00); dst[x] = a; } dst += pitch; src += slot->bitmap.pitch; } } } } else { qWarning("glyph neither outline nor bitmap format=%d", slot->format); delete [] buffer; return 0; }#ifndef QT_NO_XRENDER if (add_to_glyphset) { if (format == Format_Mono) { /* * swap bit order around; FreeType is always MSBFirst */ if (BitmapBitOrder(X11->display) != MSBFirst) { unsigned char *line = (unsigned char *) buffer; int i = size; i = size; while (i--) { unsigned char c; c = *line; c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55); c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33); c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f); *line++ = c; } } } ::Glyph xglyph = glyph; XRenderAddGlyphs (X11->display, glyphSet, &xglyph, &info, 1, (const char *)buffer, size); delete [] buffer; buffer = 0; }#endif bool large_glyph = (((signed char)(slot->linearHoriAdvance>>16) != slot->linearHoriAdvance>>16) || ((uchar)(info.width) != info.width) || ((uchar)(info.height) != info.height) || ((signed char)(info.x) != info.x) || ((signed char)(info.y) != info.y) || ((signed char)(info.xOff) != info.xOff)); if (large_glyph) {// qDebug("got a large glyph!"); return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -