comparison src/redisplay-output.c @ 4187:26dccfc8fa60

[xemacs-hg @ 2007-09-26 13:27:59 by didierv] More fixes about face indexes
author didierv
date Wed, 26 Sep 2007 13:28:01 +0000
parents 2b84dd8eb906
children 62d532188a28
comparison
equal deleted inserted replaced
4186:05dd0ed58262 4187:26dccfc8fa60
77 : Dynarr_length (dra)); 77 : Dynarr_length (dra));
78 78
79 if (max_move) 79 if (max_move)
80 { 80 {
81 /* #### Doing this directly breaks the encapsulation. But, the 81 /* #### Doing this directly breaks the encapsulation. But, the
82 running time of this function has a measurable impact on 82 running time of this function has a measurable impact on
83 redisplay performance so avoiding all excess overhead is a 83 redisplay performance so avoiding all excess overhead is a
84 good thing. Is all of this true? */ 84 good thing. Is all of this true? */
85 memcpy (cra->base, dra->base, sizeof (struct rune) * max_move); 85 memcpy (cra->base, dra->base, sizeof (struct rune) * max_move);
86 Dynarr_set_size (cra, max_move); 86 Dynarr_set_size (cra, max_move);
87 } 87 }
88 else 88 else
89 Dynarr_reset (cra); 89 Dynarr_reset (cra);
235 else if (crb->type == RUNE_DGLYPH && 235 else if (crb->type == RUNE_DGLYPH &&
236 (!EQ (crb->object.dglyph.glyph, drb->object.dglyph.glyph) || 236 (!EQ (crb->object.dglyph.glyph, drb->object.dglyph.glyph) ||
237 !EQ (crb->object.dglyph.extent, drb->object.dglyph.extent) || 237 !EQ (crb->object.dglyph.extent, drb->object.dglyph.extent) ||
238 crb->object.dglyph.xoffset != drb->object.dglyph.xoffset || 238 crb->object.dglyph.xoffset != drb->object.dglyph.xoffset ||
239 crb->object.dglyph.yoffset != drb->object.dglyph.yoffset || 239 crb->object.dglyph.yoffset != drb->object.dglyph.yoffset ||
240 crb->object.dglyph.ascent != drb->object.dglyph.ascent || 240 crb->object.dglyph.ascent != drb->object.dglyph.ascent ||
241 crb->object.dglyph.descent != drb->object.dglyph.descent)) 241 crb->object.dglyph.descent != drb->object.dglyph.descent))
242 return 0; 242 return 0;
243 /* Only check dirtiness if we know something has changed. */ 243 /* Only check dirtiness if we know something has changed. */
244 else if (crb->type == RUNE_DGLYPH && 244 else if (crb->type == RUNE_DGLYPH &&
245 (XGLYPH_DIRTYP (crb->object.dglyph.glyph) || 245 (XGLYPH_DIRTYP (crb->object.dglyph.glyph) ||
246 crb->findex != drb->findex)) 246 crb->findex != drb->findex))
247 { 247 {
248 /* We need some way of telling redisplay_output_layout () that the 248 /* We need some way of telling redisplay_output_layout () that the
249 only reason we are outputting it is because something has 249 only reason we are outputting it is because something has
250 changed internally. That way we can optimize whether we need 250 changed internally. That way we can optimize whether we need
251 to clear the layout first and also only output the components 251 to clear the layout first and also only output the components
252 that have changed. The image_instance dirty flag and 252 that have changed. The image_instance dirty flag and
253 display_hash are no good to us because these will invariably 253 display_hash are no good to us because these will invariably
254 have been set anyway if the layout has changed. So it looks 254 have been set anyway if the layout has changed. So it looks
255 like we need yet another change flag that we can set here and 255 like we need yet another change flag that we can set here and
256 then clear in redisplay_output_layout (). */ 256 then clear in redisplay_output_layout (). */
257 Lisp_Object window, image; 257 Lisp_Object window, image;
258 Lisp_Image_Instance* ii; 258 Lisp_Image_Instance* ii;
259 window = wrap_window (w); 259 window = wrap_window (w);
260 image = glyph_image_instance (crb->object.dglyph.glyph, 260 image = glyph_image_instance (crb->object.dglyph.glyph,
261 window, ERROR_ME_DEBUG_WARN, 1); 261 window, ERROR_ME_DEBUG_WARN, 1);
338 Lisp_Image_Instance* ii; 338 Lisp_Image_Instance* ii;
339 window = wrap_window (w); 339 window = wrap_window (w);
340 image = glyph_image_instance (crb->object.dglyph.glyph, 340 image = glyph_image_instance (crb->object.dglyph.glyph,
341 window, crb->object.dglyph.matchspec, 341 window, crb->object.dglyph.matchspec,
342 ERROR_ME_DEBUG_WARN, 1); 342 ERROR_ME_DEBUG_WARN, 1);
343 343
344 if (!IMAGE_INSTANCEP (image)) 344 if (!IMAGE_INSTANCEP (image))
345 return 0; 345 return 0;
346 ii = XIMAGE_INSTANCE (image); 346 ii = XIMAGE_INSTANCE (image);
347 347
348 if (TEXT_IMAGE_INSTANCEP (image) && 348 if (TEXT_IMAGE_INSTANCEP (image) &&
349 (crb->findex != drb->findex || 349 (crb->findex != drb->findex ||
350 WINDOW_FACE_CACHEL_DIRTY (w, drb->findex))) 350 WINDOW_FACE_CACHEL_DIRTY (w, drb->findex)))
351 return 0; 351 return 0;
352 352
353 /* It is quite common for the two glyphs to be EQ since in many 353 /* It is quite common for the two glyphs to be EQ since in many
354 cases they will actually be the same object. This does not 354 cases they will actually be the same object. This does not
355 mean, however, that nothing has changed. We therefore need to 355 mean, however, that nothing has changed. We therefore need to
356 check the current hash of the glyph against the last recorded 356 check the current hash of the glyph against the last recorded
357 display hash and the pending display items. See 357 display hash and the pending display items. See
364 this is for some internal reason not related to geometry 364 this is for some internal reason not related to geometry
365 changes, send a hint to the output routines that they can 365 changes, send a hint to the output routines that they can
366 take some short cuts. This is most useful for 366 take some short cuts. This is most useful for
367 layouts. This flag should get reset by the output 367 layouts. This flag should get reset by the output
368 routines. 368 routines.
369 369
370 #### It is possible for us to get here when the 370 #### It is possible for us to get here when the
371 face_cachel is dirty. I do not know what the implications 371 face_cachel is dirty. I do not know what the implications
372 of this are.*/ 372 of this are.*/
373 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (ii) = 1; 373 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (ii) = 1;
374 return 0; 374 return 0;
538 ) 538 )
539 force = 1; 539 force = 1;
540 540
541 if (f->windows_structure_changed || 541 if (f->windows_structure_changed ||
542 /* #### Why is this so? We have face cachels so that we don't 542 /* #### Why is this so? We have face cachels so that we don't
543 have to recalculate all the display blocks when faces 543 have to recalculate all the display blocks when faces
544 change. I have fixed this for glyphs and am inclined to think 544 change. I have fixed this for glyphs and am inclined to think
545 that faces should "Just Work", but I'm not feeling brave 545 that faces should "Just Work", but I'm not feeling brave
546 today. Maybe its because the face cachels represent merged 546 today. Maybe its because the face cachels represent merged
547 faces rather than simply instantiations in a particular 547 faces rather than simply instantiations in a particular
548 domain. */ 548 domain. */
549 f->faces_changed || 549 f->faces_changed ||
550 cdl->ypos != ddl->ypos || 550 cdl->ypos != ddl->ypos ||
551 cdl->ascent != ddl->ascent || 551 cdl->ascent != ddl->ascent ||
552 cdl->descent != ddl->descent || 552 cdl->descent != ddl->descent ||
553 cdl->clip != ddl->clip || 553 cdl->clip != ddl->clip ||
704 if (ddl->cursor_elt != -1) 704 if (ddl->cursor_elt != -1)
705 { 705 {
706 struct display_block *db; 706 struct display_block *db;
707 707
708 /* If the lines cursor parameter is not -1 then it indicates 708 /* If the lines cursor parameter is not -1 then it indicates
709 which rune in the TEXT block contains the cursor. This means 709 which rune in the TEXT block contains the cursor. This means
710 that there must be at least one display block. The TEXT 710 that there must be at least one display block. The TEXT
711 block, if present, must always be the first display block. */ 711 block, if present, must always be the first display block. */
712 assert (Dynarr_length (ddba) != 0); 712 assert (Dynarr_length (ddba) != 0);
713 713
714 db = Dynarr_atp (ddba, 0); 714 db = Dynarr_atp (ddba, 0);
715 assert (db->type == TEXT); 715 assert (db->type == TEXT);
716 716
725 /* The modeline should only have a single block and it had better be 725 /* The modeline should only have a single block and it had better be
726 a TEXT block. */ 726 a TEXT block. */
727 if (ddl->modeline) 727 if (ddl->modeline)
728 { 728 {
729 /* The shadow thickness check is necessary if only the sign of 729 /* The shadow thickness check is necessary if only the sign of
730 the size changed. */ 730 the size changed. */
731 if (cdba && !w->shadow_thickness_changed) 731 if (cdba && !w->shadow_thickness_changed)
732 { 732 {
733 must_sync |= compare_display_blocks (w, cdl, ddl, 0, 0, 733 must_sync |= compare_display_blocks (w, cdl, ddl, 0, 0,
734 start_pixpos, 0, 0, 0); 734 start_pixpos, 0, 0, 0);
735 } 735 }
751 751
752 block = get_next_display_block (ddl->bounds, ddba, start_pixpos, 752 block = get_next_display_block (ddl->bounds, ddba, start_pixpos,
753 &next_start_pixpos); 753 &next_start_pixpos);
754 754
755 /* If we didn't find a block then we should blank the area 755 /* If we didn't find a block then we should blank the area
756 between start_pos and next_start if necessary. */ 756 between start_pos and next_start if necessary. */
757 if (block == NO_BLOCK) 757 if (block == NO_BLOCK)
758 { 758 {
759 /* We only erase those areas which were actually previously 759 /* We only erase those areas which were actually previously
760 covered by a display block unless the window structure 760 covered by a display block unless the window structure
761 changed. In that case we clear all areas since the current 761 changed. In that case we clear all areas since the current
762 structures may actually represent a different buffer. */ 762 structures may actually represent a different buffer. */
763 while (start_pixpos < next_start_pixpos) 763 while (start_pixpos < next_start_pixpos)
764 { 764 {
765 int block_end; 765 int block_end;
766 int old_block; 766 int old_block;
767 767
793 width = min (next_start_pixpos, block_end) - x; 793 width = min (next_start_pixpos, block_end) - x;
794 height = DISPLAY_LINE_HEIGHT (ddl); 794 height = DISPLAY_LINE_HEIGHT (ddl);
795 795
796 if (x < ddl->bounds.left_in) 796 if (x < ddl->bounds.left_in)
797 { 797 {
798 findex = ddl->left_margin_findex ? 798 findex = (ddl->left_margin_findex > DEFAULT_INDEX) ?
799 ddl->left_margin_findex 799 ddl->left_margin_findex
800 : get_builtin_face_cache_index (w, Vleft_margin_face); 800 : get_builtin_face_cache_index (w, Vleft_margin_face);
801 } 801 }
802 else if (x < ddl->bounds.right_in) 802 else if (x < ddl->bounds.right_in)
803 { 803 {
804 /* no check here because DEFAULT_INDEX == 0 anyway */ 804 findex = (ddl->default_findex >= DEFAULT_INDEX) ?
805 findex = ddl->default_findex; 805 ddl->default_findex
806 : DEFAULT_INDEX;
806 } 807 }
807 else if (x < ddl->bounds.right_out) 808 else if (x < ddl->bounds.right_out)
808 { 809 {
809 findex = ddl->right_margin_findex ? 810 findex = (ddl->right_margin_findex > DEFAULT_INDEX) ?
810 ddl->right_margin_findex 811 ddl->right_margin_findex
811 : get_builtin_face_cache_index (w, Vright_margin_face); 812 : get_builtin_face_cache_index (w, Vright_margin_face);
812 } 813 }
813 else 814 else
814 findex = (face_index) -1; 815 findex = (face_index) -1;
850 region or if it was a block of a different type, then 851 region or if it was a block of a different type, then
851 output the entire ddb. Otherwise, compare cdb and 852 output the entire ddb. Otherwise, compare cdb and
852 ddb and output only the changed region. */ 853 ddb and output only the changed region. */
853 if (!force && cdb && ddb->type == cdb->type 854 if (!force && cdb && ddb->type == cdb->type
854 /* If there was no buffer being display before the 855 /* If there was no buffer being display before the
855 compare anyway as we might be outputting a gutter. */ 856 compare anyway as we might be outputting a gutter. */
856 && 857 &&
857 (b == old_b || !old_b)) 858 (b == old_b || !old_b))
858 { 859 {
859 must_sync |= compare_display_blocks (w, cdl, ddl, old_block, 860 must_sync |= compare_display_blocks (w, cdl, ddl, old_block,
860 block, start_pixpos, 861 block, start_pixpos,
1450 int width = dga->width; 1451 int width = dga->width;
1451 1452
1452 /* The bevel_area routines always draw in from the specified 1453 /* The bevel_area routines always draw in from the specified
1453 area so there is no need to adjust the displayed area to 1454 area so there is no need to adjust the displayed area to
1454 make sure that the lines are visible. */ 1455 make sure that the lines are visible. */
1455 if (dga->xoffset >= 0) 1456 if (dga->xoffset >= 0)
1456 edges |= EDGE_LEFT; 1457 edges |= EDGE_LEFT;
1457 if (dga->width - dga->xoffset == layout_width) 1458 if (dga->width - dga->xoffset == layout_width)
1458 edges |= EDGE_RIGHT; 1459 edges |= EDGE_RIGHT;
1459 if (dga->yoffset >= 0) 1460 if (dga->yoffset >= 0)
1460 edges |= EDGE_TOP; 1461 edges |= EDGE_TOP;
1461 if (dga->height - dga->yoffset == layout_height) 1462 if (dga->height - dga->yoffset == layout_height)
1462 edges |= EDGE_BOTTOM; 1463 edges |= EDGE_BOTTOM;
1463 1464
1464 if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qetched_in)) 1465 if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qetched_in))
1465 style = EDGE_ETCHED_IN; 1466 style = EDGE_ETCHED_IN;
1466 else if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qetched_out)) 1467 else if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qetched_out))
1467 style = EDGE_ETCHED_OUT; 1468 style = EDGE_ETCHED_OUT;
1468 else if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qbevel_in)) 1469 else if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qbevel_in))
1648 dga->height = IMAGE_INSTANCE_PIXMAP_HEIGHT (p); 1649 dga->height = IMAGE_INSTANCE_PIXMAP_HEIGHT (p);
1649 dga->width = IMAGE_INSTANCE_PIXMAP_WIDTH (p); 1650 dga->width = IMAGE_INSTANCE_PIXMAP_WIDTH (p);
1650 1651
1651 #ifdef DEBUG_REDISPLAY 1652 #ifdef DEBUG_REDISPLAY
1652 printf ("redisplay_output_pixmap(request) \ 1653 printf ("redisplay_output_pixmap(request) \
1653 [%dx%d@%d+%d] in [%dx%d@%d+%d]\n", 1654 [%dx%d@%d+%d] in [%dx%d@%d+%d]\n",
1654 db->width, db->height, db->xpos, db->ypos, 1655 db->width, db->height, db->xpos, db->ypos,
1655 dga->width, dga->height, dga->xoffset, dga->yoffset); 1656 dga->width, dga->height, dga->xoffset, dga->yoffset);
1656 #endif 1657 #endif
1657 1658
1658 /* This makes the glyph area fit into the display area. */ 1659 /* This makes the glyph area fit into the display area. */
1830 else 1831 else
1831 { 1832 {
1832 int yoffset = (glyphsrc->yoffset > 0 ? glyphsrc->yoffset : 0); 1833 int yoffset = (glyphsrc->yoffset > 0 ? glyphsrc->yoffset : 0);
1833 1834
1834 /* We need to make sure that subwindows are unmapped from the 1835 /* We need to make sure that subwindows are unmapped from the
1835 whole area. */ 1836 whole area. */
1836 redisplay_unmap_subwindows_except_us (f, clear_x, dest->ypos, 1837 redisplay_unmap_subwindows_except_us (f, clear_x, dest->ypos,
1837 glyphsrc->width, dest->height, 1838 glyphsrc->width, dest->height,
1838 ignored_subwindow); 1839 ignored_subwindow);
1839 /* first the top box */ 1840 /* first the top box */
1840 if (yoffset > 0) 1841 if (yoffset > 0)
1867 1868
1868 dest - display_box 1869 dest - display_box
1869 1870
1870 xpos - absolute horizontal position of area. 1871 xpos - absolute horizontal position of area.
1871 1872
1872 ypos - absolute vertical position of area. 1873 ypos - absolute vertical position of area.
1873 1874
1874 glyphsrc - display_glyph_area 1875 glyphsrc - display_glyph_area
1875 1876
1876 xoffset - horizontal offset of the glyph, +ve means display 1877 xoffset - horizontal offset of the glyph, +ve means display
1877 the glyph with the x position offset by xoffset, -ve means 1878 the glyph with the x position offset by xoffset, -ve means
1924 if (glyphsrc->xoffset > 0) 1925 if (glyphsrc->xoffset > 0)
1925 glyphsrc->width = dest->width - glyphsrc->xoffset; 1926 glyphsrc->width = dest->width - glyphsrc->xoffset;
1926 /* glyphsrc offset is -ve we are trying to display hard up 1927 /* glyphsrc offset is -ve we are trying to display hard up
1927 against the dest corner inset into the glyphsrc by 1928 against the dest corner inset into the glyphsrc by
1928 xoffset.*/ 1929 xoffset.*/
1929 else if (glyphsrc->xoffset < 0) 1930 else if (glyphsrc->xoffset < 0)
1930 { 1931 {
1931 glyphsrc->width += glyphsrc->xoffset; 1932 glyphsrc->width += glyphsrc->xoffset;
1932 glyphsrc->width = min (glyphsrc->width, dest->width); 1933 glyphsrc->width = min (glyphsrc->width, dest->width);
1933 } 1934 }
1934 else 1935 else
1935 glyphsrc->width = dest->width; 1936 glyphsrc->width = dest->width;
1936 } 1937 }
1937 1938
1938 else if (glyphsrc->xoffset < 0) 1939 else if (glyphsrc->xoffset < 0)
1939 glyphsrc->width += glyphsrc->xoffset; 1940 glyphsrc->width += glyphsrc->xoffset;
1940 1941
1941 /* Vertical offsets. This works because yoffset can be -ve as well as +ve */ 1942 /* Vertical offsets. This works because yoffset can be -ve as well as +ve */
1942 if (dest->ypos + glyphsrc->yoffset + glyphsrc->height > dest->ypos + dest->height) 1943 if (dest->ypos + glyphsrc->yoffset + glyphsrc->height > dest->ypos + dest->height)
1943 { 1944 {
1944 if ((glyphsrc->yoffset > 0) && (dest->height > glyphsrc->yoffset)) 1945 if ((glyphsrc->yoffset > 0) && (dest->height > glyphsrc->yoffset))
1945 glyphsrc->height = dest->height - glyphsrc->yoffset; 1946 glyphsrc->height = dest->height - glyphsrc->yoffset;
1946 else if (glyphsrc->yoffset < 0) 1947 else if (glyphsrc->yoffset < 0)
1947 { 1948 {
1948 glyphsrc->height += glyphsrc->yoffset; 1949 glyphsrc->height += glyphsrc->yoffset;
1949 glyphsrc->height = min (glyphsrc->height, dest->height); 1950 glyphsrc->height = min (glyphsrc->height, dest->height);
1950 } 1951 }
1951 else 1952 else
2036 co-ordinates. 2037 co-ordinates.
2037 ****************************************************************************/ 2038 ****************************************************************************/
2038 int 2039 int
2039 redisplay_calculate_display_boxes (struct display_line *dl, int xpos, 2040 redisplay_calculate_display_boxes (struct display_line *dl, int xpos,
2040 int xoffset, int yoffset, int start_pixpos, 2041 int xoffset, int yoffset, int start_pixpos,
2041 int width, struct display_box* dest, 2042 int width, struct display_box* dest,
2042 struct display_glyph_area* src) 2043 struct display_glyph_area* src)
2043 { 2044 {
2044 dest->xpos = xpos; 2045 dest->xpos = xpos;
2045 dest->ypos = DISPLAY_LINE_YPOS (dl); 2046 dest->ypos = DISPLAY_LINE_YPOS (dl);
2046 dest->width = width; 2047 dest->width = width;
2053 src->yoffset = -dl->top_clip + yoffset; 2054 src->yoffset = -dl->top_clip + yoffset;
2054 2055
2055 if (start_pixpos >=0 && start_pixpos > xpos) 2056 if (start_pixpos >=0 && start_pixpos > xpos)
2056 { 2057 {
2057 /* Oops, we're asking for a start outside of the displayable 2058 /* Oops, we're asking for a start outside of the displayable
2058 area. */ 2059 area. */
2059 if (start_pixpos > xpos + width) 2060 if (start_pixpos > xpos + width)
2060 return 0; 2061 return 0;
2061 dest->xpos = start_pixpos; 2062 dest->xpos = start_pixpos;
2062 dest->width -= (start_pixpos - xpos); 2063 dest->width -= (start_pixpos - xpos);
2063 /* Offsets are -ve when we want to clip pixels off the displayed 2064 /* Offsets are -ve when we want to clip pixels off the displayed
2064 glyph. */ 2065 glyph. */
2065 src->xoffset -= (start_pixpos - xpos); 2066 src->xoffset -= (start_pixpos - xpos);
2066 } 2067 }
2067 2068
2068 return 1; 2069 return 1;
2069 } 2070 }
2541 end_x = min (WINDOW_RIGHT (w), (x + width)); 2542 end_x = min (WINDOW_RIGHT (w), (x + width));
2542 start_y = max (WINDOW_TOP (w), y); 2543 start_y = max (WINDOW_TOP (w), y);
2543 end_y = min (WINDOW_BOTTOM (w), y + height); 2544 end_y = min (WINDOW_BOTTOM (w), y + height);
2544 2545
2545 /* We do this to make sure that the 3D modelines get redrawn if 2546 /* We do this to make sure that the 3D modelines get redrawn if
2546 they are in the exposed region. */ 2547 they are in the exposed region. */
2547 orig_windows_structure_changed = f->windows_structure_changed; 2548 orig_windows_structure_changed = f->windows_structure_changed;
2548 f->windows_structure_changed = 1; 2549 f->windows_structure_changed = 1;
2549 } 2550 }
2550 2551
2551 /* #### Not in GTK or MS Windows. I think is because of toolbars, which 2552 /* #### Not in GTK or MS Windows. I think is because of toolbars, which