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#include "bitmaps.h" 27 28static char **charBuf; 29static XFontStruct *font, *bfont; 30static int height, ypos; 31static XTextItem *items; 32static int charsPerLine, totalLines; 33 34#define XPOS 20 35#define SEGS 3 36 37 38int 39InitText(XParms xp, Parms p, int64_t reps) 40{ 41 XGCValues gcv; 42 43 font = XLoadQueryFont(xp->d, p->font); 44 if (font == NULL) { 45 printf("Could not load font '%s', benchmark omitted\n", p->font); 46 return 0; 47 } 48 49 bfont = NULL; 50 if (p->bfont != NULL) { 51 bfont = XLoadQueryFont(xp->d, p->bfont); 52 if (bfont == NULL) { 53 printf("Could not load font '%s', benchmark omitted\n", p->bfont); 54 return 0; 55 } 56 } 57 58 ypos = XPOS; 59 height = (font->max_bounds.ascent + font->max_bounds.descent) + 1; 60 if (bfont != NULL) { 61 int h = (bfont->max_bounds.ascent + bfont->max_bounds.descent) + 1; 62 if (h > height) 63 height = h; 64 } 65 gcv.font = font->fid; 66 XChangeGC(xp->d, xp->fggc, GCFont, &gcv); 67 XChangeGC(xp->d, xp->bggc, GCFont, &gcv); 68 69 SetFillStyle(xp, p); 70 71 charsPerLine = p->objects; 72 charsPerLine = (charsPerLine + 3) & ~3; 73 p->objects = charsPerLine; 74 75 totalLines = '\177' - ' ' + 1; 76 if (totalLines > reps) totalLines = reps; 77 78 charBuf = malloc(totalLines * sizeof (char *)); 79 if (p->special) 80 items = malloc(totalLines * SEGS * sizeof (XTextItem)); 81 82 for (int i = 0; i != totalLines; i++) { 83 char ch; 84 85 charBuf[i] = malloc (sizeof (char) * charsPerLine); 86 ch = i + ' '; 87 for (int j = 0; j != charsPerLine; j++) { 88 charBuf[i][j] = ch; 89 if (ch == '\177') ch = ' '; else ch++; 90 } 91 if (p->special) { 92 items[i*SEGS+0].chars = &(charBuf[i][0]); 93 items[i*SEGS+0].nchars = charsPerLine/4; 94 items[i*SEGS+0].delta = 0; 95 items[i*SEGS+0].font = font->fid; 96 items[i*SEGS+1].chars = &(charBuf[i][charsPerLine/4]); 97 items[i*SEGS+1].nchars = charsPerLine/2; 98 items[i*SEGS+1].delta = 3; 99 items[i*SEGS+1].font = bfont->fid; 100 items[i*SEGS+2].chars = &(charBuf[i][3*charsPerLine/4]); 101 items[i*SEGS+2].nchars = charsPerLine/4; 102 items[i*SEGS+2].delta = 3; 103 items[i*SEGS+2].font = font->fid; 104 } 105 } 106 return reps; 107} 108 109 110#define GetRealChar(font, totalChars, ch) \ 111{ \ 112 XCharStruct *pci; \ 113 do { \ 114 ch--; \ 115 if (ch < 0) { \ 116 ch = totalChars-1; \ 117 } \ 118 if (font->per_char == NULL) break; \ 119 pci = &(font->per_char[ch]); \ 120 } while ( (pci->lbearing | pci->rbearing | pci->width \ 121 | pci->ascent | pci->descent | pci->attributes) == 0); \ 122} /* GetRealChar */ 123 124int 125InitText16(XParms xp, Parms p, int64_t reps) 126{ 127 XGCValues gcv; 128 int rows, columns, totalChars, ch; 129 int brows, bcolumns = 0, btotalChars = 0, bch = 0; 130 131 font = XLoadQueryFont(xp->d, p->font); 132 if (font == NULL) { 133 printf("Could not load font '%s', benchmark omitted\n", p->font); 134 return 0; 135 } 136 rows = font->max_byte1 - font->min_byte1 + 1; 137 columns = font->max_char_or_byte2 - font->min_char_or_byte2 + 1; 138 totalChars = rows * columns; 139 totalLines = rows; 140 ch = totalChars; 141 142 bfont = NULL; 143 if (p->bfont != NULL) { 144 bfont = XLoadQueryFont(xp->d, p->bfont); 145 if (bfont == NULL) { 146 printf("Could not load font '%s', benchmark omitted\n", p->bfont); 147 return 0; 148 } 149 brows = bfont->max_byte1 - bfont->min_byte1 + 1; 150 bcolumns = bfont->max_char_or_byte2 - bfont->min_char_or_byte2 + 1; 151 btotalChars = brows * bcolumns; 152 bch = btotalChars; 153 if (brows > totalLines) totalLines = brows; 154 } 155 156 ypos = XPOS; 157 height = (font->max_bounds.ascent + font->max_bounds.descent) + 1; 158 if (bfont != NULL) { 159 int h = (bfont->max_bounds.ascent + bfont->max_bounds.descent) + 1; 160 if (h > height) 161 height = h; 162 } 163 gcv.font = font->fid; 164 XChangeGC(xp->d, xp->fggc, GCFont, &gcv); 165 XChangeGC(xp->d, xp->bggc, GCFont, &gcv); 166 167 charsPerLine = p->objects; 168 169 if (totalLines > reps) totalLines = reps; 170 171 if (p->special) { 172 charsPerLine = (charsPerLine + 3) & ~3; /* make a multiple of four */ 173 p->objects = charsPerLine; 174 175 items = malloc(totalLines * SEGS * sizeof (XTextItem)); 176 177 for (int i = 0; i < totalLines; i++) { 178 char *pbuf0, *pbuf1, *pbuf2; 179 180 pbuf0 = items[i*SEGS+0].chars = 181 malloc (sizeof (char) * charsPerLine/2); 182 items[i*SEGS+0].nchars = charsPerLine/4; 183 items[i*SEGS+0].delta = 0; 184 items[i*SEGS+0].font = font->fid; 185 pbuf1 = items[i*SEGS+1].chars = 186 malloc (sizeof (char) * charsPerLine); 187 items[i*SEGS+1].nchars = charsPerLine/2; 188 items[i*SEGS+1].delta = 3; 189 items[i*SEGS+1].font = bfont->fid; 190 pbuf2 = items[i*SEGS+2].chars = 191 malloc (sizeof (char) * charsPerLine/2); 192 items[i*SEGS+2].nchars = charsPerLine/4; 193 items[i*SEGS+2].delta = 3; 194 items[i*SEGS+2].font = font->fid; 195 for (int j = 0; j < charsPerLine/4; j++) { 196 GetRealChar(font, totalChars, ch); 197 *pbuf0++ = ch / columns + font->min_byte1; 198 *pbuf0++ = ch % columns + font->min_char_or_byte2; 199 GetRealChar(font, totalChars, ch); 200 *pbuf2++ = ch / columns + font->min_byte1; 201 *pbuf2++ = ch % columns + font->min_char_or_byte2; 202 } 203 for (int j = 0; j < charsPerLine/2; j++) { 204 GetRealChar(bfont, btotalChars, bch); 205 *pbuf1++ = bch / bcolumns + bfont->min_byte1; 206 *pbuf1++ = bch % bcolumns + bfont->min_char_or_byte2; 207 } 208 } 209 } else { 210 charBuf = malloc(totalLines * sizeof (char *)); 211 for (int i = 0; i < totalLines; i++) { 212 char *pbuf0 = charBuf[i] = 213 malloc (sizeof (char) * charsPerLine * 2); 214 for (int j = 0; j < charsPerLine; j++) { 215 GetRealChar(font, totalChars, ch); 216 *pbuf0++ = ch / columns + font->min_byte1; 217 *pbuf0++ = ch % columns + font->min_char_or_byte2; 218 } 219 } 220 } 221 return reps; 222} 223 224void 225DoText(XParms xp, Parms p, int64_t reps) 226{ 227 int line, startLine; 228 229 startLine = 0; 230 line = 0; 231 for (int i = 0; i != reps; i++) { 232 XDrawString( 233 xp->d, xp->w, xp->fggc, XPOS, ypos, charBuf[line], charsPerLine); 234 ypos += height; 235 if (ypos > HEIGHT - height) { 236 /* Wraparound to top of window */ 237 ypos = XPOS; 238 line = startLine; 239 startLine = (startLine + 1) % totalLines; 240 } 241 line = (line + 1) % totalLines; 242 CheckAbort (); 243 } 244} 245 246void 247DoText16(XParms xp, Parms p, int64_t reps) 248{ 249 int line, startLine; 250 251 startLine = 0; 252 line = 0; 253 for (int i = 0; i < reps; i++) { 254 XDrawString16( 255 xp->d, xp->w, xp->fggc, XPOS, ypos, (XChar2b *)charBuf[line], charsPerLine); 256 ypos += height; 257 if (ypos > HEIGHT - height) { 258 /* Wraparound to top of window */ 259 ypos = XPOS; 260 line = startLine; 261 startLine = (startLine + 1) % totalLines; 262 } 263 line = (line + 1) % totalLines; 264 CheckAbort (); 265 } 266} 267 268void 269DoPolyText(XParms xp, Parms p, int64_t reps) 270{ 271 int line, startLine; 272 273 startLine = 0; 274 line = 0; 275 for (int i = 0; i != reps; i++) { 276 XDrawText( 277 xp->d, xp->w, xp->fggc, XPOS, ypos, &items[line*SEGS], SEGS); 278 ypos += height; 279 if (ypos > HEIGHT - height) { 280 /* Wraparound to top of window */ 281 ypos = XPOS; 282 line = startLine; 283 startLine = (startLine + 1) % totalLines; 284 } 285 line = (line + 1) % totalLines; 286 CheckAbort (); 287 } 288} 289 290void 291DoPolyText16(XParms xp, Parms p, int64_t reps) 292{ 293 int line, startLine; 294 295 startLine = 0; 296 line = 0; 297 for (int i = 0; i != reps; i++) { 298 XDrawText16( 299 xp->d, xp->w, xp->fggc, XPOS, ypos, (XTextItem16 *)&items[line*SEGS], SEGS); 300 ypos += height; 301 if (ypos > HEIGHT - height) { 302 /* Wraparound to top of window */ 303 ypos = XPOS; 304 line = startLine; 305 startLine = (startLine + 1) % totalLines; 306 } 307 line = (line + 1) % totalLines; 308 CheckAbort (); 309 } 310} 311 312void 313DoImageText(XParms xp, Parms p, int64_t reps) 314{ 315 int line, startLine; 316 317 startLine = 0; 318 line = 0; 319 for (int i = 0; i != reps; i++) { 320 XDrawImageString( 321 xp->d, xp->w, xp->fggc, XPOS, ypos, charBuf[line], charsPerLine); 322 ypos += height; 323 if (ypos > HEIGHT - height) { 324 /* Wraparound to top of window */ 325 ypos = XPOS; 326 startLine = (startLine + 17) % totalLines; 327 line = startLine; 328 } 329 line = (line + 1) % totalLines; 330 CheckAbort (); 331 } 332} 333 334void 335DoImageText16(XParms xp, Parms p, int64_t reps) 336{ 337 int line, startLine; 338 339 startLine = 0; 340 line = 0; 341 for (int i = 0; i != reps; i++) { 342 XDrawImageString16( 343 xp->d, xp->w, xp->fggc, XPOS, ypos, (XChar2b *)charBuf[line], charsPerLine); 344 ypos += height; 345 if (ypos > HEIGHT - height) { 346 /* Wraparound to top of window */ 347 ypos = XPOS; 348 startLine = (startLine + 17) % totalLines; 349 line = startLine; 350 } 351 line = (line + 1) % totalLines; 352 CheckAbort (); 353 } 354} 355 356void 357ClearTextWin(XParms xp, Parms p) 358{ 359 XClearWindow(xp->d, xp->w); 360} 361 362void 363EndText(XParms xp, Parms p) 364{ 365 if(font==NULL)return; 366 for (int 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 if(font==NULL)return; 380 if (p->special) { 381 for (int 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 (int 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 char ch; 411 XRenderColor color; 412 FcValue value; 413 int v_len; 414 FcPattern *pat; 415 FcPattern *match; 416 FcResult result; 417 418 pat = FcNameParse((FcChar8 *) p->font); 419 match = XftFontMatch(xp->d, DefaultScreen(xp->d), pat, &result); 420 FcPatternDestroy(pat); 421 if (p->bfont) { 422 FcPatternDel(match, XFT_RENDER); 423 FcPatternAddBool(match, XFT_RENDER, False); 424 } 425 426 aafont = XftFontOpenPattern (xp->d, match); 427 428 if (aafont == NULL) 429 { 430 printf("Could not load font '%s', benchmark omitted\n", 431 p->font); 432 return 0; 433 } 434 if (FcPatternGet(aafont->pattern, FC_FAMILY, 0, &value) != FcResultMatch || 435 value.type != FcTypeString) 436 { 437 printf("Could not load font '%s', benchmark omitted\n", 438 p->font); 439 XftFontClose (xp->d, aafont); 440 return 0; 441 } 442 v_len = strlen((char *) value.u.s); 443 if (strncmp((char *) value.u.s, p->font, v_len) != 0 || p->font[v_len] != ':') { 444 printf("Could not load font '%s' (found %s), benchmark omitted\n", 445 p->font, 446 (char *) value.u.s); 447 XftFontClose (xp->d, aafont); 448 return 0; 449 } 450 451 aadraw = XftDrawCreate (xp->d, xp->w, 452 xp->vinfo.visual, 453 xp->cmap); 454 455 if (!aadraw) 456 { 457 printf ("Cannot create XftDraw object\n"); 458 XftFontClose (xp->d, aafont); 459 return 0; 460 } 461 color.red = 0; 462 color.green = 0; 463 color.blue = 0; 464 color.alpha = 0xffff; 465 if (!XftColorAllocValue (xp->d, 466 xp->vinfo.visual, 467 xp->cmap, 468 &color, &aacolor)) 469 { 470 printf ("Cannot allocate black\n"); 471 XftFontClose (xp->d, aafont); 472 XftDrawDestroy (aadraw); 473 aafont = NULL; 474 aadraw = NULL; 475 return 0; 476 } 477 478 ypos = XPOS; 479 height = aafont->height; 480 481 charsPerLine = p->objects; 482 charsPerLine = (charsPerLine + 3) & ~3; 483 p->objects = charsPerLine; 484 485 totalLines = '\177' - ' ' + 1; 486 if (totalLines > reps) totalLines = reps; 487 488 charBuf = malloc(totalLines * sizeof (char *)); 489 490 for (int i = 0; i != totalLines; i++) { 491 charBuf[i] = malloc (sizeof (char) * charsPerLine); 492 ch = i + ' '; 493 for (int j = 0; j != charsPerLine; j++) { 494 charBuf[i][j] = ch; 495 if (ch == '\177') ch = ' '; else ch++; 496 } 497 } 498 return reps; 499} 500 501void 502DoAAText(XParms xp, Parms p, int64_t reps) 503{ 504 int line, startLine; 505 506 startLine = 0; 507 line = 0; 508 for (int i = 0; i != reps; i++) { 509 XftDrawString8 (aadraw, &aacolor, aafont, 510 XPOS, ypos, (unsigned char *) charBuf[line], charsPerLine); 511 ypos += height; 512 if (ypos > HEIGHT - height) { 513 /* Wraparound to top of window */ 514 ypos = XPOS; 515 line = startLine; 516 startLine = (startLine + 1) % totalLines; 517 } 518 line = (line + 1) % totalLines; 519 CheckAbort (); 520 } 521} 522 523void 524EndAAText(XParms xp, Parms p) 525{ 526 if(!aadraw)return; 527 for (int i = 0; i != totalLines; i++) 528 free(charBuf[i]); 529 free(charBuf); 530 XftDrawDestroy (aadraw); 531 XftFontClose (xp->d, aafont); 532 XftColorFree (xp->d, 533 xp->vinfo.visual, 534 xp->cmap, 535 &aacolor); 536} 537 538#endif 539