Mercurial > hg > xemacs-beta
comparison src/redisplay-msw.c @ 424:11054d720c21 r21-2-20
Import from CVS: tag r21-2-20
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:26:11 +0200 |
parents | 95016f13131a |
children |
comparison
equal
deleted
inserted
replaced
423:28d9c139be4c | 424:11054d720c21 |
---|---|
62 static void mswindows_output_vertical_divider (struct window *w, int clear); | 62 static void mswindows_output_vertical_divider (struct window *w, int clear); |
63 static void mswindows_redraw_exposed_windows (Lisp_Object window, int x, | 63 static void mswindows_redraw_exposed_windows (Lisp_Object window, int x, |
64 int y, int width, int height); | 64 int y, int width, int height); |
65 static void mswindows_output_dibitmap (struct frame *f, | 65 static void mswindows_output_dibitmap (struct frame *f, |
66 struct Lisp_Image_Instance *p, | 66 struct Lisp_Image_Instance *p, |
67 int x, int y, | 67 struct display_box* db, |
68 int clip_x, int clip_y, | 68 struct display_glyph_area* dga); |
69 int clip_width, int clip_height, | |
70 int width, int height, | |
71 int pixmap_offset, | |
72 int offset_bitmap); | |
73 static void mswindows_output_pixmap (struct window *w, struct display_line *dl, | |
74 Lisp_Object image_instance, int xpos, | |
75 int xoffset, int start_pixpos, int width, | |
76 face_index findex, int cursor_start, | |
77 int cursor_width, int cursor_height, | |
78 int offset_bitmap); | |
79 void bevel_modeline (struct window *w, struct display_line *dl); | |
80 | 69 |
81 typedef struct textual_run | 70 typedef struct textual_run |
82 { | 71 { |
83 Lisp_Object charset; | 72 Lisp_Object charset; |
84 unsigned char *ptr; | 73 unsigned char *ptr; |
302 | 291 |
303 Output a blank by clearing the area it covers in the background color | 292 Output a blank by clearing the area it covers in the background color |
304 of its face. | 293 of its face. |
305 ****************************************************************************/ | 294 ****************************************************************************/ |
306 static void | 295 static void |
307 mswindows_output_blank (struct window *w, struct display_line *dl, struct rune *rb, int start_pixpos) | 296 mswindows_output_blank (struct window *w, struct display_line *dl, |
297 struct rune *rb, int start_pixpos) | |
308 { | 298 { |
309 struct frame *f = XFRAME (w->frame); | 299 struct frame *f = XFRAME (w->frame); |
310 RECT rect = { rb->xpos, dl->ypos-dl->ascent, | 300 RECT rect = { rb->xpos, DISPLAY_LINE_YPOS (dl), |
311 rb->xpos+rb->width, dl->ypos+dl->descent-dl->clip }; | 301 rb->xpos+rb->width, |
302 DISPLAY_LINE_YEND (dl) }; | |
312 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex); | 303 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex); |
313 | 304 |
314 Lisp_Object bg_pmap = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, rb->findex); | 305 Lisp_Object bg_pmap = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, rb->findex); |
306 | |
307 /* Unmap all subwindows in the area we are going to blank. */ | |
308 redisplay_unmap_subwindows_maybe (f, rb->xpos, DISPLAY_LINE_YPOS (dl), | |
309 rb->width, DISPLAY_LINE_HEIGHT (dl)); | |
315 | 310 |
316 if (!IMAGE_INSTANCEP (bg_pmap) | 311 if (!IMAGE_INSTANCEP (bg_pmap) |
317 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) | 312 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) |
318 bg_pmap = Qnil; | 313 bg_pmap = Qnil; |
319 | 314 |
320 if (!NILP(bg_pmap)) | 315 if (!NILP(bg_pmap)) |
321 { | 316 { |
317 struct display_box db; | |
318 struct display_glyph_area dga; | |
319 redisplay_calculate_display_boxes (dl, rb->xpos, | |
320 /*rb->object.dglyph.xoffset*/ 0, | |
321 start_pixpos, rb->width, | |
322 &db, &dga); | |
322 /* blank the background in the appropriate color */ | 323 /* blank the background in the appropriate color */ |
323 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, cachel->foreground, | 324 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, cachel->foreground, |
324 cachel->background, Qnil); | 325 cachel->background, Qnil); |
325 | 326 redisplay_output_pixmap (w, bg_pmap, &db, &dga, rb->findex, |
326 mswindows_output_pixmap (w, dl, bg_pmap, | |
327 rb->xpos, 0 /*rb->object.dglyph.xoffset*/, | |
328 start_pixpos, rb->width, rb->findex, | |
329 0, 0, 0, TRUE); | 327 0, 0, 0, TRUE); |
330 } | 328 } |
331 else | 329 else |
332 { | 330 { |
333 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, | 331 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, |
357 HDC hdc = FRAME_MSWINDOWS_DC (f); | 355 HDC hdc = FRAME_MSWINDOWS_DC (f); |
358 unsigned int face_index=0; | 356 unsigned int face_index=0; |
359 char *p_char = NULL; | 357 char *p_char = NULL; |
360 int n_char = 0; | 358 int n_char = 0; |
361 RECT rect = { xpos, | 359 RECT rect = { xpos, |
362 dl->ypos - dl->ascent, | 360 DISPLAY_LINE_YPOS (dl), |
363 xpos + width, | 361 xpos + width, |
364 dl->ypos + dl->descent - dl->clip}; | 362 DISPLAY_LINE_YEND (dl) }; |
365 Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor, | 363 Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor, |
366 WINDOW_BUFFER (w)); | 364 WINDOW_BUFFER (w)); |
367 int bar_p = image_p || !NILP (bar); | 365 int bar_p = image_p || !NILP (bar); |
368 int cursor_p = !NILP (w->text_cursor_visible_p); | 366 int cursor_p = !NILP (w->text_cursor_visible_p); |
369 int real_char_p = ch != 0; | 367 int real_char_p = ch != 0; |
368 | |
369 /* Unmap all subwindows in the area we are going to blank. */ | |
370 redisplay_unmap_subwindows_maybe (f, xpos, DISPLAY_LINE_YPOS (dl), | |
371 width, DISPLAY_LINE_HEIGHT (dl)); | |
370 | 372 |
371 if (real_char_p) | 373 if (real_char_p) |
372 { | 374 { |
373 /* Use the font from the underlying character */ | 375 /* Use the font from the underlying character */ |
374 cachel = WINDOW_FACE_CACHEL (w, findex); | 376 cachel = WINDOW_FACE_CACHEL (w, findex); |
464 FINDEX Index for the face cache element describing how to display | 466 FINDEX Index for the face cache element describing how to display |
465 the text. | 467 the text. |
466 ****************************************************************************/ | 468 ****************************************************************************/ |
467 void | 469 void |
468 mswindows_output_string (struct window *w, struct display_line *dl, | 470 mswindows_output_string (struct window *w, struct display_line *dl, |
469 Emchar_dynarr *buf, int xpos, int xoffset, int clip_start, | 471 Emchar_dynarr *buf, int xpos, int xoffset, int clip_start, |
470 int width, face_index findex) | 472 int width, face_index findex, |
473 int cursor, int cursor_start, int cursor_width, | |
474 int cursor_height) | |
471 { | 475 { |
472 struct frame *f = XFRAME (w->frame); | 476 struct frame *f = XFRAME (w->frame); |
473 /* struct device *d = XDEVICE (f->device);*/ | 477 /* struct device *d = XDEVICE (f->device);*/ |
474 Lisp_Object window; | 478 Lisp_Object window; |
475 HDC hdc = FRAME_MSWINDOWS_DC (f); | 479 HDC hdc = FRAME_MSWINDOWS_DC (f); |
504 xpos -= xoffset; | 508 xpos -= xoffset; |
505 | 509 |
506 /* sort out the destination rectangle */ | 510 /* sort out the destination rectangle */ |
507 height = DISPLAY_LINE_HEIGHT (dl); | 511 height = DISPLAY_LINE_HEIGHT (dl); |
508 rect.left = clip_start; | 512 rect.left = clip_start; |
509 rect.top = dl->ypos - dl->ascent; | 513 rect.top = DISPLAY_LINE_YPOS (dl); |
510 rect.right = clip_end; | 514 rect.right = clip_end; |
511 rect.bottom = height + dl->ypos - dl->ascent; | 515 rect.bottom = rect.top + height; |
516 | |
517 /* make sure the area we are about to display is subwindow free. */ | |
518 redisplay_unmap_subwindows_maybe (f, clip_start, DISPLAY_LINE_YPOS (dl), | |
519 clip_end - clip_start, DISPLAY_LINE_HEIGHT (dl)); | |
512 | 520 |
513 /* output the background pixmap if there is one */ | 521 /* output the background pixmap if there is one */ |
514 bg_pmap = cachel->background_pixmap; | 522 bg_pmap = cachel->background_pixmap; |
515 if (!IMAGE_INSTANCEP (bg_pmap) | 523 if (!IMAGE_INSTANCEP (bg_pmap) |
516 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) | 524 || !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap))) |
517 bg_pmap = Qnil; | 525 bg_pmap = Qnil; |
518 | 526 |
519 if (!NILP(bg_pmap)) | 527 if (!NILP(bg_pmap)) |
520 { | 528 { |
529 struct display_box db; | |
530 struct display_glyph_area dga; | |
531 redisplay_calculate_display_boxes (dl, xpos + xoffset, 0, | |
532 clip_start, width, &db, &dga); | |
521 /* blank the background in the appropriate color */ | 533 /* blank the background in the appropriate color */ |
522 mswindows_update_dc (hdc, Qnil, cachel->foreground, | 534 mswindows_update_dc (hdc, Qnil, cachel->foreground, |
523 cachel->background, Qnil); | 535 cachel->background, Qnil); |
524 | 536 redisplay_output_pixmap (w, bg_pmap, &db, &dga, findex, |
525 mswindows_output_pixmap (w, dl, bg_pmap, | |
526 xpos, xoffset, | |
527 clip_start, width, findex, | |
528 0, 0, 0, TRUE); | 537 0, 0, 0, TRUE); |
529 /* output pixmap calls this so we have to recall to get correct | 538 /* output pixmap calls this so we have to recall to get correct |
530 references */ | 539 references */ |
531 cachel = WINDOW_FACE_CACHEL (w, findex); | 540 cachel = WINDOW_FACE_CACHEL (w, findex); |
532 } | 541 } |
547 NILP(bg_pmap) ? cachel->background : Qnil, Qnil); | 556 NILP(bg_pmap) ? cachel->background : Qnil, Qnil); |
548 | 557 |
549 this_width = mswindows_text_width_single_run (hdc, cachel, runs + i); | 558 this_width = mswindows_text_width_single_run (hdc, cachel, runs + i); |
550 | 559 |
551 /* cope with fonts taller than lines */ | 560 /* cope with fonts taller than lines */ |
552 if ((int) fi->height < (int) (height + dl->clip)) | 561 if ((int) fi->height < (int) (height + dl->clip + dl->top_clip)) |
553 { | 562 { |
554 int clear_start = max (xpos, clip_start); | 563 int clear_start = max (xpos, clip_start); |
555 int clear_end = min (xpos + this_width, clip_end); | 564 int clear_end = min (xpos + this_width, clip_end); |
556 | 565 |
557 { | 566 { |
558 redisplay_clear_region (window, findex, clear_start, | 567 redisplay_clear_region (window, findex, clear_start, |
559 dl->ypos - dl->ascent, | 568 DISPLAY_LINE_YPOS (dl), |
560 clear_end - clear_start, | 569 clear_end - clear_start, |
561 height); | 570 height); |
562 /* output pixmap calls this so we have to recall to get correct | 571 /* output pixmap calls this so we have to recall to get correct |
563 references */ | 572 references */ |
564 cachel = WINDOW_FACE_CACHEL (w, findex); | 573 cachel = WINDOW_FACE_CACHEL (w, findex); |
579 } | 588 } |
580 } | 589 } |
581 | 590 |
582 static void | 591 static void |
583 mswindows_output_dibitmap (struct frame *f, struct Lisp_Image_Instance *p, | 592 mswindows_output_dibitmap (struct frame *f, struct Lisp_Image_Instance *p, |
584 int x, int y, | 593 struct display_box* db, |
585 int clip_x, int clip_y, | 594 struct display_glyph_area* dga) |
586 int clip_width, int clip_height, | |
587 int width, int height, int pixmap_offset, | |
588 int offset_bitmap) | |
589 { | 595 { |
590 HDC hdc = FRAME_MSWINDOWS_DC (f); | 596 HDC hdc = FRAME_MSWINDOWS_DC (f); |
591 HGDIOBJ old=NULL; | 597 HGDIOBJ old=NULL; |
592 COLORREF bgcolor = GetBkColor (hdc); | 598 COLORREF bgcolor = GetBkColor (hdc); |
593 int need_clipping = (clip_x || clip_y); | |
594 int yoffset=0; | |
595 int xoffset=0; | |
596 | |
597 /* do we need to offset the pixmap vertically? this is necessary | |
598 for background pixmaps. */ | |
599 if (offset_bitmap) | |
600 { | |
601 yoffset = y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p); | |
602 xoffset = x % IMAGE_INSTANCE_PIXMAP_WIDTH (p); | |
603 /* the width is handled by mswindows_output_pixmap_region */ | |
604 } | |
605 | |
606 if (need_clipping) | |
607 { | |
608 } | |
609 | 599 |
610 /* first blt the mask */ | 600 /* first blt the mask */ |
611 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) | 601 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) |
612 { | 602 { |
613 RGBQUAD col; | 603 RGBQUAD col; |
620 IMAGE_INSTANCE_MSWINDOWS_MASK (p)); | 610 IMAGE_INSTANCE_MSWINDOWS_MASK (p)); |
621 | 611 |
622 SetDIBColorTable (FRAME_MSWINDOWS_CDC (f), 1, 1, &col); | 612 SetDIBColorTable (FRAME_MSWINDOWS_CDC (f), 1, 1, &col); |
623 | 613 |
624 BitBlt (hdc, | 614 BitBlt (hdc, |
625 x,y, | 615 db->xpos, db->ypos, |
626 width, height, | 616 dga->width, dga->height, |
627 FRAME_MSWINDOWS_CDC (f), | 617 FRAME_MSWINDOWS_CDC (f), |
628 xoffset,yoffset, | 618 dga->xoffset, dga->yoffset, |
629 SRCCOPY); | 619 SRCCOPY); |
630 | 620 |
631 SelectObject (FRAME_MSWINDOWS_CDC (f), old); | 621 SelectObject (FRAME_MSWINDOWS_CDC (f), old); |
632 } | 622 } |
633 | 623 |
634 /* now blt the bitmap itself. */ | 624 /* Now blt the bitmap itself, or one of its slices. */ |
635 old = SelectObject (FRAME_MSWINDOWS_CDC (f), | 625 old = SelectObject (FRAME_MSWINDOWS_CDC (f), |
636 IMAGE_INSTANCE_MSWINDOWS_BITMAP (p)); | 626 IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE |
627 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p))); | |
637 | 628 |
638 BitBlt (hdc, | 629 BitBlt (hdc, |
639 x,y, | 630 db->xpos, db->ypos, |
640 width, height, | 631 dga->width, dga->height, |
641 FRAME_MSWINDOWS_CDC (f), | 632 FRAME_MSWINDOWS_CDC (f), |
642 xoffset, yoffset, | 633 dga->xoffset, dga->yoffset, |
643 IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); | 634 IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY); |
644 | 635 |
645 SelectObject (FRAME_MSWINDOWS_CDC (f),old); | 636 SelectObject (FRAME_MSWINDOWS_CDC (f),old); |
646 | 637 } |
647 if (need_clipping) | 638 |
648 { | 639 /* X gc's have this nice property that setting the bg pixmap will |
649 } | |
650 } | |
651 | |
652 /* | |
653 * X gc's have this nice property that setting the bg pixmap will | |
654 * output it offset relative to the window. Windows doesn't have this | 640 * output it offset relative to the window. Windows doesn't have this |
655 * feature so we have to emulate this by outputting multiple pixmaps | 641 * feature so we have to emulate this by outputting multiple pixmaps. |
656 */ | 642 * This is only used for background pixmaps. Normal pixmaps are |
643 * outputted once and are scrollable */ | |
657 static void | 644 static void |
658 mswindows_output_dibitmap_region (struct frame *f, | 645 mswindows_output_dibitmap_region (struct frame *f, |
659 struct Lisp_Image_Instance *p, | 646 struct Lisp_Image_Instance *p, |
660 int x, int y, | 647 struct display_box *db, |
661 int clip_x, int clip_y, | 648 struct display_glyph_area *dga) |
662 int clip_width, int clip_height, | 649 { |
663 int width, int height, int pixmap_offset, | 650 struct display_box xdb = { db->xpos, db->ypos, db->width, db->height }; |
664 int offset_bitmap) | 651 struct display_glyph_area xdga |
665 { | 652 = { 0, 0, IMAGE_INSTANCE_PIXMAP_WIDTH (p), |
666 int pwidth = min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | 653 IMAGE_INSTANCE_PIXMAP_HEIGHT (p) }; |
667 int pheight = min (height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | |
668 int pxoffset = 0, pyoffset = 0; | 654 int pxoffset = 0, pyoffset = 0; |
655 | |
656 if (dga) | |
657 { | |
658 xdga.width = dga->width; | |
659 xdga.height = dga->height; | |
660 } | |
661 else if (!redisplay_normalize_glyph_area (&xdb, &xdga)) | |
662 return; | |
669 | 663 |
670 /* when doing a bg pixmap do a partial pixmap first so that we | 664 /* when doing a bg pixmap do a partial pixmap first so that we |
671 blt whole pixmaps thereafter */ | 665 blt whole pixmaps thereafter */ |
672 | 666 xdga.height = min (xdga.height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - |
673 if (offset_bitmap) | 667 db->ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); |
674 { | 668 |
675 pheight = min (pheight, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - | 669 while (xdga.height > 0) |
676 y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | 670 { |
677 } | 671 xdga.width = min (min (db->width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), |
678 | 672 IMAGE_INSTANCE_PIXMAP_WIDTH (p) - |
679 while (pheight > 0) | 673 db->xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); |
680 { | 674 pxoffset = 0; |
681 if (offset_bitmap) | 675 while (xdga.width > 0) |
682 { | 676 { |
683 pwidth = min (min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)), | 677 xdb.xpos = db->xpos + pxoffset; |
684 IMAGE_INSTANCE_PIXMAP_WIDTH (p) - | 678 xdb.ypos = db->ypos + pyoffset; |
685 x % IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | 679 /* do we need to offset the pixmap vertically? this is necessary |
686 pxoffset = 0; | 680 for background pixmaps. */ |
681 xdga.yoffset = xdb.ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p); | |
682 xdga.xoffset = xdb.xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p); | |
683 /* the width is handled by mswindows_output_pixmap_region */ | |
684 mswindows_output_dibitmap (f, p, &xdb, &xdga); | |
685 pxoffset += xdga.width; | |
686 xdga.width = min ((db->width - pxoffset), | |
687 IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | |
687 } | 688 } |
688 while (pwidth > 0) | 689 pyoffset += xdga.height; |
689 { | 690 xdga.height = min ((db->height - pyoffset), |
690 mswindows_output_dibitmap (f, p, | 691 IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); |
691 x + pxoffset, y + pyoffset, | 692 } |
692 clip_x, clip_y, | 693 } |
693 clip_width, clip_height, | 694 |
694 pwidth, pheight, pixmap_offset, | 695 /* Output a pixmap at the desired location. |
695 offset_bitmap); | 696 DB normalized display_box. |
696 pxoffset += pwidth; | 697 DGA normalized display_glyph_area. */ |
697 pwidth = min ((width-pxoffset), | 698 static void |
698 IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | 699 mswindows_output_pixmap (struct window *w, Lisp_Object image_instance, |
699 } | 700 struct display_box *db, struct display_glyph_area *dga, |
700 pyoffset += pheight; | 701 face_index findex, int cursor_start, int cursor_width, |
701 pheight = min ((height-pyoffset), | 702 int cursor_height, int bg_pixmap) |
702 IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | |
703 } | |
704 } | |
705 | |
706 static void | |
707 mswindows_output_pixmap (struct window *w, struct display_line *dl, | |
708 Lisp_Object image_instance, int xpos, int xoffset, | |
709 int start_pixpos, int width, face_index findex, | |
710 int cursor_start, int cursor_width, int cursor_height, | |
711 int offset_bitmap) | |
712 { | 703 { |
713 struct frame *f = XFRAME (w->frame); | 704 struct frame *f = XFRAME (w->frame); |
714 HDC hdc = FRAME_MSWINDOWS_DC (f); | 705 HDC hdc = FRAME_MSWINDOWS_DC (f); |
715 | 706 |
716 struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | 707 struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); |
717 Lisp_Object window; | 708 Lisp_Object window; |
718 | 709 |
719 int lheight = DISPLAY_LINE_HEIGHT (dl); | |
720 int pheight = ((int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p) > lheight ? lheight : | |
721 IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | |
722 int clip_x, clip_y, clip_width, clip_height; | |
723 | |
724 /* The pixmap_offset is used to center the pixmap on lines which are | |
725 shorter than it is. This results in odd effects when scrolling | |
726 pixmaps off of the bottom. Let's try not using it. */ | |
727 #if 0 | |
728 int pixmap_offset = (int) (IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - lheight) / 2; | |
729 #else | |
730 int pixmap_offset = 0; | |
731 #endif | |
732 | |
733 XSETWINDOW (window, w); | 710 XSETWINDOW (window, w); |
734 | |
735 if ((start_pixpos >= 0 && start_pixpos > xpos) || xoffset) | |
736 { | |
737 if (start_pixpos > xpos && start_pixpos > xpos + width) | |
738 return; | |
739 | |
740 clip_x = xoffset; | |
741 clip_width = width; | |
742 if (start_pixpos > xpos) | |
743 { | |
744 clip_x += (start_pixpos - xpos); | |
745 clip_width -= (start_pixpos - xpos); | |
746 } | |
747 } | |
748 else | |
749 { | |
750 clip_x = 0; | |
751 clip_width = 0; | |
752 } | |
753 | |
754 /* Place markers for possible future functionality (clipping the top | |
755 half instead of the bottom half; think pixel scrolling). */ | |
756 clip_y = 0; | |
757 clip_height = pheight; | |
758 | |
759 /* Clear the area the pixmap is going into. The pixmap itself will | |
760 always take care of the full width. We don't want to clear where | |
761 it is going to go in order to avoid flicker. So, all we have to | |
762 take care of is any area above or below the pixmap. */ | |
763 /* #### We take a shortcut for now. We know that since we have | |
764 pixmap_offset hardwired to 0 that the pixmap is against the top | |
765 edge so all we have to worry about is below it. */ | |
766 /* #### Unless the pixmap has a mask in which case we have to clear | |
767 the whole damn thing since we can't yet clear just the area not | |
768 included in the mask. */ | |
769 if (((int) (dl->ypos - dl->ascent + pheight) < | |
770 (int) (dl->ypos + dl->descent - dl->clip)) | |
771 || IMAGE_INSTANCE_MSWINDOWS_MASK (p)) | |
772 { | |
773 int clear_x, clear_y, clear_width, clear_height; | |
774 | |
775 if (IMAGE_INSTANCE_MSWINDOWS_MASK (p)) | |
776 { | |
777 clear_y = dl->ypos - dl->ascent; | |
778 clear_height = lheight; | |
779 } | |
780 else | |
781 { | |
782 clear_y = dl->ypos - dl->ascent + pheight; | |
783 clear_height = lheight - pheight; | |
784 } | |
785 | |
786 if (start_pixpos >= 0 && start_pixpos > xpos) | |
787 { | |
788 clear_x = start_pixpos; | |
789 clear_width = xpos + width - start_pixpos; | |
790 } | |
791 else | |
792 { | |
793 clear_x = xpos; | |
794 clear_width = width; | |
795 } | |
796 | |
797 if (!offset_bitmap) /* i.e. not a bg pixmap */ | |
798 redisplay_clear_region (window, findex, clear_x, clear_y, | |
799 clear_width, clear_height); | |
800 } | |
801 | 711 |
802 /* Output the pixmap. Have to do this as many times as is required | 712 /* Output the pixmap. Have to do this as many times as is required |
803 to fill the given area */ | 713 to fill the given area */ |
804 mswindows_update_dc (hdc, Qnil, | 714 mswindows_update_dc (hdc, Qnil, |
805 WINDOW_FACE_CACHEL_FOREGROUND (w, findex), | 715 WINDOW_FACE_CACHEL_FOREGROUND (w, findex), |
806 WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); | 716 WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil); |
807 | 717 |
808 mswindows_output_dibitmap_region (f, p, xpos - xoffset, | 718 if (bg_pixmap) |
809 dl->ypos - dl->ascent, | 719 mswindows_output_dibitmap_region (f, p, db, dga); |
810 clip_x, clip_y, clip_width, clip_height, | 720 else |
811 width + xoffset, pheight, pixmap_offset, | 721 mswindows_output_dibitmap (f, p, db, dga); |
812 offset_bitmap); | |
813 } | 722 } |
814 | 723 |
815 #ifdef HAVE_SCROLLBARS | 724 #ifdef HAVE_SCROLLBARS |
816 /* | 725 /* |
817 * This function paints window's deadbox, a rectangle between window | 726 * This function paints window's deadbox, a rectangle between window |
899 } | 808 } |
900 | 809 |
901 for (line = 0; line < Dynarr_length (cdla); line++) | 810 for (line = 0; line < Dynarr_length (cdla); line++) |
902 { | 811 { |
903 struct display_line *cdl = Dynarr_atp (cdla, line); | 812 struct display_line *cdl = Dynarr_atp (cdla, line); |
904 int top_y = cdl->ypos - cdl->ascent; | 813 |
905 int bottom_y = cdl->ypos + cdl->descent; | 814 if (DISPLAY_LINE_YPOS (cdl) + DISPLAY_LINE_HEIGHT (cdl) |
906 | 815 >= rect_draw.top) |
907 if (bottom_y >= rect_draw.top) | |
908 { | 816 { |
909 if (top_y > rect_draw.bottom) | 817 if (DISPLAY_LINE_YPOS (cdl) > rect_draw.bottom) |
910 { | 818 { |
911 if (line == 0) | 819 if (line == 0) |
912 continue; | 820 continue; |
913 else | 821 else |
914 break; | 822 break; |
984 | 892 |
985 Draw a 3d border around the specified area on window W. | 893 Draw a 3d border around the specified area on window W. |
986 ****************************************************************************/ | 894 ****************************************************************************/ |
987 static void | 895 static void |
988 mswindows_bevel_area (struct window *w, face_index findex, int x, int y, | 896 mswindows_bevel_area (struct window *w, face_index findex, int x, int y, |
989 int width, int height, int shadow_thickness) | 897 int width, int height, int thickness, |
898 int edges, enum edge_style style) | |
990 { | 899 { |
991 struct frame *f = XFRAME (w->frame); | 900 struct frame *f = XFRAME (w->frame); |
992 UINT edge; | 901 UINT edge; |
993 | 902 UINT border = 0; |
994 if (shadow_thickness < -1) | 903 |
995 edge = EDGE_SUNKEN; | 904 if (style == EDGE_ETCHED_IN) |
996 else if (shadow_thickness < 0) | 905 edge = EDGE_ETCHED; |
997 edge = BDR_SUNKENINNER; | 906 else if (style == EDGE_ETCHED_OUT) |
998 else if (shadow_thickness == 1) | 907 edge = EDGE_BUMP; |
999 edge = BDR_RAISEDINNER; | 908 else if (style == EDGE_BEVEL_IN) |
1000 else | 909 { |
1001 edge = EDGE_RAISED; | 910 if (thickness == 1) |
1002 | 911 edge = BDR_SUNKENINNER; |
1003 if (shadow_thickness < 0) | 912 else |
1004 shadow_thickness = -shadow_thickness; | 913 edge = EDGE_SUNKEN; |
914 } | |
915 else /* EDGE_BEVEL_OUT */ | |
916 { | |
917 if (thickness == 1) | |
918 edge = BDR_RAISEDINNER; | |
919 else | |
920 edge = EDGE_RAISED; | |
921 } | |
922 | |
923 if (edges & EDGE_TOP) | |
924 border |= BF_TOP; | |
925 if (edges & EDGE_LEFT) | |
926 border |= BF_LEFT; | |
927 if (edges & EDGE_BOTTOM) | |
928 border |= BF_BOTTOM; | |
929 if (edges & EDGE_RIGHT) | |
930 border |= BF_RIGHT; | |
1005 | 931 |
1006 { | 932 { |
1007 RECT rect = { x, y, x + width, y + height }; | 933 RECT rect = { x, y, x + width, y + height }; |
1008 Lisp_Object color = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); | 934 Lisp_Object color = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); |
1009 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, color, Qnil); | 935 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, color, Qnil); |
1010 | 936 |
1011 DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, edge, BF_RECT); | 937 DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, edge, border); |
1012 } | 938 } |
1013 } | 939 } |
1014 | 940 |
1015 | 941 |
1016 /***************************************************************************** | 942 /***************************************************************************** |
1139 else | 1065 else |
1140 { | 1066 { |
1141 if (Dynarr_length (buf)) | 1067 if (Dynarr_length (buf)) |
1142 { | 1068 { |
1143 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, | 1069 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, |
1144 findex); | 1070 findex, 0, 0, 0, 0); |
1145 xpos = rb->xpos; | 1071 xpos = rb->xpos; |
1146 width = 0; | 1072 width = 0; |
1147 } | 1073 } |
1148 Dynarr_reset (buf); | 1074 Dynarr_reset (buf); |
1149 width = 0; | 1075 width = 0; |
1173 elt++; | 1099 elt++; |
1174 } | 1100 } |
1175 else if (rb->object.chr.ch == '\n') | 1101 else if (rb->object.chr.ch == '\n') |
1176 { | 1102 { |
1177 /* Clear in case a cursor was formerly here. */ | 1103 /* Clear in case a cursor was formerly here. */ |
1178 int height = DISPLAY_LINE_HEIGHT (dl); | 1104 redisplay_clear_region (window, findex, xpos, |
1179 | 1105 DISPLAY_LINE_YPOS (dl), |
1180 redisplay_clear_region (window, findex, xpos, dl->ypos - dl->ascent, | 1106 rb->width, DISPLAY_LINE_HEIGHT (dl)); |
1181 rb->width, height); | |
1182 elt++; | 1107 elt++; |
1183 } | 1108 } |
1184 } | 1109 } |
1185 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) | 1110 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) |
1186 { | 1111 { |
1212 } | 1137 } |
1213 } | 1138 } |
1214 else if (rb->type == RUNE_DGLYPH) | 1139 else if (rb->type == RUNE_DGLYPH) |
1215 { | 1140 { |
1216 Lisp_Object instance; | 1141 Lisp_Object instance; |
1142 struct display_box db; | |
1143 struct display_glyph_area dga; | |
1144 redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset, | |
1145 start_pixpos, rb->width, | |
1146 &db, &dga); | |
1217 | 1147 |
1218 XSETWINDOW (window, w); | 1148 XSETWINDOW (window, w); |
1219 instance = glyph_image_instance (rb->object.dglyph.glyph, | 1149 instance = glyph_image_instance (rb->object.dglyph.glyph, |
1220 window, ERROR_ME_NOT, 1); | 1150 window, ERROR_ME_NOT, 1); |
1221 findex = rb->findex; | 1151 findex = rb->findex; |
1236 mswindows_output_cursor (w, dl, xpos, cursor_width, | 1166 mswindows_output_cursor (w, dl, xpos, cursor_width, |
1237 findex, Dynarr_at (buf, 0), 0); | 1167 findex, Dynarr_at (buf, 0), 0); |
1238 else /* #### redisplay-x passes -1 as the width: why ? */ | 1168 else /* #### redisplay-x passes -1 as the width: why ? */ |
1239 mswindows_output_string (w, dl, buf, xpos, | 1169 mswindows_output_string (w, dl, buf, xpos, |
1240 rb->object.dglyph.xoffset, | 1170 rb->object.dglyph.xoffset, |
1241 start_pixpos, rb->width, findex); | 1171 start_pixpos, rb->width, findex, |
1172 0, 0, 0, 0); | |
1242 Dynarr_reset (buf); | 1173 Dynarr_reset (buf); |
1243 } | 1174 } |
1244 break; | 1175 break; |
1245 | 1176 |
1246 case IMAGE_MONO_PIXMAP: | 1177 case IMAGE_MONO_PIXMAP: |
1247 case IMAGE_COLOR_PIXMAP: | 1178 case IMAGE_COLOR_PIXMAP: |
1248 mswindows_output_pixmap (w, dl, instance, xpos, | 1179 redisplay_output_pixmap (w, instance, &db, &dga, findex, |
1249 rb->object.dglyph.xoffset, start_pixpos, | 1180 cursor_start, cursor_width, |
1250 rb->width, findex, cursor_start, | 1181 cursor_height, 0); |
1251 cursor_width, cursor_height, 0); | |
1252 if (rb->cursor_type == CURSOR_ON) | 1182 if (rb->cursor_type == CURSOR_ON) |
1253 mswindows_output_cursor (w, dl, xpos, cursor_width, | 1183 mswindows_output_cursor (w, dl, xpos, cursor_width, |
1254 findex, 0, 1); | 1184 findex, 0, 1); |
1255 break; | 1185 break; |
1256 | 1186 |
1257 case IMAGE_POINTER: | 1187 case IMAGE_POINTER: |
1258 abort (); | 1188 abort (); |
1259 | 1189 |
1260 case IMAGE_SUBWINDOW: | 1190 case IMAGE_SUBWINDOW: |
1261 case IMAGE_WIDGET: | 1191 case IMAGE_WIDGET: |
1262 redisplay_output_subwindow (w, dl, instance, xpos, | 1192 redisplay_output_subwindow (w, instance, &db, &dga, findex, |
1263 rb->object.dglyph.xoffset, start_pixpos, | 1193 cursor_start, cursor_width, |
1264 rb->width, findex, cursor_start, | 1194 cursor_height); |
1265 cursor_width, cursor_height); | 1195 if (rb->cursor_type == CURSOR_ON) |
1196 mswindows_output_cursor (w, dl, xpos, cursor_width, | |
1197 findex, 0, 1); | |
1198 break; | |
1199 | |
1200 case IMAGE_LAYOUT: | |
1201 redisplay_output_layout (w, instance, &db, &dga, findex, | |
1202 cursor_start, cursor_width, | |
1203 cursor_height); | |
1266 if (rb->cursor_type == CURSOR_ON) | 1204 if (rb->cursor_type == CURSOR_ON) |
1267 mswindows_output_cursor (w, dl, xpos, cursor_width, | 1205 mswindows_output_cursor (w, dl, xpos, cursor_width, |
1268 findex, 0, 1); | 1206 findex, 0, 1); |
1269 break; | 1207 break; |
1270 | 1208 |
1283 abort (); | 1221 abort (); |
1284 } | 1222 } |
1285 } | 1223 } |
1286 | 1224 |
1287 if (Dynarr_length (buf)) | 1225 if (Dynarr_length (buf)) |
1288 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex); | 1226 mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex, |
1227 0, 0, 0, 0); | |
1289 | 1228 |
1290 if (dl->modeline | 1229 if (dl->modeline |
1291 && !EQ (Qzero, w->modeline_shadow_thickness) | 1230 && !EQ (Qzero, w->modeline_shadow_thickness) |
1292 && (f->clear | 1231 && (f->clear |
1293 || f->windows_structure_changed | 1232 || f->windows_structure_changed |
1398 { | 1337 { |
1399 RECT rect = { x, y, x+width, y+height }; | 1338 RECT rect = { x, y, x+width, y+height }; |
1400 | 1339 |
1401 if (!NILP (background_pixmap)) | 1340 if (!NILP (background_pixmap)) |
1402 { | 1341 { |
1342 struct display_box db = { x, y, width, height }; | |
1403 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), | 1343 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), |
1404 Qnil, fcolor, bcolor, background_pixmap); | 1344 Qnil, fcolor, bcolor, background_pixmap); |
1405 | |
1406 mswindows_output_dibitmap_region | 1345 mswindows_output_dibitmap_region |
1407 ( f, XIMAGE_INSTANCE (background_pixmap), | 1346 ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0); |
1408 x, y, 0, 0, 0, 0, width, height, 0, TRUE); | |
1409 } | 1347 } |
1410 else | 1348 else |
1411 { | 1349 { |
1412 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, fcolor, Qnil); | 1350 mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, fcolor, Qnil); |
1413 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, | 1351 ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, |
1447 CONSOLE_HAS_METHOD (mswindows, output_begin); | 1385 CONSOLE_HAS_METHOD (mswindows, output_begin); |
1448 CONSOLE_HAS_METHOD (mswindows, output_end); | 1386 CONSOLE_HAS_METHOD (mswindows, output_end); |
1449 CONSOLE_HAS_METHOD (mswindows, flash); | 1387 CONSOLE_HAS_METHOD (mswindows, flash); |
1450 CONSOLE_HAS_METHOD (mswindows, ring_bell); | 1388 CONSOLE_HAS_METHOD (mswindows, ring_bell); |
1451 CONSOLE_HAS_METHOD (mswindows, bevel_area); | 1389 CONSOLE_HAS_METHOD (mswindows, bevel_area); |
1452 } | 1390 CONSOLE_HAS_METHOD (mswindows, output_string); |
1391 CONSOLE_HAS_METHOD (mswindows, output_pixmap); | |
1392 } |