diff --git a/Xr.h b/Xr.h index 24df20fe1..8778451bd 100644 --- a/Xr.h +++ b/Xr.h @@ -33,9 +33,11 @@ typedef struct _XrState XrState; +typedef enum _XrFormat { XrFormatARGB32, XrFormatRGB32, XrFormatA8, XrFormatA1 } XrFormat; + /* Functions for manipulating state objects */ XrState * -XrCreate(Display *dpy, Drawable drawable, Visual *visual); +XrCreate(Display *dpy); void XrDestroy(XrState *xrs); @@ -50,10 +52,16 @@ XrRestore(XrState *xrs); /* Modify state */ void -XrSetDrawable(XrState *xrs, Drawable drawable, Visual *visual); +XrSetDrawable(XrState *xrs, Drawable drawable); void -XrSetColorRGB(XrState *xrs, double red, double green, double blue); +XrSetVisual(XrState *xrs, Visual *visual); + +void +XrSetFormat(XrState *xrs, XrFormat format); + +void +XrSetRGBColor(XrState *xrs, double red, double green, double blue); void XrSetAlpha(XrState *xrs, double alpha); @@ -100,4 +108,6 @@ XrStroke(XrState *xrs); void XrFill(XrState *xrs); +/* XXX: Error querys XrGetErrors, XrClearErrors */ + #endif diff --git a/src/Xr.h b/src/Xr.h index 24df20fe1..8778451bd 100644 --- a/src/Xr.h +++ b/src/Xr.h @@ -33,9 +33,11 @@ typedef struct _XrState XrState; +typedef enum _XrFormat { XrFormatARGB32, XrFormatRGB32, XrFormatA8, XrFormatA1 } XrFormat; + /* Functions for manipulating state objects */ XrState * -XrCreate(Display *dpy, Drawable drawable, Visual *visual); +XrCreate(Display *dpy); void XrDestroy(XrState *xrs); @@ -50,10 +52,16 @@ XrRestore(XrState *xrs); /* Modify state */ void -XrSetDrawable(XrState *xrs, Drawable drawable, Visual *visual); +XrSetDrawable(XrState *xrs, Drawable drawable); void -XrSetColorRGB(XrState *xrs, double red, double green, double blue); +XrSetVisual(XrState *xrs, Visual *visual); + +void +XrSetFormat(XrState *xrs, XrFormat format); + +void +XrSetRGBColor(XrState *xrs, double red, double green, double blue); void XrSetAlpha(XrState *xrs, double alpha); @@ -100,4 +108,6 @@ XrStroke(XrState *xrs); void XrFill(XrState *xrs); +/* XXX: Error querys XrGetErrors, XrClearErrors */ + #endif diff --git a/src/xr.c b/src/xr.c index 2211a45c4..a1e9615b6 100644 --- a/src/xr.c +++ b/src/xr.c @@ -29,14 +29,9 @@ #include "xrint.h" XrState * -XrCreate(Display *dpy, Drawable drawable, Visual *visual) +XrCreate(Display *dpy) { - XrState *xrs; - - xrs = XrStateCreate(dpy); - XrSetDrawable(xrs, drawable, visual); - - return xrs; + return XrStateCreate(dpy); } void @@ -58,13 +53,25 @@ XrRestore(XrState *xrs) } void -XrSetDrawable(XrState *xrs, Drawable drawable, Visual *visual) +XrSetDrawable(XrState *xrs, Drawable drawable) { - XrGStateSetDrawable(CURRENT_GSTATE(xrs), drawable, visual); + XrGStateSetDrawable(CURRENT_GSTATE(xrs), drawable); } void -XrSetColorRGB(XrState *xrs, double red, double green, double blue) +XrSetVisual(XrState *xrs, Visual *visual) +{ + XrGStateSetVisual(CURRENT_GSTATE(xrs), visual); +} + +void +XrSetFormat(XrState *xrs, XrFormat format) +{ + XrGStateSetFormat(CURRENT_GSTATE(xrs), format); +} + +void +XrSetRGBColor(XrState *xrs, double red, double green, double blue) { XrGStateSetColorRGB(CURRENT_GSTATE(xrs), red, green, blue); } diff --git a/src/xrcolor.c b/src/xrcolor.c index a09b10e42..a80f7ec63 100644 --- a/src/xrcolor.c +++ b/src/xrcolor.c @@ -51,6 +51,7 @@ _XrColorComputeRenderColor(XrColor *color) color->render.red = color->red * color->alpha * 0xffff; color->render.green = color->green * color->alpha * 0xffff; color->render.blue = color->blue * color->alpha * 0xffff; + color->render.alpha = color->alpha * 0xffff; } void diff --git a/src/xrgstate.c b/src/xrgstate.c index a7bd58418..ba1d29fda 100644 --- a/src/xrgstate.c +++ b/src/xrgstate.c @@ -85,7 +85,8 @@ XrGStateInit(XrGState *gstate, Display *dpy) XrColorInit(&gstate->color); XrPictureSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat); - XrTransformInit(&gstate->transform); + XrTransformInit(&gstate->ctm); + XrTransformInit(&gstate->ctm_inverse); XrPathInit(&gstate->path); XrPathInit(&gstate->outline); @@ -106,7 +107,8 @@ XrGStateDeinit(XrGState *gstate) XrColorDeinit(&gstate->color); XrPictureDeinit(&gstate->src); XrPictureDeinit(&gstate->picture); - XrTransformInit(&gstate->transform); + XrTransformDeinit(&gstate->ctm); + XrTransformDeinit(&gstate->ctm_inverse); XrPathDeinit(&gstate->path); } @@ -136,9 +138,21 @@ XrGStateGetCurrentPoint(XrGState *gstate, XPointDouble *pt) } void -XrGStateSetDrawable(XrGState *gstate, Drawable drawable, Visual *visual) +XrGStateSetDrawable(XrGState *gstate, Drawable drawable) { - XrPictureSetDrawable(&gstate->picture, drawable, visual); + XrPictureSetDrawable(&gstate->picture, drawable); +} + +void +XrGStateSetVisual(XrGState *gstate, Visual *visual) +{ + XrPictureSetVisual(&gstate->picture, visual); +} + +void +XrGStateSetFormat(XrGState *gstate, XrFormat format) +{ + XrPictureSetFormat(&gstate->picture, format); } void @@ -164,28 +178,37 @@ XrGStateSetLineWidth(XrGState *gstate, double width) void XrGStateTranslate(XrGState *gstate, double tx, double ty) { - XrTransform new; + XrTransform tmp; - XrTransformInitTranslate(&new, tx, ty); - XrTransformCompose(&gstate->transform, &new); + XrTransformInitTranslate(&tmp, tx, ty); + XrTransformMultiplyIntoRight(&tmp, &gstate->ctm); + + XrTransformInitTranslate(&tmp, -tx, -ty); + XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp); } void XrGStateScale(XrGState *gstate, double sx, double sy) { - XrTransform new; + XrTransform tmp; - XrTransformInitScale(&new, sx, sy); - XrTransformCompose(&gstate->transform, &new); + XrTransformInitScale(&tmp, sx, sy); + XrTransformMultiplyIntoRight(&tmp, &gstate->ctm); + + XrTransformInitScale(&tmp, -sx, -sy); + XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp); } void XrGStateRotate(XrGState *gstate, double angle) { - XrTransform new; + XrTransform tmp; - XrTransformInitRotate(&new, angle); - XrTransformCompose(&gstate->transform, &new); + XrTransformInitRotate(&tmp, angle); + XrTransformMultiplyIntoRight(&tmp, &gstate->ctm); + + XrTransformInitRotate(&tmp, -angle); + XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp); } void @@ -202,7 +225,7 @@ XrGStateMoveTo(XrGState *gstate, double x, double y) pt.x = x; pt.y = y; - XrTransformPoint(&gstate->transform, &pt); + XrTransformPoint(&gstate->ctm, &pt); XrPathMoveTo(&gstate->path, &pt); } @@ -214,7 +237,7 @@ XrGStateLineTo(XrGState *gstate, double x, double y) pt.x = x; pt.y = y; - XrTransformPoint(&gstate->transform, &pt); + XrTransformPoint(&gstate->ctm, &pt); XrPathLineTo(&gstate->path, &pt); } @@ -233,7 +256,7 @@ XrGStateRelMoveTo(XrGState *gstate, double x, double y) pt.x = x; pt.y = y; - XrTransformPointWithoutTranslate(&gstate->transform, &pt); + XrTransformPointWithoutTranslate(&gstate->ctm, &pt); XrGStateGetCurrentPoint(gstate, ¤t); _TranslatePoint(&pt, ¤t); XrPathMoveTo(&gstate->path, &pt); @@ -247,7 +270,7 @@ XrGStateRelLineTo(XrGState *gstate, double x, double y) pt.x = x; pt.y = y; - XrTransformPointWithoutTranslate(&gstate->transform, &pt); + XrTransformPointWithoutTranslate(&gstate->ctm, &pt); XrGStateGetCurrentPoint(gstate, ¤t); _TranslatePoint(&pt, ¤t); XrPathLineTo(&gstate->path, &pt); @@ -338,19 +361,29 @@ _XrGStateStrokeSubPath(XrGState *gstate, XrSubPath *subpath, XrPath *outline) static void _XrGStateStrokeSegment(XrGState *gstate, const XPointDouble *p0, const XPointDouble *p1, XrPath *outline) { - double dx, dy, mag; + double mag, tmp; XPointDouble offset; XPointDouble p0_off = *p0; XPointDouble p1_off = *p1; - dx = p1->x - p0->x; - dy = p1->y - p0->y; - mag = (gstate->line_width / 2) / sqrt(dx * dx + dy *dy); + offset.x = p1->x - p0->x; + offset.y = p1->y - p0->y; - offset.x = -dy * mag; - offset.y = dx * mag; + mag = sqrt(offset.x * offset.x + offset.y * offset.y); + if (mag == 0) { + return; + } - XrTransformPointWithoutTranslate(&gstate->transform, &offset); + offset.x /= mag; + offset.y /= mag; + + XrTransformPointWithoutTranslate(&gstate->ctm_inverse, &offset); + + tmp = offset.x; + offset.x = offset.y * (gstate->line_width / 2); + offset.y = - tmp * (gstate->line_width / 2); + + XrTransformPointWithoutTranslate(&gstate->ctm, &offset); _TranslatePoint(&p0_off, &offset); XrPathAddPoint(outline, &p0_off); @@ -387,3 +420,4 @@ _XrGStateFillPath(XrGState *gstate, XrPath *path) free(polys); } + diff --git a/src/xrint.h b/src/xrint.h index 6ac30b0ac..52eda4b9f 100644 --- a/src/xrint.h +++ b/src/xrint.h @@ -58,10 +58,8 @@ typedef struct _XrPicture { Drawable drawable; - Visual *visual; unsigned int depth; - XRenderPictFormat *format; unsigned long pa_mask; XRenderPictureAttributes pa; @@ -82,9 +80,8 @@ typedef struct _XrColor { /* XXX: Will also need a mechanism for a non-render color here */ } XrColor; - typedef struct _XrTransform { - double matrix[6]; + double m[3][2]; } XrTransform; #define XR_GSTATE_OP_DEFAULT PictOpOver @@ -104,7 +101,9 @@ typedef struct _XrGState { XrColor color; XrPicture src; XrPicture picture; - XrTransform transform; + + XrTransform ctm; + XrTransform ctm_inverse; XrPath path; XrPath outline; @@ -162,7 +161,13 @@ void XrGStateGetCurrentPoint(XrGState *gstate, XPointDouble *pt); void -XrGStateSetDrawable(XrGState *gstate, Drawable drawable, Visual *visual); +XrGStateSetDrawable(XrGState *gstate, Drawable drawable); + +void +XrGStateSetVisual(XrGState *gstate, Visual *visual); + +void +XrGStateSetFormat(XrGState *gstate, XrFormat format); void XrGStateSetColorRGB(XrGState *gstate, double red, double green, double blue); @@ -304,12 +309,21 @@ void XrPictureSetSolidColor(XrPicture *picture, XrColor *color, XRenderPictFormat *format); void -XrPictureSetDrawable(XrPicture *picture, Drawable drawable, Visual *visual); +XrPictureSetDrawable(XrPicture *picture, Drawable drawable); + +void +XrPictureSetVisual(XrPicture *picture, Visual *visual); + +void +XrPictureSetFormat(XrPicture *picture, XrFormat format); /* xrtransform.c */ void XrTransformInit(XrTransform *transform); +void +XrTransformDeinit(XrTransform *transform); + void XrTransformInitMatrix(XrTransform *transform, double a, double b, @@ -329,10 +343,16 @@ XrTransformInitRotate(XrTransform *transform, double angle); void -XrTransformDeinit(XrTransform *transform); +XrTransformMultiplyIntoLeft(XrTransform *t1, const XrTransform *t2); void -XrTransformCompose(XrTransform *t1, const XrTransform *t2); +XrTransformMultiplyIntoRight(const XrTransform *t1, XrTransform *t2); + +void +XrTransformMultiply(const XrTransform *t1, const XrTransform *t2, XrTransform *new); + +void +XrTransformPointScaleOnly(XrTransform *transform, XPointDouble *pt); void XrTransformPointWithoutTranslate(XrTransform *transform, XPointDouble *pt); diff --git a/src/xrtransform.c b/src/xrtransform.c index b90d02c70..4359fca40 100644 --- a/src/xrtransform.c +++ b/src/xrtransform.c @@ -32,9 +32,19 @@ #include "xrint.h" static XrTransform XR_TRANSFORM_DEFAULT = { - {1, 0, - 0, 1, - 0, 0} + { + {1, 0}, + {0, 1}, + {0, 0} + } +}; + +static XrTransform XR_TRANSFORM_ZERO = { + { + {0, 0}, + {0, 0}, + {0, 0} + } }; void @@ -43,15 +53,21 @@ XrTransformInit(XrTransform *transform) *transform = XR_TRANSFORM_DEFAULT; } +void +XrTransformDeinit(XrTransform *transform) +{ + /* nothing to do here */ +} + void XrTransformInitMatrix(XrTransform *transform, double a, double b, double c, double d, double tx, double ty) { - transform->matrix[0] = a; transform->matrix[1] = b; - transform->matrix[2] = c; transform->matrix[3] = d; - transform->matrix[4] = tx; transform->matrix[5] = ty; + transform->m[0][0] = a; transform->m[0][1] = b; + transform->m[1][0] = c; transform->m[1][1] = d; + transform->m[2][0] = tx; transform->m[2][1] = ty; } void @@ -85,24 +101,39 @@ XrTransformInitRotate(XrTransform *transform, } void -XrTransformDeinit(XrTransform *transform) +XrTransformMultiplyIntoLeft(XrTransform *t1, const XrTransform *t2) { - /* Nothing to do here */ + XrTransform new; + + XrTransformMultiply(t1, t2, &new); + + *t1 = new; } void -XrTransformCompose(XrTransform *t1, const XrTransform *t2) +XrTransformMultiplyIntoRight(const XrTransform *t1, XrTransform *t2) { - double new[6]; + XrTransform new; - new[0] = t2->matrix[0] * t1->matrix[0] + t2->matrix[1] * t1->matrix[2]; - new[1] = t2->matrix[0] * t1->matrix[1] + t2->matrix[1] * t1->matrix[3]; - new[2] = t2->matrix[2] * t1->matrix[0] + t2->matrix[3] * t1->matrix[2]; - new[3] = t2->matrix[2] * t1->matrix[1] + t2->matrix[3] * t1->matrix[3]; - new[4] = t2->matrix[4] * t1->matrix[0] + t2->matrix[5] * t1->matrix[2] + t1->matrix[4]; - new[5] = t2->matrix[4] * t1->matrix[1] + t2->matrix[5] * t1->matrix[3] + t1->matrix[5]; + XrTransformMultiply(t1, t2, &new); - memcpy(t1->matrix, new, 6 * sizeof(double)); + *t2 = new; +} + +void +XrTransformMultiply(const XrTransform *t1, const XrTransform *t2, XrTransform *new) +{ + int row, col, n; + + *new = XR_TRANSFORM_ZERO; + + for (row = 0; row < 3; row++) { + for (col = 0; col < 2; col++) { + for (n = 0; n < 2; n++) { + new->m[row][col] += t1->m[row][n] * t2->m[n][col]; + } + } + } } void @@ -110,10 +141,10 @@ XrTransformPointWithoutTranslate(XrTransform *transform, XPointDouble *pt) { double new_x, new_y; - new_x = (transform->matrix[0] * pt->x - + transform->matrix[2] * pt->y); - new_y = (transform->matrix[1] * pt->x - + transform->matrix[3] * pt->y); + new_x = (transform->m[0][0] * pt->x + + transform->m[1][0] * pt->y); + new_y = (transform->m[0][1] * pt->x + + transform->m[1][1] * pt->y); pt->x = new_x; pt->y = new_y; @@ -124,6 +155,6 @@ XrTransformPoint(XrTransform *transform, XPointDouble *pt) { XrTransformPointWithoutTranslate(transform, pt); - pt->x += transform->matrix[4]; - pt->y += transform->matrix[5]; + pt->x += transform->m[2][0]; + pt->y += transform->m[2][1]; } diff --git a/xr.c b/xr.c index 2211a45c4..a1e9615b6 100644 --- a/xr.c +++ b/xr.c @@ -29,14 +29,9 @@ #include "xrint.h" XrState * -XrCreate(Display *dpy, Drawable drawable, Visual *visual) +XrCreate(Display *dpy) { - XrState *xrs; - - xrs = XrStateCreate(dpy); - XrSetDrawable(xrs, drawable, visual); - - return xrs; + return XrStateCreate(dpy); } void @@ -58,13 +53,25 @@ XrRestore(XrState *xrs) } void -XrSetDrawable(XrState *xrs, Drawable drawable, Visual *visual) +XrSetDrawable(XrState *xrs, Drawable drawable) { - XrGStateSetDrawable(CURRENT_GSTATE(xrs), drawable, visual); + XrGStateSetDrawable(CURRENT_GSTATE(xrs), drawable); } void -XrSetColorRGB(XrState *xrs, double red, double green, double blue) +XrSetVisual(XrState *xrs, Visual *visual) +{ + XrGStateSetVisual(CURRENT_GSTATE(xrs), visual); +} + +void +XrSetFormat(XrState *xrs, XrFormat format) +{ + XrGStateSetFormat(CURRENT_GSTATE(xrs), format); +} + +void +XrSetRGBColor(XrState *xrs, double red, double green, double blue) { XrGStateSetColorRGB(CURRENT_GSTATE(xrs), red, green, blue); } diff --git a/xrcolor.c b/xrcolor.c index a09b10e42..a80f7ec63 100644 --- a/xrcolor.c +++ b/xrcolor.c @@ -51,6 +51,7 @@ _XrColorComputeRenderColor(XrColor *color) color->render.red = color->red * color->alpha * 0xffff; color->render.green = color->green * color->alpha * 0xffff; color->render.blue = color->blue * color->alpha * 0xffff; + color->render.alpha = color->alpha * 0xffff; } void diff --git a/xrgstate.c b/xrgstate.c index a7bd58418..ba1d29fda 100644 --- a/xrgstate.c +++ b/xrgstate.c @@ -85,7 +85,8 @@ XrGStateInit(XrGState *gstate, Display *dpy) XrColorInit(&gstate->color); XrPictureSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat); - XrTransformInit(&gstate->transform); + XrTransformInit(&gstate->ctm); + XrTransformInit(&gstate->ctm_inverse); XrPathInit(&gstate->path); XrPathInit(&gstate->outline); @@ -106,7 +107,8 @@ XrGStateDeinit(XrGState *gstate) XrColorDeinit(&gstate->color); XrPictureDeinit(&gstate->src); XrPictureDeinit(&gstate->picture); - XrTransformInit(&gstate->transform); + XrTransformDeinit(&gstate->ctm); + XrTransformDeinit(&gstate->ctm_inverse); XrPathDeinit(&gstate->path); } @@ -136,9 +138,21 @@ XrGStateGetCurrentPoint(XrGState *gstate, XPointDouble *pt) } void -XrGStateSetDrawable(XrGState *gstate, Drawable drawable, Visual *visual) +XrGStateSetDrawable(XrGState *gstate, Drawable drawable) { - XrPictureSetDrawable(&gstate->picture, drawable, visual); + XrPictureSetDrawable(&gstate->picture, drawable); +} + +void +XrGStateSetVisual(XrGState *gstate, Visual *visual) +{ + XrPictureSetVisual(&gstate->picture, visual); +} + +void +XrGStateSetFormat(XrGState *gstate, XrFormat format) +{ + XrPictureSetFormat(&gstate->picture, format); } void @@ -164,28 +178,37 @@ XrGStateSetLineWidth(XrGState *gstate, double width) void XrGStateTranslate(XrGState *gstate, double tx, double ty) { - XrTransform new; + XrTransform tmp; - XrTransformInitTranslate(&new, tx, ty); - XrTransformCompose(&gstate->transform, &new); + XrTransformInitTranslate(&tmp, tx, ty); + XrTransformMultiplyIntoRight(&tmp, &gstate->ctm); + + XrTransformInitTranslate(&tmp, -tx, -ty); + XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp); } void XrGStateScale(XrGState *gstate, double sx, double sy) { - XrTransform new; + XrTransform tmp; - XrTransformInitScale(&new, sx, sy); - XrTransformCompose(&gstate->transform, &new); + XrTransformInitScale(&tmp, sx, sy); + XrTransformMultiplyIntoRight(&tmp, &gstate->ctm); + + XrTransformInitScale(&tmp, -sx, -sy); + XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp); } void XrGStateRotate(XrGState *gstate, double angle) { - XrTransform new; + XrTransform tmp; - XrTransformInitRotate(&new, angle); - XrTransformCompose(&gstate->transform, &new); + XrTransformInitRotate(&tmp, angle); + XrTransformMultiplyIntoRight(&tmp, &gstate->ctm); + + XrTransformInitRotate(&tmp, -angle); + XrTransformMultiplyIntoLeft(&gstate->ctm_inverse, &tmp); } void @@ -202,7 +225,7 @@ XrGStateMoveTo(XrGState *gstate, double x, double y) pt.x = x; pt.y = y; - XrTransformPoint(&gstate->transform, &pt); + XrTransformPoint(&gstate->ctm, &pt); XrPathMoveTo(&gstate->path, &pt); } @@ -214,7 +237,7 @@ XrGStateLineTo(XrGState *gstate, double x, double y) pt.x = x; pt.y = y; - XrTransformPoint(&gstate->transform, &pt); + XrTransformPoint(&gstate->ctm, &pt); XrPathLineTo(&gstate->path, &pt); } @@ -233,7 +256,7 @@ XrGStateRelMoveTo(XrGState *gstate, double x, double y) pt.x = x; pt.y = y; - XrTransformPointWithoutTranslate(&gstate->transform, &pt); + XrTransformPointWithoutTranslate(&gstate->ctm, &pt); XrGStateGetCurrentPoint(gstate, ¤t); _TranslatePoint(&pt, ¤t); XrPathMoveTo(&gstate->path, &pt); @@ -247,7 +270,7 @@ XrGStateRelLineTo(XrGState *gstate, double x, double y) pt.x = x; pt.y = y; - XrTransformPointWithoutTranslate(&gstate->transform, &pt); + XrTransformPointWithoutTranslate(&gstate->ctm, &pt); XrGStateGetCurrentPoint(gstate, ¤t); _TranslatePoint(&pt, ¤t); XrPathLineTo(&gstate->path, &pt); @@ -338,19 +361,29 @@ _XrGStateStrokeSubPath(XrGState *gstate, XrSubPath *subpath, XrPath *outline) static void _XrGStateStrokeSegment(XrGState *gstate, const XPointDouble *p0, const XPointDouble *p1, XrPath *outline) { - double dx, dy, mag; + double mag, tmp; XPointDouble offset; XPointDouble p0_off = *p0; XPointDouble p1_off = *p1; - dx = p1->x - p0->x; - dy = p1->y - p0->y; - mag = (gstate->line_width / 2) / sqrt(dx * dx + dy *dy); + offset.x = p1->x - p0->x; + offset.y = p1->y - p0->y; - offset.x = -dy * mag; - offset.y = dx * mag; + mag = sqrt(offset.x * offset.x + offset.y * offset.y); + if (mag == 0) { + return; + } - XrTransformPointWithoutTranslate(&gstate->transform, &offset); + offset.x /= mag; + offset.y /= mag; + + XrTransformPointWithoutTranslate(&gstate->ctm_inverse, &offset); + + tmp = offset.x; + offset.x = offset.y * (gstate->line_width / 2); + offset.y = - tmp * (gstate->line_width / 2); + + XrTransformPointWithoutTranslate(&gstate->ctm, &offset); _TranslatePoint(&p0_off, &offset); XrPathAddPoint(outline, &p0_off); @@ -387,3 +420,4 @@ _XrGStateFillPath(XrGState *gstate, XrPath *path) free(polys); } + diff --git a/xrint.h b/xrint.h index 6ac30b0ac..52eda4b9f 100644 --- a/xrint.h +++ b/xrint.h @@ -58,10 +58,8 @@ typedef struct _XrPicture { Drawable drawable; - Visual *visual; unsigned int depth; - XRenderPictFormat *format; unsigned long pa_mask; XRenderPictureAttributes pa; @@ -82,9 +80,8 @@ typedef struct _XrColor { /* XXX: Will also need a mechanism for a non-render color here */ } XrColor; - typedef struct _XrTransform { - double matrix[6]; + double m[3][2]; } XrTransform; #define XR_GSTATE_OP_DEFAULT PictOpOver @@ -104,7 +101,9 @@ typedef struct _XrGState { XrColor color; XrPicture src; XrPicture picture; - XrTransform transform; + + XrTransform ctm; + XrTransform ctm_inverse; XrPath path; XrPath outline; @@ -162,7 +161,13 @@ void XrGStateGetCurrentPoint(XrGState *gstate, XPointDouble *pt); void -XrGStateSetDrawable(XrGState *gstate, Drawable drawable, Visual *visual); +XrGStateSetDrawable(XrGState *gstate, Drawable drawable); + +void +XrGStateSetVisual(XrGState *gstate, Visual *visual); + +void +XrGStateSetFormat(XrGState *gstate, XrFormat format); void XrGStateSetColorRGB(XrGState *gstate, double red, double green, double blue); @@ -304,12 +309,21 @@ void XrPictureSetSolidColor(XrPicture *picture, XrColor *color, XRenderPictFormat *format); void -XrPictureSetDrawable(XrPicture *picture, Drawable drawable, Visual *visual); +XrPictureSetDrawable(XrPicture *picture, Drawable drawable); + +void +XrPictureSetVisual(XrPicture *picture, Visual *visual); + +void +XrPictureSetFormat(XrPicture *picture, XrFormat format); /* xrtransform.c */ void XrTransformInit(XrTransform *transform); +void +XrTransformDeinit(XrTransform *transform); + void XrTransformInitMatrix(XrTransform *transform, double a, double b, @@ -329,10 +343,16 @@ XrTransformInitRotate(XrTransform *transform, double angle); void -XrTransformDeinit(XrTransform *transform); +XrTransformMultiplyIntoLeft(XrTransform *t1, const XrTransform *t2); void -XrTransformCompose(XrTransform *t1, const XrTransform *t2); +XrTransformMultiplyIntoRight(const XrTransform *t1, XrTransform *t2); + +void +XrTransformMultiply(const XrTransform *t1, const XrTransform *t2, XrTransform *new); + +void +XrTransformPointScaleOnly(XrTransform *transform, XPointDouble *pt); void XrTransformPointWithoutTranslate(XrTransform *transform, XPointDouble *pt); diff --git a/xrpicture.c b/xrpicture.c index 79f62e290..a2492e9ea 100644 --- a/xrpicture.c +++ b/xrpicture.c @@ -36,9 +36,7 @@ XrPictureInit(XrPicture *picture, Display *dpy) picture->drawable = 0; picture->depth = 0; - picture->visual = 0; - picture->format = 0; picture->pa_mask = 0; picture->picture = 0; @@ -74,29 +72,63 @@ XrPictureSetSolidColor(XrPicture *picture, XrColor *color, XRenderPictFormat *fo 0, 0, 1, 1); } -static void -_XrPictureFindFormat(XrPicture *picture) -{ - if (picture->format) { - return; - } - - picture->format = XRenderFindVisualFormat(picture->dpy, picture->visual); -} - void -XrPictureSetDrawable(XrPicture *picture, Drawable drawable, Visual *visual) +XrPictureSetDrawable(XrPicture *picture, Drawable drawable) { if (picture->picture) { XRenderFreePicture(picture->dpy, picture->picture); + picture->picture = 0; } - picture->visual = visual; picture->drawable = drawable; - - _XrPictureFindFormat(picture); - - picture->picture = XRenderCreatePicture(picture->dpy, drawable, - picture->format, picture->pa_mask, &picture->pa); } +void +XrPictureSetVisual(XrPicture *picture, Visual *visual) +{ + XRenderPictFormat *pict_format; + + if (picture->picture) { + XRenderFreePicture(picture->dpy, picture->picture); + picture->picture = 0; + } + + pict_format = XRenderFindVisualFormat(picture->dpy, visual); + + picture->picture = XRenderCreatePicture(picture->dpy, picture->drawable, + pict_format, picture->pa_mask, &picture->pa); +} + +void +XrPictureSetFormat(XrPicture *picture, XrFormat format) +{ + XRenderPictFormat *pict_format; + int std_format; + + if (picture->picture) { + XRenderFreePicture(picture->dpy, picture->picture); + picture->picture = 0; + } + + switch (format) { + case XrFormatARGB32: + std_format = PictStandardARGB32; + break; + case XrFormatRGB32: + std_format = PictStandardRGB24; + break; + case XrFormatA8: + std_format = PictStandardA8; + break; + case XrFormatA1: + std_format = PictStandardA1; + break; + default: + return; + } + + pict_format = XRenderFindStandardFormat(picture->dpy, std_format); + + picture->picture = XRenderCreatePicture(picture->dpy, picture->drawable, + pict_format, picture->pa_mask, &picture->pa); +} diff --git a/xrsubpath.c b/xrsubpath.c index 79384cfcf..ae53428a6 100644 --- a/xrsubpath.c +++ b/xrsubpath.c @@ -61,8 +61,10 @@ XrSubPathInitCopy(XrSubPath *path, XrSubPath *other) { *path = *other; - path->pts = malloc(path->pts_size * sizeof(XPointDouble)); - *path->pts = *other->pts; + if (other->pts_size) { + path->pts = malloc(path->pts_size * sizeof(XPointDouble)); + memcpy(path->pts, other->pts, path->num_pts * sizeof(XPointDouble)); + } } void diff --git a/xrtransform.c b/xrtransform.c index b90d02c70..4359fca40 100644 --- a/xrtransform.c +++ b/xrtransform.c @@ -32,9 +32,19 @@ #include "xrint.h" static XrTransform XR_TRANSFORM_DEFAULT = { - {1, 0, - 0, 1, - 0, 0} + { + {1, 0}, + {0, 1}, + {0, 0} + } +}; + +static XrTransform XR_TRANSFORM_ZERO = { + { + {0, 0}, + {0, 0}, + {0, 0} + } }; void @@ -43,15 +53,21 @@ XrTransformInit(XrTransform *transform) *transform = XR_TRANSFORM_DEFAULT; } +void +XrTransformDeinit(XrTransform *transform) +{ + /* nothing to do here */ +} + void XrTransformInitMatrix(XrTransform *transform, double a, double b, double c, double d, double tx, double ty) { - transform->matrix[0] = a; transform->matrix[1] = b; - transform->matrix[2] = c; transform->matrix[3] = d; - transform->matrix[4] = tx; transform->matrix[5] = ty; + transform->m[0][0] = a; transform->m[0][1] = b; + transform->m[1][0] = c; transform->m[1][1] = d; + transform->m[2][0] = tx; transform->m[2][1] = ty; } void @@ -85,24 +101,39 @@ XrTransformInitRotate(XrTransform *transform, } void -XrTransformDeinit(XrTransform *transform) +XrTransformMultiplyIntoLeft(XrTransform *t1, const XrTransform *t2) { - /* Nothing to do here */ + XrTransform new; + + XrTransformMultiply(t1, t2, &new); + + *t1 = new; } void -XrTransformCompose(XrTransform *t1, const XrTransform *t2) +XrTransformMultiplyIntoRight(const XrTransform *t1, XrTransform *t2) { - double new[6]; + XrTransform new; - new[0] = t2->matrix[0] * t1->matrix[0] + t2->matrix[1] * t1->matrix[2]; - new[1] = t2->matrix[0] * t1->matrix[1] + t2->matrix[1] * t1->matrix[3]; - new[2] = t2->matrix[2] * t1->matrix[0] + t2->matrix[3] * t1->matrix[2]; - new[3] = t2->matrix[2] * t1->matrix[1] + t2->matrix[3] * t1->matrix[3]; - new[4] = t2->matrix[4] * t1->matrix[0] + t2->matrix[5] * t1->matrix[2] + t1->matrix[4]; - new[5] = t2->matrix[4] * t1->matrix[1] + t2->matrix[5] * t1->matrix[3] + t1->matrix[5]; + XrTransformMultiply(t1, t2, &new); - memcpy(t1->matrix, new, 6 * sizeof(double)); + *t2 = new; +} + +void +XrTransformMultiply(const XrTransform *t1, const XrTransform *t2, XrTransform *new) +{ + int row, col, n; + + *new = XR_TRANSFORM_ZERO; + + for (row = 0; row < 3; row++) { + for (col = 0; col < 2; col++) { + for (n = 0; n < 2; n++) { + new->m[row][col] += t1->m[row][n] * t2->m[n][col]; + } + } + } } void @@ -110,10 +141,10 @@ XrTransformPointWithoutTranslate(XrTransform *transform, XPointDouble *pt) { double new_x, new_y; - new_x = (transform->matrix[0] * pt->x - + transform->matrix[2] * pt->y); - new_y = (transform->matrix[1] * pt->x - + transform->matrix[3] * pt->y); + new_x = (transform->m[0][0] * pt->x + + transform->m[1][0] * pt->y); + new_y = (transform->m[0][1] * pt->x + + transform->m[1][1] * pt->y); pt->x = new_x; pt->y = new_y; @@ -124,6 +155,6 @@ XrTransformPoint(XrTransform *transform, XPointDouble *pt) { XrTransformPointWithoutTranslate(transform, pt); - pt->x += transform->matrix[4]; - pt->y += transform->matrix[5]; + pt->x += transform->m[2][0]; + pt->y += transform->m[2][1]; }