src/gui/text/qfontengine_ft.cpp
changeset 30 5dc02b23752f
parent 18 2f34d5167611
child 33 3e2da88830cd
--- a/src/gui/text/qfontengine_ft.cpp	Wed Jun 23 19:07:03 2010 +0300
+++ b/src/gui/text/qfontengine_ft.cpp	Tue Jul 06 15:10:48 2010 +0300
@@ -619,7 +619,7 @@
     transform = false;
     antialias = true;
     freetype = 0;
-    default_load_flags = 0;
+    default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
     default_hint_style = HintNone;
     subpixelType = Subpixel_None;
     lcdFilterType = 0;
@@ -746,7 +746,7 @@
 
 QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph) const
 {
-    Glyph *g = set->glyph_data.value(glyph);
+    Glyph *g = set->getGlyph(glyph);
     if (g)
         return g;
 
@@ -858,10 +858,10 @@
         }
     }
 
-    Glyph *g = set->glyph_data.value(glyph);
+    Glyph *g = set->getGlyph(glyph);
     if (g && g->format == format) {
         if (uploadToServer && !g->uploadedToServer) {
-            set->glyph_data[glyph] = 0;
+            set->setGlyph(glyph, 0);
             delete g;
             g = 0;
         } else {
@@ -1158,7 +1158,7 @@
         uploadGlyphToServer(set, glyph, g, &info, glyph_buffer_size);
     }
 
-    set->glyph_data[glyph] = g;
+    set->setGlyph(glyph, g);
 
     return g;
 }
@@ -1368,7 +1368,7 @@
 
     if (!gs) {
         // don't try to load huge fonts
-        bool draw_as_outline = fontDef.pixelSize * qSqrt(matrix.det()) >= 64;
+        bool draw_as_outline = fontDef.pixelSize * qSqrt(qAbs(matrix.det())) >= 64;
         if (draw_as_outline)
             return 0;
 
@@ -1381,8 +1381,7 @@
         }
         gs = &transformedGlyphSets[0];
 
-        qDeleteAll(gs->glyph_data);
-        gs->glyph_data.clear();
+        gs->clear();
 
         gs->id = allocateServerGlyphSet();
 
@@ -1398,7 +1397,7 @@
     FT_Face face = 0;
 
     for (int i = 0; i < num_glyphs; ++i) {
-        Glyph *glyph = gs->glyph_data.value(glyphs[i]);
+        Glyph *glyph = gs->getGlyph(glyphs[i]);
         if (glyph == 0 || glyph->format != format) {
             if (!face) {
                 face = lockFace();
@@ -1635,7 +1634,7 @@
     FT_Face face = 0;
     if (flags & QTextEngine::DesignMetrics) {
         for (int i = 0; i < glyphs->numGlyphs; i++) {
-            Glyph *g = defaultGlyphSet.glyph_data.value(glyphs->glyphs[i]);
+            Glyph *g = defaultGlyphSet.getGlyph(glyphs->glyphs[i]);
             if (g) {
                 glyphs->advances_x[i] = QFixed::fromFixed(g->linearAdvance);
             } else {
@@ -1648,7 +1647,7 @@
         }
     } else {
         for (int i = 0; i < glyphs->numGlyphs; i++) {
-            Glyph *g = defaultGlyphSet.glyph_data.value(glyphs->glyphs[i]);
+            Glyph *g = defaultGlyphSet.getGlyph(glyphs->glyphs[i]);
             if (g) {
                 glyphs->advances_x[i] = QFixed(g->advance);
             } else {
@@ -1677,7 +1676,7 @@
     QFixed ymax = 0;
     QFixed xmax = 0;
     for (int i = 0; i < glyphs.numGlyphs; i++) {
-        Glyph *g = defaultGlyphSet.glyph_data.value(glyphs.glyphs[i]);
+        Glyph *g = defaultGlyphSet.getGlyph(glyphs.glyphs[i]);
         if (!g) {
             if (!face)
                 face = lockFace();
@@ -1719,7 +1718,7 @@
 {
     FT_Face face = 0;
     glyph_metrics_t overall;
-    Glyph *g = defaultGlyphSet.glyph_data.value(glyph);
+    Glyph *g = defaultGlyphSet.getGlyph(glyph);
     if (!g) {
         face = lockFace();
         g = loadGlyph(glyph, Format_None, true);
@@ -1783,8 +1782,7 @@
                 transformedGlyphSets.prepend(QGlyphSet());
             }
             glyphSet = &transformedGlyphSets[0];
-            qDeleteAll(glyphSet->glyph_data);
-            glyphSet->glyph_data.clear();
+            glyphSet->clear();
             glyphSet->id = allocateServerGlyphSet();
             glyphSet->transformationMatrix = m;
         }
@@ -1792,7 +1790,7 @@
     } else {
         glyphSet = &defaultGlyphSet;
     }
-    Glyph * g = glyphSet->glyph_data.value(glyph);
+    Glyph * g = glyphSet->getGlyph(glyph);
     if (!g) {
         face = lockFace();
         g = loadGlyphMetrics(glyphSet, glyph);
@@ -1881,7 +1879,7 @@
 
 void QFontEngineFT::removeGlyphFromCache(glyph_t glyph)
 {
-    delete defaultGlyphSet.glyph_data.take(glyph);
+    defaultGlyphSet.removeGlyphFromCache(glyph);
 }
 
 int QFontEngineFT::glyphCount() const
@@ -1937,11 +1935,53 @@
     transformationMatrix.yy = 0x10000;
     transformationMatrix.xy = 0;
     transformationMatrix.yx = 0;
+    memset(fast_glyph_data, 0, sizeof(fast_glyph_data));
+    fast_glyph_count = 0;
 }
 
 QFontEngineFT::QGlyphSet::~QGlyphSet()
 {
+    clear();
+}
+
+void QFontEngineFT::QGlyphSet::clear()
+{
+    if (fast_glyph_count > 0) {
+        for (int i = 0; i < 256; ++i) {
+            if (fast_glyph_data[i]) {
+                delete fast_glyph_data[i];
+                fast_glyph_data[i] = 0;
+            }
+        }
+        fast_glyph_count = 0;
+    }
     qDeleteAll(glyph_data);
+    glyph_data.clear();
+}
+
+void QFontEngineFT::QGlyphSet::removeGlyphFromCache(int index)
+{
+    if (index < 256) {
+        if (fast_glyph_data[index]) {
+            delete fast_glyph_data[index];
+            fast_glyph_data[index] = 0;
+            if (fast_glyph_count > 0)
+                --fast_glyph_count;
+        }
+    } else {
+        delete glyph_data.take(index);
+    }
+}
+
+void QFontEngineFT::QGlyphSet::setGlyph(int index, Glyph *glyph)
+{
+    if (index < 256) {
+        if (!fast_glyph_data[index])
+            ++fast_glyph_count;
+        fast_glyph_data[index] = glyph;
+    } else {
+        glyph_data.insert(index, glyph);
+    }
 }
 
 unsigned long QFontEngineFT::allocateServerGlyphSet()