Glyph.c revision b9867631
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{
331f0ac6a5Smrg    XRenderExtDisplayInfo		*info = XRenderFindDisplay (dpy);
341f0ac6a5Smrg    GlyphSet			gsid;
351f0ac6a5Smrg    xRenderCreateGlyphSetReq	*req;
361f0ac6a5Smrg
371f0ac6a5Smrg    RenderCheckExtension (dpy, info, 0);
381f0ac6a5Smrg    LockDisplay(dpy);
391f0ac6a5Smrg    GetReq(RenderCreateGlyphSet, req);
401f0ac6a5Smrg    req->reqType = info->codes->major_opcode;
411f0ac6a5Smrg    req->renderReqType = X_RenderCreateGlyphSet;
421f0ac6a5Smrg    req->gsid = gsid = XAllocID(dpy);
431f0ac6a5Smrg    req->format = format->id;
441f0ac6a5Smrg    UnlockDisplay(dpy);
451f0ac6a5Smrg    SyncHandle();
461f0ac6a5Smrg    return gsid;
471f0ac6a5Smrg}
481f0ac6a5Smrg
491f0ac6a5SmrgGlyphSet
501f0ac6a5SmrgXRenderReferenceGlyphSet (Display *dpy, GlyphSet existing)
511f0ac6a5Smrg{
521f0ac6a5Smrg    XRenderExtDisplayInfo             *info = XRenderFindDisplay (dpy);
531f0ac6a5Smrg    GlyphSet                    gsid;
541f0ac6a5Smrg    xRenderReferenceGlyphSetReq	*req;
551f0ac6a5Smrg
561f0ac6a5Smrg    RenderCheckExtension (dpy, info, 0);
571f0ac6a5Smrg    LockDisplay(dpy);
581f0ac6a5Smrg    GetReq(RenderReferenceGlyphSet, req);
591f0ac6a5Smrg    req->reqType = info->codes->major_opcode;
601f0ac6a5Smrg    req->renderReqType = X_RenderReferenceGlyphSet;
611f0ac6a5Smrg    req->gsid = gsid = XAllocID(dpy);
621f0ac6a5Smrg    req->existing = existing;
631f0ac6a5Smrg    UnlockDisplay(dpy);
641f0ac6a5Smrg    SyncHandle();
651f0ac6a5Smrg    return gsid;
661f0ac6a5Smrg}
671f0ac6a5Smrg
681f0ac6a5Smrgvoid
691f0ac6a5SmrgXRenderFreeGlyphSet (Display *dpy, GlyphSet glyphset)
701f0ac6a5Smrg{
711f0ac6a5Smrg    XRenderExtDisplayInfo         *info = XRenderFindDisplay (dpy);
721f0ac6a5Smrg    xRenderFreeGlyphSetReq  *req;
731f0ac6a5Smrg
741f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
751f0ac6a5Smrg    LockDisplay(dpy);
761f0ac6a5Smrg    GetReq(RenderFreeGlyphSet, req);
771f0ac6a5Smrg    req->reqType = info->codes->major_opcode;
781f0ac6a5Smrg    req->renderReqType = X_RenderFreeGlyphSet;
791f0ac6a5Smrg    req->glyphset = 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{
931f0ac6a5Smrg    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);
1021f0ac6a5Smrg    req->reqType = info->codes->major_opcode;
1031f0ac6a5Smrg    req->renderReqType = X_RenderAddGlyphs;
1041f0ac6a5Smrg    req->glyphset = glyphset;
1051f0ac6a5Smrg    req->nglyphs = nglyphs;
1061f0ac6a5Smrg    len = (nglyphs * (SIZEOF (xGlyphInfo) + 4) + nbyte_images) >> 2;
1071f0ac6a5Smrg    SetReqLen(req, len, len);
1081f0ac6a5Smrg    Data32 (dpy, (long *) gids, nglyphs * 4);
1091f0ac6a5Smrg    Data16 (dpy, (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{
1211f0ac6a5Smrg    XRenderExtDisplayInfo         *info = XRenderFindDisplay (dpy);
1221f0ac6a5Smrg    xRenderFreeGlyphsReq    *req;
1231f0ac6a5Smrg    long                    len;
1241f0ac6a5Smrg
1251f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
1261f0ac6a5Smrg    LockDisplay(dpy);
1271f0ac6a5Smrg    GetReq(RenderFreeGlyphs, req);
1281f0ac6a5Smrg    req->reqType = info->codes->major_opcode;
1291f0ac6a5Smrg    req->renderReqType = X_RenderFreeGlyphs;
1301f0ac6a5Smrg    req->glyphset = glyphset;
1311f0ac6a5Smrg    len = nglyphs;
1321f0ac6a5Smrg    SetReqLen(req, len, len);
1331f0ac6a5Smrg    len <<= 2;
1341f0ac6a5Smrg    Data32 (dpy, (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{
1531f0ac6a5Smrg    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);
1661f0ac6a5Smrg    req->reqType = info->codes->major_opcode;
1671f0ac6a5Smrg    req->renderReqType = X_RenderCompositeGlyphs8;
1681f0ac6a5Smrg    req->op = op;
1691f0ac6a5Smrg    req->src = src;
1701f0ac6a5Smrg    req->dst = dst;
1711f0ac6a5Smrg    req->maskFormat = maskFormat ? maskFormat->id : None;
1721f0ac6a5Smrg    req->glyphset = glyphset;
1731f0ac6a5Smrg    req->xSrc = xSrc;
1746fae4e5dSmrg    req->ySrc = 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
1861f0ac6a5Smrg    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;
2011f0ac6a5Smrg	elt->deltax = xDst;
2021f0ac6a5Smrg	elt->deltay = 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);
2141f0ac6a5Smrg	elt->len = nchar;
2151f0ac6a5Smrg	elt->deltax = xDst;
2161f0ac6a5Smrg	elt->deltay = yDst;
2171f0ac6a5Smrg	memcpy ((char *) (elt + 1), string, 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{
2381f0ac6a5Smrg    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);
2511f0ac6a5Smrg    req->reqType = info->codes->major_opcode;
2521f0ac6a5Smrg    req->renderReqType = X_RenderCompositeGlyphs16;
2531f0ac6a5Smrg    req->op = op;
2541f0ac6a5Smrg    req->src = src;
2551f0ac6a5Smrg    req->dst = dst;
2561f0ac6a5Smrg    req->maskFormat = maskFormat ? maskFormat->id : None;
2571f0ac6a5Smrg    req->glyphset = glyphset;
2581f0ac6a5Smrg    req->xSrc = xSrc;
2596fae4e5dSmrg    req->ySrc = ySrc;
2601f0ac6a5Smrg
2611f0ac6a5Smrg#define MAX_16	254
2621f0ac6a5Smrg
2631f0ac6a5Smrg    len = SIZEOF(xGlyphElt) * ((nchar + MAX_16-1) / MAX_16) + nchar * 2;
2646fae4e5dSmrg
2651f0ac6a5Smrg    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;
2801f0ac6a5Smrg	elt->deltax = xDst;
2811f0ac6a5Smrg	elt->deltay = yDst;
2821f0ac6a5Smrg	xDst = 0;
2831f0ac6a5Smrg	yDst = 0;
2841f0ac6a5Smrg	memcpy ((char *) (elt + 1), (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);
2931f0ac6a5Smrg	elt->len = nchar;
2941f0ac6a5Smrg	elt->deltax = xDst;
2951f0ac6a5Smrg	elt->deltay = yDst;
2961f0ac6a5Smrg	memcpy ((char *) (elt + 1), (char *) string, 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{
3181f0ac6a5Smrg    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);
3311f0ac6a5Smrg    req->reqType = info->codes->major_opcode;
3321f0ac6a5Smrg    req->renderReqType = X_RenderCompositeGlyphs32;
3331f0ac6a5Smrg    req->op = op;
3341f0ac6a5Smrg    req->src = src;
3351f0ac6a5Smrg    req->dst = dst;
3361f0ac6a5Smrg    req->maskFormat = maskFormat ? maskFormat->id : None;
3371f0ac6a5Smrg    req->glyphset = glyphset;
3381f0ac6a5Smrg    req->xSrc = xSrc;
3396fae4e5dSmrg    req->ySrc = ySrc;
3401f0ac6a5Smrg
3411f0ac6a5Smrg#define MAX_32	254
3421f0ac6a5Smrg
3431f0ac6a5Smrg    len = SIZEOF(xGlyphElt) * ((nchar + MAX_32-1) / MAX_32) + nchar * 4;
3446fae4e5dSmrg
3451f0ac6a5Smrg    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;
3601f0ac6a5Smrg	elt->deltax = xDst;
3611f0ac6a5Smrg	elt->deltay = yDst;
3621f0ac6a5Smrg	xDst = 0;
3631f0ac6a5Smrg	yDst = 0;
3641f0ac6a5Smrg	memcpy ((char *) (elt + 1), (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);
3731f0ac6a5Smrg	elt->len = nchar;
3741f0ac6a5Smrg	elt->deltax = xDst;
3751f0ac6a5Smrg	elt->deltay = yDst;
3761f0ac6a5Smrg	memcpy ((char *) (elt + 1), (char *) string, 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{
3971f0ac6a5Smrg    XRenderExtDisplayInfo		*info = XRenderFindDisplay (dpy);
3981f0ac6a5Smrg    xRenderCompositeGlyphs8Req	*req;
3991f0ac6a5Smrg    GlyphSet			glyphset;
4001f0ac6a5Smrg    long			len;
4011f0ac6a5Smrg    long			elen;
4021f0ac6a5Smrg    xGlyphElt			*elt;
4031f0ac6a5Smrg    int				i;
4041f0ac6a5Smrg    _Xconst char		*chars;
4051f0ac6a5Smrg    int				nchars;
4061f0ac6a5Smrg
4071f0ac6a5Smrg    if (!nelt)
4081f0ac6a5Smrg	return;
4096fae4e5dSmrg
4101f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
4111f0ac6a5Smrg    LockDisplay(dpy);
4121f0ac6a5Smrg
4131f0ac6a5Smrg    GetReq(RenderCompositeGlyphs8, req);
4141f0ac6a5Smrg    req->reqType = info->codes->major_opcode;
4151f0ac6a5Smrg    req->renderReqType = X_RenderCompositeGlyphs8;
4161f0ac6a5Smrg    req->op = op;
4171f0ac6a5Smrg    req->src = src;
4181f0ac6a5Smrg    req->dst = dst;
4191f0ac6a5Smrg    req->maskFormat = maskFormat ? maskFormat->id : None;
4201f0ac6a5Smrg    req->glyphset = elts[0].glyphset;
4211f0ac6a5Smrg    req->xSrc = xSrc;
4226fae4e5dSmrg    req->ySrc = ySrc;
4231f0ac6a5Smrg
4241f0ac6a5Smrg    /*
4251f0ac6a5Smrg     * Compute the space necessary
4261f0ac6a5Smrg     */
4271f0ac6a5Smrg    len = 0;
4286fae4e5dSmrg
4291f0ac6a5Smrg#define MAX_8 252
4301f0ac6a5Smrg
4311f0ac6a5Smrg    glyphset = elts[0].glyphset;
4321f0ac6a5Smrg    for (i = 0; i < nelt; i++)
4331f0ac6a5Smrg    {
4341f0ac6a5Smrg	/*
4351f0ac6a5Smrg	 * Check for glyphset change
4361f0ac6a5Smrg	 */
4371f0ac6a5Smrg	if (elts[i].glyphset != glyphset)
4381f0ac6a5Smrg	{
4391f0ac6a5Smrg	    glyphset = elts[i].glyphset;
4401f0ac6a5Smrg	    len += (SIZEOF (xGlyphElt) + 4) >> 2;
4411f0ac6a5Smrg	}
4421f0ac6a5Smrg	nchars = elts[i].nchars;
4431f0ac6a5Smrg	/*
4441f0ac6a5Smrg	 * xGlyphElt must be aligned on a 32-bit boundary; this is
4451f0ac6a5Smrg	 * easily done by filling no more than 252 glyphs in each
4461f0ac6a5Smrg	 * bucket
4471f0ac6a5Smrg	 */
4481f0ac6a5Smrg	elen = SIZEOF(xGlyphElt) * ((nchars + MAX_8-1) / MAX_8) + nchars;
4491f0ac6a5Smrg	len += (elen + 3) >> 2;
4501f0ac6a5Smrg    }
4516fae4e5dSmrg
4521f0ac6a5Smrg    req->length += len;
4531f0ac6a5Smrg
4541f0ac6a5Smrg    /*
4551f0ac6a5Smrg     * Send the glyphs
4561f0ac6a5Smrg     */
4571f0ac6a5Smrg    glyphset = elts[0].glyphset;
4581f0ac6a5Smrg    for (i = 0; i < nelt; i++)
4591f0ac6a5Smrg    {
4601f0ac6a5Smrg	/*
4611f0ac6a5Smrg	 * Switch glyphsets
4621f0ac6a5Smrg	 */
4631f0ac6a5Smrg	if (elts[i].glyphset != glyphset)
4641f0ac6a5Smrg	{
4651f0ac6a5Smrg	    glyphset = elts[i].glyphset;
4661f0ac6a5Smrg	    BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
4671f0ac6a5Smrg	    elt->len = 0xff;
4681f0ac6a5Smrg	    elt->deltax = 0;
4691f0ac6a5Smrg	    elt->deltay = 0;
4701f0ac6a5Smrg	    Data32(dpy, &glyphset, 4);
4711f0ac6a5Smrg	}
4721f0ac6a5Smrg	nchars = elts[i].nchars;
4731f0ac6a5Smrg	xDst = elts[i].xOff;
4741f0ac6a5Smrg	yDst = elts[i].yOff;
4751f0ac6a5Smrg	chars = elts[i].chars;
4761f0ac6a5Smrg	while (nchars)
4771f0ac6a5Smrg	{
4781f0ac6a5Smrg	    int this_chars = nchars > MAX_8 ? MAX_8 : nchars;
4791f0ac6a5Smrg
4801f0ac6a5Smrg	    BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt))
4811f0ac6a5Smrg	    elt->len = this_chars;
4821f0ac6a5Smrg	    elt->deltax = xDst;
4831f0ac6a5Smrg	    elt->deltay = yDst;
4841f0ac6a5Smrg	    xDst = 0;
4851f0ac6a5Smrg	    yDst = 0;
4861f0ac6a5Smrg	    Data (dpy, chars, this_chars);
4871f0ac6a5Smrg	    nchars -= this_chars;
4881f0ac6a5Smrg	    chars += this_chars;
4891f0ac6a5Smrg	}
4901f0ac6a5Smrg    }
4911f0ac6a5Smrg#undef MAX_8
4926fae4e5dSmrg
4931f0ac6a5Smrg    UnlockDisplay(dpy);
4941f0ac6a5Smrg    SyncHandle();
4951f0ac6a5Smrg}
4961f0ac6a5Smrg
4971f0ac6a5Smrgvoid
4981f0ac6a5SmrgXRenderCompositeText16 (Display			    *dpy,
4991f0ac6a5Smrg			int			    op,
5001f0ac6a5Smrg			Picture			    src,
5011f0ac6a5Smrg			Picture			    dst,
5021f0ac6a5Smrg			_Xconst XRenderPictFormat   *maskFormat,
5031f0ac6a5Smrg			int			    xSrc,
5041f0ac6a5Smrg			int			    ySrc,
5051f0ac6a5Smrg			int			    xDst,
5061f0ac6a5Smrg			int			    yDst,
5071f0ac6a5Smrg			_Xconst XGlyphElt16	    *elts,
5081f0ac6a5Smrg			int			    nelt)
5091f0ac6a5Smrg{
5101f0ac6a5Smrg    XRenderExtDisplayInfo		*info = XRenderFindDisplay (dpy);
5111f0ac6a5Smrg    xRenderCompositeGlyphs16Req	*req;
5121f0ac6a5Smrg    GlyphSet			glyphset;
5131f0ac6a5Smrg    long			len;
5141f0ac6a5Smrg    long			elen;
5151f0ac6a5Smrg    xGlyphElt			*elt;
5161f0ac6a5Smrg    int				i;
5171f0ac6a5Smrg    _Xconst unsigned short    	*chars;
5181f0ac6a5Smrg    int				nchars;
5191f0ac6a5Smrg
5201f0ac6a5Smrg    if (!nelt)
5211f0ac6a5Smrg	return;
5226fae4e5dSmrg
5231f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
5241f0ac6a5Smrg    LockDisplay(dpy);
5251f0ac6a5Smrg
5261f0ac6a5Smrg    GetReq(RenderCompositeGlyphs16, req);
5271f0ac6a5Smrg    req->reqType = info->codes->major_opcode;
5281f0ac6a5Smrg    req->renderReqType = X_RenderCompositeGlyphs16;
5291f0ac6a5Smrg    req->op = op;
5301f0ac6a5Smrg    req->src = src;
5311f0ac6a5Smrg    req->dst = dst;
5321f0ac6a5Smrg    req->maskFormat = maskFormat ? maskFormat->id : None;
5331f0ac6a5Smrg    req->glyphset = elts[0].glyphset;
5341f0ac6a5Smrg    req->xSrc = xSrc;
5356fae4e5dSmrg    req->ySrc = ySrc;
5361f0ac6a5Smrg
5371f0ac6a5Smrg    /*
5381f0ac6a5Smrg     * Compute the space necessary
5391f0ac6a5Smrg     */
5401f0ac6a5Smrg    len = 0;
5416fae4e5dSmrg
5421f0ac6a5Smrg#define MAX_16	254
5431f0ac6a5Smrg
5441f0ac6a5Smrg    glyphset = elts[0].glyphset;
5451f0ac6a5Smrg    for (i = 0; i < nelt; i++)
5461f0ac6a5Smrg    {
5471f0ac6a5Smrg	/*
5481f0ac6a5Smrg	 * Check for glyphset change
5491f0ac6a5Smrg	 */
5501f0ac6a5Smrg	if (elts[i].glyphset != glyphset)
5511f0ac6a5Smrg	{
5521f0ac6a5Smrg	    glyphset = elts[i].glyphset;
5531f0ac6a5Smrg	    len += (SIZEOF (xGlyphElt) + 4) >> 2;
5541f0ac6a5Smrg	}
5551f0ac6a5Smrg	nchars = elts[i].nchars;
5561f0ac6a5Smrg	/*
5571f0ac6a5Smrg	 * xGlyphElt must be aligned on a 32-bit boundary; this is
5581f0ac6a5Smrg	 * easily done by filling no more than 254 glyphs in each
5591f0ac6a5Smrg	 * bucket
5601f0ac6a5Smrg	 */
5611f0ac6a5Smrg	elen = SIZEOF(xGlyphElt) * ((nchars + MAX_16-1) / MAX_16) + nchars * 2;
5621f0ac6a5Smrg	len += (elen + 3) >> 2;
5631f0ac6a5Smrg    }
5646fae4e5dSmrg
5651f0ac6a5Smrg    req->length += len;
5661f0ac6a5Smrg
5671f0ac6a5Smrg    glyphset = elts[0].glyphset;
5681f0ac6a5Smrg    for (i = 0; i < nelt; i++)
5691f0ac6a5Smrg    {
5701f0ac6a5Smrg	/*
5711f0ac6a5Smrg	 * Switch glyphsets
5721f0ac6a5Smrg	 */
5731f0ac6a5Smrg	if (elts[i].glyphset != glyphset)
5741f0ac6a5Smrg	{
5751f0ac6a5Smrg	    glyphset = elts[i].glyphset;
5761f0ac6a5Smrg	    BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
5771f0ac6a5Smrg	    elt->len = 0xff;
5781f0ac6a5Smrg	    elt->deltax = 0;
5791f0ac6a5Smrg	    elt->deltay = 0;
5801f0ac6a5Smrg	    Data32(dpy, &glyphset, 4);
5811f0ac6a5Smrg	}
5821f0ac6a5Smrg	nchars = elts[i].nchars;
5831f0ac6a5Smrg	xDst = elts[i].xOff;
5841f0ac6a5Smrg	yDst = elts[i].yOff;
5851f0ac6a5Smrg	chars = elts[i].chars;
5861f0ac6a5Smrg	while (nchars)
5871f0ac6a5Smrg	{
5881f0ac6a5Smrg	    int this_chars = nchars > MAX_16 ? MAX_16 : nchars;
5891f0ac6a5Smrg	    int this_bytes = this_chars * 2;
5906fae4e5dSmrg
5911f0ac6a5Smrg	    BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt))
5921f0ac6a5Smrg	    elt->len = this_chars;
5931f0ac6a5Smrg	    elt->deltax = xDst;
5941f0ac6a5Smrg	    elt->deltay = yDst;
5951f0ac6a5Smrg	    xDst = 0;
5961f0ac6a5Smrg	    yDst = 0;
5971f0ac6a5Smrg	    Data16 (dpy, chars, this_bytes);
5981f0ac6a5Smrg	    nchars -= this_chars;
5991f0ac6a5Smrg	    chars += this_chars;
6001f0ac6a5Smrg	}
6011f0ac6a5Smrg    }
6021f0ac6a5Smrg#undef MAX_16
6036fae4e5dSmrg
6041f0ac6a5Smrg    UnlockDisplay(dpy);
6051f0ac6a5Smrg    SyncHandle();
6061f0ac6a5Smrg}
6071f0ac6a5Smrg
6081f0ac6a5Smrgvoid
6091f0ac6a5SmrgXRenderCompositeText32 (Display			    *dpy,
6101f0ac6a5Smrg			int			    op,
6111f0ac6a5Smrg			Picture			    src,
6121f0ac6a5Smrg			Picture			    dst,
6131f0ac6a5Smrg			_Xconst XRenderPictFormat   *maskFormat,
6141f0ac6a5Smrg			int			    xSrc,
6151f0ac6a5Smrg			int			    ySrc,
6161f0ac6a5Smrg			int			    xDst,
6171f0ac6a5Smrg			int			    yDst,
6181f0ac6a5Smrg			_Xconst XGlyphElt32	    *elts,
6191f0ac6a5Smrg			int			    nelt)
6201f0ac6a5Smrg{
6211f0ac6a5Smrg    XRenderExtDisplayInfo		*info = XRenderFindDisplay (dpy);
6221f0ac6a5Smrg    xRenderCompositeGlyphs32Req	*req;
6231f0ac6a5Smrg    GlyphSet			glyphset;
6241f0ac6a5Smrg    long			len;
6251f0ac6a5Smrg    long			elen;
6261f0ac6a5Smrg    xGlyphElt			*elt;
6271f0ac6a5Smrg    int				i;
6281f0ac6a5Smrg    _Xconst unsigned int    	*chars;
6291f0ac6a5Smrg    int				nchars;
6301f0ac6a5Smrg
6311f0ac6a5Smrg    if (!nelt)
6321f0ac6a5Smrg	return;
6336fae4e5dSmrg
6341f0ac6a5Smrg    RenderSimpleCheckExtension (dpy, info);
6351f0ac6a5Smrg    LockDisplay(dpy);
6361f0ac6a5Smrg
6376fae4e5dSmrg
6381f0ac6a5Smrg    GetReq(RenderCompositeGlyphs32, req);
6391f0ac6a5Smrg    req->reqType = info->codes->major_opcode;
6401f0ac6a5Smrg    req->renderReqType = X_RenderCompositeGlyphs32;
6411f0ac6a5Smrg    req->op = op;
6421f0ac6a5Smrg    req->src = src;
6431f0ac6a5Smrg    req->dst = dst;
6441f0ac6a5Smrg    req->maskFormat = maskFormat ? maskFormat->id : None;
6451f0ac6a5Smrg    req->glyphset = elts[0].glyphset;
6461f0ac6a5Smrg    req->xSrc = xSrc;
6476fae4e5dSmrg    req->ySrc = ySrc;
6481f0ac6a5Smrg
6491f0ac6a5Smrg    /*
6501f0ac6a5Smrg     * Compute the space necessary
6511f0ac6a5Smrg     */
6521f0ac6a5Smrg    len = 0;
6531f0ac6a5Smrg
6541f0ac6a5Smrg#define MAX_32	254
6556fae4e5dSmrg
6561f0ac6a5Smrg    glyphset = elts[0].glyphset;
6571f0ac6a5Smrg    for (i = 0; i < nelt; i++)
6581f0ac6a5Smrg    {
6591f0ac6a5Smrg	/*
6601f0ac6a5Smrg	 * Check for glyphset change
6611f0ac6a5Smrg	 */
6621f0ac6a5Smrg	if (elts[i].glyphset != glyphset)
6631f0ac6a5Smrg	{
6641f0ac6a5Smrg	    glyphset = elts[i].glyphset;
6651f0ac6a5Smrg	    len += (SIZEOF (xGlyphElt) + 4) >> 2;
6661f0ac6a5Smrg	}
6671f0ac6a5Smrg	nchars = elts[i].nchars;
668b9867631Smrg	elen = SIZEOF(xGlyphElt) * ((nchars + MAX_32-1) / MAX_32) + nchars *4;
6691f0ac6a5Smrg	len += (elen + 3) >> 2;
6701f0ac6a5Smrg    }
6716fae4e5dSmrg
6721f0ac6a5Smrg    req->length += len;
6731f0ac6a5Smrg
6741f0ac6a5Smrg    glyphset = elts[0].glyphset;
6751f0ac6a5Smrg    for (i = 0; i < nelt; i++)
6761f0ac6a5Smrg    {
6771f0ac6a5Smrg	/*
6781f0ac6a5Smrg	 * Switch glyphsets
6791f0ac6a5Smrg	 */
6801f0ac6a5Smrg	if (elts[i].glyphset != glyphset)
6811f0ac6a5Smrg	{
6821f0ac6a5Smrg	    glyphset = elts[i].glyphset;
6831f0ac6a5Smrg	    BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt));
6841f0ac6a5Smrg	    elt->len = 0xff;
6851f0ac6a5Smrg	    elt->deltax = 0;
6861f0ac6a5Smrg	    elt->deltay = 0;
6871f0ac6a5Smrg	    Data32(dpy, &glyphset, 4);
6881f0ac6a5Smrg	}
6891f0ac6a5Smrg	nchars = elts[i].nchars;
6901f0ac6a5Smrg	xDst = elts[i].xOff;
6911f0ac6a5Smrg	yDst = elts[i].yOff;
6921f0ac6a5Smrg	chars = elts[i].chars;
6931f0ac6a5Smrg	while (nchars)
6941f0ac6a5Smrg	{
6951f0ac6a5Smrg	    int this_chars = nchars > MAX_32 ? MAX_32 : nchars;
6961f0ac6a5Smrg	    int this_bytes = this_chars * 4;
6971f0ac6a5Smrg	    BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt))
6981f0ac6a5Smrg	    elt->len = this_chars;
6991f0ac6a5Smrg	    elt->deltax = xDst;
7001f0ac6a5Smrg	    elt->deltay = yDst;
7011f0ac6a5Smrg	    xDst = 0;
7021f0ac6a5Smrg	    yDst = 0;
7031f0ac6a5Smrg	    DataInt32 (dpy, chars, this_bytes);
7041f0ac6a5Smrg	    nchars -= this_chars;
7051f0ac6a5Smrg	    chars += this_chars;
7061f0ac6a5Smrg	}
7071f0ac6a5Smrg    }
7081f0ac6a5Smrg#undef MAX_32
7096fae4e5dSmrg
7101f0ac6a5Smrg    UnlockDisplay(dpy);
7111f0ac6a5Smrg    SyncHandle();
7121f0ac6a5Smrg}
713