summaryrefslogtreecommitdiff
path: root/cd/src/win32
diff options
context:
space:
mode:
Diffstat (limited to 'cd/src/win32')
-rwxr-xr-xcd/src/win32/cdwdbuf.c1
-rwxr-xr-xcd/src/win32/cdwdib.c38
-rwxr-xr-xcd/src/win32/cdwin.c313
-rwxr-xr-xcd/src/win32/cdwin.h1
-rwxr-xr-xcd/src/win32/cdwnative.c11
5 files changed, 256 insertions, 108 deletions
diff --git a/cd/src/win32/cdwdbuf.c b/cd/src/win32/cdwdbuf.c
index 85af87c..4beac10 100755
--- a/cd/src/win32/cdwdbuf.c
+++ b/cd/src/win32/cdwdbuf.c
@@ -75,6 +75,7 @@ static void cdcreatecanvas(cdCanvas* canvas, cdCanvas* canvas_dbuffer)
canvas->bpp = ctximage->bpp;
canvas->xres = ctximage->xres;
canvas->yres = ctximage->yres;
+
ctxcanvas->clip_pnt[2].x = ctxcanvas->clip_pnt[1].x = ctximage->w - 1;
ctxcanvas->clip_pnt[3].y = ctxcanvas->clip_pnt[2].y = ctximage->h - 1;
}
diff --git a/cd/src/win32/cdwdib.c b/cd/src/win32/cdwdib.c
index aff3f64..25851cd 100755
--- a/cd/src/win32/cdwdib.c
+++ b/cd/src/win32/cdwdib.c
@@ -323,6 +323,44 @@ void cdwDIBEncodeRGBARect(cdwDIB* dib, const unsigned char *red, const unsigned
}
}
+void cdwDIBEncodeRGBARectMirror(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int xi, int yi, int wi, int hi)
+{
+ int x,y, resto1, resto2, offset, line_size;
+ BYTE* bits;
+
+ line_size = cdwDIBLineSize(dib->w, 32);
+
+ bits = dib->bits + line_size*(dib->h-1);
+ resto1 = line_size - dib->w * 4;
+ resto2 = wi - dib->w;
+
+ offset = wi * yi + xi;
+
+ red = red + offset;
+ green = green + offset;
+ blue = blue + offset;
+ alpha = alpha + offset;
+
+ for (y = 0; y < dib->h; y++)
+ {
+ for (x = 0; x < dib->w; x++)
+ {
+ *bits++ = CD_ALPHAPRE(*blue, *alpha); blue++;
+ *bits++ = CD_ALPHAPRE(*green, *alpha); green++;
+ *bits++ = CD_ALPHAPRE(*red, *alpha); red++;
+ *bits++ = *alpha++;
+ }
+
+ bits += resto1;
+ bits -= 2*line_size;
+
+ red += resto2;
+ green += resto2;
+ blue += resto2;
+ alpha += resto2;
+ }
+}
+
void cdwDIBEncodeAlphaRect(cdwDIB* dib, const unsigned char *alpha, int xi, int yi, int wi, int hi)
{
int x,y, resto1, resto2, offset;
diff --git a/cd/src/win32/cdwin.c b/cd/src/win32/cdwin.c
index 313e833..e2eb9ea 100755
--- a/cd/src/win32/cdwin.c
+++ b/cd/src/win32/cdwin.c
@@ -626,6 +626,7 @@ static int cdinteriorstyle (cdCtxCanvas* ctxcanvas, int style)
ctxcanvas->hBrush = CreateBrushIndirect(&ctxcanvas->logBrush);
ctxcanvas->hOldBrush = SelectObject(ctxcanvas->hDC, ctxcanvas->hBrush);
break;
+ /* the remaining styles must recreate the current brush */
case CD_HATCH:
cdhatch(ctxcanvas, ctxcanvas->canvas->hatch_style);
break;
@@ -642,10 +643,26 @@ static int cdinteriorstyle (cdCtxCanvas* ctxcanvas, int style)
return style;
}
+static void sUpdateFill(cdCtxCanvas* ctxcanvas, int fill)
+{
+ if (fill)
+ {
+ if ((ctxcanvas->logBrush.lbColor != ctxcanvas->fg) &&
+ (ctxcanvas->canvas->interior_style != CD_PATTERN))
+ cdinteriorstyle(ctxcanvas, ctxcanvas->canvas->interior_style);
+ }
+ else
+ {
+ if (ctxcanvas->rebuild_pen)
+ sCreatePen(ctxcanvas);
+ }
+}
+
+/*******************************************************************************/
+
static void cdline (cdCtxCanvas* ctxcanvas, int x1, int y1, int x2, int y2)
{
- if (ctxcanvas->rebuild_pen)
- sCreatePen(ctxcanvas);
+ sUpdateFill(ctxcanvas, 0);
MoveToEx( ctxcanvas->hDC, x1, y1, NULL );
LineTo( ctxcanvas->hDC, x2, y2 );
@@ -656,8 +673,7 @@ static void cdrect (cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ym
{
HBRUSH oldBrush;
- if (ctxcanvas->rebuild_pen)
- sCreatePen(ctxcanvas);
+ sUpdateFill(ctxcanvas, 0);
oldBrush = SelectObject(ctxcanvas->hDC, GetStockObject(NULL_BRUSH)); /* tira o desenho do interior */
Rectangle(ctxcanvas->hDC, xmin, ymin, xmax+1, ymax+1); /* +1 porque nao inclue right/bottom */
@@ -666,9 +682,7 @@ static void cdrect (cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ym
static void cdbox (cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, int ymax)
{
- if ((ctxcanvas->logBrush.lbColor != ctxcanvas->fg) &&
- (ctxcanvas->canvas->interior_style != CD_PATTERN) )
- cdinteriorstyle(ctxcanvas, ctxcanvas->canvas->interior_style);
+ sUpdateFill(ctxcanvas, 1);
if (ctxcanvas->canvas->new_region)
{
@@ -696,40 +710,46 @@ typedef struct _winArcParam
YEndArc; /* second radial ending point */
} winArcParam;
-static void calcArc(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double angle1, double angle2, winArcParam* arc)
+static void sCalcArc(cdCanvas* canvas, int xc, int yc, int w, int h, double a1, double a2, winArcParam* arc, int swap)
{
- arc->LeftRect = xc - w/2;
- arc->RightRect = xc + w/2 + 1;
- arc->XStartArc = xc + cdRound(w * cos(CD_DEG2RAD * angle1) / 2.0);
- arc->XEndArc = xc + cdRound(w * cos(CD_DEG2RAD * angle2) / 2.0);
+ /* computation is done as if the angles are counter-clockwise,
+ and yaxis is NOT inverted. */
- if (ctxcanvas->canvas->invert_yaxis)
+ arc->LeftRect = xc - w/2;
+ arc->TopRect = yc - h/2;
+ arc->RightRect = xc + w/2 + 1;
+ arc->BottomRect = yc + h/2 + 1;
+
+ /* GDI orientation is the same as CD */
+
+ if (!canvas->invert_yaxis)
+ _cdSwapInt(arc->BottomRect, arc->TopRect); /* not necessary, but done for clarity */
+
+ cdCanvasGetArcStartEnd(xc, yc, w, h, a1, a2, &(arc->XStartArc), &(arc->YStartArc), &(arc->XEndArc), &(arc->YEndArc));
+
+ if (canvas->invert_yaxis)
{
- arc->TopRect = yc - h/2;
- arc->BottomRect = yc + h/2 + 1;
- arc->YStartArc = yc - cdRound(h * sin(CD_DEG2RAD * angle1) / 2.0);
- arc->YEndArc = yc - cdRound(h * sin(CD_DEG2RAD * angle2) / 2.0);
+ /* fix axis orientation */
+ arc->YStartArc = 2*yc - arc->YStartArc;
+ arc->YEndArc = 2*yc - arc->YEndArc;
}
else
{
- arc->BottomRect = yc - h/2;
- arc->TopRect = yc + h/2 + 1;
- arc->YStartArc = yc + cdRound(h * sin(CD_DEG2RAD * angle1) / 2.0);
- arc->YEndArc = yc + cdRound(h * sin(CD_DEG2RAD * angle2) / 2.0);
-
- /* it is clock-wise when axis inverted */
- _cdSwapInt(arc->XStartArc, arc->XEndArc);
- _cdSwapInt(arc->YStartArc, arc->YEndArc);
+ /* it is clock-wise when axis NOT inverted */
+ if (swap)
+ {
+ _cdSwapInt(arc->XStartArc, arc->XEndArc);
+ _cdSwapInt(arc->YStartArc, arc->YEndArc);
+ }
}
}
static void cdarc(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double angle1, double angle2)
{
winArcParam arc;
- calcArc(ctxcanvas, xc, yc, w, h, angle1, angle2, &arc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, angle1, angle2, &arc, 1);
- if (ctxcanvas->rebuild_pen)
- sCreatePen(ctxcanvas);
+ sUpdateFill(ctxcanvas, 0);
Arc(ctxcanvas->hDC, arc.LeftRect, arc.TopRect, arc.RightRect, arc.BottomRect, arc.XStartArc, arc.YStartArc, arc.XEndArc, arc.YEndArc);
}
@@ -737,11 +757,9 @@ static void cdarc(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double a
static void cdsector(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double angle1, double angle2)
{
winArcParam arc;
- calcArc(ctxcanvas, xc, yc, w, h, angle1, angle2, &arc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, angle1, angle2, &arc, 1);
- if ((ctxcanvas->logBrush.lbColor != ctxcanvas->fg) &&
- (ctxcanvas->canvas->interior_style != CD_PATTERN) )
- cdinteriorstyle(ctxcanvas, ctxcanvas->canvas->interior_style);
+ sUpdateFill(ctxcanvas, 1);
if (angle1==0 && angle2==360)
{
@@ -781,11 +799,9 @@ static void cdsector(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, doubl
static void cdchord(cdCtxCanvas* ctxcanvas, int xc, int yc, int w, int h, double angle1, double angle2)
{
winArcParam arc;
- calcArc(ctxcanvas, xc, yc, w, h, angle1, angle2, &arc);
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, angle1, angle2, &arc, 1);
- if ((ctxcanvas->logBrush.lbColor != ctxcanvas->fg) &&
- (ctxcanvas->canvas->interior_style != CD_PATTERN) )
- cdinteriorstyle(ctxcanvas, ctxcanvas->canvas->interior_style);
+ sUpdateFill(ctxcanvas, 1);
if (angle1==0 && angle2==360)
{
@@ -828,6 +844,105 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
POINT* pnt;
HPEN oldPen = NULL, Pen = NULL;
+ if (mode == CD_PATH)
+ {
+ int p, current_set;
+
+ /* if there is any current path, remove it */
+ BeginPath(ctxcanvas->hDC);
+ current_set = 0;
+
+ i = 0;
+ for (p=0; p<ctxcanvas->canvas->path_n; p++)
+ {
+ switch(ctxcanvas->canvas->path[p])
+ {
+ case CD_PATH_NEW:
+ EndPath(ctxcanvas->hDC);
+ BeginPath(ctxcanvas->hDC);
+ current_set = 0;
+ break;
+ case CD_PATH_MOVETO:
+ if (i+1 > n) return;
+ MoveToEx(ctxcanvas->hDC, poly[i].x, poly[i].y, NULL);
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_LINETO:
+ if (i+1 > n) return;
+ LineTo(ctxcanvas->hDC, poly[i].x, poly[i].y);
+ current_set = 1;
+ i++;
+ break;
+ case CD_PATH_ARC:
+ {
+ int xc, yc, w, h, old_arcmode = 0;
+ double a1, a2;
+ winArcParam arc;
+
+ if (i+3 > n) return;
+
+ if (!cdCanvasGetArcPath(ctxcanvas->canvas, poly+i, &xc, &yc, &w, &h, &a1, &a2))
+ return;
+
+ sCalcArc(ctxcanvas->canvas, xc, yc, w, h, a1, a2, &arc, 0);
+
+ if (current_set)
+ LineTo(ctxcanvas->hDC, arc.XStartArc, arc.YStartArc);
+
+ if ((a2-a1)<0) /* can be clockwise */
+ {
+ /* Arc behave diferent when GM_ADVANCED is set */
+ old_arcmode = SetArcDirection(ctxcanvas->hDC, ctxcanvas->canvas->invert_yaxis? AD_CLOCKWISE: AD_COUNTERCLOCKWISE);
+ }
+
+ ArcTo(ctxcanvas->hDC, arc.LeftRect, arc.TopRect, arc.RightRect, arc.BottomRect, arc.XStartArc, arc.YStartArc, arc.XEndArc, arc.YEndArc);
+
+ if (old_arcmode) /* restore */
+ SetArcDirection(ctxcanvas->hDC, old_arcmode);
+
+ current_set = 1;
+
+ i += 3;
+ }
+ break;
+ case CD_PATH_CURVETO:
+ if (i+3 > n) return;
+ PolyBezierTo(ctxcanvas->hDC, (POINT*)(poly + i), 3);
+ current_set = 1;
+ i += 3;
+ break;
+ case CD_PATH_CLOSE:
+ CloseFigure(ctxcanvas->hDC);
+ break;
+ case CD_PATH_FILL:
+ sUpdateFill(ctxcanvas, 1);
+ SetPolyFillMode(ctxcanvas->hDC, ctxcanvas->canvas->fill_mode==CD_EVENODD?ALTERNATE:WINDING);
+ EndPath(ctxcanvas->hDC);
+ FillPath(ctxcanvas->hDC);
+ break;
+ case CD_PATH_STROKE:
+ sUpdateFill(ctxcanvas, 0);
+ EndPath(ctxcanvas->hDC);
+ StrokePath(ctxcanvas->hDC);
+ break;
+ case CD_PATH_FILLSTROKE:
+ sUpdateFill(ctxcanvas, 1);
+ sUpdateFill(ctxcanvas, 0);
+ SetPolyFillMode(ctxcanvas->hDC, ctxcanvas->canvas->fill_mode==CD_EVENODD?ALTERNATE:WINDING);
+ EndPath(ctxcanvas->hDC);
+ StrokeAndFillPath(ctxcanvas->hDC);
+ break;
+ case CD_PATH_CLIP:
+ SetPolyFillMode(ctxcanvas->hDC, ctxcanvas->canvas->fill_mode==CD_EVENODD?ALTERNATE:WINDING);
+ EndPath(ctxcanvas->hDC);
+ SelectClipPath(ctxcanvas->hDC, RGN_AND);
+ break;
+ }
+ }
+ return;
+ }
+
switch( mode )
{
case CD_CLOSED_LINES:
@@ -836,13 +951,11 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
n++;
/* continua */
case CD_OPEN_LINES:
- if (ctxcanvas->rebuild_pen)
- sCreatePen(ctxcanvas);
+ sUpdateFill(ctxcanvas, 0);
Polyline(ctxcanvas->hDC, (POINT*)poly, n);
break;
case CD_BEZIER:
- if (ctxcanvas->rebuild_pen)
- sCreatePen(ctxcanvas);
+ sUpdateFill(ctxcanvas, 0);
PolyBezier(ctxcanvas->hDC, (POINT*)poly, n);
break;
case CD_FILL:
@@ -857,14 +970,10 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
}
else
{
- if ((ctxcanvas->logBrush.lbColor != ctxcanvas->fg) &&
- (ctxcanvas->canvas->interior_style != CD_PATTERN))
- cdinteriorstyle(ctxcanvas, ctxcanvas->canvas->interior_style);
+ sUpdateFill(ctxcanvas, 1);
if (ctxcanvas->canvas->interior_style != CD_SOLID || ctxcanvas->fill_attrib[0] == '0')
- {
SelectObject(ctxcanvas->hDC, ctxcanvas->hNullPen); /* tira o desenho da borda */
- }
else
{
Pen = CreatePen(PS_SOLID, 1, ctxcanvas->fg);
@@ -875,9 +984,7 @@ static void cdpoly(cdCtxCanvas* ctxcanvas, int mode, cdPoint* poly, int n)
Polygon(ctxcanvas->hDC, (POINT*)poly, n);
if (ctxcanvas->canvas->interior_style != CD_SOLID || ctxcanvas->fill_attrib[0] == '0')
- {
SelectObject(ctxcanvas->hDC, ctxcanvas->hPen); /* restaura a Pen corrente */
- }
else
{
SelectObject(ctxcanvas->hDC, oldPen);
@@ -963,8 +1070,37 @@ static void cdtransform(cdCtxCanvas *ctxcanvas, const double* matrix)
else
{
ctxcanvas->canvas->invert_yaxis = 1;
- ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
- SetGraphicsMode(ctxcanvas->hDC, GM_COMPATIBLE);
+
+ if (ctxcanvas->rotate_angle)
+ {
+ XFORM xForm;
+
+ /* the rotation must be corrected because of the Y axis orientation */
+
+ SetGraphicsMode(ctxcanvas->hDC, GM_ADVANCED);
+ ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
+
+ xForm.eM11 = (FLOAT) cos(-CD_DEG2RAD*ctxcanvas->rotate_angle);
+ xForm.eM12 = (FLOAT) sin(-CD_DEG2RAD*ctxcanvas->rotate_angle);
+ xForm.eM21 = (FLOAT) -xForm.eM12;
+ xForm.eM22 = (FLOAT) xForm.eM11;
+ xForm.eDx = (FLOAT) ctxcanvas->rotate_center_x;
+ xForm.eDy = (FLOAT) _cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y);
+ ModifyWorldTransform(ctxcanvas->hDC, &xForm, MWT_LEFTMULTIPLY);
+
+ xForm.eM11 = (FLOAT) 1;
+ xForm.eM12 = (FLOAT) 0;
+ xForm.eM21 = (FLOAT) 0;
+ xForm.eM22 = (FLOAT) 1;
+ xForm.eDx = (FLOAT) -ctxcanvas->rotate_center_x;
+ xForm.eDy = (FLOAT) -_cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y);
+ ModifyWorldTransform(ctxcanvas->hDC, &xForm, MWT_LEFTMULTIPLY);
+ }
+ else
+ {
+ ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
+ SetGraphicsMode(ctxcanvas->hDC, GM_COMPATIBLE);
+ }
}
}
@@ -1581,11 +1717,12 @@ static void cdgetimagergb(cdCtxCanvas* ctxcanvas, unsigned char *red, unsigned c
if (GetGraphicsMode(ctxcanvas->hDC) == GM_ADVANCED)
{
+ /* reset to the identity. */
GetWorldTransform(ctxcanvas->hDC, &xForm);
ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_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);
yr = y - (h - 1); /* y starts at the bottom of the image */
@@ -1622,10 +1759,12 @@ static void sFixImageY(cdCanvas* canvas, int *y, int *h)
/* Here, y is from top to bottom,
is at the bottom-left corner of the image if h>0
is at the top-left corner of the image if h<0. (Undocumented feature)
+
cdCalcZoom expects Y at top-left if h>0
and Y at bottom-left if h<0
if h<0 then eh<0 to StretchDIBits mirror the image.
- BUT!!!!!! AlphaBlend will NOT mirror the image. */
+ BUT!!!!!! AlphaBlend will NOT mirror the image.
+ So it must be manually made there. */
if (!canvas->invert_yaxis)
*h = -(*h);
@@ -1741,26 +1880,16 @@ static void cdputimagerectrgba(cdCtxCanvas* ctxcanvas, int width, int height, co
return;
}
- cdwDIBEncodeRGBARect(&dib, red, green, blue, alpha, bx, by, width, height);
-
if (eh < 0) /* must mirror the image */
{
- XFORM xForm;
-
+ /* Fix position */
eh = -eh;
+ ey = ey - eh;
- SetGraphicsMode(hDCMem, GM_ADVANCED);
- ModifyWorldTransform(hDCMem, NULL, MWT_IDENTITY);
-
- /* configure a bottom-up coordinate system */
- xForm.eM11 = (FLOAT)1;
- xForm.eM12 = (FLOAT)0;
- xForm.eM21 = (FLOAT)0;
- xForm.eM22 = (FLOAT)-1;
- xForm.eDx = (FLOAT)0;
- xForm.eDy = (FLOAT)(bh-1);
- ModifyWorldTransform(hDCMem, &xForm, MWT_LEFTMULTIPLY);
+ cdwDIBEncodeRGBARectMirror(&dib, red, green, blue, alpha, bx, by, width, height);
}
+ else
+ cdwDIBEncodeRGBARect(&dib, red, green, blue, alpha, bx, by, width, height);
hOldBitmap = SelectObject(hDCMem, hBitmap);
@@ -1891,20 +2020,21 @@ static cdCtxImage *cdcreateimage(cdCtxCanvas* ctxcanvas, int width, int height)
static void cdgetimage(cdCtxCanvas* ctxcanvas, cdCtxImage *ctximage, int x, int y)
{
- int yr;
XFORM xForm;
if (GetGraphicsMode(ctxcanvas->hDC) == GM_ADVANCED)
{
+ /* reset to the identity. */
GetWorldTransform(ctxcanvas->hDC, &xForm);
ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_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);
- yr = y - (ctximage->h - 1);
- BitBlt(ctximage->hDC, 0, 0, ctximage->w, ctximage->h, ctxcanvas->hDC, x, yr, SRCCOPY);
+ /* y is the bottom-left of the image in CD, must be at upper-left */
+ y -= ctximage->h-1;
+ BitBlt(ctximage->hDC, 0, 0, ctximage->w, ctximage->h, ctxcanvas->hDC, x, y, SRCCOPY);
if (GetGraphicsMode(ctxcanvas->hDC) == GM_ADVANCED)
ModifyWorldTransform(ctxcanvas->hDC, &xForm, MWT_LEFTMULTIPLY);
@@ -1971,18 +2101,15 @@ static void cdscrollarea(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, i
{
XFORM xForm;
RECT rect;
- rect.left = xmin;
- rect.right = xmax+1;
- rect.top = ymin;
- rect.bottom = ymax+1;
if (GetGraphicsMode(ctxcanvas->hDC) == GM_ADVANCED)
{
+ /* reset to the identity. */
GetWorldTransform(ctxcanvas->hDC, &xForm);
ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_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);
@@ -1990,6 +2117,11 @@ static void cdscrollarea(cdCtxCanvas* ctxcanvas, int xmin, int xmax, int ymin, i
_cdSwapInt(ymin, ymax);
}
+ rect.left = xmin;
+ rect.right = xmax+1;
+ rect.top = ymin;
+ rect.bottom = ymax+1;
+
ScrollDC(ctxcanvas->hDC, dx, dy, &rect, NULL, NULL, NULL);
if (GetGraphicsMode(ctxcanvas->hDC) == GM_ADVANCED)
@@ -2136,47 +2268,25 @@ static cdAttribute img_points_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;
if (data)
{
- XFORM xForm;
sscanf(data, "%g %d %d", &ctxcanvas->rotate_angle,
&ctxcanvas->rotate_center_x,
&ctxcanvas->rotate_center_y);
-
- /* the rotation must be corrected because of the Y axis orientation */
-
- SetGraphicsMode(ctxcanvas->hDC, GM_ADVANCED);
- ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
-
- xForm.eM11 = (FLOAT) cos(-CD_DEG2RAD*ctxcanvas->rotate_angle);
- xForm.eM12 = (FLOAT) sin(-CD_DEG2RAD*ctxcanvas->rotate_angle);
- xForm.eM21 = (FLOAT) -xForm.eM12;
- xForm.eM22 = (FLOAT) xForm.eM11;
- xForm.eDx = (FLOAT) ctxcanvas->rotate_center_x;
- xForm.eDy = (FLOAT) _cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y);
- ModifyWorldTransform(ctxcanvas->hDC, &xForm, MWT_LEFTMULTIPLY);
-
- xForm.eM11 = (FLOAT) 1;
- xForm.eM12 = (FLOAT) 0;
- xForm.eM21 = (FLOAT) 0;
- xForm.eM22 = (FLOAT) 1;
- xForm.eDx = (FLOAT) -ctxcanvas->rotate_center_x;
- xForm.eDy = (FLOAT) -_cdInvertYAxis(ctxcanvas->canvas, ctxcanvas->rotate_center_y);
- ModifyWorldTransform(ctxcanvas->hDC, &xForm, MWT_LEFTMULTIPLY);
}
else
{
ctxcanvas->rotate_angle = 0;
ctxcanvas->rotate_center_x = 0;
ctxcanvas->rotate_center_y = 0;
-
- ModifyWorldTransform(ctxcanvas->hDC, NULL, MWT_IDENTITY);
- SetGraphicsMode(ctxcanvas->hDC, GM_COMPATIBLE);
}
+
+ cdtransform(ctxcanvas, NULL);
}
static char* get_rotate_attrib(cdCtxCanvas* ctxcanvas)
@@ -2325,6 +2435,7 @@ void cdwInitTable(cdCanvas* canvas)
canvas->cxSector = cdsector;
canvas->cxChord = cdchord;
canvas->cxText = cdtext;
+
canvas->cxGetFontDim = cdgetfontdim;
canvas->cxGetTextSize = cdgettextsize;
canvas->cxPutImageRectRGB = cdputimagerectrgb;
diff --git a/cd/src/win32/cdwin.h b/cd/src/win32/cdwin.h
index a8230e7..94ed62c 100755
--- a/cd/src/win32/cdwin.h
+++ b/cd/src/win32/cdwin.h
@@ -169,6 +169,7 @@ void cdwDIBEncodePattern(cdwDIB* dib, const long int *colors);
void cdwDIBEncodeMapRect(cdwDIB* dib, const unsigned char *index, const long int *colors, int xi, int yi, int wi, int hi);
void cdwDIBEncodeRGBRect(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, int xi, int yi, int wi, int hi);
void cdwDIBEncodeRGBARect(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int xi, int yi, int wi, int hi);
+void cdwDIBEncodeRGBARectMirror(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int xi, int yi, int wi, int hi);
void cdwDIBEncodeRGBARectZoom(cdwDIB* dib, const unsigned char *red, const unsigned char *green, const unsigned char *blue, const unsigned char *alpha, int w, int h, int xi, int yi, int wi, int hi);
void cdwDIBEncodeAlphaRect(cdwDIB* dib, const unsigned char *alpha, int xi, int yi, int wi, int hi);
diff --git a/cd/src/win32/cdwnative.c b/cd/src/win32/cdwnative.c
index 69623e1..3534c6e 100755
--- a/cd/src/win32/cdwnative.c
+++ b/cd/src/win32/cdwnative.c
@@ -44,7 +44,6 @@ static int cdactivate(cdCtxCanvas *ctxcanvas)
if (ctxcanvas->hWnd)
{
RECT rect;
- HDC ScreenDC;
GetClientRect(ctxcanvas->hWnd, &rect);
ctxcanvas->canvas->w = rect.right - rect.left;
ctxcanvas->canvas->h = rect.bottom - rect.top;
@@ -52,12 +51,7 @@ static int cdactivate(cdCtxCanvas *ctxcanvas)
ctxcanvas->canvas->w_mm = ((double)ctxcanvas->canvas->w) / ctxcanvas->canvas->xres;
ctxcanvas->canvas->h_mm = ((double)ctxcanvas->canvas->h) / ctxcanvas->canvas->yres;
- ScreenDC = GetDC(NULL);
- ctxcanvas->canvas->bpp = GetDeviceCaps(ScreenDC, BITSPIXEL);
- ReleaseDC(NULL, ScreenDC);
-
- if (ctxcanvas->canvas->use_matrix)
- ctxcanvas->canvas->cxTransform(ctxcanvas, ctxcanvas->canvas->matrix);
+ ctxcanvas->canvas->bpp = cdGetScreenColorPlanes();
}
/* Se nao e' ownwer, tem que restaurar o contexto */
@@ -70,6 +64,9 @@ static int cdactivate(cdCtxCanvas *ctxcanvas)
cdwRestoreDC(ctxcanvas);
}
+ if (ctxcanvas->canvas->use_matrix)
+ ctxcanvas->canvas->cxTransform(ctxcanvas, ctxcanvas->canvas->matrix);
+
return CD_OK;
}