11f0ac6a5Smrg/*
21f0ac6a5Smrg *
31f0ac6a5Smrg * Copyright © 2000 SuSE, Inc.
41f0ac6a5Smrg *
51f0ac6a5Smrg * Permission to use, copy, modify, distribute, and sell this software and its
61f0ac6a5Smrg * documentation for any purpose is hereby granted without fee, provided that
71f0ac6a5Smrg * the above copyright notice appear in all copies and that both that
81f0ac6a5Smrg * copyright notice and this permission notice appear in supporting
91f0ac6a5Smrg * documentation, and that the name of SuSE not be used in advertising or
101f0ac6a5Smrg * publicity pertaining to distribution of the software without specific,
111f0ac6a5Smrg * written prior permission.  SuSE makes no representations about the
121f0ac6a5Smrg * suitability of this software for any purpose.  It is provided "as is"
131f0ac6a5Smrg * without express or implied warranty.
141f0ac6a5Smrg *
151f0ac6a5Smrg * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
161f0ac6a5Smrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
171f0ac6a5Smrg * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
181f0ac6a5Smrg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
196fae4e5dSmrg * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
201f0ac6a5Smrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
211f0ac6a5Smrg *
221f0ac6a5Smrg * Author:  Keith Packard, SuSE, Inc.
231f0ac6a5Smrg */
241f0ac6a5Smrg
251f0ac6a5Smrg#ifdef HAVE_CONFIG_H
261f0ac6a5Smrg#include <config.h>
271f0ac6a5Smrg#endif
281f0ac6a5Smrg#include "Xrenderint.h"
291f0ac6a5Smrg
301f0ac6a5SmrgGlyphSet
311f0ac6a5SmrgXRenderCreateGlyphSet (Display *dpy, _Xconst XRenderPictFormat *format)
321f0ac6a5Smrg{
33d21ab8bcSmrg    XRenderExtDisplayInfo	*info = XRenderFindDisplay (dpy);
341f0ac6a5Smrg    GlyphSet			gsid;
351f0ac6a5Smrg    xRenderCreateGlyphSetReq	*req;
361f0ac6a5Smrg
371f0ac6a5Smrg    RenderCheckExtension (dpy, info, 0);
381f0ac6a5Smrg    LockDisplay(dpy);
391f0ac6a5Smrg    GetReq(RenderCreateGlyphSet, req);
40d21ab8bcSmrg    req->reqType = (CARD8) info->codes->major_opcode;
411f0ac6a5Smrg    req->renderReqType = X_RenderCreateGlyphSet;
42d21ab8bcSmrg    req->gsid = (CARD32) (gsid = XAllocID(dpy));
43d21ab8bcSmrg    req->format = (CARD32) format->id;
441f0ac6a5Smrg    UnlockDisplay(dpy);
451f0ac6a5Smrg    SyncHandle();
461f0ac6a5Smrg    return gsid;
471f0ac6a5Smrg}
481f0ac6a5Smrg
491f0ac6a5SmrgGlyphSet
501f0ac6a5SmrgXRenderReferenceGlyphSet (Display *dpy, GlyphSet existing)
511f0ac6a5Smrg{
52d21ab8bcSmrg    XRenderExtDisplayInfo       *info = XRenderFindDisplay (dpy);
531f0ac6a5Smrg    GlyphSet                    gsid;
541f0ac6a5Smrg    xRenderReferenceGlyphSetReq	*req;
551f0ac6a5Smrg
561f0ac6a5Smrg    RenderCheckExtension (dpy, info, 0);
571f0ac6a5Smrg    LockDisplay(dpy);
581f0ac6a5Smrg    GetReq(RenderReferenceGlyphSet, req);
59d21ab8bcSmrg    req->reqType = (CARD8) info->codes->major_opcode;
601f0ac6a5Smrg    req->renderReqType = X_RenderReferenceGlyphSet;
61d21ab8bcSmrg    req->gsid = (CARD32) (gsid = XAllocID(dpy));
62d21ab8bcSmrg    req->existing = (CARD32) existing;
631f0ac6a5Smrg    UnlockDisplay(dpy);
641f0ac6a5Smrg    SyncHandle();
651f0ac6a5Smrg    return gsid;
661f0ac6a5Smrg}
671f0ac6a5Smrg
681f0ac6a5Smrgvoid
691f0ac6a5SmrgXRenderFreeGlyphSet (Display *dpy, GlyphSet glyphset)
701f0ac6a5Smrg{
71d21ab8bcSmrg    XRenderExtDisplayInfo   *info = XRenderFindDisplay (dpy);
721f0ac6a5Smrg    xRenderFreeGlyphSetReq  *req;
731f0ac6a5Smrg
741f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
751f0ac6a5Smrg    LockDisplay(dpy);
761f0ac6a5Smrg    GetReq(RenderFreeGlyphSet, req);
77d21ab8bcSmrg    req->reqType = (CARD8) info->codes->major_opcode;
781f0ac6a5Smrg    req->renderReqType = X_RenderFreeGlyphSet;
79d21ab8bcSmrg    req->glyphset = (CARD32) glyphset;
801f0ac6a5Smrg    UnlockDisplay(dpy);
811f0ac6a5Smrg    SyncHandle();
821f0ac6a5Smrg}
831f0ac6a5Smrg
841f0ac6a5Smrgvoid
851f0ac6a5SmrgXRenderAddGlyphs (Display	*dpy,
861f0ac6a5Smrg		  GlyphSet	glyphset,
871f0ac6a5Smrg		  _Xconst Glyph		*gids,
881f0ac6a5Smrg		  _Xconst XGlyphInfo	*glyphs,
891f0ac6a5Smrg		  int		nglyphs,
901f0ac6a5Smrg		  _Xconst char		*images,
911f0ac6a5Smrg		  int		nbyte_images)
921f0ac6a5Smrg{
93d21ab8bcSmrg    XRenderExtDisplayInfo   *info = XRenderFindDisplay (dpy);
941f0ac6a5Smrg    xRenderAddGlyphsReq	    *req;
951f0ac6a5Smrg    long		    len;
961f0ac6a5Smrg
971f0ac6a5Smrg    if (nbyte_images & 3)
981f0ac6a5Smrg	nbyte_images += 4 - (nbyte_images & 3);
991f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
1001f0ac6a5Smrg    LockDisplay(dpy);
1011f0ac6a5Smrg    GetReq(RenderAddGlyphs, req);
102d21ab8bcSmrg    req->reqType = (CARD8) info->codes->major_opcode;
1031f0ac6a5Smrg    req->renderReqType = X_RenderAddGlyphs;
104d21ab8bcSmrg    req->glyphset = (CARD32) glyphset;
105d21ab8bcSmrg    req->nglyphs = (CARD32) nglyphs;
1061f0ac6a5Smrg    len = (nglyphs * (SIZEOF (xGlyphInfo) + 4) + nbyte_images) >> 2;
1071f0ac6a5Smrg    SetReqLen(req, len, len);
108d21ab8bcSmrg    Data32 (dpy, (_Xconst long *) gids, nglyphs * 4);
109d21ab8bcSmrg    Data16 (dpy, (_Xconst short *) glyphs, nglyphs * SIZEOF (xGlyphInfo));
1101f0ac6a5Smrg    Data (dpy, images, nbyte_images);
1111f0ac6a5Smrg    UnlockDisplay(dpy);
1121f0ac6a5Smrg    SyncHandle();
1131f0ac6a5Smrg}
1141f0ac6a5Smrg
1151f0ac6a5Smrgvoid
1161f0ac6a5SmrgXRenderFreeGlyphs (Display   *dpy,
1171f0ac6a5Smrg		   GlyphSet  glyphset,
1181f0ac6a5Smrg		   _Xconst Glyph     *gids,
1191f0ac6a5Smrg		   int       nglyphs)
1201f0ac6a5Smrg{
121d21ab8bcSmrg    XRenderExtDisplayInfo   *info = XRenderFindDisplay (dpy);
1221f0ac6a5Smrg    xRenderFreeGlyphsReq    *req;
1231f0ac6a5Smrg    long                    len;
1241f0ac6a5Smrg
1251f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
1261f0ac6a5Smrg    LockDisplay(dpy);
1271f0ac6a5Smrg    GetReq(RenderFreeGlyphs, req);
128d21ab8bcSmrg    req->reqType = (CARD8) info->codes->major_opcode;
1291f0ac6a5Smrg    req->renderReqType = X_RenderFreeGlyphs;
130d21ab8bcSmrg    req->glyphset = (CARD32) glyphset;
1311f0ac6a5Smrg    len = nglyphs;
1321f0ac6a5Smrg    SetReqLen(req, len, len);
1331f0ac6a5Smrg    len <<= 2;
134d21ab8bcSmrg    Data32 (dpy, (_Xconst long *) gids, len);
1351f0ac6a5Smrg    UnlockDisplay(dpy);
1361f0ac6a5Smrg    SyncHandle();
1371f0ac6a5Smrg}
1386fae4e5dSmrg
1391f0ac6a5Smrgvoid
1401f0ac6a5SmrgXRenderCompositeString8 (Display	    *dpy,
1411f0ac6a5Smrg			 int		    op,
1421f0ac6a5Smrg			 Picture	    src,
1431f0ac6a5Smrg			 Picture	    dst,
1441f0ac6a5Smrg			 _Xconst XRenderPictFormat  *maskFormat,
1451f0ac6a5Smrg			 GlyphSet	    glyphset,
1461f0ac6a5Smrg			 int		    xSrc,
1471f0ac6a5Smrg			 int		    ySrc,
1481f0ac6a5Smrg			 int		    xDst,
1491f0ac6a5Smrg			 int		    yDst,
1501f0ac6a5Smrg			 _Xconst char	    *string,
1511f0ac6a5Smrg			 int		    nchar)
1521f0ac6a5Smrg{
153d21ab8bcSmrg    XRenderExtDisplayInfo	*info = XRenderFindDisplay (dpy);
1541f0ac6a5Smrg    xRenderCompositeGlyphs8Req	*req;
1551f0ac6a5Smrg    long			len;
1561f0ac6a5Smrg    xGlyphElt			*elt;
1571f0ac6a5Smrg    int				nbytes;
1581f0ac6a5Smrg
1591f0ac6a5Smrg    if (!nchar)
1601f0ac6a5Smrg	return;
1616fae4e5dSmrg
1621f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
1631f0ac6a5Smrg    LockDisplay(dpy);
1641f0ac6a5Smrg
1651f0ac6a5Smrg    GetReq(RenderCompositeGlyphs8, req);
166d21ab8bcSmrg    req->reqType = (CARD8) info->codes->major_opcode;
1671f0ac6a5Smrg    req->renderReqType = X_RenderCompositeGlyphs8;
168d21ab8bcSmrg    req->op = (CARD8) op;
169d21ab8bcSmrg    req->src = (CARD32) src;
170d21ab8bcSmrg    req->dst = (CARD32) dst;
171d21ab8bcSmrg    req->maskFormat = (CARD32) (maskFormat ? maskFormat->id : None);
172d21ab8bcSmrg    req->glyphset = (CARD32) glyphset;
173d21ab8bcSmrg    req->xSrc = (INT16) xSrc;
174d21ab8bcSmrg    req->ySrc = (INT16) ySrc;
1751f0ac6a5Smrg
1761f0ac6a5Smrg    /*
1771f0ac6a5Smrg     * xGlyphElt must be aligned on a 32-bit boundary; this is
1781f0ac6a5Smrg     * easily done by filling no more than 252 glyphs in each
1791f0ac6a5Smrg     * bucket
1801f0ac6a5Smrg     */
1816fae4e5dSmrg
1821f0ac6a5Smrg#define MAX_8 252
1831f0ac6a5Smrg
1841f0ac6a5Smrg    len = SIZEOF(xGlyphElt) * ((nchar + MAX_8-1) / MAX_8) + nchar;
1856fae4e5dSmrg
186d21ab8bcSmrg    req->length = (CARD16) (req->length + ((len + 3)>>2));  /* convert to number of 32-bit words */
1876fae4e5dSmrg
1886fae4e5dSmrg    /*
1891f0ac6a5Smrg     * If the entire request does not fit into the remaining space in the
1901f0ac6a5Smrg     * buffer, flush the buffer first.
1911f0ac6a5Smrg     */
1921f0ac6a5Smrg
1931f0ac6a5Smrg    if (dpy->bufptr + len > dpy->bufmax)
1941f0ac6a5Smrg    	_XFlush (dpy);
1951f0ac6a5Smrg
1961f0ac6a5Smrg    while(nchar > MAX_8)
1971f0ac6a5Smrg    {
1981f0ac6a5Smrg	nbytes = MAX_8 + SIZEOF(xGlyphElt);
1991f0ac6a5Smrg	BufAlloc (xGlyphElt *, elt, nbytes);
2001f0ac6a5Smrg	elt->len = MAX_8;
201d21ab8bcSmrg	elt->deltax = (INT16) xDst;
202d21ab8bcSmrg	elt->deltay = (INT16) yDst;
2031f0ac6a5Smrg	xDst = 0;
2041f0ac6a5Smrg	yDst = 0;
2051f0ac6a5Smrg	memcpy ((char *) (elt + 1), string, MAX_8);
2061f0ac6a5Smrg	nchar = nchar - MAX_8;
2071f0ac6a5Smrg	string += MAX_8;
2081f0ac6a5Smrg    }
2096fae4e5dSmrg
2101f0ac6a5Smrg    if (nchar)
2111f0ac6a5Smrg    {
2121f0ac6a5Smrg	nbytes = (nchar + SIZEOF(xGlyphElt) + 3) & ~3;
2136fae4e5dSmrg	BufAlloc (xGlyphElt *, elt, nbytes);
214d21ab8bcSmrg	elt->len = (CARD8) nchar;
215d21ab8bcSmrg	elt->deltax = (INT16) xDst;
216d21ab8bcSmrg	elt->deltay = (INT16) yDst;
217d21ab8bcSmrg	memcpy ((char *) (elt + 1), string, (size_t) nchar);
2181f0ac6a5Smrg    }
2191f0ac6a5Smrg#undef MAX_8
2206fae4e5dSmrg
2211f0ac6a5Smrg    UnlockDisplay(dpy);
2221f0ac6a5Smrg    SyncHandle();
2231f0ac6a5Smrg}
2241f0ac6a5Smrgvoid
2251f0ac6a5SmrgXRenderCompositeString16 (Display	    *dpy,
2261f0ac6a5Smrg			  int		    op,
2271f0ac6a5Smrg			  Picture	    src,
2281f0ac6a5Smrg			  Picture	    dst,
2291f0ac6a5Smrg			  _Xconst XRenderPictFormat *maskFormat,
2301f0ac6a5Smrg			  GlyphSet	    glyphset,
2311f0ac6a5Smrg			  int		    xSrc,
2321f0ac6a5Smrg			  int		    ySrc,
2331f0ac6a5Smrg			  int		    xDst,
2341f0ac6a5Smrg			  int		    yDst,
2351f0ac6a5Smrg			  _Xconst unsigned short    *string,
2361f0ac6a5Smrg			  int		    nchar)
2371f0ac6a5Smrg{
238d21ab8bcSmrg    XRenderExtDisplayInfo	*info = XRenderFindDisplay (dpy);
2391f0ac6a5Smrg    xRenderCompositeGlyphs8Req	*req;
2401f0ac6a5Smrg    long			len;
2411f0ac6a5Smrg    xGlyphElt			*elt;
2421f0ac6a5Smrg    int				nbytes;
2431f0ac6a5Smrg
2441f0ac6a5Smrg    if (!nchar)
2451f0ac6a5Smrg	return;
2466fae4e5dSmrg
2471f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
2481f0ac6a5Smrg    LockDisplay(dpy);
2496fae4e5dSmrg
2501f0ac6a5Smrg    GetReq(RenderCompositeGlyphs16, req);
251d21ab8bcSmrg    req->reqType = (CARD8) info->codes->major_opcode;
2521f0ac6a5Smrg    req->renderReqType = X_RenderCompositeGlyphs16;
253d21ab8bcSmrg    req->op = (CARD8) op;
254d21ab8bcSmrg    req->src = (CARD32) src;
255d21ab8bcSmrg    req->dst = (CARD32) dst;
256d21ab8bcSmrg    req->maskFormat = (CARD32) (maskFormat ? maskFormat->id : None);
257d21ab8bcSmrg    req->glyphset = (CARD32) glyphset;
258d21ab8bcSmrg    req->xSrc = (INT16) xSrc;
259d21ab8bcSmrg    req->ySrc = (INT16) ySrc;
2601f0ac6a5Smrg
2611f0ac6a5Smrg#define MAX_16	254
2621f0ac6a5Smrg
2631f0ac6a5Smrg    len = SIZEOF(xGlyphElt) * ((nchar + MAX_16-1) / MAX_16) + nchar * 2;
2646fae4e5dSmrg
265d21ab8bcSmrg    req->length = (CARD16) (req->length + ((len + 3)>>2));  /* convert to number of 32-bit words */
2666fae4e5dSmrg
2676fae4e5dSmrg    /*
2681f0ac6a5Smrg     * If the entire request does not fit into the remaining space in the
2691f0ac6a5Smrg     * buffer, flush the buffer first.
2701f0ac6a5Smrg     */
2711f0ac6a5Smrg
2721f0ac6a5Smrg    if (dpy->bufptr + len > dpy->bufmax)
2731f0ac6a5Smrg    	_XFlush (dpy);
2741f0ac6a5Smrg
2751f0ac6a5Smrg    while(nchar > MAX_16)
2761f0ac6a5Smrg    {
2771f0ac6a5Smrg	nbytes = MAX_16 * 2 + SIZEOF(xGlyphElt);
2781f0ac6a5Smrg	BufAlloc (xGlyphElt *, elt, nbytes);
2791f0ac6a5Smrg	elt->len = MAX_16;
280d21ab8bcSmrg	elt->deltax = (INT16) xDst;
281d21ab8bcSmrg	elt->deltay = (INT16) yDst;
2821f0ac6a5Smrg	xDst = 0;
2831f0ac6a5Smrg	yDst = 0;
284d21ab8bcSmrg	memcpy ((char *) (elt + 1), (_Xconst char *) string, MAX_16 * 2);
2851f0ac6a5Smrg	nchar = nchar - MAX_16;
2861f0ac6a5Smrg	string += MAX_16;
2871f0ac6a5Smrg    }
2886fae4e5dSmrg
2891f0ac6a5Smrg    if (nchar)
2901f0ac6a5Smrg    {
2911f0ac6a5Smrg	nbytes = (nchar * 2 + SIZEOF(xGlyphElt) + 3) & ~3;
2926fae4e5dSmrg	BufAlloc (xGlyphElt *, elt, nbytes);
293d21ab8bcSmrg	elt->len = (CARD8) nchar;
294d21ab8bcSmrg	elt->deltax = (INT16) xDst;
295d21ab8bcSmrg	elt->deltay = (INT16) yDst;
296d21ab8bcSmrg	memcpy ((char *) (elt + 1), (_Xconst char *) string, (size_t) (nchar * 2));
2971f0ac6a5Smrg    }
2981f0ac6a5Smrg#undef MAX_16
2996fae4e5dSmrg
3001f0ac6a5Smrg    UnlockDisplay(dpy);
3011f0ac6a5Smrg    SyncHandle();
3021f0ac6a5Smrg}
3031f0ac6a5Smrg
3041f0ac6a5Smrgvoid
3051f0ac6a5SmrgXRenderCompositeString32 (Display	    *dpy,
3061f0ac6a5Smrg			  int		    op,
3071f0ac6a5Smrg			  Picture	    src,
3081f0ac6a5Smrg			  Picture	    dst,
3091f0ac6a5Smrg			  _Xconst XRenderPictFormat  *maskFormat,
3101f0ac6a5Smrg			  GlyphSet	    glyphset,
3111f0ac6a5Smrg			  int		    xSrc,
3121f0ac6a5Smrg			  int		    ySrc,
3131f0ac6a5Smrg			  int		    xDst,
3141f0ac6a5Smrg			  int		    yDst,
3151f0ac6a5Smrg			  _Xconst unsigned int	    *string,
3161f0ac6a5Smrg			  int		    nchar)
3171f0ac6a5Smrg{
318d21ab8bcSmrg    XRenderExtDisplayInfo	*info = XRenderFindDisplay (dpy);
3191f0ac6a5Smrg    xRenderCompositeGlyphs8Req	*req;
3201f0ac6a5Smrg    long			len;
3211f0ac6a5Smrg    xGlyphElt			*elt;
3221f0ac6a5Smrg    int				nbytes;
3231f0ac6a5Smrg
3241f0ac6a5Smrg    if (!nchar)
3251f0ac6a5Smrg	return;
3266fae4e5dSmrg
3271f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
3281f0ac6a5Smrg    LockDisplay(dpy);
3296fae4e5dSmrg
3301f0ac6a5Smrg    GetReq(RenderCompositeGlyphs32, req);
331d21ab8bcSmrg    req->reqType = (CARD8) info->codes->major_opcode;
3321f0ac6a5Smrg    req->renderReqType = X_RenderCompositeGlyphs32;
333d21ab8bcSmrg    req->op = (CARD8) op;
334d21ab8bcSmrg    req->src = (CARD32) src;
335d21ab8bcSmrg    req->dst = (CARD32) dst;
336d21ab8bcSmrg    req->maskFormat = (CARD32) (maskFormat ? maskFormat->id : None);
337d21ab8bcSmrg    req->glyphset = (CARD32) glyphset;
338d21ab8bcSmrg    req->xSrc = (INT16) xSrc;
339d21ab8bcSmrg    req->ySrc = (INT16) ySrc;
3401f0ac6a5Smrg
3411f0ac6a5Smrg#define MAX_32	254
3421f0ac6a5Smrg
3431f0ac6a5Smrg    len = SIZEOF(xGlyphElt) * ((nchar + MAX_32-1) / MAX_32) + nchar * 4;
3446fae4e5dSmrg
345d21ab8bcSmrg    req->length = (CARD16) (req->length + ((len + 3)>>2));  /* convert to number of 32-bit words */
3466fae4e5dSmrg
3476fae4e5dSmrg    /*
3481f0ac6a5Smrg     * If the entire request does not fit into the remaining space in the
3491f0ac6a5Smrg     * buffer, flush the buffer first.
3501f0ac6a5Smrg     */
3511f0ac6a5Smrg
3521f0ac6a5Smrg    if (dpy->bufptr + len > dpy->bufmax)
3531f0ac6a5Smrg    	_XFlush (dpy);
3541f0ac6a5Smrg
3551f0ac6a5Smrg    while(nchar > MAX_32)
3561f0ac6a5Smrg    {
3571f0ac6a5Smrg	nbytes = MAX_32 * 4 + SIZEOF(xGlyphElt);
3581f0ac6a5Smrg	BufAlloc (xGlyphElt *, elt, nbytes);
3591f0ac6a5Smrg	elt->len = MAX_32;
360d21ab8bcSmrg	elt->deltax = (INT16) xDst;
361d21ab8bcSmrg	elt->deltay = (INT16) yDst;
3621f0ac6a5Smrg	xDst = 0;
3631f0ac6a5Smrg	yDst = 0;
364d21ab8bcSmrg	memcpy ((char *) (elt + 1), (_Xconst char *) string, MAX_32 * 4);
3651f0ac6a5Smrg	nchar = nchar - MAX_32;
3661f0ac6a5Smrg	string += MAX_32;
3671f0ac6a5Smrg    }
3686fae4e5dSmrg
3691f0ac6a5Smrg    if (nchar)
3701f0ac6a5Smrg    {
3711f0ac6a5Smrg	nbytes = nchar * 4 + SIZEOF(xGlyphElt);
3726fae4e5dSmrg	BufAlloc (xGlyphElt *, elt, nbytes);
373d21ab8bcSmrg	elt->len = (CARD8) nchar;
374d21ab8bcSmrg	elt->deltax = (INT16) xDst;
375d21ab8bcSmrg	elt->deltay = (INT16) yDst;
376d21ab8bcSmrg	memcpy ((char *) (elt + 1), (_Xconst char *) string, (size_t) (nchar * 4));
3771f0ac6a5Smrg    }
3781f0ac6a5Smrg#undef MAX_32
3796fae4e5dSmrg
3801f0ac6a5Smrg    UnlockDisplay(dpy);
3811f0ac6a5Smrg    SyncHandle();
3821f0ac6a5Smrg}
3831f0ac6a5Smrg
3841f0ac6a5Smrgvoid
3851f0ac6a5SmrgXRenderCompositeText8 (Display			    *dpy,
3861f0ac6a5Smrg		       int			    op,
3871f0ac6a5Smrg		       Picture			    src,
3881f0ac6a5Smrg		       Picture			    dst,
3891f0ac6a5Smrg		       _Xconst XRenderPictFormat    *maskFormat,
3901f0ac6a5Smrg		       int			    xSrc,
3911f0ac6a5Smrg		       int			    ySrc,
3921f0ac6a5Smrg		       int			    xDst,
3931f0ac6a5Smrg		       int			    yDst,
3941f0ac6a5Smrg		       _Xconst XGlyphElt8	    *elts,
3951f0ac6a5Smrg		       int			    nelt)
3961f0ac6a5Smrg{
397d21ab8bcSmrg    XRenderExtDisplayInfo	*info = XRenderFindDisplay (dpy);
3981f0ac6a5Smrg    xRenderCompositeGlyphs8Req	*req;
3991f0ac6a5Smrg    GlyphSet			glyphset;
4001f0ac6a5Smrg    long			len;
4011f0ac6a5Smrg    int				i;
4021f0ac6a5Smrg
4031f0ac6a5Smrg    if (!nelt)
4041f0ac6a5Smrg	return;
4056fae4e5dSmrg
4061f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
4071f0ac6a5Smrg    LockDisplay(dpy);
4081f0ac6a5Smrg
4091f0ac6a5Smrg    GetReq(RenderCompositeGlyphs8, req);
410d21ab8bcSmrg    req->reqType = (CARD8) info->codes->major_opcode;
4111f0ac6a5Smrg    req->renderReqType = X_RenderCompositeGlyphs8;
412d21ab8bcSmrg    req->op = (CARD8) op;
413d21ab8bcSmrg    req->src = (CARD32) src;
414d21ab8bcSmrg    req->dst = (CARD32) dst;
415d21ab8bcSmrg    req->maskFormat = (CARD32) (maskFormat ? maskFormat->id : None);
416d21ab8bcSmrg    req->glyphset = (CARD32) elts[0].glyphset;
417d21ab8bcSmrg    req->xSrc = (INT16) xSrc;
418d21ab8bcSmrg    req->ySrc = (INT16) ySrc;
4191f0ac6a5Smrg
4201f0ac6a5Smrg    /*
4211f0ac6a5Smrg     * Compute the space necessary
4221f0ac6a5Smrg     */
4231f0ac6a5Smrg    len = 0;
4246fae4e5dSmrg
4251f0ac6a5Smrg#define MAX_8 252
4261f0ac6a5Smrg
4271f0ac6a5Smrg    glyphset = elts[0].glyphset;
4281f0ac6a5Smrg    for (i = 0; i < nelt; i++)
4291f0ac6a5Smrg    {
430d21ab8bcSmrg	long	elen;
431d21ab8bcSmrg	int	nchars;
432d21ab8bcSmrg
4331f0ac6a5Smrg	/*
4341f0ac6a5Smrg	 * Check for glyphset change
4351f0ac6a5Smrg	 */
4361f0ac6a5Smrg	if (elts[i].glyphset != glyphset)
4371f0ac6a5Smrg	{
4381f0ac6a5Smrg	    glyphset = elts[i].glyphset;
4391f0ac6a5Smrg	    len += (SIZEOF (xGlyphElt) + 4) >> 2;
4401f0ac6a5Smrg	}
4411f0ac6a5Smrg	nchars = elts[i].nchars;
4421f0ac6a5Smrg	/*
4431f0ac6a5Smrg	 * xGlyphElt must be aligned on a 32-bit boundary; this is
4441f0ac6a5Smrg	 * easily done by filling no more than 252 glyphs in each
4451f0ac6a5Smrg	 * bucket
4461f0ac6a5Smrg	 */
4471f0ac6a5Smrg	elen = SIZEOF(xGlyphElt) * ((nchars + MAX_8-1) / MAX_8) + nchars;
4481f0ac6a5Smrg	len += (elen + 3) >> 2;
4491f0ac6a5Smrg    }
4506fae4e5dSmrg
451d21ab8bcSmrg    req->length = (CARD16) (req->length + len);
4521f0ac6a5Smrg
4531f0ac6a5Smrg    /*
4541f0ac6a5Smrg     * Send the glyphs
4551f0ac6a5Smrg     */
4561f0ac6a5Smrg    glyphset = elts[0].glyphset;
4571f0ac6a5Smrg    for (i = 0; i < nelt; i++)
4581f0ac6a5Smrg    {
459d21ab8bcSmrg	xGlyphElt	*elt;
460d21ab8bcSmrg	_Xconst char	*chars;
461d21ab8bcSmrg	int		nchars;
462d21ab8bcSmrg
4631f0ac6a5Smrg	/*
4641f0ac6a5Smrg	 * Switch glyphsets
4651f0ac6a5Smrg	 */
4661f0ac6a5Smrg	if (elts[i].glyphset != glyphset)
4671f0ac6a5Smrg	{
4681f0ac6a5Smrg	    glyphset = elts[i].glyphset;
4691f0ac6a5Smrg	    BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
4701f0ac6a5Smrg	    elt->len = 0xff;
4711f0ac6a5Smrg	    elt->deltax = 0;
4721f0ac6a5Smrg	    elt->deltay = 0;
4731f0ac6a5Smrg	    Data32(dpy, &glyphset, 4);
4741f0ac6a5Smrg	}
4751f0ac6a5Smrg	nchars = elts[i].nchars;
4761f0ac6a5Smrg	xDst = elts[i].xOff;
4771f0ac6a5Smrg	yDst = elts[i].yOff;
4781f0ac6a5Smrg	chars = elts[i].chars;
4791f0ac6a5Smrg	while (nchars)
4801f0ac6a5Smrg	{
4811f0ac6a5Smrg	    int this_chars = nchars > MAX_8 ? MAX_8 : nchars;
4821f0ac6a5Smrg
4836ee7d557Smrg	    BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
484d21ab8bcSmrg	    elt->len = (CARD8) this_chars;
485d21ab8bcSmrg	    elt->deltax = (INT16) xDst;
486d21ab8bcSmrg	    elt->deltay = (INT16) yDst;
4871f0ac6a5Smrg	    xDst = 0;
4881f0ac6a5Smrg	    yDst = 0;
4891f0ac6a5Smrg	    Data (dpy, chars, this_chars);
4901f0ac6a5Smrg	    nchars -= this_chars;
4911f0ac6a5Smrg	    chars += this_chars;
4921f0ac6a5Smrg	}
4931f0ac6a5Smrg    }
4941f0ac6a5Smrg#undef MAX_8
4956fae4e5dSmrg
4961f0ac6a5Smrg    UnlockDisplay(dpy);
4971f0ac6a5Smrg    SyncHandle();
4981f0ac6a5Smrg}
4991f0ac6a5Smrg
5001f0ac6a5Smrgvoid
5011f0ac6a5SmrgXRenderCompositeText16 (Display			    *dpy,
5021f0ac6a5Smrg			int			    op,
5031f0ac6a5Smrg			Picture			    src,
5041f0ac6a5Smrg			Picture			    dst,
5051f0ac6a5Smrg			_Xconst XRenderPictFormat   *maskFormat,
5061f0ac6a5Smrg			int			    xSrc,
5071f0ac6a5Smrg			int			    ySrc,
5081f0ac6a5Smrg			int			    xDst,
5091f0ac6a5Smrg			int			    yDst,
5101f0ac6a5Smrg			_Xconst XGlyphElt16	    *elts,
5111f0ac6a5Smrg			int			    nelt)
5121f0ac6a5Smrg{
513d21ab8bcSmrg    XRenderExtDisplayInfo	*info = XRenderFindDisplay (dpy);
5141f0ac6a5Smrg    xRenderCompositeGlyphs16Req	*req;
5151f0ac6a5Smrg    GlyphSet			glyphset;
5161f0ac6a5Smrg    long			len;
5171f0ac6a5Smrg    int				i;
5181f0ac6a5Smrg
5191f0ac6a5Smrg    if (!nelt)
5201f0ac6a5Smrg	return;
5216fae4e5dSmrg
5221f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
5231f0ac6a5Smrg    LockDisplay(dpy);
5241f0ac6a5Smrg
5251f0ac6a5Smrg    GetReq(RenderCompositeGlyphs16, req);
526d21ab8bcSmrg    req->reqType = (CARD8) info->codes->major_opcode;
5271f0ac6a5Smrg    req->renderReqType = X_RenderCompositeGlyphs16;
528d21ab8bcSmrg    req->op = (CARD8) op;
529d21ab8bcSmrg    req->src = (CARD32) src;
530d21ab8bcSmrg    req->dst = (CARD32) dst;
531d21ab8bcSmrg    req->maskFormat = (CARD32) (maskFormat ? maskFormat->id : None);
532d21ab8bcSmrg    req->glyphset = (CARD32) elts[0].glyphset;
533d21ab8bcSmrg    req->xSrc = (INT16) xSrc;
534d21ab8bcSmrg    req->ySrc = (INT16) ySrc;
5351f0ac6a5Smrg
5361f0ac6a5Smrg    /*
5371f0ac6a5Smrg     * Compute the space necessary
5381f0ac6a5Smrg     */
5391f0ac6a5Smrg    len = 0;
5406fae4e5dSmrg
5411f0ac6a5Smrg#define MAX_16	254
5421f0ac6a5Smrg
5431f0ac6a5Smrg    glyphset = elts[0].glyphset;
5441f0ac6a5Smrg    for (i = 0; i < nelt; i++)
5451f0ac6a5Smrg    {
546d21ab8bcSmrg	int	nchars;
547d21ab8bcSmrg	long	elen;
548d21ab8bcSmrg
5491f0ac6a5Smrg	/*
5501f0ac6a5Smrg	 * Check for glyphset change
5511f0ac6a5Smrg	 */
5521f0ac6a5Smrg	if (elts[i].glyphset != glyphset)
5531f0ac6a5Smrg	{
5541f0ac6a5Smrg	    glyphset = elts[i].glyphset;
5551f0ac6a5Smrg	    len += (SIZEOF (xGlyphElt) + 4) >> 2;
5561f0ac6a5Smrg	}
5571f0ac6a5Smrg	nchars = elts[i].nchars;
5581f0ac6a5Smrg	/*
5591f0ac6a5Smrg	 * xGlyphElt must be aligned on a 32-bit boundary; this is
5601f0ac6a5Smrg	 * easily done by filling no more than 254 glyphs in each
5611f0ac6a5Smrg	 * bucket
5621f0ac6a5Smrg	 */
5631f0ac6a5Smrg	elen = SIZEOF(xGlyphElt) * ((nchars + MAX_16-1) / MAX_16) + nchars * 2;
5641f0ac6a5Smrg	len += (elen + 3) >> 2;
5651f0ac6a5Smrg    }
5666fae4e5dSmrg
567d21ab8bcSmrg    req->length = (CARD16) (req->length + len);
5681f0ac6a5Smrg
5691f0ac6a5Smrg    glyphset = elts[0].glyphset;
5701f0ac6a5Smrg    for (i = 0; i < nelt; i++)
5711f0ac6a5Smrg    {
572d21ab8bcSmrg	xGlyphElt		*elt;
573d21ab8bcSmrg	_Xconst unsigned short	*chars;
574d21ab8bcSmrg	int			nchars;
575d21ab8bcSmrg
5761f0ac6a5Smrg	/*
5771f0ac6a5Smrg	 * Switch glyphsets
5781f0ac6a5Smrg	 */
5791f0ac6a5Smrg	if (elts[i].glyphset != glyphset)
5801f0ac6a5Smrg	{
5811f0ac6a5Smrg	    glyphset = elts[i].glyphset;
5821f0ac6a5Smrg	    BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
5831f0ac6a5Smrg	    elt->len = 0xff;
5841f0ac6a5Smrg	    elt->deltax = 0;
5851f0ac6a5Smrg	    elt->deltay = 0;
5861f0ac6a5Smrg	    Data32(dpy, &glyphset, 4);
5871f0ac6a5Smrg	}
5881f0ac6a5Smrg	nchars = elts[i].nchars;
5891f0ac6a5Smrg	xDst = elts[i].xOff;
5901f0ac6a5Smrg	yDst = elts[i].yOff;
5911f0ac6a5Smrg	chars = elts[i].chars;
5921f0ac6a5Smrg	while (nchars)
5931f0ac6a5Smrg	{
5941f0ac6a5Smrg	    int this_chars = nchars > MAX_16 ? MAX_16 : nchars;
5951f0ac6a5Smrg	    int this_bytes = this_chars * 2;
5966fae4e5dSmrg
5976ee7d557Smrg	    BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
598d21ab8bcSmrg	    elt->len = (CARD8) this_chars;
599d21ab8bcSmrg	    elt->deltax = (INT16) xDst;
600d21ab8bcSmrg	    elt->deltay = (INT16) yDst;
6011f0ac6a5Smrg	    xDst = 0;
6021f0ac6a5Smrg	    yDst = 0;
6031f0ac6a5Smrg	    Data16 (dpy, chars, this_bytes);
6041f0ac6a5Smrg	    nchars -= this_chars;
6051f0ac6a5Smrg	    chars += this_chars;
6061f0ac6a5Smrg	}
6071f0ac6a5Smrg    }
6081f0ac6a5Smrg#undef MAX_16
6096fae4e5dSmrg
6101f0ac6a5Smrg    UnlockDisplay(dpy);
6111f0ac6a5Smrg    SyncHandle();
6121f0ac6a5Smrg}
6131f0ac6a5Smrg
6141f0ac6a5Smrgvoid
6151f0ac6a5SmrgXRenderCompositeText32 (Display			    *dpy,
6161f0ac6a5Smrg			int			    op,
6171f0ac6a5Smrg			Picture			    src,
6181f0ac6a5Smrg			Picture			    dst,
6191f0ac6a5Smrg			_Xconst XRenderPictFormat   *maskFormat,
6201f0ac6a5Smrg			int			    xSrc,
6211f0ac6a5Smrg			int			    ySrc,
6221f0ac6a5Smrg			int			    xDst,
6231f0ac6a5Smrg			int			    yDst,
6241f0ac6a5Smrg			_Xconst XGlyphElt32	    *elts,
6251f0ac6a5Smrg			int			    nelt)
6261f0ac6a5Smrg{
627d21ab8bcSmrg    XRenderExtDisplayInfo	*info = XRenderFindDisplay (dpy);
6281f0ac6a5Smrg    xRenderCompositeGlyphs32Req	*req;
6291f0ac6a5Smrg    GlyphSet			glyphset;
6301f0ac6a5Smrg    long			len;
6311f0ac6a5Smrg    int				i;
6321f0ac6a5Smrg
6331f0ac6a5Smrg    if (!nelt)
6341f0ac6a5Smrg	return;
6356fae4e5dSmrg
6361f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
6371f0ac6a5Smrg    LockDisplay(dpy);
6381f0ac6a5Smrg
6396fae4e5dSmrg
6401f0ac6a5Smrg    GetReq(RenderCompositeGlyphs32, req);
641d21ab8bcSmrg    req->reqType = (CARD8) info->codes->major_opcode;
6421f0ac6a5Smrg    req->renderReqType = X_RenderCompositeGlyphs32;
643d21ab8bcSmrg    req->op = (CARD8) op;
644d21ab8bcSmrg    req->src = (CARD32) src;
645d21ab8bcSmrg    req->dst = (CARD32) dst;
646d21ab8bcSmrg    req->maskFormat = (CARD32) (maskFormat ? maskFormat->id : None);
647d21ab8bcSmrg    req->glyphset = (CARD32) elts[0].glyphset;
648d21ab8bcSmrg    req->xSrc = (INT16) xSrc;
649d21ab8bcSmrg    req->ySrc = (INT16) ySrc;
6501f0ac6a5Smrg
6511f0ac6a5Smrg    /*
6521f0ac6a5Smrg     * Compute the space necessary
6531f0ac6a5Smrg     */
6541f0ac6a5Smrg    len = 0;
6551f0ac6a5Smrg
6561f0ac6a5Smrg#define MAX_32	254
6576fae4e5dSmrg
6581f0ac6a5Smrg    glyphset = elts[0].glyphset;
6591f0ac6a5Smrg    for (i = 0; i < nelt; i++)
6601f0ac6a5Smrg    {
661d21ab8bcSmrg	int	nchars;
662d21ab8bcSmrg	long	elen;
663d21ab8bcSmrg
6641f0ac6a5Smrg	/*
6651f0ac6a5Smrg	 * Check for glyphset change
6661f0ac6a5Smrg	 */
6671f0ac6a5Smrg	if (elts[i].glyphset != glyphset)
6681f0ac6a5Smrg	{
6691f0ac6a5Smrg	    glyphset = elts[i].glyphset;
6701f0ac6a5Smrg	    len += (SIZEOF (xGlyphElt) + 4) >> 2;
6711f0ac6a5Smrg	}
6721f0ac6a5Smrg	nchars = elts[i].nchars;
673b9867631Smrg	elen = SIZEOF(xGlyphElt) * ((nchars + MAX_32-1) / MAX_32) + nchars *4;
6741f0ac6a5Smrg	len += (elen + 3) >> 2;
6751f0ac6a5Smrg    }
6766fae4e5dSmrg
677d21ab8bcSmrg    req->length = (CARD16) (req->length + len);
6781f0ac6a5Smrg
6791f0ac6a5Smrg    glyphset = elts[0].glyphset;
6801f0ac6a5Smrg    for (i = 0; i < nelt; i++)
6811f0ac6a5Smrg    {
682d21ab8bcSmrg	xGlyphElt		*elt;
683d21ab8bcSmrg	_Xconst unsigned int	*chars;
684d21ab8bcSmrg	int			nchars;
685d21ab8bcSmrg
6861f0ac6a5Smrg	/*
6871f0ac6a5Smrg	 * Switch glyphsets
6881f0ac6a5Smrg	 */
6891f0ac6a5Smrg	if (elts[i].glyphset != glyphset)
6901f0ac6a5Smrg	{
6911f0ac6a5Smrg	    glyphset = elts[i].glyphset;
6921f0ac6a5Smrg	    BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
6931f0ac6a5Smrg	    elt->len = 0xff;
6941f0ac6a5Smrg	    elt->deltax = 0;
6951f0ac6a5Smrg	    elt->deltay = 0;
6961f0ac6a5Smrg	    Data32(dpy, &glyphset, 4);
6971f0ac6a5Smrg	}
6981f0ac6a5Smrg	nchars = elts[i].nchars;
6991f0ac6a5Smrg	xDst = elts[i].xOff;
7001f0ac6a5Smrg	yDst = elts[i].yOff;
7011f0ac6a5Smrg	chars = elts[i].chars;
7021f0ac6a5Smrg	while (nchars)
7031f0ac6a5Smrg	{
7041f0ac6a5Smrg	    int this_chars = nchars > MAX_32 ? MAX_32 : nchars;
7051f0ac6a5Smrg	    int this_bytes = this_chars * 4;
7066ee7d557Smrg	    BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
707d21ab8bcSmrg	    elt->len = (CARD8) this_chars;
708d21ab8bcSmrg	    elt->deltax = (INT16) xDst;
709d21ab8bcSmrg	    elt->deltay = (INT16) yDst;
7101f0ac6a5Smrg	    xDst = 0;
7111f0ac6a5Smrg	    yDst = 0;
7121f0ac6a5Smrg	    DataInt32 (dpy, chars, this_bytes);
7131f0ac6a5Smrg	    nchars -= this_chars;
7141f0ac6a5Smrg	    chars += this_chars;
7151f0ac6a5Smrg	}
7161f0ac6a5Smrg    }
7171f0ac6a5Smrg#undef MAX_32
7186fae4e5dSmrg
7191f0ac6a5Smrg    UnlockDisplay(dpy);
7201f0ac6a5Smrg    SyncHandle();
7211f0ac6a5Smrg}
722