Glyph.c revision 6fae4e5d
1/* 2 * 3 * Copyright © 2000 SuSE, Inc. 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of SuSE not be used in advertising or 10 * publicity pertaining to distribution of the software without specific, 11 * written prior permission. SuSE makes no representations about the 12 * suitability of this software for any purpose. It is provided "as is" 13 * without express or implied warranty. 14 * 15 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE 17 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 19 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 * 22 * Author: Keith Packard, SuSE, Inc. 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include <config.h> 27#endif 28#include "Xrenderint.h" 29 30GlyphSet 31XRenderCreateGlyphSet (Display *dpy, _Xconst XRenderPictFormat *format) 32{ 33 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 34 GlyphSet gsid; 35 xRenderCreateGlyphSetReq *req; 36 37 RenderCheckExtension (dpy, info, 0); 38 LockDisplay(dpy); 39 GetReq(RenderCreateGlyphSet, req); 40 req->reqType = info->codes->major_opcode; 41 req->renderReqType = X_RenderCreateGlyphSet; 42 req->gsid = gsid = XAllocID(dpy); 43 req->format = format->id; 44 UnlockDisplay(dpy); 45 SyncHandle(); 46 return gsid; 47} 48 49GlyphSet 50XRenderReferenceGlyphSet (Display *dpy, GlyphSet existing) 51{ 52 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 53 GlyphSet gsid; 54 xRenderReferenceGlyphSetReq *req; 55 56 RenderCheckExtension (dpy, info, 0); 57 LockDisplay(dpy); 58 GetReq(RenderReferenceGlyphSet, req); 59 req->reqType = info->codes->major_opcode; 60 req->renderReqType = X_RenderReferenceGlyphSet; 61 req->gsid = gsid = XAllocID(dpy); 62 req->existing = existing; 63 UnlockDisplay(dpy); 64 SyncHandle(); 65 return gsid; 66} 67 68void 69XRenderFreeGlyphSet (Display *dpy, GlyphSet glyphset) 70{ 71 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 72 xRenderFreeGlyphSetReq *req; 73 74 RenderSimpleCheckExtension (dpy, info); 75 LockDisplay(dpy); 76 GetReq(RenderFreeGlyphSet, req); 77 req->reqType = info->codes->major_opcode; 78 req->renderReqType = X_RenderFreeGlyphSet; 79 req->glyphset = glyphset; 80 UnlockDisplay(dpy); 81 SyncHandle(); 82} 83 84void 85XRenderAddGlyphs (Display *dpy, 86 GlyphSet glyphset, 87 _Xconst Glyph *gids, 88 _Xconst XGlyphInfo *glyphs, 89 int nglyphs, 90 _Xconst char *images, 91 int nbyte_images) 92{ 93 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 94 xRenderAddGlyphsReq *req; 95 long len; 96 97 if (nbyte_images & 3) 98 nbyte_images += 4 - (nbyte_images & 3); 99 RenderSimpleCheckExtension (dpy, info); 100 LockDisplay(dpy); 101 GetReq(RenderAddGlyphs, req); 102 req->reqType = info->codes->major_opcode; 103 req->renderReqType = X_RenderAddGlyphs; 104 req->glyphset = glyphset; 105 req->nglyphs = nglyphs; 106 len = (nglyphs * (SIZEOF (xGlyphInfo) + 4) + nbyte_images) >> 2; 107 SetReqLen(req, len, len); 108 Data32 (dpy, (long *) gids, nglyphs * 4); 109 Data16 (dpy, (short *) glyphs, nglyphs * SIZEOF (xGlyphInfo)); 110 Data (dpy, images, nbyte_images); 111 UnlockDisplay(dpy); 112 SyncHandle(); 113} 114 115void 116XRenderFreeGlyphs (Display *dpy, 117 GlyphSet glyphset, 118 _Xconst Glyph *gids, 119 int nglyphs) 120{ 121 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 122 xRenderFreeGlyphsReq *req; 123 long len; 124 125 RenderSimpleCheckExtension (dpy, info); 126 LockDisplay(dpy); 127 GetReq(RenderFreeGlyphs, req); 128 req->reqType = info->codes->major_opcode; 129 req->renderReqType = X_RenderFreeGlyphs; 130 req->glyphset = glyphset; 131 len = nglyphs; 132 SetReqLen(req, len, len); 133 len <<= 2; 134 Data32 (dpy, (long *) gids, len); 135 UnlockDisplay(dpy); 136 SyncHandle(); 137} 138 139void 140XRenderCompositeString8 (Display *dpy, 141 int op, 142 Picture src, 143 Picture dst, 144 _Xconst XRenderPictFormat *maskFormat, 145 GlyphSet glyphset, 146 int xSrc, 147 int ySrc, 148 int xDst, 149 int yDst, 150 _Xconst char *string, 151 int nchar) 152{ 153 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 154 xRenderCompositeGlyphs8Req *req; 155 long len; 156 xGlyphElt *elt; 157 int nbytes; 158 159 if (!nchar) 160 return; 161 162 RenderSimpleCheckExtension (dpy, info); 163 LockDisplay(dpy); 164 165 GetReq(RenderCompositeGlyphs8, req); 166 req->reqType = info->codes->major_opcode; 167 req->renderReqType = X_RenderCompositeGlyphs8; 168 req->op = op; 169 req->src = src; 170 req->dst = dst; 171 req->maskFormat = maskFormat ? maskFormat->id : None; 172 req->glyphset = glyphset; 173 req->xSrc = xSrc; 174 req->ySrc = ySrc; 175 176 /* 177 * xGlyphElt must be aligned on a 32-bit boundary; this is 178 * easily done by filling no more than 252 glyphs in each 179 * bucket 180 */ 181 182#define MAX_8 252 183 184 len = SIZEOF(xGlyphElt) * ((nchar + MAX_8-1) / MAX_8) + nchar; 185 186 req->length += (len + 3)>>2; /* convert to number of 32-bit words */ 187 188 /* 189 * If the entire request does not fit into the remaining space in the 190 * buffer, flush the buffer first. 191 */ 192 193 if (dpy->bufptr + len > dpy->bufmax) 194 _XFlush (dpy); 195 196 while(nchar > MAX_8) 197 { 198 nbytes = MAX_8 + SIZEOF(xGlyphElt); 199 BufAlloc (xGlyphElt *, elt, nbytes); 200 elt->len = MAX_8; 201 elt->deltax = xDst; 202 elt->deltay = yDst; 203 xDst = 0; 204 yDst = 0; 205 memcpy ((char *) (elt + 1), string, MAX_8); 206 nchar = nchar - MAX_8; 207 string += MAX_8; 208 } 209 210 if (nchar) 211 { 212 nbytes = (nchar + SIZEOF(xGlyphElt) + 3) & ~3; 213 BufAlloc (xGlyphElt *, elt, nbytes); 214 elt->len = nchar; 215 elt->deltax = xDst; 216 elt->deltay = yDst; 217 memcpy ((char *) (elt + 1), string, nchar); 218 } 219#undef MAX_8 220 221 UnlockDisplay(dpy); 222 SyncHandle(); 223} 224void 225XRenderCompositeString16 (Display *dpy, 226 int op, 227 Picture src, 228 Picture dst, 229 _Xconst XRenderPictFormat *maskFormat, 230 GlyphSet glyphset, 231 int xSrc, 232 int ySrc, 233 int xDst, 234 int yDst, 235 _Xconst unsigned short *string, 236 int nchar) 237{ 238 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 239 xRenderCompositeGlyphs8Req *req; 240 long len; 241 xGlyphElt *elt; 242 int nbytes; 243 244 if (!nchar) 245 return; 246 247 RenderSimpleCheckExtension (dpy, info); 248 LockDisplay(dpy); 249 250 GetReq(RenderCompositeGlyphs16, req); 251 req->reqType = info->codes->major_opcode; 252 req->renderReqType = X_RenderCompositeGlyphs16; 253 req->op = op; 254 req->src = src; 255 req->dst = dst; 256 req->maskFormat = maskFormat ? maskFormat->id : None; 257 req->glyphset = glyphset; 258 req->xSrc = xSrc; 259 req->ySrc = ySrc; 260 261#define MAX_16 254 262 263 len = SIZEOF(xGlyphElt) * ((nchar + MAX_16-1) / MAX_16) + nchar * 2; 264 265 req->length += (len + 3)>>2; /* convert to number of 32-bit words */ 266 267 /* 268 * If the entire request does not fit into the remaining space in the 269 * buffer, flush the buffer first. 270 */ 271 272 if (dpy->bufptr + len > dpy->bufmax) 273 _XFlush (dpy); 274 275 while(nchar > MAX_16) 276 { 277 nbytes = MAX_16 * 2 + SIZEOF(xGlyphElt); 278 BufAlloc (xGlyphElt *, elt, nbytes); 279 elt->len = MAX_16; 280 elt->deltax = xDst; 281 elt->deltay = yDst; 282 xDst = 0; 283 yDst = 0; 284 memcpy ((char *) (elt + 1), (char *) string, MAX_16 * 2); 285 nchar = nchar - MAX_16; 286 string += MAX_16; 287 } 288 289 if (nchar) 290 { 291 nbytes = (nchar * 2 + SIZEOF(xGlyphElt) + 3) & ~3; 292 BufAlloc (xGlyphElt *, elt, nbytes); 293 elt->len = nchar; 294 elt->deltax = xDst; 295 elt->deltay = yDst; 296 memcpy ((char *) (elt + 1), (char *) string, nchar * 2); 297 } 298#undef MAX_16 299 300 UnlockDisplay(dpy); 301 SyncHandle(); 302} 303 304void 305XRenderCompositeString32 (Display *dpy, 306 int op, 307 Picture src, 308 Picture dst, 309 _Xconst XRenderPictFormat *maskFormat, 310 GlyphSet glyphset, 311 int xSrc, 312 int ySrc, 313 int xDst, 314 int yDst, 315 _Xconst unsigned int *string, 316 int nchar) 317{ 318 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 319 xRenderCompositeGlyphs8Req *req; 320 long len; 321 xGlyphElt *elt; 322 int nbytes; 323 324 if (!nchar) 325 return; 326 327 RenderSimpleCheckExtension (dpy, info); 328 LockDisplay(dpy); 329 330 GetReq(RenderCompositeGlyphs32, req); 331 req->reqType = info->codes->major_opcode; 332 req->renderReqType = X_RenderCompositeGlyphs32; 333 req->op = op; 334 req->src = src; 335 req->dst = dst; 336 req->maskFormat = maskFormat ? maskFormat->id : None; 337 req->glyphset = glyphset; 338 req->xSrc = xSrc; 339 req->ySrc = ySrc; 340 341#define MAX_32 254 342 343 len = SIZEOF(xGlyphElt) * ((nchar + MAX_32-1) / MAX_32) + nchar * 4; 344 345 req->length += (len + 3)>>2; /* convert to number of 32-bit words */ 346 347 /* 348 * If the entire request does not fit into the remaining space in the 349 * buffer, flush the buffer first. 350 */ 351 352 if (dpy->bufptr + len > dpy->bufmax) 353 _XFlush (dpy); 354 355 while(nchar > MAX_32) 356 { 357 nbytes = MAX_32 * 4 + SIZEOF(xGlyphElt); 358 BufAlloc (xGlyphElt *, elt, nbytes); 359 elt->len = MAX_32; 360 elt->deltax = xDst; 361 elt->deltay = yDst; 362 xDst = 0; 363 yDst = 0; 364 memcpy ((char *) (elt + 1), (char *) string, MAX_32 * 4); 365 nchar = nchar - MAX_32; 366 string += MAX_32; 367 } 368 369 if (nchar) 370 { 371 nbytes = nchar * 4 + SIZEOF(xGlyphElt); 372 BufAlloc (xGlyphElt *, elt, nbytes); 373 elt->len = nchar; 374 elt->deltax = xDst; 375 elt->deltay = yDst; 376 memcpy ((char *) (elt + 1), (char *) string, nchar * 4); 377 } 378#undef MAX_32 379 380 UnlockDisplay(dpy); 381 SyncHandle(); 382} 383 384void 385XRenderCompositeText8 (Display *dpy, 386 int op, 387 Picture src, 388 Picture dst, 389 _Xconst XRenderPictFormat *maskFormat, 390 int xSrc, 391 int ySrc, 392 int xDst, 393 int yDst, 394 _Xconst XGlyphElt8 *elts, 395 int nelt) 396{ 397 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 398 xRenderCompositeGlyphs8Req *req; 399 GlyphSet glyphset; 400 long len; 401 long elen; 402 xGlyphElt *elt; 403 int i; 404 _Xconst char *chars; 405 int nchars; 406 407 if (!nelt) 408 return; 409 410 RenderSimpleCheckExtension (dpy, info); 411 LockDisplay(dpy); 412 413 GetReq(RenderCompositeGlyphs8, req); 414 req->reqType = info->codes->major_opcode; 415 req->renderReqType = X_RenderCompositeGlyphs8; 416 req->op = op; 417 req->src = src; 418 req->dst = dst; 419 req->maskFormat = maskFormat ? maskFormat->id : None; 420 req->glyphset = elts[0].glyphset; 421 req->xSrc = xSrc; 422 req->ySrc = ySrc; 423 424 /* 425 * Compute the space necessary 426 */ 427 len = 0; 428 429#define MAX_8 252 430 431 glyphset = elts[0].glyphset; 432 for (i = 0; i < nelt; i++) 433 { 434 /* 435 * Check for glyphset change 436 */ 437 if (elts[i].glyphset != glyphset) 438 { 439 glyphset = elts[i].glyphset; 440 len += (SIZEOF (xGlyphElt) + 4) >> 2; 441 } 442 nchars = elts[i].nchars; 443 /* 444 * xGlyphElt must be aligned on a 32-bit boundary; this is 445 * easily done by filling no more than 252 glyphs in each 446 * bucket 447 */ 448 elen = SIZEOF(xGlyphElt) * ((nchars + MAX_8-1) / MAX_8) + nchars; 449 len += (elen + 3) >> 2; 450 } 451 452 req->length += len; 453 454 /* 455 * Send the glyphs 456 */ 457 glyphset = elts[0].glyphset; 458 for (i = 0; i < nelt; i++) 459 { 460 /* 461 * Switch glyphsets 462 */ 463 if (elts[i].glyphset != glyphset) 464 { 465 glyphset = elts[i].glyphset; 466 BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); 467 elt->len = 0xff; 468 elt->deltax = 0; 469 elt->deltay = 0; 470 Data32(dpy, &glyphset, 4); 471 } 472 nchars = elts[i].nchars; 473 xDst = elts[i].xOff; 474 yDst = elts[i].yOff; 475 chars = elts[i].chars; 476 while (nchars) 477 { 478 int this_chars = nchars > MAX_8 ? MAX_8 : nchars; 479 480 BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt)) 481 elt->len = this_chars; 482 elt->deltax = xDst; 483 elt->deltay = yDst; 484 xDst = 0; 485 yDst = 0; 486 Data (dpy, chars, this_chars); 487 nchars -= this_chars; 488 chars += this_chars; 489 } 490 } 491#undef MAX_8 492 493 UnlockDisplay(dpy); 494 SyncHandle(); 495} 496 497void 498XRenderCompositeText16 (Display *dpy, 499 int op, 500 Picture src, 501 Picture dst, 502 _Xconst XRenderPictFormat *maskFormat, 503 int xSrc, 504 int ySrc, 505 int xDst, 506 int yDst, 507 _Xconst XGlyphElt16 *elts, 508 int nelt) 509{ 510 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 511 xRenderCompositeGlyphs16Req *req; 512 GlyphSet glyphset; 513 long len; 514 long elen; 515 xGlyphElt *elt; 516 int i; 517 _Xconst unsigned short *chars; 518 int nchars; 519 520 if (!nelt) 521 return; 522 523 RenderSimpleCheckExtension (dpy, info); 524 LockDisplay(dpy); 525 526 GetReq(RenderCompositeGlyphs16, req); 527 req->reqType = info->codes->major_opcode; 528 req->renderReqType = X_RenderCompositeGlyphs16; 529 req->op = op; 530 req->src = src; 531 req->dst = dst; 532 req->maskFormat = maskFormat ? maskFormat->id : None; 533 req->glyphset = elts[0].glyphset; 534 req->xSrc = xSrc; 535 req->ySrc = ySrc; 536 537 /* 538 * Compute the space necessary 539 */ 540 len = 0; 541 542#define MAX_16 254 543 544 glyphset = elts[0].glyphset; 545 for (i = 0; i < nelt; i++) 546 { 547 /* 548 * Check for glyphset change 549 */ 550 if (elts[i].glyphset != glyphset) 551 { 552 glyphset = elts[i].glyphset; 553 len += (SIZEOF (xGlyphElt) + 4) >> 2; 554 } 555 nchars = elts[i].nchars; 556 /* 557 * xGlyphElt must be aligned on a 32-bit boundary; this is 558 * easily done by filling no more than 254 glyphs in each 559 * bucket 560 */ 561 elen = SIZEOF(xGlyphElt) * ((nchars + MAX_16-1) / MAX_16) + nchars * 2; 562 len += (elen + 3) >> 2; 563 } 564 565 req->length += len; 566 567 glyphset = elts[0].glyphset; 568 for (i = 0; i < nelt; i++) 569 { 570 /* 571 * Switch glyphsets 572 */ 573 if (elts[i].glyphset != glyphset) 574 { 575 glyphset = elts[i].glyphset; 576 BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); 577 elt->len = 0xff; 578 elt->deltax = 0; 579 elt->deltay = 0; 580 Data32(dpy, &glyphset, 4); 581 } 582 nchars = elts[i].nchars; 583 xDst = elts[i].xOff; 584 yDst = elts[i].yOff; 585 chars = elts[i].chars; 586 while (nchars) 587 { 588 int this_chars = nchars > MAX_16 ? MAX_16 : nchars; 589 int this_bytes = this_chars * 2; 590 591 BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt)) 592 elt->len = this_chars; 593 elt->deltax = xDst; 594 elt->deltay = yDst; 595 xDst = 0; 596 yDst = 0; 597 Data16 (dpy, chars, this_bytes); 598 nchars -= this_chars; 599 chars += this_chars; 600 } 601 } 602#undef MAX_16 603 604 UnlockDisplay(dpy); 605 SyncHandle(); 606} 607 608void 609XRenderCompositeText32 (Display *dpy, 610 int op, 611 Picture src, 612 Picture dst, 613 _Xconst XRenderPictFormat *maskFormat, 614 int xSrc, 615 int ySrc, 616 int xDst, 617 int yDst, 618 _Xconst XGlyphElt32 *elts, 619 int nelt) 620{ 621 XRenderExtDisplayInfo *info = XRenderFindDisplay (dpy); 622 xRenderCompositeGlyphs32Req *req; 623 GlyphSet glyphset; 624 long len; 625 long elen; 626 xGlyphElt *elt; 627 int i; 628 _Xconst unsigned int *chars; 629 int nchars; 630 631 if (!nelt) 632 return; 633 634 RenderSimpleCheckExtension (dpy, info); 635 LockDisplay(dpy); 636 637 638 GetReq(RenderCompositeGlyphs32, req); 639 req->reqType = info->codes->major_opcode; 640 req->renderReqType = X_RenderCompositeGlyphs32; 641 req->op = op; 642 req->src = src; 643 req->dst = dst; 644 req->maskFormat = maskFormat ? maskFormat->id : None; 645 req->glyphset = elts[0].glyphset; 646 req->xSrc = xSrc; 647 req->ySrc = ySrc; 648 649 /* 650 * Compute the space necessary 651 */ 652 len = 0; 653 654#define MAX_32 254 655 656 glyphset = elts[0].glyphset; 657 for (i = 0; i < nelt; i++) 658 { 659 /* 660 * Check for glyphset change 661 */ 662 if (elts[i].glyphset != glyphset) 663 { 664 glyphset = elts[i].glyphset; 665 len += (SIZEOF (xGlyphElt) + 4) >> 2; 666 } 667 nchars = elts[i].nchars; 668 elen = SIZEOF(xGlyphElt) * ((nchars + MAX_32) / MAX_32) + nchars *4; 669 len += (elen + 3) >> 2; 670 } 671 672 req->length += len; 673 674 glyphset = elts[0].glyphset; 675 for (i = 0; i < nelt; i++) 676 { 677 /* 678 * Switch glyphsets 679 */ 680 if (elts[i].glyphset != glyphset) 681 { 682 glyphset = elts[i].glyphset; 683 BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); 684 elt->len = 0xff; 685 elt->deltax = 0; 686 elt->deltay = 0; 687 Data32(dpy, &glyphset, 4); 688 } 689 nchars = elts[i].nchars; 690 xDst = elts[i].xOff; 691 yDst = elts[i].yOff; 692 chars = elts[i].chars; 693 while (nchars) 694 { 695 int this_chars = nchars > MAX_32 ? MAX_32 : nchars; 696 int this_bytes = this_chars * 4; 697 BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt)) 698 elt->len = this_chars; 699 elt->deltax = xDst; 700 elt->deltay = yDst; 701 xDst = 0; 702 yDst = 0; 703 DataInt32 (dpy, chars, this_bytes); 704 nchars -= this_chars; 705 chars += this_chars; 706 } 707 } 708#undef MAX_32 709 710 UnlockDisplay(dpy); 711 SyncHandle(); 712} 713