📄 qpaintengine_raster.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#define QT_FT_BEGIN_HEADER#define QT_FT_END_HEADER#include <private/qrasterdefs_p.h>#include <private/qgrayraster_p.h>#include <private/qblackraster_p.h>#include <qpainterpath.h>#include <qdebug.h>#include <qhash.h>#include <qlabel.h>#include <qbitmap.h>#include <private/qmath_p.h>#include <private/qdatabuffer_p.h>#include <private/qpainter_p.h>#include <private/qtextengine_p.h>#include <private/qpixmap_p.h>#include <private/qfontengine_p.h>#include <private/qpolygonclipper_p.h>#include <private/qrasterizer_p.h>#include "qpaintengine_raster_p.h"#include "qbezier_p.h"#if defined(Q_WS_X11)# include <private/qfontengine_ft_p.h># include <qwidget.h># include <qx11info_x11.h># include <X11/Xlib.h># include <X11/Xutil.h># undef None#elif defined(Q_WS_WIN)# include <qt_windows.h># include <qvarlengtharray.h># include <private/qfontengine_p.h>#elif defined(Q_WS_MAC)# include <private/qt_mac_p.h># if Q_BYTE_ORDER == Q_BIG_ENDIAN# define BITMAPS_ARE_MSB# endif#elif defined(Q_WS_QWS)# if !defined(QT_NO_FREETYPE)# include <private/qfontengine_ft_p.h># endif# if !defined(QT_NO_QWS_QPF2)# include <private/qfontengine_qpf_p.h># endif# include <private/qabstractfontengine_p.h>#endif#if defined(Q_WS_WIN64)# include <malloc.h>#endif#include <limits.h>#if defined(Q_WS_WIN)# ifndef SPI_GETFONTSMOOTHINGTYPE# define SPI_GETFONTSMOOTHINGTYPE 0x200A# endif# ifndef FE_FONTSMOOTHINGCLEARTYPE# define FE_FONTSMOOTHINGCLEARTYPE 0x0002# endif#endif#if defined(QT_NO_FPU) || (_MSC_VER >= 1300 && _MSC_VER < 1400)# define FLOATING_POINT_BUGGY_OR_NO_FPU#endif#define qreal_to_fixed_26_6(f) (int(f * 64))#define qt_swap_int(x, y) { int tmp = (x); (x) = (y); (y) = tmp; }#define qt_swap_qreal(x, y) { qreal tmp = (x); (x) = (y); (y) = tmp; }#ifdef Q_WS_WINvoid qt_draw_text_item(const QPointF &point, const QTextItemInt &ti, HDC hdc, bool convertToText, const QTransform &xform, const QPointF &topLeft);#endif// #define QT_DEBUG_DRAW// #define QT_DEBUG_CONVERT#define QT_FAST_SPANS/******************************************************************************** * Span functions */static void qt_span_fill_clipRect(int count, const QSpan *spans, void *userData);static void qt_span_fill_clipRegion(int count, const QSpan *spans, void *userData);static void qt_span_fill_clipped(int count, const QSpan *spans, void *userData);static void qt_span_clip(int count, const QSpan *spans, void *userData);struct ClipData{ QClipData *oldClip; QClipData *newClip; Qt::ClipOperation operation;};enum LineDrawMode { LineDrawClipped, LineDrawNormal, LineDrawIncludeLastPixel};static void drawLine_midpoint_i(int x1, int y1, int x2, int y2, ProcessSpans span_func, QSpanData *data, LineDrawMode style, const QRect &devRect);static void drawLine_midpoint_dashed_i(int x1, int y1, int x2, int y2, QPen *pen, ProcessSpans span_func, QSpanData *data, LineDrawMode style, const QRect &devRect, int *patternOffset);// static void drawLine_midpoint_f(qreal x1, qreal y1, qreal x2, qreal y2,// ProcessSpans span_func, QSpanData *data,// LineDrawMode style, const QRect &devRect);static void drawEllipse_midpoint_i(const QRect &rect, const QRect &clip, ProcessSpans pen_func, ProcessSpans brush_func, QSpanData *pen_data, QSpanData *brush_data);// This limitations comes from qgrayraster.c. Any higher and// rasterization of shapes will produce incorrect results.const int QT_RASTER_COORD_LIMIT = 16385;struct QRasterFloatPoint { qreal x; qreal y;};static const QRectF boundingRect(const QPointF *points, int pointCount){ const QPointF *e = points; const QPointF *last = points + pointCount; qreal minx, maxx, miny, maxy; minx = maxx = e->x(); miny = maxy = e->y(); while (++e < last) { if (e->x() < minx) minx = e->x(); else if (e->x() > maxx) maxx = e->x(); if (e->y() < miny) miny = e->y(); else if (e->y() > maxy) maxy = e->y(); } return QRectF(QPointF(minx, miny), QPointF(maxx, maxy));}static const QRect boundingRect(const QPoint *points, int pointCount){ const QPoint *e = points; const QPoint *last= points + pointCount; int minx, maxx, miny, maxy; minx = maxx = e->x(); miny = maxy = e->y(); while (++e < last) { if (e->x() < minx) minx = e->x(); else if (e->x() > maxx) maxx = e->x(); if (e->y() < miny) miny = e->y(); else if (e->y() > maxy) maxy = e->y(); } return QRect(QPoint(minx, miny), QPoint(maxx, maxy));}/******************************************************************************** * class QFTOutlineMapper * * Used to map between QPainterPath and the QT_FT_Outline structure used by the * freetype scanconvertor. * * The outline mapper uses a path iterator to get points from the path, * so that it is possible to transform the points as they are converted. The * callback can be a noop, translate or full-fledged xform. (Tests indicated * that using a C callback was low cost). */class QFTOutlineMapper{public: /*! Sets up the matrix to be used for conversion. This also sets up the qt_path_iterator function that is used as a callback to get points. */ void setMatrix(const QTransform &m, uint txop) { m_m11 = m.m11(); m_m12 = m.m12(); m_m13 = m.m13(); m_m21 = m.m21(); m_m22 = m.m22(); m_m23 = m.m23(); m_dx = m.dx(); m_dy = m.dy(); m_txop = txop; } void beginOutline(Qt::FillRule fillRule) {#ifdef QT_DEBUG_CONVERT printf("QFTOutlineMapper::beginOutline rule=%d\n", fillRule);#endif m_valid = true; m_elements.reset(); m_elements_dev.reset(); m_element_types.reset(); m_points.reset(); m_tags.reset(); m_contours.reset(); m_outline.flags = fillRule == Qt::WindingFill ? QT_FT_OUTLINE_NONE : QT_FT_OUTLINE_EVEN_ODD_FILL; m_subpath_start = 0; } void endOutline(); void clipElements(const QPointF *points, const QPainterPath::ElementType *types, int count); void convertElements(const QPointF *points, const QPainterPath::ElementType *types, int count); inline void moveTo(const QPointF &pt) {#ifdef QT_DEBUG_CONVERT printf("QFTOutlineMapper::moveTo() (%f, %f)\n", pt.x(), pt.y());#endif closeSubpath(); m_subpath_start = m_elements.size(); m_elements << pt; m_element_types << QPainterPath::MoveToElement; } inline void lineTo(const QPointF &pt) {#ifdef QT_DEBUG_CONVERT printf("QFTOutlineMapper::lineTo() (%f, %f)\n", pt.x(), pt.y());#endif m_elements.add(pt); m_element_types << QPainterPath::LineToElement; } inline void curveTo(const QPointF &cp1, const QPointF &cp2, const QPointF &ep) {#ifdef QT_DEBUG_CONVERT printf("QFTOutlineMapper::curveTo() (%f, %f)\n", ep.x(), ep.y());#endif m_elements << cp1 << cp2 << ep; m_element_types << QPainterPath::CurveToElement << QPainterPath::CurveToDataElement << QPainterPath::CurveToDataElement; } inline void closeSubpath() { int element_count = m_elements.size(); if (element_count > 0) { if (m_elements.at(element_count-1) != m_elements.at(m_subpath_start)) {#ifdef QT_DEBUG_CONVERT printf(" - implicitly closing\n");#endif // Put the object on the stack to avoid the odd case where // lineTo reallocs the databuffer and the QPointF & will // be invalidated. QPointF pt = m_elements.at(m_subpath_start); lineTo(pt); } } } QT_FT_Outline *outline() { if (m_valid) return &m_outline; return 0; } QT_FT_Outline *convertPath(const QPainterPath &path) { Q_ASSERT(!path.isEmpty()); int elmCount = path.elementCount();#ifdef QT_DEBUG_CONVERT printf("QFTOutlineMapper::convertPath(), size=%d\n", elmCount);#endif beginOutline(path.fillRule()); for (int index=0; index<elmCount; ++index) { const QPainterPath::Element &elm = path.elementAt(index); switch (elm.type) { case QPainterPath::MoveToElement: if (index == elmCount - 1) continue; moveTo(elm); break; case QPainterPath::LineToElement: lineTo(elm); break; case QPainterPath::CurveToElement: curveTo(elm, path.elementAt(index + 1), path.elementAt(index + 2)); index += 2; break; default: break; // This will never hit.. } } endOutline(); return outline(); }public: QDataBuffer<QPainterPath::ElementType> m_element_types; QDataBuffer<QPointF> m_elements; QDataBuffer<QPointF> m_elements_dev; QDataBuffer<QT_FT_Vector> m_points; QDataBuffer<char> m_tags; QDataBuffer<int> m_contours; QPolygonClipper<QRasterFloatPoint, QRasterFloatPoint, qreal> m_clipper; QDataBuffer<QPointF> m_polygon_dev; QRectF controlPointRect; // only valid after endOutline() QT_FT_Outline m_outline; uint m_txop; int m_subpath_start; // Matrix qreal m_m11; qreal m_m12; qreal m_m13; qreal m_m21; qreal m_m22; qreal m_m23; qreal m_dx; qreal m_dy; bool m_valid;};void QFTOutlineMapper::endOutline(){ closeSubpath(); int element_count = m_elements.size(); const QPointF *elements; // Transform the outline if (m_txop == QTransform::TxNone) { elements = m_elements.data(); } else { if (m_txop == QTransform::TxTranslate) { for (int i=0; i<m_elements.size(); ++i) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -