Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/text/qfontengine.cpp

    r125 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information ([email protected])
     4** All rights reserved.
     5** Contact: Nokia Corporation ([email protected])
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    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.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you
     37** @nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7171}
    7272
    73 
    74 
    75 QFontEngineGlyphCache::~QFontEngineGlyphCache()
    76 {
    77 }
    78 
    7973// Harfbuzz helper functions
    8074
     
    192186QFontEngine::~QFontEngine()
    193187{
    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();
    208193    qHBFreeFace(hbFace);
    209194}
     
    241226HB_Face QFontEngine::harfbuzzFace() const
    242227{
    243     if (!hbFace)
     228    if (!hbFace)
    244229        hbFace = qHBNewFace(const_cast<QFontEngine *>(this), hb_getSFntTable);
     230
     231
    245232    return hbFace;
    246233}
     
    429416    QVarLengthArray<QFixedPoint> positions;
    430417    QVarLengthArray<glyph_t> positioned_glyphs;
    431     QTransform matrix;
    432     matrix.translate(x, y);
     418    QTransform matrix = QTransform::fromTranslate(x, y);
    433419    getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions);
    434420    addGlyphsToPath(positioned_glyphs.data(), positions.data(), positioned_glyphs.size(), path, flags);
     
    625611}
    626612
     613
     614
     615
     616
     617
     618
     619
     620
     621
     622
     623
     624
     625
     626
     627
     628
     629
     630
     631
     632
     633
     634
     635
     636
     637
     638
     639
     640
     641
     642
     643
     644
     645
     646
     647
     648
     649
     650
     651
    627652
    628653void QFontEngine::removeGlyphFromCache(glyph_t)
     
    678703}
    679704
    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 
    709705void QFontEngine::setGlyphCache(void *key, QFontEngineGlyphCache *data)
    710706{
    711707    Q_ASSERT(data);
    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
     722QFontEngineGlyphCache *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)) {
    762729            return c;
    763730        }
     
    766733}
    767734
    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)
    784736static inline QFixed kerning(int left, int right, const QFontEngine::KernPair *pairs, int numPairs)
    785737{
     
    877829    qSort(kerning_pairs);
    878830//    for (int i = 0; i < kerning_pairs.count(); ++i)
    879 //        qDebug() << "i" << i << "left_right" << hex << kerning_pairs.at(i).left_right;
     831//        qDebug() << << i << "left_right" << hex << kerning_pairs.at(i).left_right;
    880832}
    881833
     
    911863        return 0;
    912864
     865
     866
     867
     868
     869
     870
     871
     872
     873
     874
     875
    913876    int tableToUse = -1;
    914     int score = 0;
     877    int score = ;
    915878    for (int n = 0; n < numTables; ++n) {
    916879        const quint16 platformId = qFromBigEndian<quint16>(maps + 8 * n);
     
    918881        switch (platformId) {
    919882        case 0: // Unicode
    920             if (score < 4 &&
     883            if (score < &&
    921884                (platformSpecificId == 0 ||
    922885                 platformSpecificId == 2 ||
    923886                 platformSpecificId == 3)) {
    924887                tableToUse = n;
    925                 score = 4;
    926             } else if (score < 3 && platformSpecificId == 1) {
     888                score = ;
     889            } else if (score < && platformSpecificId == 1) {
    927890                tableToUse = n;
    928                 score = 3;
     891                score = ;
    929892            }
    930893            break;
    931894        case 1: // Apple
    932             if (score < 2 && platformSpecificId == 0) { // Apple Roman
     895            if (score < && platformSpecificId == 0) { // Apple Roman
    933896                tableToUse = n;
    934                 score = 2;
     897                score = ;
    935898            }
    936899            break;
     
    938901            switch (platformSpecificId) {
    939902            case 0:
    940                 if (score < 1) {
     903                symbolTable = n;
     904                if (score < Symbol) {
    941905                    tableToUse = n;
    942                     score = 1;
     906                    score = ;
    943907                }
    944908                break;
    945909            case 1:
    946                 if (score < 5) {
     910                if (score < ) {
    947911                    tableToUse = n;
    948                     score = 5;
     912                    score = ;
    949913                }
    950914                break;
    951915            case 0xa:
    952                 if (score < 6) {
     916                if (score < ) {
    953917                    tableToUse = n;
    954                     score = 6;
     918                    score = ;
    955919                }
    956920                break;
     
    964928    if(tableToUse < 0)
    965929        return 0;
    966     *isSymbolFont = (score == 1);
     930
     931resolveTable:
     932    *isSymbolFont = (score == Symbol);
    967933
    968934    unsigned int unicode_table = qFromBigEndian<quint32>(maps + 8*tableToUse + 4);