src/gui/text/qfontengine_ft.cpp
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
child 33 3e2da88830cd
equal deleted inserted replaced
27:93b982ccede2 31:5daf16870df6
   617     cache_cost = 100;
   617     cache_cost = 100;
   618     kerning_pairs_loaded = false;
   618     kerning_pairs_loaded = false;
   619     transform = false;
   619     transform = false;
   620     antialias = true;
   620     antialias = true;
   621     freetype = 0;
   621     freetype = 0;
   622     default_load_flags = 0;
   622     default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
   623     default_hint_style = HintNone;
   623     default_hint_style = HintNone;
   624     subpixelType = Subpixel_None;
   624     subpixelType = Subpixel_None;
   625     lcdFilterType = 0;
   625     lcdFilterType = 0;
   626 #if defined(FT_LCD_FILTER_H)
   626 #if defined(FT_LCD_FILTER_H)
   627     lcdFilterType = (int)((quintptr) FT_LCD_FILTER_DEFAULT);
   627     lcdFilterType = (int)((quintptr) FT_LCD_FILTER_DEFAULT);
   744     return true;
   744     return true;
   745 }
   745 }
   746 
   746 
   747 QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph) const
   747 QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph) const
   748 {
   748 {
   749     Glyph *g = set->glyph_data.value(glyph);
   749     Glyph *g = set->getGlyph(glyph);
   750     if (g)
   750     if (g)
   751         return g;
   751         return g;
   752 
   752 
   753     int load_flags = FT_LOAD_DEFAULT | default_load_flags;
   753     int load_flags = FT_LOAD_DEFAULT | default_load_flags;
   754     if (set->outline_drawing)
   754     if (set->outline_drawing)
   856         } else {
   856         } else {
   857             format = Format_Mono;
   857             format = Format_Mono;
   858         }
   858         }
   859     }
   859     }
   860 
   860 
   861     Glyph *g = set->glyph_data.value(glyph);
   861     Glyph *g = set->getGlyph(glyph);
   862     if (g && g->format == format) {
   862     if (g && g->format == format) {
   863         if (uploadToServer && !g->uploadedToServer) {
   863         if (uploadToServer && !g->uploadedToServer) {
   864             set->glyph_data[glyph] = 0;
   864             set->setGlyph(glyph, 0);
   865             delete g;
   865             delete g;
   866             g = 0;
   866             g = 0;
   867         } else {
   867         } else {
   868             return g;
   868             return g;
   869         }
   869         }
  1156 
  1156 
  1157     if (uploadToServer) {
  1157     if (uploadToServer) {
  1158         uploadGlyphToServer(set, glyph, g, &info, glyph_buffer_size);
  1158         uploadGlyphToServer(set, glyph, g, &info, glyph_buffer_size);
  1159     }
  1159     }
  1160 
  1160 
  1161     set->glyph_data[glyph] = g;
  1161     set->setGlyph(glyph, g);
  1162 
  1162 
  1163     return g;
  1163     return g;
  1164 }
  1164 }
  1165 
  1165 
  1166 bool QFontEngineFT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *g, GlyphInfo *info, int glyphDataSize) const
  1166 bool QFontEngineFT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph *g, GlyphInfo *info, int glyphDataSize) const
  1366         }
  1366         }
  1367     }
  1367     }
  1368 
  1368 
  1369     if (!gs) {
  1369     if (!gs) {
  1370         // don't try to load huge fonts
  1370         // don't try to load huge fonts
  1371         bool draw_as_outline = fontDef.pixelSize * qSqrt(matrix.det()) >= 64;
  1371         bool draw_as_outline = fontDef.pixelSize * qSqrt(qAbs(matrix.det())) >= 64;
  1372         if (draw_as_outline)
  1372         if (draw_as_outline)
  1373             return 0;
  1373             return 0;
  1374 
  1374 
  1375         // don't cache more than 10 transformations
  1375         // don't cache more than 10 transformations
  1376         if (transformedGlyphSets.count() >= 10) {
  1376         if (transformedGlyphSets.count() >= 10) {
  1379         } else {
  1379         } else {
  1380             transformedGlyphSets.prepend(QGlyphSet());
  1380             transformedGlyphSets.prepend(QGlyphSet());
  1381         }
  1381         }
  1382         gs = &transformedGlyphSets[0];
  1382         gs = &transformedGlyphSets[0];
  1383 
  1383 
  1384         qDeleteAll(gs->glyph_data);
  1384         gs->clear();
  1385         gs->glyph_data.clear();
       
  1386 
  1385 
  1387         gs->id = allocateServerGlyphSet();
  1386         gs->id = allocateServerGlyphSet();
  1388 
  1387 
  1389         gs->transformationMatrix = m;
  1388         gs->transformationMatrix = m;
  1390         gs->outline_drawing = draw_as_outline;
  1389         gs->outline_drawing = draw_as_outline;
  1396 bool QFontEngineFT::loadGlyphs(QGlyphSet *gs, glyph_t *glyphs, int num_glyphs, GlyphFormat format)
  1395 bool QFontEngineFT::loadGlyphs(QGlyphSet *gs, glyph_t *glyphs, int num_glyphs, GlyphFormat format)
  1397 {
  1396 {
  1398     FT_Face face = 0;
  1397     FT_Face face = 0;
  1399 
  1398 
  1400     for (int i = 0; i < num_glyphs; ++i) {
  1399     for (int i = 0; i < num_glyphs; ++i) {
  1401         Glyph *glyph = gs->glyph_data.value(glyphs[i]);
  1400         Glyph *glyph = gs->getGlyph(glyphs[i]);
  1402         if (glyph == 0 || glyph->format != format) {
  1401         if (glyph == 0 || glyph->format != format) {
  1403             if (!face) {
  1402             if (!face) {
  1404                 face = lockFace();
  1403                 face = lockFace();
  1405                 FT_Matrix m = matrix;
  1404                 FT_Matrix m = matrix;
  1406                 FT_Matrix_Multiply(&gs->transformationMatrix, &m);
  1405                 FT_Matrix_Multiply(&gs->transformationMatrix, &m);
  1633 void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
  1632 void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
  1634 {
  1633 {
  1635     FT_Face face = 0;
  1634     FT_Face face = 0;
  1636     if (flags & QTextEngine::DesignMetrics) {
  1635     if (flags & QTextEngine::DesignMetrics) {
  1637         for (int i = 0; i < glyphs->numGlyphs; i++) {
  1636         for (int i = 0; i < glyphs->numGlyphs; i++) {
  1638             Glyph *g = defaultGlyphSet.glyph_data.value(glyphs->glyphs[i]);
  1637             Glyph *g = defaultGlyphSet.getGlyph(glyphs->glyphs[i]);
  1639             if (g) {
  1638             if (g) {
  1640                 glyphs->advances_x[i] = QFixed::fromFixed(g->linearAdvance);
  1639                 glyphs->advances_x[i] = QFixed::fromFixed(g->linearAdvance);
  1641             } else {
  1640             } else {
  1642                 if (!face)
  1641                 if (!face)
  1643                     face = lockFace();
  1642                     face = lockFace();
  1646             }
  1645             }
  1647             glyphs->advances_y[i] = 0;
  1646             glyphs->advances_y[i] = 0;
  1648         }
  1647         }
  1649     } else {
  1648     } else {
  1650         for (int i = 0; i < glyphs->numGlyphs; i++) {
  1649         for (int i = 0; i < glyphs->numGlyphs; i++) {
  1651             Glyph *g = defaultGlyphSet.glyph_data.value(glyphs->glyphs[i]);
  1650             Glyph *g = defaultGlyphSet.getGlyph(glyphs->glyphs[i]);
  1652             if (g) {
  1651             if (g) {
  1653                 glyphs->advances_x[i] = QFixed(g->advance);
  1652                 glyphs->advances_x[i] = QFixed(g->advance);
  1654             } else {
  1653             } else {
  1655                 if (!face)
  1654                 if (!face)
  1656                     face = lockFace();
  1655                     face = lockFace();
  1675     overall.height = ascent() + descent() + 1;
  1674     overall.height = ascent() + descent() + 1;
  1676 
  1675 
  1677     QFixed ymax = 0;
  1676     QFixed ymax = 0;
  1678     QFixed xmax = 0;
  1677     QFixed xmax = 0;
  1679     for (int i = 0; i < glyphs.numGlyphs; i++) {
  1678     for (int i = 0; i < glyphs.numGlyphs; i++) {
  1680         Glyph *g = defaultGlyphSet.glyph_data.value(glyphs.glyphs[i]);
  1679         Glyph *g = defaultGlyphSet.getGlyph(glyphs.glyphs[i]);
  1681         if (!g) {
  1680         if (!g) {
  1682             if (!face)
  1681             if (!face)
  1683                 face = lockFace();
  1682                 face = lockFace();
  1684             g = loadGlyph(glyphs.glyphs[i], Format_None, true);
  1683             g = loadGlyph(glyphs.glyphs[i], Format_None, true);
  1685         }
  1684         }
  1717 
  1716 
  1718 glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph)
  1717 glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph)
  1719 {
  1718 {
  1720     FT_Face face = 0;
  1719     FT_Face face = 0;
  1721     glyph_metrics_t overall;
  1720     glyph_metrics_t overall;
  1722     Glyph *g = defaultGlyphSet.glyph_data.value(glyph);
  1721     Glyph *g = defaultGlyphSet.getGlyph(glyph);
  1723     if (!g) {
  1722     if (!g) {
  1724         face = lockFace();
  1723         face = lockFace();
  1725         g = loadGlyph(glyph, Format_None, true);
  1724         g = loadGlyph(glyph, Format_None, true);
  1726     }
  1725     }
  1727     if (g) {
  1726     if (g) {
  1781                 freeServerGlyphSet(transformedGlyphSets.at(0).id);
  1780                 freeServerGlyphSet(transformedGlyphSets.at(0).id);
  1782             } else {
  1781             } else {
  1783                 transformedGlyphSets.prepend(QGlyphSet());
  1782                 transformedGlyphSets.prepend(QGlyphSet());
  1784             }
  1783             }
  1785             glyphSet = &transformedGlyphSets[0];
  1784             glyphSet = &transformedGlyphSets[0];
  1786             qDeleteAll(glyphSet->glyph_data);
  1785             glyphSet->clear();
  1787             glyphSet->glyph_data.clear();
       
  1788             glyphSet->id = allocateServerGlyphSet();
  1786             glyphSet->id = allocateServerGlyphSet();
  1789             glyphSet->transformationMatrix = m;
  1787             glyphSet->transformationMatrix = m;
  1790         }
  1788         }
  1791         Q_ASSERT(glyphSet);
  1789         Q_ASSERT(glyphSet);
  1792     } else {
  1790     } else {
  1793         glyphSet = &defaultGlyphSet;
  1791         glyphSet = &defaultGlyphSet;
  1794     }
  1792     }
  1795     Glyph * g = glyphSet->glyph_data.value(glyph);
  1793     Glyph * g = glyphSet->getGlyph(glyph);
  1796     if (!g) {
  1794     if (!g) {
  1797         face = lockFace();
  1795         face = lockFace();
  1798         g = loadGlyphMetrics(glyphSet, glyph);
  1796         g = loadGlyphMetrics(glyphSet, glyph);
  1799     }
  1797     }
  1800 
  1798 
  1879     return img;
  1877     return img;
  1880 }
  1878 }
  1881 
  1879 
  1882 void QFontEngineFT::removeGlyphFromCache(glyph_t glyph)
  1880 void QFontEngineFT::removeGlyphFromCache(glyph_t glyph)
  1883 {
  1881 {
  1884     delete defaultGlyphSet.glyph_data.take(glyph);
  1882     defaultGlyphSet.removeGlyphFromCache(glyph);
  1885 }
  1883 }
  1886 
  1884 
  1887 int QFontEngineFT::glyphCount() const
  1885 int QFontEngineFT::glyphCount() const
  1888 {
  1886 {
  1889     int count = 0;
  1887     int count = 0;
  1935 {
  1933 {
  1936     transformationMatrix.xx = 0x10000;
  1934     transformationMatrix.xx = 0x10000;
  1937     transformationMatrix.yy = 0x10000;
  1935     transformationMatrix.yy = 0x10000;
  1938     transformationMatrix.xy = 0;
  1936     transformationMatrix.xy = 0;
  1939     transformationMatrix.yx = 0;
  1937     transformationMatrix.yx = 0;
       
  1938     memset(fast_glyph_data, 0, sizeof(fast_glyph_data));
       
  1939     fast_glyph_count = 0;
  1940 }
  1940 }
  1941 
  1941 
  1942 QFontEngineFT::QGlyphSet::~QGlyphSet()
  1942 QFontEngineFT::QGlyphSet::~QGlyphSet()
  1943 {
  1943 {
       
  1944     clear();
       
  1945 }
       
  1946 
       
  1947 void QFontEngineFT::QGlyphSet::clear()
       
  1948 {
       
  1949     if (fast_glyph_count > 0) {
       
  1950         for (int i = 0; i < 256; ++i) {
       
  1951             if (fast_glyph_data[i]) {
       
  1952                 delete fast_glyph_data[i];
       
  1953                 fast_glyph_data[i] = 0;
       
  1954             }
       
  1955         }
       
  1956         fast_glyph_count = 0;
       
  1957     }
  1944     qDeleteAll(glyph_data);
  1958     qDeleteAll(glyph_data);
       
  1959     glyph_data.clear();
       
  1960 }
       
  1961 
       
  1962 void QFontEngineFT::QGlyphSet::removeGlyphFromCache(int index)
       
  1963 {
       
  1964     if (index < 256) {
       
  1965         if (fast_glyph_data[index]) {
       
  1966             delete fast_glyph_data[index];
       
  1967             fast_glyph_data[index] = 0;
       
  1968             if (fast_glyph_count > 0)
       
  1969                 --fast_glyph_count;
       
  1970         }
       
  1971     } else {
       
  1972         delete glyph_data.take(index);
       
  1973     }
       
  1974 }
       
  1975 
       
  1976 void QFontEngineFT::QGlyphSet::setGlyph(int index, Glyph *glyph)
       
  1977 {
       
  1978     if (index < 256) {
       
  1979         if (!fast_glyph_data[index])
       
  1980             ++fast_glyph_count;
       
  1981         fast_glyph_data[index] = glyph;
       
  1982     } else {
       
  1983         glyph_data.insert(index, glyph);
       
  1984     }
  1945 }
  1985 }
  1946 
  1986 
  1947 unsigned long QFontEngineFT::allocateServerGlyphSet()
  1987 unsigned long QFontEngineFT::allocateServerGlyphSet()
  1948 {
  1988 {
  1949     return 0;
  1989     return 0;