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