src/opengl/gl2paintengineex/qtriangulatingstroker.cpp
changeset 30 5dc02b23752f
parent 22 79de32ba3296
--- a/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp	Wed Jun 23 19:07:03 2010 +0300
+++ b/src/opengl/gl2paintengineex/qtriangulatingstroker.cpp	Tue Jul 06 15:10:48 2010 +0300
@@ -73,7 +73,7 @@
 }
 
 
-void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen)
+void QTriangulatingStroker::process(const QVectorPath &path, const QPen &pen, const QRectF &)
 {
     const qreal *pts = path.points();
     const QPainterPath::ElementType *types = path.elements();
@@ -111,7 +111,7 @@
     // depending on if the pen is cosmetic or not.
     //
     // The curvyness value of PI/14 was based on,
-    // arcLength=2*PI*r/4=PI/2 and splitting length into somewhere
+    // arcLength = 2*PI*r/4 = PI*r/2 and splitting length into somewhere
     // between 3 and 8 where 5 seemed to be give pretty good results
     // hence: Q_PI/14. Lower divisors will give more detail at the
     // direct cost of performance.
@@ -481,31 +481,53 @@
 }
 
 QDashedStrokeProcessor::QDashedStrokeProcessor()
-    : m_dash_stroker(0), m_inv_scale(1)
+    : m_points(0), m_types(0),
+      m_dash_stroker(0), m_inv_scale(1)
 {
     m_dash_stroker.setMoveToHook(qdashprocessor_moveTo);
     m_dash_stroker.setLineToHook(qdashprocessor_lineTo);
     m_dash_stroker.setCubicToHook(qdashprocessor_cubicTo);
 }
 
-void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen)
+void QDashedStrokeProcessor::process(const QVectorPath &path, const QPen &pen, const QRectF &clip)
 {
 
     const qreal *pts = path.points();
     const QPainterPath::ElementType *types = path.elements();
     int count = path.elementCount();
 
+    bool cosmetic = pen.isCosmetic();
+
     m_points.reset();
     m_types.reset();
+    m_points.reserve(path.elementCount());
+    m_types.reserve(path.elementCount());
 
     qreal width = qpen_widthf(pen);
     if (width == 0)
         width = 1;
 
     m_dash_stroker.setDashPattern(pen.dashPattern());
-    m_dash_stroker.setStrokeWidth(pen.isCosmetic() ? width * m_inv_scale : width);
+    m_dash_stroker.setStrokeWidth(cosmetic ? width * m_inv_scale : width);
     m_dash_stroker.setMiterLimit(pen.miterLimit());
-    qreal curvyness = sqrt(width) * m_inv_scale / 8;
+    m_dash_stroker.setClipRect(clip);
+
+    float curvynessAdd, curvynessMul, roundness = 0;
+
+    // simplfy pens that are thin in device size (2px wide or less)
+    if (width < 2.5 && (cosmetic || m_inv_scale == 1)) {
+        curvynessAdd = 0.5;
+        curvynessMul = CURVE_FLATNESS / m_inv_scale;
+        roundness = 1;
+    } else if (cosmetic) {
+        curvynessAdd= width / 2;
+        curvynessMul= CURVE_FLATNESS;
+        roundness = qMax<int>(4, width * CURVE_FLATNESS);
+    } else {
+        curvynessAdd = width * m_inv_scale;
+        curvynessMul = CURVE_FLATNESS / m_inv_scale;
+        roundness = qMax<int>(4, width * curvynessMul);
+    }
 
     if (count < 2)
         return;
@@ -540,9 +562,11 @@
                                                 *(((const QPointF *) pts) + 1),
                                                 *(((const QPointF *) pts) + 2));
                 QRectF bounds = b.bounds();
-                int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * curvyness);
+                float rad = qMax(bounds.width(), bounds.height());
+                int threshold = qMin<float>(64, (rad + curvynessAdd) * curvynessMul);
                 if (threshold < 4)
                     threshold = 4;
+
                 qreal threshold_minus_1 = threshold - 1;
                 for (int i=0; i<threshold; ++i) {
                     QPointF pt = b.pointAt(i / threshold_minus_1);