Qt 4.8
Classes | Macros | Typedefs | Functions
qstroker_p.h File Reference
#include "QtGui/qpainterpath.h"
#include "private/qdatabuffer_p.h"
#include "private/qnumeric_p.h"

Go to the source code of this file.

Classes

class  QDashStroker
 
struct  qfixed2d
 
class  QStroker
 
class  QStrokerOps
 
struct  QStrokerOps::Element
 

Macros

#define qt_fixed_to_real(fixed)   fixed
 
#define QT_PATH_KAPPA   0.5522847498
 
#define qt_real_to_fixed(real)   qfixed(real)
 

Typedefs

typedef qreal qfixed
 
typedef void(* qStrokerCubicToHook) (qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey, void *data)
 
typedef void(* qStrokerLineToHook) (qfixed x, qfixed y, void *data)
 
typedef void(* qStrokerMoveToHook) (qfixed x, qfixed y, void *data)
 

Functions

QPointF qt_curves_for_arc (const QRectF &rect, qreal startAngle, qreal sweepLength, QPointF *controlPoints, int *point_count)
 Creates a number of curves for a given arc definition. More...
 
Q_GUI_EXPORT bool qt_scaleForTransform (const QTransform &transform, qreal *scale)
 
qreal qt_t_for_arc_angle (qreal angle)
 

Macro Definition Documentation

◆ qt_fixed_to_real

#define qt_fixed_to_real (   fixed)    fixed

◆ QT_PATH_KAPPA

#define QT_PATH_KAPPA   0.5522847498

◆ qt_real_to_fixed

#define qt_real_to_fixed (   real)    qfixed(real)

Typedef Documentation

◆ qfixed

typedef qreal qfixed

Definition at line 100 of file qstroker_p.h.

◆ qStrokerCubicToHook

typedef void(* qStrokerCubicToHook) (qfixed c1x, qfixed c1y, qfixed c2x, qfixed c2y, qfixed ex, qfixed ey, void *data)

Definition at line 122 of file qstroker_p.h.

◆ qStrokerLineToHook

typedef void(* qStrokerLineToHook) (qfixed x, qfixed y, void *data)

Definition at line 121 of file qstroker_p.h.

◆ qStrokerMoveToHook

typedef void(* qStrokerMoveToHook) (qfixed x, qfixed y, void *data)

Definition at line 120 of file qstroker_p.h.

Function Documentation

◆ qt_curves_for_arc()

QPointF qt_curves_for_arc ( const QRectF rect,
qreal  startAngle,
qreal  sweepLength,
QPointF curves,
int *  point_count 
)

Creates a number of curves for a given arc definition.

Warning
This function is not part of the public interface.

The arc is defined an arc along the ellipses that fits into rect starting at startAngle and an arc length of sweepLength.

The function has three out parameters. The return value is the starting point of the arc. The curves array represents the list of cubicTo elements up to a maximum of point_count. There are of course 3 points pr curve.

Definition at line 859 of file qstroker.cpp.

Referenced by QPainterPath::addEllipse(), QPainterPath::arcTo(), QPaintEngineEx::drawEllipse(), QStroker::joinPoints(), and QStrokerOps::strokeEllipse().

