Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/painting/qtextureglyphcache.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    4848#include "private/qfontengine_ft_p.h"
    4949
    50 #ifndef QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH
    51 #define QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH 256
    52 #endif
    53 
    5450QT_BEGIN_NAMESPACE
    5551
    5652// #define CACHE_DEBUG
    5753
    58 void QTextureGlyphCache::populate(const QTextItemInt &ti,
    59                                   const QVarLengthArray<glyph_t> &glyphs,
    60                                   const QVarLengthArray<QFixedPoint> &)
     54// returns the highest number closest to v, which is a power of 2
     55// NB! assumes 32 bit ints
     56static inline int qt_next_power_of_two(int v)
     57{
     58    v--;
     59    v |= v >> 1;
     60    v |= v >> 2;
     61    v |= v >> 4;
     62    v |= v >> 8;
     63    v |= v >> 16;
     64    ++v;
     65    return v;
     66}
     67
     68bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const glyph_t *glyphs,
     69                                  const QFixedPoint *)
    6170{
    6271#ifdef CACHE_DEBUG
    63     printf("Populating with '%s'\n", QString::fromRawData(ti.chars, ti.num_chars).toLatin1().data());
     72    printf("Populating with %d glyphs\n", numGlyphs);
    6473    qDebug() << " -> current transformation: " << m_transform;
    6574#endif
    6675
    67     m_current_textitem = &ti;
     76    m_current_fontengine = fontEngine;
    6877    const int margin = glyphMargin();
     78    const int paddingDoubled = glyphPadding() * 2;
    6979
    7080    QHash<glyph_t, Coord> listItemCoordinates;
     
    7282
    7383    // check each glyph for its metrics and get the required rowHeight.
    74     for (int i=0; i < glyphs.size(); ++i) {
     84    for (int i=0; i < numGlyphs; ++i) {
    7585        const glyph_t glyph = glyphs[i];
    7686        if (coords.contains(glyph))
     
    7888        if (listItemCoordinates.contains(glyph))
    7989            continue;
    80         glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyph, m_transform);
     90        glyph_metrics_t metrics = fontEngine->boundingBox(glyph, m_transform);
    8191
    8292#ifdef CACHE_DEBUG
    83         printf("'%c' (%4x): w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f, ti.ascent=%.2f, ti.descent=%.2f\n",
    84                ti.chars[i].toLatin1(),
     93        printf("(%4x): w=%.2f, h=%.2f, xoff=%.2f, yoff=%.2f, x=%.2f, y=%.2f\n",
    8594               glyph,
    8695               metrics.width.toReal(),
     
    8998               metrics.yoff.toReal(),
    9099               metrics.x.toReal(),
    91                metrics.y.toReal(),
    92                ti.ascent.toReal(),
    93                ti.descent.toReal());
     100               metrics.y.toReal());
    94101#endif
    95102        int glyph_width = metrics.width.ceil().toInt();
     
    113120    }
    114121    if (listItemCoordinates.isEmpty())
    115         return;
    116 
    117     rowHeight += margin * 2;
     122        return true;
     123
     124    rowHeight += margin * 2 + paddingDoubled;
    118125    if (isNull())
    119         createCache(QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH, rowHeight);
     126        createCache(QT_DEFAULT_TEXTURE_GLYPH_CACHE_WIDTH, qt_next_power_of_two(rowHeight));
    120127
    121128    // now actually use the coords and paint the wanted glyps into cache.
     
    124131        Coord c = iter.value();
    125132
     133        m_currentRowHeight = qMax(m_currentRowHeight, c.h + margin * 2);
     134
    126135        if (m_cx + c.w > m_w) {
    127             // no room on the current line, start new glyph strip
    128             m_cx = 0;
    129             m_cy = m_h;
     136            int new_width = m_w*2;
     137            while (new_width < m_cx + c.w)
     138                new_width *= 2;
     139            if (new_width <= maxTextureWidth()) {
     140                resizeTextureData(new_width, m_h);
     141                m_w = new_width;
     142            } else {
     143                // no room on the current line, start new glyph strip
     144                m_cx = 0;
     145                m_cy += m_currentRowHeight + paddingDoubled;
     146                m_currentRowHeight = c.h + margin * 2; // New row
     147            }
    130148        }
    131149        if (m_cy + c.h > m_h) {
    132             int new_height;
    133             if (m_cx == 0) { // add a whole row
    134                 new_height = m_h + rowHeight;
    135                 m_cy = m_h;
    136             } else { // just extend row
    137                 new_height = m_cy + rowHeight;
    138             }
     150            int new_height = m_h*2;
     151            while (new_height < m_cy + c.h)
     152                new_height *= 2;
     153
     154            if (maxTextureHeight() > 0 && new_height > maxTextureHeight()) {
     155                // We can't make a new texture of the required size, so
     156                // bail out
     157                return false;
     158            }
     159
    139160            // if no room in the current texture - realloc a larger texture
    140161            resizeTextureData(m_w, new_height);
     
    148169        coords.insert(iter.key(), c);
    149170
    150         if (m_cx + c.w > m_w) {
    151             m_cx = 0;
    152             m_cy += rowHeight;
    153         } else {
    154             // for the Mono case, glyph_width is 8-bit aligned,
    155             // and therefore so will m_cx
    156             m_cx += c.w;
    157         }
     171        m_cx += c.w + paddingDoubled;
    158172        ++iter;
    159173    }
    160174
    161 
     175    return true;
    162176}
    163177
     
    183197        };
    184198
    185         QFontEngineFT *ft = static_cast<QFontEngineFT*> (m_current_textitem->fontEngine);
     199        QFontEngineFT *ft = static_cast<QFontEngineFT*> (m_current_fontengine);
    186200        QFontEngineFT::QGlyphSet *gset = ft->loadTransformedGlyphSet(m_transform);
    187201
    188202        if (gset && ft->loadGlyphs(gset, &g, 1, format)) {
    189             QFontEngineFT::Glyph *glyph = gset->glyph_data.value(g);
     203            QFontEngineFT::Glyph *glyph = gset->getGlyph(g);
    190204            const int bytesPerLine = (format == QFontEngineFT::Format_Mono ? ((glyph->width + 31) & ~31) >> 3
    191205                               : (glyph->width + 3) & ~3);
     
    195209#endif
    196210    if (m_type == QFontEngineGlyphCache::Raster_RGBMask)
    197         return m_current_textitem->fontEngine->alphaRGBMapForGlyph(g, glyphMargin(), m_transform);
     211        return m_current_fontengine->alphaRGBMapForGlyph(g, glyphMargin(), m_transform);
    198212    else
    199         return m_current_textitem->fontEngine->alphaMapForGlyph(g, m_transform);
     213        return m_current_fontengine->alphaMapForGlyph(g, m_transform);
    200214
    201215    return QImage();
     
    253267#endif
    254268
    255     if (m_type == QFontEngineGlyphCache::Raster_RGBMask) {
    256         QPainter p(&m_image);
     269    if (m_type == QFontEngineGlyphCache::Raster_RGBMask) {       
     270        QImage ref(m_image.bits() + (c.x * 4 + c.y * m_image.bytesPerLine()),
     271                   qMax(mask.width(), c.w), qMax(mask.height(), c.h), m_image.bytesPerLine(),
     272                   m_image.format());
     273        QPainter p(&ref);
    257274        p.setCompositionMode(QPainter::CompositionMode_Source);
    258         p.fillRect(c.x, c.y, c.w, c.h, QColor(0,0,0,0)); // TODO optimize this
    259         p.drawImage(c.x, c.y, mask);
     275        p.fillRect(0, 0, c.w, c.h, QColor(0,0,0,0)); // TODO optimize this
     276        p.drawImage(0, 0, mask);
    260277        p.end();
    261278    } else if (m_type == QFontEngineGlyphCache::Raster_Mono) {
     
    325342    if (m_image.rect().contains(base))
    326343        m_image.setPixel(base, 255);
    327     m_image.save(QString::fromLatin1("cache-%1-%2-%3.png")
    328                  .arg(m_current_textitem->font().family())
    329                  .arg(m_current_textitem->font().pointSize())
    330                  .arg(m_transform.type()));
     344    m_image.save(QString::fromLatin1("cache-%1.png").arg(int(this)));
    331345#endif
    332346}
Note: See TracChangeset for help on using the changeset viewer.