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 !(*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(GColour c)
00218 {
00219 c32 = c.c32();
00220 MakeAlphaLut();
00221 }
00222
00223 GSolidBrush(int r, int g, int b, int a = 255)
00224 {
00225 c32 = Rgba32(r, g, b, a);
00226 MakeAlphaLut();
00227 }
00228 };
00229
00230 struct GBlendStop
00231 {
00232 double Pos;
00233 COLOUR c32;
00234 };
00235
00236 class GBlendBrush : public GBrush
00237 {
00238 protected:
00239 int Stops;
00240 GBlendStop *Stop;
00241
00242 COLOUR Lut[256];
00243 double Base, IncX, IncY;
00244
00245 GPointF p[2];
00246
00247 bool Start(GRopArgs &a);
00248
00249 public:
00250 GBlendBrush(int stops, GBlendStop *stop)
00251 {
00252 MakeAlphaLut();
00253 Stops = 0;
00254 Stop = 0;
00255 if (stop)
00256 {
00257 SetStops(stops, stop);
00258 }
00259 }
00260
00261 ~GBlendBrush()
00262 {
00263 DeleteArray(Stop);
00264 }
00265
00266 int GetStops(GBlendStop **stop = 0)
00267 {
00268 if (stop)
00269 *stop = Stop;
00270 return Stops;
00271 }
00272
00273 void SetStops(int stops, GBlendStop *stop)
00274 {
00275 Stops = stops;
00276 DeleteArray(Stop);
00277 Stop = new GBlendStop[Stops];
00278 if (Stop) memcpy(Stop, stop, sizeof(*Stop) * Stops);
00279 }
00280 };
00281
00282 class GLinearBlendBrush : public GBlendBrush
00283 {
00284 bool Start(GRopArgs &Args);
00285 void Rop(GRopArgs &Args);
00286
00287 public:
00288 GLinearBlendBrush(GPointF &a, GPointF &b, int stops = 0, GBlendStop *stop = 0) :
00289 GBlendBrush(stops, stop)
00290 {
00291 p[0] = a;
00292 p[1] = b;
00293 }
00294 };
00295
00296 class GRadialBlendBrush : public GBlendBrush
00297 {
00298 void Rop(GRopArgs &Args);
00299
00300 public:
00301 GRadialBlendBrush(GPointF center, GPointF rim, int stops = 0, GBlendStop *stop = 0) :
00302 GBlendBrush(stops, stop)
00303 {
00304 p[0] = center;
00305 p[1] = rim;
00306 }
00307 };
00308
00309 class GPath
00310 {
00311
00312 List<GSeg> Segs;
00313 List<GVector> Vecs;
00314 GRectF Bounds;
00315 bool Aa;
00316 GPathFillRule FillRule;
00317 GMatrix Mat;
00318
00319
00320 int Points;
00321 GArray<int> Outline;
00322 GPointF *Point;
00323
00324
00325 void Unflatten();
00326 void Append(GPath &p);
00327
00328 public:
00329 GPath(bool aa = true);
00330 virtual ~GPath();
00331
00332
00333 void MoveTo( double x,
00334 double y);
00335 void MoveTo( GPointF &pt);
00336 void LineTo( double x,
00337 double y);
00338 void LineTo( GPointF &pt);
00339 void QuadBezierTo( double cx, double cy,
00340 double px, double py);
00341 void QuadBezierTo( GPointF &c,
00342 GPointF &p);
00343 void CubicBezierTo( double c1x, double c1y,
00344 double c2x, double c2y,
00345 double px, double py);
00346 void CubicBezierTo( GPointF &c1,
00347 GPointF &c2,
00348 GPointF &p);
00349 void Rectangle( double x1, double y1,
00350 double x2, double y2);
00351 void Rectangle( GPointF &tl,
00352 GPointF &rb);
00353 void Rectangle( GRectF &r);
00354 void RoundRect( GRectF &b, double r);
00355 void Circle( double cx,
00356 double cy,
00357 double radius);
00358 void Circle( GPointF &c,
00359 double radius);
00360 void Ellipse( double cx,
00361 double cy,
00362 double x,
00363 double y);
00364 void Ellipse( GPointF &c,
00365 double x,
00366 double y);
00367 bool Text( GFont *Font,
00368 double x,
00369 double y,
00370 char *Utf8,
00371 int Bytes = -1);
00372
00373
00374 int Segments();
00375 void GetBounds(GRectF *b);
00376 GPathFillRule GetFillRule() { return FillRule; }
00377 void SetFillRule(GPathFillRule r) { FillRule = r; }
00378
00379
00380 bool IsClosed();
00381 void Close();
00382
00383 bool IsFlattened();
00384 bool Flatten();
00385
00386 bool IsEmpty();
00387 void Empty();
00388
00389 void Transform(GMatrix &m);
00390 void DeleteSeg(int i);
00391
00392
00393 void Fill(GSurface *pDC, GBrush &Brush);
00394 void Stroke(GSurface *pDC, GBrush &Brush, double Width);
00395 };
00396
00397 void FlattenQuadratic(GPointF *&Out, GPointF &p1, GPointF &p2, GPointF &p3, int Steps);
00398 void FlattenCubic(GPointF *&Out, GPointF &p1, GPointF &p2, GPointF &p3, GPointF &p4, int Steps);
00399
00400 #endif