src/gui/text/qfontengine.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
child 7 f7bc934e204c
child 18 2f34d5167611
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
   183     glyphFormat = -1;
   183     glyphFormat = -1;
   184 }
   184 }
   185 
   185 
   186 QFontEngine::~QFontEngine()
   186 QFontEngine::~QFontEngine()
   187 {
   187 {
   188     for (GlyphPointerHash::const_iterator it = m_glyphPointerHash.constBegin(),
   188     for (QLinkedList<GlyphCacheEntry>::const_iterator it = m_glyphCaches.constBegin(),
   189             end = m_glyphPointerHash.constEnd(); it != end; ++it) {
   189             end = m_glyphCaches.constEnd(); it != end; ++it) {
   190         for (QList<QFontEngineGlyphCache*>::const_iterator it2 = it.value().constBegin(),
   190         delete it->cache;
   191                 end2 = it.value().constEnd(); it2 != end2; ++it2) {
   191     }
   192             delete *it2;
   192     m_glyphCaches.clear();
   193         }
       
   194     }
       
   195     m_glyphPointerHash.clear();
       
   196     for (GlyphIntHash::const_iterator it = m_glyphIntHash.constBegin(),
       
   197             end = m_glyphIntHash.constEnd(); it != end; ++it) {
       
   198         for (QList<QFontEngineGlyphCache*>::const_iterator it2 = it.value().constBegin(),
       
   199                 end2 = it.value().constEnd(); it2 != end2; ++it2) {
       
   200             delete *it2;
       
   201         }
       
   202     }
       
   203     m_glyphIntHash.clear();
       
   204     qHBFreeFace(hbFace);
   193     qHBFreeFace(hbFace);
   205 }
   194 }
   206 
   195 
   207 QFixed QFontEngine::lineThickness() const
   196 QFixed QFontEngine::lineThickness() const
   208 {
   197 {
   711     if (!getSfntTableData(tag, reinterpret_cast<uchar *>(table.data()), &len))
   700     if (!getSfntTableData(tag, reinterpret_cast<uchar *>(table.data()), &len))
   712         return QByteArray();
   701         return QByteArray();
   713     return table;
   702     return table;
   714 }
   703 }
   715 
   704 
   716 void QFontEngine::expireGlyphCache()
       
   717 {
       
   718     if (m_glyphCacheQueue.count() > 10) { // hold only 10 caches in memory.
       
   719         QFontEngineGlyphCache *old = m_glyphCacheQueue.takeFirst();
       
   720         // remove the value from either of our hashes
       
   721         for (GlyphPointerHash::iterator i = m_glyphPointerHash.begin(); i != m_glyphPointerHash.end(); ++i) {
       
   722             QList<QFontEngineGlyphCache *> list = i.value();
       
   723             if (list.removeAll(old)) {
       
   724                 if (list.isEmpty())
       
   725                     m_glyphPointerHash.remove(i.key());
       
   726                 else
       
   727                     m_glyphPointerHash.insert(i.key(), list);
       
   728                 break;
       
   729             }
       
   730         }
       
   731         for (GlyphIntHash::iterator i = m_glyphIntHash.begin(); i != m_glyphIntHash.end(); ++i) {
       
   732             QList<QFontEngineGlyphCache *> list = i.value();
       
   733             if (list.removeAll(old)) {
       
   734                 if (list.isEmpty())
       
   735                     m_glyphIntHash.remove(i.key());
       
   736                 else
       
   737                     m_glyphIntHash.insert(i.key(), list);
       
   738                 break;
       
   739             }
       
   740         }
       
   741         delete old;
       
   742     }
       
   743 }
       
   744 
       
   745 void QFontEngine::setGlyphCache(void *key, QFontEngineGlyphCache *data)
   705 void QFontEngine::setGlyphCache(void *key, QFontEngineGlyphCache *data)
   746 {
   706 {
   747     Q_ASSERT(data);
   707     Q_ASSERT(data);
   748     QList<QFontEngineGlyphCache*> items = m_glyphPointerHash.value(key);
   708 
   749 
   709     GlyphCacheEntry entry = { key, data };
   750     for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) {
   710     if (m_glyphCaches.contains(entry))
   751         QFontEngineGlyphCache *c = *it;
   711         return;
   752         if (qtransform_equals_no_translate(c->m_transform, data->m_transform)) {
   712 
   753             if (c == data)
   713     // Limit the glyph caches to 4. This covers all 90 degree rotations and limits
   754                 return;
   714     // memory use when there is continous or random rotation
   755             items.removeAll(c);
   715     if (m_glyphCaches.size() == 4)
   756             delete c;
   716         delete m_glyphCaches.takeLast().cache;
   757             break;
   717 
   758         }
   718     m_glyphCaches.push_front(entry);
   759     }
   719 
   760     items.append(data);
   720 }
   761     m_glyphPointerHash.insert(key, items);
   721 
   762 
   722 QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const
   763     m_glyphCacheQueue.append(data);
   723 {
   764     expireGlyphCache();
   724     for (QLinkedList<GlyphCacheEntry>::const_iterator it = m_glyphCaches.constBegin(), end = m_glyphCaches.constEnd(); it != end; ++it) {
   765 }
   725         QFontEngineGlyphCache *c = it->cache;
   766 
   726         if (key == it->context
   767 void QFontEngine::setGlyphCache(QFontEngineGlyphCache::Type key, QFontEngineGlyphCache *data)
   727             && type == c->cacheType()
   768 {
   728             && qtransform_equals_no_translate(c->m_transform, transform)) {
   769     Q_ASSERT(data);
       
   770     QList<QFontEngineGlyphCache*> items = m_glyphIntHash.value(key);
       
   771 
       
   772     for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) {
       
   773         QFontEngineGlyphCache *c = *it;
       
   774         if (qtransform_equals_no_translate(c->m_transform, data->m_transform)) {
       
   775             if (c == data)
       
   776                 return;
       
   777             items.removeAll(c);
       
   778             delete c;
       
   779             break;
       
   780         }
       
   781     }
       
   782     items.append(data);
       
   783     m_glyphIntHash.insert(key, items);
       
   784 
       
   785     m_glyphCacheQueue.append(data);
       
   786     expireGlyphCache();
       
   787 }
       
   788 
       
   789 QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, const QTransform &transform) const
       
   790 {
       
   791     QList<QFontEngineGlyphCache*> items = m_glyphPointerHash.value(key);
       
   792 
       
   793     for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) {
       
   794         QFontEngineGlyphCache *c = *it;
       
   795         if (qtransform_equals_no_translate(c->m_transform, transform)) {
       
   796             m_glyphCacheQueue.removeAll(c); // last used, move it up
       
   797             m_glyphCacheQueue.append(c);
       
   798             return c;
       
   799         }
       
   800     }
       
   801     return 0;
       
   802 }
       
   803 
       
   804 QFontEngineGlyphCache *QFontEngine::glyphCache(QFontEngineGlyphCache::Type key, const QTransform &transform) const
       
   805 {
       
   806     QList<QFontEngineGlyphCache*> items = m_glyphIntHash.value(key);
       
   807 
       
   808     for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) {
       
   809         QFontEngineGlyphCache *c = *it;
       
   810         if (qtransform_equals_no_translate(c->m_transform, transform)) {
       
   811             m_glyphCacheQueue.removeAll(c); // last used, move it up
       
   812             m_glyphCacheQueue.append(c);
       
   813             return c;
   729             return c;
   814         }
   730         }
   815     }
   731     }
   816     return 0;
   732     return 0;
   817 }
   733 }
  1368 
  1284 
  1369     int glyph_pos = 0;
  1285     int glyph_pos = 0;
  1370     for (int i = 0; i < len; ++i) {
  1286     for (int i = 0; i < len; ++i) {
  1371         bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1
  1287         bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1
  1372                           && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
  1288                           && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
  1373         if (glyphs->glyphs[glyph_pos] == 0) {
  1289 
  1374 
  1290         if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) {
  1375             QGlyphLayoutInstance tmp = glyphs->instance(glyph_pos);
  1291             QGlyphLayoutInstance tmp = glyphs->instance(glyph_pos);
  1376             for (int x = 1; x < engines.size(); ++x) {
  1292             for (int x = 1; x < engines.size(); ++x) {
  1377                 QFontEngine *engine = engines.at(x);
  1293                 QFontEngine *engine = engines.at(x);
  1378                 if (!engine) {
  1294                 if (!engine) {
  1379                     const_cast<QFontEngineMulti *>(this)->loadEngine(x);
  1295                     const_cast<QFontEngineMulti *>(this)->loadEngine(x);