src/gui/painting/qstroker_p.h
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #ifndef QSTROKER_P_H
       
    43 #define QSTROKER_P_H
       
    44 
       
    45 //
       
    46 //  W A R N I N G
       
    47 //  -------------
       
    48 //
       
    49 // This file is not part of the Qt API.  It exists purely as an
       
    50 // implementation detail.  This header file may change from version to
       
    51 // version without notice, or even be removed.
       
    52 //
       
    53 // We mean it.
       
    54 //
       
    55 
       
    56 #include "QtGui/qpainterpath.h"
       
    57 #include "private/qdatabuffer_p.h"
       
    58 #include "private/qnumeric_p.h"
       
    59 
       
    60 QT_BEGIN_NAMESPACE
       
    61 
       
    62 // #define QFIXED_IS_26_6
       
    63 
       
    64 #if defined QFIXED_IS_26_6
       
    65 typedef int qfixed;
       
    66 #define qt_real_to_fixed(real) qfixed(real * 64)
       
    67 #define qt_int_to_fixed(real) qfixed(int(real) << 6)
       
    68 #define qt_fixed_to_real(fixed) qreal(fixed / qreal(64))
       
    69 #define qt_fixed_to_int(fixed) int(fixed >> 6)
       
    70 struct qfixed2d
       
    71 {
       
    72     qfixed x;
       
    73     qfixed y;
       
    74 
       
    75     bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
       
    76 };
       
    77 #elif defined QFIXED_IS_32_32
       
    78 typedef qint64 qfixed;
       
    79 #define qt_real_to_fixed(real) qfixed(real * double(qint64(1) << 32))
       
    80 #define qt_fixed_to_real(fixed) qreal(fixed / double(qint64(1) << 32))
       
    81 struct qfixed2d
       
    82 {
       
    83     qfixed x;
       
    84     qfixed y;
       
    85 
       
    86     bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
       
    87 };
       
    88 #elif defined QFIXED_IS_16_16
       
    89 typedef int qfixed;
       
    90 #define qt_real_to_fixed(real) qfixed(real * qreal(1 << 16))
       
    91 #define qt_fixed_to_real(fixed) qreal(fixed / qreal(1 << 16))
       
    92 struct qfixed2d
       
    93 {
       
    94     qfixed x;
       
    95     qfixed y;
       
    96 
       
    97     bool operator==(const qfixed2d &other) const { return x == other.x && y == other.y; }
       
    98 };
       
    99 #else
       
   100 typedef qreal qfixed;
       
   101 #define qt_real_to_fixed(real) qfixed(real)
       
   102 #define qt_fixed_to_real(fixed) fixed
       
   103 struct qfixed2d
       
   104 {
       
   105     qfixed x;
       
   106     qfixed y;
       
   107 
       
   108     bool operator==(const qfixed2d &other) const { return qFuzzyCompare(x, other.x)
       
   109                                                        && qFuzzyCompare(y, other.y); }
       
   110 };
       
   111 #endif
       
   112 
       
   113 #define QT_PATH_KAPPA 0.5522847498
       
   114 
       
   115 QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLength,
       
   116                           QPointF *controlPoints, int *point_count);
       
   117 
       
   118 qreal qt_t_for_arc_angle(qreal angle);
       
   119 
       
   120 typedef void (*qStrokerMoveToHook)(qfixed x, qfixed y, void *data);
       
   121 typedef void (*qStrokerLineToHook)(qfixed x, qfixed y, void *data);
       
   122 typedef void (*qStrokerCubicToHook)(qfixed c1x, qfixed c1y,
       
   123                                     qfixed c2x, qfixed c2y,
       
   124                                     qfixed ex, qfixed ey,
       
   125                                     void *data);
       
   126 
       
   127 class Q_GUI_EXPORT QStrokerOps
       
   128 {
       
   129 public:
       
   130     struct Element {
       
   131         QPainterPath::ElementType type;
       
   132         qfixed x;
       
   133         qfixed y;
       
   134 
       
   135         inline bool isMoveTo() const { return type == QPainterPath::MoveToElement; }
       
   136         inline bool isLineTo() const { return type == QPainterPath::LineToElement; }
       
   137         inline bool isCurveTo() const { return type == QPainterPath::CurveToElement; }
       
   138 
       
   139         operator qfixed2d () { qfixed2d pt = { x, y }; return pt; }
       
   140     };
       
   141 
       
   142     QStrokerOps();
       
   143     virtual ~QStrokerOps();
       
   144 
       
   145     void setMoveToHook(qStrokerMoveToHook moveToHook) { m_moveTo = moveToHook; }
       
   146     void setLineToHook(qStrokerLineToHook lineToHook) { m_lineTo = lineToHook; }
       
   147     void setCubicToHook(qStrokerCubicToHook cubicToHook) { m_cubicTo = cubicToHook; }
       
   148 
       
   149     virtual void begin(void *customData);
       
   150     virtual void end();
       
   151 
       
   152     inline void moveTo(qfixed x, qfixed y);
       
   153     inline void lineTo(qfixed x, qfixed y);
       
   154     inline void cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey);
       
   155 
       
   156     void strokePath(const QPainterPath &path, void *data, const QTransform &matrix);
       
   157     void strokePolygon(const QPointF *points, int pointCount, bool implicit_close,
       
   158                        void *data, const QTransform &matrix);
       
   159     void strokeEllipse(const QRectF &ellipse, void *data, const QTransform &matrix);
       
   160 
       
   161     QRectF clipRect() const { return m_clip_rect; }
       
   162     void setClipRect(const QRectF &clip) { m_clip_rect = clip; }
       
   163 
       
   164 protected:
       
   165     inline void emitMoveTo(qfixed x, qfixed y);
       
   166     inline void emitLineTo(qfixed x, qfixed y);
       
   167     inline void emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey);
       
   168 
       
   169     virtual void processCurrentSubpath() = 0;
       
   170     QDataBuffer<Element> m_elements;
       
   171 
       
   172     QRectF m_clip_rect;
       
   173 
       
   174     void *m_customData;
       
   175     qStrokerMoveToHook m_moveTo;
       
   176     qStrokerLineToHook m_lineTo;
       
   177     qStrokerCubicToHook m_cubicTo;
       
   178 
       
   179 };
       
   180 
       
   181 class Q_GUI_EXPORT QStroker : public QStrokerOps
       
   182 {
       
   183 public:
       
   184 
       
   185     enum LineJoinMode {
       
   186         FlatJoin,
       
   187         SquareJoin,
       
   188         MiterJoin,
       
   189         RoundJoin,
       
   190         RoundCap,
       
   191         SvgMiterJoin
       
   192     };
       
   193 
       
   194     QStroker();
       
   195     ~QStroker();
       
   196 
       
   197     void setStrokeWidth(qfixed width) { m_strokeWidth = width; }
       
   198     qfixed strokeWidth() const { return m_strokeWidth; }
       
   199 
       
   200     void setCapStyle(Qt::PenCapStyle capStyle) { m_capStyle = joinModeForCap(capStyle); }
       
   201     Qt::PenCapStyle capStyle() const { return capForJoinMode(m_capStyle); }
       
   202     LineJoinMode capStyleMode() const { return m_capStyle; }
       
   203 
       
   204     void setJoinStyle(Qt::PenJoinStyle style) { m_joinStyle = joinModeForJoin(style); }
       
   205     Qt::PenJoinStyle joinStyle() const { return joinForJoinMode(m_joinStyle); }
       
   206     LineJoinMode joinStyleMode() const { return m_joinStyle; }
       
   207 
       
   208     void setMiterLimit(qfixed length) { m_miterLimit = length; }
       
   209     qfixed miterLimit() const { return m_miterLimit; }
       
   210 
       
   211     void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; }
       
   212     qfixed curveThreshold() const { return m_curveThreshold; }
       
   213 
       
   214     void joinPoints(qfixed x, qfixed y, const QLineF &nextLine, LineJoinMode join);
       
   215     inline void emitMoveTo(qfixed x, qfixed y);
       
   216     inline void emitLineTo(qfixed x, qfixed y);
       
   217     inline void emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey);
       
   218 
       
   219 protected:
       
   220     static Qt::PenCapStyle capForJoinMode(LineJoinMode mode);
       
   221     static LineJoinMode joinModeForCap(Qt::PenCapStyle);
       
   222 
       
   223     static Qt::PenJoinStyle joinForJoinMode(LineJoinMode mode);
       
   224     static LineJoinMode joinModeForJoin(Qt::PenJoinStyle joinStyle);
       
   225 
       
   226     virtual void processCurrentSubpath();
       
   227 
       
   228     qfixed m_strokeWidth;
       
   229     qfixed m_miterLimit;
       
   230     qfixed m_curveThreshold;
       
   231 
       
   232     LineJoinMode m_capStyle;
       
   233     LineJoinMode m_joinStyle;
       
   234 
       
   235     qfixed m_back1X;
       
   236     qfixed m_back1Y;
       
   237 
       
   238     qfixed m_back2X;
       
   239     qfixed m_back2Y;
       
   240 };
       
   241 
       
   242 class Q_GUI_EXPORT QDashStroker : public QStrokerOps
       
   243 {
       
   244 public:
       
   245     QDashStroker(QStroker *stroker);
       
   246 
       
   247     QStroker *stroker() const { return m_stroker; }
       
   248 
       
   249     static QVector<qfixed> patternForStyle(Qt::PenStyle style);
       
   250 
       
   251     void setDashPattern(const QVector<qfixed> &dashPattern) { m_dashPattern = dashPattern; }
       
   252     QVector<qfixed> dashPattern() const { return m_dashPattern; }
       
   253 
       
   254     void setDashOffset(qreal offset) { m_dashOffset = offset; }
       
   255     qreal dashOffset() const { return m_dashOffset; }
       
   256 
       
   257     virtual void begin(void *data);
       
   258     virtual void end();
       
   259 
       
   260     inline void setStrokeWidth(qreal width) { m_stroke_width = width; }
       
   261     inline void setMiterLimit(qreal limit) { m_miter_limit = limit; }
       
   262 
       
   263 protected:
       
   264     virtual void processCurrentSubpath();
       
   265 
       
   266     QStroker *m_stroker;
       
   267     QVector<qfixed> m_dashPattern;
       
   268     qreal m_dashOffset;
       
   269 
       
   270     qreal m_stroke_width;
       
   271     qreal m_miter_limit;
       
   272 };
       
   273 
       
   274 
       
   275 /*******************************************************************************
       
   276  * QStrokerOps inline membmers
       
   277  */
       
   278 
       
   279 inline void QStrokerOps::emitMoveTo(qfixed x, qfixed y)
       
   280 {
       
   281     Q_ASSERT(m_moveTo);
       
   282     m_moveTo(x, y, m_customData);
       
   283 }
       
   284 
       
   285 inline void QStrokerOps::emitLineTo(qfixed x, qfixed y)
       
   286 {
       
   287     Q_ASSERT(m_lineTo);
       
   288     m_lineTo(x, y, m_customData);
       
   289 }
       
   290 
       
   291 inline void QStrokerOps::emitCubicTo(qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey)
       
   292 {
       
   293     Q_ASSERT(m_cubicTo);
       
   294     m_cubicTo(c1x, c1y, c2x, c2y, ex, ey, m_customData);
       
   295 }
       
   296 
       
   297 inline void QStrokerOps::moveTo(qfixed x, qfixed y)
       
   298 {
       
   299     if (m_elements.size()>1)
       
   300         processCurrentSubpath();
       
   301     m_elements.reset();
       
   302     Element e = { QPainterPath::MoveToElement, x, y };
       
   303     m_elements.add(e);
       
   304 }
       
   305 
       
   306 inline void QStrokerOps::lineTo(qfixed x, qfixed y)
       
   307 {
       
   308     Element e = { QPainterPath::LineToElement, x, y };
       
   309     m_elements.add(e);
       
   310 }
       
   311 
       
   312 inline void QStrokerOps::cubicTo(qfixed x1, qfixed y1, qfixed x2, qfixed y2, qfixed ex, qfixed ey)
       
   313 {
       
   314     Element c1 = { QPainterPath::CurveToElement, x1, y1 };
       
   315     Element c2 = { QPainterPath::CurveToDataElement, x2, y2 };
       
   316     Element e = { QPainterPath::CurveToDataElement, ex, ey };
       
   317     m_elements.add(c1);
       
   318     m_elements.add(c2);
       
   319     m_elements.add(e);
       
   320 }
       
   321 
       
   322 /*******************************************************************************
       
   323  * QStroker inline members
       
   324  */
       
   325 inline void QStroker::emitMoveTo(qfixed x, qfixed y)
       
   326 {
       
   327     m_back2X = m_back1X;
       
   328     m_back2Y = m_back1Y;
       
   329     m_back1X = x;
       
   330     m_back1Y = y;
       
   331     QStrokerOps::emitMoveTo(x, y);
       
   332 }
       
   333 
       
   334 inline void QStroker::emitLineTo(qfixed x, qfixed y)
       
   335 {
       
   336     m_back2X = m_back1X;
       
   337     m_back2Y = m_back1Y;
       
   338     m_back1X = x;
       
   339     m_back1Y = y;
       
   340     QStrokerOps::emitLineTo(x, y);
       
   341 }
       
   342 
       
   343 inline void QStroker::emitCubicTo(qfixed c1x, qfixed c1y,
       
   344                                   qfixed c2x, qfixed c2y,
       
   345                                   qfixed ex, qfixed ey)
       
   346 {
       
   347     if (c2x == ex && c2y == ey) {
       
   348         if (c1x == ex && c1y == ey) {
       
   349             m_back2X = m_back1X;
       
   350             m_back2Y = m_back1Y;
       
   351         } else {
       
   352             m_back2X = c1x;
       
   353             m_back2Y = c1y;
       
   354         }
       
   355     } else {
       
   356         m_back2X = c2x;
       
   357         m_back2Y = c2y;
       
   358     }
       
   359     m_back1X = ex;
       
   360     m_back1Y = ey;
       
   361     QStrokerOps::emitCubicTo(c1x, c1y, c2x, c2y, ex, ey);
       
   362 }
       
   363 
       
   364 /*******************************************************************************
       
   365  * QDashStroker inline members
       
   366  */
       
   367 inline void QDashStroker::begin(void *data)
       
   368 {
       
   369     if (m_stroker)
       
   370         m_stroker->begin(data);
       
   371     QStrokerOps::begin(data);
       
   372 }
       
   373 
       
   374 inline void QDashStroker::end()
       
   375 {
       
   376     QStrokerOps::end();
       
   377     if (m_stroker)
       
   378         m_stroker->end();
       
   379 }
       
   380 
       
   381 QT_END_NAMESPACE
       
   382 
       
   383 #endif // QSTROKER_P_H