861 {
862  Q_ASSERT(point_count);
863  Q_ASSERT(curves);
864 
865  *point_count = 0;
866  if (qt_is_nan(rect.x()) || qt_is_nan(rect.y()) || qt_is_nan(rect.width()) || qt_is_nan(rect.height())
867  || qt_is_nan(startAngle) || qt_is_nan(sweepLength)) {
868  qWarning("QPainterPath::arcTo: Adding arc where a parameter is NaN, results are undefined");
869  return QPointF();
870  }
871 
872  if (rect.isNull()) {
873  return QPointF();
874  }
875 
876  qreal x = rect.x();
877  qreal y = rect.y();
878 
879  qreal w = rect.width();
880  qreal w2 = rect.width() / 2;
881  qreal w2k = w2 * QT_PATH_KAPPA;
882 
883  qreal h = rect.height();
884  qreal h2 = rect.height() / 2;
885  qreal h2k = h2 * QT_PATH_KAPPA;
886 
887  QPointF points[16] =
888  {
889  // start point
890  QPointF(x + w, y + h2),
891 
892  // 0 -> 270 degrees
893  QPointF(x + w, y + h2 + h2k),
894  QPointF(x + w2 + w2k, y + h),
895  QPointF(x + w2, y + h),
896 
897  // 270 -> 180 degrees
898  QPointF(x + w2 - w2k, y + h),
899  QPointF(x, y + h2 + h2k),
900  QPointF(x, y + h2),
901 
902  // 180 -> 90 degrees
903  QPointF(x, y + h2 - h2k),
904  QPointF(x + w2 - w2k, y),
905  QPointF(x + w2, y),
906 
907  // 90 -> 0 degrees
908  QPointF(x + w2 + w2k, y),
909  QPointF(x + w, y + h2 - h2k),
910  QPointF(x + w, y + h2)
911  };
912 
913  if (sweepLength > 360) sweepLength = 360;
914  else if (sweepLength < -360) sweepLength = -360;
915 
916  // Special case fast paths
917  if (startAngle == 0.0) {
918  if (sweepLength == 360.0) {
919  for (int i = 11; i >= 0; --i)
920  curves[(*point_count)++] = points[i];
921  return points[12];
922  } else if (sweepLength == -360.0) {
923  for (int i = 1; i <= 12; ++i)
924  curves[(*point_count)++] = points[i];
925  return points[0];
926  }
927  }
928 
929  int startSegment = int(qFloor(startAngle / 90));
930  int endSegment = int(qFloor((startAngle + sweepLength) / 90));
931 
932  qreal startT = (startAngle - startSegment * 90) / 90;
933  qreal endT = (startAngle + sweepLength - endSegment * 90) / 90;
934 
935  int delta = sweepLength > 0 ? 1 : -1;
936  if (delta < 0) {
937  startT = 1 - startT;
938  endT = 1 - endT;
939  }
940 
941  // avoid empty start segment
942  if (qFuzzyIsNull(startT - qreal(1))) {
943  startT = 0;
944  startSegment += delta;
945  }
946 
947  // avoid empty end segment
948  if (qFuzzyIsNull(endT)) {
949  endT = 1;
950  endSegment -= delta;
951  }
952 
953  startT = qt_t_for_arc_angle(startT * 90);
954  endT = qt_t_for_arc_angle(endT * 90);
955 
956  const bool splitAtStart = !qFuzzyIsNull(startT);
957  const bool splitAtEnd = !qFuzzyIsNull(endT - qreal(1));
958 
959  const int end = endSegment + delta;
960 
961  // empty arc?
962  if (startSegment == end) {
963  const int quadrant = 3 - ((startSegment % 4) + 4) % 4;
964  const int j = 3 * quadrant;
965  return delta > 0 ? points[j + 3] : points[j];
966  }
967 
968  QPointF startPoint, endPoint;
969  qt_find_ellipse_coords(rect, startAngle, sweepLength, &startPoint, &endPoint);
970 
971  for (int i = startSegment; i != end; i += delta) {
972  const int quadrant = 3 - ((i % 4) + 4) % 4;
973  const int j = 3 * quadrant;
974 
975  QBezier b;
976  if (delta > 0)
977  b = QBezier::fromPoints(points[j + 3], points[j + 2], points[j + 1], points[j]);
978  else
979  b = QBezier::fromPoints(points[j], points[j + 1], points[j + 2], points[j + 3]);
980 
981  // empty arc?
982  if (startSegment == endSegment && qFuzzyCompare(startT, endT))
983  return startPoint;
984 
985  if (i == startSegment) {
986  if (i == endSegment && splitAtEnd)
987  b = b.bezierOnInterval(startT, endT);
988  else if (splitAtStart)
989  b = b.bezierOnInterval(startT, 1);
990  } else if (i == endSegment && splitAtEnd) {
991  b = b.bezierOnInterval(0, endT);
992  }
993 
994  // push control points
995  curves[(*point_count)++] = b.pt2();
996  curves[(*point_count)++] = b.pt3();
997  curves[(*point_count)++] = b.pt4();
998  }
999 
1000  Q_ASSERT(*point_count > 0);
1001  curves[*(point_count)-1] = endPoint;
1002 
1003  return startPoint;
1004 }
QPointF pt4() const
Definition: qbezier_p.h:97
qreal y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:667
double qreal
Definition: qglobal.h:1193
int qFloor(qreal v)
Definition: qmath.h:73
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
static bool qt_is_nan(double d)
Definition: qnumeric_p.h:183
#define QT_PATH_KAPPA
Definition: qstroker_p.h:113
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
static QBezier fromPoints(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4)
Definition: qbezier.cpp:71
qreal qt_t_for_arc_angle(qreal angle)
Definition: qstroker.cpp:796
QBezier bezierOnInterval(qreal t0, qreal t1) const
Definition: qbezier.cpp:687
qreal height() const
Returns the height of the rectangle.
Definition: qrect.h:710
Q_CORE_EXPORT void qWarning(const char *,...)
qreal width() const
Returns the width of the rectangle.
Definition: qrect.h:707
Q_GUI_EXPORT void qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length, QPointF *startPoint, QPointF *endPoint)
qreal x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:664
QPointF pt2() const
Definition: qbezier_p.h:95
QPointF pt3() const
Definition: qbezier_p.h:96
bool qFuzzyCompare(const QMatrix &m1, const QMatrix &m2)
The qFuzzyCompare function is for comparing two matrices using a fuzziness factor.
Definition: qmatrix.h:172
static Q_DECL_CONSTEXPR bool qFuzzyIsNull(double d)
Definition: qglobal.h:2043
static const KeyPair *const end
bool isNull() const
Returns true if the rectangle is a null rectangle, otherwise returns false.
Definition: qrect.h:655

