comparison src/redisplay-msw.c @ 771:943eaba38521

[xemacs-hg @ 2002-03-13 08:51:24 by ben] The big ben-mule-21-5 check-in! Various files were added and deleted. See CHANGES-ben-mule. There are still some test suite failures. No crashes, though. Many of the failures have to do with problems in the test suite itself rather than in the actual code. I'll be addressing these in the next day or so -- none of the test suite failures are at all critical. Meanwhile I'll be trying to address the biggest issues -- i.e. build or run failures, which will almost certainly happen on various platforms. All comments should be sent to ben@xemacs.org -- use a Cc: if necessary when sending to mailing lists. There will be pre- and post- tags, something like pre-ben-mule-21-5-merge-in, and post-ben-mule-21-5-merge-in.
author ben
date Wed, 13 Mar 2002 08:54:06 +0000
parents b39c14581166
children e38acbeb1cae
comparison
equal deleted inserted replaced
770:336a418893b5 771:943eaba38521
1 /* mswindows output and frame manipulation routines. 1 /* mswindows output and frame manipulation routines.
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. 2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
3 Copyright (C) 1994 Lucid, Inc. 3 Copyright (C) 1994 Lucid, Inc.
4 Copyright (C) 1995 Sun Microsystems, Inc. 4 Copyright (C) 1995 Sun Microsystems, Inc.
5 Copyright (C) 2001 Ben Wing.
5 6
6 This file is part of XEmacs. 7 This file is part of XEmacs.
7 8
8 XEmacs is free software; you can redistribute it and/or modify it 9 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the 10 under the terms of the GNU General Public License as published by the
19 along with XEmacs; see the file COPYING. If not, write to 20 along with XEmacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */ 22 Boston, MA 02111-1307, USA. */
22 23
23 /* Synched up with: Not in FSF. */ 24 /* Synched up with: Not in FSF. */
25
26 /* I think this file is essentially Mule-ized, but I'm not sure!
27 Could stand a good once-over. Unicode support is trash, of course. */
24 28
25 /* Authorship: 29 /* Authorship:
26 30
27 Chuck Thompson 31 Chuck Thompson
28 Lots of work done by Ben Wing for Mule 32 Lots of work done by Ben Wing for Mule
44 #include "glyphs-msw.h" 48 #include "glyphs-msw.h"
45 #include "gutter.h" 49 #include "gutter.h"
46 #include "redisplay.h" 50 #include "redisplay.h"
47 #include "sysdep.h" 51 #include "sysdep.h"
48 #include "window.h" 52 #include "window.h"
49 53 #include "charset.h"
50 #ifdef MULE
51 #include "mule-ccl.h"
52 #include "mule-charset.h"
53 #endif
54 54
55 #define MSWINDOWS_EOL_CURSOR_WIDTH 5 55 #define MSWINDOWS_EOL_CURSOR_WIDTH 5
56 56
57 /* 57 /*
58 * Random forward declarations 58 * Random forward declarations
64 static void mswindows_output_vertical_divider (struct window *w, int clear); 64 static void mswindows_output_vertical_divider (struct window *w, int clear);
65 static void mswindows_redraw_exposed_windows (Lisp_Object window, int x, 65 static void mswindows_redraw_exposed_windows (Lisp_Object window, int x,
66 int y, int width, int height); 66 int y, int width, int height);
67 static void mswindows_output_dibitmap (struct frame *f, 67 static void mswindows_output_dibitmap (struct frame *f,
68 Lisp_Image_Instance *p, 68 Lisp_Image_Instance *p,
69 struct display_box* db, 69 struct display_box *db,
70 struct display_glyph_area* dga); 70 struct display_glyph_area *dga);
71 71
72 typedef struct textual_run 72 typedef struct textual_run
73 { 73 {
74 Lisp_Object charset; 74 Lisp_Object charset; /* charset of this run */
75 unsigned char *ptr; 75 WCHAR *ptr; /* pointer to Unicode chars in this run */
76 int len; 76 int nchars; /* number of internal characters in this run */
77 int dimension; 77 int nwchars; /* number of Unicode chars in this run */
78 } textual_run; 78 } textual_run;
79 79
80 /* Separate out the text in DYN into a series of textual runs of a 80 /* Separate out the text in STR into a series of textual runs of a
81 particular charset. Also convert the characters as necessary into 81 particular charset. Returns the number of runs actually used.
82 the format needed by XDrawImageString(), XDrawImageString16(), et 82 Returns the textual runs (STATICALLY ALLOCATED!) in RUN_STORAGE_PTR. */
83 al. (This means converting to one or two byte format, possibly
84 tweaking the high bits, and possibly running a CCL program.) You
85 must pre-allocate the space used and pass it in. (This is done so
86 you can alloca() the space.) You need to allocate (2 * len) bytes
87 of TEXT_STORAGE and (len * sizeof (textual_run)) bytes of
88 RUN_STORAGE, where LEN is the length of the dynarr.
89
90 Returns the number of runs actually used. */
91 83
92 static int 84 static int
93 separate_textual_runs (unsigned char *text_storage, 85 separate_textual_runs (textual_run **run_storage_ptr,
94 textual_run *run_storage,
95 const Emchar *str, Charcount len) 86 const Emchar *str, Charcount len)
96 { 87 {
97 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a 88 static WCHAR *ext_storage;
98 possible valid charset when 89 static int ext_storage_size; /* in WCHARS! */
99 MULE is not defined */ 90 static textual_run *run_storage;
91 static int run_storage_size;
100 int runs_so_far = 0; 92 int runs_so_far = 0;
93 int runbegin = 0;
94 int total_nchars = 0;
101 int i; 95 int i;
102 #ifdef MULE 96 Lisp_Object prev_charset;
103 struct ccl_program char_converter; 97
104 int need_ccl_conversion = 0; 98 if (len == 0)
105 #endif 99 return 0;
106 100
107 for (i = 0; i < len; i++) 101 prev_charset = CHAR_CHARSET (str[0]);
108 { 102
109 Emchar ch = str[i]; 103 for (i = 1; i <= len; i++)
110 Lisp_Object charset; 104 {
111 int byte1, byte2; 105 if (i == len || !EQ (CHAR_CHARSET (str[i]), prev_charset))
112 int dimension;
113 int graphic;
114
115 BREAKUP_CHAR (ch, charset, byte1, byte2);
116 dimension = XCHARSET_DIMENSION (charset);
117 graphic = XCHARSET_GRAPHIC (charset);
118
119 if (!EQ (charset, prev_charset))
120 { 106 {
121 run_storage[runs_so_far].ptr = text_storage; 107 int j;
122 run_storage[runs_so_far].charset = charset; 108 Intbyte *int_storage =
123 run_storage[runs_so_far].dimension = dimension; 109 alloca_intbytes (MAX_EMCHAR_LEN * (i - runbegin));
124 110 int int_storage_ptr = 0;
125 if (runs_so_far) 111 Extbyte *alloca_ext_storage;
126 { 112 int nchars;
127 run_storage[runs_so_far - 1].len = 113
128 text_storage - run_storage[runs_so_far - 1].ptr; 114 int_storage_ptr = 0;
129 if (run_storage[runs_so_far - 1].dimension == 2) 115 for (j = runbegin; j < i; j++)
130 run_storage[runs_so_far - 1].len >>= 1; 116 int_storage_ptr +=
131 } 117 set_charptr_emchar (int_storage + int_storage_ptr, str[j]);
118 TO_EXTERNAL_FORMAT (DATA, (int_storage, int_storage_ptr),
119 ALLOCA, (alloca_ext_storage, nchars),
120 Qmswindows_unicode);
121 nchars /= sizeof (WCHAR); /* Tricky ... */
122 DO_REALLOC (ext_storage, ext_storage_size, total_nchars + nchars,
123 WCHAR);
124 memcpy (ext_storage + total_nchars, alloca_ext_storage,
125 nchars * sizeof (WCHAR));
126 DO_REALLOC (run_storage, run_storage_size, runs_so_far + 1,
127 textual_run);
128 run_storage[runs_so_far].ptr = ext_storage + total_nchars;
129 run_storage[runs_so_far].charset = prev_charset;
130 run_storage[runs_so_far].nwchars = nchars;
131 run_storage[runs_so_far].nchars = i - runbegin;
132 total_nchars += nchars;
132 runs_so_far++; 133 runs_so_far++;
133 prev_charset = charset; 134 runbegin = i;
134 #ifdef MULE 135 if (i < len)
135 { 136 prev_charset = CHAR_CHARSET (str[i]);
136 Lisp_Object ccl_prog = XCHARSET_CCL_PROGRAM (charset);
137 if ((!NILP (ccl_prog))
138 && (setup_ccl_program (&char_converter, ccl_prog) >= 0))
139 need_ccl_conversion = 1;
140 }
141 #endif
142 } 137 }
143 138 }
144 if (graphic == 0) 139
145 { 140 *run_storage_ptr = run_storage;
146 byte1 &= 0x7F;
147 byte2 &= 0x7F;
148 }
149 else if (graphic == 1)
150 {
151 byte1 |= 0x80;
152 byte2 |= 0x80;
153 }
154 #ifdef MULE
155 if (need_ccl_conversion)
156 {
157 char_converter.reg[0] = XCHARSET_ID (charset);
158 char_converter.reg[1] = byte1;
159 char_converter.reg[2] = byte2;
160 char_converter.ic = 0; /* start at beginning each time */
161 ccl_driver (&char_converter, 0, 0, 0, 0, CCL_MODE_ENCODING);
162 byte1 = char_converter.reg[1];
163 byte2 = char_converter.reg[2];
164 }
165 #endif
166 *text_storage++ = (unsigned char) byte1;
167 if (dimension == 2)
168 *text_storage++ = (unsigned char) byte2;
169 }
170
171 if (runs_so_far)
172 {
173 run_storage[runs_so_far - 1].len =
174 text_storage - run_storage[runs_so_far - 1].ptr;
175 if (run_storage[runs_so_far - 1].dimension == 2)
176 run_storage[runs_so_far - 1].len >>= 1;
177 }
178
179 return runs_so_far; 141 return runs_so_far;
180 } 142 }
181 143
182 144
183 static int 145 static int
184 mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel, 146 mswindows_text_width_single_run (HDC hdc, struct face_cachel *cachel,
185 textual_run *run) 147 textual_run *run)
186 { 148 {
187 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); 149 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset);
188 Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst);
189 SIZE size; 150 SIZE size;
190 151
152 #if 0 /* @@#### not the way of ikeyama's ws */
191 if (!fi->proportional_p || !hdc) 153 if (!fi->proportional_p || !hdc)
192 return (fi->width * run->len); 154 {
155 if (XCHARSET_DIMENSION (run->charset) == 2)
156 /* Don't trust FONT_INSTANCE_WIDTH. Asian fonts have both of
157 one and two column characters. */
158 goto the_hard_way;
159 else
160 return fi->width * run->nchars;
161 }
193 else 162 else
194 { 163 {
195 assert(run->dimension == 1); /* #### FIXME! */ 164 the_hard_way:
165 #endif
196 mswindows_set_dc_font (hdc, font_inst, 166 mswindows_set_dc_font (hdc, font_inst,
197 cachel->underline, cachel->strikethru); 167 cachel->underline, cachel->strikethru);
198 /* !!#### more mule bogosity */ 168 GetTextExtentPoint32W (hdc, run->ptr, run->nwchars, &size);
199 GetTextExtentPoint32 (hdc, (char *) run->ptr, run->len, &size); 169 return size.cx;
200 return(size.cx); 170 #if 0 /* @@#### not the way of ikeyama's ws */
201 } 171 }
172 #endif
202 } 173 }
203 174
204 /* 175 /*
205 * Given F, retrieve device context. F can be a display frame, or 176 * Given F, retrieve device context. F can be a display frame, or
206 * a print job. For a print job, page is also started when printer's 177 * a print job. For a print job, page is also started when printer's
257 { 228 {
258 SetBkMode (hdc, TRANSPARENT); 229 SetBkMode (hdc, TRANSPARENT);
259 } 230 }
260 } 231 }
261 232
262 static void mswindows_set_dc_font (HDC hdc, Lisp_Object font, 233 static void
263 int under, int strike) 234 mswindows_set_dc_font (HDC hdc, Lisp_Object font, int under, int strike)
264 { 235 {
265 SelectObject(hdc, mswindows_get_hfont (XFONT_INSTANCE (font), 236 SelectObject (hdc, mswindows_get_hfont (XFONT_INSTANCE (font),
266 under, strike)); 237 under, strike));
267 } 238 }
268 239
269 /***************************************************************************** 240 /*****************************************************************************
270 mswindows_output_hline 241 mswindows_output_hline
271 242
272 Output a horizontal line in the foreground of its face. 243 Output a horizontal line in the foreground of its face.
273 ****************************************************************************/ 244 ****************************************************************************/
274 static void 245 static void
275 mswindows_output_hline (struct window *w, struct display_line *dl, struct rune *rb) 246 mswindows_output_hline (struct window *w, struct display_line *dl, struct rune *rb)
276 { /* XXX Implement me */ 247 { /* #### Implement me */
277 } 248 }
278 249
279 250
280 /***************************************************************************** 251 /*****************************************************************************
281 mswindows_output_blank 252 mswindows_output_blank
319 0, 0, 0, TRUE); 290 0, 0, 0, TRUE);
320 } 291 }
321 else 292 else
322 { 293 {
323 mswindows_update_dc (hdc, Qnil, cachel->background, Qnil); 294 mswindows_update_dc (hdc, Qnil, cachel->background, Qnil);
324 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); 295 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
325 } 296 }
326 } 297 }
327 298
328 299
329 /***************************************************************************** 300 /*****************************************************************************
336 mswindows_output_cursor (struct window *w, struct display_line *dl, int xpos, 307 mswindows_output_cursor (struct window *w, struct display_line *dl, int xpos,
337 int width, face_index findex, Emchar ch, int image_p) 308 int width, face_index findex, Emchar ch, int image_p)
338 { 309 {
339 struct frame *f = XFRAME (w->frame); 310 struct frame *f = XFRAME (w->frame);
340 struct device *d = XDEVICE (f->device); 311 struct device *d = XDEVICE (f->device);
341 struct face_cachel *cachel=0;
342 Lisp_Object font = Qnil; 312 Lisp_Object font = Qnil;
343 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); 313 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d));
344 HDC hdc = get_frame_dc (f, 1); 314 HDC hdc = get_frame_dc (f, 1);
345 int local_face_index = 0; 315 int local_face_index = 0;
346 char *p_char = NULL; 316 textual_run *run;
347 int n_char = 0; 317 int nruns = 0;
348 RECT rect = { xpos, 318 RECT rect = { xpos,
349 DISPLAY_LINE_YPOS (dl), 319 DISPLAY_LINE_YPOS (dl),
350 xpos + width, 320 xpos + width,
351 DISPLAY_LINE_YEND (dl) }; 321 DISPLAY_LINE_YEND (dl) };
352 Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor, 322 Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor,
360 width, DISPLAY_LINE_HEIGHT (dl)); 330 width, DISPLAY_LINE_HEIGHT (dl));
361 331
362 if (real_char_p) 332 if (real_char_p)
363 { 333 {
364 /* Use the font from the underlying character */ 334 /* Use the font from the underlying character */
365 cachel = WINDOW_FACE_CACHEL (w, findex); 335 struct face_cachel *font_cachel = WINDOW_FACE_CACHEL (w, findex);
366 336 nruns = separate_textual_runs (&run, &ch, 1);
367 /* #### MULE: Need to know the charset! */ 337 font = FACE_CACHEL_FONT (font_cachel, run->charset);
368 font = FACE_CACHEL_FONT (cachel, Vcharset_ascii); 338 mswindows_set_dc_font (hdc, font,
369 } 339 font_cachel->underline, font_cachel->strikethru);
370
371 if ((focus || bar_p) && real_char_p)
372 {
373 p_char = (char*) &ch;
374 n_char = 1;
375 } 340 }
376 341
377 if (!image_p) 342 if (!image_p)
378 { 343 {
379 struct face_cachel *color_cachel; 344 struct face_cachel *color_cachel;
384 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); 349 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face);
385 color_cachel = WINDOW_FACE_CACHEL (w, ((!cursor_p || bar_p) ? 350 color_cachel = WINDOW_FACE_CACHEL (w, ((!cursor_p || bar_p) ?
386 findex : local_face_index)); 351 findex : local_face_index));
387 mswindows_update_dc (hdc, color_cachel->foreground, 352 mswindows_update_dc (hdc, color_cachel->foreground,
388 color_cachel->background, Qnil); 353 color_cachel->background, Qnil);
389 if (real_char_p) 354 ExtTextOutW (hdc, xpos, dl->ypos, ETO_OPAQUE|ETO_CLIPPED, &rect,
390 mswindows_set_dc_font (hdc, font, 355 nruns ? run->ptr : NULL, nruns ? run->nwchars : 0, NULL);
391 cachel->underline, cachel->strikethru);
392
393 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE|ETO_CLIPPED, &rect, p_char, n_char, NULL);
394 } 356 }
395 357
396 if (!cursor_p) 358 if (!cursor_p)
397 return; 359 return;
398 360
399 if (focus && bar_p) 361 if (focus && bar_p)
400 { 362 {
363 struct face_cachel *cursor_cachel;
401 rect.right = rect.left + (EQ (bar, Qt) ? 1 : min (2, width)); 364 rect.right = rect.left + (EQ (bar, Qt) ? 1 : min (2, width));
402 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face); 365 local_face_index = get_builtin_face_cache_index (w, Vtext_cursor_face);
403 cachel = WINDOW_FACE_CACHEL (w, local_face_index); 366 cursor_cachel = WINDOW_FACE_CACHEL (w, local_face_index);
404 mswindows_update_dc (hdc, Qnil, cachel->background, Qnil); 367 mswindows_update_dc (hdc, Qnil, cursor_cachel->background, Qnil);
405 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE, &rect, NULL, 0, NULL); 368 ExtTextOutW (hdc, xpos, dl->ypos, ETO_OPAQUE, &rect, NULL, 0, NULL);
406 } 369 }
407 else if (!focus) 370 else if (!focus)
408 { 371 {
372 struct face_cachel *cursor_cachel;
373
409 /* Now have real character drawn in its own color. We deflate 374 /* Now have real character drawn in its own color. We deflate
410 the rectangle so character cell will be bounded by the 375 the rectangle so character cell will be bounded by the
411 previously drawn cursor shape */ 376 previously drawn cursor shape */
412 InflateRect (&rect, -1, -1); 377 InflateRect (&rect, -1, -1);
413
414 if (real_char_p)
415 {
416 p_char = (char*) &ch;
417 n_char = 1;
418 }
419
420 local_face_index = get_builtin_face_cache_index (w, Vdefault_face); 378 local_face_index = get_builtin_face_cache_index (w, Vdefault_face);
421 cachel = WINDOW_FACE_CACHEL (w, (real_char_p ? findex : local_face_index)); 379 cursor_cachel =
380 WINDOW_FACE_CACHEL (w, (real_char_p ? findex : local_face_index));
422 mswindows_update_dc (hdc, 381 mswindows_update_dc (hdc,
423 cachel->foreground, cachel->background, Qnil); 382 cursor_cachel->foreground,
424 ExtTextOut (hdc, xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED, 383 cursor_cachel->background, Qnil);
425 &rect, p_char, n_char, NULL); 384 ExtTextOutW (hdc, xpos, dl->ypos, ETO_OPAQUE | ETO_CLIPPED,
426 } 385 &rect, nruns ? run->ptr : NULL, nruns ? run->nwchars : 0,
386 NULL);
387 }
388
389 #ifdef MULE
390 if (DEVICE_MSWINDOWS_P (d) &&
391 (FRAME_MSWINDOWS_CURSOR_X (f) != xpos
392 || FRAME_MSWINDOWS_CURSOR_Y (f) != DISPLAY_LINE_YPOS (dl)
393 || FRAME_MSWINDOWS_CURSOR_FINDEX (f) != findex))
394 {
395 HWND hwnd = FRAME_MSWINDOWS_HANDLE(f);
396 HIMC himc = ImmGetContext (hwnd);
397
398 FRAME_MSWINDOWS_CURSOR_X (f) = xpos;
399 FRAME_MSWINDOWS_CURSOR_Y (f) = DISPLAY_LINE_YPOS (dl);
400 FRAME_MSWINDOWS_CURSOR_FINDEX (f) = findex;
401
402 /* If the composition window is active, reset position of the
403 composition window. */
404 if (qxeImmGetCompositionString (himc, GCS_COMPSTR, NULL, 0))
405 mswindows_start_ime_composition (f);
406
407 ImmReleaseContext (hwnd, himc);
408 }
409 #endif /* MULE */
427 } 410 }
428 411
429 412
430 /***************************************************************************** 413 /*****************************************************************************
431 mswindows_output_string 414 mswindows_output_string
462 /* struct device *d = XDEVICE (f->device);*/ 445 /* struct device *d = XDEVICE (f->device);*/
463 Lisp_Object window; 446 Lisp_Object window;
464 HDC hdc = get_frame_dc (f, 1); 447 HDC hdc = get_frame_dc (f, 1);
465 int clip_end; 448 int clip_end;
466 Lisp_Object bg_pmap; 449 Lisp_Object bg_pmap;
467 int len = Dynarr_length (buf); 450 textual_run *runs;
468 unsigned char *text_storage = (unsigned char *) alloca (2 * len);
469 textual_run *runs = alloca_array (textual_run, len);
470 int nruns; 451 int nruns;
471 int i, height; 452 int i, height;
472 RECT rect; 453 RECT rect;
473 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex); 454 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex);
474 455
523 /* output pixmap calls this so we have to recall to get correct 504 /* output pixmap calls this so we have to recall to get correct
524 references */ 505 references */
525 cachel = WINDOW_FACE_CACHEL (w, findex); 506 cachel = WINDOW_FACE_CACHEL (w, findex);
526 } 507 }
527 508
528 nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0), 509 nruns = separate_textual_runs (&runs, Dynarr_atp (buf, 0),
529 Dynarr_length (buf)); 510 Dynarr_length (buf));
530 511
531 for (i = 0; i < nruns; i++) 512 for (i = 0; i < nruns; i++)
532 { 513 {
533 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); 514 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset);
558 references */ 539 references */
559 cachel = WINDOW_FACE_CACHEL (w, findex); 540 cachel = WINDOW_FACE_CACHEL (w, findex);
560 } 541 }
561 } 542 }
562 543
563 assert (runs[i].dimension == 1); /* #### FIXME: Broken when Mule? */ 544 ExtTextOutW (hdc, xpos, dl->ypos,
564 ExtTextOut (hdc, xpos, dl->ypos, 545 NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED,
565 NILP(bg_pmap) ? ETO_CLIPPED | ETO_OPAQUE : ETO_CLIPPED, 546 &rect, runs[i].ptr, runs[i].nwchars, NULL);
566 &rect, (char *) runs[i].ptr, runs[i].len, NULL);
567 547
568 xpos += this_width; 548 xpos += this_width;
569 } 549 }
570 } 550 }
571 551
572 static void 552 static void
573 mswindows_output_dibitmap (struct frame *f, Lisp_Image_Instance *p, 553 mswindows_output_dibitmap (struct frame *f, Lisp_Image_Instance *p,
574 struct display_box* db, 554 struct display_box *db,
575 struct display_glyph_area* dga) 555 struct display_glyph_area *dga)
576 { 556 {
577 HDC hdc = get_frame_dc (f, 1); 557 HDC hdc = get_frame_dc (f, 1);
578 HDC hcompdc = get_frame_compdc (f); 558 HDC hcompdc = get_frame_compdc (f);
579 HGDIOBJ old=NULL; 559 HGDIOBJ old=NULL;
580 const int real_x = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (p); 560 const int real_x = IMAGE_INSTANCE_MSWINDOWS_BITMAP_REAL_WIDTH (p);
733 * 713 *
734 * Function checks whether deadbox intersects with the rectangle pointed 714 * Function checks whether deadbox intersects with the rectangle pointed
735 * to by PRC, and paints only the intersection 715 * to by PRC, and paints only the intersection
736 */ 716 */
737 static void 717 static void
738 mswindows_redisplay_deadbox_maybe (struct window *w, const RECT* prc) 718 mswindows_redisplay_deadbox_maybe (struct window *w, const RECT *prc)
739 { 719 {
740 int sbh = window_scrollbar_height (w); 720 int sbh = window_scrollbar_height (w);
741 int sbw = window_scrollbar_width (w); 721 int sbw = window_scrollbar_width (w);
742 RECT rect_dead, rect_paint; 722 RECT rect_dead, rect_paint;
743 if (sbh == 0 || sbw == 0) 723 if (sbh == 0 || sbw == 0)
1037 Given a display line, a block number for that start line, output all 1017 Given a display line, a block number for that start line, output all
1038 runes between start and end in the specified display block. 1018 runes between start and end in the specified display block.
1039 Ripped off with minimal thought from the corresponding X routine. 1019 Ripped off with minimal thought from the corresponding X routine.
1040 ****************************************************************************/ 1020 ****************************************************************************/
1041 static void 1021 static void
1042 mswindows_output_display_block (struct window *w, struct display_line *dl, int block, 1022 mswindows_output_display_block (struct window *w, struct display_line *dl,
1043 int start, int end, int start_pixpos, int cursor_start, 1023 int block, int start, int end,
1044 int cursor_width, int cursor_height) 1024 int start_pixpos, int cursor_start,
1025 int cursor_width, int cursor_height)
1045 { 1026 {
1046 struct frame *f = XFRAME (w->frame); 1027 struct frame *f = XFRAME (w->frame);
1047 Emchar_dynarr *buf = Dynarr_new (Emchar); 1028 Emchar_dynarr *buf = Dynarr_new (Emchar);
1048 Lisp_Object window; 1029 Lisp_Object window;
1049 1030
1087 } 1068 }
1088 else 1069 else
1089 { 1070 {
1090 if (Dynarr_length (buf)) 1071 if (Dynarr_length (buf))
1091 { 1072 {
1092 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, 1073 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos,
1093 findex, 0, 0, 0, 0); 1074 width, findex, 0, 0, 0, 0);
1094 xpos = rb->xpos; 1075 xpos = rb->xpos;
1095 width = 0; 1076 width = 0;
1096 } 1077 }
1097 Dynarr_reset (buf); 1078 Dynarr_reset (buf);
1098 width = 0; 1079 width = 0;
1270 rect.bottom = y2; 1251 rect.bottom = y2;
1271 mswindows_update_dc (hdc, Qnil, 1252 mswindows_update_dc (hdc, Qnil,
1272 WINDOW_FACE_CACHEL_BACKGROUND (w, DEFAULT_INDEX), Qnil); 1253 WINDOW_FACE_CACHEL_BACKGROUND (w, DEFAULT_INDEX), Qnil);
1273 rect.right = WINDOW_RIGHT (w); 1254 rect.right = WINDOW_RIGHT (w);
1274 rect.left = rect.right - spacing; 1255 rect.left = rect.right - spacing;
1275 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, 1256 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
1276 &rect, NULL, 0, NULL);
1277 rect.left = div_left; 1257 rect.left = div_left;
1278 rect.right = div_left + spacing; 1258 rect.right = div_left + spacing;
1279 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, 1259 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
1280 &rect, NULL, 0, NULL);
1281 } 1260 }
1282 1261
1283 /* Clear divider face */ 1262 /* Clear divider face */
1284 rect.top = y1 + abs_shadow; 1263 rect.top = y1 + abs_shadow;
1285 rect.bottom = y2 - abs_shadow; 1264 rect.bottom = y2 - abs_shadow;
1289 { 1268 {
1290 face_index div_face 1269 face_index div_face
1291 = get_builtin_face_cache_index (w, Vvertical_divider_face); 1270 = get_builtin_face_cache_index (w, Vvertical_divider_face);
1292 mswindows_update_dc (hdc, Qnil, 1271 mswindows_update_dc (hdc, Qnil,
1293 WINDOW_FACE_CACHEL_BACKGROUND (w, div_face), Qnil); 1272 WINDOW_FACE_CACHEL_BACKGROUND (w, div_face), Qnil);
1294 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); 1273 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
1295 } 1274 }
1296 1275
1297 /* Draw a shadow around the divider */ 1276 /* Draw a shadow around the divider */
1298 if (shadow != 0) 1277 if (shadow != 0)
1299 { 1278 {
1314 mswindows_text_width (struct frame *f, struct face_cachel *cachel, 1293 mswindows_text_width (struct frame *f, struct face_cachel *cachel,
1315 const Emchar *str, Charcount len) 1294 const Emchar *str, Charcount len)
1316 { 1295 {
1317 HDC hdc = get_frame_dc (f, 0); 1296 HDC hdc = get_frame_dc (f, 0);
1318 int width_so_far = 0; 1297 int width_so_far = 0;
1319 unsigned char *text_storage = (unsigned char *) alloca (2 * len); 1298 textual_run *runs;
1320 textual_run *runs = alloca_array (textual_run, len);
1321 int nruns; 1299 int nruns;
1322 int i; 1300 int i;
1323 1301
1324 nruns = separate_textual_runs (text_storage, runs, str, len); 1302 nruns = separate_textual_runs (&runs, str, len);
1325 1303
1326 for (i = 0; i < nruns; i++) 1304 for (i = 0; i < nruns; i++)
1327 width_so_far += mswindows_text_width_single_run (hdc, 1305 width_so_far += mswindows_text_width_single_run (hdc, cachel, runs + i);
1328 cachel, runs + i);
1329 1306
1330 return width_so_far; 1307 return width_so_far;
1331 } 1308 }
1332 1309
1333 1310
1336 1313
1337 Clear the area in the box defined by the given parameters using the 1314 Clear the area in the box defined by the given parameters using the
1338 given face. 1315 given face.
1339 ****************************************************************************/ 1316 ****************************************************************************/
1340 static void 1317 static void
1341 mswindows_clear_region (Lisp_Object locale, struct device* d, struct frame* f, 1318 mswindows_clear_region (Lisp_Object locale, struct device *d, struct frame *f,
1342 face_index findex, int x, int y, 1319 face_index findex, int x, int y,
1343 int width, int height, Lisp_Object fcolor, Lisp_Object bcolor, 1320 int width, int height, Lisp_Object fcolor, Lisp_Object bcolor,
1344 Lisp_Object background_pixmap) 1321 Lisp_Object background_pixmap)
1345 { 1322 {
1346 RECT rect = { x, y, x+width, y+height }; 1323 RECT rect = { x, y, x+width, y+height };
1355 ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0); 1332 ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0);
1356 } 1333 }
1357 else 1334 else
1358 { 1335 {
1359 mswindows_update_dc (hdc, Qnil, fcolor, Qnil); 1336 mswindows_update_dc (hdc, Qnil, fcolor, Qnil);
1360 ExtTextOut (hdc, 0, 0, ETO_OPAQUE, 1337 ExtTextOutW (hdc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
1361 &rect, NULL, 0, NULL);
1362 } 1338 }
1363 1339
1364 #ifdef HAVE_SCROLLBARS 1340 #ifdef HAVE_SCROLLBARS
1365 if (WINDOWP (locale)) 1341 if (WINDOWP (locale))
1366 mswindows_redisplay_deadbox_maybe (XWINDOW (locale), &rect); 1342 mswindows_redisplay_deadbox_maybe (XWINDOW (locale), &rect);
1371 static void 1347 static void
1372 mswindows_clear_frame (struct frame *f) 1348 mswindows_clear_frame (struct frame *f)
1373 { 1349 {
1374 GdiFlush(); 1350 GdiFlush();
1375 } 1351 }
1376
1377 1352
1378 1353
1379 /************************************************************************/ 1354 /************************************************************************/
1380 /* initialization */ 1355 /* initialization */
1381 /************************************************************************/ 1356 /************************************************************************/