00001 #ifndef __GPath_h__
00002 #define __GPath_h__
00003
00004 #include <math.h>
00005
00006 class GSeg;
00007 class GVector;
00008
00009 extern bool _Disable_ActiveList;
00010 extern bool _Disable_XSort;
00011 extern bool _Disable_Alpha;
00012 extern bool _Disable_Rops;
00013
00014 class GMatrix
00015 {
00016 friend class GPath;
00017
00018 double m[6];
00019
00020 public:
00021 GMatrix()
00022 {
00023 ZeroObj(m);
00024 }
00025
00026 void Translate(double x, double y)
00027 {
00028 m[0] = x;
00029 m[1] = y;
00030 }
00031 };
00032
00033 enum GPathFillRule
00034 {
00035 FILLRULE_ODDEVEN,
00036 FILLRULE_NONZERO
00037 };
00038
00039 class GPointF
00040 {
00041 public:
00042 static double Threshold;
00043 double x, y;
00044
00045 GPointF()
00046 {
00047 x = y = 0;
00048 }
00049
00050 GPointF(double X, double Y)
00051 {
00052 x = X;
00053 y = Y;
00054 }
00055
00056 GPointF(GPointF &p)
00057 {
00058 x = p.x;
00059 y = p.y;
00060 }
00061
00062 GPointF &operator =(GPointF &p)
00063 {
00064 x = p.x;
00065 y = p.y;
00066 return *this;
00067 }
00068
00069 GPointF &operator -(GPointF &p)
00070 {
00071 static GPointF Result;
00072 Result.x = x - p.x;
00073 Result.y = y - p.y;
00074 return Result;
00075 }
00076
00077 GPointF &operator +(GPointF &p)
00078 {
00079 static GPointF Result;
00080 Result.x = x + p.x;
00081 Result.y = y + p.y;
00082 return Result;
00083 }
00084
00085 bool operator ==(GPointF &p)
00086 {
00087 double dx = x - p.x;
00088 if (dx < 0) dx = -dx;
00089 double dy = y - p.y;
00090 if (dy < 0) dy = -dy;
00091 return dx<Threshold AND dy<Threshold;
00092 }
00093
00094 bool operator !=(GPointF &p)
00095 {
00096 return NOT (*this == p);
00097 }
00098
00099 void Set(double X, double Y)
00100 {
00101 x = X;
00102 y = Y;
00103 }
00104
00105 GPointF &Translate(double tx, double ty)
00106 {
00107 x += tx;
00108 y += ty;
00109 return *this;
00110 }
00111
00112 GPointF &Rotate(double a)
00113 {
00114 double ix = x;
00115 double iy = y;
00116 x = (cos(a)*ix) - (sin(a)*iy);
00117 y = (sin(a)*ix) + (cos(a)*iy);
00118 return *this;
00119 }
00120 };
00121
00122 class GRectF
00123 {
00124 public:
00125 double x1, y1, x2, y2;
00126 bool Set;
00127
00128 GRectF()
00129 {
00130 Set = false;
00131 }
00132
00133 GRectF(GRect &r)
00134 {
00135 x1 = r.x1;
00136 x2 = r.x2;
00137 y1 = r.y1;
00138 y2 = r.y2;
00139 Set = true;
00140 }
00141
00142 GRectF(double X1, double Y1, double X2, double Y2)
00143 {
00144 x1 = X1; y1 = Y1; x2 = X2; y2 = Y2;
00145 Set = true;
00146 }
00147
00148 GRectF(GPointF &a, GPointF &b)
00149 {
00150 x1 = a.x; y1 = a.y; x2 = b.x; y2 = b.y;
00151 Set = true;
00152 }
00153
00154 double X() { return x2 - x1; }
00155 double Y() { return y2 - y1; }
00156 bool IsNormal() { return x2 >= x1 AND y2 >= y1; }
00157
00158 void Normalize();
00159 void Union(GPointF &p);
00160 void Union(GRectF &p);
00161 void Intersect(GRectF &p);
00162 bool Overlap(GPointF &p);
00163 bool Overlap(GRectF &p);
00164 void Offset(double x, double y);
00165 void Size(double dx, double dy);
00166 char *Describe();
00167
00168 GRectF &operator =(GRectF &f);
00169 GRectF &operator =(GPointF &p);
00170 };
00171
00172 class GBrush
00173 {
00174 friend class GPath;
00175
00176 protected:
00177 uchar AlphaLut[65];
00178
00179 class GRopArgs
00180 {
00181 public:
00182 uchar *Pixels;
00183 uchar *EndOfMem;
00184 uchar *Alpha;
00185 int Bits;
00186 int Len;
00187 int x, y;
00188
00189 GSurface *pDC;
00190 };
00191
00192 virtual bool Start(GRopArgs &a) { return true; }
00193 virtual void Rop(GRopArgs &a) = 0;
00194 virtual int Alpha() { return 255; }
00195
00196 void MakeAlphaLut();
00197
00198 public:
00199 GBrush() {}
00200 virtual ~GBrush() {}
00201 };
00202
00203 class GSolidBrush : public GBrush
00204 {
00205 COLOUR c32;
00206
00207 void Rop(GRopArgs &a);
00208 int Alpha() { return A32(c32); }
00209
00210 public:
00211 GSolidBrush(COLOUR c)
00212 {
00213 c32 = c;
00214 MakeAlphaLut();
00215 }
00216
00217 GSolidBrush(int r, int g, int b, int a = 255)
00218 {
00219 c32 = Rgba32(r, g, b, a);
00220 MakeAlphaLut();
00221 }
00222 };
00223
00224 struct GBlendStop
00225 {
00226 double Pos;
00227 COLOUR c32;
00228 };
00229
00230 class GBlendBrush : public GBrush
00231 {
00232 protected:
00233 int Stops;
00234 GBlendStop *Stop;
00235
00236 COLOUR Lut[256];
00237 double Base, IncX, IncY;
00238
00239 GPointF p[2];
00240
00241 bool Start(GRopArgs &a);
00242
00243 public:
00244 GBlendBrush(int stops, GBlendStop *stop)
00245 {
00246 MakeAlphaLut();
00247 Stops = 0;
00248 Stop = 0;
00249 if (stop)
00250 {
00251 SetStops(stops, stop);
00252 }
00253 }
00254
00255 ~GBlendBrush()
00256 {
00257 DeleteArray(Stop);
00258 }
00259
00260 void SetStops(int stops, GBlendStop *stop)
00261 {
00262 Stops = stops;
00263 DeleteArray(Stop);
00264 Stop = NEW(GBlendStop[Stops]);
00265 if (Stop) memcpy(Stop, stop, sizeof(*Stop) * Stops);
00266 }
00267 };
00268
00269 class GLinearBlendBrush : public GBlendBrush
00270 {
00271 bool Start(GRopArgs &Args);
00272 void Rop(GRopArgs &Args);
00273
00274 public:
00275 GLinearBlendBrush(GPointF &a, GPointF &b, int stops = 0, GBlendStop *stop = 0) :
00276 GBlendBrush(stops, stop)
00277 {
00278 p[0] = a;
00279 p[1] = b;
00280 }
00281 };
00282
00283 class GRadialBlendBrush : public GBlendBrush
00284 {
00285 void Rop(GRopArgs &Args);
00286
00287 public:
00288 GRadialBlendBrush(GPointF center, GPointF rim, int stops = 0, GBlendStop *stop = 0) :
00289 GBlendBrush(stops, stop)
00290 {
00291 p[0] = center;
00292 p[1] = rim;
00293 }
00294 };
00295
00296 class GPath
00297 {
00298
00299 List<GSeg> Segs;
00300 List<GVector> Vecs;
00301 GRectF Bounds;
00302 bool Aa;
00303 GPathFillRule FillRule;
00304 GMatrix Mat;
00305
00306
00307 int Points;
00308 int *Outline;
00309 GPointF *Point;
00310
00311
00312 void Unflatten();
00313
00314 public:
00315 GPath(bool aa = true);
00316 virtual ~GPath();
00317
00318
00319 void MoveTo( double x,
00320 double y);
00321 void MoveTo( GPointF &pt);
00322 void LineTo( double x,
00323 double y);
00324 void LineTo( GPointF &pt);
00325 void QuadBezierTo( double cx, double cy,
00326 double px, double py);
00327 void QuadBezierTo( GPointF &c,
00328 GPointF &p);
00329 void CubicBezierTo( double c1x, double c1y,
00330 double c2x, double c2y,
00331 double px, double py);
00332 void CubicBezierTo( GPointF &c1,
00333 GPointF &c2,
00334 GPointF &p);
00335 void Rectangle( double x1, double y1,
00336 double x2, double y2);
00337 void Rectangle( GPointF &tl,
00338 GPointF &rb);
00339 void Rectangle( GRectF &r);
00340 void RoundRect( GRectF &b, double r);
00341 void Circle( double cx,
00342 double cy,
00343 double radius);
00344 void Circle( GPointF &c,
00345 double radius);
00346 void Ellipse( double cx,
00347 double cy,
00348 double x,
00349 double y);
00350 void Ellipse( GPointF &c,
00351 double x,
00352 double y);
00353 bool Text( GFont *Font,
00354 double x,
00355 double y,
00356 char *Utf8,
00357 int Bytes = -1);
00358
00359
00360 int Segments();
00361 void GetBounds(GRectF *b) { if (b) *b = Bounds; }
00362 GPathFillRule GetFillRule() { return FillRule; }
00363 void SetFillRule(GPathFillRule r) { FillRule = r; }
00364
00365
00366 bool IsClosed();
00367 void Close();
00368 bool Flatten();
00369 void Empty();
00370 void Transform(GMatrix &m);
00371 void DeleteSeg(int i);
00372
00373
00374 void Fill(GSurface *pDC, GBrush &Brush);
00375 void Stroke(GSurface *pDC, GBrush &Brush, int Width);
00376 };
00377
00378 void FlattenQuadratic(GPointF *&Out, GPointF &p1, GPointF &p2, GPointF &p3, int Steps);
00379 void FlattenCubic(GPointF *&Out, GPointF &p1, GPointF &p2, GPointF &p3, GPointF &p4, int Steps);
00380
00381
00382 #endif