Partial image support.

This commit is contained in:
Carl Worth 2002-11-01 19:45:30 +00:00
parent fec91ede9e
commit e39a088a29
13 changed files with 752 additions and 168 deletions

View file

@ -1,3 +1,27 @@
2002-11-01 Carl Worth <cworth@east.isi.edu>
* xrsurface.c (_XrSurfaceSetImage): Prelimary image
support. Really only works with ARGB32. I still need to think
about what formats will be supported.
(_XrSurfaceSetTransform): Partial support for transformed
surfaces.
(_XrSurfaceGetXcSurface): Moved all creation/destruction of the
XcSurface into this function so that it is only lazily created
when needed.
* xrgstate.c (_XrGStateSetCurrentPt): gstate now can throw errors
when an operation needs current point, but it doesn't exist yet.
(_XrGStateShowImage, _XrGStateShowImageTransform): Preliminary
image support, (currently it only scales according to the CTM. The
matrix passed with the image doesn't do anything yet.)
* xrfont.c (_XrFontInitCopy): Removed bogus out of memory errors.
* xr.c (XrShowImage, XrShowImageTransform): Added very preliminary
image support. Things don't work completely yet and all the
interfaces are likely to change.
(XrGetStatusString): Added function to map status values to strings.
2002-10-31 Carl Worth <cworth@isi.edu>
* xrfont.c (_XrFontInit):

27
Xr.h
View file

@ -214,16 +214,41 @@ XrTextExtents(XrState *xrs,
void
XrShowText(XrState *xrs, const unsigned char *utf8);
/* Image functions */
void
XrShowImage(XrState *xrs,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride);
void
XrShowImageTransform(XrState *xrs,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride,
double a, double b,
double c, double d,
double tx, double ty);
/* Error status queries */
typedef enum _XrStatus {
XrStatusSuccess = 0,
XrStatusNoMemory,
XrStatusInvalidRestore
XrStatusInvalidRestore,
XrStatusNoCurrentPoint
} XrStatus;
XrStatus
XrGetStatus(XrState *xrs);
const char *
XrGetStatusString(XrState *xrs);
#endif

View file

@ -214,16 +214,41 @@ XrTextExtents(XrState *xrs,
void
XrShowText(XrState *xrs, const unsigned char *utf8);
/* Image functions */
void
XrShowImage(XrState *xrs,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride);
void
XrShowImageTransform(XrState *xrs,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride,
double a, double b,
double c, double d,
double tx, double ty);
/* Error status queries */
typedef enum _XrStatus {
XrStatusSuccess = 0,
XrStatusNoMemory,
XrStatusInvalidRestore
XrStatusInvalidRestore,
XrStatusNoCurrentPoint
} XrStatus;
XrStatus
XrGetStatus(XrState *xrs);
const char *
XrGetStatusString(XrState *xrs);
#endif

View file

@ -381,12 +381,68 @@ XrShowText(XrState *xrs, const unsigned char *utf8)
xrs->status = _XrGStateShowText(_XR_CURRENT_GSTATE(xrs), utf8);
}
void
XrShowImage(XrState *xrs,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride)
{
if (xrs->status)
return;
xrs->status = _XrGStateShowImage(_XR_CURRENT_GSTATE(xrs),
data, format,
width, height, stride);
}
void
XrShowImageTransform(XrState *xrs,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride,
double a, double b,
double c, double d,
double tx, double ty)
{
if (xrs->status)
return;
xrs->status = _XrGStateShowImageTransform(_XR_CURRENT_GSTATE(xrs),
data, format,
width, height, stride,
a, b,
c, d,
tx, ty);
}
XrStatus
XrGetStatus(XrState *xrs)
{
return xrs->status;
}
const char *
XrGetStatusString(XrState *xrs)
{
switch (xrs->status) {
case XrStatusSuccess:
return "success";
case XrStatusNoMemory:
return "out of memory";
case XrStatusInvalidRestore:
return "XrRestore without matchin XrSave";
case XrStatusNoCurrentPoint:
return "no current point defined";
}
return "";
}
static void
_XrClipValue(double *value, double min, double max)
{

View file

@ -52,7 +52,7 @@ _XrFontInitCopy(XrFont *font, XrFont *other)
if (other->xft_font) {
font->xft_font = XftFontCopy(other->dpy, other->xft_font);
if (font->xft_font)
if (font->xft_font == NULL)
return XrStatusNoMemory;
}

View file

@ -57,32 +57,35 @@ _XrGStateInit(XrGState *gstate, Display *dpy)
gstate->tolerance = XR_GSTATE_TOLERANCE_DEFAULT;
gstate->fill_rule = XR_GSTATE_FILL_RULE_DEFAULT;
gstate->line_width = XR_GSTATE_LINE_WIDTH_DEFAULT;
gstate->line_cap = XR_GSTATE_LINE_CAP_DEFAULT;
gstate->line_join = XR_GSTATE_LINE_JOIN_DEFAULT;
gstate->miter_limit = XR_GSTATE_MITER_LIMIT_DEFAULT;
gstate->fill_rule = XR_GSTATE_FILL_RULE_DEFAULT;
gstate->dashes = 0;
gstate->ndashes = 0;
gstate->dash_offset = 0.0;
gstate->solidFormat = XcFindStandardFormat(dpy, PictStandardARGB32);
gstate->alphaFormat = XcFindStandardFormat(dpy, PictStandardA8);
_XrFontInit(&gstate->font, gstate);
_XrSurfaceInit(&gstate->surface, dpy);
_XrSurfaceInit(&gstate->src, dpy);
gstate->mask = NULL;
_XrColorInit(&gstate->color);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color);
_XrTransformInit(&gstate->ctm);
_XrTransformInit(&gstate->ctm_inverse);
_XrPathInit(&gstate->path);
gstate->has_current_pt = 0;
_XrPenInitEmpty(&gstate->pen_regular);
gstate->next = NULL;
@ -107,6 +110,8 @@ _XrGStateInitCopy(XrGState *gstate, XrGState *other)
_XrSurfaceReference(&gstate->surface);
_XrSurfaceReference(&gstate->src);
if (gstate->mask)
_XrSurfaceReference(gstate->mask);
status = _XrPathInitCopy(&gstate->path, &other->path);
if (status)
@ -136,6 +141,8 @@ _XrGStateDeinit(XrGState *gstate)
_XrSurfaceDereference(&gstate->src);
_XrSurfaceDereference(&gstate->surface);
if (gstate->mask)
_XrSurfaceDereferenceDestroy(gstate->mask);
_XrColorDeinit(&gstate->color);
@ -213,7 +220,7 @@ XrStatus
_XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue)
{
_XrColorSetRGB(&gstate->color, red, green, blue);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color);
return XrStatusSuccess;
}
@ -230,7 +237,7 @@ XrStatus
_XrGStateSetAlpha(XrGState *gstate, double alpha)
{
_XrColorSetAlpha(&gstate->color, alpha);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color);
return XrStatusSuccess;
}
@ -353,10 +360,20 @@ _XrGStateConcatMatrix(XrGState *gstate,
return XrStatusSuccess;
}
static void
_XrGStateSetCurrentPt(XrGState *gstate, double x, double y)
{
gstate->current_pt.x = x;
gstate->current_pt.y = y;
gstate->has_current_pt = 1;
}
XrStatus
_XrGStateNewPath(XrGState *gstate)
{
_XrPathDeinit(&gstate->path);
gstate->has_current_pt = 0;
return XrStatusSuccess;
}
@ -370,8 +387,7 @@ _XrGStateMoveTo(XrGState *gstate, double x, double y)
status = _XrPathMoveTo(&gstate->path, x, y);
gstate->current_pt.x = x;
gstate->current_pt.y = y;
_XrGStateSetCurrentPt(gstate, x, y);
gstate->last_move_pt = gstate->current_pt;
@ -387,8 +403,7 @@ _XrGStateLineTo(XrGState *gstate, double x, double y)
status = _XrPathLineTo(&gstate->path, x, y);
gstate->current_pt.x = x;
gstate->current_pt.y = y;
_XrGStateSetCurrentPt(gstate, x, y);
return status;
}
@ -410,9 +425,7 @@ _XrGStateCurveTo(XrGState *gstate,
x2, y2,
x3, y3);
gstate->current_pt.x = x3;
gstate->current_pt.y = y3;
_XrGStateSetCurrentPt(gstate, x3, y3);
return status;
}
@ -421,15 +434,16 @@ XrStatus
_XrGStateRelMoveTo(XrGState *gstate, double dx, double dy)
{
XrStatus status;
double x, y;
_XrTransformDistance(&gstate->ctm, &dx, &dy);
status = _XrPathMoveTo(&gstate->path,
gstate->current_pt.x + dx,
gstate->current_pt.y + dy);
x = gstate->current_pt.x + dx;
y = gstate->current_pt.y + dy;
gstate->current_pt.x += dx;
gstate->current_pt.y += dy;
status = _XrPathMoveTo(&gstate->path, x, y);
_XrGStateSetCurrentPt(gstate, x, y);
gstate->last_move_pt = gstate->current_pt;
@ -440,16 +454,16 @@ XrStatus
_XrGStateRelLineTo(XrGState *gstate, double dx, double dy)
{
XrStatus status;
double x, y;
_XrTransformDistance(&gstate->ctm, &dx, &dy);
status = _XrPathLineTo(&gstate->path,
gstate->current_pt.x + dx,
gstate->current_pt.y + dy);
x = gstate->current_pt.x + dx;
y = gstate->current_pt.y + dy;
status = _XrPathLineTo(&gstate->path, x, y);
gstate->current_pt.x += dx;
gstate->current_pt.y += dy;
_XrGStateSetCurrentPt(gstate, x, y);
return status;
}
@ -471,8 +485,9 @@ _XrGStateRelCurveTo(XrGState *gstate,
gstate->current_pt.x + dx2, gstate->current_pt.y + dy2,
gstate->current_pt.x + dx3, gstate->current_pt.y + dy3);
gstate->current_pt.x += dx3;
gstate->current_pt.y += dy3;
_XrGStateSetCurrentPt(gstate,
gstate->current_pt.x + dx3,
gstate->current_pt.y + dy3);
return status;
}
@ -484,7 +499,9 @@ _XrGStateClosePath(XrGState *gstate)
status = _XrPathClosePath(&gstate->path);
gstate->current_pt = gstate->last_move_pt;
_XrGStateSetCurrentPt(gstate,
gstate->last_move_pt.x,
gstate->last_move_pt.y);
return status;
}
@ -525,8 +542,8 @@ _XrGStateStroke(XrGState *gstate)
}
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
gstate->src.xc_surface,
gstate->surface.xc_surface,
_XrSurfaceGetXcSurface(&gstate->src),
_XrSurfaceGetXcSurface(&gstate->surface),
gstate->alphaFormat,
0, 0,
traps.xtraps,
@ -565,8 +582,8 @@ _XrGStateFill(XrGState *gstate)
}
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
gstate->src.xc_surface,
gstate->surface.xc_surface,
_XrSurfaceGetXcSurface(&gstate->src),
_XrSurfaceGetXcSurface(&gstate->surface),
gstate->alphaFormat,
0, 0,
traps.xtraps,
@ -637,6 +654,9 @@ _XrGStateShowText(XrGState *gstate, const unsigned char *utf8)
{
XftFont *xft_font;
if (gstate->has_current_pt == 0)
return XrStatusNoCurrentPoint;
_XrFontResolveXftFont(&gstate->font, gstate, &xft_font);
XftTextRenderUtf8(gstate->dpy,
@ -653,6 +673,67 @@ _XrGStateShowText(XrGState *gstate, const unsigned char *utf8)
return XrStatusSuccess;
}
XrStatus
_XrGStateShowImage(XrGState *gstate,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride)
{
return _XrGStateShowImageTransform(gstate,
data, format, width, height, stride,
1, 0,
0, 1,
- gstate->current_pt.x,
- gstate->current_pt.y);
}
XrStatus
_XrGStateShowImageTransform(XrGState *gstate,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride,
double a, double b,
double c, double d,
double tx, double ty)
{
XrStatus status;
XrSurface image_surface;
double dst_width, dst_height;
_XrSurfaceInit(&image_surface, gstate->dpy);
_XrSurfaceSetFormat(&image_surface, format);
status = _XrSurfaceSetImage(&image_surface, data, width, height, stride);
if (status)
return status;
_XrSurfaceSetTransform(&image_surface, &gstate->ctm_inverse);
dst_width = width;
dst_height = height;
_XrTransformDistance(&gstate->ctm, &dst_width, &dst_height);
XcComposite(gstate->dpy, gstate->operator,
_XrSurfaceGetXcSurface(&image_surface),
0,
_XrSurfaceGetXcSurface(&gstate->surface),
0, 0,
0, 0,
gstate->current_pt.x,
gstate->current_pt.y,
dst_width,
dst_height);
_XrSurfaceDeinit(&image_surface);
return XrStatusSuccess;
}
static Picture
_XrGStateGetPicture(XrGState *gstate)
{

View file

@ -169,6 +169,7 @@ typedef struct _XrSurface {
Display *dpy;
Drawable drawable;
GC gc;
unsigned int depth;
@ -177,6 +178,7 @@ typedef struct _XrSurface {
XcFormat *xc_format;
XcSurface *xc_surface;
int needs_new_xc_surface;
unsigned int ref_count;
} XrSurface;
@ -226,29 +228,31 @@ typedef struct _XrFont {
typedef struct _XrGState {
Display *dpy;
XrOperator operator;
double tolerance;
/* stroke style */
double line_width;
XrLineCap line_cap;
XrLineJoin line_join;
double *dashes;
int ndashes;
double dash_offset;
double miter_limit;
XrFillRule fill_rule;
XrOperator operator;
XcFormat *solidFormat;
double *dashes;
int ndashes;
double dash_offset;
XcFormat *alphaFormat;
XrFont font;
XrColor color;
XrSurface src;
XrSurface surface;
XrSurface *mask;
XrColor color;
XrTransform ctm;
XrTransform ctm_inverse;
@ -257,6 +261,7 @@ typedef struct _XrGState {
XPointDouble last_move_pt;
XPointDouble current_pt;
int has_current_pt;
XrPen pen_regular;
@ -447,6 +452,25 @@ _XrGStateTextExtents(XrGState *gstate,
XrStatus
_XrGStateShowText(XrGState *gstate, const unsigned char *utf8);
XrStatus
_XrGStateShowImage(XrGState *gstate,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride);
XrStatus
_XrGStateShowImageTransform(XrGState *gstate,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride,
double a, double b,
double c, double d,
double tx, double ty);
/* xrcolor.c */
void
_XrColorInit(XrColor *color);
@ -523,11 +547,24 @@ _XrSurfaceReference(XrSurface *surface);
void
_XrSurfaceDereference(XrSurface *surface);
void
_XrSurfaceDereferenceDestroy(XrSurface *surface);
void
_XrSurfaceDeinit(XrSurface *surface);
void
_XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color, XcFormat *xc_format);
_XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color);
XrStatus
_XrSurfaceSetImage(XrSurface *surface,
char *data,
unsigned int width,
unsigned int height,
unsigned int stride);
XrStatus
_XrSurfaceSetTransform(XrSurface *surface, XrTransform *transform);
void
_XrSurfaceSetDrawable(XrSurface *surface, Drawable drawable);
@ -538,6 +575,9 @@ _XrSurfaceSetVisual(XrSurface *surface, Visual *visual);
void
_XrSurfaceSetFormat(XrSurface *surface, XrFormat format);
XcSurface *
_XrSurfaceGetXcSurface(XrSurface *surface);
Picture
_XrSurfaceGetPicture(XrSurface *surface);

View file

@ -25,26 +25,22 @@
#include "xrint.h"
static void
_XrSurfaceCreateXcSurface(XrSurface *surface);
static void
_XrSurfaceDestroyXcSurface(XrSurface *surface);
void
_XrSurfaceInit(XrSurface *surface, Display *dpy)
{
surface->dpy = dpy;
surface->drawable = 0;
surface->gc = 0;
surface->depth = 0;
surface->xc_sa_mask = 0;
surface->xc_format = 0;
surface->xc_format = XcFindStandardFormat(dpy, PictStandardARGB32);
surface->xc_surface = 0;
surface->needs_new_xc_surface = 1;
surface->ref_count = 0;
}
@ -64,6 +60,15 @@ _XrSurfaceDereference(XrSurface *surface)
surface->ref_count--;
}
void
_XrSurfaceDereferenceDestroy(XrSurface *surface)
{
_XrSurfaceDereference(surface);
if (surface->ref_count == 0)
free(surface);
}
void
_XrSurfaceDeinit(XrSurface *surface)
{
@ -72,17 +77,18 @@ _XrSurfaceDeinit(XrSurface *surface)
}
void
_XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color, XcFormat *format)
_XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color)
{
/* XXX: QUESTION: Special handling for depth==1 ala xftdraw.c? */
if (surface->xc_surface == 0) {
Pixmap pix;
XcSurfaceAttributes sa;
pix = XCreatePixmap(surface->dpy, DefaultRootWindow(surface->dpy), 1, 1, format->depth);
sa.repeat = True;
surface->xc_surface = XcCreateDrawableSurface(surface->dpy, pix, format, CPRepeat, &sa);
Pixmap pix = XCreatePixmap(surface->dpy,
DefaultRootWindow(surface->dpy),
1, 1,
surface->xc_format->depth);
_XrSurfaceSetDrawable(surface, pix);
surface->xc_sa_mask |= CPRepeat;
surface->xc_sa.repeat = True;
_XrSurfaceGetXcSurface(surface);
XFreePixmap(surface->dpy, pix);
}
@ -91,62 +97,134 @@ _XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color, XcFormat *format)
0, 0, 1, 1);
}
static void
_XrSurfaceCreateXcSurface(XrSurface *surface)
XrStatus
_XrSurfaceSetImage(XrSurface *surface,
char *data,
unsigned int width,
unsigned int height,
unsigned int stride)
{
if (surface->drawable && surface->xc_format) {
surface->xc_surface = XcCreateDrawableSurface(surface->dpy,
surface->drawable,
surface->xc_format,
surface->xc_sa_mask,
&surface->xc_sa);
}
XImage *image;
unsigned int depth, bitmap_pad;
Pixmap pix;
depth = surface->xc_format->depth;
if (depth > 16)
bitmap_pad = 32;
else if (depth > 8)
bitmap_pad = 16;
else
bitmap_pad = 8;
pix = XCreatePixmap(surface->dpy,
DefaultRootWindow(surface->dpy),
width, height,
depth);
_XrSurfaceSetDrawable(surface, pix);
image = XCreateImage(surface->dpy,
DefaultVisual(surface->dpy, DefaultScreen(surface->dpy)),
depth, ZPixmap, 0,
data, width, height,
bitmap_pad,
stride);
if (image == NULL)
return XrStatusNoMemory;
XPutImage(surface->dpy, surface->drawable, surface->gc,
image, 0, 0, 0, 0, width, height);
/* Foolish XDestroyImage thinks it can free my data, but I won't
stand for it. */
image->data = NULL;
XDestroyImage(image);
return XrStatusSuccess;
}
static void
_XrSurfaceDestroyXcSurface(XrSurface *surface)
/* XXX: We may want to move to projective matrices at some point. If
nothing else, that would eliminate the two different transform data
structures we have here. */
XrStatus
_XrSurfaceSetTransform(XrSurface *surface, XrTransform *transform)
{
if (surface->xc_surface) {
XcFreeSurface(surface->dpy, surface->xc_surface);
surface->xc_surface = 0;
}
XTransform xtransform;
xtransform.matrix[0][0] = XDoubleToFixed(transform->m[0][0]);
xtransform.matrix[0][1] = 0;
xtransform.matrix[0][2] = 0;
xtransform.matrix[1][0] = 0;
xtransform.matrix[1][1] = XDoubleToFixed(transform->m[1][1]);
xtransform.matrix[1][2] = 0;
xtransform.matrix[2][0] = 0;
xtransform.matrix[2][1] = 0;
xtransform.matrix[2][2] = XDoubleToFixed(1);
XcSetSurfaceTransform(surface->dpy,
_XrSurfaceGetXcSurface(surface),
&xtransform);
return XrStatusSuccess;
}
/* XXX: These should probably be made to use lazy evaluation.
A new API will be needed, something like _XrSurfacePrepare
*/
void
_XrSurfaceSetDrawable(XrSurface *surface, Drawable drawable)
{
_XrSurfaceDestroyXcSurface(surface);
if (surface->gc)
XFreeGC(surface->dpy, surface->gc);
surface->drawable = drawable;
surface->gc = XCreateGC(surface->dpy, surface->drawable, 0, 0);
_XrSurfaceCreateXcSurface(surface);
surface->needs_new_xc_surface = 1;
}
void
_XrSurfaceSetVisual(XrSurface *surface, Visual *visual)
{
_XrSurfaceDestroyXcSurface(surface);
surface->xc_format = XcFindVisualFormat(surface->dpy, visual);
_XrSurfaceCreateXcSurface(surface);
surface->needs_new_xc_surface = 1;
}
void
_XrSurfaceSetFormat(XrSurface *surface, XrFormat format)
{
_XrSurfaceDestroyXcSurface(surface);
surface->xc_format = XcFindStandardFormat(surface->dpy, format);
surface->needs_new_xc_surface = 1;
}
_XrSurfaceCreateXcSurface(surface);
XcSurface *
_XrSurfaceGetXcSurface(XrSurface *surface)
{
if (surface == NULL)
return NULL;
if (! surface->needs_new_xc_surface)
return surface->xc_surface;
if (surface->xc_surface)
XcFreeSurface(surface->dpy, surface->xc_surface);
if (surface->drawable)
surface->xc_surface = XcCreateDrawableSurface(surface->dpy,
surface->drawable,
surface->xc_format,
surface->xc_sa_mask,
&surface->xc_sa);
else
/* XXX: Is this what we wnat to do here? */
surface->xc_surface = 0;
surface->needs_new_xc_surface = 0;
return surface->xc_surface;
}
Picture
_XrSurfaceGetPicture(XrSurface *surface)
{
return XcSurfaceGetPicture(surface->xc_surface);
return XcSurfaceGetPicture(_XrSurfaceGetXcSurface(surface));
}