◆ qt_scaleForTransform()

Q_GUI_EXPORT bool qt_scaleForTransform ( const QTransform transform,
qreal scale 
)

Definition at line 2407 of file qtransform.cpp.

Referenced by QStrokerOps::setCurveThresholdFromTransform().

2408 {
2409  const QTransform::TransformationType type = transform.type();
2410  if (type <= QTransform::TxTranslate) {
2411  if (scale)
2412  *scale = 1;
2413  return true;
2414  } else if (type == QTransform::TxScale) {
2415  const qreal xScale = qAbs(transform.m11());
2416  const qreal yScale = qAbs(transform.m22());
2417  if (scale)
2418  *scale = qMax(xScale, yScale);
2419  return qFuzzyCompare(xScale, yScale);
2420  }
2421 
2422  const qreal xScale = transform.m11() * transform.m11()
2423  + transform.m21() * transform.m21();
2424  const qreal yScale = transform.m12() * transform.m12()
2425  + transform.m22() * transform.m22();
2426  if (scale)
2427  *scale = qSqrt(qMax(xScale, yScale));
2428  return type == QTransform::TxRotate && qFuzzyCompare(xScale, yScale);
2429 }
int type
Definition: qmetatype.cpp:239
double qreal
Definition: qglobal.h:1193
qreal m21() const
Returns the horizontal shearing factor.
Definition: qtransform.h:249
qreal m22() const
Returns the vertical scaling factor.
Definition: qtransform.h:253
Q_DECL_CONSTEXPR T qAbs(const T &t)
Definition: qglobal.h:1201
TransformationType type() const
Returns the transformation type of this matrix.
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
qreal m12() const
Returns the vertical shearing factor.
Definition: qtransform.h:241
TransformationType
Definition: qtransform.h:68
bool qFuzzyCompare(const QMatrix &m1, const QMatrix &m2)
The qFuzzyCompare function is for comparing two matrices using a fuzziness factor.
Definition: qmatrix.h:172
qreal qSqrt(qreal v)
Definition: qmath.h:205
qreal m11() const
Returns the horizontal scaling factor.
Definition: qtransform.h:237

◆ qt_t_for_arc_angle()

qreal qt_t_for_arc_angle ( qreal  angle)
Warning
This function is not part of the public interface.

For a given angle in the range [0 .. 90], finds the corresponding parameter t of the prototype cubic bezier arc segment b = fromPoints(QPointF(1, 0), QPointF(1, KAPPA), QPointF(KAPPA, 1), QPointF(0, 1));

From the bezier equation: b.pointAt(t).x() = (1-t)^3 + t*(1-t)^2 + t^2*(1-t)*KAPPA b.pointAt(t).y() = t*(1-t)^2 * KAPPA + t^2*(1-t) + t^3

