diff options
| author | YAMAMOTO Mitsuharu | 2019-06-08 14:05:49 +0900 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2019-06-08 14:05:49 +0900 |
| commit | faf10bd8eb3272880b774fe220fa9916ed1f00c0 (patch) | |
| tree | f933e9f012e0c96effefb02daa31ead9acc22aed /src | |
| parent | 88c49ac31898e7b2c29338ca55cae292c450f7be (diff) | |
| download | emacs-faf10bd8eb3272880b774fe220fa9916ed1f00c0.tar.gz emacs-faf10bd8eb3272880b774fe220fa9916ed1f00c0.zip | |
Support X core font driver on cairo (Bug#28236)
* configure.ac (HAVE_X_WINDOWS): Add xfont.o to FONT_OBJ if HAVE_CAIRO.
* doc/lispref/frames.texi (Font and Color Parameters): Mention X core font
driver with Cairo drawing.
* src/font.c (syms_of_font) [HAVE_X_WINDOWS && USE_CAIRO]: Call syms_of_xfont.
* src/xfns.c (x_create_tip_frame) [USE_CAIRO]: Register xfont_driver.
* src/xterm.c (x_cr_gc_clip) [USE_CAIRO]: New function extracted from
x_begin_cr_clip.
(x_begin_cr_clip) [USE_CAIRO]: Use it.
(xlib_surface_key, saved_drawable_key) [USE_CAIRO]: New variables.
(x_cr_destroy_xlib_surface, x_try_cr_xlib_drawable)
(x_end_cr_xlib_drawable) [USE_CAIRO]: New functions.
(x_draw_composite_glyph_string_foreground)
(x_draw_glyph_string_foreground) [USE_CAIRO]: Get Xlib surface when drawing
text with X core fonts into bitmap surfaces. Add fallback code for drawing
into outline surfaces.
Diffstat (limited to 'src')
| -rw-r--r-- | src/font.c | 2 | ||||
| -rw-r--r-- | src/xfns.c | 2 | ||||
| -rw-r--r-- | src/xterm.c | 341 |
3 files changed, 261 insertions, 84 deletions
diff --git a/src/font.c b/src/font.c index 6ab4923c3d2..5705758b99f 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -5497,10 +5497,10 @@ cause Xft crashes. Only has an effect in Xft builds. */); | |||
| 5497 | #ifdef HAVE_FREETYPE | 5497 | #ifdef HAVE_FREETYPE |
| 5498 | syms_of_ftfont (); | 5498 | syms_of_ftfont (); |
| 5499 | #ifdef HAVE_X_WINDOWS | 5499 | #ifdef HAVE_X_WINDOWS |
| 5500 | syms_of_xfont (); | ||
| 5500 | #ifdef USE_CAIRO | 5501 | #ifdef USE_CAIRO |
| 5501 | syms_of_ftcrfont (); | 5502 | syms_of_ftcrfont (); |
| 5502 | #else | 5503 | #else |
| 5503 | syms_of_xfont (); | ||
| 5504 | syms_of_ftxfont (); | 5504 | syms_of_ftxfont (); |
| 5505 | #ifdef HAVE_XFT | 5505 | #ifdef HAVE_XFT |
| 5506 | syms_of_xftfont (); | 5506 | syms_of_xftfont (); |
diff --git a/src/xfns.c b/src/xfns.c index 460dd1316e6..46f19ff82ac 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -3794,8 +3794,8 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 3794 | register_font_driver (&ftxfont_driver, f); | 3794 | register_font_driver (&ftxfont_driver, f); |
| 3795 | #endif /* not HAVE_XFT */ | 3795 | #endif /* not HAVE_XFT */ |
| 3796 | #endif /* HAVE_FREETYPE */ | 3796 | #endif /* HAVE_FREETYPE */ |
| 3797 | register_font_driver (&xfont_driver, f); | ||
| 3798 | #endif /* not USE_CAIRO */ | 3797 | #endif /* not USE_CAIRO */ |
| 3798 | register_font_driver (&xfont_driver, f); | ||
| 3799 | 3799 | ||
| 3800 | image_cache_refcount = | 3800 | image_cache_refcount = |
| 3801 | FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; | 3801 | FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; |
diff --git a/src/xterm.c b/src/xterm.c index e0edd9c1a40..3cd95b7a65d 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -357,6 +357,25 @@ x_cr_update_surface_desired_size (struct frame *f, int width, int height) | |||
| 357 | } | 357 | } |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | static void | ||
| 361 | x_cr_gc_clip (cairo_t *cr, struct frame *f, GC gc) | ||
| 362 | { | ||
| 363 | if (gc) | ||
| 364 | { | ||
| 365 | struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0); | ||
| 366 | |||
| 367 | if (gc_ext && gc_ext->n_clip_rects) | ||
| 368 | { | ||
| 369 | for (int i = 0; i < gc_ext->n_clip_rects; i++) | ||
| 370 | cairo_rectangle (cr, gc_ext->clip_rects[i].x, | ||
| 371 | gc_ext->clip_rects[i].y, | ||
| 372 | gc_ext->clip_rects[i].width, | ||
| 373 | gc_ext->clip_rects[i].height); | ||
| 374 | cairo_clip (cr); | ||
| 375 | } | ||
| 376 | } | ||
| 377 | } | ||
| 378 | |||
| 360 | cairo_t * | 379 | cairo_t * |
| 361 | x_begin_cr_clip (struct frame *f, GC gc) | 380 | x_begin_cr_clip (struct frame *f, GC gc) |
| 362 | { | 381 | { |
| @@ -379,23 +398,7 @@ x_begin_cr_clip (struct frame *f, GC gc) | |||
| 379 | cairo_surface_destroy (surface); | 398 | cairo_surface_destroy (surface); |
| 380 | } | 399 | } |
| 381 | cairo_save (cr); | 400 | cairo_save (cr); |
| 382 | 401 | x_cr_gc_clip (cr, f, gc); | |
| 383 | if (gc) | ||
| 384 | { | ||
| 385 | struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0); | ||
| 386 | |||
| 387 | if (gc_ext && gc_ext->n_clip_rects) | ||
| 388 | { | ||
| 389 | int i; | ||
| 390 | |||
| 391 | for (i = 0; i < gc_ext->n_clip_rects; i++) | ||
| 392 | cairo_rectangle (cr, gc_ext->clip_rects[i].x, | ||
| 393 | gc_ext->clip_rects[i].y, | ||
| 394 | gc_ext->clip_rects[i].width, | ||
| 395 | gc_ext->clip_rects[i].height); | ||
| 396 | cairo_clip (cr); | ||
| 397 | } | ||
| 398 | } | ||
| 399 | 402 | ||
| 400 | return cr; | 403 | return cr; |
| 401 | } | 404 | } |
| @@ -434,6 +437,116 @@ x_set_cr_source_with_gc_background (struct frame *f, GC gc) | |||
| 434 | color.green / 65535.0, color.blue / 65535.0); | 437 | color.green / 65535.0, color.blue / 65535.0); |
| 435 | } | 438 | } |
| 436 | 439 | ||
| 440 | static const cairo_user_data_key_t xlib_surface_key, saved_drawable_key; | ||
| 441 | |||
| 442 | static void | ||
| 443 | x_cr_destroy_xlib_surface (cairo_surface_t *xlib_surface) | ||
| 444 | { | ||
| 445 | if (xlib_surface) | ||
| 446 | { | ||
| 447 | XFreePixmap (cairo_xlib_surface_get_display (xlib_surface), | ||
| 448 | cairo_xlib_surface_get_drawable (xlib_surface)); | ||
| 449 | cairo_surface_destroy (xlib_surface); | ||
| 450 | } | ||
| 451 | } | ||
| 452 | |||
| 453 | static bool | ||
| 454 | x_try_cr_xlib_drawable (struct frame *f, GC gc) | ||
| 455 | { | ||
| 456 | cairo_t *cr = FRAME_CR_CONTEXT (f); | ||
| 457 | if (!cr) | ||
| 458 | return true; | ||
| 459 | |||
| 460 | cairo_surface_t *surface = cairo_get_target (cr); | ||
| 461 | switch (cairo_surface_get_type (surface)) | ||
| 462 | { | ||
| 463 | case CAIRO_SURFACE_TYPE_XLIB: | ||
| 464 | cairo_surface_flush (surface); | ||
| 465 | return true; | ||
| 466 | |||
| 467 | case CAIRO_SURFACE_TYPE_IMAGE: | ||
| 468 | break; | ||
| 469 | |||
| 470 | default: | ||
| 471 | return false; | ||
| 472 | } | ||
| 473 | |||
| 474 | /* FRAME_CR_CONTEXT (f) is an image surface we can not draw into | ||
| 475 | directly with Xlib. Set up a Pixmap so we can copy back the | ||
| 476 | result later in x_end_cr_xlib_drawable. */ | ||
| 477 | cairo_surface_t *xlib_surface = cairo_get_user_data (cr, &xlib_surface_key); | ||
| 478 | int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f); | ||
| 479 | int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f); | ||
| 480 | Pixmap pixmap; | ||
| 481 | if (xlib_surface | ||
| 482 | && cairo_xlib_surface_get_width (xlib_surface) == width | ||
| 483 | && cairo_xlib_surface_get_height (xlib_surface) == height) | ||
| 484 | pixmap = cairo_xlib_surface_get_drawable (xlib_surface); | ||
| 485 | else | ||
| 486 | { | ||
| 487 | pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_RAW_DRAWABLE (f), | ||
| 488 | width, height, | ||
| 489 | DefaultDepthOfScreen (FRAME_X_SCREEN (f))); | ||
| 490 | xlib_surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f), | ||
| 491 | pixmap, FRAME_X_VISUAL (f), | ||
| 492 | width, height); | ||
| 493 | cairo_set_user_data (cr, &xlib_surface_key, xlib_surface, | ||
| 494 | (cairo_destroy_func_t) x_cr_destroy_xlib_surface); | ||
| 495 | } | ||
| 496 | |||
| 497 | cairo_t *buf = cairo_create (xlib_surface); | ||
| 498 | cairo_set_source_surface (buf, surface, 0, 0); | ||
| 499 | cairo_matrix_t matrix; | ||
| 500 | cairo_get_matrix (cr, &matrix); | ||
| 501 | cairo_pattern_set_matrix (cairo_get_source (cr), &matrix); | ||
| 502 | cairo_set_operator (buf, CAIRO_OPERATOR_SOURCE); | ||
| 503 | x_cr_gc_clip (buf, f, gc); | ||
| 504 | cairo_paint (buf); | ||
| 505 | cairo_destroy (buf); | ||
| 506 | |||
| 507 | cairo_set_user_data (cr, &saved_drawable_key, | ||
| 508 | (void *) (uintptr_t) FRAME_X_RAW_DRAWABLE (f), NULL); | ||
| 509 | FRAME_X_RAW_DRAWABLE (f) = pixmap; | ||
| 510 | cairo_surface_flush (xlib_surface); | ||
| 511 | |||
| 512 | return true; | ||
| 513 | } | ||
| 514 | |||
| 515 | static void | ||
| 516 | x_end_cr_xlib_drawable (struct frame *f, GC gc) | ||
| 517 | { | ||
| 518 | cairo_t *cr = FRAME_CR_CONTEXT (f); | ||
| 519 | if (!cr) | ||
| 520 | return; | ||
| 521 | |||
| 522 | Drawable saved_drawable | ||
| 523 | = (uintptr_t) cairo_get_user_data (cr, &saved_drawable_key); | ||
| 524 | cairo_surface_t *surface = (saved_drawable | ||
| 525 | ? cairo_get_user_data (cr, &xlib_surface_key) | ||
| 526 | : cairo_get_target (cr)); | ||
| 527 | struct x_gc_ext_data *gc_ext = x_gc_get_ext_data (f, gc, 0); | ||
| 528 | if (gc_ext && gc_ext->n_clip_rects) | ||
| 529 | for (int i = 0; i < gc_ext->n_clip_rects; i++) | ||
| 530 | cairo_surface_mark_dirty_rectangle (surface, gc_ext->clip_rects[i].x, | ||
| 531 | gc_ext->clip_rects[i].y, | ||
| 532 | gc_ext->clip_rects[i].width, | ||
| 533 | gc_ext->clip_rects[i].height); | ||
| 534 | else | ||
| 535 | cairo_surface_mark_dirty (surface); | ||
| 536 | if (!saved_drawable) | ||
| 537 | return; | ||
| 538 | |||
| 539 | cairo_save (cr); | ||
| 540 | cairo_set_source_surface (cr, surface, 0, 0); | ||
| 541 | cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); | ||
| 542 | x_cr_gc_clip (cr, f, gc); | ||
| 543 | cairo_paint (cr); | ||
| 544 | cairo_restore (cr); | ||
| 545 | |||
| 546 | FRAME_X_RAW_DRAWABLE (f) = saved_drawable; | ||
| 547 | cairo_set_user_data (cr, &saved_drawable_key, NULL, NULL); | ||
| 548 | } | ||
| 549 | |||
| 437 | /* Fringe bitmaps. */ | 550 | /* Fringe bitmaps. */ |
| 438 | 551 | ||
| 439 | static int max_fringe_bmp = 0; | 552 | static int max_fringe_bmp = 0; |
| @@ -1732,20 +1845,65 @@ x_draw_glyph_string_foreground (struct glyph_string *s) | |||
| 1732 | else | 1845 | else |
| 1733 | { | 1846 | { |
| 1734 | struct font *font = s->font; | 1847 | struct font *font = s->font; |
| 1735 | int boff = font->baseline_offset; | 1848 | #ifdef USE_CAIRO |
| 1736 | int y; | 1849 | if (!EQ (font->driver->type, Qx) |
| 1850 | || x_try_cr_xlib_drawable (s->f, s->gc)) | ||
| 1851 | { | ||
| 1852 | #endif /* USE_CAIRO */ | ||
| 1853 | int boff = font->baseline_offset; | ||
| 1854 | int y; | ||
| 1737 | 1855 | ||
| 1738 | if (font->vertical_centering) | 1856 | if (font->vertical_centering) |
| 1739 | boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff; | 1857 | boff = VCENTER_BASELINE_OFFSET (font, s->f) - boff; |
| 1740 | 1858 | ||
| 1741 | y = s->ybase - boff; | 1859 | y = s->ybase - boff; |
| 1742 | if (s->for_overlaps | 1860 | if (s->for_overlaps |
| 1743 | || (s->background_filled_p && s->hl != DRAW_CURSOR)) | 1861 | || (s->background_filled_p && s->hl != DRAW_CURSOR)) |
| 1744 | font->driver->draw (s, 0, s->nchars, x, y, false); | 1862 | font->driver->draw (s, 0, s->nchars, x, y, false); |
| 1863 | else | ||
| 1864 | font->driver->draw (s, 0, s->nchars, x, y, true); | ||
| 1865 | if (s->face->overstrike) | ||
| 1866 | font->driver->draw (s, 0, s->nchars, x + 1, y, false); | ||
| 1867 | #ifdef USE_CAIRO | ||
| 1868 | if (EQ (font->driver->type, Qx)) | ||
| 1869 | x_end_cr_xlib_drawable (s->f, s->gc); | ||
| 1870 | } | ||
| 1745 | else | 1871 | else |
| 1746 | font->driver->draw (s, 0, s->nchars, x, y, true); | 1872 | { |
| 1747 | if (s->face->overstrike) | 1873 | /* Fallback for the case that no Xlib Drawable is available |
| 1748 | font->driver->draw (s, 0, s->nchars, x + 1, y, false); | 1874 | for drawing text with X core fonts. */ |
| 1875 | if (!(s->for_overlaps | ||
| 1876 | || (s->background_filled_p && s->hl != DRAW_CURSOR))) | ||
| 1877 | { | ||
| 1878 | int box_line_width = max (s->face->box_line_width, 0); | ||
| 1879 | |||
| 1880 | if (s->stippled_p) | ||
| 1881 | { | ||
| 1882 | Display *display = FRAME_X_DISPLAY (s->f); | ||
| 1883 | |||
| 1884 | /* Fill background with a stipple pattern. */ | ||
| 1885 | XSetFillStyle (display, s->gc, FillOpaqueStippled); | ||
| 1886 | x_fill_rectangle (s->f, s->gc, s->x, | ||
| 1887 | s->y + box_line_width, | ||
| 1888 | s->background_width, | ||
| 1889 | s->height - 2 * box_line_width); | ||
| 1890 | XSetFillStyle (display, s->gc, FillSolid); | ||
| 1891 | } | ||
| 1892 | else | ||
| 1893 | x_clear_glyph_string_rect (s, s->x, s->y + box_line_width, | ||
| 1894 | s->background_width, | ||
| 1895 | s->height - 2 * box_line_width); | ||
| 1896 | } | ||
| 1897 | for (i = 0; i < s->nchars; ++i) | ||
| 1898 | { | ||
| 1899 | struct glyph *g = s->first_glyph + i; | ||
| 1900 | x_draw_rectangle (s->f, | ||
| 1901 | s->gc, x, s->y, g->pixel_width - 1, | ||
| 1902 | s->height - 1); | ||
| 1903 | x += g->pixel_width; | ||
| 1904 | } | ||
| 1905 | } | ||
| 1906 | #endif /* USE_CAIRO */ | ||
| 1749 | } | 1907 | } |
| 1750 | } | 1908 | } |
| 1751 | 1909 | ||
| @@ -1778,65 +1936,84 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s) | |||
| 1778 | x_draw_rectangle (s->f, s->gc, x, s->y, | 1936 | x_draw_rectangle (s->f, s->gc, x, s->y, |
| 1779 | s->width - 1, s->height - 1); | 1937 | s->width - 1, s->height - 1); |
| 1780 | } | 1938 | } |
| 1781 | else if (! s->first_glyph->u.cmp.automatic) | ||
| 1782 | { | ||
| 1783 | int y = s->ybase; | ||
| 1784 | |||
| 1785 | for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++) | ||
| 1786 | /* TAB in a composition means display glyphs with padding | ||
| 1787 | space on the left or right. */ | ||
| 1788 | if (COMPOSITION_GLYPH (s->cmp, j) != '\t') | ||
| 1789 | { | ||
| 1790 | int xx = x + s->cmp->offsets[j * 2]; | ||
| 1791 | int yy = y - s->cmp->offsets[j * 2 + 1]; | ||
| 1792 | |||
| 1793 | font->driver->draw (s, j, j + 1, xx, yy, false); | ||
| 1794 | if (s->face->overstrike) | ||
| 1795 | font->driver->draw (s, j, j + 1, xx + 1, yy, false); | ||
| 1796 | } | ||
| 1797 | } | ||
| 1798 | else | 1939 | else |
| 1799 | { | 1940 | #ifdef USE_CAIRO |
| 1800 | Lisp_Object gstring = composition_gstring_from_id (s->cmp_id); | 1941 | if (!EQ (font->driver->type, Qx) |
| 1801 | Lisp_Object glyph; | 1942 | || x_try_cr_xlib_drawable (s->f, s->gc)) |
| 1802 | int y = s->ybase; | 1943 | { |
| 1803 | int width = 0; | 1944 | #endif /* USE_CAIRO */ |
| 1804 | 1945 | if (! s->first_glyph->u.cmp.automatic) | |
| 1805 | for (i = j = s->cmp_from; i < s->cmp_to; i++) | 1946 | { |
| 1806 | { | 1947 | int y = s->ybase; |
| 1807 | glyph = LGSTRING_GLYPH (gstring, i); | ||
| 1808 | if (NILP (LGLYPH_ADJUSTMENT (glyph))) | ||
| 1809 | width += LGLYPH_WIDTH (glyph); | ||
| 1810 | else | ||
| 1811 | { | ||
| 1812 | int xoff, yoff, wadjust; | ||
| 1813 | 1948 | ||
| 1814 | if (j < i) | 1949 | for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++) |
| 1950 | /* TAB in a composition means display glyphs with | ||
| 1951 | padding space on the left or right. */ | ||
| 1952 | if (COMPOSITION_GLYPH (s->cmp, j) != '\t') | ||
| 1815 | { | 1953 | { |
| 1816 | font->driver->draw (s, j, i, x, y, false); | 1954 | int xx = x + s->cmp->offsets[j * 2]; |
| 1955 | int yy = y - s->cmp->offsets[j * 2 + 1]; | ||
| 1956 | |||
| 1957 | font->driver->draw (s, j, j + 1, xx, yy, false); | ||
| 1817 | if (s->face->overstrike) | 1958 | if (s->face->overstrike) |
| 1818 | font->driver->draw (s, j, i, x + 1, y, false); | 1959 | font->driver->draw (s, j, j + 1, xx + 1, yy, false); |
| 1819 | x += width; | ||
| 1820 | } | 1960 | } |
| 1821 | xoff = LGLYPH_XOFF (glyph); | 1961 | } |
| 1822 | yoff = LGLYPH_YOFF (glyph); | 1962 | else |
| 1823 | wadjust = LGLYPH_WADJUST (glyph); | 1963 | { |
| 1824 | font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false); | 1964 | Lisp_Object gstring = composition_gstring_from_id (s->cmp_id); |
| 1825 | if (s->face->overstrike) | 1965 | Lisp_Object glyph; |
| 1826 | font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff, | 1966 | int y = s->ybase; |
| 1827 | false); | 1967 | int width = 0; |
| 1828 | x += wadjust; | 1968 | |
| 1829 | j = i + 1; | 1969 | for (i = j = s->cmp_from; i < s->cmp_to; i++) |
| 1830 | width = 0; | 1970 | { |
| 1831 | } | 1971 | glyph = LGSTRING_GLYPH (gstring, i); |
| 1832 | } | 1972 | if (NILP (LGLYPH_ADJUSTMENT (glyph))) |
| 1833 | if (j < i) | 1973 | width += LGLYPH_WIDTH (glyph); |
| 1834 | { | 1974 | else |
| 1835 | font->driver->draw (s, j, i, x, y, false); | 1975 | { |
| 1836 | if (s->face->overstrike) | 1976 | int xoff, yoff, wadjust; |
| 1837 | font->driver->draw (s, j, i, x + 1, y, false); | 1977 | |
| 1838 | } | 1978 | if (j < i) |
| 1839 | } | 1979 | { |
| 1980 | font->driver->draw (s, j, i, x, y, false); | ||
| 1981 | if (s->face->overstrike) | ||
| 1982 | font->driver->draw (s, j, i, x + 1, y, false); | ||
| 1983 | x += width; | ||
| 1984 | } | ||
| 1985 | xoff = LGLYPH_XOFF (glyph); | ||
| 1986 | yoff = LGLYPH_YOFF (glyph); | ||
| 1987 | wadjust = LGLYPH_WADJUST (glyph); | ||
| 1988 | font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false); | ||
| 1989 | if (s->face->overstrike) | ||
| 1990 | font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff, | ||
| 1991 | false); | ||
| 1992 | x += wadjust; | ||
| 1993 | j = i + 1; | ||
| 1994 | width = 0; | ||
| 1995 | } | ||
| 1996 | } | ||
| 1997 | if (j < i) | ||
| 1998 | { | ||
| 1999 | font->driver->draw (s, j, i, x, y, false); | ||
| 2000 | if (s->face->overstrike) | ||
| 2001 | font->driver->draw (s, j, i, x + 1, y, false); | ||
| 2002 | } | ||
| 2003 | } | ||
| 2004 | #ifdef USE_CAIRO | ||
| 2005 | if (EQ (font->driver->type, Qx)) | ||
| 2006 | x_end_cr_xlib_drawable (s->f, s->gc); | ||
| 2007 | } | ||
| 2008 | else | ||
| 2009 | { | ||
| 2010 | /* Fallback for the case that no Xlib Drawable is available | ||
| 2011 | for drawing text with X core fonts. */ | ||
| 2012 | if (s->cmp_from == 0) | ||
| 2013 | x_draw_rectangle (s->f, s->gc, x, s->y, | ||
| 2014 | s->width - 1, s->height - 1); | ||
| 2015 | } | ||
| 2016 | #endif /* USE_CAIRO */ | ||
| 1840 | } | 2017 | } |
| 1841 | 2018 | ||
| 1842 | 2019 | ||