Added group support.

This commit is contained in:
Carl Worth 2002-11-04 00:24:44 +00:00
parent ea0104b2c0
commit 405598e4e0
15 changed files with 639 additions and 94 deletions

View file

@ -1,3 +1,34 @@
2002-11-04 Carl Worth <cworth@isi.edu>
* xrsurface.c (_XrSurfaceDereference):
(_XrSurfaceDereferenceDestroy): Fixed bug in reference counting
logic.
(_XrSurfaceSetDrawableWH): XrSurface now keeps track of its width/height.
(_XrSurfaceGetDrawable):
(_XrSurfaceGetWidth):
(_XrSurfaceGetHeight):
(_XrSurfaceGetDepth): New accessor functions.
* xrgstate.c (_XrGStateBeginGroup):
(_XrGStateEndGroup): Preliminary group support. Not too efficient
since it always composite's a full-size picture from child group
to parent picture, (even if only a small portion has
non-transparent pixels).
(_XrGStateShowImageTransform): Fixed show image to use current
alpha value.
* xrfont.c (_XrFontResolveXftFont): Fixed memory leak
(FcPatternDestroy). There's still some meory
leaking/left-reachable in Xft/fontconfig that I need to track
down.
* xr.c (XrPushGroup):
(XrPopGroup): Added preliminary group support. I think I like
having this in the API as it takes several burdens away from the
user, (plus it matches the PDF model). Things to do still: think
about the names of these functions. Re-read the PDF semantics to
see if we're missing anything.
2002-11-02 Carl Worth <cworth@isi.edu>
* xrsurface.c (_XrSurfaceSetImage): Fixed leak of the image

7
Xr.h
View file

@ -43,6 +43,12 @@ XrSave(XrState *xrs);
void
XrRestore(XrState *xrs);
void
XrPushGroup(XrState *xrs);
void
XrPopGroup(XrState *xrs);
/* Modify state */
void
XrSetDrawable(XrState *xrs, Drawable drawable);
@ -241,6 +247,7 @@ typedef enum _XrStatus {
XrStatusSuccess = 0,
XrStatusNoMemory,
XrStatusInvalidRestore,
XrStatusInvalidPopGroup,
XrStatusNoCurrentPoint
} XrStatus;

View file

@ -43,6 +43,12 @@ XrSave(XrState *xrs);
void
XrRestore(XrState *xrs);
void
XrPushGroup(XrState *xrs);
void
XrPopGroup(XrState *xrs);
/* Modify state */
void
XrSetDrawable(XrState *xrs, Drawable drawable);
@ -241,6 +247,7 @@ typedef enum _XrStatus {
XrStatusSuccess = 0,
XrStatusNoMemory,
XrStatusInvalidRestore,
XrStatusInvalidPopGroup,
XrStatusNoCurrentPoint
} XrStatus;

View file

@ -62,6 +62,32 @@ XrRestore(XrState *xrs)
xrs->status = _XrStatePop(xrs);
}
void
XrPushGroup(XrState *xrs)
{
if (xrs->status)
return;
xrs->status = _XrStatePush(xrs);
if (xrs->status)
return;
xrs->status = _XrGStateBeginGroup(_XR_CURRENT_GSTATE(xrs));
}
void
XrPopGroup(XrState *xrs)
{
if (xrs->status)
return;
xrs->status = _XrGStateEndGroup(_XR_CURRENT_GSTATE(xrs));
if (xrs->status)
return;
xrs->status = _XrStatePop(xrs);
}
void
XrSetDrawable(XrState *xrs, Drawable drawable)
{
@ -435,7 +461,9 @@ XrGetStatusString(XrState *xrs)
case XrStatusNoMemory:
return "out of memory";
case XrStatusInvalidRestore:
return "XrRestore without matchin XrSave";
return "XrRestore without matching XrSave";
case XrStatusInvalidPopGroup:
return "XrPopGroup without matching XrPushGroup";
case XrStatusNoCurrentPoint:
return "no current point defined";
}

View file

@ -28,7 +28,7 @@
#include "xrint.h"
void
_XrFontInit(XrFont *font, XrGState *gstate)
_XrFontInit(XrFont *font)
{
font->key = (unsigned char *) strdup(XR_FONT_KEY_DEFAULT);
@ -164,5 +164,7 @@ _XrFontResolveXftFont(XrFont *font, XrGState *gstate, XftFont **xft_font)
*xft_font = font->xft_font;
FcPatternDestroy (pattern);
return XrStatusSuccess;
}

View file

