diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/dialogs/qprintdialog_mac.mm | 9 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicslinearlayout.cpp | 8 | ||||
-rw-r--r-- | src/gui/image/qgifhandler.cpp | 13 | ||||
-rw-r--r-- | src/gui/image/qjpeghandler.cpp | 32 | ||||
-rw-r--r-- | src/gui/image/qpnghandler.cpp | 92 | ||||
-rw-r--r-- | src/gui/painting/qgrayraster.c | 42 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_raster.cpp | 9 | ||||
-rw-r--r-- | src/gui/painting/qpaintengineex.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qrasterdefs_p.h | 3 | ||||
-rw-r--r-- | src/gui/painting/qstroker.cpp | 9 | ||||
-rw-r--r-- | src/gui/painting/qstroker_p.h | 3 |
12 files changed, 135 insertions, 89 deletions
diff --git a/src/gui/dialogs/qprintdialog_mac.mm b/src/gui/dialogs/qprintdialog_mac.mm index 84a72db..82e4db5 100644 --- a/src/gui/dialogs/qprintdialog_mac.mm +++ b/src/gui/dialogs/qprintdialog_mac.mm @@ -140,11 +140,6 @@ QT_USE_NAMESPACE QPrintDialogPrivate *d = static_cast<QPrintDialogPrivate *>(contextInfo); QPrintDialog *dialog = d->printDialog(); - // temporary hack to work around bug in deleteLater() in Qt/Mac Cocoa -#if 1 - bool deleteDialog = dialog->testAttribute(Qt::WA_DeleteOnClose); - dialog->setAttribute(Qt::WA_DeleteOnClose, false); -#endif if (returnCode == NSOKButton) { UInt32 frompage, topage; @@ -192,10 +187,6 @@ QT_USE_NAMESPACE } dialog->done((returnCode == NSOKButton) ? QDialog::Accepted : QDialog::Rejected); -#if 1 - if (deleteDialog) - delete dialog; -#endif } @end diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp index 1588364..7e8d19f 100644 --- a/src/gui/graphicsview/qgraphicslinearlayout.cpp +++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp @@ -275,13 +275,17 @@ void QGraphicsLinearLayout::insertItem(int index, QGraphicsLayoutItem *item) qWarning("QGraphicsLinearLayout::insertItem: cannot insert itself"); return; } + Q_ASSERT(item); + + //the order of the following instructions is very important because + //invalidating the layout before adding the child item will make the layout happen + //before we try to paint the item + invalidate(); d->addChildLayoutItem(item); - Q_ASSERT(item); d->fixIndex(&index); d->engine.insertRow(index, d->orientation); new QGridLayoutItem(&d->engine, item, d->gridRow(index), d->gridColumn(index), 1, 1, 0, index); - invalidate(); } /*! diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp index 124d27b..a050baf 100644 --- a/src/gui/image/qgifhandler.cpp +++ b/src/gui/image/qgifhandler.cpp @@ -505,17 +505,26 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, code=oldcode; } while (code>=clear_code+2) { + if (code >= max_code) { + state = Error; + return -1; + } *sp++=table[1][code]; if (code==table[0][code]) { state=Error; - break; + return -1; } if (sp-stack>=(1<<(max_lzw_bits))*2) { state=Error; - break; + return -1; } code=table[0][code]; } + if (code < 0) { + state = Error; + return -1; + } + *sp++=firstcode=table[1][code]; code=max_code; if (code<(1<<max_lzw_bits)) { diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index b9eda05..d47cc82 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -648,22 +648,28 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, int sourceQ break; case QImage::Format_RGB32: case QImage::Format_ARGB32: - case QImage::Format_ARGB32_Premultiplied: { - const QRgb* rgb = (const QRgb*)image.constScanLine(cinfo.next_scanline); - for (int i=0; i<w; i++) { - *row++ = qRed(*rgb); - *row++ = qGreen(*rgb); - *row++ = qBlue(*rgb); - ++rgb; + case QImage::Format_ARGB32_Premultiplied: + { + const QRgb* rgb = (const QRgb*)image.constScanLine(cinfo.next_scanline); + for (int i=0; i<w; i++) { + *row++ = qRed(*rgb); + *row++ = qGreen(*rgb); + *row++ = qBlue(*rgb); + ++rgb; + } } break; - } default: - for (int i=0; i<w; i++) { - QRgb pix = image.pixel(i, cinfo.next_scanline); - *row++ = qRed(pix); - *row++ = qGreen(pix); - *row++ = qBlue(pix); + { + // (Testing shows that this way is actually faster than converting to RGB888 + memcpy) + QImage rowImg = image.copy(0, cinfo.next_scanline, w, 1).convertToFormat(QImage::Format_RGB32); + const QRgb* rgb = (const QRgb*)rowImg.constScanLine(0); + for (int i=0; i<w; i++) { + *row++ = qRed(*rgb); + *row++ = qGreen(*rgb); + *row++ = qBlue(*rgb); + ++rgb; + } } break; } diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index dc54313..935aba0 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -678,41 +678,19 @@ bool QPNGImageWriter::writeImage(const QImage& image, int off_x, int off_y) return writeImage(image, -1, QString(), off_x, off_y); } -bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, int quality_in, const QString &description, +bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, int quality_in, const QString &description, int off_x_in, int off_y_in) { #ifdef QT_NO_IMAGE_TEXT Q_UNUSED(description); #endif - QImage image; - switch (image_in.format()) { - case QImage::Format_ARGB32_Premultiplied: - case QImage::Format_ARGB4444_Premultiplied: - case QImage::Format_ARGB8555_Premultiplied: - case QImage::Format_ARGB8565_Premultiplied: - case QImage::Format_ARGB6666_Premultiplied: - image = image_in.convertToFormat(QImage::Format_ARGB32); - break; - case QImage::Format_RGB16: - case QImage::Format_RGB444: - case QImage::Format_RGB555: - case QImage::Format_RGB666: - case QImage::Format_RGB888: - image = image_in.convertToFormat(QImage::Format_RGB32); - break; - default: - image = image_in; - break; - } - QPoint offset = image.offset(); int off_x = off_x_in + offset.x(); int off_y = off_y_in + offset.y(); png_structp png_ptr; png_infop info_ptr; - png_bytep* row_pointers; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); if (!png_ptr) { @@ -743,13 +721,18 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn); + + int color_type = 0; + if (image.colorCount()) + color_type = PNG_COLOR_TYPE_PALETTE; + else if (image.hasAlphaChannel()) + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + else + color_type = PNG_COLOR_TYPE_RGB; + png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(), - image.depth() == 1 ? 1 : 8 /* per channel */, - image.depth() == 32 - ? image.format() == QImage::Format_RGB32 - ? PNG_COLOR_TYPE_RGB - : PNG_COLOR_TYPE_RGB_ALPHA - : PNG_COLOR_TYPE_PALETTE, 0, 0, 0); // also sets #channels + image.depth() == 1 ? 1 : 8, // per channel + color_type, 0, 0, 0); // sets #channels if (gamma != 0.0) { png_set_gAMA(png_ptr, info_ptr, 1.0/gamma); @@ -794,8 +777,9 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_set_swap_alpha(png_ptr); } - // Qt==ARGB==Big(ARGB)==Little(BGRA) - if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { + // Qt==ARGB==Big(ARGB)==Little(BGRA). But RGB888 is RGB regardless + if (QSysInfo::ByteOrder == QSysInfo::LittleEndian + && image.format() != QImage::Format_RGB888) { png_set_bgr(png_ptr); } @@ -820,7 +804,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, if (image.depth() != 1) png_set_packing(png_ptr); - if (image.format() == QImage::Format_RGB32) + if (color_type == PNG_COLOR_TYPE_RGB && image.format() != QImage::Format_RGB888) png_set_filler(png_ptr, 0, QSysInfo::ByteOrder == QSysInfo::BigEndian ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER); @@ -841,22 +825,36 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_write_chunk(png_ptr, (png_byte*)"gIFg", data, 4); } - png_uint_32 width; - png_uint_32 height; - int bit_depth; - int color_type; - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, - 0, 0, 0); - - const uchar *data = (static_cast<const QImage *>(&image))->bits(); - int bpl = image.bytesPerLine(); - row_pointers = new png_bytep[height]; - uint y; - for (y=0; y<height; y++) { - row_pointers[y] = (png_bytep)(data + y * bpl); + int height = image.height(); + int width = image.width(); + switch (image.format()) { + case QImage::Format_Mono: + case QImage::Format_MonoLSB: + case QImage::Format_Indexed8: + case QImage::Format_RGB32: + case QImage::Format_ARGB32: + case QImage::Format_RGB888: + { + png_bytep* row_pointers = new png_bytep[height]; + for (int y=0; y<height; y++) + row_pointers[y] = (png_bytep)image.constScanLine(y); + png_write_image(png_ptr, row_pointers); + delete [] row_pointers; + } + break; + default: + { + QImage::Format fmt = image.hasAlphaChannel() ? QImage::Format_ARGB32 : QImage::Format_RGB32; + QImage row; + png_bytep row_pointers[1]; + for (int y=0; y<height; y++) { + row = image.copy(0, y, width, 1).convertToFormat(fmt); + row_pointers[0] = png_bytep(row.constScanLine(0)); + png_write_rows(png_ptr, row_pointers, 1); + } + } + break; } - png_write_image(png_ptr, row_pointers); - delete [] row_pointers; png_write_end(png_ptr, info_ptr); frames_written++; diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index 94039fb..9356037 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -317,6 +317,7 @@ PCell* ycells; int ycount; + int skip_spans; } TWorker, *PWorker; @@ -324,13 +325,19 @@ { void* buffer; long buffer_size; + long buffer_allocated_size; int band_size; void* memory; PWorker worker; } TRaster, *PRaster; - + int q_gray_rendered_spans(TRaster *raster) + { + if ( raster && raster->worker ) + return raster->worker->skip_spans > 0 ? 0 : -raster->worker->skip_spans; + return 0; + } /*************************************************************************/ /* */ @@ -1178,6 +1185,7 @@ { QT_FT_Span* span; int coverage; + int skip; /* compute the coverage line's coverage, depending on the */ @@ -1228,9 +1236,16 @@ if ( ras.num_gray_spans >= QT_FT_MAX_GRAY_SPANS ) { - if ( ras.render_span ) - ras.render_span( ras.num_gray_spans, ras.gray_spans, + if ( ras.render_span && ras.num_gray_spans > ras.skip_spans ) + { + skip = ras.skip_spans > 0 ? ras.skip_spans : 0; + ras.render_span( ras.num_gray_spans - skip, + ras.gray_spans + skip, ras.render_span_data ); + } + + ras.skip_spans -= ras.num_gray_spans; + /* ras.render_span( span->y, ras.gray_spans, count ); */ #ifdef DEBUG_GRAYS @@ -1600,7 +1615,8 @@ TBand* volatile band; int volatile n, num_bands; TPos volatile min, max, max_y; - QT_FT_BBox* clip; + QT_FT_BBox* clip; + int skip; ras.num_gray_spans = 0; @@ -1741,9 +1757,15 @@ } } - if ( ras.render_span && ras.num_gray_spans > 0 ) - ras.render_span( ras.num_gray_spans, - ras.gray_spans, ras.render_span_data ); + if ( ras.render_span && ras.num_gray_spans > ras.skip_spans ) + { + skip = ras.skip_spans > 0 ? ras.skip_spans : 0; + ras.render_span( ras.num_gray_spans - skip, + ras.gray_spans + skip, + ras.render_span_data ); + } + + ras.skip_spans -= ras.num_gray_spans; if ( ras.band_shoot > 8 && ras.band_size > 16 ) ras.band_size = ras.band_size / 2; @@ -1764,10 +1786,13 @@ if ( !raster || !raster->buffer || !raster->buffer_size ) return ErrRaster_Invalid_Argument; + if ( raster->worker ) + raster->worker->skip_spans = params->skip_spans; + // If raster object and raster buffer are allocated, but // raster size isn't of the minimum size, indicate out of // memory. - if (raster && raster->buffer && raster->buffer_size < MINIMUM_POOL_SIZE ) + if (raster->buffer_allocated_size < MINIMUM_POOL_SIZE ) return ErrRaster_OutOfMemory; /* return immediately if the outline is empty */ @@ -1906,6 +1931,7 @@ rast->buffer_size = 0; rast->worker = NULL; } + rast->buffer_allocated_size = pool_size; } } diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 09a87aa..36e1082 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4148,6 +4148,10 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, rasterize(outline, callback, (void *)spanData, rasterBuffer); } +extern "C" { + int q_gray_rendered_spans(QT_FT_Raster raster); +} + void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *) @@ -4212,10 +4216,13 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, bool done = false; int error; + int rendered_spans = 0; + while (!done) { rasterParams.flags |= (QT_FT_RASTER_FLAG_AA | QT_FT_RASTER_FLAG_DIRECT); rasterParams.gray_spans = callback; + rasterParams.skip_spans = rendered_spans; error = qt_ft_grays_raster.raster_render(*grayRaster.data(), &rasterParams); // Out of memory, reallocate some more and try again... @@ -4244,6 +4251,8 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, #endif Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal. + rendered_spans += q_gray_rendered_spans(*grayRaster.data()); + qt_ft_grays_raster.raster_done(*grayRaster.data()); qt_ft_grays_raster.raster_new(grayRaster.data()); qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize); diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 1e857e4..c1e3d66 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -517,7 +517,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath()); d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform()); } else { - d->activeStroker->setCurveThresholdFromTransform(state()->matrix); + d->activeStroker->setCurveThresholdFromTransform(QTransform()); d->activeStroker->begin(d->strokeHandler); if (types) { while (points < lastPoint) { diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 12be93e..376d68b 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6185,7 +6185,7 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF * By default, QPainter draws text anti-aliased. - \note The y-position is used as the baseline of the font. + \note The y-position is used as the top of the font. \sa Qt::AlignmentFlag, Qt::TextFlag */ diff --git a/src/gui/painting/qrasterdefs_p.h b/src/gui/painting/qrasterdefs_p.h index 19a0b16..f6339ed 100644 --- a/src/gui/painting/qrasterdefs_p.h +++ b/src/gui/painting/qrasterdefs_p.h @@ -100,7 +100,7 @@ QT_FT_BEGIN_HEADER /* distances in integer font units, or 16,16, or 26.6 fixed float */ /* pixel coordinates. */ /* */ - typedef signed long QT_FT_Pos; + typedef signed int QT_FT_Pos; /*************************************************************************/ @@ -1088,6 +1088,7 @@ QT_FT_BEGIN_HEADER QT_FT_Raster_BitSet_Func bit_set; /* doesn't work! */ void* user; QT_FT_BBox clip_box; + int skip_spans; } QT_FT_Raster_Params; diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 9cff339..9decf41 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -190,6 +190,7 @@ static inline qreal adapted_angle_on_x(const QLineF &line) QStrokerOps::QStrokerOps() : m_elements(0) , m_curveThreshold(qt_real_to_fixed(0.25)) + , m_dashThreshold(qt_real_to_fixed(0.25)) , m_customData(0) , m_moveTo(0) , m_lineTo(0) @@ -243,7 +244,7 @@ void QStrokerOps::strokePath(const QPainterPath &path, void *customData, const Q if (path.isEmpty()) return; - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(customData); int count = path.elementCount(); if (matrix.isIdentity()) { @@ -315,7 +316,7 @@ void QStrokerOps::strokePolygon(const QPointF *points, int pointCount, bool impl if (!pointCount) return; - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(data); if (matrix.isIdentity()) { moveTo(qt_real_to_fixed(points[0].x()), qt_real_to_fixed(points[0].y())); @@ -356,7 +357,7 @@ void QStrokerOps::strokeEllipse(const QRectF &rect, void *data, const QTransform } } - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(data); moveTo(qt_real_to_fixed(start.x()), qt_real_to_fixed(start.y())); for (int i=0; i<12; i+=3) { @@ -1142,7 +1143,7 @@ void QDashStroker::processCurrentSubpath() QPainterPath dashPath; - QSubpathFlatIterator it(&m_elements, m_curveThreshold); + QSubpathFlatIterator it(&m_elements, m_dashThreshold); qfixed2d prev = it.next(); bool clipping = !m_clip_rect.isEmpty(); diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index d646135..5607a8e 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -168,7 +168,7 @@ public: { qreal scale; qt_scaleForTransform(transform, &scale); - setCurveThreshold(scale == 0 ? qreal(0.5) : (qreal(0.5) / scale)); + m_dashThreshold = scale == 0 ? qreal(0.5) : (qreal(0.5) / scale); } void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; } @@ -184,6 +184,7 @@ protected: QRectF m_clip_rect; qfixed m_curveThreshold; + qfixed m_dashThreshold; void *m_customData; qStrokerMoveToHook m_moveTo; |