Current File : //usr/include/qt5/QtGui/5.9.7/QtGui/private/qpaintengine_raster_p.h |
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $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 <QtGui/private/qtguiglobal_p.h>
#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 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 legacy_rounding : 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 Q_GUI_EXPORT QRasterPaintEngine : public QPaintEngineEx
{
Q_DECLARE_PRIVATE(QRasterPaintEngine)
public:
QRasterPaintEngine(QPaintDevice *device);
~QRasterPaintEngine();
bool begin(QPaintDevice *device) Q_DECL_OVERRIDE;
bool end() Q_DECL_OVERRIDE;
void penChanged() Q_DECL_OVERRIDE;
void brushChanged() Q_DECL_OVERRIDE;
void brushOriginChanged() Q_DECL_OVERRIDE;
void opacityChanged() Q_DECL_OVERRIDE;
void compositionModeChanged() Q_DECL_OVERRIDE;
void renderHintsChanged() Q_DECL_OVERRIDE;
void transformChanged() Q_DECL_OVERRIDE;
void clipEnabledChanged() Q_DECL_OVERRIDE;
void setState(QPainterState *s) Q_DECL_OVERRIDE;
QPainterState *createState(QPainterState *orig) const Q_DECL_OVERRIDE;
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);
virtual void fillPath(const QPainterPath &path, QSpanData *fillData);
virtual void fillPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE;
void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) Q_DECL_OVERRIDE;
void drawEllipse(const QRectF &rect) Q_DECL_OVERRIDE;
void fillRect(const QRectF &rect, const QBrush &brush) Q_DECL_OVERRIDE;
void fillRect(const QRectF &rect, const QColor &color) Q_DECL_OVERRIDE;
void drawRects(const QRect *rects, int rectCount) Q_DECL_OVERRIDE;
void drawRects(const QRectF *rects, int rectCount) Q_DECL_OVERRIDE;
void drawPixmap(const QPointF &p, const QPixmap &pm) Q_DECL_OVERRIDE;
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE;
void drawImage(const QPointF &p, const QImage &img) Q_DECL_OVERRIDE;
void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr) Q_DECL_OVERRIDE;
void drawTextItem(const QPointF &p, const QTextItem &textItem) Q_DECL_OVERRIDE;
void drawLines(const QLine *line, int lineCount) Q_DECL_OVERRIDE;
void drawLines(const QLineF *line, int lineCount) Q_DECL_OVERRIDE;
void drawPoints(const QPointF *points, int pointCount) Q_DECL_OVERRIDE;
void drawPoints(const QPoint *points, int pointCount) Q_DECL_OVERRIDE;
void stroke(const QVectorPath &path, const QPen &pen) Q_DECL_OVERRIDE;
void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE;
void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE;
void clip(const QRect &rect, Qt::ClipOperation op) Q_DECL_OVERRIDE;
void clip(const QRegion ®ion, Qt::ClipOperation op) Q_DECL_OVERRIDE;
inline const QClipData *clipData() const;
void drawStaticTextItem(QStaticTextItem *textItem) Q_DECL_OVERRIDE;
virtual bool drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, const QFixedPoint *positions,
QFontEngine *fontEngine);
enum ClipType {
RectClip,
ComplexClip
};
ClipType clipType() const;
QRect clipBoundingRect() const;
void releaseBuffer();
QSize size() const;
#ifndef QT_NO_DEBUG
void saveBuffer(const QString &s) const;
#endif
#ifdef Q_OS_WIN
void setDC(HDC hdc);
HDC getDC() const;
void releaseDC(HDC hdc) const;
static bool clearTypeFontsEnabled();
#endif
QRasterBuffer *rasterBuffer();
void alphaPenBlt(const void* src, int bpl, int depth, int rx,int ry,int w,int h, bool useGammaCorrection);
Type type() const Q_DECL_OVERRIDE { return Raster; }
QPoint coordinateOffset() const Q_DECL_OVERRIDE;
bool requiresPretransformedGlyphPositions(QFontEngine *fontEngine, const QTransform &m) const Q_DECL_OVERRIDE;
bool shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &m) const Q_DECL_OVERRIDE;
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 setClipRectInDeviceCoords(const QRect &r, Qt::ClipOperation op);
QRect toNormalizedFillRect(const QRectF &rect);
inline void ensureBrush(const QBrush &brush) {
if (!qbrush_fast_equals(state()->lastBrush, brush) || 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 updateRasterState();
inline void ensureRasterState() {
if (state()->dirty)
updateRasterState();
}
};
/*******************************************************************************
* QRasterPaintEnginePrivate
*/
class 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() override;
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 QRectF &rect, const QSpanData *data) const;
ProcessSpans getBrushFunc(const QRect &rect, const QSpanData *data) const;
ProcessSpans getBrushFunc(const QRectF &rect, const QSpanData *data) const;
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_OS_WIN)
HDC hdc;
#endif
QRect deviceRect;
QRect deviceRectUnclipped;
QStroker basicStroker;
QScopedPointer<QDashStroker> dashStroker;
QScopedPointer<QT_FT_Raster> grayRaster;
QDataBuffer<QLineF> cachedLines;
QSpanData image_filler;
QSpanData image_filler_xform;
QSpanData solid_color_filler;
QFontEngine::GlyphFormat glyphCacheFormat;
QScopedPointer<QClipData> baseClip;
int deviceDepth;
uint mono_surface : 1;
uint outlinemapper_xform_dirty : 1;
QScopedPointer<QRasterizer> rasterizer;
};
class 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 ®ion);
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;
}
/*******************************************************************************
* QRasterBuffer
*/
class 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);
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();
}
inline const QClipData *QRasterPaintEngine::clipData() const {
Q_D(const QRasterPaintEngine);
if (state() && state()->clip && state()->clip->enabled)
return state()->clip;
return d->baseClip.data();
}
QT_END_NAMESPACE
#endif // QPAINTENGINE_RASTER_P_H