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

📄 qrasterizer.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** 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.******************************************************************************/#include "qrasterizer_p.h"#include <QDebug>#include <QLine>#include <QPoint>#include <QRect>#include <QTransform>#include <private/qmath_p.h>#include <private/qdrawhelper_p.h>#include <private/qpaintengine_raster_p.h>typedef int Q16Dot16;#define Q16Dot16ToFloat(i) ((i)/65536.)#define FloatToQ16Dot16(i) (int)((i) * 65536.)#define IntToQ16Dot16(i) ((i) << 16)#define Q16Dot16ToInt(i) ((i) >> 16)#define Q16Dot16Factor 65536#define Q16Dot16Multiply(x, y) (int)((qlonglong(x) * qlonglong(y)) >> 16)#define Q16Dot16FastMultiply(x, y) (((x) * (y)) >> 16)#define SPAN_BUFFER_SIZE 256class QSpanBuffer {public:    QSpanBuffer(QSpanData *data, QRasterBuffer *rb, const QRect &deviceRect)        : m_spanCount(0)        , m_data(data)        , m_rb(rb)        , m_blend(data->blend)        , m_deviceRect(deviceRect)    {    }    ~QSpanBuffer()    {        flushSpans();    }    void addSpan(int x, unsigned int len, int y, unsigned char coverage)    {        if (!coverage || !len)            return;        Q_ASSERT(y >= m_deviceRect.top());        Q_ASSERT(y <= m_deviceRect.bottom());        Q_ASSERT(x >= m_deviceRect.left());        Q_ASSERT(x + int(len) - 1 <= m_deviceRect.right());        m_spans[m_spanCount].x = x;        m_spans[m_spanCount].len = len;        m_spans[m_spanCount].y = y;        m_spans[m_spanCount].coverage = coverage;        if (++m_spanCount == SPAN_BUFFER_SIZE)            flushSpans();    }    void setBoundingRect(int left, int top, int right, int bottom)    {        m_blend = isUnclipped(QRect(left, top, right - left + 1, bottom - top + 1))                    ? m_data->unclipped_blend                    : m_data->blend;    }private:    bool isUnclipped(const QRect &r) {        if (m_rb->clip)            return false;        if (m_rb->clipRect == m_deviceRect)            return true;        if (!m_rb->clipRect.isEmpty()) {            const QRect &r1 = m_rb->clipRect;            return (r.left() >= r1.left() && r.right() <= r1.right()                    && r.top() >= r1.top() && r.bottom() <= r1.bottom());        } else {            return qt_region_strictContains(m_rb->clipRegion, r);        }    }    void flushSpans()    {        m_blend(m_spanCount, m_spans, m_data);        m_spanCount = 0;    }    QT_FT_Span m_spans[SPAN_BUFFER_SIZE];    int m_spanCount;    QSpanData *m_data;    QRasterBuffer *m_rb;    QRasterPaintEnginePrivate *m_pe;    ProcessSpans m_blend;    QRect m_deviceRect;};class QRasterizerPrivate{public:    bool antialiased;    QSpanData *spanData;    QRasterBuffer *rasterBuffer;    QRect deviceRect;};QRasterizer::QRasterizer()    : d(new QRasterizerPrivate){}QRasterizer::~QRasterizer(){    delete d;}void QRasterizer::initialize(bool antialiased, QRasterBuffer *rb){    d->antialiased = antialiased;    d->rasterBuffer = rb;}void QRasterizer::setSpanData(QSpanData *data){    d->spanData = data;}void QRasterizer::setDeviceRect(const QRect &deviceRect){    d->deviceRect = deviceRect;}static Q16Dot16 intersectPixelFP(int x, Q16Dot16 top, Q16Dot16 bottom, Q16Dot16 leftIntersectX, Q16Dot16 rightIntersectX, Q16Dot16 slope, Q16Dot16 invSlope){    Q16Dot16 leftX = IntToQ16Dot16(x);    Q16Dot16 rightX = IntToQ16Dot16(x) + Q16Dot16Factor;    Q16Dot16 leftIntersectY, rightIntersectY;    if (slope > 0) {        leftIntersectY = top + Q16Dot16Multiply(leftX - leftIntersectX, invSlope);        rightIntersectY = leftIntersectY + invSlope;    } else {        leftIntersectY = top + Q16Dot16Multiply(leftX - rightIntersectX, invSlope);        rightIntersectY = leftIntersectY + invSlope;    }    if (leftIntersectX >= leftX && rightIntersectX <= rightX) {        return Q16Dot16Multiply(bottom - top, leftIntersectX - leftX + ((rightIntersectX - leftIntersectX) >> 1));    } else if (leftIntersectX >= rightX) {        return bottom - top;    } else if (leftIntersectX >= leftX) {        if (slope > 0) {            return (bottom - top) - Q16Dot16FastMultiply((rightX - leftIntersectX) >> 1, rightIntersectY - top);        } else {            return (bottom - top) - Q16Dot16FastMultiply((rightX - leftIntersectX) >> 1, bottom - rightIntersectY);        }    } else if (rightIntersectX <= leftX) {        return 0;    } else if (rightIntersectX <= rightX) {        if (slope > 0) {            return Q16Dot16FastMultiply((rightIntersectX - leftX) >> 1, bottom - leftIntersectY);        } else {            return Q16Dot16FastMultiply((rightIntersectX - leftX) >> 1, leftIntersectY - top);        }    } else {        if (slope > 0) {            return (bottom - rightIntersectY) + ((rightIntersectY - leftIntersectY) >> 1);        } else {            return (rightIntersectY - top) + ((leftIntersectY - rightIntersectY) >> 1);        }    }}void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bool squareCap){    QPointF pa = a;    QPointF pb = b;    QSpanBuffer buffer(d->spanData, d->rasterBuffer, d->deviceRect);    if (qFuzzyCompare(pa.y(), pb.y())) {        const qreal x = (a.x() + b.x()) * 0.5f;        const qreal dx = qAbs(b.x() - a.x()) * 0.5f;        const qreal dy = width * dx;        pa = QPointF(x, a.y() - dy);        pb = QPointF(x, a.y() + dy);        if (squareCap)            width = 1 / width + 1.0f;        else            width = 1 / width;        squareCap = false;    }    if (qFuzzyCompare(pa.x(), pb.x())) {        if (pa.y() > pb.y())            qSwap(pa, pb);        const qreal dy = pb.y() - pa.y();        const qreal halfWidth = 0.5f * width * dy;        if (squareCap) {            pa.ry() -= halfWidth;            pb.ry() += halfWidth;        }        qreal left = pa.x() - halfWidth;        qreal right = pa.x() + halfWidth;        left = qBound(qreal(d->deviceRect.left()), left, qreal(d->deviceRect.right() + 1));        right = qBound(qreal(d->deviceRect.left()), right, qreal(d->deviceRect.right() + 1));        pa.ry() = qBound(qreal(d->deviceRect.top()), pa.y(), qreal(d->deviceRect.bottom() + 1));        pb.ry() = qBound(qreal(d->deviceRect.top()), pb.y(), qreal(d->deviceRect.bottom() + 1));        if (qFuzzyCompare(left, right) || qFuzzyCompare(pa.y(), pb.y()))            return;        if (d->antialiased) {            int iTop = int(pa.y()) ;            int iBottom = int(pb.y());            int iLeft = int(left);            int iRight = int(right);            buffer.setBoundingRect(iLeft, iTop, iRight, iBottom);            Q16Dot16 leftWidth = FloatToQ16Dot16(iLeft + 1.0f - left);            Q16Dot16 rightWidth = FloatToQ16Dot16(right - iRight);            Q16Dot16 coverage[3];            int x[3];            int len[3];            int n = 1;            if (iLeft == iRight) {                coverage[0] = leftWidth + rightWidth;                x[0] = iLeft;                len[0] = 1;            } else {                coverage[0] = leftWidth;                x[0] = iLeft;                len[0] = 1;                if (leftWidth == Q16Dot16Factor) {                    len[0] = iRight - iLeft;                } else if (iRight - iLeft > 1) {                    coverage[1] = Q16Dot16Factor;                    x[1] = iLeft + 1;                    len[1] = iRight - iLeft - 1;                    ++n;

⌨️ 快捷键说明

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