Third degree coefficients: b.pointAt(t).x() = at^3 + bt^2 + ct + d where a = 2-3*KAPPA, b = 3*(KAPPA-1), c = 0, d = 1

b.pointAt(t).y() = at^3 + bt^2 + ct + d where a = 3*KAPPA-2, b = 6*KAPPA+3, c = 3*KAPPA, d = 0

Newton's method to find the zero of a function: given a function f(x) and initial guess x_0 x_1 = f(x_0) / f'(x_0) x_2 = f(x_1) / f'(x_1) etc...

Definition at line 796 of file qstroker.cpp.

Referenced by qt_curves_for_arc(), and qt_find_ellipse_coords().

797 {
798  if (qFuzzyIsNull(angle))
799  return 0;
800 
801  if (qFuzzyCompare(angle, qreal(90)))
802  return 1;
803 
804  qreal radians = Q_PI * angle / 180;
805  qreal cosAngle = qCos(radians);
806  qreal sinAngle = qSin(radians);
807 
808  // initial guess
809  qreal tc = angle / 90;
810  // do some iterations of newton's method to approximate cosAngle
811  // finds the zero of the function b.pointAt(tc).x() - cosAngle
812  tc -= ((((2-3*QT_PATH_KAPPA) * tc + 3*(QT_PATH_KAPPA-1)) * tc) * tc + 1 - cosAngle) // value
813  / (((6-9*QT_PATH_KAPPA) * tc + 6*(QT_PATH_KAPPA-1)) * tc); // derivative
814  tc -= ((((2-3*QT_PATH_KAPPA) * tc + 3*(QT_PATH_KAPPA-1)) * tc) * tc + 1 - cosAngle) // value
815  / (((6-9*QT_PATH_KAPPA) * tc + 6*(QT_PATH_KAPPA-1)) * tc); // derivative
816 
817  // initial guess
818  qreal ts = tc;
819  // do some iterations of newton's method to approximate sinAngle
820  // finds the zero of the function b.pointAt(tc).y() - sinAngle
821  ts -= ((((3*QT_PATH_KAPPA-2) * ts - 6*QT_PATH_KAPPA + 3) * ts + 3*QT_PATH_KAPPA) * ts - sinAngle)
822  / (((9*QT_PATH_KAPPA-6) * ts + 12*QT_PATH_KAPPA - 6) * ts + 3*QT_PATH_KAPPA);
823  ts -= ((((3*QT_PATH_KAPPA-2) * ts - 6*QT_PATH_KAPPA + 3) * ts + 3*QT_PATH_KAPPA) * ts - sinAngle)
824  / (((9*QT_PATH_KAPPA-6) * ts + 12*QT_PATH_KAPPA - 6) * ts + 3*QT_PATH_KAPPA);
825 
826  // use the average of the t that best approximates cosAngle
827  // and the t that best approximates sinAngle
828  qreal t = 0.5 * (tc + ts);
829 
830 #if 0
831  printf("angle: %f, t: %f\n", angle, t);
832  qreal a, b, c, d;
833  bezierCoefficients(t, a, b, c, d);
834  printf("cosAngle: %.10f, value: %.10f\n", cosAngle, a + b + c * QT_PATH_KAPPA);
835  printf("sinAngle: %.10f, value: %.10f\n", sinAngle, b * QT_PATH_KAPPA + c + d);
836 #endif
837 
838  return t;
839 }
double d
Definition: qnumeric_p.h:62
double qreal
Definition: qglobal.h:1193
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_PATH_KAPPA
Definition: qstroker_p.h:113
long ASN1_INTEGER_get ASN1_INTEGER * a
qreal qSin(qreal v)
Definition: qmath.h:93
qreal angle(const QPointF &p1, const QPointF &p2)
bool qFuzzyCompare(const QMatrix &m1, const QMatrix &m2)
The qFuzzyCompare function is for comparing two matrices using a fuzziness factor.
Definition: qmatrix.h:172
static Q_DECL_CONSTEXPR bool qFuzzyIsNull(double d)
Definition: qglobal.h:2043
qreal qCos(qreal v)
Definition: qmath.h:109
static const qreal Q_PI
Definition: qmath_p.h:61