mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-06 21:20:25 +01:00
Partial image support.
This commit is contained in:
parent
fec91ede9e
commit
e39a088a29
13 changed files with 752 additions and 168 deletions
24
ChangeLog
24
ChangeLog
|
|
@ -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
27
Xr.h
|
|
@ -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
|
||||
|
||||
|
|
|
|||
27
src/Xr.h
27
src/Xr.h
|
|
@ -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
|
||||
|
||||
|
|
|
|||
56
src/xr.c
56
src/xr.c
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
141
src/xrgstate.c
141
src/xrgstate.c
|
|
@ -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
src/xrint.h
56
src/xrint.h
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
166
src/xrsurface.c
166
src/xrsurface.c
|
|
@ -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
56
xr.c
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
2
xrfont.c
2
xrfont.c
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
141
xrgstate.c
141
xrgstate.c
|
|
@ -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
56
xrint.h
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
166
xrsurface.c
166
xrsurface.c
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue