[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: font handling bug in qt 4.0.1
From: LiuCougar <liucougar () gmail ! com>
Date: 2005-09-26 3:22:31
Message-ID: 9558067805092520221223e3f2 () mail ! gmail ! com
[Download RAW message or body]
*Short description: Fake oblique font does not work properly
*What I did:
Open qtconfig, in the font tab, select a font which does not have an
italic style, select style oblique
*What I expected to see:
the "Sample Text" in the lineedit should be shown in style oblique
*What I got instead:
the "Sample Text" in the lineedit did not change style to oblique
Attached is a patch to solve this issue, and also add support for
"fake bold" as well (which is supported by freetype 2.1.10)
Please someone review it?
Regards,
Cougar
--
"People's characters are strengthened through struggle against
difficulties; they are weakened by comfort."
- Old Chinese adage
["oblique_bold.patch" (application/octet-stream)]
Index: src/gui/text/qfontengine_x11.cpp
===================================================================
--- src/gui/text/qfontengine_x11.cpp (revision 463892)
+++ src/gui/text/qfontengine_x11.cpp (working copy)
@@ -39,6 +39,10 @@
#include "qfont_p.h"
#include "qfontengine_p.h"
#include "qopentype_p.h"
+#ifdef FT_SYNTHESIS_H
+#define HAVE_FT_GLYPHSLOT_EMBOLDEN 1
+#include FT_SYNTHESIS_H
+#endif
#include <qhash.h>
#include <private/qpainter_p.h>
@@ -547,6 +551,14 @@
if (!antialias || subpixel == FC_RGBA_UNKNOWN)
subpixel = FC_RGBA_NONE;
+#ifdef FC_EMBOLDEN
+ if (FcPatternGetBool (pattern,
+ FC_EMBOLDEN, 0, &b) != FcResultMatch)
+ b = FcFalse;
+
+ embolden = b;
+#endif
+
if (!library)
FT_Init_FreeType(&library);
@@ -720,11 +732,83 @@
FT_GlyphSlot slot = face->glyph;
+#if HAVE_FT_GLYPHSLOT_EMBOLDEN
+ if (embolden && (face->style_flags & FT_STYLE_FLAG_BOLD) == 0) {
+ FT_GlyphSlot_Embolden (slot);
+ }
+#endif
+
int left = FLOOR(slot->metrics.horiBearingX);
int right = CEIL(slot->metrics.horiBearingX + slot->metrics.width);
int top = CEIL(slot->metrics.horiBearingY);
int bottom = FLOOR(slot->metrics.horiBearingY - slot->metrics.height);
+ FcMatrix * matrix_builtin = 0;
+ FcPatternGetMatrix( _pattern, FC_MATRIX, 0, &matrix_builtin );
+ if ( matrix_builtin ) {
+ FT_Matrix mat2;
+ mat2.xx = (FT_Fixed) (0x10000L * matrix_builtin->xx);
+ mat2.yy = (FT_Fixed) (0x10000L * matrix_builtin->yy);
+ mat2.yx = (FT_Fixed) (0x10000L * matrix_builtin->yx);
+ mat2.xy = (FT_Fixed) (0x10000L * matrix_builtin->xy);
+
+ FT_Outline_Transform(&slot->outline, &mat2);
+
+ FT_Vector vector;
+
+ /* The matrix transformation may alter these four metrics attributes as well.
+ * As this is a const function, it is impossible to overwrite the attributes here,
+ * so they are commented out.
+ * Fortunately, in the most common cases (fake oblique), they are not modified.
+ */
+ /*
+ vector.x = 0;
+ vector.y = face->size->metrics.descender;
+ FT_Vector_Transform (&vector, &mat2);
+ std::cout << metrics.descender << " " <<vector.y << " metrics.descender\n";
+
+ vector.x = 0;
+ vector.y = face->size->metrics.ascender;
+ FT_Vector_Transform (&vector, &mat2);
+ std::cout << metrics.ascender<< " " <<vector.y << " metrics.ascender\n";
+
+ vector.x = 0;
+ vector.y = face->size->metrics.height;
+ FT_Vector_Transform (&vector, &mat2);
+ std::cout << metrics.height<< " " <<vector.y << " metrics.height\n";
+
+ //This is further dependent on FC_CHAR_WIDTH (see libXft)
+ vector.x = face->size->metrics.max_advance;
+ vector.y = 0;
+ FT_Vector_Transform (&vector, &mat2);
+ std::cout << metrics.max_advance << " " <<vector.x << " metrics.max_advance\n";
+ */
+
+ int xc, yc;
+ left = right = top = bottom = 0;
+ for(xc = 0; xc <= 1; xc ++) {
+ for(yc = 0; yc <= 1; yc++) {
+ vector.x = slot->metrics.horiBearingX + xc * slot->metrics.width;
+ vector.y = slot->metrics.horiBearingY - yc * slot->metrics.height;
+ FT_Vector_Transform(&vector, &mat2);
+ if(xc == 0 && yc == 0) {
+ left = right = vector.x;
+ top = bottom = vector.y;
+ } else {
+ if(left > vector.x) left = vector.x;
+ if(right < vector.x) right = vector.x;
+ if(bottom > vector.y) bottom = vector.y;
+ if(top < vector.y) top = vector.y;
+ }
+
+ }
+ }
+ left = FLOOR(left);
+ right = CEIL(right);
+ bottom = FLOOR(bottom);
+ top = CEIL(top);
+ }
+
#ifndef QT_NO_XRENDER
XGlyphInfo info;
#else
@@ -1199,6 +1283,12 @@
if (g->format != FT_GLYPH_FORMAT_OUTLINE)
continue;
+#if HAVE_FT_GLYPHSLOT_EMBOLDEN
+ if (embolden && (face->style_flags & FT_STYLE_FLAG_BOLD) == 0) {
+ FT_GlyphSlot_Embolden (g);
+ }
+#endif
+
// convert the outline to a painter path
int i = 0;
for (int c = 0; c < g->outline.n_contours; ++c) {
Index: src/gui/text/qfontengine_x11_p.h
===================================================================
--- src/gui/text/qfontengine_x11_p.h (revision 463892)
+++ src/gui/text/qfontengine_x11_p.h (working copy)
@@ -193,6 +193,9 @@
int ysize;
bool antialias;
bool outline_drawing;
+#ifdef FC_EMBOLDEN
+ bool embolden;
+#endif
int subpixel;
public:
Index: src/gui/text/qfontdatabase_x11.cpp
===================================================================
--- src/gui/text/qfontdatabase_x11.cpp (revision 463892)
+++ src/gui/text/qfontdatabase_x11.cpp (working copy)
@@ -1240,9 +1240,25 @@
QtFontStyle::Key key = style->key;
+ // does this style have a bold equivalent?
+ key.weight = QFont::Bold;
+ QtFontStyle *equiv = foundry->style(key);
+ if (!equiv) {
+ // let's fake one...
+ equiv = foundry->style(key, true);
+ equiv->smoothScalable = true;
+
+ QtFontSize *equiv_size = equiv->pixelSize(SMOOTH_SCALABLE, true);
+ QtFontEncoding *equiv_enc = equiv_size->encodingID(-1, 0, 0, 0, 0, true);
+
+ // keep the same pitch
+ equiv_enc->pitch = enc->pitch;
+ key.weight = QFont::Normal;
+ }
+
// does this style have an italic equivalent?
key.style = QFont::StyleItalic;
- QtFontStyle *equiv = foundry->style(key);
+ equiv = foundry->style(key);
if (equiv) continue;
// does this style have an oblique equivalent?
@@ -1421,7 +1437,6 @@
FcResult result;
FcFontSet *fs = FcFontSort(0, pattern, FcTrue, 0, &result);
- FcPatternDestroy(pattern);
if (!fs)
return 0;
@@ -1501,6 +1516,14 @@
} else {
// create a multi engine for the fontset fontconfig gave us
FcFontSet *fontSet = FcFontSetCreate();
+ // the original pattern should be added rather than the return
+ // value from FcFontSort, for addPatternProps can not add
+ // all necessary pattern props: such as the Matrix which is
+ // essential for the fake oblique support and embold settings
+ // specified in fonts.conf
+ FcFontSetAdd(fontSet, pattern);
+ pattern = 0;
+#if 0
for (int i = 0; i < fs->nfont; ++i) {
FcPattern *pattern = FcPatternDuplicate(fs->fonts[i]);
// add properties back in as the font selected from the
@@ -1508,11 +1531,14 @@
addPatternProps(pattern, key, false, true, fp, request, script);
FcFontSetAdd(fontSet, pattern);
}
+#endif
fe = new QFontEngineMultiFT(fontSet, fp->screen);
fe->fontDef = request;
}
+ if(pattern)
+ FcPatternDestroy(pattern);
FcFontSetDestroy(fs);
return fe;
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic