23 | | ** In addition, as a special exception, Nokia gives you certain |
24 | | ** additional rights. These rights are described in the Nokia Qt LGPL |
25 | | ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this |
26 | | ** package. |
| 24 | ** In addition, as a special exception, Nokia gives you certain additional |
| 25 | ** rights. These rights are described in the Nokia Qt LGPL Exception |
| 26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
194 | | for (GlyphPointerHash::iterator it = m_glyphPointerHash.begin(), end = m_glyphPointerHash.end(); |
195 | | it != end; ++it) { |
196 | | for (QList<QFontEngineGlyphCache*>::iterator it2 = it.value().begin(), end2 = it.value().end(); |
197 | | it2 != end2; ++it2) |
198 | | delete *it2; |
199 | | } |
200 | | m_glyphPointerHash.clear(); |
201 | | for (GlyphIntHash::iterator it = m_glyphIntHash.begin(), end = m_glyphIntHash.end(); |
202 | | it != end; ++it) { |
203 | | for (QList<QFontEngineGlyphCache*>::iterator it2 = it.value().begin(), end2 = it.value().end(); |
204 | | it2 != end2; ++it2) |
205 | | delete *it2; |
206 | | } |
207 | | m_glyphIntHash.clear(); |
| 188 | for (QLinkedList<GlyphCacheEntry>::const_iterator it = m_glyphCaches.constBegin(), |
| 189 | end = m_glyphCaches.constEnd(); it != end; ++it) { |
| 190 | delete it->cache; |
| 191 | } |
| 192 | m_glyphCaches.clear(); |
680 | | void QFontEngine::expireGlyphCache() |
681 | | { |
682 | | if (m_glyphCacheQueue.count() > 10) { // hold only 10 caches in memory. |
683 | | QFontEngineGlyphCache *old = m_glyphCacheQueue.takeFirst(); |
684 | | // remove the value from either of our hashes |
685 | | for (GlyphPointerHash::iterator i = m_glyphPointerHash.begin(); i != m_glyphPointerHash.end(); ++i) { |
686 | | QList<QFontEngineGlyphCache *> list = i.value(); |
687 | | if (list.removeAll(old)) { |
688 | | if (list.isEmpty()) |
689 | | m_glyphPointerHash.remove(i.key()); |
690 | | else |
691 | | m_glyphPointerHash.insert(i.key(), list); |
692 | | break; |
693 | | } |
694 | | } |
695 | | for (GlyphIntHash::iterator i = m_glyphIntHash.begin(); i != m_glyphIntHash.end(); ++i) { |
696 | | QList<QFontEngineGlyphCache *> list = i.value(); |
697 | | if (list.removeAll(old)) { |
698 | | if (list.isEmpty()) |
699 | | m_glyphIntHash.remove(i.key()); |
700 | | else |
701 | | m_glyphIntHash.insert(i.key(), list); |
702 | | break; |
703 | | } |
704 | | } |
705 | | delete old; |
706 | | } |
707 | | } |
708 | | |
712 | | QList<QFontEngineGlyphCache*> items = m_glyphPointerHash.value(key); |
713 | | |
714 | | for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) { |
715 | | QFontEngineGlyphCache *c = *it; |
716 | | if (qtransform_equals_no_translate(c->m_transform, data->m_transform)) { |
717 | | if (c == data) |
718 | | return; |
719 | | items.removeAll(c); |
720 | | delete c; |
721 | | break; |
722 | | } |
723 | | } |
724 | | items.append(data); |
725 | | m_glyphPointerHash.insert(key, items); |
726 | | |
727 | | m_glyphCacheQueue.append(data); |
728 | | expireGlyphCache(); |
729 | | } |
730 | | |
731 | | void QFontEngine::setGlyphCache(QFontEngineGlyphCache::Type key, QFontEngineGlyphCache *data) |
732 | | { |
733 | | Q_ASSERT(data); |
734 | | QList<QFontEngineGlyphCache*> items = m_glyphIntHash.value(key); |
735 | | |
736 | | for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) { |
737 | | QFontEngineGlyphCache *c = *it; |
738 | | if (qtransform_equals_no_translate(c->m_transform, data->m_transform)) { |
739 | | if (c == data) |
740 | | return; |
741 | | items.removeAll(c); |
742 | | delete c; |
743 | | break; |
744 | | } |
745 | | } |
746 | | items.append(data); |
747 | | m_glyphIntHash.insert(key, items); |
748 | | |
749 | | m_glyphCacheQueue.append(data); |
750 | | expireGlyphCache(); |
751 | | } |
752 | | |
753 | | QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, const QTransform &transform) const |
754 | | { |
755 | | QList<QFontEngineGlyphCache*> items = m_glyphPointerHash.value(key); |
756 | | |
757 | | for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) { |
758 | | QFontEngineGlyphCache *c = *it; |
759 | | if (qtransform_equals_no_translate(c->m_transform, transform)) { |
760 | | m_glyphCacheQueue.removeAll(c); // last used, move it up |
761 | | m_glyphCacheQueue.append(c); |
| 708 | |
| 709 | GlyphCacheEntry entry = { key, data }; |
| 710 | if (m_glyphCaches.contains(entry)) |
| 711 | return; |
| 712 | |
| 713 | // Limit the glyph caches to 4. This covers all 90 degree rotations and limits |
| 714 | // memory use when there is continous or random rotation |
| 715 | if (m_glyphCaches.size() == 4) |
| 716 | delete m_glyphCaches.takeLast().cache; |
| 717 | |
| 718 | m_glyphCaches.push_front(entry); |
| 719 | |
| 720 | } |
| 721 | |
| 722 | QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const |
| 723 | { |
| 724 | for (QLinkedList<GlyphCacheEntry>::const_iterator it = m_glyphCaches.constBegin(), end = m_glyphCaches.constEnd(); it != end; ++it) { |
| 725 | QFontEngineGlyphCache *c = it->cache; |
| 726 | if (key == it->context |
| 727 | && type == c->cacheType() |
| 728 | && qtransform_equals_no_translate(c->m_transform, transform)) { |
768 | | QFontEngineGlyphCache *QFontEngine::glyphCache(QFontEngineGlyphCache::Type key, const QTransform &transform) const |
769 | | { |
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, transform)) { |
775 | | m_glyphCacheQueue.removeAll(c); // last used, move it up |
776 | | m_glyphCacheQueue.append(c); |
777 | | return c; |
778 | | } |
779 | | } |
780 | | return 0; |
781 | | } |
782 | | |
783 | | #if defined(Q_WS_WIN) || defined(Q_WS_PM) || defined(Q_WS_X11) || defined(Q_WS_QWS) |
| 735 | #if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) || defined(Q_WS_PM) || defined(Q_WS_PM) |