Mercurial > hg > xemacs-beta
comparison src/redisplay-x.c @ 3094:ad2f4ae9895b
[xemacs-hg @ 2005-11-26 11:45:47 by stephent]
Xft merge. <87k6ev4p8q.fsf@tleepslib.sk.tsukuba.ac.jp>
author | stephent |
---|---|
date | Sat, 26 Nov 2005 11:46:25 +0000 |
parents | 3d8143fc88e1 |
children | d1754e7f0cea |
comparison
equal
deleted
inserted
replaced
3093:769dc945b085 | 3094:ad2f4ae9895b |
---|---|
56 #include "sysproc.h" /* for select() */ | 56 #include "sysproc.h" /* for select() */ |
57 | 57 |
58 #include <X11/bitmaps/gray> | 58 #include <X11/bitmaps/gray> |
59 | 59 |
60 /* Number of pixels below each line. */ | 60 /* Number of pixels below each line. */ |
61 int x_interline_space; /* #### implement me */ | 61 int x_interline_space; /* #### this needs to be implemented, but per-font */ |
62 | 62 |
63 #define EOL_CURSOR_WIDTH 5 | 63 #define EOL_CURSOR_WIDTH 5 |
64 | 64 |
65 static void x_output_vertical_divider (struct window *w, int clear); | 65 static void x_output_vertical_divider (struct window *w, int clear); |
66 static void x_output_blank (struct window *w, struct display_line *dl, | 66 static void x_output_blank (struct window *w, struct display_line *dl, |
71 static void x_output_eol_cursor (struct window *w, struct display_line *dl, | 71 static void x_output_eol_cursor (struct window *w, struct display_line *dl, |
72 int xpos, face_index findex); | 72 int xpos, face_index findex); |
73 static void x_clear_frame (struct frame *f); | 73 static void x_clear_frame (struct frame *f); |
74 static void x_clear_frame_windows (Lisp_Object window); | 74 static void x_clear_frame_windows (Lisp_Object window); |
75 | 75 |
76 #ifdef USE_XFT | |
77 #define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \ | |
78 ? ((unsigned long) (x)) : ((unsigned long) (y))) | |
79 #endif /* USE_XFT */ | |
80 | |
76 | 81 |
77 /* Note: We do not use the Xmb*() functions and XFontSets. | 82 /* Note: We do not use the Xmb*() functions and XFontSets. |
78 Those functions are generally losing for a number of reasons: | 83 Those functions are generally losing for a number of reasons: |
79 | 84 |
80 1) They only support one locale (e.g. you could display | 85 1) They only support one locale (e.g. you could display |
81 Japanese and ASCII text, but not mixed Japanese/Chinese | 86 Japanese and ASCII text, but not mixed Japanese/Chinese |
82 text). You could maybe call setlocale() frequently | 87 text). You could maybe call setlocale() frequently |
83 to try to deal with this, but that would generally | 88 to try to deal with this, but that would generally |
84 fail because an XFontSet is tied to one locale and | 89 fail because an XFontSet is tied to one locale and |
85 won't have the other character sets in it. | 90 won't have the other character sets in it. |
91 | |
92 The following aren't true any more, but that doesn't make Xmb*() | |
93 usable. One wonders about Xft and Pango, etc, tho'. Except they | |
94 aren't cross-platform solutions. FMH, as jwz would say. -- sjt | |
95 [[ | |
86 2) Not all (or even very many) OS's support the useful | 96 2) Not all (or even very many) OS's support the useful |
87 locales. For example, as far as I know SunOS and | 97 locales. For example, as far as I know SunOS and |
88 Solaris only support the Japanese locale if you get the | 98 Solaris only support the Japanese locale if you get the |
89 special Asian-language version of the OS. Yuck yuck | 99 special Asian-language version of the OS. Yuck yuck |
90 yuck. Linux doesn't support the Japanese locale at | 100 yuck. Linux doesn't support the Japanese locale at |
96 specific) is even the same for the same locale on | 106 specific) is even the same for the same locale on |
97 different OS's? It's not even documented anywhere that | 107 different OS's? It's not even documented anywhere that |
98 I can find what the multi-byte text format for the | 108 I can find what the multi-byte text format for the |
99 Japanese locale under SunOS and Solaris is, but I assume | 109 Japanese locale under SunOS and Solaris is, but I assume |
100 it's EUC. | 110 it's EUC. |
111 ]] | |
101 */ | 112 */ |
102 | 113 |
114 /* #### Break me out into a separate header */ | |
103 struct textual_run | 115 struct textual_run |
104 { | 116 { |
105 Lisp_Object charset; | 117 Lisp_Object charset; |
106 unsigned char *ptr; | 118 unsigned char *ptr; |
107 int len; | 119 int len; |
118 of TEXT_STORAGE and (len * sizeof (struct textual_run)) bytes of | 130 of TEXT_STORAGE and (len * sizeof (struct textual_run)) bytes of |
119 RUN_STORAGE, where LEN is the length of the dynarr. | 131 RUN_STORAGE, where LEN is the length of the dynarr. |
120 | 132 |
121 Returns the number of runs actually used. */ | 133 Returns the number of runs actually used. */ |
122 | 134 |
135 /* Notes on Xft implementation | |
136 | |
137 - Xft Reloaded, v.4, uses a function like that in redisplay-msw.c to | |
138 handle all characters. However, instead of using an appropriate | |
139 character width for each run, it just uses UTF-8 for all runs. This | |
140 is not obviously a bad idea, but (for Han characters etc) the estimate | |
141 of TEXT_STORAGE allocation needed is (3 * len), and for characters not | |
142 in the BMP, it's (4 * len). | |
143 - With Unicode, we're no longer going to have repertoires reified as | |
144 charsets. (Not that we ever really did, what with corporate variants, | |
145 and so on.) So we really should be querying the face for the desired | |
146 font, rather than the character for the charset, and that's what would | |
147 determine the separation into runs. | |
148 - The widechar versions of fontconfig (and therefore Xft) functions | |
149 seem to be just bigendian Unicode. So there's actually no need to use | |
150 the 8-bit versions in computing runs and runes, it would seem. | |
151 - Mule won't "just work"; substantially more effort seems needed. | |
152 */ | |
153 | |
123 static int | 154 static int |
124 separate_textual_runs (unsigned char *text_storage, | 155 separate_textual_runs (unsigned char *text_storage, |
125 struct textual_run *run_storage, | 156 struct textual_run *run_storage, |
126 const Ichar *str, Charcount len) | 157 const Ichar *str, Charcount len) |
127 { | 158 { |
137 | 168 |
138 for (i = 0; i < len; i++) | 169 for (i = 0; i < len; i++) |
139 { | 170 { |
140 Ichar ch = str[i]; | 171 Ichar ch = str[i]; |
141 Lisp_Object charset; | 172 Lisp_Object charset; |
142 int byte1, byte2; | 173 int byte1, byte2; /* #### why aren't these UExtbytes? */ |
143 int dimension; | 174 int dimension; |
144 int graphic; | 175 int graphic; |
145 | 176 |
146 BREAKUP_ICHAR (ch, charset, byte1, byte2); | 177 BREAKUP_ICHAR (ch, charset, byte1, byte2); |
147 dimension = XCHARSET_DIMENSION (charset); | 178 dimension = XCHARSET_DIMENSION (charset); |
149 | 180 |
150 if (!EQ (charset, prev_charset)) | 181 if (!EQ (charset, prev_charset)) |
151 { | 182 { |
152 run_storage[runs_so_far].ptr = text_storage; | 183 run_storage[runs_so_far].ptr = text_storage; |
153 run_storage[runs_so_far].charset = charset; | 184 run_storage[runs_so_far].charset = charset; |
185 #ifdef USE_XFT | |
186 run_storage[runs_so_far].dimension = 2; | |
187 #else | |
154 run_storage[runs_so_far].dimension = dimension; | 188 run_storage[runs_so_far].dimension = dimension; |
189 #endif | |
155 | 190 |
156 if (runs_so_far) | 191 if (runs_so_far) |
157 { | 192 { |
158 run_storage[runs_so_far - 1].len = | 193 run_storage[runs_so_far - 1].len = |
159 text_storage - run_storage[runs_so_far - 1].ptr; | 194 text_storage - run_storage[runs_so_far - 1].ptr; |
170 need_ccl_conversion = 1; | 205 need_ccl_conversion = 1; |
171 } | 206 } |
172 #endif | 207 #endif |
173 } | 208 } |
174 | 209 |
210 #ifndef USE_XFT | |
175 if (graphic == 0) | 211 if (graphic == 0) |
176 { | 212 { |
177 byte1 &= 0x7F; | 213 byte1 &= 0x7F; |
178 byte2 &= 0x7F; | 214 byte2 &= 0x7F; |
179 } | 215 } |
190 char_converter.reg[2] = byte2; | 226 char_converter.reg[2] = byte2; |
191 ccl_driver (&char_converter, 0, 0, 0, 0, CCL_MODE_ENCODING); | 227 ccl_driver (&char_converter, 0, 0, 0, 0, CCL_MODE_ENCODING); |
192 byte1 = char_converter.reg[1]; | 228 byte1 = char_converter.reg[1]; |
193 byte2 = char_converter.reg[2]; | 229 byte2 = char_converter.reg[2]; |
194 } | 230 } |
195 #endif | 231 #endif /* MULE */ |
196 *text_storage++ = (unsigned char) byte1; | 232 *text_storage++ = (unsigned char) byte1; |
197 if (dimension == 2) | 233 if (dimension == 2) |
198 *text_storage++ = (unsigned char) byte2; | 234 *text_storage++ = (unsigned char) byte2; |
235 #else /* USE_XFT */ | |
236 /* #### This is bogus as hell. XftChar16, aka FcChar16, is actually | |
237 unsigned short, and therefore is not suitable for indexing matrix | |
238 fonts such as the JIS fonts supplied with X11. But if this were | |
239 consistent, the XftDraw*8 and XftDraw*16 functions are pretty | |
240 incoherent, as then we not should allow anything but ISO 8859/1 | |
241 (ie, the first 256 code points of Unicode) in XftDraw*8. So it | |
242 looks like this depends on the font, not the charset. */ | |
243 { | |
244 XftChar16 xftchar16 = 0xFFFD; /* unsigned short */ | |
245 #ifndef MULE | |
246 int unicode = ch; | |
247 #else | |
248 int unicode = ichar_to_unicode (ch); | |
249 if (unicode < 0) | |
250 /* abort(); */ /* #### serious error, tables are corrupt | |
251 Unfortunately, not a valid assumption; this can happen with | |
252 composite characters. Fake it. */ | |
253 unicode = 0xFFFD; /* REPLACEMENT CHARACTER, can't represent */ | |
254 else if (need_ccl_conversion) | |
255 /* #### maybe we should just ignore this and hope the font wins? */ | |
256 unicode = 0xFFFD; /* REPLACEMENT CHARACTER, can't represent */ | |
257 else if (unicode > 65535) | |
258 unicode = 0xFFFD; /* REPLACEMENT CHARACTER, can't represent */ | |
259 else | |
260 #endif | |
261 xftchar16 = (XftChar16) unicode; | |
262 /* #### endianness dependency? No, | |
263 apparently xft handles endianness for us; | |
264 the "big-endian" code works on Intel and PPC */ | |
265 #if 1 | |
266 /* big-endian or auto-endian */ | |
267 byte1 = ((unsigned char *) (&xftchar16))[0]; | |
268 byte2 = ((unsigned char *) (&xftchar16))[1]; | |
269 #else | |
270 /* little-endian */ | |
271 byte1 = ((unsigned char *) (&xftchar16))[1]; | |
272 byte2 = ((unsigned char *) (&xftchar16))[0]; | |
273 #endif | |
274 } | |
275 *text_storage++ = (unsigned char) byte1; | |
276 *text_storage++ = (unsigned char) byte2; | |
277 #endif /* USE_XFT */ | |
199 } | 278 } |
200 | 279 |
201 if (runs_so_far) | 280 if (runs_so_far) |
202 { | 281 { |
203 run_storage[runs_so_far - 1].len = | 282 run_storage[runs_so_far - 1].len = |
214 /* X output routines */ | 293 /* X output routines */ |
215 /* */ | 294 /* */ |
216 /****************************************************************************/ | 295 /****************************************************************************/ |
217 | 296 |
218 static int | 297 static int |
219 x_text_width_single_run (struct face_cachel *cachel, struct textual_run *run) | 298 x_text_width_single_run (struct frame * USED_IF_XFT (f), |
299 struct face_cachel *cachel, struct textual_run *run) | |
220 { | 300 { |
221 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); | 301 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); |
222 Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); | 302 Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); |
223 if (!fi->proportional_p) | 303 if (!fi->proportional_p) |
224 return fi->width * run->len; | 304 return fi->width * run->len; |
225 else | 305 #ifdef USE_XFT |
306 else if (FONT_INSTANCE_X_XFTFONT(fi)) | |
307 { | |
308 static XGlyphInfo glyphinfo; | |
309 struct device *d = XDEVICE (f->device); | |
310 Display *dpy = DEVICE_X_DISPLAY (d); | |
311 | |
312 if (run->dimension == 2) { | |
313 XftTextExtents16 (dpy, | |
314 FONT_INSTANCE_X_XFTFONT(fi), | |
315 (XftChar16 *) run->ptr, run->len, &glyphinfo); | |
316 } else { | |
317 XftTextExtents8 (dpy, | |
318 FONT_INSTANCE_X_XFTFONT(fi), | |
319 run->ptr, run->len, &glyphinfo); | |
320 } | |
321 | |
322 return glyphinfo.xOff; | |
323 } | |
324 #endif | |
325 else if (FONT_INSTANCE_X_FONT (fi)) | |
226 { | 326 { |
227 if (run->dimension == 2) | 327 if (run->dimension == 2) |
228 return XTextWidth16 (FONT_INSTANCE_X_FONT (fi), | 328 return XTextWidth16 (FONT_INSTANCE_X_FONT (fi), |
229 (XChar2b *) run->ptr, run->len); | 329 (XChar2b *) run->ptr, run->len); |
230 else | 330 else |
231 return XTextWidth (FONT_INSTANCE_X_FONT (fi), | 331 return XTextWidth (FONT_INSTANCE_X_FONT (fi), |
232 (char *) run->ptr, run->len); | 332 (char *) run->ptr, run->len); |
233 } | 333 } |
334 else | |
335 abort(); | |
336 return 0; /* shut up GCC */ | |
234 } | 337 } |
235 | 338 |
236 /* | 339 /* |
237 x_text_width | 340 x_text_width |
238 | 341 |
239 Given a string and a face, return the string's length in pixels when | 342 Given a string and a merged face, return the string's length in pixels |
240 displayed in the font associated with the face. | 343 when displayed in the fonts associated with the face. |
241 */ | 344 */ |
242 | 345 |
243 static int | 346 /* #### Break me out into a separate header */ |
244 x_text_width (struct frame *UNUSED (f), struct face_cachel *cachel, | 347 int x_text_width (struct frame *f, struct face_cachel *cachel, |
348 const Ichar *str, Charcount len); | |
349 int | |
350 x_text_width (struct frame *f, struct face_cachel *cachel, | |
245 const Ichar *str, Charcount len) | 351 const Ichar *str, Charcount len) |
246 { | 352 { |
247 /* !!#### Needs review */ | 353 /* !!#### Needs review */ |
248 int width_so_far = 0; | 354 int width_so_far = 0; |
249 unsigned char *text_storage = (unsigned char *) ALLOCA (2 * len); | 355 unsigned char *text_storage = (unsigned char *) ALLOCA (2 * len); |
252 int i; | 358 int i; |
253 | 359 |
254 nruns = separate_textual_runs (text_storage, runs, str, len); | 360 nruns = separate_textual_runs (text_storage, runs, str, len); |
255 | 361 |
256 for (i = 0; i < nruns; i++) | 362 for (i = 0; i < nruns; i++) |
257 width_so_far += x_text_width_single_run (cachel, runs + i); | 363 width_so_far += x_text_width_single_run (f, cachel, runs + i); |
258 | 364 |
259 return width_so_far; | 365 return width_so_far; |
260 } | 366 } |
261 | 367 |
262 /***************************************************************************** | 368 /***************************************************************************** |
317 static void | 423 static void |
318 x_output_display_block (struct window *w, struct display_line *dl, int block, | 424 x_output_display_block (struct window *w, struct display_line *dl, int block, |
319 int start, int end, int start_pixpos, int cursor_start, | 425 int start, int end, int start_pixpos, int cursor_start, |
320 int cursor_width, int cursor_height) | 426 int cursor_width, int cursor_height) |
321 { | 427 { |
428 #ifndef USE_XFT | |
322 struct frame *f = XFRAME (w->frame); | 429 struct frame *f = XFRAME (w->frame); |
430 #endif | |
323 Ichar_dynarr *buf = Dynarr_new (Ichar); | 431 Ichar_dynarr *buf = Dynarr_new (Ichar); |
324 Lisp_Object window; | 432 Lisp_Object window; |
325 | 433 |
326 struct display_block *db = Dynarr_atp (dl->display_blocks, block); | 434 struct display_block *db = Dynarr_atp (dl->display_blocks, block); |
327 rune_dynarr *rba = db->runes; | 435 rune_dynarr *rba = db->runes; |
500 | 608 |
501 if (Dynarr_length (buf)) | 609 if (Dynarr_length (buf)) |
502 x_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex, | 610 x_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex, |
503 0, cursor_start, cursor_width, cursor_height); | 611 0, cursor_start, cursor_width, cursor_height); |
504 | 612 |
505 /* #### This is really conditionalized well for optimized | |
506 performance. */ | |
507 if (dl->modeline | 613 if (dl->modeline |
508 && !EQ (Qzero, w->modeline_shadow_thickness) | 614 && !EQ (Qzero, w->modeline_shadow_thickness) |
615 #ifndef USE_XFT | |
616 /* This optimization doesn't work right with some Xft fonts, which | |
617 leave antialiasing turds at the boundary. I don't know if this | |
618 is an Xft bug or not, but I think it is. See x_output_string. */ | |
509 && (f->clear | 619 && (f->clear |
510 || f->windows_structure_changed | 620 || f->windows_structure_changed |
511 || w->shadow_thickness_changed)) | 621 || w->shadow_thickness_changed) |
622 #endif | |
623 ) | |
512 bevel_modeline (w, dl); | 624 bevel_modeline (w, dl); |
513 | 625 |
514 Dynarr_free (buf); | 626 Dynarr_free (buf); |
515 } | 627 } |
516 | 628 |
660 gcv.clip_y_origin = 0; | 772 gcv.clip_y_origin = 0; |
661 gcv.fill_style = FillSolid; | 773 gcv.fill_style = FillSolid; |
662 mask = GCGraphicsExposures | GCClipMask | GCClipXOrigin | GCClipYOrigin; | 774 mask = GCGraphicsExposures | GCClipMask | GCClipXOrigin | GCClipYOrigin; |
663 mask |= GCFillStyle; | 775 mask |= GCFillStyle; |
664 | 776 |
665 if (!NILP (font)) | 777 if (!NILP (font) |
778 #ifdef USE_XFT | |
779 /* Only set the font if it's a core font */ | |
780 /* the renderfont will be set elsewhere (not part of gc) */ | |
781 && !FONT_INSTANCE_X_XFTFONT (XFONT_INSTANCE (font)) | |
782 #endif | |
783 ) | |
666 { | 784 { |
667 gcv.font = FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font))->fid; | 785 gcv.font = FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font))->fid; |
668 mask |= GCFont; | 786 mask |= GCFont; |
669 } | 787 } |
670 | 788 |
671 /* evil kludge! */ | 789 /* evil kludge! */ |
672 if (!NILP (fg) && !COLOR_INSTANCEP (fg) && !INTP (fg)) | 790 if (!NILP (fg) && !COLOR_INSTANCEP (fg) && !INTP (fg)) |
673 { | 791 { |
674 /* #### I fixed once case where this was getting it. It was a | 792 /* #### I fixed one case where this was getting hit. It was a |
675 bad macro expansion (compiler bug). */ | 793 bad macro expansion (compiler bug). */ |
676 stderr_out ("Help! x_get_gc got a bogus fg value! fg = "); | 794 stderr_out ("Help! x_get_gc got a bogus fg value! fg = "); |
677 debug_print (fg); | 795 debug_print (fg); |
678 fg = Qnil; | 796 fg = Qnil; |
679 } | 797 } |
727 { | 845 { |
728 gcv.line_width = XINT (lwidth); | 846 gcv.line_width = XINT (lwidth); |
729 mask |= GCLineWidth; | 847 mask |= GCLineWidth; |
730 } | 848 } |
731 | 849 |
850 #if 0 | |
851 debug_out ("\nx_get_gc: calling gc_cache_lookup\n"); | |
852 #endif | |
732 return gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); | 853 return gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); |
733 } | 854 } |
734 | 855 |
735 /***************************************************************************** | 856 /***************************************************************************** |
736 x_output_string | 857 x_output_string |
772 int cursor_start, int cursor_width, int cursor_height) | 893 int cursor_start, int cursor_width, int cursor_height) |
773 { | 894 { |
774 /* General variables */ | 895 /* General variables */ |
775 struct frame *f = XFRAME (w->frame); | 896 struct frame *f = XFRAME (w->frame); |
776 struct device *d = XDEVICE (f->device); | 897 struct device *d = XDEVICE (f->device); |
777 Lisp_Object window; | 898 Lisp_Object window = wrap_window (w); |
778 Display *dpy = DEVICE_X_DISPLAY (d); | 899 Display *dpy = DEVICE_X_DISPLAY (d); |
779 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | 900 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); |
780 | 901 |
781 int clip_end; | 902 int clip_end; |
782 | 903 |
788 struct face_cachel *cursor_cachel = 0; | 909 struct face_cachel *cursor_cachel = 0; |
789 | 910 |
790 /* Text-related variables */ | 911 /* Text-related variables */ |
791 Lisp_Object bg_pmap; | 912 Lisp_Object bg_pmap; |
792 GC bgc, gc; | 913 GC bgc, gc; |
793 int height; | 914 int height = DISPLAY_LINE_HEIGHT (dl); |
915 int ypos = DISPLAY_LINE_YPOS (dl); | |
794 int len = Dynarr_length (buf); | 916 int len = Dynarr_length (buf); |
795 unsigned char *text_storage = (unsigned char *) ALLOCA (2 * len); | 917 unsigned char *text_storage = (unsigned char *) ALLOCA (2 * len); |
796 struct textual_run *runs = alloca_array (struct textual_run, len); | 918 struct textual_run *runs = alloca_array (struct textual_run, len); |
797 int nruns; | 919 int nruns; |
798 int i; | 920 int i; |
799 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex); | 921 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex); |
800 | 922 |
801 window = wrap_window (w); | 923 int use_x_font = 1; /* #### bogus!! |
924 The logic of this function needs review! */ | |
925 #ifdef USE_XFT | |
926 Colormap cmap = DEVICE_X_COLORMAP (d); | |
927 Visual *visual = DEVICE_X_VISUAL (d); | |
928 static XftColor fg, bg; | |
929 XftDraw *xftDraw; | |
930 | |
931 /* Lazily initialize frame's xftDraw member. */ | |
932 if (!FRAME_X_XFTDRAW (f)) { | |
933 FRAME_X_XFTDRAW (f) = XftDrawCreate (dpy, x_win, visual, cmap); | |
934 } | |
935 xftDraw = FRAME_X_XFTDRAW (f); | |
936 | |
937 /* #### This will probably cause asserts when passed a Lisp integer for a | |
938 color. See ca. line 759 this file. | |
939 #### Maybe xft_convert_color should take an XColor, not a pixel. */ | |
940 #define XFT_FROB_LISP_COLOR(color, dim) \ | |
941 xft_convert_color (dpy, cmap, visual, \ | |
942 COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (color)).pixel, \ | |
943 (dim)) | |
944 #endif | |
802 | 945 |
803 if (width < 0) | 946 if (width < 0) |
804 width = x_text_width (f, cachel, Dynarr_atp (buf, 0), Dynarr_length (buf)); | 947 width = x_text_width (f, cachel, Dynarr_atp (buf, 0), Dynarr_length (buf)); |
805 height = DISPLAY_LINE_HEIGHT (dl); | |
806 | 948 |
807 /* Regularize the variables passed in. */ | 949 /* Regularize the variables passed in. */ |
808 | 950 |
809 if (clip_start < xpos) | 951 if (clip_start < xpos) |
810 clip_start = xpos; | 952 clip_start = xpos; |
814 return; | 956 return; |
815 | 957 |
816 xpos -= xoffset; | 958 xpos -= xoffset; |
817 | 959 |
818 /* make sure the area we are about to display is subwindow free. */ | 960 /* make sure the area we are about to display is subwindow free. */ |
819 redisplay_unmap_subwindows_maybe (f, clip_start, DISPLAY_LINE_YPOS (dl), | 961 redisplay_unmap_subwindows_maybe (f, clip_start, ypos, |
820 clip_end - clip_start, DISPLAY_LINE_HEIGHT (dl)); | 962 clip_end - clip_start, height); |
821 | |
822 nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0), | |
823 Dynarr_length (buf)); | |
824 | 963 |
825 cursor_clip = (cursor_start >= clip_start && | 964 cursor_clip = (cursor_start >= clip_start && |
826 cursor_start < clip_end); | 965 cursor_start < clip_end); |
827 | 966 |
828 /* This cursor code is really a mess. */ | 967 /* This cursor code is really a mess. */ |
856 | 995 |
857 if ((cursor && focus && NILP (bar_cursor_value) | 996 if ((cursor && focus && NILP (bar_cursor_value) |
858 && !NILP (w->text_cursor_visible_p)) || NILP (bg_pmap)) | 997 && !NILP (w->text_cursor_visible_p)) || NILP (bg_pmap)) |
859 bgc = 0; | 998 bgc = 0; |
860 else | 999 else |
861 bgc = x_get_gc (d, Qnil, cachel->foreground, cachel->background, | 1000 { |
862 bg_pmap, Qnil); | 1001 bgc = x_get_gc (d, Qnil, cachel->foreground, cachel->background, |
1002 bg_pmap, Qnil); | |
1003 } | |
863 | 1004 |
864 if (bgc) | 1005 if (bgc) |
865 XFillRectangle (dpy, x_win, bgc, clip_start, | 1006 { |
866 DISPLAY_LINE_YPOS (dl), clip_end - clip_start, | 1007 XFillRectangle (dpy, x_win, bgc, clip_start, |
867 height); | 1008 ypos, clip_end - clip_start, |
1009 height); | |
1010 } | |
1011 | |
1012 nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0), | |
1013 Dynarr_length (buf)); | |
868 | 1014 |
869 for (i = 0; i < nruns; i++) | 1015 for (i = 0; i < nruns; i++) |
870 { | 1016 { |
871 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); | 1017 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); |
872 Lisp_Font_Instance *fi = XFONT_INSTANCE (font); | 1018 Lisp_Font_Instance *fi = XFONT_INSTANCE (font); |
874 int need_clipping; | 1020 int need_clipping; |
875 | 1021 |
876 if (EQ (font, Vthe_null_font_instance)) | 1022 if (EQ (font, Vthe_null_font_instance)) |
877 continue; | 1023 continue; |
878 | 1024 |
879 this_width = x_text_width_single_run (cachel, runs + i); | 1025 this_width = x_text_width_single_run (f, cachel, runs + i); |
880 need_clipping = (dl->clip || clip_start > xpos || | 1026 need_clipping = (dl->clip || clip_start > xpos || |
881 clip_end < xpos + this_width); | 1027 clip_end < xpos + this_width); |
882 | 1028 |
883 /* XDrawImageString only clears the area equal to the height of | 1029 /* XDrawImageString only clears the area equal to the height of |
884 the given font. It is possible that a font is being displayed | 1030 the given font. It is possible that a font is being displayed |
893 { | 1039 { |
894 int ypos1_line, ypos1_string, ypos2_line, ypos2_string; | 1040 int ypos1_line, ypos1_string, ypos2_line, ypos2_string; |
895 | 1041 |
896 ypos1_string = dl->ypos - fi->ascent; | 1042 ypos1_string = dl->ypos - fi->ascent; |
897 ypos2_string = dl->ypos + fi->descent; | 1043 ypos2_string = dl->ypos + fi->descent; |
898 ypos1_line = DISPLAY_LINE_YPOS (dl); | 1044 ypos1_line = ypos; |
899 ypos2_line = ypos1_line + DISPLAY_LINE_HEIGHT (dl); | 1045 ypos2_line = ypos1_line + height; |
900 | 1046 |
901 /* Make sure we don't clear below the real bottom of the | 1047 /* Make sure we don't clear below the real bottom of the |
902 line. */ | 1048 line. */ |
903 if (ypos1_string > ypos2_line) | 1049 if (ypos1_string > ypos2_line) |
904 ypos1_string = ypos2_line; | 1050 ypos1_string = ypos2_line; |
920 } | 1066 } |
921 } | 1067 } |
922 else | 1068 else |
923 { | 1069 { |
924 redisplay_clear_region (window, findex, clear_start, | 1070 redisplay_clear_region (window, findex, clear_start, |
925 DISPLAY_LINE_YPOS (dl), clear_end - clear_start, | 1071 ypos, clear_end - clear_start, |
926 height); | 1072 height); |
927 } | 1073 } |
928 } | 1074 } |
929 | 1075 |
930 if (cursor && cursor_cachel && focus && NILP (bar_cursor_value)) | 1076 if (cursor && cursor_cachel && focus && NILP (bar_cursor_value)) |
931 gc = x_get_gc (d, font, cursor_cachel->foreground, | 1077 { |
932 cursor_cachel->background, Qnil, Qnil); | 1078 #ifdef USE_XFT |
1079 fg = XFT_FROB_LISP_COLOR (cursor_cachel->foreground, 0); | |
1080 bg = XFT_FROB_LISP_COLOR (cursor_cachel->background, 0); | |
1081 #endif | |
1082 gc = x_get_gc (d, font, cursor_cachel->foreground, | |
1083 cursor_cachel->background, Qnil, Qnil); | |
1084 } | |
933 else if (cachel->dim) | 1085 else if (cachel->dim) |
934 { | 1086 { |
935 /* Ensure the gray bitmap exists */ | 1087 /* Ensure the gray bitmap exists */ |
936 if (DEVICE_X_GRAY_PIXMAP (d) == None) | 1088 if (DEVICE_X_GRAY_PIXMAP (d) == None) |
937 DEVICE_X_GRAY_PIXMAP (d) = | 1089 DEVICE_X_GRAY_PIXMAP (d) = |
938 XCreateBitmapFromData (dpy, x_win, (char *)gray_bits, | 1090 XCreateBitmapFromData (dpy, x_win, (char *)gray_bits, |
939 gray_width, gray_height); | 1091 gray_width, gray_height); |
940 | 1092 |
941 /* Request a GC with the gray stipple pixmap to draw dimmed text */ | 1093 /* Request a GC with the gray stipple pixmap to draw dimmed text */ |
1094 #ifdef USE_XFT | |
1095 fg = XFT_FROB_LISP_COLOR (cachel->foreground, 1); | |
1096 bg = XFT_FROB_LISP_COLOR (cachel->background, 0); | |
1097 #endif | |
942 gc = x_get_gc (d, font, cachel->foreground, cachel->background, | 1098 gc = x_get_gc (d, font, cachel->foreground, cachel->background, |
943 Qdim, Qnil); | 1099 Qdim, Qnil); |
944 } | 1100 } |
945 else | 1101 else |
946 gc = x_get_gc (d, font, cachel->foreground, cachel->background, | 1102 { |
947 Qnil, Qnil); | 1103 #ifdef USE_XFT |
948 | 1104 fg = XFT_FROB_LISP_COLOR (cachel->foreground, 0); |
949 if (need_clipping) | 1105 bg = XFT_FROB_LISP_COLOR (cachel->background, 0); |
950 { | 1106 #endif |
951 XRectangle clip_box[1]; | 1107 gc = x_get_gc (d, font, cachel->foreground, cachel->background, |
952 | 1108 Qnil, Qnil); |
953 clip_box[0].x = 0; | 1109 } |
954 clip_box[0].y = 0; | 1110 #ifdef USE_XFT |
955 clip_box[0].width = clip_end - clip_start; | 1111 { |
956 clip_box[0].height = height; | 1112 XftFont *rf = FONT_INSTANCE_X_XFTFONT (fi); |
957 | 1113 |
958 XSetClipRectangles (dpy, gc, clip_start, DISPLAY_LINE_YPOS (dl), | 1114 if (rf) |
959 clip_box, 1, Unsorted); | 1115 { |
960 } | 1116 use_x_font = 0; |
961 | 1117 if (need_clipping) |
962 if (runs[i].dimension == 1) | 1118 { |
963 (bgc ? XDrawString : XDrawImageString) (dpy, x_win, gc, xpos, | 1119 Region clip_reg = XCreateRegion(); |
964 dl->ypos, (char *) runs[i].ptr, | 1120 XRectangle clip_box = { clip_start, ypos, |
965 runs[i].len); | 1121 clip_end - clip_start, height }; |
966 else | 1122 |
967 (bgc ? XDrawString16 : XDrawImageString16) (dpy, x_win, gc, xpos, | 1123 XUnionRectWithRegion (&clip_box, clip_reg, clip_reg); |
968 dl->ypos, | 1124 XftDrawSetClip(xftDraw, clip_reg); |
969 (XChar2b *) runs[i].ptr, | 1125 XDestroyRegion(clip_reg); |
970 runs[i].len); | 1126 } |
1127 | |
1128 if (!bgc) | |
1129 { | |
1130 /* #### Neither rect_height nor XftTextExtents as computed | |
1131 below handles the vertical space taken up by antialiasing, | |
1132 which for some fonts (eg, Bitstream Vera Sans Mono-16 on | |
1133 my Mac PowerBook G4) leaves behind orphaned dots on | |
1134 insertion or deletion earlier in the line, especially in | |
1135 the case of the underscore character. | |
1136 Interestingly, insertion or deletion of a single character | |
1137 immediately after a refresh does not leave any droppings, | |
1138 but any further insertions or deletions do. | |
1139 While adding a pixel to rect_height (mostly) takes care of | |
1140 this, it trashes aggressively laid-out elements like the | |
1141 modeline (overwriting part of the bevel). | |
1142 OK, unconditionally redraw the bevel, and increment | |
1143 rect_height by 1. See x_output_display_block. -- sjt */ | |
1144 struct textual_run *run = &runs[i]; | |
1145 int rect_width = x_text_width_single_run (f, cachel, run); | |
1146 #ifndef USE_XFTTEXTENTS_TO_AVOID_FONT_DROPPINGS | |
1147 int rect_height = FONT_INSTANCE_ASCENT(fi) | |
1148 + FONT_INSTANCE_DESCENT(fi) + 1; | |
1149 #else | |
1150 int rect_height = FONT_INSTANCE_ASCENT(fi) | |
1151 + FONT_INSTANCE_DESCENT(fi); | |
1152 XGlyphInfo gi; | |
1153 if (run->dimension == 2) { | |
1154 XftTextExtents16 (dpy, | |
1155 FONT_INSTANCE_X_XFTFONT(fi), | |
1156 (XftChar16 *) run->ptr, run->len, &gi); | |
1157 } else { | |
1158 XftTextExtents8 (dpy, | |
1159 FONT_INSTANCE_X_XFTFONT(fi), | |
1160 run->ptr, run->len, &gi); | |
1161 } | |
1162 rect_height = rect_height > gi.height | |
1163 ? rect_height : gi.height; | |
1164 #endif | |
1165 | |
1166 XftDrawRect (xftDraw, &bg, | |
1167 xpos, ypos, rect_width, rect_height); | |
1168 } | |
1169 | |
1170 if (runs[i].dimension == 1) | |
1171 XftDrawString8 (xftDraw, &fg, rf, xpos, dl->ypos, | |
1172 runs[i].ptr, runs[i].len); | |
1173 else | |
1174 XftDrawString16 (xftDraw, &fg, rf, xpos, dl->ypos, | |
1175 (XftChar16 *) runs[i].ptr, runs[i].len); | |
1176 } | |
1177 } | |
1178 #endif | |
1179 { | |
1180 if (use_x_font) | |
1181 { | |
1182 if (need_clipping) | |
1183 { | |
1184 XRectangle clip_box[1]; | |
1185 | |
1186 clip_box[0].x = 0; | |
1187 clip_box[0].y = 0; | |
1188 clip_box[0].width = clip_end - clip_start; | |
1189 clip_box[0].height = height; | |
1190 | |
1191 XSetClipRectangles (dpy, gc, clip_start, ypos, | |
1192 clip_box, 1, YXBanded); | |
1193 } | |
1194 | |
1195 if (runs[i].dimension == 1) | |
1196 (bgc ? XDrawString : XDrawImageString) | |
1197 (dpy, x_win, gc, xpos, dl->ypos, | |
1198 (char *) runs[i].ptr, runs[i].len); | |
1199 else | |
1200 (bgc ? XDrawString16 : XDrawImageString16) | |
1201 (dpy, x_win, gc, xpos, dl->ypos, | |
1202 (XChar2b *) runs[i].ptr, runs[i].len); | |
1203 } | |
1204 } | |
971 | 1205 |
972 /* We draw underlines in the same color as the text. */ | 1206 /* We draw underlines in the same color as the text. */ |
973 if (cachel->underline) | 1207 if (cachel->underline) |
974 { | 1208 { |
975 int upos, uthick; | 1209 int upos, uthick; |
976 unsigned long upos_ext, uthick_ext; | 1210 unsigned long upos_ext, uthick_ext; |
977 XFontStruct *xfont; | 1211 XFontStruct *fs = |
978 | 1212 use_x_font ? FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)) : 0; |
979 xfont = FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)); | 1213 /* #### the logic of the next two may be suboptimal: we may want |
980 if (!XGetFontProperty (xfont, XA_UNDERLINE_POSITION, &upos_ext)) | 1214 to use the POSITION and/or THICKNESS information with Xft */ |
1215 if (fs && XGetFontProperty (fs, XA_UNDERLINE_POSITION, &upos_ext)) | |
1216 upos = (int) upos_ext; | |
1217 else | |
981 upos = dl->descent / 2; | 1218 upos = dl->descent / 2; |
1219 if (fs && XGetFontProperty (fs, XA_UNDERLINE_THICKNESS, &uthick_ext)) | |
1220 uthick = (int) uthick_ext; | |
982 else | 1221 else |
983 upos = (int) upos_ext; | |
984 if (!XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &uthick_ext)) | |
985 uthick = 1; | 1222 uthick = 1; |
986 else | |
987 uthick = (int) uthick_ext; | |
988 | |
989 if (dl->ypos + upos < dl->ypos + dl->descent - dl->clip) | 1223 if (dl->ypos + upos < dl->ypos + dl->descent - dl->clip) |
990 { | 1224 { |
991 if (dl->ypos + upos + uthick > dl->ypos + dl->descent - dl->clip) | 1225 if (dl->ypos + upos + uthick > dl->ypos + dl->descent - dl->clip) |
992 uthick = dl->descent - dl->clip - upos; | 1226 uthick = dl->descent - dl->clip - upos; |
993 | 1227 |
1006 | 1240 |
1007 if (cachel->strikethru) | 1241 if (cachel->strikethru) |
1008 { | 1242 { |
1009 int ascent, descent, upos, uthick; | 1243 int ascent, descent, upos, uthick; |
1010 unsigned long ascent_ext, descent_ext, uthick_ext; | 1244 unsigned long ascent_ext, descent_ext, uthick_ext; |
1011 XFontStruct *xfont; | 1245 XFontStruct *fs = FONT_INSTANCE_X_FONT (fi); |
1012 | |
1013 xfont = FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)); | |
1014 | 1246 |
1015 if (!XGetFontProperty (xfont, XA_STRIKEOUT_ASCENT, &ascent_ext)) | 1247 if (!use_x_font) |
1016 ascent = xfont->ascent; | 1248 { |
1249 ascent = dl->ascent; | |
1250 descent = dl->descent; | |
1251 uthick = 1; | |
1252 } | |
1017 else | 1253 else |
1018 ascent = (int) ascent_ext; | 1254 { |
1019 if (!XGetFontProperty (xfont, XA_STRIKEOUT_DESCENT, &descent_ext)) | 1255 if (!XGetFontProperty (fs, XA_STRIKEOUT_ASCENT, &ascent_ext)) |
1020 descent = xfont->descent; | 1256 ascent = fs->ascent; |
1021 else | 1257 else |
1022 descent = (int) descent_ext; | 1258 ascent = (int) ascent_ext; |
1023 if (!XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &uthick_ext)) | 1259 if (!XGetFontProperty (fs, XA_STRIKEOUT_DESCENT, &descent_ext)) |
1024 uthick = 1; | 1260 descent = fs->descent; |
1025 else | 1261 else |
1026 uthick = (int) uthick_ext; | 1262 descent = (int) descent_ext; |
1263 if (!XGetFontProperty (fs, XA_UNDERLINE_THICKNESS, &uthick_ext)) | |
1264 uthick = 1; | |
1265 else | |
1266 uthick = (int) uthick_ext; | |
1267 } | |
1027 | 1268 |
1028 upos = ascent - ((ascent + descent) / 2) + 1; | 1269 upos = ascent - ((ascent + descent) / 2) + 1; |
1029 | 1270 |
1030 /* Generally, upos will be positive (above the baseline),so | 1271 /* Generally, upos will be positive (above the baseline),so |
1031 subtract */ | 1272 subtract */ |
1044 } | 1285 } |
1045 | 1286 |
1046 /* Restore the GC */ | 1287 /* Restore the GC */ |
1047 if (need_clipping) | 1288 if (need_clipping) |
1048 { | 1289 { |
1049 XSetClipMask (dpy, gc, None); | 1290 #ifdef USE_XFT |
1050 XSetClipOrigin (dpy, gc, 0, 0); | 1291 if (!use_x_font) |
1292 { | |
1293 XftDrawSetClip(xftDraw, 0); | |
1294 } | |
1295 else | |
1296 { | |
1297 #endif | |
1298 XSetClipMask (dpy, gc, None); | |
1299 XSetClipOrigin (dpy, gc, 0, 0); | |
1300 #ifdef USE_XFT | |
1301 } | |
1302 #endif | |
1051 } | 1303 } |
1052 | 1304 |
1053 /* If we are actually superimposing the cursor then redraw with just | 1305 /* If we are actually superimposing the cursor then redraw with just |
1054 the appropriate section highlighted. */ | 1306 the appropriate section highlighted. */ |
1055 if (cursor_clip && !cursor && focus && cursor_cachel) | 1307 if (cursor_clip && !cursor && focus && cursor_cachel) |
1056 { | 1308 { |
1057 GC cgc; | 1309 #ifdef USE_XFT |
1058 XRectangle clip_box[1]; | 1310 if (!use_x_font) /* Xft */ |
1059 | 1311 { |
1060 cgc = x_get_gc (d, font, cursor_cachel->foreground, | 1312 XftFont *rf = FONT_INSTANCE_X_XFTFONT (fi); |
1061 cursor_cachel->background, Qnil, Qnil); | 1313 |
1062 | 1314 { /* set up clipping */ |
1063 clip_box[0].x = 0; | 1315 Region clip_reg = XCreateRegion(); |
1064 clip_box[0].y = 0; | 1316 XRectangle clip_box = { cursor_start, ypos, |
1065 clip_box[0].width = cursor_width; | 1317 cursor_width, height }; |
1066 clip_box[0].height = height; | 1318 |
1067 | 1319 XUnionRectWithRegion (&clip_box, clip_reg, clip_reg); |
1068 XSetClipRectangles (dpy, cgc, cursor_start, DISPLAY_LINE_YPOS (dl), | 1320 XftDrawSetClip(xftDraw, clip_reg); |
1069 clip_box, 1, Unsorted); | 1321 XDestroyRegion(clip_reg); |
1070 | 1322 } |
1071 if (runs[i].dimension == 1) | 1323 { /* draw background rectangle & draw text */ |
1072 XDrawImageString (dpy, x_win, cgc, xpos, dl->ypos, | 1324 int rect_height = FONT_INSTANCE_ASCENT(fi) |
1073 (char *) runs[i].ptr, runs[i].len); | 1325 + FONT_INSTANCE_DESCENT(fi); |
1074 else | 1326 int rect_width = x_text_width_single_run(f, cachel, &runs[i]); |
1075 XDrawImageString16 (dpy, x_win, cgc, xpos, dl->ypos, | 1327 XftColor xft_color; |
1076 (XChar2b *) runs[i].ptr, runs[i].len); | 1328 |
1077 | 1329 xft_color = XFT_FROB_LISP_COLOR (cursor_cachel->background, 0); |
1078 XSetClipMask (dpy, cgc, None); | 1330 XftDrawRect (xftDraw, &xft_color, |
1079 XSetClipOrigin (dpy, cgc, 0, 0); | 1331 xpos, ypos, rect_width, rect_height); |
1332 | |
1333 xft_color = XFT_FROB_LISP_COLOR (cursor_cachel->foreground, 0); | |
1334 if (runs[i].dimension == 1) | |
1335 XftDrawString8 (xftDraw, &xft_color, rf, xpos, dl->ypos, | |
1336 runs[i].ptr, runs[i].len); | |
1337 else | |
1338 XftDrawString16 (xftDraw, &xft_color, rf, xpos, dl->ypos, | |
1339 (XftChar16 *) runs[i].ptr, runs[i].len); | |
1340 } | |
1341 | |
1342 XftDrawSetClip(xftDraw, 0); | |
1343 } | |
1344 else /* core font, not Xft */ | |
1345 { | |
1346 #endif | |
1347 GC cgc; | |
1348 XRectangle clip_box[1]; | |
1349 | |
1350 cgc = x_get_gc (d, font, cursor_cachel->foreground, | |
1351 cursor_cachel->background, Qnil, Qnil); | |
1352 | |
1353 clip_box[0].x = 0; | |
1354 clip_box[0].y = 0; | |
1355 clip_box[0].width = cursor_width; | |
1356 clip_box[0].height = height; | |
1357 | |
1358 XSetClipRectangles (dpy, cgc, cursor_start, ypos, | |
1359 clip_box, 1, YXBanded); | |
1360 if (runs[i].dimension == 1) | |
1361 XDrawImageString (dpy, x_win, cgc, xpos, dl->ypos, | |
1362 (char *) runs[i].ptr, runs[i].len); | |
1363 else | |
1364 XDrawImageString16 (dpy, x_win, cgc, xpos, dl->ypos, | |
1365 (XChar2b *) runs[i].ptr, runs[i].len); | |
1366 | |
1367 XSetClipMask (dpy, cgc, None); | |
1368 XSetClipOrigin (dpy, cgc, 0, 0); | |
1369 #ifdef USE_XFT | |
1370 } | |
1371 #endif | |
1080 } | 1372 } |
1081 | 1373 |
1082 xpos += this_width; | 1374 xpos += this_width; |
1083 } | 1375 } |
1084 | 1376 |
1100 be called with exactly one character, so we know we | 1392 be called with exactly one character, so we know we |
1101 can always use runs[0]. | 1393 can always use runs[0]. |
1102 | 1394 |
1103 This is bogus as all hell, however. The cursor handling in | 1395 This is bogus as all hell, however. The cursor handling in |
1104 this function is way bogus and desperately needs to be | 1396 this function is way bogus and desperately needs to be |
1105 cleaned up. (In particular, the drawing of the cursor should | 1397 cleaned up. (In particular, the drawing of the cursor should |
1106 really really be separated out of this function. This may be | 1398 really really be separated out of this function. This may be |
1107 a bit tricky now because this function itself does way too | 1399 a bit tricky now because this function itself does way too |
1108 much stuff, a lot of which needs to be moved into | 1400 much stuff, a lot of which needs to be moved into |
1109 redisplay.c) This is the only way to be able to easily add | 1401 redisplay.c.) This is the only way to be able to easily add |
1110 new cursor types or (e.g.) make the bar cursor be able to | 1402 new cursor types or (e.g.) make the bar cursor be able to |
1111 span two characters instead of overlaying just one. */ | 1403 span two characters instead of overlaying just one. */ |
1112 int bogusly_obtained_ascent_value = | 1404 int bogusly_obtained_ascent_value = |
1113 XFONT_INSTANCE (FACE_CACHEL_FONT (cachel, runs[0].charset))->ascent; | 1405 XFONT_INSTANCE (FACE_CACHEL_FONT (cachel, runs[0].charset))->ascent; |
1114 | 1406 |
1123 Qnil, Qnil, Qnil); | 1415 Qnil, Qnil, Qnil); |
1124 } | 1416 } |
1125 | 1417 |
1126 tmp_y = dl->ypos - bogusly_obtained_ascent_value; | 1418 tmp_y = dl->ypos - bogusly_obtained_ascent_value; |
1127 tmp_height = cursor_height; | 1419 tmp_height = cursor_height; |
1128 if (tmp_y + tmp_height > (int) (DISPLAY_LINE_YPOS(dl) + height)) | 1420 if (tmp_y + tmp_height > (int) (ypos + height)) |
1129 { | 1421 { |
1130 tmp_y = DISPLAY_LINE_YPOS (dl) + height - tmp_height; | 1422 tmp_y = ypos + height - tmp_height; |
1131 if (tmp_y < (int) DISPLAY_LINE_YPOS (dl)) | 1423 if (tmp_y < (int) ypos) |
1132 tmp_y = DISPLAY_LINE_YPOS (dl); | 1424 tmp_y = ypos; |
1133 tmp_height = DISPLAY_LINE_YPOS (dl) + height - tmp_y; | 1425 tmp_height = ypos + height - tmp_y; |
1134 } | 1426 } |
1135 | 1427 |
1136 if (need_clipping) | 1428 if (need_clipping) |
1137 { | 1429 { |
1138 XRectangle clip_box[1]; | 1430 XRectangle clip_box[1]; |
1139 clip_box[0].x = 0; | 1431 clip_box[0].x = 0; |
1140 clip_box[0].y = 0; | 1432 clip_box[0].y = 0; |
1141 clip_box[0].width = clip_end - clip_start; | 1433 clip_box[0].width = clip_end - clip_start; |
1142 clip_box[0].height = tmp_height; | 1434 clip_box[0].height = tmp_height; |
1143 XSetClipRectangles (dpy, gc, clip_start, tmp_y, | 1435 XSetClipRectangles (dpy, gc, clip_start, tmp_y, |
1144 clip_box, 1, Unsorted); | 1436 /* #### why not Unsorted? */ |
1437 clip_box, 1, YXBanded); | |
1145 } | 1438 } |
1146 | 1439 |
1147 if (!focus && NILP (bar_cursor_value)) | 1440 if (!focus && NILP (bar_cursor_value)) |
1148 { | 1441 { |
1149 XDrawRectangle (dpy, x_win, gc, cursor_start, tmp_y, | 1442 XDrawRectangle (dpy, x_win, gc, cursor_start, tmp_y, |
1160 { | 1453 { |
1161 XSetClipMask (dpy, gc, None); | 1454 XSetClipMask (dpy, gc, None); |
1162 XSetClipOrigin (dpy, gc, 0, 0); | 1455 XSetClipOrigin (dpy, gc, 0, 0); |
1163 } | 1456 } |
1164 } | 1457 } |
1458 | |
1459 #ifdef USE_XFT | |
1460 #undef XFT_FROB_LISP_COLOR | |
1461 #endif | |
1462 | |
1165 } | 1463 } |
1166 | 1464 |
1167 void | 1465 void |
1168 x_output_x_pixmap (struct frame *f, Lisp_Image_Instance *p, int x, | 1466 x_output_x_pixmap (struct frame *f, Lisp_Image_Instance *p, int x, |
1169 int y, int xoffset, int yoffset, | 1467 int y, int xoffset, int yoffset, |
1623 XQueryColor (dpy, cmap, &topc); | 1921 XQueryColor (dpy, cmap, &topc); |
1624 /* don't overflow/wrap! */ | 1922 /* don't overflow/wrap! */ |
1625 topc.red = MINL (65535, (unsigned long) topc.red * 6 / 5); | 1923 topc.red = MINL (65535, (unsigned long) topc.red * 6 / 5); |
1626 topc.green = MINL (65535, (unsigned long) topc.green * 6 / 5); | 1924 topc.green = MINL (65535, (unsigned long) topc.green * 6 / 5); |
1627 topc.blue = MINL (65535, (unsigned long) topc.blue * 6 / 5); | 1925 topc.blue = MINL (65535, (unsigned long) topc.blue * 6 / 5); |
1628 if (allocate_nearest_color (dpy, cmap, visual, &topc)) | 1926 if (x_allocate_nearest_color (dpy, cmap, visual, &topc)) |
1629 { | 1927 { |
1630 *top_shadow = topc.pixel; | 1928 *top_shadow = topc.pixel; |
1631 top_frobbed = 1; | 1929 top_frobbed = 1; |
1632 } | 1930 } |
1633 } | 1931 } |
1639 botc.pixel = background; | 1937 botc.pixel = background; |
1640 XQueryColor (dpy, cmap, &botc); | 1938 XQueryColor (dpy, cmap, &botc); |
1641 botc.red = (unsigned short) ((unsigned long) botc.red * 3 / 5); | 1939 botc.red = (unsigned short) ((unsigned long) botc.red * 3 / 5); |
1642 botc.green = (unsigned short) ((unsigned long) botc.green * 3 / 5); | 1940 botc.green = (unsigned short) ((unsigned long) botc.green * 3 / 5); |
1643 botc.blue = (unsigned short) ((unsigned long) botc.blue * 3 / 5); | 1941 botc.blue = (unsigned short) ((unsigned long) botc.blue * 3 / 5); |
1644 if (allocate_nearest_color (dpy, cmap, visual, &botc)) | 1942 if (x_allocate_nearest_color (dpy, cmap, visual, &botc)) |
1645 { | 1943 { |
1646 *bottom_shadow = botc.pixel; | 1944 *bottom_shadow = botc.pixel; |
1647 bottom_frobbed = 1; | 1945 bottom_frobbed = 1; |
1648 } | 1946 } |
1649 } | 1947 } |