@ -41,9 +41,8 @@ _XrGStateCreate(Display *dpy)
gstate = malloc(sizeof(XrGState));
if (gstate) {
if (gstate)
_XrGStateInit(gstate, dpy);
}
return gstate;
}
@ -70,14 +69,16 @@ _XrGStateInit(XrGState *gstate, Display *dpy)
gstate->alphaFormat = XcFindStandardFormat(dpy, PictStandardA8);
_XrFontInit(&gstate->font, gstate);
_XrFontInit(&gstate->font);
_XrSurfaceInit(&gstate->surface, dpy);
_XrSurfaceInit(&gstate->src, dpy);
gstate->parent_surface = NULL;
gstate->surface = _XrSurfaceCreate(dpy);
gstate->src = _XrSurfaceCreate(dpy);
gstate->mask = NULL;
gstate->alpha = 1.0;
_XrColorInit(&gstate->color);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color);
_XrSurfaceSetSolidColor(gstate->src, &gstate->color);
_XrTransformInit(&gstate->ctm);
_XrTransformInit(&gstate->ctm_inverse);
@ -107,9 +108,10 @@ _XrGStateInitCopy(XrGState *gstate, XrGState *other)
status = _XrFontInitCopy(&gstate->font, &other->font);
if (status)
goto CLEANUP_DASHES;
_XrSurfaceReference(&gstate->surface);
_XrSurfaceReference(&gstate->src);
gstate->parent_surface = NULL;
_XrSurfaceReference(gstate->surface);
_XrSurfaceReference(gstate->src);
if (gstate->mask)
_XrSurfaceReference(gstate->mask);
@ -137,10 +139,13 @@ _XrGStateInitCopy(XrGState *gstate, XrGState *other)
void
_XrGStateDeinit(XrGState *gstate)
{
if (gstate->parent_surface)
_XrGStateEndGroup(gstate);
_XrFontDeinit(&gstate->font);
_XrSurfaceDereference(&gstate->src);
_XrSurfaceDereference(&gstate->surface);
_XrSurfaceDereferenceDestroy(gstate->surface);
_XrSurfaceDereferenceDestroy(gstate->src);
if (gstate->mask)
_XrSurfaceDereferenceDestroy(gstate->mask);
@ -184,10 +189,92 @@ _XrGStateClone(XrGState *gstate)
return clone;
}
/* Push rendering off to an off-screen group. */
XrStatus
_XrGStateBeginGroup(XrGState *gstate)
{
Pixmap pix;
XrColor clear;
unsigned int width, height;
gstate->parent_surface = gstate->surface;
width = _XrSurfaceGetWidth(gstate->surface);
height = _XrSurfaceGetHeight(gstate->surface);
pix = XCreatePixmap(gstate->dpy,
_XrSurfaceGetDrawable(gstate->surface),
width, height,
_XrSurfaceGetDepth(gstate->surface));
if (pix == 0)
return XrStatusNoMemory;
gstate->surface = _XrSurfaceCreate(gstate->dpy);
if (gstate->surface == NULL)
return XrStatusNoMemory;
_XrSurfaceSetDrawableWH(gstate->surface, pix, width, height);
_XrColorInit(&clear);
_XrColorSetAlpha(&clear, 0);
XcFillRectangle(gstate->dpy,
XrOperatorSrc,
_XrSurfaceGetXcSurface(gstate->surface),
&clear.xc_color,
0, 0,
_XrSurfaceGetWidth(gstate->surface),
_XrSurfaceGetHeight(gstate->surface));
return XrStatusSuccess;
}
/* Complete the current offscreen group, composing its contents onto the parent surface. */
XrStatus
_XrGStateEndGroup(XrGState *gstate)
{
Pixmap pix;
XrColor mask_color;
XrSurface mask;
if (gstate->parent_surface == NULL)
return XrStatusInvalidPopGroup;
_XrSurfaceInit(&mask, gstate->dpy);
_XrColorInit(&mask_color);
_XrColorSetAlpha(&mask_color, gstate->alpha);
_XrSurfaceSetSolidColor(&mask, &mask_color);
/* XXX: This could be made much more efficient by using
_XrSurfaceGetDamagedWidth/Height if XrSurface actually kept
track of such informaton. */
XcComposite(gstate->dpy, gstate->operator,
_XrSurfaceGetXcSurface(gstate->surface),
_XrSurfaceGetXcSurface(&mask),
_XrSurfaceGetXcSurface(gstate->parent_surface),
0, 0,
0, 0,
0, 0,
_XrSurfaceGetWidth(gstate->surface),
_XrSurfaceGetHeight(gstate->surface));
_XrSurfaceDeinit(&mask);
pix = _XrSurfaceGetDrawable(gstate->surface);
XFreePixmap(gstate->dpy, pix);
_XrSurfaceDestroy(gstate->surface);
gstate->surface = gstate->parent_surface;
gstate->parent_surface = NULL;
return XrStatusSuccess;
}
XrStatus
_XrGStateSetDrawable(XrGState *gstate, Drawable drawable)
{
_XrSurfaceSetDrawable(&gstate->surface, drawable);
_XrSurfaceSetDrawable(gstate->surface, drawable);
return XrStatusSuccess;
}
@ -195,7 +282,7 @@ _XrGStateSetDrawable(XrGState *gstate, Drawable drawable)
XrStatus
_XrGStateSetVisual(XrGState *gstate, Visual *visual)
{
_XrSurfaceSetVisual(&gstate->surface, visual);
_XrSurfaceSetVisual(gstate->surface, visual);
return XrStatusSuccess;
}
@ -203,7 +290,7 @@ _XrGStateSetVisual(XrGState *gstate, Visual *visual)
XrStatus
_XrGStateSetFormat(XrGState *gstate, XrFormat format)
{
_XrSurfaceSetFormat(&gstate->surface, format);
_XrSurfaceSetFormat(gstate->surface, format);
return XrStatusSuccess;
}
@ -220,7 +307,7 @@ XrStatus
_XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue)
{
_XrColorSetRGB(&gstate->color, red, green, blue);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color);
_XrSurfaceSetSolidColor(gstate->src, &gstate->color);
return XrStatusSuccess;
}
@ -236,8 +323,9 @@ _XrGStateSetTolerance(XrGState *gstate, double tolerance)
XrStatus
_XrGStateSetAlpha(XrGState *gstate, double alpha)
{
gstate->alpha = alpha;
_XrColorSetAlpha(&gstate->color, alpha);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color);
_XrSurfaceSetSolidColor(gstate->src, &gstate->color);
return XrStatusSuccess;
}
@ -542,8 +630,8 @@ _XrGStateStroke(XrGState *gstate)
}
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
_XrSurfaceGetXcSurface(&gstate->src),
_XrSurfaceGetXcSurface(&gstate->surface),
_XrSurfaceGetXcSurface(gstate->src),
_XrSurfaceGetXcSurface(gstate->surface),
gstate->alphaFormat,
0, 0,
traps.xtraps,
@ -582,8 +670,8 @@ _XrGStateFill(XrGState *gstate)
}
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
_XrSurfaceGetXcSurface(&gstate->src),
_XrSurfaceGetXcSurface(&gstate->surface),
_XrSurfaceGetXcSurface(gstate->src),
_XrSurfaceGetXcSurface(gstate->surface),
gstate->alphaFormat,
0, 0,
traps.xtraps,
@ -701,14 +789,21 @@ _XrGStateShowImageTransform(XrGState *gstate,
double tx, double ty)
{
XrStatus status;
XrSurface image_surface;
XrColor mask_color;
XrSurface image_surface, mask;
double dst_width, dst_height;
_XrSurfaceInit(&mask, gstate->dpy);
_XrColorInit(&mask_color);
_XrColorSetAlpha(&mask_color, gstate->alpha);
_XrSurfaceSetSolidColor(&mask, &mask_color);
_XrSurfaceInit(&image_surface, gstate->dpy);
_XrSurfaceSetFormat(&image_surface, format);
status = _XrSurfaceSetImage(&image_surface, data, width, height, stride);
status = _XrSurfaceSetImage(&image_surface, data,width, height, stride);
if (status)
return status;
@ -720,8 +815,8 @@ _XrGStateShowImageTransform(XrGState *gstate,
XcComposite(gstate->dpy, gstate->operator,
_XrSurfaceGetXcSurface(&image_surface),
0,
_XrSurfaceGetXcSurface(&gstate->surface),
_XrSurfaceGetXcSurface(&mask),
_XrSurfaceGetXcSurface(gstate->surface),
0, 0,
0, 0,
gstate->current_pt.x,
@ -730,6 +825,7 @@ _XrGStateShowImageTransform(XrGState *gstate,
dst_height);
_XrSurfaceDeinit(&image_surface);
_XrSurfaceDeinit(&mask);
return XrStatusSuccess;
}
@ -737,11 +833,11 @@ _XrGStateShowImageTransform(XrGState *gstate,
static Picture
_XrGStateGetPicture(XrGState *gstate)
{
return _XrSurfaceGetPicture(&gstate->surface);
return _XrSurfaceGetPicture(gstate->surface);
}
static Picture
_XrGStateGetSrcPicture(XrGState *gstate)
{
return _XrSurfaceGetPicture(&gstate->src);
return _XrSurfaceGetPicture(gstate->src);
}

View file

@ -171,10 +171,14 @@ typedef struct _XrSurface {
Drawable drawable;
GC gc;
unsigned int width;
unsigned int height;
unsigned int depth;
unsigned long xc_sa_mask;
XcSurfaceAttributes xc_sa;
XrFormat format;
XcFormat *xc_format;
XcSurface *xc_surface;
@ -248,10 +252,12 @@ typedef struct _XrGState {
XrFont font;
XrSurface src;
XrSurface surface;
XrSurface *parent_surface;
XrSurface *surface;
XrSurface *src;
XrSurface *mask;
double alpha;
XrColor color;
XrTransform ctm;
@ -341,6 +347,12 @@ _XrGStateDestroy(XrGState *gstate);
XrGState *
_XrGStateClone(XrGState *gstate);
XrStatus
_XrGStateBeginGroup(XrGState *gstate);
XrStatus
_XrGStateEndGroup(XrGState *gstate);
XrStatus
_XrGStateSetDrawable(XrGState *gstate, Drawable drawable);
@ -487,7 +499,7 @@ _XrColorSetAlpha(XrColor *color, double alpha);
/* xrfont.c */
void
_XrFontInit(XrFont *font, XrGState *gstate);
_XrFontInit(XrFont *font);
XrStatus
_XrFontInitCopy(XrFont *font, XrFont *other);
@ -538,9 +550,18 @@ XrStatus
_XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure);
/* xrsurface.c */
XrSurface *
_XrSurfaceCreate(Display *dpy);
void
_XrSurfaceInit(XrSurface *surface, Display *dpy);
void
_XrSurfaceDeinit(XrSurface *surface);
void
_XrSurfaceDestroy(XrSurface *surface);
void
_XrSurfaceReference(XrSurface *surface);
@ -550,9 +571,6 @@ _XrSurfaceDereference(XrSurface *surface);
void
_XrSurfaceDereferenceDestroy(XrSurface *surface);
void
_XrSurfaceDeinit(XrSurface *surface);
void
_XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color);
@ -569,6 +587,12 @@ _XrSurfaceSetTransform(XrSurface *surface, XrTransform *transform);
void
_XrSurfaceSetDrawable(XrSurface *surface, Drawable drawable);
void
_XrSurfaceSetDrawableWH(XrSurface *surface,
Drawable drawable,
unsigned int width,
unsigned int height);
void
_XrSurfaceSetVisual(XrSurface *surface, Visual *visual);
@ -581,6 +605,18 @@ _XrSurfaceGetXcSurface(XrSurface *surface);
Picture
_XrSurfaceGetPicture(XrSurface *surface);
Drawable
_XrSurfaceGetDrawable(XrSurface *surface);
unsigned int
_XrSurfaceGetWidth(XrSurface *surface);
unsigned int
_XrSurfaceGetHeight(XrSurface *surface);
unsigned int
_XrSurfaceGetDepth(XrSurface *surface);
/* xrpen.c */
XrStatus
_XrPenInit(XrPen *pen, double radius, XrGState *gstate);

View file

@ -50,6 +50,7 @@ _XrStateInit(XrState *xrs, Display *dpy)
{
xrs->dpy = dpy;
xrs->stack = NULL;
xrs->status = XrStatusSuccess;
return _XrStatePush(xrs);

View file

@ -23,8 +23,23 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include "xrint.h"
XrSurface *
_XrSurfaceCreate(Display *dpy)
{
XrSurface *surface;
surface = malloc(sizeof(XrSurface));
if (surface)
_XrSurfaceInit(surface, dpy);
return surface;
}
void
_XrSurfaceInit(XrSurface *surface, Display *dpy)
{
@ -33,11 +48,13 @@ _XrSurfaceInit(XrSurface *surface, Display *dpy)
surface->drawable = 0;
surface->gc = 0;
surface->width = 0;
surface->height = 0;
surface->depth = 0;
surface->xc_sa_mask = 0;
surface->xc_format = XcFindStandardFormat(dpy, PictStandardARGB32);
_XrSurfaceSetFormat(surface, XrFormatARGB32);
surface->xc_surface = 0;
surface->needs_new_xc_surface = 1;
@ -45,6 +62,22 @@ _XrSurfaceInit(XrSurface *surface, Display *dpy)
surface->ref_count = 0;
}
void
_XrSurfaceDeinit(XrSurface *surface)
{
if (surface->xc_surface)
XcFreeSurface(surface->dpy, surface->xc_surface);
if (surface->gc)
XFreeGC(surface->dpy, surface->gc);
}
void
_XrSurfaceDestroy(XrSurface *surface)
{
_XrSurfaceDeinit(surface);
free(surface);
}
void
_XrSurfaceReference(XrSurface *surface)
{
@ -63,17 +96,10 @@ _XrSurfaceDereference(XrSurface *surface)
void
_XrSurfaceDereferenceDestroy(XrSurface *surface)
{
_XrSurfaceDereference(surface);
if (surface->ref_count == 0)
free(surface);
}
void
_XrSurfaceDeinit(XrSurface *surface)
{
if (surface->xc_surface)
XcFreeSurface(surface->dpy, surface->xc_surface);
_XrSurfaceDestroy(surface);
else
_XrSurfaceDereference(surface);
}
void
@ -85,7 +111,7 @@ _XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color)
DefaultRootWindow(surface->dpy),
1, 1,
surface->xc_format->depth);
_XrSurfaceSetDrawable(surface, pix);
_XrSurfaceSetDrawableWH(surface, pix, 1, 1);
surface->xc_sa_mask |= CPRepeat;
surface->xc_sa.repeat = True;
_XrSurfaceGetXcSurface(surface);
@ -121,7 +147,7 @@ _XrSurfaceSetImage(XrSurface *surface,
DefaultRootWindow(surface->dpy),
width, height,
depth);
_XrSurfaceSetDrawable(surface, pix);
_XrSurfaceSetDrawableWH(surface, pix, width, height);
image = XCreateImage(surface->dpy,
DefaultVisual(surface->dpy, DefaultScreen(surface->dpy)),
@ -178,11 +204,32 @@ _XrSurfaceSetTransform(XrSurface *surface, XrTransform *transform)
void
_XrSurfaceSetDrawable(XrSurface *surface, Drawable drawable)
{
Window root;
int x, y;
unsigned int border, depth;
unsigned int width, height;
XGetGeometry (surface->dpy, drawable,
&root, &x, &y,
&width, &height,
&border, &depth);
_XrSurfaceSetDrawableWH(surface, drawable, width, height);
}
void
_XrSurfaceSetDrawableWH(XrSurface *surface,
Drawable drawable,
unsigned int width,
unsigned int height)
{
if (surface->gc)
XFreeGC(surface->dpy, surface->gc);
surface->drawable = drawable;
surface->width = width;
surface->height = height;
surface->gc = XCreateGC(surface->dpy, surface->drawable, 0, 0);
surface->needs_new_xc_surface = 1;
@ -198,7 +245,23 @@ _XrSurfaceSetVisual(XrSurface *surface, Visual *visual)
void
_XrSurfaceSetFormat(XrSurface *surface, XrFormat format)
{
surface->format = format;
surface->xc_format = XcFindStandardFormat(surface->dpy, format);
switch (surface->format) {
case XrFormatARGB32:
surface->depth = 32;
case XrFormatRGB32:
/* XXX: Is this correct? */
surface->depth = 24;
case XrFormatA8:
surface->depth = 8;
case XrFormatA1:
surface->depth = 1;
default:
surface->depth = 32;
}
surface->needs_new_xc_surface = 1;
}
@ -234,3 +297,27 @@ _XrSurfaceGetPicture(XrSurface *surface)
{
return XcSurfaceGetPicture(_XrSurfaceGetXcSurface(surface));
}
Drawable
_XrSurfaceGetDrawable(XrSurface *surface)
{
return surface->drawable;
}
unsigned int
_XrSurfaceGetWidth(XrSurface *surface)
{
return surface->width;
}
unsigned int
_XrSurfaceGetHeight(XrSurface *surface)
{
return surface->height;
}
unsigned int
_XrSurfaceGetDepth(XrSurface *surface)
{
return surface->depth;
}

30
xr.c
View file

@ -62,6 +62,32 @@ XrRestore(XrState *xrs)
xrs->status = _XrStatePop(xrs);
}
void
XrPushGroup(XrState *xrs)
{
if (xrs->status)
return;
xrs->status = _XrStatePush(xrs);
if (xrs->status)
return;
xrs->status = _XrGStateBeginGroup(_XR_CURRENT_GSTATE(xrs));
}
void
XrPopGroup(XrState *xrs)
{
if (xrs->status)
return;
xrs->status = _XrGStateEndGroup(_XR_CURRENT_GSTATE(xrs));
if (xrs->status)
return;
xrs->status = _XrStatePop(xrs);
}
void
XrSetDrawable(XrState *xrs, Drawable drawable)
{
@ -435,7 +461,9 @@ XrGetStatusString(XrState *xrs)
case XrStatusNoMemory:
return "out of memory";
case XrStatusInvalidRestore:
return "XrRestore without matchin XrSave";
return "XrRestore without matching XrSave";
case XrStatusInvalidPopGroup:
return "XrPopGroup without matching XrPushGroup";
case XrStatusNoCurrentPoint:
return "no current point defined";
}

View file

@ -28,7 +28,7 @@
#include "xrint.h"
void
_XrFontInit(XrFont *font, XrGState *gstate)
_XrFontInit(XrFont *font)
{
font->key = (unsigned char *) strdup(XR_FONT_KEY_DEFAULT);
@ -164,5 +164,7 @@ _XrFontResolveXftFont(XrFont *font, XrGState *gstate, XftFont **xft_font)
*xft_font = font->xft_font;
FcPatternDestroy (pattern);
return XrStatusSuccess;
}

View file

@ -41,9 +41,8 @@ _XrGStateCreate(Display *dpy)
gstate = malloc(sizeof(XrGState));
if (gstate) {
if (gstate)
_XrGStateInit(gstate, dpy);
}
return gstate;
}
@ -70,14 +69,16 @@ _XrGStateInit(XrGState *gstate, Display *dpy)
gstate->alphaFormat = XcFindStandardFormat(dpy, PictStandardA8);
_XrFontInit(&gstate->font, gstate);
_XrFontInit(&gstate->font);
_XrSurfaceInit(&gstate->surface, dpy);
_XrSurfaceInit(&gstate->src, dpy);
gstate->parent_surface = NULL;
gstate->surface = _XrSurfaceCreate(dpy);
gstate->src = _XrSurfaceCreate(dpy);
gstate->mask = NULL;
gstate->alpha = 1.0;
_XrColorInit(&gstate->color);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color);
_XrSurfaceSetSolidColor(gstate->src, &gstate->color);
_XrTransformInit(&gstate->ctm);
_XrTransformInit(&gstate->ctm_inverse);
@ -107,9 +108,10 @@ _XrGStateInitCopy(XrGState *gstate, XrGState *other)
status = _XrFontInitCopy(&gstate->font, &other->font);
if (status)
goto CLEANUP_DASHES;
_XrSurfaceReference(&gstate->surface);
_XrSurfaceReference(&gstate->src);
gstate->parent_surface = NULL;
_XrSurfaceReference(gstate->surface);
_XrSurfaceReference(gstate->src);
if (gstate->mask)
_XrSurfaceReference(gstate->mask);
@ -137,10 +139,13 @@ _XrGStateInitCopy(XrGState *gstate, XrGState *other)
void
_XrGStateDeinit(XrGState *gstate)
{
if (gstate->parent_surface)
_XrGStateEndGroup(gstate);
_XrFontDeinit(&gstate->font);
_XrSurfaceDereference(&gstate->src);
_XrSurfaceDereference(&gstate->surface);
_XrSurfaceDereferenceDestroy(gstate->surface);
_XrSurfaceDereferenceDestroy(gstate->src);
if (gstate->mask)
_XrSurfaceDereferenceDestroy(gstate->mask);
@ -184,10 +189,92 @@ _XrGStateClone(XrGState *gstate)
return clone;
}
/* Push rendering off to an off-screen group. */
XrStatus
_XrGStateBeginGroup(XrGState *gstate)
{
Pixmap pix;
XrColor clear;
unsigned int width, height;
gstate->parent_surface = gstate->surface;
width = _XrSurfaceGetWidth(gstate->surface);
height = _XrSurfaceGetHeight(gstate->surface);
pix = XCreatePixmap(gstate->dpy,
_XrSurfaceGetDrawable(gstate->surface),
width, height,
_XrSurfaceGetDepth(gstate->surface));
if (pix == 0)
return XrStatusNoMemory;
gstate->surface = _XrSurfaceCreate(gstate->dpy);
if (gstate->surface == NULL)
return XrStatusNoMemory;
_XrSurfaceSetDrawableWH(gstate->surface, pix, width, height);
_XrColorInit(&clear);
_XrColorSetAlpha(&clear, 0);
XcFillRectangle(gstate->dpy,
XrOperatorSrc,
_XrSurfaceGetXcSurface(gstate->surface),
&clear.xc_color,
0, 0,
_XrSurfaceGetWidth(gstate->surface),
_XrSurfaceGetHeight(gstate->surface));
return XrStatusSuccess;
}
/* Complete the current offscreen group, composing its contents onto the parent surface. */
XrStatus
_XrGStateEndGroup(XrGState *gstate)
{
Pixmap pix;
XrColor mask_color;
XrSurface mask;
if (gstate->parent_surface == NULL)
return XrStatusInvalidPopGroup;
_XrSurfaceInit(&mask, gstate->dpy);
_XrColorInit(&mask_color);
_XrColorSetAlpha(&mask_color, gstate->alpha);
_XrSurfaceSetSolidColor(&mask, &mask_color);
/* XXX: This could be made much more efficient by using
_XrSurfaceGetDamagedWidth/Height if XrSurface actually kept
track of such informaton. */
XcComposite(gstate->dpy, gstate->operator,
_XrSurfaceGetXcSurface(gstate->surface),
_XrSurfaceGetXcSurface(&mask),
_XrSurfaceGetXcSurface(gstate->parent_surface),
0, 0,
0, 0,
0, 0,
_XrSurfaceGetWidth(gstate->surface),
_XrSurfaceGetHeight(gstate->surface));
_XrSurfaceDeinit(&mask);
pix = _XrSurfaceGetDrawable(gstate->surface);
XFreePixmap(gstate->dpy, pix);
_XrSurfaceDestroy(gstate->surface);
gstate->surface = gstate->parent_surface;
gstate->parent_surface = NULL;
return XrStatusSuccess;
}
XrStatus
_XrGStateSetDrawable(XrGState *gstate, Drawable drawable)
{
_XrSurfaceSetDrawable(&gstate->surface, drawable);
_XrSurfaceSetDrawable(gstate->surface, drawable);
return XrStatusSuccess;
}
@ -195,7 +282,7 @@ _XrGStateSetDrawable(XrGState *gstate, Drawable drawable)
XrStatus
_XrGStateSetVisual(XrGState *gstate, Visual *visual)
{
_XrSurfaceSetVisual(&gstate->surface, visual);
_XrSurfaceSetVisual(gstate->surface, visual);
return XrStatusSuccess;
}
@ -203,7 +290,7 @@ _XrGStateSetVisual(XrGState *gstate, Visual *visual)
XrStatus
_XrGStateSetFormat(XrGState *gstate, XrFormat format)
{
_XrSurfaceSetFormat(&gstate->surface, format);
_XrSurfaceSetFormat(gstate->surface, format);
return XrStatusSuccess;
}
@ -220,7 +307,7 @@ XrStatus
_XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue)
{
_XrColorSetRGB(&gstate->color, red, green, blue);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color);
_XrSurfaceSetSolidColor(gstate->src, &gstate->color);
return XrStatusSuccess;
}
@ -236,8 +323,9 @@ _XrGStateSetTolerance(XrGState *gstate, double tolerance)
XrStatus
_XrGStateSetAlpha(XrGState *gstate, double alpha)
{
gstate->alpha = alpha;
_XrColorSetAlpha(&gstate->color, alpha);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color);
_XrSurfaceSetSolidColor(gstate->src, &gstate->color);
return XrStatusSuccess;
}
@ -542,8 +630,8 @@ _XrGStateStroke(XrGState *gstate)
}
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
_XrSurfaceGetXcSurface(&gstate->src),
_XrSurfaceGetXcSurface(&gstate->surface),
_XrSurfaceGetXcSurface(gstate->src),
_XrSurfaceGetXcSurface(gstate->surface),
gstate->alphaFormat,
0, 0,
traps.xtraps,
@ -582,8 +670,8 @@ _XrGStateFill(XrGState *gstate)
}
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
_XrSurfaceGetXcSurface(&gstate->src),
_XrSurfaceGetXcSurface(&gstate->surface),
_XrSurfaceGetXcSurface(gstate->src),
_XrSurfaceGetXcSurface(gstate->surface),
gstate->alphaFormat,
0, 0,
traps.xtraps,
@ -701,14 +789,21 @@ _XrGStateShowImageTransform(XrGState *gstate,
double tx, double ty)
{
XrStatus status;
XrSurface image_surface;
XrColor mask_color;
XrSurface image_surface, mask;
double dst_width, dst_height;
_XrSurfaceInit(&mask, gstate->dpy);
_XrColorInit(&mask_color);
_XrColorSetAlpha(&mask_color, gstate->alpha);
_XrSurfaceSetSolidColor(&mask, &mask_color);
_XrSurfaceInit(&image_surface, gstate->dpy);
_XrSurfaceSetFormat(&image_surface, format);
status = _XrSurfaceSetImage(&image_surface, data, width, height, stride);
status = _XrSurfaceSetImage(&image_surface, data,width, height, stride);
if (status)
return status;
@ -720,8 +815,8 @@ _XrGStateShowImageTransform(XrGState *gstate,
XcComposite(gstate->dpy, gstate->operator,
_XrSurfaceGetXcSurface(&image_surface),
0,
_XrSurfaceGetXcSurface(&gstate->surface),
_XrSurfaceGetXcSurface(&mask),
_XrSurfaceGetXcSurface(gstate->surface),
0, 0,
0, 0,
gstate->current_pt.x,
@ -730,6 +825,7 @@ _XrGStateShowImageTransform(XrGState *gstate,
dst_height);
_XrSurfaceDeinit(&image_surface);
_XrSurfaceDeinit(&mask);
return XrStatusSuccess;
}
@ -737,11 +833,11 @@ _XrGStateShowImageTransform(XrGState *gstate,
static Picture
_XrGStateGetPicture(XrGState *gstate)
{
return _XrSurfaceGetPicture(&gstate->surface);
return _XrSurfaceGetPicture(gstate->surface);
}
static Picture
_XrGStateGetSrcPicture(XrGState *gstate)
{
return _XrSurfaceGetPicture(&gstate->src);
return _XrSurfaceGetPicture(gstate->src);
}

48
xrint.h
View file

@ -171,10 +171,14 @@ typedef struct _XrSurface {
Drawable drawable;
GC gc;
unsigned int width;
unsigned int height;
unsigned int depth;
unsigned long xc_sa_mask;
XcSurfaceAttributes xc_sa;
XrFormat format;
XcFormat *xc_format;
XcSurface *xc_surface;
@ -248,10 +252,12 @@ typedef struct _XrGState {
XrFont font;
XrSurface src;
XrSurface surface;
XrSurface *parent_surface;
XrSurface *surface;
XrSurface *src;
XrSurface *mask;
double alpha;
XrColor color;
XrTransform ctm;
@ -341,6 +347,12 @@ _XrGStateDestroy(XrGState *gstate);
XrGState *
_XrGStateClone(XrGState *gstate);
XrStatus
_XrGStateBeginGroup(XrGState *gstate);
XrStatus
_XrGStateEndGroup(XrGState *gstate);
XrStatus
_XrGStateSetDrawable(XrGState *gstate, Drawable drawable);
@ -487,7 +499,7 @@ _XrColorSetAlpha(XrColor *color, double alpha);
/* xrfont.c */
void
_XrFontInit(XrFont *font, XrGState *gstate);
_XrFontInit(XrFont *font);
XrStatus
_XrFontInitCopy(XrFont *font, XrFont *other);
@ -538,9 +550,18 @@ XrStatus
_XrPathInterpret(XrPath *path, XrPathDirection dir, XrPathCallbacks *cb, void *closure);
/* xrsurface.c */
XrSurface *
_XrSurfaceCreate(Display *dpy);
void
_XrSurfaceInit(XrSurface *surface, Display *dpy);
void
_XrSurfaceDeinit(XrSurface *surface);
void
_XrSurfaceDestroy(XrSurface *surface);
void
_XrSurfaceReference(XrSurface *surface);
@ -550,9 +571,6 @@ _XrSurfaceDereference(XrSurface *surface);
void
_XrSurfaceDereferenceDestroy(XrSurface *surface);
void
_XrSurfaceDeinit(XrSurface *surface);
void
_XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color);
@ -569,6 +587,12 @@ _XrSurfaceSetTransform(XrSurface *surface, XrTransform *transform);
void
_XrSurfaceSetDrawable(XrSurface *surface, Drawable drawable);
void
_XrSurfaceSetDrawableWH(XrSurface *surface,
Drawable drawable,
unsigned int width,
unsigned int height);
void
_XrSurfaceSetVisual(XrSurface *surface, Visual *visual);
@ -581,6 +605,18 @@ _XrSurfaceGetXcSurface(XrSurface *surface);
Picture
_XrSurfaceGetPicture(XrSurface *surface);
Drawable
_XrSurfaceGetDrawable(XrSurface *surface);
unsigned int
_XrSurfaceGetWidth(XrSurface *surface);
unsigned int
_XrSurfaceGetHeight(XrSurface *surface);
unsigned int
_XrSurfaceGetDepth(XrSurface *surface);
/* xrpen.c */
XrStatus
_XrPenInit(XrPen *pen, double radius, XrGState *gstate);

View file

@ -50,6 +50,7 @@ _XrStateInit(XrState *xrs, Display *dpy)
{
xrs->dpy = dpy;
xrs->stack = NULL;
xrs->status = XrStatusSuccess;
return _XrStatePush(xrs);

View file

@ -23,8 +23,23 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include "xrint.h"
XrSurface *
_XrSurfaceCreate(Display *dpy)
{
XrSurface *surface;
surface = malloc(sizeof(XrSurface));
if (surface)
_XrSurfaceInit(surface, dpy);
return surface;
}
void
_XrSurfaceInit(XrSurface *surface, Display *dpy)
{
@ -33,11 +48,13 @@ _XrSurfaceInit(XrSurface *surface, Display *dpy)
surface->drawable = 0;
surface->gc = 0;
surface->width = 0;
surface->height = 0;
surface->depth = 0;
surface->xc_sa_mask = 0;
surface->xc_format = XcFindStandardFormat(dpy, PictStandardARGB32);
_XrSurfaceSetFormat(surface, XrFormatARGB32);
surface->xc_surface = 0;
surface->needs_new_xc_surface = 1;
@ -45,6 +62,22 @@ _XrSurfaceInit(XrSurface *surface, Display *dpy)
surface->ref_count = 0;
}
void
_XrSurfaceDeinit(XrSurface *surface)
{
if (surface->xc_surface)
XcFreeSurface(surface->dpy, surface->xc_surface);
if (surface->gc)
XFreeGC(surface->dpy, surface->gc);
}
void
_XrSurfaceDestroy(XrSurface *surface)
{
_XrSurfaceDeinit(surface);
free(surface);
}
void
_XrSurfaceReference(XrSurface *surface)
{
@ -63,17 +96,10 @@ _XrSurfaceDereference(XrSurface *surface)
void
_XrSurfaceDereferenceDestroy(XrSurface *surface)
{
_XrSurfaceDereference(surface);
if (surface->ref_count == 0)
free(surface);
}
void
_XrSurfaceDeinit(XrSurface *surface)
{
if (surface->xc_surface)
XcFreeSurface(surface->dpy, surface->xc_surface);
_XrSurfaceDestroy(surface);
else
_XrSurfaceDereference(surface);
}
void
@ -85,7 +111,7 @@ _XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color)
DefaultRootWindow(surface->dpy),
1, 1,
surface->xc_format->depth);
_XrSurfaceSetDrawable(surface, pix);
_XrSurfaceSetDrawableWH(surface, pix, 1, 1);
surface->xc_sa_mask |= CPRepeat;
surface->xc_sa.repeat = True;
_XrSurfaceGetXcSurface(surface);
@ -121,7 +147,7 @@ _XrSurfaceSetImage(XrSurface *surface,
DefaultRootWindow(surface->dpy),
width, height,
depth);
_XrSurfaceSetDrawable(surface, pix);
_XrSurfaceSetDrawableWH(surface, pix, width, height);
image = XCreateImage(surface->dpy,
DefaultVisual(surface->dpy, DefaultScreen(surface->dpy)),
@ -178,11 +204,32 @@ _XrSurfaceSetTransform(XrSurface *surface, XrTransform *transform)
void
_XrSurfaceSetDrawable(XrSurface *surface, Drawable drawable)
{
Window root;
int x, y;
unsigned int border, depth;
unsigned int width, height;
XGetGeometry (surface->dpy, drawable,
&root, &x, &y,
&width, &height,
&border, &depth);
_XrSurfaceSetDrawableWH(surface, drawable, width, height);
}
void
_XrSurfaceSetDrawableWH(XrSurface *surface,
Drawable drawable,
unsigned int width,
unsigned int height)
{
if (surface->gc)
XFreeGC(surface->dpy, surface->gc);
surface->drawable = drawable;
surface->width = width;
surface->height = height;
surface->gc = XCreateGC(surface->dpy, surface->drawable, 0, 0);
surface->needs_new_xc_surface = 1;
@ -198,7 +245,23 @@ _XrSurfaceSetVisual(XrSurface *surface, Visual *visual)
void
_XrSurfaceSetFormat(XrSurface *surface, XrFormat format)
{
surface->format = format;
surface->xc_format = XcFindStandardFormat(surface->dpy, format);
switch (surface->format) {
case XrFormatARGB32:
surface->depth = 32;
case XrFormatRGB32:
/* XXX: Is this correct? */
surface->depth = 24;
case XrFormatA8:
surface->depth = 8;
case XrFormatA1:
surface->depth = 1;
default:
surface->depth = 32;
}
surface->needs_new_xc_surface = 1;
}
@ -234,3 +297,27 @@ _XrSurfaceGetPicture(XrSurface *surface)
{
return XcSurfaceGetPicture(_XrSurfaceGetXcSurface(surface));
}
Drawable
_XrSurfaceGetDrawable(XrSurface *surface)
{
return surface->drawable;
}
unsigned int
_XrSurfaceGetWidth(XrSurface *surface)
{
return surface->width;
}
unsigned int
_XrSurfaceGetHeight(XrSurface *surface)
{
return surface->height;
}
unsigned int
_XrSurfaceGetDepth(XrSurface *surface)
{
return surface->depth;
}