1 /*
2 * Copyright © 2000 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
13 *
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23 #include "xftint.h"
24
25 #define NUM_LOCAL 1024
26 #define NUM_ELT_LOCAL 128
27
28 /*
29 * Use the Render extension to draw the glyphs
30 */
31
32 _X_EXPORT void
XftGlyphRender(Display * dpy,int op,Picture src,XftFont * pub,Picture dst,int srcx,int srcy,int x,int y,_Xconst FT_UInt * glyphs,int nglyphs)33 XftGlyphRender (Display *dpy,
34 int op,
35 Picture src,
36 XftFont *pub,
37 Picture dst,
38 int srcx,
39 int srcy,
40 int x,
41 int y,
42 _Xconst FT_UInt *glyphs,
43 int nglyphs)
44 {
45 XftFontInt *font = (XftFontInt *) pub;
46 int i;
47 FT_UInt missing[XFT_NMISSING];
48 int nmissing;
49 FT_UInt g, max;
50 int size, width;
51 Glyph wire;
52 char *char8;
53 unsigned short *char16;
54 unsigned int *char32;
55 unsigned int char_local[NUM_LOCAL];
56 unsigned int *chars;
57 FcBool glyphs_loaded;
58
59 if (!font->format)
60 return;
61
62 /*
63 * Load missing glyphs
64 */
65 nmissing = 0;
66 max = 0;
67 glyphs_loaded = FcFalse;
68 for (i = 0; i < nglyphs; i++)
69 {
70 g = glyphs[i];
71 if (g > max)
72 max = g;
73 if (XftFontCheckGlyph (dpy, pub, FcTrue, g, missing, &nmissing))
74 glyphs_loaded = FcTrue;
75 }
76 if (nmissing)
77 XftFontLoadGlyphs (dpy, pub, FcTrue, missing, nmissing);
78
79 if (!font->glyphset)
80 goto bail1;
81 if (max < 0x100)
82 {
83 width = 1;
84 size = sizeof (char);
85 }
86 else if (max < 0x10000)
87 {
88 width = 2;
89 size = sizeof (unsigned short);
90 }
91 else
92 {
93 width = 4;
94 size = sizeof (unsigned int);
95 }
96 chars = char_local;
97 if (nglyphs * size > sizeof (char_local))
98 {
99 chars = malloc ((size_t)(nglyphs * size));
100 if (!chars)
101 goto bail1;
102 }
103 char8 = (char *) chars;
104 char16 = (unsigned short *) chars;
105 char32 = (unsigned int *) chars;
106 for (i = 0; i < nglyphs; i++)
107 {
108 wire = (Glyph) glyphs[i];
109 if (wire >= font->num_glyphs || !font->glyphs[wire])
110 wire = 0;
111 switch (width) {
112 case 1: char8[i] = (char) wire; break;
113 case 2: char16[i] = (unsigned short) wire; break;
114 case 4: char32[i] = (unsigned int) wire; break;
115 }
116 }
117 switch (width) {
118 case 1:
119 default:
120 XRenderCompositeString8 (dpy, op,
121 src, dst, font->format, font->glyphset,
122 srcx, srcy, x, y, char8, nglyphs);
123 break;
124 case 2:
125 XRenderCompositeString16(dpy, op,
126 src, dst, font->format, font->glyphset,
127 srcx, srcy, x, y, char16, nglyphs);
128 break;
129 case 4:
130 XRenderCompositeString32(dpy, op,
131 src, dst, font->format, font->glyphset,
132 srcx, srcy, x, y, char32, nglyphs);
133 break;
134 }
135 if (chars != char_local)
136 free (chars);
137 bail1:
138 if (glyphs_loaded)
139 _XftFontManageMemory (dpy, pub);
140 }
141
142 _X_EXPORT void
XftGlyphSpecRender(Display * dpy,int op,Picture src,XftFont * pub,Picture dst,int srcx,int srcy,_Xconst XftGlyphSpec * glyphs,int nglyphs)143 XftGlyphSpecRender (Display *dpy,
144 int op,
145 Picture src,
146 XftFont *pub,
147 Picture dst,
148 int srcx,
149 int srcy,
150 _Xconst XftGlyphSpec *glyphs,
151 int nglyphs)
152 {
153 XftFontInt *font = (XftFontInt *) pub;
154 int i, j;
155 FT_UInt missing[XFT_NMISSING];
156 int nmissing;
157 int n;
158 FT_UInt g;
159 XftGlyph *glyph;
160 FT_UInt max;
161 int size, width;
162 char *char8;
163 unsigned short *char16;
164 unsigned int *char32;
165 unsigned int char_local[NUM_LOCAL];
166 unsigned int *chars;
167 XGlyphElt8 *elts;
168 XGlyphElt8 elts_local[NUM_ELT_LOCAL];
169 FcBool glyphs_loaded;
170 int nelt;
171 int x, y;
172
173 if (!font->format)
174 return;
175 if (!nglyphs)
176 return;
177
178 /*
179 * Load missing glyphs
180 */
181 max = 0;
182 nmissing = 0;
183 glyphs_loaded = FcFalse;
184 g = glyphs[0].glyph;
185 for (i = 0; i < nglyphs; i++)
186 {
187 g = glyphs[i].glyph;
188 if (g > max)
189 max = g;
190 if (XftFontCheckGlyph (dpy, pub, FcTrue, g, missing, &nmissing))
191 glyphs_loaded = FcTrue;
192 }
193 if (nmissing)
194 XftFontLoadGlyphs (dpy, pub, FcTrue, missing, nmissing);
195
196 if (!font->glyphset)
197 goto bail1;
198
199 /*
200 * See what encoding size is needed
201 */
202 if (max < 0x100)
203 {
204 size = sizeof (char);
205 width = 1;
206 }
207 else if (max < 0x10000)
208 {
209 size = sizeof (unsigned short);
210 width = 2;
211 }
212 else
213 {
214 size = sizeof (unsigned int);
215 width = 4;
216 }
217 chars = char_local;
218 if (nglyphs * size > NUM_LOCAL)
219 {
220 chars = malloc ((size_t)(nglyphs * size));
221 if (!chars)
222 goto bail1;
223 }
224 char8 = (char *) chars;
225 char16 = (unsigned short *) chars;
226 char32 = (unsigned int *) chars;
227
228 /*
229 * Compute the number of glyph elts needed
230 */
231 nelt = 1;
232 for (i = 0; i < nglyphs; i++)
233 {
234 g = glyphs[i].glyph;
235 /* Substitute default for non-existant glyphs */
236 if (g >= font->num_glyphs || !font->glyphs[g])
237 g = 0;
238 if (font->glyphs[g])
239 break;
240 }
241 if (i == nglyphs)
242 goto bail2;
243 glyph = font->glyphs[g];
244 x = glyphs[i].x + glyph->metrics.xOff;
245 y = glyphs[i].y + glyph->metrics.yOff;
246 while (++i < nglyphs)
247 {
248 g = glyphs[i].glyph;
249 /* Substitute default for non-existant glyphs */
250 if (g >= font->num_glyphs || !font->glyphs[g])
251 g = 0;
252 /*
253 * check to see if the glyph is placed where it would
254 * fall using the normal spacing
255 */
256 if ((glyph = font->glyphs[g]))
257 {
258 if (x != glyphs[i].x || y != glyphs[i].y)
259 {
260 x = glyphs[i].x;
261 y = glyphs[i].y;
262 ++nelt;
263 }
264 x += glyph->metrics.xOff;
265 y += glyph->metrics.yOff;
266 }
267 }
268
269 elts = elts_local;
270 if (nelt > NUM_ELT_LOCAL)
271 {
272 elts = malloc ((size_t)nelt * sizeof (XGlyphElt8));
273 if (!elts)
274 goto bail2;
275 }
276
277 /*
278 * Generate the list of glyph elts
279 */
280 nelt = 0;
281 x = y = 0;
282 n = 0;
283 j = 0;
284 for (i = 0; i < nglyphs; i++)
285 {
286 g = glyphs[i].glyph;
287 /* Substitute default for non-existant glyphs */
288 if (g >= font->num_glyphs || !font->glyphs[g])
289 g = 0;
290 if ((glyph = font->glyphs[g]))
291 {
292 if (!i || x != glyphs[i].x || y != glyphs[i].y)
293 {
294 if (n)
295 {
296 elts[nelt].nchars = n;
297 nelt++;
298 }
299 elts[nelt].glyphset = font->glyphset;
300 elts[nelt].chars = char8 + size * j;
301 elts[nelt].xOff = glyphs[i].x - x;
302 elts[nelt].yOff = glyphs[i].y - y;
303 x = glyphs[i].x;
304 y = glyphs[i].y;
305 n = 0;
306 }
307 switch (width) {
308 case 1: char8[j] = (char) g; break;
309 case 2: char16[j] = (unsigned short) g; break;
310 case 4: char32[j] = (unsigned int) g; break;
311 }
312 x += glyph->metrics.xOff;
313 y += glyph->metrics.yOff;
314 j++;
315 n++;
316 }
317 }
318 if (n)
319 {
320 elts[nelt].nchars = n;
321 nelt++;
322 }
323 switch (width) {
324 case 1:
325 XRenderCompositeText8 (dpy, op, src, dst, font->format,
326 srcx, srcy, glyphs[0].x, glyphs[0].y,
327 elts, nelt);
328 break;
329 case 2:
330 XRenderCompositeText16 (dpy, op, src, dst, font->format,
331 srcx, srcy, glyphs[0].x, glyphs[0].y,
332 (XGlyphElt16 *) elts, nelt);
333 break;
334 case 4:
335 XRenderCompositeText32 (dpy, op, src, dst, font->format,
336 srcx, srcy, glyphs[0].x, glyphs[0].y,
337 (XGlyphElt32 *) elts, nelt);
338 break;
339 }
340
341 if (elts != elts_local)
342 free (elts);
343 bail2:
344 if (chars != char_local)
345 free (chars);
346 bail1:
347 if (glyphs_loaded)
348 _XftFontManageMemory (dpy, pub);
349 }
350
351 _X_EXPORT void
XftCharSpecRender(Display * dpy,int op,Picture src,XftFont * pub,Picture dst,int srcx,int srcy,_Xconst XftCharSpec * chars,int len)352 XftCharSpecRender (Display *dpy,
353 int op,
354 Picture src,
355 XftFont *pub,
356 Picture dst,
357 int srcx,
358 int srcy,
359 _Xconst XftCharSpec *chars,
360 int len)
361 {
362 XftGlyphSpec *glyphs, glyphs_local[NUM_LOCAL];
363 int i;
364
365 if (len <= NUM_LOCAL)
366 glyphs = glyphs_local;
367 else
368 {
369 glyphs = malloc ((size_t)len * sizeof (XftGlyphSpec));
370 if (!glyphs)
371 return;
372 }
373 for (i = 0; i < len; i++)
374 {
375 glyphs[i].glyph = XftCharIndex(dpy, pub, chars[i].ucs4);
376 glyphs[i].x = chars[i].x;
377 glyphs[i].y = chars[i].y;
378 }
379
380 XftGlyphSpecRender (dpy, op, src, pub, dst, srcx, srcy, glyphs, len);
381
382 if (glyphs != glyphs_local)
383 free (glyphs);
384 }
385
386 /*
387 * Choose which format to draw text in when drawing with fonts
388 * of different formats. The trick is that ARGB formats aren't
389 * compatible with A formats as PictOpAdd does the wrong thing, so
390 * fall back to an A format when presented with an ARGB and A format
391 */
392
393 #define XftIsARGBFormat(a) ((a)->depth == 32)
394
395 static XRenderPictFormat *
XftPreferFormat(Display * dpy,XRenderPictFormat * a,XRenderPictFormat * b)396 XftPreferFormat (Display *dpy, XRenderPictFormat *a, XRenderPictFormat *b)
397 {
398 XRenderPictFormat *prefer = NULL;
399
400 if (a == b)
401 prefer = a;
402 else if (XftIsARGBFormat(a) != XftIsARGBFormat(b))
403 prefer = XRenderFindStandardFormat (dpy, PictStandardA8);
404 else if (a->depth > b->depth)
405 prefer = a;
406 else
407 prefer = b;
408 return prefer;
409 }
410
411 _X_EXPORT void
XftGlyphFontSpecRender(Display * dpy,int op,Picture src,Picture dst,int srcx,int srcy,_Xconst XftGlyphFontSpec * glyphs,int nglyphs)412 XftGlyphFontSpecRender (Display *dpy,
413 int op,
414 Picture src,
415 Picture dst,
416 int srcx,
417 int srcy,
418 _Xconst XftGlyphFontSpec *glyphs,
419 int nglyphs)
420 {
421 int i, j;
422 XftFont *prevPublic;
423 XftFontInt *firstFont;
424 XRenderPictFormat *format;
425 FT_UInt missing[XFT_NMISSING];
426 int nmissing;
427 int n;
428 FT_UInt g;
429 XftGlyph *glyph;
430 FT_UInt max;
431 int size, width;
432 char *char8;
433 unsigned short *char16;
434 unsigned int *char32;
435 unsigned int char_local[NUM_LOCAL];
436 unsigned int *chars;
437 XGlyphElt8 *elts;
438 XGlyphElt8 elts_local[NUM_ELT_LOCAL];
439 FcBool glyphs_loaded;
440 int nelt;
441 int x, y;
442
443 if (!nglyphs)
444 return;
445
446 /*
447 * Load missing glyphs. Have to load them
448 * one at a time in case the font changes
449 */
450 max = 0;
451 glyphs_loaded = FcFalse;
452 g = glyphs[0].glyph;
453 for (i = 0; i < nglyphs; i++)
454 {
455 XftFont *pub = glyphs[i].font;
456 XftFontInt *font = (XftFontInt *) pub;
457 g = glyphs[i].glyph;
458 if (g > max)
459 max = g;
460 nmissing = 0;
461 if (XftFontCheckGlyph (dpy, pub, FcTrue, g, missing, &nmissing))
462 glyphs_loaded = FcTrue;
463 if (nmissing)
464 XftFontLoadGlyphs (dpy, pub, FcTrue, missing, nmissing);
465 if (!font->format)
466 goto bail1;
467 if (!font->glyphset)
468 goto bail1;
469 }
470
471 /*
472 * See what encoding size is needed
473 */
474 if (max < 0x100)
475 {
476 size = sizeof (char);
477 width = 1;
478 }
479 else if (max < 0x10000)
480 {
481 size = sizeof (unsigned short);
482 width = 2;
483 }
484 else
485 {
486 size = sizeof (unsigned int);
487 width = 4;
488 }
489 chars = char_local;
490 if (nglyphs * size > NUM_LOCAL)
491 {
492 chars = malloc ((size_t)(nglyphs * size));
493 if (!chars)
494 goto bail1;
495 }
496 char8 = (char *) chars;
497 char16 = (unsigned short *) chars;
498 char32 = (unsigned int *) chars;
499
500 /*
501 * Compute the number of glyph elts needed
502 */
503 nelt = 1;
504 firstFont = NULL;
505 for (i = 0; i < nglyphs; i++)
506 {
507 XftFont *pub = glyphs[i].font;
508 XftFontInt *font = (XftFontInt *) pub;
509 g = glyphs[i].glyph;
510 /* Substitute default for non-existant glyphs */
511 if (g >= font->num_glyphs || !font->glyphs[g])
512 g = 0;
513 if (font->glyphs[g])
514 {
515 firstFont = font;
516 break;
517 }
518 }
519 if (i == nglyphs || !firstFont)
520 goto bail2;
521 glyph = firstFont->glyphs[g];
522 format = firstFont->format;
523 x = glyphs[i].x + glyph->metrics.xOff;
524 y = glyphs[i].y + glyph->metrics.yOff;
525 prevPublic = NULL;
526 while (++i < nglyphs)
527 {
528 XftFont *pub = glyphs[i].font;
529 XftFontInt *font = (XftFontInt *) pub;
530 g = glyphs[i].glyph;
531 /* Substitute default for non-existant glyphs */
532 if (g >= font->num_glyphs || !font->glyphs[g])
533 g = 0;
534 /*
535 * check to see if the glyph is placed where it would
536 * fall using the normal spacing
537 */
538 if ((glyph = font->glyphs[g]))
539 {
540 if (pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
541 {
542 prevPublic = pub;
543 if (font->format != format)
544 format = XftPreferFormat (dpy, font->format, format);
545 x = glyphs[i].x;
546 y = glyphs[i].y;
547 ++nelt;
548 }
549 x += glyph->metrics.xOff;
550 y += glyph->metrics.yOff;
551 }
552 }
553
554 elts = elts_local;
555 if (nelt > NUM_ELT_LOCAL)
556 {
557 elts = malloc ((size_t)nelt * sizeof (XGlyphElt8));
558 if (!elts)
559 goto bail2;
560 }
561
562 /*
563 * Generate the list of glyph elts
564 */
565 nelt = 0;
566 x = y = 0;
567 n = 0;
568 j = 0;
569 prevPublic = NULL;
570 for (i = 0; i < nglyphs; i++)
571 {
572 XftFont *pub = glyphs[i].font;
573 XftFontInt *font = (XftFontInt *) pub;
574
575 g = glyphs[i].glyph;
576 /* Substitute default for non-existant glyphs */
577 if (g >= font->num_glyphs || !font->glyphs[g])
578 g = 0;
579 if ((glyph = font->glyphs[g]))
580 {
581 if (!i || pub != prevPublic || x != glyphs[i].x || y != glyphs[i].y)
582 {
583 if (n)
584 {
585 elts[nelt].nchars = n;
586 nelt++;
587 }
588 elts[nelt].glyphset = font->glyphset;
589 elts[nelt].chars = char8 + size * j;
590 elts[nelt].xOff = glyphs[i].x - x;
591 elts[nelt].yOff = glyphs[i].y - y;
592 prevPublic = pub;
593 x = glyphs[i].x;
594 y = glyphs[i].y;
595 n = 0;
596 }
597 switch (width) {
598 case 1: char8[j] = (char) g; break;
599 case 2: char16[j] = (unsigned short) g; break;
600 case 4: char32[j] = (unsigned int) g; break;
601 }
602 x += glyph->metrics.xOff;
603 y += glyph->metrics.yOff;
604 j++;
605 n++;
606 }
607 }
608 if (n)
609 {
610 elts[nelt].nchars = n;
611 nelt++;
612 }
613 switch (width) {
614 case 1:
615 XRenderCompositeText8 (dpy, op, src, dst, format,
616 srcx, srcy, glyphs[0].x, glyphs[0].y,
617 elts, nelt);
618 break;
619 case 2:
620 XRenderCompositeText16 (dpy, op, src, dst, format,
621 srcx, srcy, glyphs[0].x, glyphs[0].y,
622 (XGlyphElt16 *) elts, nelt);
623 break;
624 case 4:
625 XRenderCompositeText32 (dpy, op, src, dst, format,
626 srcx, srcy, glyphs[0].x, glyphs[0].y,
627 (XGlyphElt32 *) elts, nelt);
628 break;
629 }
630
631 if (elts != elts_local)
632 free (elts);
633 bail2:
634 if (chars != char_local)
635 free (chars);
636 bail1:
637 if (glyphs_loaded)
638 for (i = 0; i < nglyphs; i++)
639 _XftFontManageMemory (dpy, glyphs[i].font);
640 }
641
642 _X_EXPORT void
XftCharFontSpecRender(Display * dpy,int op,Picture src,Picture dst,int srcx,int srcy,_Xconst XftCharFontSpec * chars,int len)643 XftCharFontSpecRender (Display *dpy,
644 int op,
645 Picture src,
646 Picture dst,
647 int srcx,
648 int srcy,
649 _Xconst XftCharFontSpec *chars,
650 int len)
651 {
652 XftGlyphFontSpec *glyphs, glyphs_local[NUM_LOCAL];
653 int i;
654
655 if (len <= NUM_LOCAL)
656 glyphs = glyphs_local;
657 else
658 {
659 glyphs = malloc ((size_t)len * sizeof (XftGlyphFontSpec));
660 if (!glyphs)
661 return;
662 }
663 for (i = 0; i < len; i++)
664 {
665 glyphs[i].font = chars[i].font;
666 glyphs[i].glyph = XftCharIndex(dpy, glyphs[i].font, chars[i].ucs4);
667 glyphs[i].x = chars[i].x;
668 glyphs[i].y = chars[i].y;
669 }
670
671 XftGlyphFontSpecRender (dpy, op, src, dst, srcx, srcy, glyphs, len);
672 if (glyphs != glyphs_local)
673 free (glyphs);
674 }
675
676 _X_EXPORT void
XftTextRender8(Display * dpy,int op,Picture src,XftFont * pub,Picture dst,int srcx,int srcy,int x,int y,_Xconst FcChar8 * string,int len)677 XftTextRender8 (Display *dpy,
678 int op,
679 Picture src,
680 XftFont *pub,
681 Picture dst,
682 int srcx,
683 int srcy,
684 int x,
685 int y,
686 _Xconst FcChar8 *string,
687 int len)
688 {
689 FT_UInt *glyphs, glyphs_local[NUM_LOCAL];
690 int i;
691
692 if (len <= NUM_LOCAL)
693 glyphs = glyphs_local;
694 else
695 {
696 glyphs = malloc ((size_t)len * sizeof (FT_UInt));
697 if (!glyphs)
698 return;
699 }
700 for (i = 0; i < len; i++)
701 glyphs[i] = XftCharIndex (dpy, pub, string[i]);
702 XftGlyphRender (dpy, op, src, pub, dst,
703 srcx, srcy, x, y, glyphs, len);
704 if (glyphs != glyphs_local)
705 free (glyphs);
706 }
707
708 _X_EXPORT void
XftTextRender16(Display * dpy,int op,Picture src,XftFont * pub,Picture dst,int srcx,int srcy,int x,int y,_Xconst FcChar16 * string,int len)709 XftTextRender16 (Display *dpy,
710 int op,
711 Picture src,
712 XftFont *pub,
713 Picture dst,
714 int srcx,
715 int srcy,
716 int x,
717 int y,
718 _Xconst FcChar16 *string,
719 int len)
720 {
721 FT_UInt *glyphs, glyphs_local[NUM_LOCAL];
722 int i;
723
724 if (len <= NUM_LOCAL)
725 glyphs = glyphs_local;
726 else
727 {
728 glyphs = malloc ((size_t)len * sizeof (FT_UInt));
729 if (!glyphs)
730 return;
731 }
732 for (i = 0; i < len; i++)
733 glyphs[i] = XftCharIndex (dpy, pub, string[i]);
734 XftGlyphRender (dpy, op, src, pub, dst,
735 srcx, srcy, x, y, glyphs, len);
736 if (glyphs != glyphs_local)
737 free (glyphs);
738 }
739
740 _X_EXPORT void
XftTextRender16BE(Display * dpy,int op,Picture src,XftFont * pub,Picture dst,int srcx,int srcy,int x,int y,_Xconst FcChar8 * string,int len)741 XftTextRender16BE (Display *dpy,
742 int op,
743 Picture src,
744 XftFont *pub,
745 Picture dst,
746 int srcx,
747 int srcy,
748 int x,
749 int y,
750 _Xconst FcChar8 *string,
751 int len)
752 {
753 FT_UInt *glyphs, glyphs_local[NUM_LOCAL];
754 int i;
755
756 if (len <= NUM_LOCAL)
757 glyphs = glyphs_local;
758 else
759 {
760 glyphs = malloc ((size_t)len * sizeof (FT_UInt));
761 if (!glyphs)
762 return;
763 }
764 for (i = 0; i < len; i++)
765 glyphs[i] = XftCharIndex (dpy, pub,
766 (FcChar32)((string[i*2]<<8) | string[i*2+1]));
767 XftGlyphRender (dpy, op, src, pub, dst,
768 srcx, srcy, x, y, glyphs, len);
769 if (glyphs != glyphs_local)
770 free (glyphs);
771 }
772
773 _X_EXPORT void
XftTextRender16LE(Display * dpy,int op,Picture src,XftFont * pub,Picture dst,int srcx,int srcy,int x,int y,_Xconst FcChar8 * string,int len)774 XftTextRender16LE (Display *dpy,
775 int op,
776 Picture src,
777 XftFont *pub,
778 Picture dst,
779 int srcx,
780 int srcy,
781 int x,
782 int y,
783 _Xconst FcChar8 *string,
784 int len)
785 {
786 FT_UInt *glyphs, glyphs_local[NUM_LOCAL];
787 int i;
788
789 if (len <= NUM_LOCAL)
790 glyphs = glyphs_local;
791 else
792 {
793 glyphs = malloc ((size_t)len * sizeof (FT_UInt));
794 if (!glyphs)
795 return;
796 }
797 for (i = 0; i < len; i++)
798 glyphs[i] = XftCharIndex (dpy, pub,
799 (FcChar32)(string[i*2] | (string[i*2+1]<<8)));
800 XftGlyphRender (dpy, op, src, pub, dst,
801 srcx, srcy, x, y, glyphs, len);
802 if (glyphs != glyphs_local)
803 free (glyphs);
804 }
805
806 _X_EXPORT void
XftTextRender32(Display * dpy,int op,Picture src,XftFont * pub,Picture dst,int srcx,int srcy,int x,int y,_Xconst FcChar32 * string,int len)807 XftTextRender32 (Display *dpy,
808 int op,
809 Picture src,
810 XftFont *pub,
811 Picture dst,
812 int srcx,
813 int srcy,
814 int x,
815 int y,
816 _Xconst FcChar32 *string,
817 int len)
818 {
819 FT_UInt *glyphs, glyphs_local[NUM_LOCAL];
820 int i;
821
822 if (len <= NUM_LOCAL)
823 glyphs = glyphs_local;
824 else
825 {
826 glyphs = malloc ((size_t)len * sizeof (FT_UInt));
827 if (!glyphs)
828 return;
829 }
830 for (i = 0; i < len; i++)
831 glyphs[i] = XftCharIndex (dpy, pub, string[i]);
832 XftGlyphRender (dpy, op, src, pub, dst,
833 srcx, srcy, x, y, glyphs, len);
834 if (glyphs != glyphs_local)
835 free (glyphs);
836 }
837
838 _X_EXPORT void
XftTextRender32BE(Display * dpy,int op,Picture src,XftFont * pub,Picture dst,int srcx,int srcy,int x,int y,_Xconst FcChar8 * string,int len)839 XftTextRender32BE (Display *dpy,
840 int op,
841 Picture src,
842 XftFont *pub,
843 Picture dst,
844 int srcx,
845 int srcy,
846 int x,
847 int y,
848 _Xconst FcChar8 *string,
849 int len)
850 {
851 FT_UInt *glyphs, glyphs_local[NUM_LOCAL];
852 int i;
853
854 if (len <= NUM_LOCAL)
855 glyphs = glyphs_local;
856 else
857 {
858 glyphs = malloc ((size_t)len * sizeof (FT_UInt));
859 if (!glyphs)
860 return;
861 }
862 for (i = 0; i < len; i++)
863 glyphs[i] = XftCharIndex (dpy, pub,
864 (FcChar32)((string[i*4] << 24) |
865 (string[i*4+1] << 16) |
866 (string[i*4+2] << 8) |
867 (string[i*4+3])));
868 XftGlyphRender (dpy, op, src, pub, dst,
869 srcx, srcy, x, y, glyphs, len);
870 if (glyphs != glyphs_local)
871 free (glyphs);
872 }
873
874 _X_EXPORT void
XftTextRender32LE(Display * dpy,int op,Picture src,XftFont * pub,Picture dst,int srcx,int srcy,int x,int y,_Xconst FcChar8 * string,int len)875 XftTextRender32LE (Display *dpy,
876 int op,
877 Picture src,
878 XftFont *pub,
879 Picture dst,
880 int srcx,
881 int srcy,
882 int x,
883 int y,
884 _Xconst FcChar8 *string,
885 int len)
886 {
887 FT_UInt *glyphs, glyphs_local[NUM_LOCAL];
888 int i;
889
890 if (len <= NUM_LOCAL)
891 glyphs = glyphs_local;
892 else
893 {
894 glyphs = malloc ((size_t)len * sizeof (FT_UInt));
895 if (!glyphs)
896 return;
897 }
898 for (i = 0; i < len; i++)
899 glyphs[i] = XftCharIndex (dpy, pub,
900 (FcChar32)((string[i*4]) |
901 (string[i*4+1] << 8) |
902 (string[i*4+2] << 16) |
903 (string[i*4+3] << 24)));
904 XftGlyphRender (dpy, op, src, pub, dst,
905 srcx, srcy, x, y, glyphs, len);
906 if (glyphs != glyphs_local)
907 free (glyphs);
908 }
909
910 _X_EXPORT void
XftTextRenderUtf8(Display * dpy,int op,Picture src,XftFont * pub,Picture dst,int srcx,int srcy,int x,int y,_Xconst FcChar8 * string,int len)911 XftTextRenderUtf8 (Display *dpy,
912 int op,
913 Picture src,
914 XftFont *pub,
915 Picture dst,
916 int srcx,
917 int srcy,
918 int x,
919 int y,
920 _Xconst FcChar8 *string,
921 int len)
922 {
923 FT_UInt *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL];
924 FcChar32 ucs4;
925 int i;
926 int l;
927 int size;
928
929 i = 0;
930 glyphs = glyphs_local;
931 size = NUM_LOCAL;
932 while (len && (l = FcUtf8ToUcs4 (string, &ucs4, len)) > 0)
933 {
934 if (i == size)
935 {
936 glyphs_new = malloc ((size_t)size * 2 * sizeof (FT_UInt));
937 if (!glyphs_new)
938 {
939 if (glyphs != glyphs_local)
940 free (glyphs);
941 return;
942 }
943 memcpy (glyphs_new, glyphs, (size_t)size * sizeof (FT_UInt));
944 size *= 2;
945 if (glyphs != glyphs_local)
946 free (glyphs);
947 glyphs = glyphs_new;
948 }
949 glyphs[i++] = XftCharIndex (dpy, pub, ucs4);
950 string += l;
951 len -= l;
952 }
953 XftGlyphRender (dpy, op, src, pub, dst,
954 srcx, srcy, x, y, glyphs, i);
955 if (glyphs != glyphs_local)
956 free (glyphs);
957 }
958
959 _X_EXPORT void
XftTextRenderUtf16(Display * dpy,int op,Picture src,XftFont * pub,Picture dst,int srcx,int srcy,int x,int y,_Xconst FcChar8 * string,FcEndian endian,int len)960 XftTextRenderUtf16 (Display *dpy,
961 int op,
962 Picture src,
963 XftFont *pub,
964 Picture dst,
965 int srcx,
966 int srcy,
967 int x,
968 int y,
969 _Xconst FcChar8 *string,
970 FcEndian endian,
971 int len)
972 {
973 FT_UInt *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL];
974 FcChar32 ucs4;
975 int i;
976 int l;
977 int size;
978
979 i = 0;
980 glyphs = glyphs_local;
981 size = NUM_LOCAL;
982 while (len && (l = FcUtf16ToUcs4 (string, endian, &ucs4, len)) > 0)
983 {
984 if (i == size)
985 {
986 glyphs_new = malloc ((size_t)size * 2 * sizeof (FT_UInt));
987 if (!glyphs_new)
988 {
989 if (glyphs != glyphs_local)
990 free (glyphs);
991 return;
992 }
993 memcpy (glyphs_new, glyphs, (size_t)size * sizeof (FT_UInt));
994 size *= 2;
995 if (glyphs != glyphs_local)
996 free (glyphs);
997 glyphs = glyphs_new;
998 }
999 glyphs[i++] = XftCharIndex (dpy, pub, ucs4);
1000 string += l;
1001 len -= l;
1002 }
1003 XftGlyphRender (dpy, PictOpOver, src, pub, dst,
1004 srcx, srcy, x, y, glyphs, i);
1005 if (glyphs != glyphs_local)
1006 free (glyphs);
1007 }
1008