do_text.c revision 264fa531
1/* $Xorg: do_text.c,v 1.4 2000/08/17 19:54:10 cpqbld Exp $ */
2/*****************************************************************************
3Copyright 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
4
5                        All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the name of Digital not be
12used in advertising or publicity pertaining to distribution of the
13software without specific, written prior permission.
14
15DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
16ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
17DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
18ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
19WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
20ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
21SOFTWARE.
22
23******************************************************************************/
24/* $XFree86: xc/programs/x11perf/do_text.c,v 1.7 2001/01/17 23:45:12 dawes Exp $ */
25
26#include "x11perf.h"
27#include <stdio.h>
28
29static char **charBuf;
30static XFontStruct *font, *bfont;
31static int height, ypos;
32static XTextItem *items;
33static int charsPerLine, totalLines;
34
35#define XPOS 20
36#define SEGS 3
37
38
39int
40InitText(XParms xp, Parms p, int reps)
41{
42    int		i, j;
43    char	ch;
44    XGCValues   gcv;
45
46    font = XLoadQueryFont(xp->d, p->font);
47    if (font == NULL) {
48	printf("Could not load font '%s', benchmark omitted\n", p->font);
49	return 0;
50    }
51
52    bfont = NULL;
53    if (p->bfont != NULL) {
54	bfont = XLoadQueryFont(xp->d, p->bfont);
55	if (bfont == NULL) {
56	    printf("Could not load font '%s', benchmark omitted\n", p->bfont);
57	    return 0;
58	}
59    }
60
61    ypos = XPOS;
62    height = (font->max_bounds.ascent + font->max_bounds.descent) + 1;
63    if (bfont != NULL) {
64	int     h = (bfont->max_bounds.ascent + bfont->max_bounds.descent) + 1;
65	if (h > height)
66	    height = h;
67    }
68    gcv.font = font->fid;
69    XChangeGC(xp->d, xp->fggc, GCFont, &gcv);
70    XChangeGC(xp->d, xp->bggc, GCFont, &gcv);
71
72    charsPerLine = p->objects;
73    charsPerLine = (charsPerLine + 3) & ~3;
74    p->objects = charsPerLine;
75
76    totalLines = '\177' - ' ' + 1;
77    if (totalLines > reps) totalLines = reps;
78
79    charBuf = (char **) malloc(totalLines*sizeof (char *));
80    if (p->special)
81	items = (XTextItem *) malloc(totalLines*SEGS*sizeof (XTextItem));
82
83    for (i = 0; i != totalLines; i++) {
84	charBuf[i] = (char *) malloc (sizeof (char)*charsPerLine);
85	ch = i + ' ';
86	for (j = 0; j != charsPerLine; j++) {
87	    charBuf[i][j] = ch;
88	    if (ch == '\177') ch = ' '; else ch++;
89	}
90	if (p->special) {
91	    items[i*SEGS+0].chars = &(charBuf[i][0]);
92	    items[i*SEGS+0].nchars = charsPerLine/4;
93	    items[i*SEGS+0].delta = 0;
94	    items[i*SEGS+0].font = font->fid;
95	    items[i*SEGS+1].chars = &(charBuf[i][charsPerLine/4]);
96	    items[i*SEGS+1].nchars = charsPerLine/2;
97	    items[i*SEGS+1].delta = 3;
98	    items[i*SEGS+1].font = bfont->fid;
99	    items[i*SEGS+2].chars = &(charBuf[i][3*charsPerLine/4]);
100	    items[i*SEGS+2].nchars = charsPerLine/4;
101	    items[i*SEGS+2].delta = 3;
102	    items[i*SEGS+2].font = font->fid;
103	}
104    }
105    return reps;
106}
107
108
109#define GetRealChar(font, totalChars, ch)				\
110{									\
111    XCharStruct *pci;							\
112    do {								\
113	ch--;								\
114	if (ch < 0) {							\
115	    ch = totalChars-1;						\
116	}								\
117	if (font->per_char == NULL) break;				\
118	pci = &(font->per_char[ch]);					\
119    } while ( (pci->lbearing | pci->rbearing | pci->width		\
120             | pci->ascent | pci->descent | pci->attributes) == 0);     \
121} /* GetRealChar */
122
123int
124InitText16(XParms xp, Parms p, int reps)
125{
126    register int	i, j;
127    register char	*pbuf0, *pbuf1, *pbuf2;
128    XGCValues   	gcv;
129    int			rows, columns, totalChars, ch;
130    int			brows, bcolumns = 0, btotalChars = 0, bch = 0;
131
132    font = XLoadQueryFont(xp->d, p->font);
133    if (font == NULL) {
134	printf("Could not load font '%s', benchmark omitted\n", p->font);
135	return 0;
136    }
137    rows = font->max_byte1 - font->min_byte1 + 1;
138    columns = font->max_char_or_byte2 - font->min_char_or_byte2 + 1;
139    totalChars = rows * columns;
140    totalLines = rows;
141    ch = totalChars;
142
143    bfont = NULL;
144    if (p->bfont != NULL) {
145	bfont = XLoadQueryFont(xp->d, p->bfont);
146	if (bfont == NULL) {
147	    printf("Could not load font '%s', benchmark omitted\n", p->bfont);
148	    return 0;
149	}
150	brows = bfont->max_byte1 - bfont->min_byte1 + 1;
151	bcolumns = bfont->max_char_or_byte2 - bfont->min_char_or_byte2 + 1;
152	btotalChars = brows * bcolumns;
153	bch = btotalChars;
154	if (brows > totalLines) totalLines = brows;
155    }
156
157    ypos = XPOS;
158    height = (font->max_bounds.ascent + font->max_bounds.descent) + 1;
159    if (bfont != NULL) {
160	int     h = (bfont->max_bounds.ascent + bfont->max_bounds.descent) + 1;
161	if (h > height)
162	    height = h;
163    }
164    gcv.font = font->fid;
165    XChangeGC(xp->d, xp->fggc, GCFont, &gcv);
166    XChangeGC(xp->d, xp->bggc, GCFont, &gcv);
167
168    charsPerLine = p->objects;
169
170    if (totalLines > reps) totalLines = reps;
171
172    if (p->special) {
173	charsPerLine = (charsPerLine + 3) & ~3;	/* make a multiple of four */
174	p->objects = charsPerLine;
175
176	items = (XTextItem *) malloc(totalLines*SEGS*sizeof (XTextItem));
177
178	for (i = 0; i < totalLines; i++) {
179	    pbuf0 = items[i*SEGS+0].chars =
180			    (char *) malloc (sizeof (char)*charsPerLine/2);
181	    items[i*SEGS+0].nchars = charsPerLine/4;
182	    items[i*SEGS+0].delta = 0;
183	    items[i*SEGS+0].font = font->fid;
184	    pbuf1 = items[i*SEGS+1].chars =
185			    (char *) malloc (sizeof (char)*charsPerLine);
186	    items[i*SEGS+1].nchars = charsPerLine/2;
187	    items[i*SEGS+1].delta = 3;
188	    items[i*SEGS+1].font = bfont->fid;
189	    pbuf2 = items[i*SEGS+2].chars =
190			    (char *) malloc (sizeof (char)*charsPerLine/2);
191	    items[i*SEGS+2].nchars = charsPerLine/4;
192	    items[i*SEGS+2].delta = 3;
193	    items[i*SEGS+2].font = font->fid;
194	    for (j = 0; j < charsPerLine/4; j++) {
195		GetRealChar(font, totalChars, ch);
196		*pbuf0++ = ch / columns + font->min_byte1;
197		*pbuf0++ = ch % columns + font->min_char_or_byte2;
198		GetRealChar(font, totalChars, ch);
199		*pbuf2++ = ch / columns + font->min_byte1;
200		*pbuf2++ = ch % columns + font->min_char_or_byte2;
201	    }
202	    for (j = 0; j < charsPerLine/2; j++) {
203		GetRealChar(bfont, btotalChars, bch);
204		*pbuf1++ = bch / bcolumns + bfont->min_byte1;
205		*pbuf1++ = bch % bcolumns + bfont->min_char_or_byte2;
206	    }
207	}
208    } else {
209	charBuf = (char **) malloc(totalLines*sizeof (char *));
210	for (i = 0; i < totalLines; i++) {
211	    pbuf0 = charBuf[i] = (char *) malloc (sizeof (char)*charsPerLine*2);
212	    for (j = 0; j < charsPerLine; j++) {
213		GetRealChar(font, totalChars, ch);
214		*pbuf0++ = ch / columns + font->min_byte1;
215		*pbuf0++ = ch % columns + font->min_char_or_byte2;
216	    }
217	}
218    }
219    return reps;
220}
221
222void
223DoText(XParms xp, Parms p, int reps)
224{
225    int     i, line, startLine;
226
227    startLine = 0;
228    line = 0;
229    for (i = 0; i != reps; i++) {
230	XDrawString(
231	    xp->d, xp->w, xp->fggc, XPOS, ypos, charBuf[line], charsPerLine);
232	ypos += height;
233	if (ypos > HEIGHT - height) {
234	    /* Wraparound to top of window */
235	    ypos = XPOS;
236	    line = startLine;
237	    startLine = (startLine + 1) % totalLines;
238	}
239	line = (line + 1) % totalLines;
240	CheckAbort ();
241    }
242}
243
244void
245DoText16(XParms xp, Parms p, int reps)
246{
247    int     i, line, startLine;
248
249    startLine = 0;
250    line = 0;
251    for (i = 0; i < reps; i++) {
252	XDrawString16(
253	    xp->d, xp->w, xp->fggc, XPOS, ypos, (XChar2b *)charBuf[line], charsPerLine);
254	ypos += height;
255	if (ypos > HEIGHT - height) {
256	    /* Wraparound to top of window */
257	    ypos = XPOS;
258	    line = startLine;
259	    startLine = (startLine + 1) % totalLines;
260	}
261	line = (line + 1) % totalLines;
262	CheckAbort ();
263    }
264}
265
266void
267DoPolyText(XParms xp, Parms p, int reps)
268{
269    int     i, line, startLine;
270
271    startLine = 0;
272    line = 0;
273    for (i = 0; i != reps; i++) {
274	XDrawText(
275	    xp->d, xp->w, xp->fggc, XPOS, ypos, &items[line*SEGS], SEGS);
276	ypos += height;
277	if (ypos > HEIGHT - height) {
278	    /* Wraparound to top of window */
279	    ypos = XPOS;
280	    line = startLine;
281	    startLine = (startLine + 1) % totalLines;
282	}
283	line = (line + 1) % totalLines;
284	CheckAbort ();
285    }
286}
287
288void
289DoPolyText16(XParms xp, Parms p, int reps)
290{
291    int     i, line, startLine;
292
293    startLine = 0;
294    line = 0;
295    for (i = 0; i != reps; i++) {
296	XDrawText16(
297	    xp->d, xp->w, xp->fggc, XPOS, ypos, (XTextItem16 *)&items[line*SEGS], SEGS);
298	ypos += height;
299	if (ypos > HEIGHT - height) {
300	    /* Wraparound to top of window */
301	    ypos = XPOS;
302	    line = startLine;
303	    startLine = (startLine + 1) % totalLines;
304	}
305	line = (line + 1) % totalLines;
306	CheckAbort ();
307    }
308}
309
310void
311DoImageText(XParms xp, Parms p, int reps)
312{
313    int     i, line, startLine;
314
315    startLine = 0;
316    line = 0;
317    for (i = 0; i != reps; i++) {
318	XDrawImageString(
319	    xp->d, xp->w, xp->fggc, XPOS, ypos, charBuf[line], charsPerLine);
320	ypos += height;
321	if (ypos > HEIGHT - height) {
322	    /* Wraparound to top of window */
323	    ypos = XPOS;
324	    startLine = (startLine + 17) % totalLines;
325	    line = startLine;
326	}
327	line = (line + 1) % totalLines;
328	CheckAbort ();
329    }
330}
331
332void
333DoImageText16(XParms xp, Parms p, int reps)
334{
335    int     i, line, startLine;
336
337    startLine = 0;
338    line = 0;
339    for (i = 0; i != reps; i++) {
340	XDrawImageString16(
341	    xp->d, xp->w, xp->fggc, XPOS, ypos, (XChar2b *)charBuf[line], charsPerLine);
342	ypos += height;
343	if (ypos > HEIGHT - height) {
344	    /* Wraparound to top of window */
345	    ypos = XPOS;
346	    startLine = (startLine + 17) % totalLines;
347	    line = startLine;
348	}
349	line = (line + 1) % totalLines;
350	CheckAbort ();
351    }
352}
353
354void
355ClearTextWin(XParms xp, Parms p)
356{
357    XClearWindow(xp->d, xp->w);
358}
359
360void
361EndText(XParms xp, Parms p)
362{
363    int i;
364
365    if(font==NULL)return;
366    for (i = 0; i != totalLines; i++)
367	free(charBuf[i]);
368    free(charBuf);
369    if (p->special)
370	free(items);
371    XFreeFont(xp->d, font);
372    if (bfont != NULL)
373	XFreeFont(xp->d, bfont);
374}
375
376void
377EndText16(XParms xp, Parms p)
378{
379    int i;
380
381    if(font==NULL)return;
382    if (p->special) {
383	for (i = 0; i < totalLines; i++) {
384	    free(items[i*SEGS+0].chars);
385	    free(items[i*SEGS+1].chars);
386	    free(items[i*SEGS+2].chars);
387	}
388	free(items);
389    } else {
390	for (i = 0; i < totalLines; i++) {
391	    free(charBuf[i]);
392	}
393	free(charBuf);
394    }
395    XFreeFont(xp->d, font);
396    if(bfont != NULL) {
397	XFreeFont(xp->d, bfont);
398    }
399}
400
401#ifdef XFT
402#include <X11/extensions/Xrender.h>
403#include <X11/Xft/Xft.h>
404
405static XftFont	*aafont;
406static XftDraw	*aadraw;
407static XftColor	aacolor;
408
409int
410InitAAText(XParms xp, Parms p, int reps)
411{
412    int			i, j;
413    char		ch;
414    XRenderColor	color;
415
416    aafont = XftFontOpenName (xp->d, DefaultScreen (xp->d), p->font);
417
418    if (aafont == NULL)
419    {
420	printf("Could not load font '%s', benchmark omitted\n",
421	       p->font);
422	return 0;
423    }
424
425    aadraw = XftDrawCreate (xp->d, xp->w,
426			    xp->vinfo.visual,
427			    xp->cmap);
428
429    if (!aadraw)
430    {
431	printf ("Cannot create XftDraw object\n");
432	XftFontClose (xp->d, aafont);
433	return 0;
434    }
435    color.red = 0;
436    color.green = 0;
437    color.blue = 0;
438    color.alpha = 0xffff;
439    if (!XftColorAllocValue (xp->d,
440			     xp->vinfo.visual,
441			     xp->cmap,
442			     &color, &aacolor))
443    {
444	printf ("Cannot allocate black\n");
445	XftFontClose (xp->d, aafont);
446	XftDrawDestroy (aadraw);
447	aafont = 0;
448	aadraw = 0;
449	return 0;
450    }
451
452    ypos = XPOS;
453    height = aafont->height;
454
455    charsPerLine = p->objects;
456    charsPerLine = (charsPerLine + 3) & ~3;
457    p->objects = charsPerLine;
458
459    totalLines = '\177' - ' ' + 1;
460    if (totalLines > reps) totalLines = reps;
461
462    charBuf = (char **) malloc(totalLines*sizeof (char *));
463
464    for (i = 0; i != totalLines; i++) {
465	charBuf[i] = (char *) malloc (sizeof (char)*charsPerLine);
466	ch = i + ' ';
467	for (j = 0; j != charsPerLine; j++) {
468	    charBuf[i][j] = ch;
469	    if (ch == '\177') ch = ' '; else ch++;
470	}
471    }
472    return reps;
473}
474
475void
476DoAAText(XParms xp, Parms p, int reps)
477{
478    int     i, line, startLine;
479
480    startLine = 0;
481    line = 0;
482    for (i = 0; i != reps; i++) {
483	XftDrawString8 (aadraw, &aacolor, aafont,
484		       XPOS, ypos, (unsigned char *) charBuf[line], charsPerLine);
485	ypos += height;
486	if (ypos > HEIGHT - height) {
487	    /* Wraparound to top of window */
488	    ypos = XPOS;
489	    line = startLine;
490	    startLine = (startLine + 1) % totalLines;
491	}
492	line = (line + 1) % totalLines;
493	CheckAbort ();
494    }
495}
496
497void
498EndAAText(XParms xp, Parms p)
499{
500    int i;
501
502    if(!aadraw)return;
503    for (i = 0; i != totalLines; i++)
504	free(charBuf[i]);
505    free(charBuf);
506    XftDrawDestroy (aadraw);
507    XftFontClose (xp->d, aafont);
508    XftColorFree (xp->d,
509		  xp->vinfo.visual,
510		  xp->cmap,
511		  &aacolor);
512}
513
514#endif
515