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/qpaintengine_raster.cpp

    r769 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)
     
    4141
    4242#include <QtCore/qglobal.h>
     43#include <QtCore/qmutex.h>
    4344
    4445#define QT_FT_BEGIN_HEADER
     
    6869//   #include <private/qrasterizer_p.h>
    6970#include <private/qimage_p.h>
     71#include <private/qstatictext_p.h>
     72#include "qmemrotate_p.h"
    7073
    7174#include "qpaintengine_raster_p.h"
     
    251254#endif
    252255
     256QRasterPaintEnginePrivate::QRasterPaintEnginePrivate() :
     257    QPaintEngineExPrivate(),
     258    cachedLines(0)
     259{
     260}
    253261
    254262
     
    336344#endif
    337345
    338     d->rasterPoolSize = 8192;
    339     d->rasterPoolBase =
    340 #if defined(Q_WS_WIN64)
    341         // We make use of setjmp and longjmp in qgrayraster.c which requires
    342         // 16-byte alignment, hence we hardcode this requirement here..
    343         (unsigned char *) _aligned_malloc(d->rasterPoolSize, sizeof(void*) * 2);
    344 #else
    345         (unsigned char *) malloc(d->rasterPoolSize);
    346 #endif
    347     Q_CHECK_PTR(d->rasterPoolBase);
    348 
    349346    // The antialiasing raster.
    350347    d->grayRaster.reset(new QT_FT_Raster);
    351348    Q_CHECK_PTR(d->grayRaster.data());
    352     if (qt_ft_grays_raster.raster_new(0, d->grayRaster.data()))
     349    if (qt_ft_grays_raster.raster_new(d->grayRaster.data()))
    353350        QT_THROW(std::bad_alloc()); // an error creating the raster is caused by a bad malloc
    354351
    355 
    356     qt_ft_grays_raster.raster_reset(*d->grayRaster.data(), d->rasterPoolBase, d->rasterPoolSize);
    357352
    358353    d->rasterizer.reset(new QRasterizer);
     
    437432    Q_D(QRasterPaintEngine);
    438433
    439 #if defined(Q_WS_WIN64)
    440     _aligned_free(d->rasterPoolBase);
    441 #else
    442     free(d->rasterPoolBase);
    443 #endif
    444 
    445434    qt_ft_grays_raster.raster_done(*d->grayRaster.data());
    446435}
     
    455444    if (device->devType() == QInternal::Pixmap) {
    456445        QPixmap *pixmap = static_cast<QPixmap *>(device);
    457         if (pixmap->data->classId() == QPixmapData::RasterClass)
    458             d->device = pixmap->data->buffer();
     446        QPixmapData *pd = pixmap->pixmapData();
     447        if (pd->classId() == QPixmapData::RasterClass)
     448            d->device = pd->buffer();
    459449    } else {
    460450        d->device = device;
     
    471461    QRasterPaintEngineState *s = state();
    472462    ensureOutlineMapper();
    473     d->outlineMapper->m_clip_rect = d->deviceRect.adjusted(-10, -10, 10, 10);
    474 
    475     // This is the upp
    476     QRect bounds(-QT_RASTER_COORD_LIMIT, -QT_RASTER_COORD_LIMIT,
    477                  QT_RASTER_COORD_LIMIT*2 - 1, QT_RASTER_COORD_LIMIT * 2 - 1);
    478     d->outlineMapper->m_clip_rect = bounds.intersected(d->outlineMapper->m_clip_rect);
    479 
     463    d->outlineMapper->m_clip_rect = d->deviceRect;
     464
     465    if (d->outlineMapper->m_clip_rect.width() > QT_RASTER_COORD_LIMIT)
     466        d->outlineMapper->m_clip_rect.setWidth(QT_RASTER_COORD_LIMIT);
     467    if (d->outlineMapper->m_clip_rect.height() > QT_RASTER_COORD_LIMIT)
     468        d->outlineMapper->m_clip_rect.setHeight(QT_RASTER_COORD_LIMIT);
    480469
    481470    d->rasterizer->setClipRect(d->deviceRect);
     
    887876        updateMatrix(s->matrix);
    888877
    889     if (s->dirty & (DirtyPen|DirtyCompositionMode)) {
     878    if (s->dirty & (DirtyPen|DirtyCompositionMode|DirtyOpacity)) {
    890879        const QPainter::CompositionMode mode = s->composition_mode;
    891880        s->flags.fast_text = (s->penData.type == QSpanData::Solid)
     881                       && s->intOpacity == 256
    892882                       && (mode == QPainter::CompositionMode_Source
    893883                           || (mode == QPainter::CompositionMode_SourceOver
     
    913903    s->strokeFlags |= DirtyOpacity;
    914904    s->pixmapFlags |= DirtyOpacity;
     905    s->dirty |= DirtyOpacity;
    915906    s->intOpacity = (int) (s->opacity * 256);
    916907}
     
    11151106    bool bilinear = q->state()->flags.bilinear;
    11161107
    1117     if (b.d->transform.type() > QTransform::TxNone) { // FALCON: optimise
     1108    if (b.d->transform.type() > QTransform::TxNone) { // FALCON: optimize
    11181109        spanData->setupMatrix(b.transform() * m, bilinear);
    11191110    } else {
     
    12221213    if (op != Qt::UniteClip && (op != Qt::IntersectClip || !s->clip
    12231214                                || s->clip->hasRectClip || s->clip->hasRegionClip)) {
    1224         if (s->matrix.type() <= QTransform::TxTranslate
     1215        if (s->matrix.type() <= QTransform::TxScale
    12251216            && ((path.shape() == QVectorPath::RectangleHint)
    12261217                || (isRect(points, path.elementCount())
     
    12341225
    12351226            QRectF r(points[0], points[1], points[4]-points[0], points[5]-points[1]);
    1236             clip(r.toRect(), op);
    1237             return;
     1227            if (setClipRectInDeviceCoords(s->matrix.mapRect(r).toRect(), op))
     1228                return;
    12381229        }
    12391230    }
     
    12961287#endif
    12971288
    1298     Q_D(QRasterPaintEngine);
    12991289    QRasterPaintEngineState *s = state();
    13001290
     
    13061296        return;
    13071297
    1308     } else if (op == Qt::ReplaceClip || s->clip == 0) {
     1298    } else if (!setClipRectInDeviceCoords(s->matrix.mapRect(rect), op)) {
     1299        QPaintEngineEx::clip(rect, op);
     1300        return;
     1301    }
     1302}
     1303
     1304
     1305bool QRasterPaintEngine::setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op)
     1306{
     1307    Q_D(QRasterPaintEngine);
     1308    QRect clipRect = r & d->deviceRect;
     1309    QRasterPaintEngineState *s = state();
     1310
     1311    if (op == Qt::ReplaceClip || s->clip == 0) {
    13091312
    13101313        // No current clip, hence we intersect with sysclip and be
    13111314        // done with it...
    1312         QRect clipRect = s->matrix.mapRect(rect) & d->deviceRect;
    13131315        QRegion clipRegion = systemClip();
    13141316        QClipData *clip = new QClipData(d->rasterBuffer->height());
     
    13261328        s->flags.has_clip_ownership = true;
    13271329
    1328     } else { // intersect clip with current clip
     1330    } else if (op == Qt::IntersectClip){ // intersect clip with current clip
    13291331        QClipData *base = s->clip;
    13301332
    13311333        Q_ASSERT(base);
    13321334        if (base->hasRectClip || base->hasRegionClip) {
    1333             QRect clipRect = s->matrix.mapRect(rect) & d->deviceRect;
    13341335            if (!s->flags.has_clip_ownership) {
    13351336                s->clip = new QClipData(d->rasterBuffer->height());
     
    13421343            s->clip->enabled = true;
    13431344        } else {
    1344             QPaintEngineEx::clip(rect, op);
    1345             return;
    1346         }
    1347     }
     1345            return false;
     1346        }
     1347    } else {
     1348        return false;
     1349    }
     1350
    13481351    qrasterpaintengine_dirty_clip(d, s);
     1352    return true;
    13491353}
    13501354
     
    17251729            int n = qFloor(dashOffset / patternLength);
    17261730            dashOffset -= n * patternLength;
    1727             while (dashOffset > pattern.at(dashIndex)) {
     1731            while (dashOffset >= pattern.at(dashIndex)) {
    17281732                dashOffset -= pattern.at(dashIndex);
    1729                 dashIndex = (dashIndex + 1) % pattern.size();
     1733                if (++dashIndex >= pattern.size())
     1734                    dashIndex = 0;
    17301735                inDash = !inDash;
    17311736            }
     
    17381743
    17391744        for (int i = 0; i < lineCount; ++i) {
    1740             dashOffset = s->lastPen.dashOffset();
    17411745            if (lines[i].p1() == lines[i].p2()) {
    17421746                if (s->lastPen.capStyle() != Qt::FlatCap) {
     
    18121816        if (s->flags.tx_noshear) {
    18131817            d->initializeRasterizer(&s->brushData);
    1814             // ### Is normalizing really nessesary here?
     1818            // ### Is normalizing really necessary here?
    18151819            const qreal *p = path.points();
    18161820            QRectF r = QRectF(p[0], p[1], p[2] - p[0], p[7] - p[1]).normalized();
     
    23722376#endif
    23732377
    2374     if (pixmap.data->classId() == QPixmapData::RasterClass) {
    2375         const QImage &image = static_cast<QRasterPixmapData *>(pixmap.data.data())->image;
     2378    QPixmapData *pd = pixmap.pixmapData();
     2379    if (pd->classId() == QPixmapData::RasterClass) {
     2380        const QImage &image = static_cast<QRasterPixmapData *>(pd)->image;
    23762381        if (image.depth() == 1) {
    23772382            Q_D(QRasterPaintEngine);
     
    24122417#endif
    24132418
    2414     if (pixmap.data->classId() == QPixmapData::RasterClass) {
    2415         const QImage &image = static_cast<QRasterPixmapData *>(pixmap.data.data())->image;
     2419    QPixmapData* pd = pixmap.pixmapData();
     2420    if (pd->classId() == QPixmapData::RasterClass) {
     2421        const QImage &image = static_cast<QRasterPixmapData *>(pd)->image;
    24162422        if (image.depth() == 1) {
    24172423            Q_D(QRasterPaintEngine);
     
    24302436        }
    24312437    } else {
    2432         const QImage image = pixmap.toImage();
     2438        QRect clippedSource = sr.toAlignedRect().intersected(pixmap.rect());
     2439        const QImage image = pd->toImage(clippedSource);
     2440        QRectF translatedSource = sr.translated(-clippedSource.topLeft());
    24332441        if (image.depth() == 1) {
    24342442            Q_D(QRasterPaintEngine);
     
    24412449                return;
    24422450            } else {
    2443                 drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), sr);
     2451                drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), translatedSource);
    24442452            }
    24452453        } else {
    2446             drawImage(r, image, sr);
     2454            drawImage(r, image, translatedSource);
    24472455        }
    24482456    }
     
    25322540}
    25332541
     2542namespace {
     2543    enum RotationType {
     2544        Rotation90,
     2545        Rotation180,
     2546        Rotation270,
     2547        NoRotation
     2548    };
     2549
     2550    inline RotationType qRotationType(const QTransform &transform)
     2551    {
     2552        QTransform::TransformationType type = transform.type();
     2553
     2554        if (type > QTransform::TxRotate)
     2555            return NoRotation;
     2556
     2557        if (type == QTransform::TxRotate && qFuzzyIsNull(transform.m11()) && qFuzzyCompare(transform.m12(), qreal(-1))
     2558            && qFuzzyCompare(transform.m21(), qreal(1)) && qFuzzyIsNull(transform.m22()))
     2559            return Rotation90;
     2560
     2561        if (type == QTransform::TxScale && qFuzzyCompare(transform.m11(), qreal(-1)) && qFuzzyIsNull(transform.m12())
     2562            && qFuzzyIsNull(transform.m21()) && qFuzzyCompare(transform.m22(), qreal(-1)))
     2563            return Rotation180;
     2564
     2565        if (type == QTransform::TxRotate && qFuzzyIsNull(transform.m11()) && qFuzzyCompare(transform.m12(), qreal(1))
     2566            && qFuzzyCompare(transform.m21(), qreal(-1)) && qFuzzyIsNull(transform.m22()))
     2567            return Rotation270;
     2568
     2569        return NoRotation;
     2570    }
     2571
     2572    inline bool isPixelAligned(const QRectF &rect) {
     2573        return QRectF(rect.toRect()) == rect;
     2574    }
     2575}
     2576
    25342577/*!
    25352578    \reimp
     
    25522595    int sr_b = qCeil(sr.bottom()) - 1;
    25532596
    2554     if (!s->flags.antialiased && sr_l == sr_r && sr_t == sr_b) {
     2597    if (s->matrix.type() <= QTransform::TxScale && !s->flags.antialiased && sr_l == sr_r && sr_t == sr_b) {
    25552598        // as fillRect will apply the aliased coordinate delta we need to
    25562599        // subtract it here as we don't use it for image drawing
     
    25932636    const QClipData *clip = d->clip();
    25942637
     2638    if (s->matrix.type() > QTransform::TxTranslate
     2639        && !stretch_sr
     2640        && (!clip || clip->hasRectClip)
     2641        && s->intOpacity == 256
     2642        && (d->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver
     2643            || d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)
     2644        && d->rasterBuffer->format == img.format()
     2645        && (d->rasterBuffer->format == QImage::Format_RGB16
     2646            || d->rasterBuffer->format == QImage::Format_RGB32
     2647            || (d->rasterBuffer->format == QImage::Format_ARGB32_Premultiplied
     2648                && d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source)))
     2649    {
     2650        RotationType rotationType = qRotationType(s->matrix);
     2651
     2652        if (rotationType != NoRotation && qMemRotateFunctions[d->rasterBuffer->format][rotationType] && img.rect().contains(sr.toAlignedRect())) {
     2653            QRectF transformedTargetRect = s->matrix.mapRect(r);
     2654
     2655            if ((!(s->renderHints & QPainter::SmoothPixmapTransform) && !(s->renderHints & QPainter::Antialiasing))
     2656                || (isPixelAligned(transformedTargetRect) && isPixelAligned(sr)))
     2657            {
     2658                QRect clippedTransformedTargetRect = transformedTargetRect.toRect().intersected(clip ? clip->clipRect : d->deviceRect);
     2659                if (clippedTransformedTargetRect.isNull())
     2660                    return;
     2661
     2662                QRectF clippedTargetRect = s->matrix.inverted().mapRect(QRectF(clippedTransformedTargetRect));
     2663
     2664                QRect clippedSourceRect
     2665                    = QRectF(sr.x() + clippedTargetRect.x() - r.x(), sr.y() + clippedTargetRect.y() - r.y(),
     2666                            clippedTargetRect.width(), clippedTargetRect.height()).toRect();
     2667
     2668                uint dbpl = d->rasterBuffer->bytesPerLine();
     2669                uint sbpl = img.bytesPerLine();
     2670
     2671                uchar *dst = d->rasterBuffer->buffer();
     2672                uint bpp = img.depth() >> 3;
     2673
     2674                const uchar *srcBase = img.bits() + clippedSourceRect.y() * sbpl + clippedSourceRect.x() * bpp;
     2675                uchar *dstBase = dst + clippedTransformedTargetRect.y() * dbpl + clippedTransformedTargetRect.x() * bpp;
     2676
     2677                uint cw = clippedSourceRect.width();
     2678                uint ch = clippedSourceRect.height();
     2679
     2680                qMemRotateFunctions[d->rasterBuffer->format][rotationType](srcBase, cw, ch, sbpl, dstBase, dbpl);
     2681
     2682                return;
     2683            }
     2684        }
     2685    }
     2686
    25952687    if (s->matrix.type() > QTransform::TxTranslate || stretch_sr) {
    25962688
    2597         if (s->flags.fast_images) {
     2689        QRectF targetBounds = s->matrix.mapRect(r);
     2690        bool exceedsPrecision = targetBounds.width() > 0xffff
     2691                                || targetBounds.height() > 0xffff;
     2692
     2693        if (s->flags.fast_images && !exceedsPrecision) {
    25982694            if (s->matrix.type() > QTransform::TxScale) {
    25992695                SrcOverTransformFunc func = qTransformFunctions[d->rasterBuffer->format][img.format()];
     
    27172813    QImage image;
    27182814
    2719     if (pixmap.data->classId() == QPixmapData::RasterClass) {
    2720         image = static_cast<QRasterPixmapData *>(pixmap.data.data())->image;
     2815    QPixmapData *pd = pixmap.pixmapData();
     2816    if (pd->classId() == QPixmapData::RasterClass) {
     2817        image = static_cast<QRasterPixmapData *>(pd)->image;
    27212818    } else {
    27222819        image = pixmap.toImage();
     
    30033100}
    30043101
    3005 void QRasterPaintEngine::drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti)
     3102void QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs,
     3103                                          const QFixedPoint *positions, QFontEngine *fontEngine)
    30063104{
    30073105    Q_D(QRasterPaintEngine);
    30083106    QRasterPaintEngineState *s = state();
    30093107
    3010     QVarLengthArray<QFixedPoint> positions;
    3011     QVarLengthArray<glyph_t> glyphs;
    3012     QTransform matrix = s->matrix;
    3013     matrix.translate(p.x(), p.y());
    3014     ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
    3015 
    3016     QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(ti.fontEngine->glyphFormat) : d->glyphCacheType;
     3108    QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(fontEngine->glyphFormat) : d->glyphCacheType;
    30173109
    30183110    QImageTextureGlyphCache *cache =
    3019         (QImageTextureGlyphCache *) ti.fontEngine->glyphCache(0, glyphType, s->matrix);
     3111        static_cast<QImageTextureGlyphCache *>(fontEngine->glyphCache(0, glyphType, s->matrix));
    30203112    if (!cache) {
    30213113        cache = new QImageTextureGlyphCache(glyphType, s->matrix);
    3022         ti.fontEngine->setGlyphCache(0, cache);
    3023     }
    3024 
    3025     cache->populate(ti, glyphs, positions);
     3114        fontEngine->setGlyphCache(0, cache);
     3115    }
     3116
     3117    cache->populate(fontEngine, numGlyphs, glyphs, positions);
    30263118
    30273119    const QImage &image = cache->image();
     
    30413133
    30423134    const uchar *bits = image.bits();
    3043     for (int i=0; i<glyphs.size(); ++i) {
     3135    for (int i=0; i<numGlyphs; ++i) {
    30443136        const QTextureGlyphCache::Coord &c = cache->coords.value(glyphs[i]);
    30453137        int x = qFloor(positions[i].x + offs) + c.baseLineX - margin;
     
    30893181        TSize glyphBitmapSize;
    30903182        fe->getCharacterData(glyphs[i], tmetrics, glyphBitmapBytes, glyphBitmapSize);
    3091         const glyph_metrics_t metrics = ti.fontEngine->boundingBox(glyphs[i]);
    3092         const int x = qFloor(positions[i].x + metrics.x + aliasDelta);
    3093         const int y = qFloor(positions[i].y + metrics.y + aliasDelta);
    3094 
     3183        const int x = qFloor(positions[i].x + tmetrics.HorizBearingX() + aliasDelta);
     3184        const int y = qFloor(positions[i].y - tmetrics.HorizBearingY() + aliasDelta);
    30953185        alphaPenBlt(glyphBitmapBytes, glyphBitmapSize.iWidth, 8, x, y, glyphBitmapSize.iWidth, glyphBitmapSize.iHeight);
    30963186    }
     
    31043194
    31053195/*!
    3106  * Returns true if the rectangle is completly within the current clip
     3196 * Returns true if the rectangle is completely within the current clip
    31073197 * state of the paint engine.
    31083198 */
     
    32193309
    32203310/*!
     3311   \reimp
     3312*/
     3313void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
     3314{
     3315    ensurePen();
     3316    ensureState();
     3317
     3318    drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions,
     3319                     textItem->fontEngine());
     3320}
     3321
     3322/*!
    32213323    \reimp
    32223324*/
     
    32663368#endif
    32673369    if (drawCached) {
    3268         drawCachedGlyphs(p, ti);
     3370        QRasterPaintEngineState *s = state();
     3371
     3372        QVarLengthArray<QFixedPoint> positions;
     3373        QVarLengthArray<glyph_t> glyphs;
     3374
     3375        QTransform matrix = s->matrix;
     3376        matrix.translate(p.x(), p.y());
     3377
     3378        ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
     3379
     3380        drawCachedGlyphs(glyphs.size(), glyphs.constData(), positions.constData(), ti.fontEngine);
    32693381        return;
    32703382    }
     
    33733485
    33743486    for(int i = 0; i < glyphs.size(); i++) {
    3375         QFontEngineFT::Glyph *glyph = gset->glyph_data.value(glyphs[i]);
     3487        QFontEngineFT::Glyph *glyph = gset->getGlyph(glyphs[i]);
    33763488
    33773489        if (!glyph || glyph->format != neededFormat) {
     
    36093721            *dashOffset = 0;
    36103722            *inDash = !(*inDash);
    3611             *dashIndex = (*dashIndex + 1) % pattern.size();
     3723            if (++*dashIndex >= pattern.size())
     3724                *dashIndex = 0;
    36123725            length -= dash;
    36133726            l.setLength(dash);
     
    36153728        }
    36163729
    3617         if (rasterize && dash != 0)
     3730        if (rasterize && dash > 0)
    36183731            rasterizer->rasterizeLine(l.p1(), l.p2(), width / dash, squareCap);
    36193732    }
     
    36763789         || (qpen_style(s->lastPen) == Qt::NoPen && !s->flags.antialiased))
    36773790        && qMax(rect.width(), rect.height()) < QT_RASTER_COORD_LIMIT
     3791        && !rect.isEmpty()
    36783792        && s->matrix.type() <= QTransform::TxScale) // no shear
    36793793    {
     
    40494163}
    40504164
     4165extern "C" {
     4166    int q_gray_rendered_spans(QT_FT_Raster raster);
     4167}
     4168
    40514169void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline,
    40524170                                          ProcessSpans callback,
     
    40714189        return;
    40724190    }
     4191
     4192    // Initial size for raster pool is MINIMUM_POOL_SIZE so as to
     4193    // minimize memory reallocations. However if initial size for
     4194    // raster pool is changed for lower value, reallocations will
     4195    // occur normally.
     4196    const int rasterPoolInitialSize = MINIMUM_POOL_SIZE;
     4197    int rasterPoolSize = rasterPoolInitialSize;
     4198    unsigned char *rasterPoolBase;
     4199#if defined(Q_WS_WIN64)
     4200    rasterPoolBase =
     4201        // We make use of setjmp and longjmp in qgrayraster.c which requires
     4202        // 16-byte alignment, hence we hardcode this requirement here..
     4203        (unsigned char *) _aligned_malloc(rasterPoolSize, sizeof(void*) * 2);
     4204#else
     4205    unsigned char rasterPoolOnStack[rasterPoolInitialSize];
     4206    rasterPoolBase = rasterPoolOnStack;
     4207#endif
     4208    Q_CHECK_PTR(rasterPoolBase);
     4209
     4210    qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize);
    40734211
    40744212    void *data = userData;
     
    40934231    int error;
    40944232
     4233    int rendered_spans = 0;
     4234
    40954235    while (!done) {
    40964236
    40974237        rasterParams.flags |= (QT_FT_RASTER_FLAG_AA | QT_FT_RASTER_FLAG_DIRECT);
    40984238        rasterParams.gray_spans = callback;
     4239        rasterParams.skip_spans = rendered_spans;
    40994240        error = qt_ft_grays_raster.raster_render(*grayRaster.data(), &rasterParams);
    41004241
    41014242        // Out of memory, reallocate some more and try again...
    4102         if (error == -6) { // -6 is Result_err_OutOfMemory
     4243        if (error == -6) { // ErrRaster_OutOfMemory from qgrayraster.c
    41034244            int new_size = rasterPoolSize * 2;
    41044245            if (new_size > 1024 * 1024) {
    41054246                qWarning("QPainter: Rasterization of primitive failed");
    4106                 return;
     4247                break;
    41074248            }
     4249
     4250            rendered_spans += q_gray_rendered_spans(*grayRaster.data());
    41084251
    41094252#if defined(Q_WS_WIN64)
    41104253            _aligned_free(rasterPoolBase);
    41114254#else
    4112             free(rasterPoolBase);
     4255            if (rasterPoolBase != rasterPoolOnStack) // initially on the stack
     4256                free(rasterPoolBase);
    41134257#endif
    41144258
     
    41254269
    41264270            qt_ft_grays_raster.raster_done(*grayRaster.data());
    4127             qt_ft_grays_raster.raster_new(0, grayRaster.data());
     4271            qt_ft_grays_raster.raster_new(grayRaster.data());
    41284272            qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize);
    41294273        } else {
     
    41314275        }
    41324276    }
     4277
     4278#if defined(Q_WS_WIN64)
     4279    _aligned_free(rasterPoolBase);
     4280#else
     4281    if (rasterPoolBase != rasterPoolOnStack) // initially on the stack
     4282        free(rasterPoolBase);
     4283#endif
    41334284}
    41344285
     
    48124963            hash_val += stops[i].second.rgba();
    48134964
     4965        QMutexLocker lock(&mutex);
    48144966        QGradientColorTableHash::const_iterator it = cache.constFind(hash_val);
    48154967
     
    48454997
    48464998    QGradientColorTableHash cache;
     4999    QMutex mutex;
    48475000};
    48485001
Note: See TracChangeset for help on using the changeset viewer.