summaryrefslogtreecommitdiffstats
path: root/src/gui/painting/qpaintengine_raster_p.h
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /src/gui/painting/qpaintengine_raster_p.h
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/gui/painting/qpaintengine_raster_p.h')
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h567
1 files changed, 567 insertions, 0 deletions
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
new file mode 100644
index 0000000000..52f51fab16
--- /dev/null
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -0,0 +1,567 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPAINTENGINE_RASTER_P_H
+#define QPAINTENGINE_RASTER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qpaintengineex_p.h"
+#include "QtGui/qpainterpath.h"
+#include "private/qdatabuffer_p.h"
+#include "private/qdrawhelper_p.h"
+#include "private/qpaintengine_p.h"
+#include "private/qrasterizer_p.h"
+#include "private/qstroker_p.h"
+#include "private/qpainter_p.h"
+#include "private/qtextureglyphcache_p.h"
+#include "private/qoutlinemapper_p.h"
+
+#include <stdlib.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOutlineMapper;
+class QRasterPaintEnginePrivate;
+class QRasterBuffer;
+class QClipData;
+class QCustomRasterPaintDevice;
+
+class QRasterPaintEngineState : public QPainterState
+{
+public:
+ QRasterPaintEngineState(QRasterPaintEngineState &other);
+ QRasterPaintEngineState();
+ ~QRasterPaintEngineState();
+
+
+ QPen lastPen;
+ QSpanData penData;
+ QStrokerOps *stroker;
+ uint strokeFlags;
+
+ QBrush lastBrush;
+ QSpanData brushData;
+ uint fillFlags;
+
+ uint pixmapFlags;
+ int intOpacity;
+
+ qreal txscale;
+
+ QClipData *clip;
+// QRect clipRect;
+// QRegion clipRegion;
+
+// QPainter::RenderHints hints;
+// QPainter::CompositionMode compositionMode;
+
+ uint dirty;
+
+ struct Flags {
+ uint has_clip_ownership : 1; // should delete the clip member..
+ uint fast_pen : 1; // cosmetic 1-width pens, using midpoint drawlines
+ uint non_complex_pen : 1; // can use rasterizer, rather than stroker
+ uint antialiased : 1;
+ uint bilinear : 1;
+ uint fast_text : 1;
+ uint int_xform : 1;
+ uint tx_noshear : 1;
+ uint fast_images : 1;
+ };
+
+ union {
+ Flags flags;
+ uint flag_bits;
+ };
+};
+
+
+
+
+/*******************************************************************************
+ * QRasterPaintEngine
+ */
+class
+#ifdef Q_WS_QWS
+Q_GUI_EXPORT
+#endif
+QRasterPaintEngine : public QPaintEngineEx
+{
+ Q_DECLARE_PRIVATE(QRasterPaintEngine)
+public:
+
+ QRasterPaintEngine(QPaintDevice *device);
+ ~QRasterPaintEngine();
+ bool begin(QPaintDevice *device);
+ bool end();
+
+ void penChanged();
+ void brushChanged();
+ void brushOriginChanged();
+ void opacityChanged();
+ void compositionModeChanged();
+ void renderHintsChanged();
+ void transformChanged();
+ void clipEnabledChanged();
+
+ void setState(QPainterState *s);
+ QPainterState *createState(QPainterState *orig) const;
+ inline QRasterPaintEngineState *state() {
+ return static_cast<QRasterPaintEngineState *>(QPaintEngineEx::state());
+ }
+ inline const QRasterPaintEngineState *state() const {
+ return static_cast<const QRasterPaintEngineState *>(QPaintEngineEx::state());
+ }
+
+ void updateBrush(const QBrush &brush);
+ void updatePen(const QPen &pen);
+
+ void updateMatrix(const QTransform &matrix);
+
+ void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
+ void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode);
+ void fillPath(const QPainterPath &path, QSpanData *fillData);
+ void fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
+
+ void drawEllipse(const QRectF &rect);
+
+ void fillRect(const QRectF &rect, const QBrush &brush);
+ void fillRect(const QRectF &rect, const QColor &color);
+
+ void drawRects(const QRect *rects, int rectCount);
+ void drawRects(const QRectF *rects, int rectCount);
+
+ void drawPixmap(const QPointF &p, const QPixmap &pm);
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+ void drawImage(const QPointF &p, const QImage &img);
+ void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
+ Qt::ImageConversionFlags falgs = Qt::AutoColor);
+ void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr);
+ void drawTextItem(const QPointF &p, const QTextItem &textItem);
+
+ void drawLines(const QLine *line, int lineCount);
+ void drawLines(const QLineF *line, int lineCount);
+
+ void drawPoints(const QPointF *points, int pointCount);
+ void drawPoints(const QPoint *points, int pointCount);
+
+ void stroke(const QVectorPath &path, const QPen &pen);
+ void fill(const QVectorPath &path, const QBrush &brush);
+
+ void strokePolygonCosmetic(const QPoint *pts, int pointCount, PolygonDrawMode mode);
+ void strokePolygonCosmetic(const QPointF *pt, int pointCount, PolygonDrawMode mode);
+
+ void clip(const QVectorPath &path, Qt::ClipOperation op);
+ void clip(const QRect &rect, Qt::ClipOperation op);
+ void clip(const QRegion &region, Qt::ClipOperation op);
+
+ void drawStaticTextItem(QStaticTextItem *textItem);
+
+ enum ClipType {
+ RectClip,
+ ComplexClip
+ };
+ ClipType clipType() const;
+ QRect clipBoundingRect() const;
+
+#ifdef Q_NO_USING_KEYWORD
+ inline void drawEllipse(const QRect &rect) { QPaintEngineEx::drawEllipse(rect); }
+#else
+ using QPaintEngineEx::drawPolygon;
+ using QPaintEngineEx::drawEllipse;
+#endif
+
+ void releaseBuffer();
+
+ QSize size() const;
+
+#ifndef QT_NO_DEBUG
+ void saveBuffer(const QString &s) const;
+#endif
+
+#ifdef Q_WS_MAC
+ void setCGContext(CGContextRef ref);
+ CGContextRef getCGContext() const;
+#endif
+
+#ifdef Q_WS_WIN
+ void setDC(HDC hdc);
+ HDC getDC() const;
+ void releaseDC(HDC hdc) const;
+#endif
+
+ void alphaPenBlt(const void* src, int bpl, int depth, int rx,int ry,int w,int h);
+
+ Type type() const { return Raster; }
+
+ QPoint coordinateOffset() const;
+
+#if defined(Q_WS_QWS) && !defined(QT_NO_RASTERCALLBACKS)
+ virtual void drawColorSpans(const QSpan *spans, int count, uint color);
+ virtual void drawBufferSpan(const uint *buffer, int bufsize,
+ int x, int y, int length, uint const_alpha);
+#endif
+
+protected:
+ QRasterPaintEngine(QRasterPaintEnginePrivate &d, QPaintDevice *);
+private:
+ friend struct QSpanData;
+ friend class QBlitterPaintEngine;
+ friend class QBlitterPaintEnginePrivate;
+ void init();
+
+ void fillRect(const QRectF &rect, QSpanData *data);
+ void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill);
+
+ bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions,
+ QFontEngine *fontEngine);
+
+#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
+ void drawGlyphsS60(const QPointF &p, const QTextItemInt &ti);
+#endif // Q_OS_SYMBIAN && QT_NO_FREETYPE
+
+ bool setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op);
+
+ inline void ensureBrush(const QBrush &brush) {
+ if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags))
+ updateBrush(brush);
+ }
+ inline void ensureBrush() { ensureBrush(state()->brush); }
+
+ inline void ensurePen(const QPen &pen) {
+ if (!qpen_fast_equals(state()->lastPen, pen) || (pen.style() != Qt::NoPen && state()->strokeFlags))
+ updatePen(pen);
+ }
+ inline void ensurePen() { ensurePen(state()->pen); }
+
+ void updateOutlineMapper();
+ inline void ensureOutlineMapper();
+
+ void updateState();
+ inline void ensureState() {
+ if (state()->dirty)
+ updateState();
+ }
+};
+
+
+/*******************************************************************************
+ * QRasterPaintEnginePrivate
+ */
+class
+#ifdef Q_WS_QWS
+Q_GUI_EXPORT
+#endif
+QRasterPaintEnginePrivate : public QPaintEngineExPrivate
+{
+ Q_DECLARE_PUBLIC(QRasterPaintEngine)
+public:
+ QRasterPaintEnginePrivate();
+
+ void rasterizeLine_dashed(QLineF line, qreal width,
+ int *dashIndex, qreal *dashOffset, bool *inDash);
+ void rasterize(QT_FT_Outline *outline, ProcessSpans callback, QSpanData *spanData, QRasterBuffer *rasterBuffer);
+ void rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *rasterBuffer);
+ void updateMatrixData(QSpanData *spanData, const QBrush &brush, const QTransform &brushMatrix);
+
+ void systemStateChanged();
+
+ void drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func,
+ const QRect &clip, int alpha, const QRect &sr = QRect());
+
+ QTransform brushMatrix() const {
+ Q_Q(const QRasterPaintEngine);
+ const QRasterPaintEngineState *s = q->state();
+ QTransform m(s->matrix);
+ m.translate(s->brushOrigin.x(), s->brushOrigin.y());
+ return m;
+ }
+
+ bool isUnclipped_normalized(const QRect &rect) const;
+ bool isUnclipped(const QRect &rect, int penWidth) const;
+ bool isUnclipped(const QRectF &rect, int penWidth) const;
+ ProcessSpans getPenFunc(const QRect &rect, const QSpanData *data) const;
+ ProcessSpans getPenFunc(const QRectF &rect, const QSpanData *data) const;
+ ProcessSpans getBrushFunc(const QRect &rect, const QSpanData *data) const;
+ ProcessSpans getBrushFunc(const QRectF &rect, const QSpanData *data) const;
+
+#ifdef Q_WS_QWS
+ void prepare(QCustomRasterPaintDevice *);
+#endif
+
+ inline const QClipData *clip() const;
+
+ void initializeRasterizer(QSpanData *data);
+
+ void recalculateFastImages();
+ bool canUseFastImageBlending(QPainter::CompositionMode mode, const QImage &image) const;
+
+ QPaintDevice *device;
+ QScopedPointer<QOutlineMapper> outlineMapper;
+ QScopedPointer<QRasterBuffer> rasterBuffer;
+
+#if defined (Q_WS_WIN)
+ HDC hdc;
+#elif defined(Q_WS_MAC)
+ CGContextRef cgContext;
+#endif
+
+ QRect deviceRect;
+
+ QStroker basicStroker;
+ QScopedPointer<QDashStroker> dashStroker;
+
+ QScopedPointer<QT_FT_Raster> grayRaster;
+
+ QDataBuffer<QLineF> cachedLines;
+ QSpanData image_filler;
+ QSpanData image_filler_xform;
+ QSpanData solid_color_filler;
+
+
+ QFontEngineGlyphCache::Type glyphCacheType;
+
+ QScopedPointer<QClipData> baseClip;
+
+ int deviceDepth;
+
+ uint mono_surface : 1;
+ uint outlinemapper_xform_dirty : 1;
+
+#ifdef Q_WS_WIN
+ uint isPlain45DegreeRotation : 1;
+#endif
+
+ QScopedPointer<QRasterizer> rasterizer;
+};
+
+
+class
+#ifdef Q_WS_QWS
+Q_GUI_EXPORT
+#endif
+QClipData {
+public:
+ QClipData(int height);
+ ~QClipData();
+
+ int clipSpanHeight;
+ struct ClipLine {
+ int count;
+ QSpan *spans;
+ } *m_clipLines;
+
+ void initialize();
+
+ inline ClipLine *clipLines() {
+ if (!m_clipLines)
+ initialize();
+ return m_clipLines;
+ }
+
+ inline QSpan *spans() {
+ if (!m_spans)
+ initialize();
+ return m_spans;
+ }
+
+ int allocated;
+ int count;
+ QSpan *m_spans;
+ int xmin, xmax, ymin, ymax;
+
+ QRect clipRect;
+ QRegion clipRegion;
+
+ uint enabled : 1;
+ uint hasRectClip : 1;
+ uint hasRegionClip : 1;
+
+ void appendSpan(int x, int length, int y, int coverage);
+ void appendSpans(const QSpan *s, int num);
+
+ // ### Should optimize and actually kill the QSpans if the rect is
+ // ### a subset of The current region. Thus the "fast" clipspan
+ // ### callback can be used
+ void setClipRect(const QRect &rect);
+ void setClipRegion(const QRegion &region);
+ void fixup();
+};
+
+inline void QClipData::appendSpan(int x, int length, int y, int coverage)
+{
+ Q_ASSERT(m_spans); // initialize() has to be called prior to adding spans..
+
+ if (count == allocated) {
+ allocated *= 2;
+ m_spans = (QSpan *)realloc(m_spans, allocated*sizeof(QSpan));
+ }
+ m_spans[count].x = x;
+ m_spans[count].len = length;
+ m_spans[count].y = y;
+ m_spans[count].coverage = coverage;
+ ++count;
+}
+
+inline void QClipData::appendSpans(const QSpan *s, int num)
+{
+ Q_ASSERT(m_spans);
+
+ if (count + num > allocated) {
+ do {
+ allocated *= 2;
+ } while (count + num > allocated);
+ m_spans = (QSpan *)realloc(m_spans, allocated*sizeof(QSpan));
+ }
+ memcpy(m_spans+count, s, num*sizeof(QSpan));
+ count += num;
+}
+
+#ifdef Q_WS_QWS
+class Q_GUI_EXPORT QCustomRasterPaintDevice : public QPaintDevice
+{
+public:
+ QCustomRasterPaintDevice(QWidget *w) : widget(w) {}
+
+ int devType() const { return QInternal::CustomRaster; }
+
+ virtual int metric(PaintDeviceMetric m) const;
+
+ virtual void* memory() const { return 0; }
+
+ virtual QImage::Format format() const {
+ return QImage::Format_ARGB32_Premultiplied;
+ }
+
+ virtual int bytesPerLine() const;
+
+ virtual QSize size() const {
+ return static_cast<QRasterPaintEngine*>(paintEngine())->size();
+ }
+
+private:
+ QWidget *widget;
+};
+#endif // Q_WS_QWS
+
+/*******************************************************************************
+ * QRasterBuffer
+ */
+class
+#ifdef Q_WS_QWS
+Q_GUI_EXPORT
+#endif
+QRasterBuffer
+{
+public:
+ QRasterBuffer() : m_width(0), m_height(0), m_buffer(0) { init(); }
+
+ ~QRasterBuffer();
+
+ void init();
+
+ QImage::Format prepare(QImage *image);
+ QImage::Format prepare(QPixmap *pix);
+#ifdef Q_WS_QWS
+ void prepare(QCustomRasterPaintDevice *device);
+#endif
+ void prepare(int w, int h);
+ void prepareBuffer(int w, int h);
+
+ void resetBuffer(int val=0);
+
+ uchar *scanLine(int y) { Q_ASSERT(y>=0); Q_ASSERT(y<m_height); return m_buffer + y * bytes_per_line; }
+
+#ifndef QT_NO_DEBUG
+ QImage bufferImage() const;
+#endif
+
+ void flushToARGBImage(QImage *image) const;
+
+ int width() const { return m_width; }
+ int height() const { return m_height; }
+ int bytesPerLine() const { return bytes_per_line; }
+ int bytesPerPixel() const { return bytes_per_pixel; }
+
+ uchar *buffer() const { return m_buffer; }
+
+ bool monoDestinationWithClut;
+ QRgb destColor0;
+ QRgb destColor1;
+
+ QPainter::CompositionMode compositionMode;
+ QImage::Format format;
+ DrawHelper *drawHelper;
+ QImage colorizeBitmap(const QImage &image, const QColor &color);
+
+private:
+ int m_width;
+ int m_height;
+ int bytes_per_line;
+ int bytes_per_pixel;
+ uchar *m_buffer;
+};
+
+inline void QRasterPaintEngine::ensureOutlineMapper() {
+ if (d_func()->outlinemapper_xform_dirty)
+ updateOutlineMapper();
+}
+
+inline const QClipData *QRasterPaintEnginePrivate::clip() const {
+ Q_Q(const QRasterPaintEngine);
+ if (q->state() && q->state()->clip && q->state()->clip->enabled)
+ return q->state()->clip;
+ return baseClip.data();
+}
+
+
+QT_END_NAMESPACE
+#endif // QPAINTENGINE_RASTER_P_H