do_text.c revision c9e4df9b
1264fa531Smrg/*****************************************************************************
2264fa531SmrgCopyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
3264fa531Smrg
4264fa531Smrg                        All Rights Reserved
5264fa531Smrg
6264fa531SmrgPermission to use, copy, modify, and distribute this software and its
7264fa531Smrgdocumentation for any purpose and without fee is hereby granted,
8264fa531Smrgprovided that the above copyright notice appear in all copies and that
9264fa531Smrgboth that copyright notice and this permission notice appear in
10264fa531Smrgsupporting documentation, and that the name of Digital not be
11264fa531Smrgused in advertising or publicity pertaining to distribution of the
12264fa531Smrgsoftware without specific, written prior permission.
13264fa531Smrg
14264fa531SmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15264fa531SmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16264fa531SmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17264fa531SmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18264fa531SmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19264fa531SmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20264fa531SmrgSOFTWARE.
21264fa531Smrg
22264fa531Smrg******************************************************************************/
23264fa531Smrg
24264fa531Smrg#include "x11perf.h"
25264fa531Smrg#include <stdio.h>
26264fa531Smrg
27264fa531Smrgstatic char **charBuf;
28264fa531Smrgstatic XFontStruct *font, *bfont;
29264fa531Smrgstatic int height, ypos;
30264fa531Smrgstatic XTextItem *items;
31264fa531Smrgstatic int charsPerLine, totalLines;
32264fa531Smrg
33264fa531Smrg#define XPOS 20
34264fa531Smrg#define SEGS 3
35264fa531Smrg
36264fa531Smrg
37264fa531Smrgint
38533545b5SmrgInitText(XParms xp, Parms p, int64_t reps)
39264fa531Smrg{
40264fa531Smrg    XGCValues   gcv;
41264fa531Smrg
42264fa531Smrg    font = XLoadQueryFont(xp->d, p->font);
43264fa531Smrg    if (font == NULL) {
44264fa531Smrg	printf("Could not load font '%s', benchmark omitted\n", p->font);
45264fa531Smrg	return 0;
46264fa531Smrg    }
47264fa531Smrg
48264fa531Smrg    bfont = NULL;
49264fa531Smrg    if (p->bfont != NULL) {
50264fa531Smrg	bfont = XLoadQueryFont(xp->d, p->bfont);
51264fa531Smrg	if (bfont == NULL) {
52264fa531Smrg	    printf("Could not load font '%s', benchmark omitted\n", p->bfont);
53264fa531Smrg	    return 0;
54264fa531Smrg	}
55264fa531Smrg    }
56264fa531Smrg
57264fa531Smrg    ypos = XPOS;
58264fa531Smrg    height = (font->max_bounds.ascent + font->max_bounds.descent) + 1;
59264fa531Smrg    if (bfont != NULL) {
60264fa531Smrg	int     h = (bfont->max_bounds.ascent + bfont->max_bounds.descent) + 1;
61264fa531Smrg	if (h > height)
62264fa531Smrg	    height = h;
63264fa531Smrg    }
64264fa531Smrg    gcv.font = font->fid;
65264fa531Smrg    XChangeGC(xp->d, xp->fggc, GCFont, &gcv);
66264fa531Smrg    XChangeGC(xp->d, xp->bggc, GCFont, &gcv);
67264fa531Smrg
68264fa531Smrg    charsPerLine = p->objects;
69264fa531Smrg    charsPerLine = (charsPerLine + 3) & ~3;
70264fa531Smrg    p->objects = charsPerLine;
71264fa531Smrg
72264fa531Smrg    totalLines = '\177' - ' ' + 1;
73264fa531Smrg    if (totalLines > reps) totalLines = reps;
74264fa531Smrg
75c9e4df9bSmrg    charBuf = malloc(totalLines * sizeof (char *));
76264fa531Smrg    if (p->special)
77c9e4df9bSmrg	items = malloc(totalLines * SEGS * sizeof (XTextItem));
78264fa531Smrg
79c9e4df9bSmrg    for (int i = 0; i != totalLines; i++) {
80c9e4df9bSmrg	char	ch;
81c9e4df9bSmrg
82c9e4df9bSmrg	charBuf[i] = malloc (sizeof (char) * charsPerLine);
83264fa531Smrg	ch = i + ' ';
84c9e4df9bSmrg	for (int j = 0; j != charsPerLine; j++) {
85264fa531Smrg	    charBuf[i][j] = ch;
86264fa531Smrg	    if (ch == '\177') ch = ' '; else ch++;
87264fa531Smrg	}
88264fa531Smrg	if (p->special) {
89264fa531Smrg	    items[i*SEGS+0].chars = &(charBuf[i][0]);
90264fa531Smrg	    items[i*SEGS+0].nchars = charsPerLine/4;
91264fa531Smrg	    items[i*SEGS+0].delta = 0;
92264fa531Smrg	    items[i*SEGS+0].font = font->fid;
93264fa531Smrg	    items[i*SEGS+1].chars = &(charBuf[i][charsPerLine/4]);
94264fa531Smrg	    items[i*SEGS+1].nchars = charsPerLine/2;
95264fa531Smrg	    items[i*SEGS+1].delta = 3;
96264fa531Smrg	    items[i*SEGS+1].font = bfont->fid;
97264fa531Smrg	    items[i*SEGS+2].chars = &(charBuf[i][3*charsPerLine/4]);
98264fa531Smrg	    items[i*SEGS+2].nchars = charsPerLine/4;
99264fa531Smrg	    items[i*SEGS+2].delta = 3;
100264fa531Smrg	    items[i*SEGS+2].font = font->fid;
101264fa531Smrg	}
102264fa531Smrg    }
103264fa531Smrg    return reps;
104264fa531Smrg}
105264fa531Smrg
106264fa531Smrg
107264fa531Smrg#define GetRealChar(font, totalChars, ch)				\
108264fa531Smrg{									\
109264fa531Smrg    XCharStruct *pci;							\
110264fa531Smrg    do {								\
111264fa531Smrg	ch--;								\
112264fa531Smrg	if (ch < 0) {							\
113264fa531Smrg	    ch = totalChars-1;						\
114264fa531Smrg	}								\
115264fa531Smrg	if (font->per_char == NULL) break;				\
116264fa531Smrg	pci = &(font->per_char[ch]);					\
117264fa531Smrg    } while ( (pci->lbearing | pci->rbearing | pci->width		\
118264fa531Smrg             | pci->ascent | pci->descent | pci->attributes) == 0);     \
119264fa531Smrg} /* GetRealChar */
120264fa531Smrg
121264fa531Smrgint
122533545b5SmrgInitText16(XParms xp, Parms p, int64_t reps)
123264fa531Smrg{
124264fa531Smrg    XGCValues   	gcv;
125264fa531Smrg    int			rows, columns, totalChars, ch;
126264fa531Smrg    int			brows, bcolumns = 0, btotalChars = 0, bch = 0;
127264fa531Smrg
128264fa531Smrg    font = XLoadQueryFont(xp->d, p->font);
129264fa531Smrg    if (font == NULL) {
130264fa531Smrg	printf("Could not load font '%s', benchmark omitted\n", p->font);
131264fa531Smrg	return 0;
132264fa531Smrg    }
133264fa531Smrg    rows = font->max_byte1 - font->min_byte1 + 1;
134264fa531Smrg    columns = font->max_char_or_byte2 - font->min_char_or_byte2 + 1;
135264fa531Smrg    totalChars = rows * columns;
136264fa531Smrg    totalLines = rows;
137264fa531Smrg    ch = totalChars;
138264fa531Smrg
139264fa531Smrg    bfont = NULL;
140264fa531Smrg    if (p->bfont != NULL) {
141264fa531Smrg	bfont = XLoadQueryFont(xp->d, p->bfont);
142264fa531Smrg	if (bfont == NULL) {
143264fa531Smrg	    printf("Could not load font '%s', benchmark omitted\n", p->bfont);
144264fa531Smrg	    return 0;
145264fa531Smrg	}
146264fa531Smrg	brows = bfont->max_byte1 - bfont->min_byte1 + 1;
147264fa531Smrg	bcolumns = bfont->max_char_or_byte2 - bfont->min_char_or_byte2 + 1;
148264fa531Smrg	btotalChars = brows * bcolumns;
149264fa531Smrg	bch = btotalChars;
150264fa531Smrg	if (brows > totalLines) totalLines = brows;
151264fa531Smrg    }
152264fa531Smrg
153264fa531Smrg    ypos = XPOS;
154264fa531Smrg    height = (font->max_bounds.ascent + font->max_bounds.descent) + 1;
155264fa531Smrg    if (bfont != NULL) {
156264fa531Smrg	int     h = (bfont->max_bounds.ascent + bfont->max_bounds.descent) + 1;
157264fa531Smrg	if (h > height)
158264fa531Smrg	    height = h;
159264fa531Smrg    }
160264fa531Smrg    gcv.font = font->fid;
161264fa531Smrg    XChangeGC(xp->d, xp->fggc, GCFont, &gcv);
162264fa531Smrg    XChangeGC(xp->d, xp->bggc, GCFont, &gcv);
163264fa531Smrg
164264fa531Smrg    charsPerLine = p->objects;
165264fa531Smrg
166264fa531Smrg    if (totalLines > reps) totalLines = reps;
167264fa531Smrg
168264fa531Smrg    if (p->special) {
169264fa531Smrg	charsPerLine = (charsPerLine + 3) & ~3;	/* make a multiple of four */
170264fa531Smrg	p->objects = charsPerLine;
171264fa531Smrg
172c9e4df9bSmrg	items = malloc(totalLines * SEGS * sizeof (XTextItem));
173c9e4df9bSmrg
174c9e4df9bSmrg	for (int i = 0; i < totalLines; i++) {
175c9e4df9bSmrg	    char	*pbuf0, *pbuf1, *pbuf2;
176264fa531Smrg
177264fa531Smrg	    pbuf0 = items[i*SEGS+0].chars =
178c9e4df9bSmrg                malloc (sizeof (char) * charsPerLine/2);
179264fa531Smrg	    items[i*SEGS+0].nchars = charsPerLine/4;
180264fa531Smrg	    items[i*SEGS+0].delta = 0;
181264fa531Smrg	    items[i*SEGS+0].font = font->fid;
182264fa531Smrg	    pbuf1 = items[i*SEGS+1].chars =
183c9e4df9bSmrg                malloc (sizeof (char) * charsPerLine);
184264fa531Smrg	    items[i*SEGS+1].nchars = charsPerLine/2;
185264fa531Smrg	    items[i*SEGS+1].delta = 3;
186264fa531Smrg	    items[i*SEGS+1].font = bfont->fid;
187264fa531Smrg	    pbuf2 = items[i*SEGS+2].chars =
188c9e4df9bSmrg                malloc (sizeof (char) * charsPerLine/2);
189264fa531Smrg	    items[i*SEGS+2].nchars = charsPerLine/4;
190264fa531Smrg	    items[i*SEGS+2].delta = 3;
191264fa531Smrg	    items[i*SEGS+2].font = font->fid;
192c9e4df9bSmrg	    for (int j = 0; j < charsPerLine/4; j++) {
193264fa531Smrg		GetRealChar(font, totalChars, ch);
194264fa531Smrg		*pbuf0++ = ch / columns + font->min_byte1;
195264fa531Smrg		*pbuf0++ = ch % columns + font->min_char_or_byte2;
196264fa531Smrg		GetRealChar(font, totalChars, ch);
197264fa531Smrg		*pbuf2++ = ch / columns + font->min_byte1;
198264fa531Smrg		*pbuf2++ = ch % columns + font->min_char_or_byte2;
199264fa531Smrg	    }
200c9e4df9bSmrg	    for (int j = 0; j < charsPerLine/2; j++) {
201264fa531Smrg		GetRealChar(bfont, btotalChars, bch);
202264fa531Smrg		*pbuf1++ = bch / bcolumns + bfont->min_byte1;
203264fa531Smrg		*pbuf1++ = bch % bcolumns + bfont->min_char_or_byte2;
204264fa531Smrg	    }
205264fa531Smrg	}
206264fa531Smrg    } else {
207c9e4df9bSmrg	charBuf = malloc(totalLines * sizeof (char *));
208c9e4df9bSmrg	for (int i = 0; i < totalLines; i++) {
209c9e4df9bSmrg	    char *pbuf0 = charBuf[i] =
210c9e4df9bSmrg                malloc (sizeof (char) * charsPerLine * 2);
211c9e4df9bSmrg	    for (int j = 0; j < charsPerLine; j++) {
212264fa531Smrg		GetRealChar(font, totalChars, ch);
213264fa531Smrg		*pbuf0++ = ch / columns + font->min_byte1;
214264fa531Smrg		*pbuf0++ = ch % columns + font->min_char_or_byte2;
215264fa531Smrg	    }
216264fa531Smrg	}
217264fa531Smrg    }
218264fa531Smrg    return reps;
219264fa531Smrg}
220264fa531Smrg
221264fa531Smrgvoid
222533545b5SmrgDoText(XParms xp, Parms p, int64_t reps)
223264fa531Smrg{
224c9e4df9bSmrg    int     line, startLine;
225264fa531Smrg
226264fa531Smrg    startLine = 0;
227264fa531Smrg    line = 0;
228c9e4df9bSmrg    for (int i = 0; i != reps; i++) {
229264fa531Smrg	XDrawString(
230264fa531Smrg	    xp->d, xp->w, xp->fggc, XPOS, ypos, charBuf[line], charsPerLine);
231264fa531Smrg	ypos += height;
232264fa531Smrg	if (ypos > HEIGHT - height) {
233264fa531Smrg	    /* Wraparound to top of window */
234264fa531Smrg	    ypos = XPOS;
235264fa531Smrg	    line = startLine;
236264fa531Smrg	    startLine = (startLine + 1) % totalLines;
237264fa531Smrg	}
238264fa531Smrg	line = (line + 1) % totalLines;
239264fa531Smrg	CheckAbort ();
240264fa531Smrg    }
241264fa531Smrg}
242264fa531Smrg
243264fa531Smrgvoid
244533545b5SmrgDoText16(XParms xp, Parms p, int64_t reps)
245264fa531Smrg{
246c9e4df9bSmrg    int     line, startLine;
247264fa531Smrg
248264fa531Smrg    startLine = 0;
249264fa531Smrg    line = 0;
250c9e4df9bSmrg    for (int i = 0; i < reps; i++) {
251264fa531Smrg	XDrawString16(
252264fa531Smrg	    xp->d, xp->w, xp->fggc, XPOS, ypos, (XChar2b *)charBuf[line], charsPerLine);
253264fa531Smrg	ypos += height;
254264fa531Smrg	if (ypos > HEIGHT - height) {
255264fa531Smrg	    /* Wraparound to top of window */
256264fa531Smrg	    ypos = XPOS;
257264fa531Smrg	    line = startLine;
258264fa531Smrg	    startLine = (startLine + 1) % totalLines;
259264fa531Smrg	}
260264fa531Smrg	line = (line + 1) % totalLines;
261264fa531Smrg	CheckAbort ();
262264fa531Smrg    }
263264fa531Smrg}
264264fa531Smrg
265264fa531Smrgvoid
266533545b5SmrgDoPolyText(XParms xp, Parms p, int64_t reps)
267264fa531Smrg{
268c9e4df9bSmrg    int     line, startLine;
269264fa531Smrg
270264fa531Smrg    startLine = 0;
271264fa531Smrg    line = 0;
272c9e4df9bSmrg    for (int i = 0; i != reps; i++) {
273264fa531Smrg	XDrawText(
274264fa531Smrg	    xp->d, xp->w, xp->fggc, XPOS, ypos, &items[line*SEGS], SEGS);
275264fa531Smrg	ypos += height;
276264fa531Smrg	if (ypos > HEIGHT - height) {
277264fa531Smrg	    /* Wraparound to top of window */
278264fa531Smrg	    ypos = XPOS;
279264fa531Smrg	    line = startLine;
280264fa531Smrg	    startLine = (startLine + 1) % totalLines;
281264fa531Smrg	}
282264fa531Smrg	line = (line + 1) % totalLines;
283264fa531Smrg	CheckAbort ();
284264fa531Smrg    }
285264fa531Smrg}
286264fa531Smrg
287264fa531Smrgvoid
288533545b5SmrgDoPolyText16(XParms xp, Parms p, int64_t reps)
289264fa531Smrg{
290c9e4df9bSmrg    int     line, startLine;
291264fa531Smrg
292264fa531Smrg    startLine = 0;
293264fa531Smrg    line = 0;
294c9e4df9bSmrg    for (int i = 0; i != reps; i++) {
295264fa531Smrg	XDrawText16(
296264fa531Smrg	    xp->d, xp->w, xp->fggc, XPOS, ypos, (XTextItem16 *)&items[line*SEGS], SEGS);
297264fa531Smrg	ypos += height;
298264fa531Smrg	if (ypos > HEIGHT - height) {
299264fa531Smrg	    /* Wraparound to top of window */
300264fa531Smrg	    ypos = XPOS;
301264fa531Smrg	    line = startLine;
302264fa531Smrg	    startLine = (startLine + 1) % totalLines;
303264fa531Smrg	}
304264fa531Smrg	line = (line + 1) % totalLines;
305264fa531Smrg	CheckAbort ();
306264fa531Smrg    }
307264fa531Smrg}
308264fa531Smrg
309264fa531Smrgvoid
310533545b5SmrgDoImageText(XParms xp, Parms p, int64_t reps)
311264fa531Smrg{
312c9e4df9bSmrg    int     line, startLine;
313264fa531Smrg
314264fa531Smrg    startLine = 0;
315264fa531Smrg    line = 0;
316c9e4df9bSmrg    for (int i = 0; i != reps; i++) {
317264fa531Smrg	XDrawImageString(
318264fa531Smrg	    xp->d, xp->w, xp->fggc, XPOS, ypos, charBuf[line], charsPerLine);
319264fa531Smrg	ypos += height;
320264fa531Smrg	if (ypos > HEIGHT - height) {
321264fa531Smrg	    /* Wraparound to top of window */
322264fa531Smrg	    ypos = XPOS;
323264fa531Smrg	    startLine = (startLine + 17) % totalLines;
324264fa531Smrg	    line = startLine;
325264fa531Smrg	}
326264fa531Smrg	line = (line + 1) % totalLines;
327264fa531Smrg	CheckAbort ();
328264fa531Smrg    }
329264fa531Smrg}
330264fa531Smrg
331264fa531Smrgvoid
332533545b5SmrgDoImageText16(XParms xp, Parms p, int64_t reps)
333264fa531Smrg{
334c9e4df9bSmrg    int     line, startLine;
335264fa531Smrg
336264fa531Smrg    startLine = 0;
337264fa531Smrg    line = 0;
338c9e4df9bSmrg    for (int i = 0; i != reps; i++) {
339264fa531Smrg	XDrawImageString16(
340264fa531Smrg	    xp->d, xp->w, xp->fggc, XPOS, ypos, (XChar2b *)charBuf[line], charsPerLine);
341264fa531Smrg	ypos += height;
342264fa531Smrg	if (ypos > HEIGHT - height) {
343264fa531Smrg	    /* Wraparound to top of window */
344264fa531Smrg	    ypos = XPOS;
345264fa531Smrg	    startLine = (startLine + 17) % totalLines;
346264fa531Smrg	    line = startLine;
347264fa531Smrg	}
348264fa531Smrg	line = (line + 1) % totalLines;
349264fa531Smrg	CheckAbort ();
350264fa531Smrg    }
351264fa531Smrg}
352264fa531Smrg
353264fa531Smrgvoid
354264fa531SmrgClearTextWin(XParms xp, Parms p)
355264fa531Smrg{
356264fa531Smrg    XClearWindow(xp->d, xp->w);
357264fa531Smrg}
358264fa531Smrg
359264fa531Smrgvoid
360264fa531SmrgEndText(XParms xp, Parms p)
361264fa531Smrg{
362264fa531Smrg    if(font==NULL)return;
363c9e4df9bSmrg    for (int i = 0; i != totalLines; i++)
364264fa531Smrg	free(charBuf[i]);
365264fa531Smrg    free(charBuf);
366264fa531Smrg    if (p->special)
367264fa531Smrg	free(items);
368264fa531Smrg    XFreeFont(xp->d, font);
369264fa531Smrg    if (bfont != NULL)
370264fa531Smrg	XFreeFont(xp->d, bfont);
371264fa531Smrg}
372264fa531Smrg
373264fa531Smrgvoid
374264fa531SmrgEndText16(XParms xp, Parms p)
375264fa531Smrg{
376264fa531Smrg    if(font==NULL)return;
377264fa531Smrg    if (p->special) {
378c9e4df9bSmrg	for (int i = 0; i < totalLines; i++) {
379264fa531Smrg	    free(items[i*SEGS+0].chars);
380264fa531Smrg	    free(items[i*SEGS+1].chars);
381264fa531Smrg	    free(items[i*SEGS+2].chars);
382264fa531Smrg	}
383264fa531Smrg	free(items);
384264fa531Smrg    } else {
385c9e4df9bSmrg	for (int i = 0; i < totalLines; i++) {
386264fa531Smrg	    free(charBuf[i]);
387264fa531Smrg	}
388264fa531Smrg	free(charBuf);
389264fa531Smrg    }
390264fa531Smrg    XFreeFont(xp->d, font);
391264fa531Smrg    if(bfont != NULL) {
392264fa531Smrg	XFreeFont(xp->d, bfont);
393264fa531Smrg    }
394264fa531Smrg}
395264fa531Smrg
396264fa531Smrg#ifdef XFT
397264fa531Smrg#include <X11/extensions/Xrender.h>
398264fa531Smrg#include <X11/Xft/Xft.h>
399264fa531Smrg
400264fa531Smrgstatic XftFont	*aafont;
401264fa531Smrgstatic XftDraw	*aadraw;
402264fa531Smrgstatic XftColor	aacolor;
403264fa531Smrg
404264fa531Smrgint
405533545b5SmrgInitAAText(XParms xp, Parms p, int64_t reps)
406264fa531Smrg{
407264fa531Smrg    char		ch;
408264fa531Smrg    XRenderColor	color;
409264fa531Smrg
410264fa531Smrg    aafont = XftFontOpenName (xp->d, DefaultScreen (xp->d), p->font);
411264fa531Smrg
412264fa531Smrg    if (aafont == NULL)
413264fa531Smrg    {
414264fa531Smrg	printf("Could not load font '%s', benchmark omitted\n",
415264fa531Smrg	       p->font);
416264fa531Smrg	return 0;
417264fa531Smrg    }
418264fa531Smrg
419264fa531Smrg    aadraw = XftDrawCreate (xp->d, xp->w,
420264fa531Smrg			    xp->vinfo.visual,
421264fa531Smrg			    xp->cmap);
422264fa531Smrg
423264fa531Smrg    if (!aadraw)
424264fa531Smrg    {
425264fa531Smrg	printf ("Cannot create XftDraw object\n");
426264fa531Smrg	XftFontClose (xp->d, aafont);
427264fa531Smrg	return 0;
428264fa531Smrg    }
429264fa531Smrg    color.red = 0;
430264fa531Smrg    color.green = 0;
431264fa531Smrg    color.blue = 0;
432264fa531Smrg    color.alpha = 0xffff;
433264fa531Smrg    if (!XftColorAllocValue (xp->d,
434264fa531Smrg			     xp->vinfo.visual,
435264fa531Smrg			     xp->cmap,
436264fa531Smrg			     &color, &aacolor))
437264fa531Smrg    {
438264fa531Smrg	printf ("Cannot allocate black\n");
439264fa531Smrg	XftFontClose (xp->d, aafont);
440264fa531Smrg	XftDrawDestroy (aadraw);
441c37a63b8Smrg	aafont = NULL;
442c37a63b8Smrg	aadraw = NULL;
443264fa531Smrg	return 0;
444264fa531Smrg    }
445264fa531Smrg
446264fa531Smrg    ypos = XPOS;
447264fa531Smrg    height = aafont->height;
448264fa531Smrg
449264fa531Smrg    charsPerLine = p->objects;
450264fa531Smrg    charsPerLine = (charsPerLine + 3) & ~3;
451264fa531Smrg    p->objects = charsPerLine;
452264fa531Smrg
453264fa531Smrg    totalLines = '\177' - ' ' + 1;
454264fa531Smrg    if (totalLines > reps) totalLines = reps;
455264fa531Smrg
456c9e4df9bSmrg    charBuf = malloc(totalLines * sizeof (char *));
457264fa531Smrg
458c9e4df9bSmrg    for (int i = 0; i != totalLines; i++) {
459c9e4df9bSmrg	charBuf[i] = malloc (sizeof (char) * charsPerLine);
460264fa531Smrg	ch = i + ' ';
461c9e4df9bSmrg	for (int j = 0; j != charsPerLine; j++) {
462264fa531Smrg	    charBuf[i][j] = ch;
463264fa531Smrg	    if (ch == '\177') ch = ' '; else ch++;
464264fa531Smrg	}
465264fa531Smrg    }
466264fa531Smrg    return reps;
467264fa531Smrg}
468264fa531Smrg
469264fa531Smrgvoid
470533545b5SmrgDoAAText(XParms xp, Parms p, int64_t reps)
471264fa531Smrg{
472c9e4df9bSmrg    int     line, startLine;
473264fa531Smrg
474264fa531Smrg    startLine = 0;
475264fa531Smrg    line = 0;
476c9e4df9bSmrg    for (int i = 0; i != reps; i++) {
477264fa531Smrg	XftDrawString8 (aadraw, &aacolor, aafont,
478264fa531Smrg		       XPOS, ypos, (unsigned char *) charBuf[line], charsPerLine);
479264fa531Smrg	ypos += height;
480264fa531Smrg	if (ypos > HEIGHT - height) {
481264fa531Smrg	    /* Wraparound to top of window */
482264fa531Smrg	    ypos = XPOS;
483264fa531Smrg	    line = startLine;
484264fa531Smrg	    startLine = (startLine + 1) % totalLines;
485264fa531Smrg	}
486264fa531Smrg	line = (line + 1) % totalLines;
487264fa531Smrg	CheckAbort ();
488264fa531Smrg    }
489264fa531Smrg}
490264fa531Smrg
491264fa531Smrgvoid
492264fa531SmrgEndAAText(XParms xp, Parms p)
493264fa531Smrg{
494264fa531Smrg    if(!aadraw)return;
495c9e4df9bSmrg    for (int i = 0; i != totalLines; i++)
496264fa531Smrg	free(charBuf[i]);
497264fa531Smrg    free(charBuf);
498264fa531Smrg    XftDrawDestroy (aadraw);
499264fa531Smrg    XftFontClose (xp->d, aafont);
500264fa531Smrg    XftColorFree (xp->d,
501264fa531Smrg		  xp->vinfo.visual,
502264fa531Smrg		  xp->cmap,
503264fa531Smrg		  &aacolor);
504264fa531Smrg}
505264fa531Smrg
506264fa531Smrg#endif
507