56
xr.c
View file

@ -381,12 +381,68 @@ XrShowText(XrState *xrs, const unsigned char *utf8)
xrs->status = _XrGStateShowText(_XR_CURRENT_GSTATE(xrs), utf8);
}
void
XrShowImage(XrState *xrs,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride)
{
if (xrs->status)
return;
xrs->status = _XrGStateShowImage(_XR_CURRENT_GSTATE(xrs),
data, format,
width, height, stride);
}
void
XrShowImageTransform(XrState *xrs,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride,
double a, double b,
double c, double d,
double tx, double ty)
{
if (xrs->status)
return;
xrs->status = _XrGStateShowImageTransform(_XR_CURRENT_GSTATE(xrs),
data, format,
width, height, stride,
a, b,
c, d,
tx, ty);
}
XrStatus
XrGetStatus(XrState *xrs)
{
return xrs->status;
}
const char *
XrGetStatusString(XrState *xrs)
{
switch (xrs->status) {
case XrStatusSuccess:
return "success";
case XrStatusNoMemory:
return "out of memory";
case XrStatusInvalidRestore:
return "XrRestore without matchin XrSave";
case XrStatusNoCurrentPoint:
return "no current point defined";
}
return "";
}
static void
_XrClipValue(double *value, double min, double max)
{

View file

@ -52,7 +52,7 @@ _XrFontInitCopy(XrFont *font, XrFont *other)
if (other->xft_font) {
font->xft_font = XftFontCopy(other->dpy, other->xft_font);
if (font->xft_font)
if (font->xft_font == NULL)
return XrStatusNoMemory;
}

View file

@ -57,32 +57,35 @@ _XrGStateInit(XrGState *gstate, Display *dpy)
gstate->tolerance = XR_GSTATE_TOLERANCE_DEFAULT;
gstate->fill_rule = XR_GSTATE_FILL_RULE_DEFAULT;
gstate->line_width = XR_GSTATE_LINE_WIDTH_DEFAULT;
gstate->line_cap = XR_GSTATE_LINE_CAP_DEFAULT;
gstate->line_join = XR_GSTATE_LINE_JOIN_DEFAULT;
gstate->miter_limit = XR_GSTATE_MITER_LIMIT_DEFAULT;
gstate->fill_rule = XR_GSTATE_FILL_RULE_DEFAULT;
gstate->dashes = 0;
gstate->ndashes = 0;
gstate->dash_offset = 0.0;
gstate->solidFormat = XcFindStandardFormat(dpy, PictStandardARGB32);
gstate->alphaFormat = XcFindStandardFormat(dpy, PictStandardA8);
_XrFontInit(&gstate->font, gstate);
_XrSurfaceInit(&gstate->surface, dpy);
_XrSurfaceInit(&gstate->src, dpy);
gstate->mask = NULL;
_XrColorInit(&gstate->color);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color);
_XrTransformInit(&gstate->ctm);
_XrTransformInit(&gstate->ctm_inverse);
_XrPathInit(&gstate->path);
gstate->has_current_pt = 0;
_XrPenInitEmpty(&gstate->pen_regular);
gstate->next = NULL;
@ -107,6 +110,8 @@ _XrGStateInitCopy(XrGState *gstate, XrGState *other)
_XrSurfaceReference(&gstate->surface);
_XrSurfaceReference(&gstate->src);
if (gstate->mask)
_XrSurfaceReference(gstate->mask);
status = _XrPathInitCopy(&gstate->path, &other->path);
if (status)
@ -136,6 +141,8 @@ _XrGStateDeinit(XrGState *gstate)
_XrSurfaceDereference(&gstate->src);
_XrSurfaceDereference(&gstate->surface);
if (gstate->mask)
_XrSurfaceDereferenceDestroy(gstate->mask);
_XrColorDeinit(&gstate->color);
@ -213,7 +220,7 @@ XrStatus
_XrGStateSetRGBColor(XrGState *gstate, double red, double green, double blue)
{
_XrColorSetRGB(&gstate->color, red, green, blue);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color);
return XrStatusSuccess;
}
@ -230,7 +237,7 @@ XrStatus
_XrGStateSetAlpha(XrGState *gstate, double alpha)
{
_XrColorSetAlpha(&gstate->color, alpha);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color, gstate->solidFormat);
_XrSurfaceSetSolidColor(&gstate->src, &gstate->color);
return XrStatusSuccess;
}
@ -353,10 +360,20 @@ _XrGStateConcatMatrix(XrGState *gstate,
return XrStatusSuccess;
}
static void
_XrGStateSetCurrentPt(XrGState *gstate, double x, double y)
{
gstate->current_pt.x = x;
gstate->current_pt.y = y;
gstate->has_current_pt = 1;
}
XrStatus
_XrGStateNewPath(XrGState *gstate)
{
_XrPathDeinit(&gstate->path);
gstate->has_current_pt = 0;
return XrStatusSuccess;
}
@ -370,8 +387,7 @@ _XrGStateMoveTo(XrGState *gstate, double x, double y)
status = _XrPathMoveTo(&gstate->path, x, y);
gstate->current_pt.x = x;
gstate->current_pt.y = y;
_XrGStateSetCurrentPt(gstate, x, y);
gstate->last_move_pt = gstate->current_pt;
@ -387,8 +403,7 @@ _XrGStateLineTo(XrGState *gstate, double x, double y)
status = _XrPathLineTo(&gstate->path, x, y);
gstate->current_pt.x = x;
gstate->current_pt.y = y;
_XrGStateSetCurrentPt(gstate, x, y);
return status;
}
@ -410,9 +425,7 @@ _XrGStateCurveTo(XrGState *gstate,
x2, y2,
x3, y3);
gstate->current_pt.x = x3;
gstate->current_pt.y = y3;
_XrGStateSetCurrentPt(gstate, x3, y3);
return status;
}
@ -421,15 +434,16 @@ XrStatus
_XrGStateRelMoveTo(XrGState *gstate, double dx, double dy)
{
XrStatus status;
double x, y;
_XrTransformDistance(&gstate->ctm, &dx, &dy);
status = _XrPathMoveTo(&gstate->path,
gstate->current_pt.x + dx,
gstate->current_pt.y + dy);
x = gstate->current_pt.x + dx;
y = gstate->current_pt.y + dy;
gstate->current_pt.x += dx;
gstate->current_pt.y += dy;
status = _XrPathMoveTo(&gstate->path, x, y);
_XrGStateSetCurrentPt(gstate, x, y);
gstate->last_move_pt = gstate->current_pt;
@ -440,16 +454,16 @@ XrStatus
_XrGStateRelLineTo(XrGState *gstate, double dx, double dy)
{
XrStatus status;
double x, y;
_XrTransformDistance(&gstate->ctm, &dx, &dy);
status = _XrPathLineTo(&gstate->path,
gstate->current_pt.x + dx,
gstate->current_pt.y + dy);
x = gstate->current_pt.x + dx;
y = gstate->current_pt.y + dy;
status = _XrPathLineTo(&gstate->path, x, y);
gstate->current_pt.x += dx;
gstate->current_pt.y += dy;
_XrGStateSetCurrentPt(gstate, x, y);
return status;
}
@ -471,8 +485,9 @@ _XrGStateRelCurveTo(XrGState *gstate,
gstate->current_pt.x + dx2, gstate->current_pt.y + dy2,
gstate->current_pt.x + dx3, gstate->current_pt.y + dy3);
gstate->current_pt.x += dx3;
gstate->current_pt.y += dy3;
_XrGStateSetCurrentPt(gstate,
gstate->current_pt.x + dx3,
gstate->current_pt.y + dy3);
return status;
}
@ -484,7 +499,9 @@ _XrGStateClosePath(XrGState *gstate)
status = _XrPathClosePath(&gstate->path);
gstate->current_pt = gstate->last_move_pt;
_XrGStateSetCurrentPt(gstate,
gstate->last_move_pt.x,
gstate->last_move_pt.y);
return status;
}
@ -525,8 +542,8 @@ _XrGStateStroke(XrGState *gstate)
}
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
gstate->src.xc_surface,
gstate->surface.xc_surface,
_XrSurfaceGetXcSurface(&gstate->src),
_XrSurfaceGetXcSurface(&gstate->surface),
gstate->alphaFormat,
0, 0,
traps.xtraps,
@ -565,8 +582,8 @@ _XrGStateFill(XrGState *gstate)
}
XcCompositeTrapezoids(gstate->dpy, gstate->operator,
gstate->src.xc_surface,
gstate->surface.xc_surface,
_XrSurfaceGetXcSurface(&gstate->src),
_XrSurfaceGetXcSurface(&gstate->surface),
gstate->alphaFormat,
0, 0,
traps.xtraps,
@ -637,6 +654,9 @@ _XrGStateShowText(XrGState *gstate, const unsigned char *utf8)
{
XftFont *xft_font;
if (gstate->has_current_pt == 0)
return XrStatusNoCurrentPoint;
_XrFontResolveXftFont(&gstate->font, gstate, &xft_font);
XftTextRenderUtf8(gstate->dpy,
@ -653,6 +673,67 @@ _XrGStateShowText(XrGState *gstate, const unsigned char *utf8)
return XrStatusSuccess;
}
XrStatus
_XrGStateShowImage(XrGState *gstate,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride)
{
return _XrGStateShowImageTransform(gstate,
data, format, width, height, stride,
1, 0,
0, 1,
- gstate->current_pt.x,
- gstate->current_pt.y);
}
XrStatus
_XrGStateShowImageTransform(XrGState *gstate,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride,
double a, double b,
double c, double d,
double tx, double ty)
{
XrStatus status;
XrSurface image_surface;
double dst_width, dst_height;
_XrSurfaceInit(&image_surface, gstate->dpy);
_XrSurfaceSetFormat(&image_surface, format);
status = _XrSurfaceSetImage(&image_surface, data, width, height, stride);
if (status)
return status;
_XrSurfaceSetTransform(&image_surface, &gstate->ctm_inverse);
dst_width = width;
dst_height = height;
_XrTransformDistance(&gstate->ctm, &dst_width, &dst_height);
XcComposite(gstate->dpy, gstate->operator,
_XrSurfaceGetXcSurface(&image_surface),
0,
_XrSurfaceGetXcSurface(&gstate->surface),
0, 0,
0, 0,
gstate->current_pt.x,
gstate->current_pt.y,
dst_width,
dst_height);
_XrSurfaceDeinit(&image_surface);
return XrStatusSuccess;
}
static Picture
_XrGStateGetPicture(XrGState *gstate)
{

56
xrint.h
View file

@ -169,6 +169,7 @@ typedef struct _XrSurface {
Display *dpy;
Drawable drawable;
GC gc;
unsigned int depth;
@ -177,6 +178,7 @@ typedef struct _XrSurface {
XcFormat *xc_format;
XcSurface *xc_surface;
int needs_new_xc_surface;
unsigned int ref_count;
} XrSurface;
@ -226,29 +228,31 @@ typedef struct _XrFont {
typedef struct _XrGState {
Display *dpy;
XrOperator operator;
double tolerance;
/* stroke style */
double line_width;
XrLineCap line_cap;
XrLineJoin line_join;
double *dashes;
int ndashes;
double dash_offset;
double miter_limit;
XrFillRule fill_rule;
XrOperator operator;
XcFormat *solidFormat;
double *dashes;
int ndashes;
double dash_offset;
XcFormat *alphaFormat;
XrFont font;
XrColor color;
XrSurface src;
XrSurface surface;
XrSurface *mask;
XrColor color;
XrTransform ctm;
XrTransform ctm_inverse;
@ -257,6 +261,7 @@ typedef struct _XrGState {
XPointDouble last_move_pt;
XPointDouble current_pt;
int has_current_pt;
XrPen pen_regular;
@ -447,6 +452,25 @@ _XrGStateTextExtents(XrGState *gstate,
XrStatus
_XrGStateShowText(XrGState *gstate, const unsigned char *utf8);
XrStatus
_XrGStateShowImage(XrGState *gstate,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride);
XrStatus
_XrGStateShowImageTransform(XrGState *gstate,
char *data,
XrFormat format,
unsigned int width,
unsigned int height,
unsigned int stride,
double a, double b,
double c, double d,
double tx, double ty);
/* xrcolor.c */
void
_XrColorInit(XrColor *color);
@ -523,11 +547,24 @@ _XrSurfaceReference(XrSurface *surface);
void
_XrSurfaceDereference(XrSurface *surface);
void
_XrSurfaceDereferenceDestroy(XrSurface *surface);
void
_XrSurfaceDeinit(XrSurface *surface);
void
_XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color, XcFormat *xc_format);
_XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color);
XrStatus
_XrSurfaceSetImage(XrSurface *surface,
char *data,
unsigned int width,
unsigned int height,
unsigned int stride);
XrStatus
_XrSurfaceSetTransform(XrSurface *surface, XrTransform *transform);
void
_XrSurfaceSetDrawable(XrSurface *surface, Drawable drawable);
@ -538,6 +575,9 @@ _XrSurfaceSetVisual(XrSurface *surface, Visual *visual);
void
_XrSurfaceSetFormat(XrSurface *surface, XrFormat format);
XcSurface *
_XrSurfaceGetXcSurface(XrSurface *surface);
Picture
_XrSurfaceGetPicture(XrSurface *surface);

View file

@ -25,26 +25,22 @@
#include "xrint.h"
static void
_XrSurfaceCreateXcSurface(XrSurface *surface);
static void
_XrSurfaceDestroyXcSurface(XrSurface *surface);
void
_XrSurfaceInit(XrSurface *surface, Display *dpy)
{
surface->dpy = dpy;
surface->drawable = 0;
surface->gc = 0;
surface->depth = 0;
surface->xc_sa_mask = 0;
surface->xc_format = 0;
surface->xc_format = XcFindStandardFormat(dpy, PictStandardARGB32);
surface->xc_surface = 0;
surface->needs_new_xc_surface = 1;
surface->ref_count = 0;
}
@ -64,6 +60,15 @@ _XrSurfaceDereference(XrSurface *surface)
surface->ref_count--;
}
void
_XrSurfaceDereferenceDestroy(XrSurface *surface)
{
_XrSurfaceDereference(surface);
if (surface->ref_count == 0)
free(surface);
}
void
_XrSurfaceDeinit(XrSurface *surface)
{
@ -72,17 +77,18 @@ _XrSurfaceDeinit(XrSurface *surface)
}
void
_XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color, XcFormat *format)
_XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color)
{
/* XXX: QUESTION: Special handling for depth==1 ala xftdraw.c? */
if (surface->xc_surface == 0) {
Pixmap pix;
XcSurfaceAttributes sa;
pix = XCreatePixmap(surface->dpy, DefaultRootWindow(surface->dpy), 1, 1, format->depth);
sa.repeat = True;
surface->xc_surface = XcCreateDrawableSurface(surface->dpy, pix, format, CPRepeat, &sa);
Pixmap pix = XCreatePixmap(surface->dpy,
DefaultRootWindow(surface->dpy),
1, 1,
surface->xc_format->depth);
_XrSurfaceSetDrawable(surface, pix);
surface->xc_sa_mask |= CPRepeat;
surface->xc_sa.repeat = True;
_XrSurfaceGetXcSurface(surface);
XFreePixmap(surface->dpy, pix);
}
@ -91,62 +97,134 @@ _XrSurfaceSetSolidColor(XrSurface *surface, XrColor *color, XcFormat *format)
0, 0, 1, 1);
}
static void
_XrSurfaceCreateXcSurface(XrSurface *surface)
XrStatus
_XrSurfaceSetImage(XrSurface *surface,
char *data,
unsigned int width,
unsigned int height,
unsigned int stride)
{
if (surface->drawable && surface->xc_format) {
surface->xc_surface = XcCreateDrawableSurface(surface->dpy,
surface->drawable,
surface->xc_format,
surface->xc_sa_mask,
&surface->xc_sa);
}
XImage *image;
unsigned int depth, bitmap_pad;
Pixmap pix;
depth = surface->xc_format->depth;
if (depth > 16)
bitmap_pad = 32;
else if (depth > 8)
bitmap_pad = 16;
else
bitmap_pad = 8;
pix = XCreatePixmap(surface->dpy,
DefaultRootWindow(surface->dpy),
width, height,
depth);
_XrSurfaceSetDrawable(surface, pix);
image = XCreateImage(surface->dpy,
DefaultVisual(surface->dpy, DefaultScreen(surface->dpy)),
depth, ZPixmap, 0,
data, width, height,
bitmap_pad,
stride);
if (image == NULL)
return XrStatusNoMemory;
XPutImage(surface->dpy, surface->drawable, surface->gc,
image, 0, 0, 0, 0, width, height);
/* Foolish XDestroyImage thinks it can free my data, but I won't
stand for it. */
image->data = NULL;
XDestroyImage(image);
return XrStatusSuccess;
}
static void
_XrSurfaceDestroyXcSurface(XrSurface *surface)
/* XXX: We may want to move to projective matrices at some point. If
nothing else, that would eliminate the two different transform data
structures we have here. */
XrStatus
_XrSurfaceSetTransform(XrSurface *surface, XrTransform *transform)
{
if (surface->xc_surface) {
XcFreeSurface(surface->dpy, surface->xc_surface);
surface->xc_surface = 0;
}
XTransform xtransform;
xtransform.matrix[0][0] = XDoubleToFixed(transform->m[0][0]);
xtransform.matrix[0][1] = 0;
xtransform.matrix[0][2] = 0;
xtransform.matrix[1][0] = 0;
xtransform.matrix[1][1] = XDoubleToFixed(transform->m[1][1]);
xtransform.matrix[1][2] = 0;
xtransform.matrix[2][0] = 0;
xtransform.matrix[2][1] = 0;
xtransform.matrix[2][2] = XDoubleToFixed(1);
XcSetSurfaceTransform(surface->dpy,
_XrSurfaceGetXcSurface(surface),
&xtransform);
return XrStatusSuccess;
}
/* XXX: These should probably be made to use lazy evaluation.
A new API will be needed, something like _XrSurfacePrepare
*/
void
_XrSurfaceSetDrawable(XrSurface *surface, Drawable drawable)
{
_XrSurfaceDestroyXcSurface(surface);
if (surface->gc)
XFreeGC(surface->dpy, surface->gc);
surface->drawable = drawable;
surface->gc = XCreateGC(surface->dpy, surface->drawable, 0, 0);
_XrSurfaceCreateXcSurface(surface);
surface->needs_new_xc_surface = 1;
}
void
_XrSurfaceSetVisual(XrSurface *surface, Visual *visual)
{
_XrSurfaceDestroyXcSurface(surface);
surface->xc_format = XcFindVisualFormat(surface->dpy, visual);
_XrSurfaceCreateXcSurface(surface);
surface->needs_new_xc_surface = 1;
}
void
_XrSurfaceSetFormat(XrSurface *surface, XrFormat format)
{
_XrSurfaceDestroyXcSurface(surface);
surface->xc_format = XcFindStandardFormat(surface->dpy, format);
surface->needs_new_xc_surface = 1;
}
_XrSurfaceCreateXcSurface(surface);
XcSurface *
_XrSurfaceGetXcSurface(XrSurface *surface)
{
if (surface == NULL)
return NULL;
if (! surface->needs_new_xc_surface)
return surface->xc_surface;
if (surface->xc_surface)
XcFreeSurface(surface->dpy, surface->xc_surface);
if (surface->drawable)
surface->xc_surface = XcCreateDrawableSurface(surface->dpy,
surface->drawable,
surface->xc_format,
surface->xc_sa_mask,
&surface->xc_sa);
else
/* XXX: Is this what we wnat to do here? */
surface->xc_surface = 0;
surface->needs_new_xc_surface = 0;
return surface->xc_surface;
}
Picture
_XrSurfaceGetPicture(XrSurface *surface)
{
return XcSurfaceGetPicture(surface->xc_surface);
return XcSurfaceGetPicture(_XrSurfaceGetXcSurface(surface));
}