/*
*
* Copyright © 2000 SuSE, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of SuSE not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. SuSE makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Keith Packard, SuSE, Inc.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "Xrenderint.h"
GlyphSet
XRenderCreateGlyphSet (Display *dpy, _Xconst XRenderPictFormat *format)
{
XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy);
GlyphSet gsid;
xRenderCreateGlyphSetReq *req;
RenderCheckExtension (dpy, info, 0);
LockDisplay(dpy);
GetReq(RenderCreateGlyphSet, req);
req->reqType = info->codes->major_opcode;
req->renderReqType = X_RenderCreateGlyphSet;
req->gsid = gsid = XAllocID(dpy);
req->format = format->id;
UnlockDisplay(dpy);
SyncHandle();
return gsid;
}
GlyphSet
XRenderReferenceGlyphSet (Display *dpy, GlyphSet existing)
{
XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy);
GlyphSet gsid;
xRenderReferenceGlyphSetReq *req;
RenderCheckExtension (dpy, info, 0);
LockDisplay(dpy);
GetReq(RenderReferenceGlyphSet, req);
req->reqType = info->codes->major_opcode;
req->renderReqType = X_RenderReferenceGlyphSet;
req->gsid = gsid = XAllocID(dpy);
req->existing = existing;
UnlockDisplay(dpy);
SyncHandle();
return gsid;
}
void
XRenderFreeGlyphSet (Display *dpy, GlyphSet glyphset)
{
XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy);
xRenderFreeGlyphSetReq *req;
RenderSimpleCheckExtension (dpy, info);
LockDisplay(dpy);
GetReq(RenderFreeGlyphSet, req);
req->reqType = info->codes->major_opcode;
req->renderReqType = X_RenderFreeGlyphSet;
req->glyphset = glyphset;
UnlockDisplay(dpy);
SyncHandle();
}
void
XRenderAddGlyphs (Display *dpy,
GlyphSet glyphset,
_Xconst Glyph *gids,
_Xconst XGlyphInfo *glyphs,
int nglyphs,
_Xconst char *images,
int nbyte_images)
{
XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy);
xRenderAddGlyphsReq *req;
long len;
if (nbyte_images & 3)
nbyte_images += 4 - (nbyte_images & 3);
RenderSimpleCheckExtension (dpy, info);
LockDisplay(dpy);
GetReq(RenderAddGlyphs, req);
req->reqType = info->codes->major_opcode;
req->renderReqType = X_RenderAddGlyphs;
req->glyphset = glyphset;
req->nglyphs = nglyphs;
len = (nglyphs * (SIZEOF (xGlyphInfo) + 4) + nbyte_images) >> 2;
SetReqLen(req, len, len);
Data32 (dpy, (long *) gids, nglyphs * 4);
Data16 (dpy, (short *) glyphs, nglyphs * SIZEOF (xGlyphInfo));
Data (dpy, images, nbyte_images);
UnlockDisplay(dpy);
SyncHandle();
}
void
XRenderFreeGlyphs (Display *dpy,
GlyphSet glyphset,
_Xconst Glyph *gids,
int nglyphs)
{
XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy);
xRenderFreeGlyphsReq *req;
long len;
RenderSimpleCheckExtension (dpy, info);
LockDisplay(dpy);
GetReq(RenderFreeGlyphs, req);
req->reqType = info->codes->major_opcode;
req->renderReqType = X_RenderFreeGlyphs;
req->glyphset = glyphset;
len = nglyphs;
SetReqLen(req, len, len);
len <<= 2;
Data32 (dpy, (long *) gids, len);
UnlockDisplay(dpy);
SyncHandle();
}
void
XRenderCompositeString8 (Display *dpy,
int op,
Picture src,
Picture dst,
_Xconst XRenderPictFormat *maskFormat,
GlyphSet glyphset,
int xSrc,
int ySrc,
int xDst,
int yDst,
_Xconst char *string,
int nchar)
{
XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy);
xRenderCompositeGlyphs8Req *req;
long len;
xGlyphElt *elt;
int nbytes;
if (!nchar)
return;
RenderSimpleCheckExtension (dpy, info);
LockDisplay(dpy);
GetReq(RenderCompositeGlyphs8, req);
req->reqType = info->codes->major_opcode;
req->renderReqType = X_RenderCompositeGlyphs8;
req->op = op;
req->src = src;
req->dst = dst;
req->maskFormat = maskFormat ? maskFormat->id : None;
req->glyphset = glyphset;
req->xSrc = xSrc;
req->ySrc = ySrc;
/*
* xGlyphElt must be aligned on a 32-bit boundary; this is
* easily done by filling no more than 252 glyphs in each
* bucket
*/
#define MAX_8 252
len = SIZEOF(xGlyphElt) * ((nchar + MAX_8-1) / MAX_8) + nchar;
req->length += (len + 3)>>2; /* convert to number of 32-bit words */
/*
* If the entire request does not fit into the remaining space in the
* buffer, flush the buffer first.
*/
if (dpy->bufptr + len > dpy->bufmax)
_XFlush (dpy);
while(nchar > MAX_8)
{
nbytes = MAX_8 + SIZEOF(xGlyphElt);
BufAlloc (xGlyphElt *, elt, nbytes);
elt->len = MAX_8;
elt->deltax = xDst;
elt->deltay = yDst;
xDst = 0;
yDst = 0;
memcpy ((char *) (elt + 1), string, MAX_8);
nchar = nchar - MAX_8;
string += MAX_8;
}
if (nchar)
{
nbytes = (nchar + SIZEOF(xGlyphElt) + 3) & ~3;
BufAlloc (xGlyphElt *, elt, nbytes);
elt->len = nchar;
elt->deltax = xDst;
elt->deltay = yDst;
memcpy ((char *) (elt + 1), string, nchar);
}
#undef MAX_8
UnlockDisplay(dpy);
SyncHandle();
}
void
XRenderCompositeString16 (Display *dpy,
int op,
Picture src,
Picture dst,
_Xconst XRenderPictFormat *maskFormat,
GlyphSet glyphset,
int xSrc,
int ySrc,
int xDst,
int yDst,
_Xconst unsigned short *string,
int nchar)
{
XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy);
xRenderCompositeGlyphs8Req *req;
long len;
xGlyphElt *elt;
int nbytes;
if (!nchar)
return;
RenderSimpleCheckExtension (dpy, info);
LockDisplay(dpy);
GetReq(RenderCompositeGlyphs16, req);
req->reqType = info->codes->major_opcode;
req->renderReqType = X_RenderCompositeGlyphs16;
req->op = op;
req->src = src;
req->dst = dst;
req->maskFormat = maskFormat ? maskFormat->id : None;
req->glyphset = glyphset;
req->xSrc = xSrc;
req->ySrc = ySrc;
#define MAX_16 254
len = SIZEOF(xGlyphElt) * ((nchar + MAX_16-1) / MAX_16) + nchar * 2;
req->length += (len + 3)>>2; /* convert to number of 32-bit words */
/*
* If the entire request does not fit into the remaining space in the
* buffer, flush the buffer first.
*/
if (dpy->bufptr + len > dpy->bufmax)
_XFlush (dpy);
while(nchar > MAX_16)
{
nbytes = MAX_16 * 2 + SIZEOF(xGlyphElt);
BufAlloc (xGlyphElt *, elt, nbytes);
elt->len = MAX_16;
elt->deltax = xDst;
elt->deltay = yDst;
xDst = 0;
yDst = 0;
memcpy ((char *) (elt + 1), (char *) string, MAX_16 * 2);
nchar = nchar - MAX_16;
string += MAX_16;
}
if (nchar)
{
nbytes = (nchar * 2 + SIZEOF(xGlyphElt) + 3) & ~3;
BufAlloc (xGlyphElt *, elt, nbytes);
elt->len = nchar;
elt->deltax = xDst;
elt->deltay = yDst;
memcpy ((char *) (elt + 1), (char *) string, nchar * 2);
}
#undef MAX_16
UnlockDisplay(dpy);
SyncHandle();
}
void
XRenderCompositeString32 (Display *dpy,
int op,
Picture src,
Picture dst,
_Xconst XRenderPictFormat *maskFormat,
GlyphSet glyphset,
int xSrc,
int ySrc,
int xDst,
int yDst,
_Xconst unsigned int *string,
int nchar)
{
XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy);
xRenderCompositeGlyphs8Req *req;
long len;
xGlyphElt *elt;
int nbytes;
if (!nchar)
return;
RenderSimpleCheckExtension (dpy, info);
LockDisplay(dpy);
GetReq(RenderCompositeGlyphs32, req);
req->reqType = info->codes->major_opcode;
req->renderReqType = X_RenderCompositeGlyphs32;
req->op = op;
req->src = src;
req->dst = dst;
req->maskFormat = maskFormat ? maskFormat->id : None;
req->glyphset = glyphset;
req->xSrc = xSrc;
req->ySrc = ySrc;
#define MAX_32 254
len = SIZEOF(xGlyphElt) * ((nchar + MAX_32-1) / MAX_32) + nchar * 4;
req->length += (len + 3)>>2; /* convert to number of 32-bit words */
/*
* If the entire request does not fit into the remaining space in the
* buffer, flush the buffer first.
*/
if (dpy->bufptr + len > dpy->bufmax)
_XFlush (dpy);
while(nchar > MAX_32)
{
nbytes = MAX_32 * 4 + SIZEOF(xGlyphElt);
BufAlloc (xGlyphElt *, elt, nbytes);
elt->len = MAX_32;
elt->deltax = xDst;
elt->deltay = yDst;
xDst = 0;
yDst = 0;
memcpy ((char *) (elt + 1), (char *) string, MAX_32 * 4);
nchar = nchar - MAX_32;
string += MAX_32;
}
if (nchar)
{
nbytes = nchar * 4 + SIZEOF(xGlyphElt);
BufAlloc (xGlyphElt *, elt, nbytes);
elt->len = nchar;
elt->deltax = xDst;
elt->deltay = yDst;
memcpy ((char *) (elt + 1), (char *) string, nchar * 4);
}
#undef MAX_32
UnlockDisplay(dpy);
SyncHandle();
}
void
XRenderCompositeText8 (Display *dpy,
int op,
Picture src,
Picture dst,
_Xconst XRenderPictFormat *maskFormat,
int xSrc,
int ySrc,
int xDst,
int yDst,
_Xconst XGlyphElt8 *elts,
int nelt)
{
XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy);
xRenderCompositeGlyphs8Req *req;
GlyphSet glyphset;
long len;
long elen;
xGlyphElt *elt;
int i;
_Xconst char *chars;
int nchars;
if (!nelt)
return;
RenderSimpleCheckExtension (dpy, info);
LockDisplay(dpy);
GetReq(RenderCompositeGlyphs8, req);
req->reqType = info->codes->major_opcode;
req->renderReqType = X_RenderCompositeGlyphs8;
req->op = op;
req->src = src;
req->dst = dst;
req->maskFormat = maskFormat ? maskFormat->id : None;
req->glyphset = elts[0].glyphset;
req->xSrc = xSrc;
req->ySrc = ySrc;
/*
* Compute the space necessary
*/
len = 0;
#define MAX_8 252
glyphset = elts[0].glyphset;
for (i = 0; i < nelt; i++)
{
/*
* Check for glyphset change
*/
if (elts[i].glyphset != glyphset)
{
glyphset = elts[i].glyphset;
len += (SIZEOF (xGlyphElt) + 4) >> 2;
}
nchars = elts[i].nchars;
/*
* xGlyphElt must be aligned on a 32-bit boundary; this is
* easily done by filling no more than 252 glyphs in each
* bucket
*/
elen = SIZEOF(xGlyphElt) * ((nchars + MAX_8-1) / MAX_8) + nchars;
len += (elen + 3) >> 2;
}
req->length += len;
/*
* Send the glyphs
*/
glyphset = elts[0].glyphset;
for (i = 0; i < nelt; i++)
{
/*
* Switch glyphsets
*/
if (elts[i].glyphset != glyphset)
{
glyphset = elts[i].glyphset;
BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
elt->len = 0xff;
elt->deltax = 0;
elt->deltay = 0;
Data32(dpy, &glyphset, 4);
}
nchars = elts[i].nchars;
xDst = elts[i].xOff;
yDst = elts[i].yOff;
chars = elts[i].chars;
while (nchars)
{
int this_chars = nchars > MAX_8 ? MAX_8 : nchars;
BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt))
elt->len = this_chars;
elt->deltax = xDst;
elt->deltay = yDst;
xDst = 0;
yDst = 0;
Data (dpy, chars, this_chars);
nchars -= this_chars;
chars += this_chars;
}
}
#undef MAX_8
UnlockDisplay(dpy);
SyncHandle();
}
void
XRenderCompositeText16 (Display *dpy,
int op,
Picture src,
Picture dst,
_Xconst XRenderPictFormat *maskFormat,
int xSrc,
int ySrc,
int xDst,
int yDst,
_Xconst XGlyphElt16 *elts,
int nelt)
{
XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy);
xRenderCompositeGlyphs16Req *req;
GlyphSet glyphset;
long len;
long elen;
xGlyphElt *elt;
int i;
_Xconst unsigned short *chars;
int nchars;
if (!nelt)
return;
RenderSimpleCheckExtension (dpy, info);
LockDisplay(dpy);
GetReq(RenderCompositeGlyphs16, req);
req->reqType = info->codes->major_opcode;
req->renderReqType = X_RenderCompositeGlyphs16;
req->op = op;
req->src = src;
req->dst = dst;
req->maskFormat = maskFormat ? maskFormat->id : None;
req->glyphset = elts[0].glyphset;
req->xSrc = xSrc;
req->ySrc = ySrc;
/*
* Compute the space necessary
*/
len = 0;
#define MAX_16 254
glyphset = elts[0].glyphset;
for (i = 0; i < nelt; i++)
{
/*
* Check for glyphset change
*/
if (elts[i].glyphset != glyphset)
{
glyphset = elts[i].glyphset;
len += (SIZEOF (xGlyphElt) + 4) >> 2;
}
nchars = elts[i].nchars;
/*
* xGlyphElt must be aligned on a 32-bit boundary; this is
* easily done by filling no more than 254 glyphs in each
* bucket
*/
elen = SIZEOF(xGlyphElt) * ((nchars + MAX_16-1) / MAX_16) + nchars * 2;
len += (elen + 3) >> 2;
}
req->length += len;
glyphset = elts[0].glyphset;
for (i = 0; i < nelt; i++)
{
/*
* Switch glyphsets
*/
if (elts[i].glyphset != glyphset)
{
glyphset = elts[i].glyphset;
BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
elt->len = 0xff;
elt->deltax = 0;
elt->deltay = 0;
Data32(dpy, &glyphset, 4);
}
nchars = elts[i].nchars;
xDst = elts[i].xOff;
yDst = elts[i].yOff;
chars = elts[i].chars;
while (nchars)
{
int this_chars = nchars > MAX_16 ? MAX_16 : nchars;
int this_bytes = this_chars * 2;
BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt))
elt->len = this_chars;
elt->deltax = xDst;
elt->deltay = yDst;
xDst = 0;
yDst = 0;
Data16 (dpy, chars, this_bytes);
nchars -= this_chars;
chars += this_chars;
}
}
#undef MAX_16
UnlockDisplay(dpy);
SyncHandle();
}
void
XRenderCompositeText32 (Display *dpy,
int op,
Picture src,
Picture dst,
_Xconst XRenderPictFormat *maskFormat,
int xSrc,
int ySrc,
int xDst,
int yDst,
_Xconst XGlyphElt32 *elts,
int nelt)
{
XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy);
xRenderCompositeGlyphs32Req *req;
GlyphSet glyphset;
long len;
long elen;
xGlyphElt *elt;
int i;
_Xconst unsigned int *chars;
int nchars;
if (!nelt)
return;
RenderSimpleCheckExtension (dpy, info);
LockDisplay(dpy);
GetReq(RenderCompositeGlyphs32, req);
req->reqType = info->codes->major_opcode;
req->renderReqType = X_RenderCompositeGlyphs32;
req->op = op;
req->src = src;
req->dst = dst;
req->maskFormat = maskFormat ? maskFormat->id : None;
req->glyphset = elts[0].glyphset;
req->xSrc = xSrc;
req->ySrc = ySrc;
/*
* Compute the space necessary
*/
len = 0;
#define MAX_32 254
glyphset = elts[0].glyphset;
for (i = 0; i < nelt; i++)
{
/*
* Check for glyphset change
*/
if (elts[i].glyphset != glyphset)
{
glyphset = elts[i].glyphset;
len += (SIZEOF (xGlyphElt) + 4) >> 2;
}
nchars = elts[i].nchars;
elen = SIZEOF(xGlyphElt) * ((nchars + MAX_32) / MAX_32) + nchars *4;
len += (elen + 3) >> 2;
}
req->length += len;
glyphset = elts[0].glyphset;
for (i = 0; i < nelt; i++)
{
/*
* Switch glyphsets
*/
if (elts[i].glyphset != glyphset)
{
glyphset = elts[i].glyphset;
BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
elt->len = 0xff;
elt->deltax = 0;
elt->deltay = 0;
Data32(dpy, &glyphset, 4);
}
nchars = elts[i].nchars;
xDst = elts[i].xOff;
yDst = elts[i].yOff;
chars = elts[i].chars;
while (nchars)
{
int this_chars = nchars > MAX_32 ? MAX_32 : nchars;
int this_bytes = this_chars * 4;
BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt))
elt->len = this_chars;
elt->deltax = xDst;
elt->deltay = yDst;
xDst = 0;
yDst = 0;
DataInt32 (dpy, chars, this_bytes);
nchars -= this_chars;
chars += this_chars;
}
}
#undef MAX_32
UnlockDisplay(dpy);
SyncHandle();
}
|