aboutsummaryrefslogtreecommitdiff
path: root/libXrender/src/Glyph.c
diff options
context:
space:
mode:
Diffstat (limited to 'libXrender/src/Glyph.c')
-rw-r--r--libXrender/src/Glyph.c712
1 files changed, 712 insertions, 0 deletions
diff --git a/libXrender/src/Glyph.c b/libXrender/src/Glyph.c
new file mode 100644
index 000000000..894bb77f2
--- /dev/null
+++ b/libXrender/src/Glyph.c
@@ -0,0 +1,712 @@
+/*
+ *
+ * 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();
+}