do_text.c revision c9e4df9b
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    XGCValues   gcv;
41
42    font = XLoadQueryFont(xp->d, p->font);
43    if (font == NULL) {
44	printf("Could not load font '%s', benchmark omitted\n", p->font);
45	return 0;
46    }
47
48    bfont = NULL;
49    if (p->bfont != NULL) {
50	bfont = XLoadQueryFont(xp->d, p->bfont);
51	if (bfont == NULL) {
52	    printf("Could not load font '%s', benchmark omitted\n", p->bfont);
53	    return 0;
54	}
55    }
56
57    ypos = XPOS;
58    height = (font->max_bounds.ascent + font->max_bounds.descent) + 1;
59    if (bfont != NULL) {
60	int     h = (bfont->max_bounds.ascent + bfont->max_bounds.descent) + 1;
61	if (h > height)
62	    height = h;
63    }
64    gcv.font = font->fid;
65    XChangeGC(xp->d, xp->fggc, GCFont, &gcv);
66    XChangeGC(xp->d, xp->bggc, GCFont, &gcv);
67
68    charsPerLine = p->objects;
69    charsPerLine = (charsPerLine + 3) & ~3;
70    p->objects = charsPerLine;
71
72    totalLines = '\177' - ' ' + 1;
73    if (totalLines > reps) totalLines = reps;
74
75    charBuf = malloc(totalLines * sizeof (char *));
76    if (p->special)
77	items = malloc(totalLines * SEGS * sizeof (XTextItem));
78
79    for (int i = 0; i != totalLines; i++) {
80	char	ch;
81
82	charBuf[i] = malloc (sizeof (char) * charsPerLine);
83	ch = i + ' ';
84	for (int 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    XGCValues   	gcv;
125    int			rows, columns, totalChars, ch;
126    int			brows, bcolumns = 0, btotalChars = 0, bch = 0;
127
128    font = XLoadQueryFont(xp->d, p->font);
129    if (font == NULL) {
130	printf("Could not load font '%s', benchmark omitted\n", p->font);
131	return 0;
132    }
133    rows = font->max_byte1 - font->min_byte1 + 1;
134    columns = font->max_char_or_byte2 - font->min_char_or_byte2 + 1;
135    totalChars = rows * columns;
136    totalLines = rows;
137    ch = totalChars;
138
139    bfont = NULL;
140    if (p->bfont != NULL) {
141	bfont = XLoadQueryFont(xp->d, p->bfont);
142	if (bfont == NULL) {
143	    printf("Could not load font '%s', benchmark omitted\n", p->bfont);
144	    return 0;
145	}
146	brows = bfont->max_byte1 - bfont->min_byte1 + 1;
147	bcolumns = bfont->max_char_or_byte2 - bfont->min_char_or_byte2 + 1;
148	btotalChars = brows * bcolumns;
149	bch = btotalChars;
150	if (brows > totalLines) totalLines = brows;
151    }
152
153    ypos = XPOS;
154    height = (font->max_bounds.ascent + font->max_bounds.descent) + 1;
155    if (bfont != NULL) {
156	int     h = (bfont->max_bounds.ascent + bfont->max_bounds.descent) + 1;
157	if (h > height)
158	    height = h;
159    }
160    gcv.font = font->fid;
161    XChangeGC(xp->d, xp->fggc, GCFont, &gcv);
162    XChangeGC(xp->d, xp->bggc, GCFont, &gcv);
163
164    charsPerLine = p->objects;
165
166    if (totalLines > reps) totalLines = reps;
167
168    if (p->special) {
169	charsPerLine = (charsPerLine + 3) & ~3;	/* make a multiple of four */
170	p->objects = charsPerLine;
171
172	items = malloc(totalLines * SEGS * sizeof (XTextItem));
173
174	for (int i = 0; i < totalLines; i++) {
175	    char	*pbuf0, *pbuf1, *pbuf2;
176
177	    pbuf0 = items[i*SEGS+0].chars =
178                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                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                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 (int 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 (int 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 = malloc(totalLines * sizeof (char *));
208	for (int i = 0; i < totalLines; i++) {
209	    char *pbuf0 = charBuf[i] =
210                malloc (sizeof (char) * charsPerLine * 2);
211	    for (int j = 0; j < charsPerLine; j++) {
212		GetRealChar(font, totalChars, ch);
213		*pbuf0++ = ch / columns + font->min_byte1;
214		*pbuf0++ = ch % columns + font->min_char_or_byte2;
215	    }
216	}
217    }
218    return reps;
219}
220
221void
222DoText(XParms xp, Parms p, int64_t reps)
223{
224    int     line, startLine;
225
226    startLine = 0;
227    line = 0;
228    for (int i = 0; i != reps; i++) {
229	XDrawString(
230	    xp->d, xp->w, xp->fggc, XPOS, ypos, charBuf[line], charsPerLine);
231	ypos += height;
232	if (ypos > HEIGHT - height) {
233	    /* Wraparound to top of window */
234	    ypos = XPOS;
235	    line = startLine;
236	    startLine = (startLine + 1) % totalLines;
237	}
238	line = (line + 1) % totalLines;
239	CheckAbort ();
240    }
241}
242
243void
244DoText16(XParms xp, Parms p, int64_t reps)
245{
246    int     line, startLine;
247
248    startLine = 0;
249    line = 0;
250    for (int i = 0; i < reps; i++) {
251	XDrawString16(
252	    xp->d, xp->w, xp->fggc, XPOS, ypos, (XChar2b *)charBuf[line], charsPerLine);
253	ypos += height;
254	if (ypos > HEIGHT - height) {
255	    /* Wraparound to top of window */
256	    ypos = XPOS;
257	    line = startLine;
258	    startLine = (startLine + 1) % totalLines;
259	}
260	line = (line + 1) % totalLines;
261	CheckAbort ();
262    }
263}
264
265void
266DoPolyText(XParms xp, Parms p, int64_t reps)
267{
268    int     line, startLine;
269
270    startLine = 0;
271    line = 0;
272    for (int i = 0; i != reps; i++) {
273	XDrawText(
274	    xp->d, xp->w, xp->fggc, XPOS, ypos, &items[line*SEGS], SEGS);
275	ypos += height;
276	if (ypos > HEIGHT - height) {
277	    /* Wraparound to top of window */
278	    ypos = XPOS;
279	    line = startLine;
280	    startLine = (startLine + 1) % totalLines;
281	}
282	line = (line + 1) % totalLines;
283	CheckAbort ();
284    }
285}
286
287void
288DoPolyText16(XParms xp, Parms p, int64_t reps)
289{
290    int     line, startLine;
291
292    startLine = 0;
293    line = 0;
294    for (int i = 0; i != reps; i++) {
295	XDrawText16(
296	    xp->d, xp->w, xp->fggc, XPOS, ypos, (XTextItem16 *)&items[line*SEGS], SEGS);
297	ypos += height;
298	if (ypos > HEIGHT - height) {
299	    /* Wraparound to top of window */
300	    ypos = XPOS;
301	    line = startLine;
302	    startLine = (startLine + 1) % totalLines;
303	}
304	line = (line + 1) % totalLines;
305	CheckAbort ();
306    }
307}
308
309void
310DoImageText(XParms xp, Parms p, int64_t reps)
311{
312    int     line, startLine;
313
314    startLine = 0;
315    line = 0;
316    for (int i = 0; i != reps; i++) {
317	XDrawImageString(
318	    xp->d, xp->w, xp->fggc, XPOS, ypos, charBuf[line], charsPerLine);
319	ypos += height;
320	if (ypos > HEIGHT - height) {
321	    /* Wraparound to top of window */
322	    ypos = XPOS;
323	    startLine = (startLine + 17) % totalLines;
324	    line = startLine;
325	}
326	line = (line + 1) % totalLines;
327	CheckAbort ();
328    }
329}
330
331void
332DoImageText16(XParms xp, Parms p, int64_t reps)
333{
334    int     line, startLine;
335
336    startLine = 0;
337    line = 0;
338    for (int i = 0; i != reps; i++) {
339	XDrawImageString16(
340	    xp->d, xp->w, xp->fggc, XPOS, ypos, (XChar2b *)charBuf[line], charsPerLine);
341	ypos += height;
342	if (ypos > HEIGHT - height) {
343	    /* Wraparound to top of window */
344	    ypos = XPOS;
345	    startLine = (startLine + 17) % totalLines;
346	    line = startLine;
347	}
348	line = (line + 1) % totalLines;
349	CheckAbort ();
350    }
351}
352
353void
354ClearTextWin(XParms xp, Parms p)
355{
356    XClearWindow(xp->d, xp->w);
357}
358
359void
360EndText(XParms xp, Parms p)
361{
362    if(font==NULL)return;
363    for (int i = 0; i != totalLines; i++)
364	free(charBuf[i]);
365    free(charBuf);
366    if (p->special)
367	free(items);
368    XFreeFont(xp->d, font);
369    if (bfont != NULL)
370	XFreeFont(xp->d, bfont);
371}
372
373void
374EndText16(XParms xp, Parms p)
375{
376    if(font==NULL)return;
377    if (p->special) {
378	for (int i = 0; i < totalLines; i++) {
379	    free(items[i*SEGS+0].chars);
380	    free(items[i*SEGS+1].chars);
381	    free(items[i*SEGS+2].chars);
382	}
383	free(items);
384    } else {
385	for (int i = 0; i < totalLines; i++) {
386	    free(charBuf[i]);
387	}
388	free(charBuf);
389    }
390    XFreeFont(xp->d, font);
391    if(bfont != NULL) {
392	XFreeFont(xp->d, bfont);
393    }
394}
395
396#ifdef XFT
397#include <X11/extensions/Xrender.h>
398#include <X11/Xft/Xft.h>
399
400static XftFont	*aafont;
401static XftDraw	*aadraw;
402static XftColor	aacolor;
403
404int
405InitAAText(XParms xp, Parms p, int64_t reps)
406{
407    char		ch;
408    XRenderColor	color;
409
410    aafont = XftFontOpenName (xp->d, DefaultScreen (xp->d), p->font);
411
412    if (aafont == NULL)
413    {
414	printf("Could not load font '%s', benchmark omitted\n",
415	       p->font);
416	return 0;
417    }
418
419    aadraw = XftDrawCreate (xp->d, xp->w,
420			    xp->vinfo.visual,
421			    xp->cmap);
422
423    if (!aadraw)
424    {
425	printf ("Cannot create XftDraw object\n");
426	XftFontClose (xp->d, aafont);
427	return 0;
428    }
429    color.red = 0;
430    color.green = 0;
431    color.blue = 0;
432    color.alpha = 0xffff;
433    if (!XftColorAllocValue (xp->d,
434			     xp->vinfo.visual,
435			     xp->cmap,
436			     &color, &aacolor))
437    {
438	printf ("Cannot allocate black\n");
439	XftFontClose (xp->d, aafont);
440	XftDrawDestroy (aadraw);
441	aafont = NULL;
442	aadraw = NULL;
443	return 0;
444    }
445
446    ypos = XPOS;
447    height = aafont->height;
448
449    charsPerLine = p->objects;
450    charsPerLine = (charsPerLine + 3) & ~3;
451    p->objects = charsPerLine;
452
453    totalLines = '\177' - ' ' + 1;
454    if (totalLines > reps) totalLines = reps;
455
456    charBuf = malloc(totalLines * sizeof (char *));
457
458    for (int i = 0; i != totalLines; i++) {
459	charBuf[i] = malloc (sizeof (char) * charsPerLine);
460	ch = i + ' ';
461	for (int j = 0; j != charsPerLine; j++) {
462	    charBuf[i][j] = ch;
463	    if (ch == '\177') ch = ' '; else ch++;
464	}
465    }
466    return reps;
467}
468
469void
470DoAAText(XParms xp, Parms p, int64_t reps)
471{
472    int     line, startLine;
473
474    startLine = 0;
475    line = 0;
476    for (int i = 0; i != reps; i++) {
477	XftDrawString8 (aadraw, &aacolor, aafont,
478		       XPOS, ypos, (unsigned char *) charBuf[line], charsPerLine);
479	ypos += height;
480	if (ypos > HEIGHT - height) {
481	    /* Wraparound to top of window */
482	    ypos = XPOS;
483	    line = startLine;
484	    startLine = (startLine + 1) % totalLines;
485	}
486	line = (line + 1) % totalLines;
487	CheckAbort ();
488    }
489}
490
491void
492EndAAText(XParms xp, Parms p)
493{
494    if(!aadraw)return;
495    for (int i = 0; i != totalLines; i++)
496	free(charBuf[i]);
497    free(charBuf);
498    XftDrawDestroy (aadraw);
499    XftFontClose (xp->d, aafont);
500    XftColorFree (xp->d,
501		  xp->vinfo.visual,
502		  xp->cmap,
503		  &aacolor);
504}
505
506#endif
507