aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/lib/Xrender/Glyph.c
diff options
context:
space:
mode:
authorReinhard Tartler <siretart@tauware.de>2011-10-10 17:43:39 +0200
committerReinhard Tartler <siretart@tauware.de>2011-10-10 17:43:39 +0200
commitf4092abdf94af6a99aff944d6264bc1284e8bdd4 (patch)
tree2ac1c9cc16ceb93edb2c4382c088dac5aeafdf0f /nx-X11/lib/Xrender/Glyph.c
parenta840692edc9c6d19cd7c057f68e39c7d95eb767d (diff)
downloadnx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.gz
nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.tar.bz2
nx-libs-f4092abdf94af6a99aff944d6264bc1284e8bdd4.zip
Imported nx-X11-3.1.0-1.tar.gznx-X11/3.1.0-1
Summary: Imported nx-X11-3.1.0-1.tar.gz Keywords: Imported nx-X11-3.1.0-1.tar.gz into Git repository
Diffstat (limited to 'nx-X11/lib/Xrender/Glyph.c')
-rw-r--r--nx-X11/lib/Xrender/Glyph.c1169
1 files changed, 1169 insertions, 0 deletions
diff --git a/nx-X11/lib/Xrender/Glyph.c b/nx-X11/lib/Xrender/Glyph.c
new file mode 100644
index 000000000..e25805f5c
--- /dev/null
+++ b/nx-X11/lib/Xrender/Glyph.c
@@ -0,0 +1,1169 @@
+/*
+ *
+ * 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"
+
+/*
+ * NX_RENDER_CLEANUP enables cleaning of padding bytes
+ */
+
+#define NX_RENDER_CLEANUP
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+#undef DUMP
+
+#ifdef NX_RENDER_CLEANUP
+
+#include <stdio.h>
+
+#define ROUNDUP(nbits, pad) ((((nbits) + ((pad)-1)) / (pad)) * ((pad)>>3))
+
+#endif /* NX_RENDER_CLEANUP */
+
+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();
+}
+
+#ifdef NX_RENDER_CLEANUP
+
+void
+XRenderCleanGlyphs(xGlyphInfo *gi,
+ int nglyphs,
+ CARD8 *images,
+ int depth,
+ Display *dpy)
+{
+
+ int widthInBits;
+ int bytesPerLine;
+ int bytesToClean;
+ int bitsToClean;
+ int widthInBytes;
+ int height = gi -> height;
+ register int i;
+ int j;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCleanGlyphs: Found a Glyph with Depth %d, width %d, pad %d.\n",
+ depth, gi -> width, dpy -> bitmap_pad);
+ #endif
+
+ while (nglyphs > 0)
+ {
+ if (depth == 24)
+ {
+ widthInBits = gi -> width * 32;
+
+ bytesPerLine = ROUNDUP(widthInBits, dpy -> bitmap_pad);
+
+ bytesToClean = bytesPerLine * height;
+
+ #ifdef DUBUG
+ fprintf(stderr, "nxagentCleanGlyphs: Found glyph with depth 24, bytes to clean is %d"
+ "width in bits is %d bytes per line [%d] height [%d].\n", bytesToClean,
+ widthInBits, bytesPerLine, height);
+ #endif
+
+ if (dpy -> byte_order == LSBFirst)
+ {
+ for (i = 3; i < bytesToClean; i += 4)
+ {
+ images[i] = 0x00;
+ }
+ }
+ else
+ {
+ for (i = 0; i < bytesToClean; i += 4)
+ {
+ images[i] = 0x00;
+ }
+ }
+
+ #ifdef DUMP
+ fprintf(stderr, "nxagentCleanGlyphs: depth %d, bytesToClean %d, scanline: ", depth, bytesToClean);
+ for (i = 0; i < bytesPerLine; i++)
+ {
+ fprintf(stderr, "[%d]", images[i]);
+ }
+ fprintf(stderr,"\n");
+ #endif
+
+ images += bytesToClean;
+
+ gi++;
+
+ nglyphs--;
+ }
+ else if (depth == 1)
+ {
+ widthInBits = gi -> width;
+
+ bytesPerLine = ROUNDUP(widthInBits, dpy -> bitmap_pad);
+
+ bitsToClean = (bytesPerLine << 3) - (gi -> width);
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCleanGlyphs: Found glyph with depth 1, width [%d], height [%d], bitsToClean [%d],"
+ " bytesPerLine [%d].\n", gi -> width, height, bitsToClean, bytesPerLine);
+ #endif
+
+ bytesToClean = bitsToClean >> 3;
+
+ bitsToClean &= 7;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCleanGlyphs: bitsToClean &=7 is %d, bytesToCLean is %d."
+ " byte_order is %d, bitmap_bit_order is %d.\n", bitsToClean, bytesToClean,
+ dpy -> byte_order, dpy -> bitmap_bit_order);
+ #endif
+
+ for (i = 1; i <= height; i++)
+ {
+ if (dpy -> byte_order == dpy -> bitmap_bit_order)
+ {
+ for (j = 1; j <= bytesToClean; j++)
+ {
+ images[i * bytesPerLine - j] = 0x00;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCleanGlyphs: byte_order = bitmap_bit_orde, cleaning %d, i=%d, j=%d.\n"
+ , (i * bytesPerLine - j), i, j);
+ #endif
+
+ }
+ }
+ else
+ {
+ for (j = bytesToClean; j >= 1; j--)
+ {
+ images[i * bytesPerLine - j] = 0x00;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCleanGlyphs: byte_order %d, bitmap_bit_order %d, cleaning %d, i=%d, j=%d.\n"
+ , dpy -> byte_order, dpy -> bitmap_bit_order, (i * bytesPerLine - j), i, j);
+ #endif
+
+ }
+ }
+
+ if (dpy -> bitmap_bit_order == MSBFirst)
+ {
+ images[i * bytesPerLine - j] &= 0xff << bitsToClean;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCleanGlyphs: byte_order MSBFirst, cleaning %d, i=%d, j=%d.\n"
+ , (i * bytesPerLine - j), i, j);
+ #endif
+ }
+ else
+ {
+ images[i * bytesPerLine - j] &= 0xff >> bitsToClean;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCleanGlyphs: byte_order LSBFirst, cleaning %d, i=%d, j=%d.\n"
+ , (i * bytesPerLine - j), i, j);
+ #endif
+ }
+ }
+
+ #ifdef DUMP
+ fprintf(stderr, "nxagentCleanGlyphs: depth %d, bytesToClean %d, scanline: ", depth, bytesToClean);
+ for (i = 0; i < bytesPerLine; i++)
+ {
+ fprintf(stderr, "[%d]", images[i]);
+ }
+ fprintf(stderr,"\n");
+ #endif
+
+ images += bytesPerLine * height;
+
+ gi++;
+
+ nglyphs--;
+ }
+ else if ((depth == 8) || (depth == 16) )
+ {
+ widthInBits = gi -> width * depth;
+
+ bytesPerLine = ROUNDUP(widthInBits, dpy -> bitmap_pad);
+
+ widthInBytes = (widthInBits >> 3);
+
+ bytesToClean = bytesPerLine - widthInBytes;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCleanGlyphs: nglyphs is %d, width of glyph in bits is %d, in bytes is %d.\n",
+ nglyphs, widthInBits, widthInBytes);
+
+ fprintf(stderr, "nxagentCleanGlyphs: bytesPerLine is %d bytes, there are %d scanlines.\n", bytesPerLine, height);
+
+ fprintf(stderr, "nxagentCleanGlyphs: Bytes to clean for each scanline are %d.\n", bytesToClean);
+ #endif
+
+ if (bytesToClean > 0)
+ {
+ while (height > 0)
+ {
+ i = bytesToClean;
+
+ while (i > 0)
+ {
+ *(images + (bytesPerLine - i)) = 0;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCleanGlyphs: cleaned a byte.\n");
+ #endif
+
+ i--;
+ }
+
+ #ifdef DUMP
+ fprintf(stderr, "nxagentCleanGlyphs: depth %d, bytesToClean %d, scanline: ", depth, bytesToClean);
+ for (i = 0; i < bytesPerLine; i++)
+ {
+ fprintf(stderr, "[%d]", images[i]);
+ }
+ fprintf(stderr,"\n");
+ #endif
+
+ images += bytesPerLine;
+
+ height--;
+ }
+ }
+
+ gi++;
+
+ nglyphs--;
+
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCleanGlyphs: Breaking Out.\n");
+ #endif
+ }
+ else if (depth == 32)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "nxagentCleanGlyphs: Found glyph with depth 32.\n");
+ #endif
+
+ gi++;
+
+ nglyphs--;
+ }
+ else
+ {
+ #ifdef WARNING
+ fprintf(stderr, "nxagentCleanGlyphs: Unrecognized glyph, depth is not 8/16/24/32, it appears to be %d.\n",
+ depth);
+ #endif
+
+ gi++;
+
+ nglyphs--;
+ }
+ }
+}
+
+#endif /* #ifdef NX_RENDER_CLEANUP */
+
+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;
+
+ #ifdef NX_RENDER_CLEANUP
+
+ char tmpChar[4];
+ int bytes_to_clean;
+ int bytes_to_write;
+
+ #endif /* NX_RENDER_CLEANUP */
+
+ 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));
+
+ #ifdef NX_RENDER_CLEANUP
+
+ elt->pad1 = 0;
+ elt->pad2 = 0;
+
+ #endif /* NX_RENDER_CLEANUP */
+
+ 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))
+
+ #ifdef NX_RENDER_CLEANUP
+
+ elt->pad1 = 0;
+ elt->pad2 = 0;
+
+ #endif /* NX_RENDER_CLEANUP */
+
+ elt->len = this_chars;
+ elt->deltax = xDst;
+ elt->deltay = yDst;
+ xDst = 0;
+ yDst = 0;
+
+ #ifdef NX_RENDER_CLEANUP
+
+ bytes_to_write = this_chars & ~3;
+
+ bytes_to_clean = ((this_chars + 3) & ~3) - this_chars;
+
+ #ifdef DEBUG
+ fprintf(stderr, "XRenderCompositeText8: bytes_to_write %d, bytes_to_clean are %d,"
+ " this_chars %d.\n", bytes_to_write, bytes_to_clean, this_chars);
+ #endif
+
+ if (bytes_to_clean > 0)
+ {
+ if (bytes_to_write > 0)
+ {
+ #ifdef DEBUG
+ fprintf(stderr, "XRenderCompositeText8: found %d clean bytes, bytes_to_clean are %d,"
+ " this_chars %d.\n", bytes_to_write, bytes_to_clean, this_chars);
+ #endif
+
+ Data (dpy, chars, bytes_to_write);
+ chars += bytes_to_write;
+ }
+
+ bytes_to_write = this_chars % 4;
+ memcpy (tmpChar, chars, bytes_to_write);
+ chars += bytes_to_write;
+
+ #ifdef DEBUG
+ fprintf(stderr, "XRenderCompositeText8: last 32 bit, bytes_to_write are %d,"
+ " bytes_to_clean are %d, this_chars are %d.\n", bytes_to_write, bytes_to_clean, this_chars);
+ #endif
+
+ #ifdef DUMP
+ fprintf(stderr, "XRenderCompositeText8: bytes_to_clean %d, ", bytes_to_clean);
+ #endif
+
+ while (bytes_to_clean > 0)
+ {
+ tmpChar[4 - bytes_to_clean] = 0;
+ bytes_to_clean--;
+
+ #ifdef DEBUG
+ fprintf(stderr, "XRenderCompositeText8: Cleaned %d byte.\n", 4 - bytes_to_clean);
+ #endif
+ }
+
+ Data (dpy, tmpChar, 4);
+ nchars -= this_chars;
+
+ #ifdef DUMP
+ fprintf(stderr, "Data: ");
+ for (i = 0; i < 4; i++)
+ {
+ fprintf(stderr, "[%d]", tmpChar[i]);
+ }
+ fprintf(stderr,"\n");
+ #endif
+
+ #ifdef DEBUG
+ fprintf(stderr, "XRenderCompositeText8: nchars now is %d.\n", nchars);
+ #endif
+
+ continue;
+ }
+
+ #endif /* NX_RENDER_CLEANUP */
+
+ 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;
+
+ #ifdef NX_RENDER_CLEANUP
+
+ int bytes_to_write;
+ int bytes_to_clean;
+ char tmpChar[4];
+
+ #endif /* NX_RENDER_CLEANUP */
+
+ 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));
+
+ #ifdef NX_RENDER_CLEANUP
+
+ elt->pad1 = 0;
+ elt->pad2 = 0;
+
+ #endif /* NX_RENDER_CLEANUP */
+
+ 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))
+
+ #ifdef NX_RENDER_CLEANUP
+
+ elt->pad1 = 0;
+ elt->pad2 = 0;
+
+ #endif /* NX_RENDER_CLEANUP */
+
+ elt->len = this_chars;
+ elt->deltax = xDst;
+ elt->deltay = yDst;
+ xDst = 0;
+ yDst = 0;
+
+ #ifdef NX_RENDER_CLEANUP
+
+ bytes_to_write = this_bytes & ~3;
+ bytes_to_clean = ((this_bytes + 3) & ~3) - this_bytes;
+
+ #ifdef DEBUG
+ fprintf(stderr, "XRenderCompositeText16: this_chars %d, this_bytes %d.\n"
+ "bytes_to_write %d, bytes_to_clean are %d.\n", this_chars, this_bytes,
+ bytes_to_write, bytes_to_clean);
+ #endif
+
+ if (bytes_to_clean > 0)
+ {
+ if (bytes_to_write > 0)
+ {
+ Data16 (dpy, chars, bytes_to_write);
+
+ /*
+ * Cast chars to avoid errors with pointer arithmetic.
+ */
+
+ chars = (unsigned short *) ((char *) chars + bytes_to_write);
+ }
+
+ bytes_to_write = this_bytes % 4;
+ memcpy (tmpChar, (char *) chars, bytes_to_write);
+ chars = (unsigned short *) ((char *) chars + bytes_to_write);
+
+ #ifdef DEBUG
+ fprintf(stderr, "XRenderCompositeText16: last 32 bit, bytes_to_write are %d,"
+ " bytes_to_clean are %d.\n", bytes_to_write, bytes_to_clean);
+ #endif
+
+ while (bytes_to_clean > 0)
+ {
+ tmpChar[4 - bytes_to_clean] = 0;
+ bytes_to_clean--;
+
+ #ifdef DEBUG
+ fprintf(stderr, "XRenderCompositeText16: Cleaned %d byte.\n", 4 - bytes_to_clean);
+ #endif
+ }
+
+ Data16 (dpy, tmpChar, 4);
+ nchars -= this_chars;
+
+ #ifdef DEBUG
+ fprintf(stderr, "XRenderCompositeText16: nchars now is %d.\n", nchars);
+ #endif
+
+ continue;
+ }
+
+ #endif /* NX_RENDER_CLEANUP */
+
+ 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));
+
+ #ifdef NX_RENDER_CLEANUP
+
+ elt->pad1 = 0;
+ elt->pad2 = 0;
+
+ #endif /* NX_RENDER_CLEANUP */
+
+ 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))
+
+ #ifdef NX_RENDER_CLEANUP
+
+ elt->pad1 = 0;
+ elt->pad2 = 0;
+
+ #endif /* NX_RENDER_CLEANUP */
+
+ elt->len = this_chars;
+ elt->deltax = xDst;
+ elt->deltay = yDst;
+ xDst = 0;
+ yDst = 0;
+
+ #ifdef TEST
+ fprintf(stderr, "XRenderCompositeText32: this_chars %d, this_bytes %d.\n",
+ this_chars, this_bytes);
+ #endif
+
+ DataInt32 (dpy, chars, this_bytes);
+ nchars -= this_chars;
+ chars += this_chars;
+ }
+ }
+#undef MAX_32
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+}