PolyTxt16.c revision 1ab64890
1/* $Xorg: PolyTxt16.c,v 1.4 2001/02/09 02:03:35 xorgcvs Exp $ */
2/*
3
4Copyright 1986, 1998  The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25
26*/
27/* $XFree86: xc/lib/X11/PolyTxt16.c,v 1.4 2001/10/28 03:32:31 tsi Exp $ */
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32#include "Xlibint.h"
33
34int
35XDrawText16(
36    register Display *dpy,
37    Drawable d,
38    GC gc,
39    int x,
40    int y,
41    XTextItem16 *items,
42    int nitems)
43{
44    register int i;
45    register XTextItem16 *item;
46    int length = 0;
47    register xPolyText16Req *req;
48
49    LockDisplay(dpy);
50    FlushGC(dpy, gc);
51    GetReq (PolyText16, req);
52    req->drawable = d;
53    req->gc = gc->gid;
54    req->x = x;
55    req->y = y;
56
57    item = items;
58    for (i=0; i < nitems; i++) {
59	if (item->font)
60	    length += 5;  /* a 255 byte, plus size of Font id */
61        if (item->delta)
62        {
63	    if (item->delta > 0)
64	    {
65	      length += SIZEOF(xTextElt) * ((item->delta + 126) / 127);
66	    }
67            else
68            {
69   	      length += SIZEOF(xTextElt) * ((-item->delta + 127) / 128);
70 	    }
71        }
72	if (item->nchars > 0)
73	{
74	    length += SIZEOF(xTextElt) * ((item->nchars + 253) / 254 - 1);
75	    if (!item->delta) length += SIZEOF(xTextElt);
76	    length += item->nchars << 1;
77     	}
78	item++;
79    }
80
81    req->length += (length + 3)>>2;  /* convert to number of 32-bit words */
82
83
84    /*
85     * If the entire request does not fit into the remaining space in the
86     * buffer, flush the buffer first.   If the request does fit into the
87     * empty buffer, then we won't have to flush it at the end to keep
88     *  the buffer 32-bit aligned.
89     */
90
91    if (dpy->bufptr + length > dpy->bufmax)
92    	_XFlush (dpy);
93
94    item = items;
95    for (i=0; i< nitems; i++) {
96
97	if (item->font) {
98            /* to mark a font shift, write a 255 byte followed by
99	       the 4 bytes of font ID, big-end first */
100	    register unsigned char *f;
101	    BufAlloc (unsigned char *, f, 5);
102
103	    f[0] = 255;
104	    f[1] = (item->font & 0xff000000) >> 24;
105	    f[2] = (item->font & 0x00ff0000) >> 16;
106	    f[3] = (item->font & 0x0000ff00) >> 8;
107	    f[4] =  item->font & 0x000000ff;
108
109            /* update GC shadow */
110	    gc->values.font = item->font;
111	    }
112
113	{
114	    int nbytes = SIZEOF(xTextElt);
115	    int PartialNChars = item->nchars;
116	    int PartialDelta = item->delta;
117            register xTextElt *elt = NULL;
118	    int FirstTimeThrough = True;
119 	    XChar2b *CharacterOffset = item->chars;
120
121	    while((PartialDelta < -128) || (PartialDelta > 127))
122            {
123	    	int nb = SIZEOF(xTextElt);
124
125	    	BufAlloc (xTextElt *, elt, nb);
126	    	elt->len = 0;
127	    	if (PartialDelta > 0 )
128		{
129		    elt->delta = 127;
130		    PartialDelta = PartialDelta - 127;
131		}
132		else
133		{
134		    elt->delta = -128;
135		    PartialDelta = PartialDelta + 128;
136		}
137	    }
138	    if (PartialDelta)
139            {
140                BufAlloc (xTextElt *, elt, nbytes);
141	        elt->len = 0;
142		elt->delta = PartialDelta;
143	    }
144	    while(PartialNChars > 254)
145            {
146		nbytes = 254 * 2;
147	    	if (FirstTimeThrough)
148		{
149		    FirstTimeThrough = False;
150		    if (!item->delta)
151 		    {
152			nbytes += SIZEOF(xTextElt);
153	   		BufAlloc (xTextElt *, elt, nbytes);
154		        elt->delta = 0;
155		    }
156		    else
157		    {
158			char *DummyChar;
159		        BufAlloc(char *, DummyChar, nbytes);
160#ifdef lint
161			DummyChar = DummyChar;
162#endif
163		    }
164		}
165		else
166		{
167 		    nbytes += SIZEOF(xTextElt);
168	   	    BufAlloc (xTextElt *, elt, nbytes);
169		    elt->delta = 0;
170		}
171	    	elt->len = 254;
172
173#if defined(MUSTCOPY) || defined(MUSTCOPY2B)
174		{
175		    register int i;
176		    register unsigned char *cp;
177		    for (i = 0, cp = ((unsigned char *)elt) + 2; i < 254; i++) {
178			*cp++ = CharacterOffset[i].byte1;
179			*cp++ = CharacterOffset[i].byte2;
180		    }
181		}
182#else
183		memcpy ((char *) (elt + 1), (char *)CharacterOffset, 254 * 2);
184#endif
185		PartialNChars = PartialNChars - 254;
186		CharacterOffset += 254;
187
188	    }
189	    if (PartialNChars)
190            {
191		nbytes = PartialNChars * 2;
192	    	if (FirstTimeThrough)
193		{
194		    FirstTimeThrough = False;
195		    if (!item->delta)
196 		    {
197			nbytes += SIZEOF(xTextElt);
198	   		BufAlloc (xTextElt *, elt, nbytes);
199			elt->delta = 0;
200		    }
201		    else
202		    {
203			char *DummyChar;
204		        BufAlloc(char *, DummyChar, nbytes);
205#ifdef lint
206			DummyChar = DummyChar;
207#endif
208		    }
209		}
210		else
211		{
212 		    nbytes += SIZEOF(xTextElt);
213	   	    BufAlloc (xTextElt *, elt, nbytes);
214		    elt->delta = 0;
215		}
216	    	elt->len = PartialNChars;
217
218#if defined(MUSTCOPY) || defined(MUSTCOPY2B)
219		{
220		    register int i;
221		    register unsigned char *cp;
222		    for (i = 0, cp = ((unsigned char *)elt) + 2; i < PartialNChars;
223			 i++) {
224			*cp++ = CharacterOffset[i].byte1;
225			*cp++ = CharacterOffset[i].byte2;
226		    }
227		}
228#else
229		memcpy ((char *) (elt + 1), (char *)CharacterOffset,
230			PartialNChars *
2312);
232#endif
233	    }
234	}
235    item++;
236    }
237
238    /* Pad request out to a 32-bit boundary */
239
240    if (length &= 3) {
241	char *pad;
242	/*
243	 * BufAlloc is a macro that uses its last argument more than
244	 * once, otherwise I'd write "BufAlloc (char *, pad, 4-length)"
245	 */
246	length = 4 - length;
247	BufAlloc (char *, pad, length);
248	/*
249	 * if there are 3 bytes of padding, the first byte MUST be 0
250	 * so the pad bytes aren't mistaken for a final xTextElt
251	 */
252	*pad = 0;
253        }
254
255    /*
256     * If the buffer pointer is not now pointing to a 32-bit boundary,
257     * we must flush the buffer so that it does point to a 32-bit boundary
258     * at the end of this routine.
259     */
260
261    if ((dpy->bufptr - dpy->buffer) & 3)
262       _XFlush (dpy);
263
264    UnlockDisplay(dpy);
265    SyncHandle();
266    return 1;
267    }
268
269
270
271