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