diff options
Diffstat (limited to 'cd/src/gdiplus')
-rwxr-xr-x | cd/src/gdiplus/cdwclpp.cpp | 6 | ||||
-rwxr-xr-x | cd/src/gdiplus/cdwdbufp.cpp | 5 | ||||
-rwxr-xr-x | cd/src/gdiplus/cdwemfp.cpp | 3 | ||||
-rwxr-xr-x | cd/src/gdiplus/cdwimgp.cpp | 3 | ||||
-rwxr-xr-x | cd/src/gdiplus/cdwinp.cpp | 596 | ||||
-rwxr-xr-x | cd/src/gdiplus/cdwinp.h | 5 | ||||
-rwxr-xr-x | cd/src/gdiplus/cdwnativep.cpp | 3 | ||||
-rwxr-xr-x | cd/src/gdiplus/cdwprnp.cpp | 1 |
8 files changed, 556 insertions, 66 deletions
diff --git a/cd/src/gdiplus/cdwclpp.cpp b/cd/src/gdiplus/cdwclpp.cpp index 719713f..0e3c5ea 100755 --- a/cd/src/gdiplus/cdwclpp.cpp +++ b/cd/src/gdiplus/cdwclpp.cpp @@ -187,10 +187,8 @@ static void cdinittable(cdCanvas* canvas) static cdContext cdClipboardContext = { - CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_FLUSH | CD_CAP_YAXIS | - CD_CAP_PLAY | - CD_CAP_IMAGERGBA | CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV | - CD_CAP_FPRIMTIVES ), + CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_FLUSH | CD_CAP_YAXIS | CD_CAP_PLAY | + CD_CAP_IMAGERGBA | CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV ), 1, cdcreatecanvas, cdinittable, diff --git a/cd/src/gdiplus/cdwdbufp.cpp b/cd/src/gdiplus/cdwdbufp.cpp index 95cfe2e..68bc7b8 100755 --- a/cd/src/gdiplus/cdwdbufp.cpp +++ b/cd/src/gdiplus/cdwdbufp.cpp @@ -120,7 +120,7 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data) bitmap->SetResolution((REAL)(canvas_dbuffer->xres*25.4), (REAL)(canvas_dbuffer->yres*25.4)); Graphics imggraphics(bitmap); - imggraphics.Clear(Color::White); + imggraphics.Clear(Color((ARGB)Color::White)); Graphics* graphics = new Graphics(bitmap); @@ -147,8 +147,7 @@ static void cdinittable(cdCanvas* canvas) static cdContext cdDBufferContext = { - CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | - CD_CAP_FPRIMTIVES), + CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS ), 1, cdcreatecanvas, cdinittable, diff --git a/cd/src/gdiplus/cdwemfp.cpp b/cd/src/gdiplus/cdwemfp.cpp index 38b4200..23ae02d 100755 --- a/cd/src/gdiplus/cdwemfp.cpp +++ b/cd/src/gdiplus/cdwemfp.cpp @@ -58,7 +58,7 @@ static void cdcreatecanvas(cdCanvas* canvas, void* data) Rect frameRect(0, 0, (int)(100 * w / canvas->xres), (int)(100 * h / canvas->yres)); metafile = new Metafile(cdwpString2Unicode(filename, strlen(filename)), - ScreenDC, frameRect, MetafileFrameUnitGdi, EmfTypeEmfPlusDual, NULL); + ScreenDC, frameRect, MetafileFrameUnitGdi, EmfTypeEmfPlusDual, NULL); ReleaseDC(NULL, ScreenDC); } @@ -86,7 +86,6 @@ static void cdinittable(cdCanvas* canvas) static cdContext cdEMFContext = { CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_FLUSH | CD_CAP_YAXIS | - CD_CAP_FPRIMTIVES | CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV), 1, cdcreatecanvas, diff --git a/cd/src/gdiplus/cdwimgp.cpp b/cd/src/gdiplus/cdwimgp.cpp index 697ff40..5dd8b96 100755 --- a/cd/src/gdiplus/cdwimgp.cpp +++ b/cd/src/gdiplus/cdwimgp.cpp @@ -48,8 +48,7 @@ static void cdinittable(cdCanvas* canvas) static cdContext cdImageContext = { - CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_YAXIS | - CD_CAP_FPRIMTIVES ), + CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_YAXIS ), 1, cdcreatecanvas, cdinittable, 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; diff --git a/cd/src/gdiplus/cdwinp.h b/cd/src/gdiplus/cdwinp.h index 0c4ae55..b42dc9a 100755 --- a/cd/src/gdiplus/cdwinp.h +++ b/cd/src/gdiplus/cdwinp.h @@ -48,15 +48,12 @@ struct _cdCtxCanvas } fontinfo; Point *clip_poly; /* coordenadas do pixel no X,Y */ + PointF *clip_fpoly; /* coordenadas do pixel no X,Y */ int clip_poly_n; /* numero de pontos correntes */ Region *clip_region; Region *new_region; - int max_points; - PointF *wdpoly; // cache buffer for wdpoly - Point *cdpoly; // alias to cache buffer (float=int) - int antialias; Point gradient[2]; diff --git a/cd/src/gdiplus/cdwnativep.cpp b/cd/src/gdiplus/cdwnativep.cpp index fffd044..80209af 100755 --- a/cd/src/gdiplus/cdwnativep.cpp +++ b/cd/src/gdiplus/cdwnativep.cpp @@ -121,8 +121,7 @@ static void cdinittable(cdCanvas* canvas) static cdContext cdNativeContext = { - CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_YAXIS | - CD_CAP_FPRIMTIVES ), + CD_CAP_ALL & ~(CD_CAP_FLUSH | CD_CAP_PLAY | CD_CAP_YAXIS ), 1, cdcreatecanvas, cdinittable, diff --git a/cd/src/gdiplus/cdwprnp.cpp b/cd/src/gdiplus/cdwprnp.cpp index 3d2b9f7..2eed9d9 100755 --- a/cd/src/gdiplus/cdwprnp.cpp +++ b/cd/src/gdiplus/cdwprnp.cpp @@ -140,7 +140,6 @@ static void cdinittable(cdCanvas* canvas) static cdContext cdPrinterContext = { CD_CAP_ALL & ~(CD_CAP_CLEAR | CD_CAP_PLAY | CD_CAP_YAXIS | - CD_CAP_FPRIMTIVES | CD_CAP_GETIMAGERGB | CD_CAP_IMAGESRV), 1, cdcreatecanvas, |