⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qpaintengine_raster.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************** Copyright (C) 1992-2006 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://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** 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 "qpaintengine_raster_p.h"#include "qbezier_p.h"#if defined(Q_WS_X11)#  include <qwidget.h>#  include <qx11info_x11.h>#  include <X11/Xlib.h>#  include <X11/Xutil.h>#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#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#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 = false);#endif// #define QT_DEBUG_DRAW// #define QT_DEBUG_CONVERT/******************************************************************************** * Span functions */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;};/******************************************************************************** * 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 QMatrix &m, uint txop)    {        m_m11 = m.m11();        m_m12 = m.m12();        m_m21 = m.m21();        m_m22 = m.m22();        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;    QT_FT_Outline m_outline;    uint m_txop;    int m_subpath_start;    // Matrix    qreal m_m11;    qreal m_m12;    qreal m_m21;    qreal m_m22;    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 == QPainterPrivate::TxNone) {        elements = m_elements.data();    } else {        if (m_txop == QPainterPrivate::TxTranslate) {            for (int i=0; i<m_elements.size(); ++i) {                const QPointF &e = m_elements.at(i);                m_elements_dev << QPointF(e.x() + m_dx, e.y() + m_dy);            }        } else if (m_txop == QPainterPrivate::TxScale) {            for (int i=0; i<m_elements.size(); ++i) {                const QPointF &e = m_elements.at(i);                m_elements_dev << QPointF(m_m11 * e.x() + m_dx, m_m22 * e.y() + m_dy);            }        } else {            for (int i=0; i<m_elements.size(); ++i) {                const QPointF &e = m_elements.at(i);                m_elements_dev << QPointF(m_m11 * e.x() + m_m21 * e.y() + m_dx,                                          m_m22 * e.y() + m_m12 * e.x() + m_dy);            }        }        elements = m_elements_dev.data();    }    // Check for out of dev bounds...    const QPointF *last_element = elements + element_count;    const QPointF *e = elements;    bool do_clip = false;    while (e < last_element) {        if (e->x() < -QT_RASTER_COORD_LIMIT            || e->x() > QT_RASTER_COORD_LIMIT            || e->y() < -QT_RASTER_COORD_LIMIT            || e->y() > QT_RASTER_COORD_LIMIT) {            do_clip = true;            break;        }        ++e;    }    if (do_clip) {        clipElements(elements, m_element_types.data(), element_count);    } else {        convertElements(elements, m_element_types.data(), element_count);    }}void QFTOutlineMapper::convertElements(const QPointF *elements,                                       const QPainterPath::ElementType *types,                                       int element_count){    // Translate into FT coords    const QPointF *e = elements;    for (int i=0; i<element_count; ++i) {        switch (*types) {        case QPainterPath::MoveToElement:            {                QT_FT_Vector pt_fixed = { qreal_to_fixed_26_6(e->x()),                                          qreal_to_fixed_26_6(e->y()) };                if (i != 0)                    m_contours << m_points.size() - 1;                m_points << pt_fixed;                m_tags <<  QT_FT_CURVE_TAG_ON;            }            break;        case QPainterPath::LineToElement:            {                QT_FT_Vector pt_fixed = { qreal_to_fixed_26_6(e->x()),                                          qreal_to_fixed_26_6(e->y()) };                m_points << pt_fixed;                m_tags << QT_FT_CURVE_TAG_ON;            }            break;        case QPainterPath::CurveToElement:            {                QT_FT_Vector cp1_fixed = { qreal_to_fixed_26_6(e->x()),                                           qreal_to_fixed_26_6(e->y()) };                ++e;                QT_FT_Vector cp2_fixed = { qreal_to_fixed_26_6((e)->x()),                                           qreal_to_fixed_26_6((e)->y()) };

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -