src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
changeset 30 5dc02b23752f
parent 22 79de32ba3296
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    71     m_vertices.add(x);
    71     m_vertices.add(x);
    72     m_vertices.add(y);
    72     m_vertices.add(y);
    73 }
    73 }
    74 
    74 
    75 
    75 
    76 void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen)
    76 void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, const QRectF &)
    77 {
    77 {
    78     const qreal *pts = path.points();
    78     const qreal *pts = path.points();
    79     const QPainterPath::ElementType *types = path.elements();
    79     const QPainterPath::ElementType *types = path.elements();
    80     int count = path.elementCount();
    80     int count = path.elementCount();
    81     if (count < 2)
    81     if (count < 2)
   109     // logic we can estimate the length of the outline edges based on
   109     // logic we can estimate the length of the outline edges based on
   110     // the radius + a pen width and adjusting for scale factors
   110     // the radius + a pen width and adjusting for scale factors
   111     // depending on if the pen is cosmetic or not.
   111     // depending on if the pen is cosmetic or not.
   112     //
   112     //
   113     // The curvyness value of PI/14 was based on,
   113     // The curvyness value of PI/14 was based on,
   114     // arcLength=2*PI*r/4=PI/2 and splitting length into somewhere
   114     // arcLength = 2*PI*r/4 = PI*r/2 and splitting length into somewhere
   115     // between 3 and 8 where 5 seemed to be give pretty good results
   115     // between 3 and 8 where 5 seemed to be give pretty good results
   116     // hence: Q_PI/14. Lower divisors will give more detail at the
   116     // hence: Q_PI/14. Lower divisors will give more detail at the
   117     // direct cost of performance.
   117     // direct cost of performance.
   118 
   118 
   119     // simplfy pens that are thin in device size (2px wide or less)
   119     // simplfy pens that are thin in device size (2px wide or less)
   479 {
   479 {
   480     Q_ASSERT(0); // The dasher should not produce curves...
   480     Q_ASSERT(0); // The dasher should not produce curves...
   481 }
   481 }
   482 
   482 
   483 QDashedStrokeProcessor::QDashedStrokeProcessor()
   483 QDashedStrokeProcessor::QDashedStrokeProcessor()
   484     : m_dash_stroker(0), m_inv_scale(1)
   484     : m_points(0), m_types(0),
       
   485       m_dash_stroker(0), m_inv_scale(1)
   485 {
   486 {
   486     m_dash_stroker.setMoveToHook(qdashprocessor_moveTo);
   487     m_dash_stroker.setMoveToHook(qdashprocessor_moveTo);
   487     m_dash_stroker.setLineToHook(qdashprocessor_lineTo);
   488     m_dash_stroker.setLineToHook(qdashprocessor_lineTo);
   488     m_dash_stroker.setCubicToHook(qdashprocessor_cubicTo);
   489     m_dash_stroker.setCubicToHook(qdashprocessor_cubicTo);
   489 }
   490 }
   490 
   491 
   491 void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen)
   492 void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, const QRectF &clip)
   492 {
   493 {
   493 
   494 
   494     const qreal *pts = path.points();
   495     const qreal *pts = path.points();
   495     const QPainterPath::ElementType *types = path.elements();
   496     const QPainterPath::ElementType *types = path.elements();
   496     int count = path.elementCount();
   497     int count = path.elementCount();
   497 
   498 
       
   499     bool cosmetic = pen.isCosmetic();
       
   500 
   498     m_points.reset();
   501     m_points.reset();
   499     m_types.reset();
   502     m_types.reset();
       
   503     m_points.reserve(path.elementCount());
       
   504     m_types.reserve(path.elementCount());
   500 
   505 
   501     qreal width = qpen_widthf(pen);
   506     qreal width = qpen_widthf(pen);
   502     if (width == 0)
   507     if (width == 0)
   503         width = 1;
   508         width = 1;
   504 
   509 
   505     m_dash_stroker.setDashPattern(pen.dashPattern());
   510     m_dash_stroker.setDashPattern(pen.dashPattern());
   506     m_dash_stroker.setStrokeWidth(pen.isCosmetic() ? width * m_inv_scale : width);
   511     m_dash_stroker.setStrokeWidth(cosmetic ? width * m_inv_scale : width);
   507     m_dash_stroker.setMiterLimit(pen.miterLimit());
   512     m_dash_stroker.setMiterLimit(pen.miterLimit());
   508     qreal curvyness = sqrt(width) * m_inv_scale / 8;
   513     m_dash_stroker.setClipRect(clip);
       
   514 
       
   515     float curvynessAdd, curvynessMul, roundness = 0;
       
   516 
       
   517     // simplfy pens that are thin in device size (2px wide or less)
       
   518     if (width < 2.5 && (cosmetic || m_inv_scale == 1)) {
       
   519         curvynessAdd = 0.5;
       
   520         curvynessMul = CURVE_FLATNESS / m_inv_scale;
       
   521         roundness = 1;
       
   522     } else if (cosmetic) {
       
   523         curvynessAdd= width / 2;
       
   524         curvynessMul= CURVE_FLATNESS;
       
   525         roundness = qMax<int>(4, width * CURVE_FLATNESS);
       
   526     } else {
       
   527         curvynessAdd = width * m_inv_scale;
       
   528         curvynessMul = CURVE_FLATNESS / m_inv_scale;
       
   529         roundness = qMax<int>(4, width * curvynessMul);
       
   530     }
   509 
   531 
   510     if (count < 2)
   532     if (count < 2)
   511         return;
   533         return;
   512 
   534 
   513     const qreal *endPts = pts + (count<<1);
   535     const qreal *endPts = pts + (count<<1);
   538                 QBezier b = QBezier::fromPoints(*(((const QPointF *) pts) - 1),
   560                 QBezier b = QBezier::fromPoints(*(((const QPointF *) pts) - 1),
   539                                                 *(((const QPointF *) pts)),
   561                                                 *(((const QPointF *) pts)),
   540                                                 *(((const QPointF *) pts) + 1),
   562                                                 *(((const QPointF *) pts) + 1),
   541                                                 *(((const QPointF *) pts) + 2));
   563                                                 *(((const QPointF *) pts) + 2));
   542                 QRectF bounds = b.bounds();
   564                 QRectF bounds = b.bounds();
   543                 int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * curvyness);
   565                 float rad = qMax(bounds.width(), bounds.height());
       
   566                 int threshold = qMin<float>(64, (rad + curvynessAdd) * curvynessMul);
   544                 if (threshold < 4)
   567                 if (threshold < 4)
   545                     threshold = 4;
   568                     threshold = 4;
       
   569 
   546                 qreal threshold_minus_1 = threshold - 1;
   570                 qreal threshold_minus_1 = threshold - 1;
   547                 for (int i=0; i<threshold; ++i) {
   571                 for (int i=0; i<threshold; ++i) {
   548                     QPointF pt = b.pointAt(i / threshold_minus_1);
   572                     QPointF pt = b.pointAt(i / threshold_minus_1);
   549                     m_dash_stroker.lineTo(pt.x(), pt.y());
   573                     m_dash_stroker.lineTo(pt.x(), pt.y());
   550                 }
   574                 }