summaryrefslogtreecommitdiff
path: root/cd/src/gdiplus/cdwinp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cd/src/gdiplus/cdwinp.cpp')
-rwxr-xr-xcd/src/gdiplus/cdwinp.cpp596
1 files changed, 548 insertions, 48 deletions
diff --git a/cd/src/gdiplus/cdwinp.cpp b/cd/src/gdiplus/cdwinp.cpp
index 1cbed3c..013cc9a 100755
--- a/cd/src/gdiplus/cdwinp.cpp
+++ b/cd/src/gdiplus/cdwinp.cpp
@@ -51,10 +51,10 @@ void cdwpShowStatus(const char* title, Status status)
void cdwpKillCanvas(cdCtxCanvas* ctxcanvas)
{
if (ctxcanvas->clip_poly) delete[] ctxcanvas->clip_poly;
+ if (ctxcanvas->clip_fpoly) delete[] ctxcanvas->clip_fpoly;
if (ctxcanvas->clip_region) delete ctxcanvas->clip_region;
if (ctxcanvas->new_region) delete ctxcanvas->new_region;
if (ctxcanvas->font) delete ctxcanvas->font;
- if (ctxcanvas->wdpoly) delete ctxcanvas->wdpoly;
delete ctxcanvas->fillBrush;
delete ctxcanvas->lineBrush;
@@ -65,13 +65,14 @@ void cdwpKillCanvas(cdCtxCanvas* ctxcanvas)
/* ctxcanvas eŽ liberado em cada driver */
}
-static int cdwpSetTransform(cdCtxCanvas* ctxcanvas, Matrix &transformMatrix, const double* matrix)
+static int sAddTransform(cdCtxCanvas* ctxcanvas, Matrix &transformMatrix, const double* matrix)
{
if (matrix)
{
// configure a bottom-up coordinate system
Matrix Matrix1((REAL)1, (REAL)0, (REAL)0, (REAL)-1, (REAL)0, (REAL)(ctxcanvas->canvas->h-1));
transformMatrix.Multiply(&Matrix1);
+
// add the global transform
Matrix Matrix2((REAL)matrix[0], (REAL)matrix[1], (REAL)matrix[2], (REAL)matrix[3], (REAL)matrix[4], (REAL)matrix[5]);
transformMatrix.Multiply(&Matrix2);
@@ -89,11 +90,11 @@ static int cdwpSetTransform(cdCtxCanvas* ctxcanvas, Matrix &transformMatrix, con
return 0;
}
-static void cdwpUpdateTransform(cdCtxCanvas* ctxcanvas)
+static void sUpdateTransform(cdCtxCanvas* ctxcanvas)
{
Matrix transformMatrix;
ctxcanvas->graphics->ResetTransform(); // reset to the identity.
- if (cdwpSetTransform(ctxcanvas, transformMatrix, ctxcanvas->canvas->use_matrix? ctxcanvas->canvas->matrix: NULL))
+ if (sAddTransform(ctxcanvas, transformMatrix, ctxcanvas->canvas->use_matrix? ctxcanvas->canvas->matrix: NULL))
ctxcanvas->graphics->SetTransform(&transformMatrix);
}
@@ -245,7 +246,10 @@ static void sClipPoly(cdCtxCanvas* ctxcanvas)
GraphicsPath path;
path.SetFillMode(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
- path.AddPolygon(ctxcanvas->clip_poly, ctxcanvas->clip_poly_n);
+ if (ctxcanvas->clip_fpoly)
+ path.AddPolygon(ctxcanvas->clip_fpoly, ctxcanvas->clip_poly_n);
+ else
+ path.AddPolygon(ctxcanvas->clip_poly, ctxcanvas->clip_poly_n);
ctxcanvas->clip_region = new Region(&path);
ctxcanvas->graphics->SetClip(ctxcanvas->clip_region);
@@ -523,6 +527,7 @@ static void cdpattern(cdCtxCanvas* ctxcanvas, int w, int h, const long int *colo
{
int line_offset_colors;
int line_offset = j*stride;
+ /* internal transform, affects also pattern orientation */
if (ctxcanvas->canvas->invert_yaxis)
line_offset_colors = ((h - 1) - j)*w; // Fix up side down
else
@@ -551,6 +556,7 @@ static int cdinteriorstyle(cdCtxCanvas* ctxcanvas, int style)
delete ctxcanvas->fillBrush;
ctxcanvas->fillBrush = new SolidBrush(ctxcanvas->fg);
break;
+ /* the remaining styles must recreate the current brush */
case CD_HATCH:
cdhatch(ctxcanvas, ctxcanvas->canvas->hatch_style);
break;
@@ -571,6 +577,12 @@ static void cdline(cdCtxCanvas* ctxcanvas, int x1, int y1, int x2, int y2)
ctxcanvas->dirty = 1;
}
+static void cdfline(cdCtxCanvas* ctxcanvas, double x1, double y1, double x2, double y2)
+{
+ ctxcanvas->graphics->DrawLine(ctxcanvas->linePen, (REAL)x1, (REAL)y1, (REAL)x2, (REAL)y2);
+ ctxcanvas->dirty = 1;
+}
+
static void cdrect(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
Rect rect(xmin, ymin, xmax-xmin, ymax-ymin); // in this case Size = Max - Min
@@ -578,6 +590,13 @@ static void cdrect(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int yma
ctxcanvas->dirty = 1;
}
+static void cdfrect(cdCtxCanvas* ctxcanvas, double xmin, double xmax, double ymin, double ymax)
+{
+ RectF rect((REAL)xmin, (REAL)ymin, (REAL)(xmax-xmin), (REAL)(ymax-ymin)); // in this case Size = Max - Min
+ ctxcanvas->graphics->DrawRectangle(ctxcanvas->linePen, rect);
+ ctxcanvas->dirty = 1;
+}
+
static void cdbox(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
Rect rect(xmin, ymin, xmax-xmin+1, ymax-ymin+1);
@@ -593,13 +612,36 @@ static void cdbox(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax
}
}
-static void cdwpFixAngles(cdCtxCanvas* ctxcanvas, double *angle1, double *angle2)
+static void cdfbox(cdCtxCanvas* ctxcanvas, double xmin, double xmax, double ymin, double ymax)
{
- if (ctxcanvas->canvas->invert_yaxis)
+ RectF rect((REAL)xmin, (REAL)ymin, (REAL)(xmax-xmin+1), (REAL)(ymax-ymin+1));
+ if (ctxcanvas->canvas->new_region)
+ {
+ Region region(rect);
+ sCombineRegion(ctxcanvas, region);
+ }
+ else
{
- // GDI+ angle are clock-wise by default
- *angle1 *= -1;
- *angle2 *= -1;
+ ctxcanvas->graphics->FillRectangle(ctxcanvas->fillBrush, rect);
+ ctxcanvas->dirty = 1;
+ }
+}
+
+static void sFixAngles(cdCanvas* canvas, double *a1, double *a2)
+{
+ // GDI+ angles are clock-wise by default, in degrees
+
+ /* if NOT inverted means a transformation is set,
+ so the angle will follow the transformation that includes the axis invertion,
+ then it is already counter-clockwise */
+
+ if (canvas->invert_yaxis)
+ {
+ /* change orientation */
+ *a1 *= -1;
+ *a2 *= -1;
+
+ /* no need to swap, because we will use (angle2-angle1) */
}
}
@@ -610,7 +652,20 @@ static void cdarc(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double a
ctxcanvas->graphics->DrawEllipse(ctxcanvas->linePen, rect);
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
+ ctxcanvas->graphics->DrawArc(ctxcanvas->linePen, rect, (REAL)angle1, (REAL)(angle2-angle1));
+ }
+ ctxcanvas->dirty = 1;
+}
+
+static void cdfarc(cdCtxCanvas* ctxcanvas, double xc, double yc, double w, double h, double angle1, double angle2)
+{
+ RectF rect((REAL)(xc - w/2.0), (REAL)(yc - h/2.0), (REAL)w, (REAL)h);
+ if (angle1 == 0 && angle2 == 360)
+ ctxcanvas->graphics->DrawEllipse(ctxcanvas->linePen, rect);
+ else
+ {
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
ctxcanvas->graphics->DrawArc(ctxcanvas->linePen, rect, (REAL)angle1, (REAL)(angle2-angle1));
}
ctxcanvas->dirty = 1;
@@ -626,7 +681,7 @@ static void cdsector(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, doubl
path.AddEllipse(rect);
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
path.AddPie(rect, (REAL)angle1, (REAL)(angle2-angle1));
}
Region region(&path);
@@ -644,7 +699,43 @@ static void cdsector(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, doubl
}
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
+ ctxcanvas->graphics->FillPie(ctxcanvas->fillBrush, rect, (REAL)angle1, (REAL)(angle2-angle1));
+ ctxcanvas->graphics->DrawArc(&pen, rect, (REAL)angle1, (REAL)(angle2-angle1));
+ }
+ ctxcanvas->dirty = 1;
+ }
+}
+
+static void cdfsector(cdCtxCanvas* ctxcanvas, double xc, double yc, double w, double h, double angle1, double angle2)
+{
+ RectF rect((REAL)(xc - w/2.0), (REAL)(yc - h/2.0), (REAL)w, (REAL)h);
+ if (ctxcanvas->canvas->new_region)
+ {
+ GraphicsPath path;
+ if (angle1==0 && angle2==360)
+ path.AddEllipse(rect);
+ else
+ {
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
+ path.AddPie(rect, (REAL)angle1, (REAL)(angle2-angle1));
+ }
+ Region region(&path);
+ sCombineRegion(ctxcanvas, region);
+ }
+ else
+ {
+ // complete the remaining pixels using an Arc
+ Pen pen(ctxcanvas->fillBrush);
+
+ if (angle1==0 && angle2==360)
+ {
+ ctxcanvas->graphics->FillEllipse(ctxcanvas->fillBrush, rect);
+ ctxcanvas->graphics->DrawEllipse(&pen, rect);
+ }
+ else
+ {
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
ctxcanvas->graphics->FillPie(ctxcanvas->fillBrush, rect, (REAL)angle1, (REAL)(angle2-angle1));
ctxcanvas->graphics->DrawArc(&pen, rect, (REAL)angle1, (REAL)(angle2-angle1));
}
@@ -662,7 +753,41 @@ static void cdchord(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double
path.AddEllipse(rect);
else
{
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
+ path.AddArc(rect, (REAL)angle1, (REAL)(angle2-angle1));
+ path.CloseFigure();
+ }
+ Region region(&path);
+ sCombineRegion(ctxcanvas, region);
+ }
+ else
+ {
+ if (angle1==0 && angle2==360)
+ ctxcanvas->graphics->FillEllipse(ctxcanvas->fillBrush, rect);
+ else
+ {
+ GraphicsPath path;
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
+ path.AddArc(rect, (REAL)angle1, (REAL)(angle2-angle1));
+ ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, &path);
+ }
+ Pen pen(ctxcanvas->fillBrush); // complete the remaining pixels using an Arc
+ ctxcanvas->graphics->DrawArc(&pen, rect, (REAL)angle1, (REAL)(angle2-angle1));
+ ctxcanvas->dirty = 1;
+ }
+}
+
+static void cdfchord(cdCtxCanvas* ctxcanvas, double xc, double yc, double w, double h, double angle1, double angle2)
+{
+ RectF rect((REAL)(xc - w/2.0), (REAL)(yc - h/2.0), (REAL)w, (REAL)h);
+ if (ctxcanvas->canvas->new_region)
+ {
+ GraphicsPath path;
+ if (angle1==0 && angle2==360)
+ path.AddEllipse(rect);
+ else
+ {
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
path.AddArc(rect, (REAL)angle1, (REAL)(angle2-angle1));
path.CloseFigure();
}
@@ -676,7 +801,7 @@ static void cdchord(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double
else
{
GraphicsPath path;
- cdwpFixAngles(ctxcanvas, &angle1, &angle2);
+ sFixAngles(ctxcanvas->canvas, &angle1, &angle2);
path.AddArc(rect, (REAL)angle1, (REAL)(angle2-angle1));
ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, &path);
}
@@ -688,8 +813,118 @@ static void cdchord(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double
static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
{
- switch( mode )
+ switch (mode)
{
+ case CD_PATH:
+ {
+ int p, i, current_x = 0, current_y = 0, current_set = 0;
+ GraphicsPath* graphics_path;
+ PointF lastPoint;
+
+ /* starts a new path */
+ graphics_path = new GraphicsPath(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ graphics_path->Reset();
+ graphics_path->SetFillMode(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) break;
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) break;
+ if (current_set)
+ graphics_path->AddLine(current_x, current_y, poly[i].x, poly[i].y);
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ int xc, yc, w, h;
+ double a1, a2;
+
+ if (i+3 > n) break;
+
+ if (!cdCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ if (current_set)
+ {
+ int StartX, StartY;
+
+ if (ctxcanvas->canvas->invert_yaxis)
+ cdCanvasGetArcStartEnd(xc, yc, w, h, -a1, -a2, &StartX, &StartY, NULL, NULL);
+ else
+ cdCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, &StartX, &StartY, NULL, NULL);
+
+ graphics_path->AddLine(current_x, current_y, StartX, StartY);
+ }
+
+ Rect rect(xc - w/2, yc - h/2, w, h);
+ if (a1 == 0 && a2 == 360)
+ graphics_path->AddEllipse(rect);
+ else
+ {
+ sFixAngles(ctxcanvas->canvas, &a1, &a2);
+ graphics_path->AddArc(rect, (REAL)a1, (REAL)(a2-a1));
+ }
+
+ graphics_path->GetLastPoint(&lastPoint);
+ current_x = (int)lastPoint.X;
+ current_y = (int)lastPoint.Y;
+ current_set = 1;
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) break;
+ if (!current_set)
+ {
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ }
+ graphics_path->AddBezier(current_x, current_y, poly[i].x, poly[i].y, poly[i+1].x, poly[i+1].y, poly[i+2].x, poly[i+2].y);
+ graphics_path->GetLastPoint(&lastPoint);
+ current_x = (int)lastPoint.X;
+ current_y = (int)lastPoint.Y;
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ graphics_path->CloseFigure();
+ break;
+ case CD_PATH_FILL:
+ ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, graphics_path);
+ break;
+ case CD_PATH_STROKE:
+ ctxcanvas->graphics->DrawPath(ctxcanvas->linePen, graphics_path);
+ break;
+ case CD_PATH_FILLSTROKE:
+ ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, graphics_path);
+ ctxcanvas->graphics->DrawPath(ctxcanvas->linePen, graphics_path);
+ break;
+ case CD_PATH_CLIP:
+ ctxcanvas->graphics->SetClip(graphics_path, CombineModeIntersect);
+ break;
+ }
+ }
+
+ delete graphics_path;
+ break;
+ }
case CD_BEZIER:
if (n < 4) return;
ctxcanvas->graphics->DrawBeziers(ctxcanvas->linePen, (Point*)poly, n);
@@ -748,6 +983,11 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
if (ctxcanvas->clip_poly)
delete[] ctxcanvas->clip_poly;
+ if (ctxcanvas->clip_fpoly)
+ {
+ delete[] ctxcanvas->clip_fpoly;
+ ctxcanvas->clip_fpoly = NULL;
+ }
ctxcanvas->clip_poly = new Point [n];
@@ -779,6 +1019,242 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
ctxcanvas->dirty = 1;
}
+static PointF* sPolyToFloat(cdfPoint* poly, int n)
+{
+ PointF* fpoly = new PointF[n+1];
+
+ for (int i = 0; i < n; i++)
+ {
+ fpoly[i].X = (REAL)poly[i].x;
+ fpoly[i].Y = (REAL)poly[i].y;
+ }
+
+ return fpoly;
+}
+
+static void cdfpoly(cdCtxCanvas* ctxcanvas, int mode, cdfPoint* poly, int n)
+{
+ PointF* fpoly = NULL;
+
+ switch (mode)
+ {
+ case CD_PATH:
+ {
+ int p, i, current_set = 0;
+ double current_x = 0, current_y = 0;
+ GraphicsPath* graphics_path;
+ PointF lastPoint;
+
+ /* starts a new path */
+ graphics_path = new GraphicsPath(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ graphics_path->Reset();
+ graphics_path->SetFillMode(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) break;
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) break;
+ if (current_set)
+ graphics_path->AddLine((REAL)current_x, (REAL)current_y, (REAL)poly[i].x, (REAL)poly[i].y);
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ double xc, yc, w, h;
+ double a1, a2;
+
+ if (i+3 > n) break;
+
+ if (!cdfCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ if (current_set)
+ {
+ double StartX, StartY;
+
+ if (ctxcanvas->canvas->invert_yaxis)
+ cdfCanvasGetArcStartEnd(xc, yc, w, h, -a1, -a2, &StartX, &StartY, NULL, NULL);
+ else
+ cdfCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, &StartX, &StartY, NULL, NULL);
+
+ graphics_path->AddLine((REAL)current_x, (REAL)current_y, (REAL)StartX, (REAL)StartY);
+ }
+
+ RectF rect((REAL)(xc - w/2.0), (REAL)(yc - h/2.0), (REAL)w, (REAL)h);
+ if (a1 == 0 && a2 == 360)
+ graphics_path->AddEllipse(rect);
+ else
+ {
+ sFixAngles(ctxcanvas->canvas, &a1, &a2);
+ graphics_path->AddArc(rect, (REAL)a1, (REAL)(a2-a1));
+ }
+
+ graphics_path->GetLastPoint(&lastPoint);
+ current_x = lastPoint.X;
+ current_y = lastPoint.Y;
+ current_set = 1;
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) break;
+ if (!current_set)
+ {
+ current_x = poly[i].x;
+ current_y = poly[i].y;
+ }
+ graphics_path->AddBezier((REAL)current_x, (REAL)current_y, (REAL)poly[i].x, (REAL)poly[i].y, (REAL)poly[i+1].x, (REAL)poly[i+1].y, (REAL)poly[i+2].x, (REAL)poly[i+2].y);
+ graphics_path->GetLastPoint(&lastPoint);
+ current_x = lastPoint.X;
+ current_y = lastPoint.Y;
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ graphics_path->CloseFigure();
+ break;
+ case CD_PATH_FILL:
+ ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, graphics_path);
+ break;
+ case CD_PATH_STROKE:
+ ctxcanvas->graphics->DrawPath(ctxcanvas->linePen, graphics_path);
+ break;
+ case CD_PATH_FILLSTROKE:
+ ctxcanvas->graphics->FillPath(ctxcanvas->fillBrush, graphics_path);
+ ctxcanvas->graphics->DrawPath(ctxcanvas->linePen, graphics_path);
+ break;
+ case CD_PATH_CLIP:
+ ctxcanvas->graphics->SetClip(graphics_path, CombineModeIntersect);
+ break;
+ }
+ }
+
+ delete graphics_path;
+ break;
+ }
+ case CD_BEZIER:
+ if (n < 4) return;
+ fpoly = sPolyToFloat(poly, n);
+ ctxcanvas->graphics->DrawBeziers(ctxcanvas->linePen, (PointF*)fpoly, n);
+ break;
+ case CD_FILLSPLINE:
+ if (n < 4) return;
+ fpoly = sPolyToFloat(poly, n);
+ if (ctxcanvas->canvas->new_region)
+ {
+ GraphicsPath path(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ path.AddClosedCurve((PointF*)fpoly, n);
+ Region region(&path);
+ sCombineRegion(ctxcanvas, region);
+ }
+ else
+ ctxcanvas->graphics->FillClosedCurve(ctxcanvas->fillBrush, (PointF*)fpoly, n);
+ break;
+ case CD_SPLINE:
+ if (n < 4) return;
+ fpoly = sPolyToFloat(poly, n);
+ ctxcanvas->graphics->DrawClosedCurve(ctxcanvas->linePen, (PointF*)fpoly, n);
+ break;
+ case CD_CLOSED_LINES:
+ poly[n].x = poly[0].x;
+ poly[n].y = poly[0].y;
+ n++;
+ /* continue */
+ case CD_OPEN_LINES:
+ fpoly = sPolyToFloat(poly, n);
+ ctxcanvas->graphics->DrawLines(ctxcanvas->linePen, (PointF*)fpoly, n);
+ break;
+ case CD_FILLGRADIENT:
+ {
+ int count = n;
+ PathGradientBrush* brush = new PathGradientBrush((PointF*)fpoly, n);
+ fpoly = sPolyToFloat(poly, n);
+ brush->SetSurroundColors(ctxcanvas->pathGradient, &count);
+ brush->SetCenterColor(ctxcanvas->pathGradient[n]);
+ ctxcanvas->graphics->FillPolygon(brush, (PointF*)fpoly, n, ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ delete brush;
+ }
+ break;
+ case CD_FILL:
+ poly[n].x = poly[0].x;
+ poly[n].y = poly[0].y;
+ n++;
+ fpoly = sPolyToFloat(poly, n);
+ if (ctxcanvas->canvas->new_region)
+ {
+ GraphicsPath path(ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ path.AddPolygon((PointF*)fpoly, n);
+ Region region(&path);
+ sCombineRegion(ctxcanvas, region);
+ }
+ else
+ ctxcanvas->graphics->FillPolygon(ctxcanvas->fillBrush, (PointF*)fpoly, n, ctxcanvas->canvas->fill_mode==CD_EVENODD?FillModeAlternate:FillModeWinding);
+ break;
+ case CD_CLIP:
+ poly[n].x = poly[0].x;
+ poly[n].y = poly[0].y;
+ n++;
+
+ if (ctxcanvas->clip_fpoly)
+ delete[] ctxcanvas->clip_fpoly;
+ if (ctxcanvas->clip_poly)
+ {
+ delete[] ctxcanvas->clip_poly;
+ ctxcanvas->clip_poly = NULL;
+ }
+
+ ctxcanvas->clip_fpoly = new PointF [n];
+
+ cdfPoint* pnt = poly;
+ int t = n;
+ int nc = 1;
+
+ ctxcanvas->clip_fpoly[0].X = (REAL)pnt->x;
+ ctxcanvas->clip_fpoly[0].Y = (REAL)pnt->y;
+ pnt++;
+
+ for (int i = 1; i < t-1; i++, pnt++)
+ {
+ if (!(((REAL)pnt->x == ctxcanvas->clip_fpoly[nc-1].X && pnt->x == (pnt + 1)->x) ||
+ ((REAL)pnt->y == ctxcanvas->clip_fpoly[nc-1].Y && pnt->y == (pnt + 1)->y)))
+ {
+ ctxcanvas->clip_fpoly[nc].X = (REAL)pnt->x;
+ ctxcanvas->clip_fpoly[nc].Y = (REAL)pnt->y;
+ nc++;
+ }
+ }
+
+ ctxcanvas->clip_poly_n = nc;
+
+ if (ctxcanvas->canvas->clip_mode == CD_CLIPPOLYGON)
+ sClipPoly(ctxcanvas);
+
+ break;
+ }
+
+ if (fpoly)
+ delete[] fpoly;
+
+ ctxcanvas->dirty = 1;
+}
+
WCHAR* cdwpString2Unicode(const char* s, int len)
{
static WCHAR wstr[10240] = L"";
@@ -829,7 +1305,7 @@ static void sTextBox(cdCtxCanvas* ctxcanvas, WCHAR *ws, int len, int x, int y, i
*ymin += ydir * (*h);
}
-static void cdwpCanvasGetTextHeight(cdCanvas* canvas, int x, int y, int w, int h, int *hbox)
+static void sGetTransformTextHeight(cdCanvas* canvas, int x, int y, int w, int h, int *hbox)
{
int xmin, xmax, ymin, ymax;
@@ -865,21 +1341,12 @@ static void cdwpCanvasGetTextHeight(cdCanvas* canvas, int x, int y, int w, int h
*hbox = ymax-ymin+1;
}
-static void cdwpTextTransform(cdCtxCanvas* ctxcanvas, int *x, int *y, int w, int h, Matrix &transformMatrix)
+static void sAddTextTransform(cdCtxCanvas* ctxcanvas, int *x, int *y, int w, int h, Matrix &transformMatrix)
{
int hbox;
- double* matrix = ctxcanvas->canvas->matrix;
Matrix m1;
- cdwpCanvasGetTextHeight(ctxcanvas->canvas, *x, *y, w, h, &hbox);
-
- // configure a bottom-up coordinate system
- m1.SetElements((REAL)1, (REAL)0, (REAL)0, (REAL)-1, (REAL)0, (REAL)(ctxcanvas->canvas->h-1));
- transformMatrix.Multiply(&m1);
-
- // add the global transform
- m1.SetElements((REAL)matrix[0], (REAL)matrix[1], (REAL)matrix[2], (REAL)matrix[3], (REAL)matrix[4], (REAL)matrix[5]);
- transformMatrix.Multiply(&m1);
+ sGetTransformTextHeight(ctxcanvas->canvas, *x, *y, w, h, &hbox);
// move to (x,y) and remove a vertical offset since text reference point is top-left
m1.SetElements((REAL)1, (REAL)0, (REAL)0, (REAL)1, (REAL)*x, (REAL)(*y - (hbox-1)));
@@ -912,10 +1379,12 @@ static void cdtext(cdCtxCanvas* ctxcanvas, int x, int y, const char *s, int len)
if (ctxcanvas->canvas->use_matrix)
{
- cdwpTextTransform(ctxcanvas, &x, &y, w, h, transformMatrix);
+ double* matrix = ctxcanvas->canvas->matrix;
+ sAddTransform(ctxcanvas, transformMatrix, matrix);
+ sAddTextTransform(ctxcanvas, &x, &y, w, h, transformMatrix);
use_transform = 1;
}
- else if (cdwpSetTransform(ctxcanvas, transformMatrix, NULL))
+ else if (sAddTransform(ctxcanvas, transformMatrix, NULL))
use_transform = 1;
if (ctxcanvas->canvas->new_region)
@@ -944,7 +1413,7 @@ static void cdtext(cdCtxCanvas* ctxcanvas, int x, int y, const char *s, int len)
ctxcanvas->lineBrush);
if (use_transform)
- cdwpUpdateTransform(ctxcanvas); // reset transform
+ sUpdateTransform(ctxcanvas); // reset transform
ctxcanvas->dirty = 1;
}
@@ -1141,7 +1610,7 @@ static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)
else
ctxcanvas->canvas->invert_yaxis = 1;
- if (cdwpSetTransform(ctxcanvas, transformMatrix, matrix))
+ if (sAddTransform(ctxcanvas, transformMatrix, matrix))
ctxcanvas->graphics->SetTransform(&transformMatrix);
}
@@ -1173,6 +1642,10 @@ static void sRGB2Bitmap(Bitmap& image, int width, int height, const unsigned cha
Rect rect(0,0,image.GetWidth(),image.GetHeight());
image.LockBits(&rect, ImageLockModeWrite, PixelFormat24bppRGB, &bitmapData);
+ /* ymin and xmax unused */
+ (void)ymin;
+ (void)xmax;
+
int line_offset;
for(int j = 0; j < rect.Height; j++)
{
@@ -1206,6 +1679,10 @@ static void sRGBA2Bitmap(Bitmap& image, int width, int height, const unsigned ch
Rect rect(0,0,image.GetWidth(),image.GetHeight());
image.LockBits(&rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapData);
+ /* ymin and xmax unused */
+ (void)ymin;
+ (void)xmax;
+
int line_offset;
for(int j = 0; j < rect.Height; j++)
{
@@ -1237,6 +1714,10 @@ static void sAlpha2Bitmap(Bitmap& image, int width, int height, const unsigned c
Rect rect(0,0,image.GetWidth(),image.GetHeight());
image.LockBits(&rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapData);
+ /* ymin and xmax unused */
+ (void)ymin;
+ (void)xmax;
+
int line_offset;
for(int j = 0; j < rect.Height; j++)
{
@@ -1279,6 +1760,10 @@ static void sMap2Bitmap(Bitmap& image, int width, int height, const unsigned cha
Rect rect(0,0,image.GetWidth(),image.GetHeight());
image.LockBits(&rect, ImageLockModeWrite, PixelFormat24bppRGB, &bitmapData);
+ /* ymin and xmax unused */
+ (void)ymin;
+ (void)xmax;
+
int line_offset;
for(int j = 0; j < rect.Height; j++)
{
@@ -1337,7 +1822,7 @@ static void cdgetimagergb(cdCtxCanvas* ctxcanvas, unsigned char *red, unsigned c
if (!transformMatrix.IsIdentity())
ctxcanvas->graphics->ResetTransform(); // reset to the identity.
- if (ctxcanvas->canvas->invert_yaxis==0) // if 0, then the transform was reset
+ if (ctxcanvas->canvas->invert_yaxis==0) // if 0, invert because the transform was reset here
y = _cdInvertYAxis(ctxcanvas->canvas, y);
int yr = y - (h - 1); /* y starts at the bottom of the image */
@@ -1637,7 +2122,7 @@ static cdCtxImage *cdcreateimage(cdCtxCanvas* ctxcanvas, int width, int height)
ctximage->h_mm = ctximage->h / ctximage->yres;
Graphics imggraphics(ctximage->bitmap);
- imggraphics.Clear(Color::White);
+ imggraphics.Clear(Color((ARGB)Color::White));
return ctximage;
}
@@ -1649,10 +2134,11 @@ static void cdgetimage(cdCtxCanvas* ctxcanvas, cdCtxImage *ctximage, int x, int
if (!transformMatrix.IsIdentity())
ctxcanvas->graphics->ResetTransform(); // reset to the identity.
- if (ctxcanvas->canvas->invert_yaxis==0) // if 0, then the transform was reset
+ if (ctxcanvas->canvas->invert_yaxis==0) // if 0, invert because the transform was reset here
y = _cdInvertYAxis(ctxcanvas->canvas, y);
- int yr = y - (ctximage->h - 1); /* y0 starts at the bottom of the image */
+ /* y is the bottom-left of the image in CD, must be at upper-left */
+ y -= ctximage->h-1;
if (ctxcanvas->wtype == CDW_BMP)
{
@@ -1660,7 +2146,7 @@ static void cdgetimage(cdCtxCanvas* ctxcanvas, cdCtxImage *ctximage, int x, int
imggraphics.DrawImage(ctxcanvas->bitmap,
Rect(0, 0, ctximage->w,ctximage->h),
- x, yr, ctximage->w, ctximage->h, UnitPixel,
+ x, y, ctximage->w, ctximage->h, UnitPixel,
NULL, NULL, NULL);
}
else
@@ -1670,7 +2156,7 @@ static void cdgetimage(cdCtxCanvas* ctxcanvas, cdCtxImage *ctximage, int x, int
HDC hdc = ctxcanvas->graphics->GetHDC();
HDC img_hdc = imggraphics.GetHDC();
- BitBlt(img_hdc,0,0,ctximage->w,ctximage->h,hdc,x,yr,SRCCOPY);
+ BitBlt(img_hdc,0,0,ctximage->w,ctximage->h,hdc,x,y,SRCCOPY);
imggraphics.ReleaseHDC(img_hdc);
ctxcanvas->graphics->ReleaseHDC(hdc);
@@ -1740,7 +2226,7 @@ static void cdscrollarea(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, i
if (!transformMatrix.IsIdentity())
ctxcanvas->graphics->ResetTransform(); // reset to the identity.
- if (ctxcanvas->canvas->invert_yaxis==0) // if 0, then the transform was reset
+ if (ctxcanvas->canvas->invert_yaxis==0) // if 0, invert because the transform was reset here
{
dy = -dy;
ymin = _cdInvertYAxis(ctxcanvas->canvas, ymin);
@@ -1992,7 +2478,8 @@ static cdAttribute linecap_attrib =
static void set_rotate_attrib(cdCtxCanvas* ctxcanvas, char* data)
{
- /* ignore ROTATE if transform is set */
+ /* ignore ROTATE if transform is set,
+ because there is native support for transformations */
if (ctxcanvas->canvas->use_matrix)
return;
@@ -2009,7 +2496,7 @@ static void set_rotate_attrib(cdCtxCanvas* ctxcanvas, char* data)
ctxcanvas->rotate_center_y = 0;
}
- cdwpUpdateTransform(ctxcanvas);
+ cdtransform(ctxcanvas, NULL);
}
static char* get_rotate_attrib(cdCtxCanvas* ctxcanvas)
@@ -2073,19 +2560,22 @@ static cdAttribute img_points_attrib =
get_img_points_attrib
};
-static BOOL Is_WinXP_or_Later(void)
+static BOOL Is_WinXP_or_WinSrv03(void)
{
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx (&osvi);
- BOOL bIsWindowsXPorLater =
+ BOOL bIsWindowsXP =
+ (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
+ ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 1));
+
+ BOOL bIsWindowsServer2003 =
(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
- ( (osvi.dwMajorVersion > 5) || ( (osvi.dwMajorVersion == 5) &&
- (osvi.dwMinorVersion >= 1)));
+ ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 2));
- return bIsWindowsXPorLater;
+ return bIsWindowsXP || bIsWindowsServer2003;
}
static void set_aa_attrib(cdCtxCanvas* ctxcanvas, char* data)
@@ -2101,7 +2591,7 @@ static void set_aa_attrib(cdCtxCanvas* ctxcanvas, char* data)
{
ctxcanvas->graphics->SetInterpolationMode(InterpolationModeBilinear);
ctxcanvas->graphics->SetSmoothingMode(SmoothingModeAntiAlias);
- if (Is_WinXP_or_Later())
+ if (Is_WinXP_or_WinSrv03())
ctxcanvas->graphics->SetTextRenderingHint(TextRenderingHintClearTypeGridFit);
else
ctxcanvas->graphics->SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
@@ -2198,7 +2688,7 @@ void cdwpUpdateCanvas(cdCtxCanvas* ctxcanvas)
else
set_aa_attrib(ctxcanvas, NULL);
- cdwpUpdateTransform(ctxcanvas);
+ sUpdateTransform(ctxcanvas);
}
/*
@@ -2229,6 +2719,7 @@ cdCtxCanvas *cdwpCreateCanvas(cdCanvas* canvas, Graphics* graphics, int wtype)
canvas->invert_yaxis = 1;
ctxcanvas->clip_poly = NULL;
+ ctxcanvas->clip_fpoly = NULL;
ctxcanvas->clip_poly_n = 0;
ctxcanvas->clip_region = NULL;
ctxcanvas->new_region = NULL;
@@ -2284,6 +2775,7 @@ void cdwpInitTable(cdCanvas* canvas)
canvas->cxFlush = cdflush;
canvas->cxPixel = cdpixel;
+
canvas->cxLine = cdline;
canvas->cxPoly = cdpoly;
canvas->cxRect = cdrect;
@@ -2293,6 +2785,14 @@ void cdwpInitTable(cdCanvas* canvas)
canvas->cxChord = cdchord;
canvas->cxText = cdtext;
+ canvas->cxFLine = cdfline;
+ canvas->cxFPoly = cdfpoly;
+ canvas->cxFRect = cdfrect;
+ canvas->cxFBox = cdfbox;
+ canvas->cxFArc = cdfarc;
+ canvas->cxFSector = cdfsector;
+ canvas->cxFChord = cdfchord;
+
canvas->cxNewRegion = cdnewregion;
canvas->cxIsPointInRegion = cdispointinregion;
canvas->cxOffsetRegion = cdoffsetregion;