comparison src/redisplay-output.c @ 442:abe6d1db359e r21-2-36

Import from CVS: tag r21-2-36
author cvs
date Mon, 13 Aug 2007 11:35:02 +0200
parents 8de8e3f6228a
children 1ccc32a20af4
comparison
equal deleted inserted replaced
441:72a7cfa4a488 442:abe6d1db359e
99 sync_display_line_structs 99 sync_display_line_structs
100 100
101 For the given LINE in window W, make the current display line equal 101 For the given LINE in window W, make the current display line equal
102 the desired display line. 102 the desired display line.
103 ****************************************************************************/ 103 ****************************************************************************/
104 static void 104 void
105 sync_display_line_structs (struct window *w, int line, int do_blocks, 105 sync_display_line_structs (struct window *w, int line, int do_blocks,
106 display_line_dynarr *cdla, 106 display_line_dynarr *cdla,
107 display_line_dynarr *ddla) 107 display_line_dynarr *ddla)
108 { 108 {
109 int cdla_len = Dynarr_length (cdla); 109 int cdla_len = Dynarr_length (cdla);
209 So I (JV) conjecture 209 So I (JV) conjecture
210 210
211 #### It would really be worth it to arrange for this function to 211 #### It would really be worth it to arrange for this function to
212 be (almost) a single call to memcmp. */ 212 be (almost) a single call to memcmp. */
213 213
214 if ((crb->findex != drb->findex) || 214 if (crb->xpos != drb->xpos)
215 (WINDOW_FACE_CACHEL_DIRTY (w, drb->findex)))
216 return 0;
217 else if (crb->xpos != drb->xpos)
218 return 0; 215 return 0;
219 else if (crb->width != drb->width) 216 else if (crb->width != drb->width)
220 return 0; 217 return 0;
221 else if (crb->cursor_type != drb->cursor_type) 218 else if (crb->cursor_type != drb->cursor_type)
222 return 0; 219 return 0;
234 !EQ (crb->object.dglyph.extent, drb->object.dglyph.extent) || 231 !EQ (crb->object.dglyph.extent, drb->object.dglyph.extent) ||
235 crb->object.dglyph.xoffset != drb->object.dglyph.xoffset)) 232 crb->object.dglyph.xoffset != drb->object.dglyph.xoffset))
236 return 0; 233 return 0;
237 /* Only check dirtiness if we know something has changed. */ 234 /* Only check dirtiness if we know something has changed. */
238 else if (crb->type == RUNE_DGLYPH && 235 else if (crb->type == RUNE_DGLYPH &&
239 XFRAME (w->frame)->glyphs_changed) 236 (XGLYPH_DIRTYP (crb->object.dglyph.glyph) ||
240 { 237 crb->findex != drb->findex))
241 glyph_index gindex = get_glyph_cachel_index (w, drb->object.dglyph.glyph); 238 {
242 /* Although doing the cachel lookup for every comparison is 239 /* We need some way of telling redisplay_output_layout () that the
243 very expensive.we have to do it to make sure the cache is 240 only reason we are outputting it is because something has
244 up-to-date. */ 241 changed internally. That way we can optimize whether we need
245 if (GLYPH_CACHEL_DIRTYP (w, gindex)) 242 to clear the layout first and also only output the components
243 that have changed. The image_instance dirty flag and
244 display_hash are no good to us because these will invariably
245 have been set anyway if the layout has changed. So it looks
246 like we need yet another change flag that we can set here and
247 then clear in redisplay_output_layout (). */
248 Lisp_Object window, image;
249 Lisp_Image_Instance* ii;
250 XSETWINDOW (window, w);
251 image = glyph_image_instance (crb->object.dglyph.glyph,
252 window, ERROR_ME_NOT, 1);
253
254 if (!IMAGE_INSTANCEP (image))
246 return 0; 255 return 0;
256 ii = XIMAGE_INSTANCE (image);
257
258 if (TEXT_IMAGE_INSTANCEP (image) &&
259 (crb->findex != drb->findex ||
260 WINDOW_FACE_CACHEL_DIRTY (w, drb->findex)))
261 return 0;
262
263 /* It is quite common for the two glyphs to be EQ since in many
264 cases they will actually be the same object. This does not
265 mean, however, that nothing has changed. We therefore need to
266 check the current hash of the glyph against the last recorded
267 display hash and the pending display items. See
268 update_subwindow (). */
269 if (image_instance_changed (image) ||
270 crb->findex != drb->findex ||
271 WINDOW_FACE_CACHEL_DIRTY (w, drb->findex))
272 {
273 /* We now now we are going to re-output the glyph, but since
274 this is for some internal reason not related to geometry
275 changes, send a hint to the output routines that they can
276 take some short cuts. This is most useful for
277 layouts. This flag should get reset by the output
278 routines.
279
280 #### It is possible for us to get here when the
281 face_cachel is dirty. I do not know what the implications
282 of this are.*/
283 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (ii) = 1;
284 return 0;
285 }
247 else 286 else
248 return 1; 287 return 1;
249 } 288 }
289 /* We now do this last so that glyph checks can do their own thing
290 for face changes. Face changes quite often happen when we are
291 trying to output something in the gutter, this would normally
292 lead to a lot of flashing. The indices can quite often be
293 different and yet the faces are the same, we do not want to
294 re-output in this instance. */
295 else if (crb->findex != drb->findex ||
296 WINDOW_FACE_CACHEL_DIRTY (w, drb->findex))
297 return 0;
250 else 298 else
251 return 1; 299 return 1;
252 } 300 }
253 301
254 /***************************************************************************** 302 /*****************************************************************************
848 dl->cursor_elt = x; 896 dl->cursor_elt = x;
849 return 1; 897 return 1;
850 } 898 }
851 else 899 else
852 { 900 {
853 DEVMETH (d, output_begin, (d)); 901 {
854 902 MAYBE_DEVMETH (d, frame_output_begin, (f));
855 /* #### This is a gross kludge. Cursor handling is such a royal 903 MAYBE_DEVMETH (d, window_output_begin, (w));
856 pain in the ass. */ 904 }
857 if (rb->type == RUNE_DGLYPH && 905 rb->cursor_type = CURSOR_OFF;
858 (EQ (rb->object.dglyph.glyph, Vtruncation_glyph) ||
859 EQ (rb->object.dglyph.glyph, Vcontinuation_glyph)))
860 rb->cursor_type = NO_CURSOR;
861 else
862 rb->cursor_type = CURSOR_OFF;
863 dl->cursor_elt = -1; 906 dl->cursor_elt = -1;
864 output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width); 907 output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width);
865 } 908 }
866 909
867 w->last_point_x[CURRENT_DISP] = -1; 910 w->last_point_x[CURRENT_DISP] = -1;
871 /* If this isn't the selected frame, then erasing the old cursor is 914 /* If this isn't the selected frame, then erasing the old cursor is
872 all we actually had to do. */ 915 all we actually had to do. */
873 if (w != XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame (d)))) 916 if (w != XWINDOW (FRAME_SELECTED_WINDOW (device_selected_frame (d))))
874 { 917 {
875 if (!no_output_end) 918 if (!no_output_end)
876 DEVMETH (d, output_end, (d)); 919 {
920 MAYBE_DEVMETH (d, window_output_end, (w));
921 MAYBE_DEVMETH (d, frame_output_end, (f));
922 }
877 923
878 return 1; 924 return 1;
879 } 925 }
880 926
881 /* This should only occur in the minibuffer. */ 927 /* This should only occur in the minibuffer. */
890 dl->cursor_elt = 0; 936 dl->cursor_elt = 0;
891 937
892 output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width); 938 output_display_line (w, 0, cla, y, rb->xpos, rb->xpos + rb->width);
893 939
894 if (!no_output_end) 940 if (!no_output_end)
895 DEVMETH (d, output_end, (d)); 941 {
942 MAYBE_DEVMETH (d, window_output_end, (w));
943 MAYBE_DEVMETH (d, frame_output_end, (f));
944 }
896 return 1; 945 return 1;
897 } 946 }
898 else 947 else
899 { 948 {
900 int cur_rb = 0; 949 int cur_rb = 0;
954 w->last_point_y[CURRENT_DISP] = cur_dl; 1003 w->last_point_y[CURRENT_DISP] = cur_dl;
955 Fset_marker (w->last_point[CURRENT_DISP], 1004 Fset_marker (w->last_point[CURRENT_DISP],
956 make_int (ADJ_BUFPOS), w->buffer); 1005 make_int (ADJ_BUFPOS), w->buffer);
957 1006
958 if (!no_output_end) 1007 if (!no_output_end)
959 DEVMETH (d, output_end, (d)); 1008 {
1009 MAYBE_DEVMETH (d, window_output_end, (w));
1010 MAYBE_DEVMETH (d, frame_output_end, (f));
1011 }
960 return 1; 1012 return 1;
961 } 1013 }
962 1014
963 (up ? cur_rb++ : cur_rb--); 1015 (up ? cur_rb++ : cur_rb--);
964 } 1016 }
967 (up ? cur_dl++ : cur_dl--); 1019 (up ? cur_dl++ : cur_dl--);
968 } 1020 }
969 } 1021 }
970 1022
971 if (!no_output_end) 1023 if (!no_output_end)
972 DEVMETH (d, output_end, (d)); 1024 {
1025 MAYBE_DEVMETH (d, window_output_end, (w));
1026 MAYBE_DEVMETH (d, frame_output_end, (f));
1027 }
973 return 0; 1028 return 0;
974 } 1029 }
975 #undef ADJ_BUFPOS 1030 #undef ADJ_BUFPOS
976 #undef ADJ_ENDPOS 1031 #undef ADJ_ENDPOS
977 1032
1022 { 1077 {
1023 MAYBE_DEVMETH (d, set_final_cursor_coords, 1078 MAYBE_DEVMETH (d, set_final_cursor_coords,
1024 (f, dl->ypos - 1, rb->xpos)); 1079 (f, dl->ypos - 1, rb->xpos));
1025 1080
1026 if (run_end_begin_meths) 1081 if (run_end_begin_meths)
1027 DEVMETH (d, output_begin, (d)); 1082 {
1083 MAYBE_DEVMETH (d, frame_output_begin, (f));
1084 MAYBE_DEVMETH (d, window_output_begin, (w));
1085 }
1028 1086
1029 output_display_line (w, 0, dla, y, rb->xpos, rb->xpos + rb->width); 1087 output_display_line (w, 0, dla, y, rb->xpos, rb->xpos + rb->width);
1030 1088
1031 if (run_end_begin_meths) 1089 if (run_end_begin_meths)
1032 DEVMETH (d, output_end, (d)); 1090 {
1091 MAYBE_DEVMETH (d, window_output_end, (w));
1092 MAYBE_DEVMETH (d, frame_output_end, (f));
1093 }
1033 } 1094 }
1034 } 1095 }
1035 1096
1036 /***************************************************************************** 1097 /*****************************************************************************
1037 redisplay_redraw_cursor 1098 redisplay_redraw_cursor
1065 int start, int end, int start_pixpos, int cursor_start, 1126 int start, int end, int start_pixpos, int cursor_start,
1066 int cursor_width, int cursor_height) 1127 int cursor_width, int cursor_height)
1067 { 1128 {
1068 struct frame *f = XFRAME (w->frame); 1129 struct frame *f = XFRAME (w->frame);
1069 struct device *d = XDEVICE (f->device); 1130 struct device *d = XDEVICE (f->device);
1131 /* Temporarily disabled until generalization is done. */
1132 #if 0
1070 struct display_block *db = Dynarr_atp (dl->display_blocks, block); 1133 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
1071 rune_dynarr *rba = db->runes; 1134 rune_dynarr *rba = db->runes;
1072 struct rune *rb; 1135 struct rune *rb;
1073 int xpos, width; 1136 int xpos, width;
1074 rb = Dynarr_atp (rba, start); 1137 rb = Dynarr_atp (rba, start);
1082 if (end < 0) 1145 if (end < 0)
1083 end = Dynarr_length (rba); 1146 end = Dynarr_length (rba);
1084 1147
1085 rb = Dynarr_atp (rba, end - 1); 1148 rb = Dynarr_atp (rba, end - 1);
1086 width = rb->xpos + rb->width - xpos; 1149 width = rb->xpos + rb->width - xpos;
1150 #endif
1087 /* now actually output the block. */ 1151 /* now actually output the block. */
1088 DEVMETH (d, output_display_block, (w, dl, block, start, 1152 DEVMETH (d, output_display_block, (w, dl, block, start,
1089 end, start_pixpos, 1153 end, start_pixpos,
1090 cursor_start, cursor_width, 1154 cursor_start, cursor_width,
1091 cursor_height)); 1155 cursor_height));
1098 parameters. 1162 parameters.
1099 ****************************************************************************/ 1163 ****************************************************************************/
1100 static void redisplay_unmap_subwindows (struct frame* f, int x, int y, int width, int height, 1164 static void redisplay_unmap_subwindows (struct frame* f, int x, int y, int width, int height,
1101 Lisp_Object ignored_window) 1165 Lisp_Object ignored_window)
1102 { 1166 {
1103 int elt; 1167 Lisp_Object rest;
1104 1168
1105 for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++) 1169 LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))
1106 { 1170 {
1107 struct subwindow_cachel *cachel = 1171 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (XCAR (rest));
1108 Dynarr_atp (f->subwindow_cachels, elt); 1172 if (IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii)
1109
1110 if (cachel->being_displayed
1111 && 1173 &&
1112 cachel->x + cachel->width > x && cachel->x < x + width 1174 IMAGE_INSTANCE_DISPLAY_X (ii)
1175 + IMAGE_INSTANCE_DISPLAY_WIDTH (ii) > x
1113 && 1176 &&
1114 cachel->y + cachel->height > y && cachel->y < y + height 1177 IMAGE_INSTANCE_DISPLAY_X (ii) < x + width
1115 && 1178 &&
1116 !EQ (cachel->subwindow, ignored_window)) 1179 IMAGE_INSTANCE_DISPLAY_Y (ii)
1117 { 1180 + IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) > y
1118 unmap_subwindow (cachel->subwindow); 1181 &&
1182 IMAGE_INSTANCE_DISPLAY_Y (ii) < y + height
1183 &&
1184 !EQ (XCAR (rest), ignored_window))
1185 {
1186 unmap_subwindow (XCAR (rest));
1119 } 1187 }
1120 } 1188 }
1121 } 1189 }
1122 1190
1123 /**************************************************************************** 1191 /****************************************************************************
1126 Potentially subwindows from the area in the box defined by the given 1194 Potentially subwindows from the area in the box defined by the given
1127 parameters. 1195 parameters.
1128 ****************************************************************************/ 1196 ****************************************************************************/
1129 void redisplay_unmap_subwindows_maybe (struct frame* f, int x, int y, int width, int height) 1197 void redisplay_unmap_subwindows_maybe (struct frame* f, int x, int y, int width, int height)
1130 { 1198 {
1131 if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f))) 1199 if (!NILP (XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))))
1132 { 1200 {
1133 redisplay_unmap_subwindows (f, x, y, width, height, Qnil); 1201 redisplay_unmap_subwindows (f, x, y, width, height, Qnil);
1134 } 1202 }
1135 } 1203 }
1136 1204
1137 static void redisplay_unmap_subwindows_except_us (struct frame* f, int x, int y, int width, 1205 static void redisplay_unmap_subwindows_except_us (struct frame* f, int x, int y, int width,
1138 int height, Lisp_Object subwindow) 1206 int height, Lisp_Object subwindow)
1139 { 1207 {
1140 if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f))) 1208 if (!NILP (XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))))
1141 { 1209 {
1142 redisplay_unmap_subwindows (f, x, y, width, height, subwindow); 1210 redisplay_unmap_subwindows (f, x, y, width, height, subwindow);
1143 } 1211 }
1144 } 1212 }
1145 1213
1159 { 1227 {
1160 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); 1228 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
1161 Lisp_Object window; 1229 Lisp_Object window;
1162 struct display_glyph_area sdga; 1230 struct display_glyph_area sdga;
1163 1231
1164 dga->height = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p); 1232 dga->height = IMAGE_INSTANCE_HEIGHT (p);
1165 dga->width = IMAGE_INSTANCE_SUBWINDOW_WIDTH (p); 1233 dga->width = IMAGE_INSTANCE_WIDTH (p);
1234
1235 /* The first thing we are going to do is update the display
1236 characteristics of the subwindow. This also clears the dirty
1237 flags as a side effect. */
1238 redisplay_subwindow (image_instance);
1166 1239
1167 /* This makes the glyph area fit into the display area. */ 1240 /* This makes the glyph area fit into the display area. */
1168 if (!redisplay_normalize_glyph_area (db, dga)) 1241 if (!redisplay_normalize_glyph_area (db, dga))
1169 return; 1242 return;
1170 1243
1185 need to be careful since the subwindow could be outside the 1258 need to be careful since the subwindow could be outside the
1186 window in the gutter or modeline - we also need to allow these 1259 window in the gutter or modeline - we also need to allow these
1187 cases.*/ 1260 cases.*/
1188 sdga.xoffset = -dga->xoffset; 1261 sdga.xoffset = -dga->xoffset;
1189 sdga.yoffset = -dga->yoffset; 1262 sdga.yoffset = -dga->yoffset;
1190 sdga.height = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p); 1263 sdga.height = IMAGE_INSTANCE_HEIGHT (p);
1191 sdga.width = IMAGE_INSTANCE_SUBWINDOW_WIDTH (p); 1264 sdga.width = IMAGE_INSTANCE_WIDTH (p);
1192 1265
1193 if (redisplay_display_boxes_in_window_p (w, db, &sdga) < 0) 1266 if (redisplay_display_boxes_in_window_p (w, db, &sdga) < 0)
1194 { 1267 {
1195 map_subwindow (image_instance, db->xpos, db->ypos, dga); 1268 map_subwindow (image_instance, db->xpos, db->ypos, dga);
1196 } 1269 }
1204 1277
1205 /**************************************************************************** 1278 /****************************************************************************
1206 redisplay_output_layout 1279 redisplay_output_layout
1207 1280
1208 Output a widget hierarchy. This can safely call itself recursively. 1281 Output a widget hierarchy. This can safely call itself recursively.
1282
1283 The complexity of outputting layouts is deciding whether to do it or
1284 not. Consider a layout enclosing some text, the text changes and is
1285 marked as dirty, but the enclosing layout has not been marked as
1286 dirty so no updates occur and the text will potentially be truncated.
1287 Alternatively we hold a back pointer in the image instance to the
1288 parent and mark the parent as dirty. But the layout code assumes that
1289 if the layout is dirty then the whole layout should be redisplayed,
1290 so we then get lots of flashing even though only the text has changed
1291 size. Of course if the text shrinks in size then we do actually need
1292 to redisplay the layout to repaint the exposed area. So what happens
1293 if we make a non-structural change like changing color? Either we
1294 redisplay everything, or we redisplay nothing. These are exactly the
1295 issues lwlib has to grapple with. We really need to know what has
1296 actually changed and make a layout decision based on that. We also
1297 really need to know what has changed so that we can only make the
1298 necessary changes in update_subwindow. This has all now been
1299 implemented, Viva la revolution!
1209 ****************************************************************************/ 1300 ****************************************************************************/
1210 void 1301 void
1211 redisplay_output_layout (struct window *w, 1302 redisplay_output_layout (Lisp_Object domain,
1212 Lisp_Object image_instance, 1303 Lisp_Object image_instance,
1213 struct display_box* db, struct display_glyph_area* dga, 1304 struct display_box* db, struct display_glyph_area* dga,
1214 face_index findex, int cursor_start, int cursor_width, 1305 face_index findex, int cursor_start, int cursor_width,
1215 int cursor_height) 1306 int cursor_height)
1216 { 1307 {
1217 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); 1308 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
1218 Lisp_Object window, rest; 1309 Lisp_Object rest, window = DOMAIN_WINDOW (domain);
1219 Emchar_dynarr *buf = Dynarr_new (Emchar); 1310 Emchar_dynarr *buf = Dynarr_new (Emchar);
1220 struct frame *f = XFRAME (w->frame); 1311 struct window *w = XWINDOW (window);
1221 struct device *d = XDEVICE (f->device); 1312 struct device *d = DOMAIN_XDEVICE (domain);
1222 int layout_height, layout_width; 1313 int layout_height, layout_width;
1223 /* We bogusly don't take f->extents_changed and f->glyphs_changed 1314
1224 into account. This is because if we do we always redisplay the 1315 layout_height = glyph_height (image_instance, domain);
1225 entire layout. So far I have seen no ill effects so we'll see. */ 1316 layout_width = glyph_width (image_instance, domain);
1226 int frame_really_changed = (f->buffers_changed ||
1227 f->clip_changed ||
1228 f->faces_changed ||
1229 f->frame_changed ||
1230 f->modeline_changed ||
1231 f->subwindows_changed ||
1232 f->windows_changed ||
1233 f->windows_structure_changed);
1234
1235 XSETWINDOW (window, w);
1236
1237 layout_height = glyph_height (image_instance, window);
1238 layout_width = glyph_width (image_instance, window);
1239 1317
1240 dga->height = layout_height; 1318 dga->height = layout_height;
1241 dga->width = layout_width; 1319 dga->width = layout_width;
1242 1320 #ifdef DEBUG_WIDGET_OUTPUT
1321 printf ("outputing layout glyph %p\n", p);
1322 #endif
1243 /* This makes the glyph area fit into the display area. */ 1323 /* This makes the glyph area fit into the display area. */
1244 if (!redisplay_normalize_glyph_area (db, dga)) 1324 if (!redisplay_normalize_glyph_area (db, dga))
1245 return; 1325 return;
1246 1326
1247 /* Highly dodgy optimization. We want to only output the whole 1327 /* Highly dodgy optimization. We want to only output the whole
1248 layout if we really have to. */ 1328 layout if we really have to. */
1249 if (frame_really_changed || IMAGE_INSTANCE_DIRTYP (p)) 1329 if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (p)
1330 || IMAGE_INSTANCE_LAYOUT_CHANGED (p)
1331 || IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p)
1332 || IMAGE_INSTANCE_SIZE_CHANGED (p)
1333 || IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (p))
1250 { 1334 {
1251 /* First clear the area we are drawing into. This is the easiest 1335 /* First clear the area we are drawing into. This is the easiest
1252 thing to do since we have many gaps that we have to make sure are 1336 thing to do since we have many gaps that we have to make sure are
1253 filled in. */ 1337 filled in. */
1254 redisplay_clear_clipped_region (window, findex, db, dga, 1, Qnil); 1338 redisplay_clear_clipped_region (window, findex, db, dga, 1, Qnil);
1300 redisplay_normalize_display_box (db, dga); 1384 redisplay_normalize_display_box (db, dga);
1301 1385
1302 /* Flip through the widgets in the layout displaying as necessary */ 1386 /* Flip through the widgets in the layout displaying as necessary */
1303 LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (p)) 1387 LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (p))
1304 { 1388 {
1305 Lisp_Object child = XCAR (rest); 1389 Lisp_Object child = glyph_image_instance (XCAR (rest), image_instance,
1390 ERROR_ME_NOT, 1);
1306 1391
1307 struct display_box cdb; 1392 struct display_box cdb;
1308 /* For losing HP-UX */ 1393 /* For losing HP-UX */
1309 cdb.xpos = db->xpos; 1394 cdb.xpos = db->xpos;
1310 cdb.ypos = db->ypos; 1395 cdb.ypos = db->ypos;
1313 1398
1314 /* First determine if the image is visible at all */ 1399 /* First determine if the image is visible at all */
1315 if (IMAGE_INSTANCEP (child)) 1400 if (IMAGE_INSTANCEP (child))
1316 { 1401 {
1317 Lisp_Image_Instance* childii = XIMAGE_INSTANCE (child); 1402 Lisp_Image_Instance* childii = XIMAGE_INSTANCE (child);
1403
1318 /* The enclosing layout offsets are +ve at this point */ 1404 /* The enclosing layout offsets are +ve at this point */
1319 struct display_glyph_area cdga; 1405 struct display_glyph_area cdga;
1320 cdga.xoffset = IMAGE_INSTANCE_XOFFSET (childii) - dga->xoffset; 1406 cdga.xoffset = IMAGE_INSTANCE_XOFFSET (childii) - dga->xoffset;
1321 cdga.yoffset = IMAGE_INSTANCE_YOFFSET (childii) - dga->yoffset; 1407 cdga.yoffset = IMAGE_INSTANCE_YOFFSET (childii) - dga->yoffset;
1322 cdga.width = glyph_width (child, window); 1408 cdga.width = glyph_width (child, image_instance);
1323 cdga.height = glyph_height (child, window); 1409 cdga.height = glyph_height (child, image_instance);
1410
1411 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) =
1412 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (p);
1324 1413
1325 /* Although normalization is done by the output routines 1414 /* Although normalization is done by the output routines
1326 we have to do it here so that they don't try and 1415 we have to do it here so that they don't try and
1327 clear all of db. This is true below also. */ 1416 clear all of db. This is true below also. */
1328 if (redisplay_normalize_glyph_area (&cdb, &cdga)) 1417 if (redisplay_normalize_glyph_area (&cdb, &cdga))
1334 || cdb.xpos + cdb.width > db->xpos + db->width 1423 || cdb.xpos + cdb.width > db->xpos + db->width
1335 || cdb.ypos + cdb.height > db->ypos + db->height) 1424 || cdb.ypos + cdb.height > db->ypos + db->height)
1336 continue; 1425 continue;
1337 /* We have to invert the offset here as normalization 1426 /* We have to invert the offset here as normalization
1338 will have made them positive which the output 1427 will have made them positive which the output
1339 routines will treat as a truely +ve offset. */ 1428 routines will treat as a truly +ve offset. */
1340 cdga.xoffset = -cdga.xoffset; 1429 cdga.xoffset = -cdga.xoffset;
1341 cdga.yoffset = -cdga.yoffset; 1430 cdga.yoffset = -cdga.yoffset;
1342 1431
1343 switch (IMAGE_INSTANCE_TYPE (childii)) 1432 switch (IMAGE_INSTANCE_TYPE (childii))
1344 { 1433 {
1346 { 1435 {
1347 /* #### This is well hacked and could use some 1436 /* #### This is well hacked and could use some
1348 generalisation.*/ 1437 generalisation.*/
1349 if (redisplay_normalize_glyph_area (&cdb, &cdga) 1438 if (redisplay_normalize_glyph_area (&cdb, &cdga)
1350 && 1439 &&
1351 (frame_really_changed || IMAGE_INSTANCE_DIRTYP (childii))) 1440 (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) ||
1441 IMAGE_INSTANCE_DIRTYP (childii)))
1352 { 1442 {
1353 struct display_line dl; /* this is fake */ 1443 struct display_line dl; /* this is fake */
1354 Lisp_Object string = 1444 Lisp_Object string =
1355 IMAGE_INSTANCE_TEXT_STRING (childii); 1445 IMAGE_INSTANCE_TEXT_STRING (childii);
1446 unsigned char charsets[NUM_LEADING_BYTES];
1447 struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, findex);
1448
1449 find_charsets_in_bufbyte_string (charsets,
1450 XSTRING_DATA (string),
1451 XSTRING_LENGTH (string));
1452 ensure_face_cachel_complete (cachel, window, charsets);
1453
1356 convert_bufbyte_string_into_emchar_dynarr 1454 convert_bufbyte_string_into_emchar_dynarr
1357 (XSTRING_DATA (string), XSTRING_LENGTH (string), buf); 1455 (XSTRING_DATA (string), XSTRING_LENGTH (string), buf);
1358 1456
1359 redisplay_normalize_display_box (&cdb, &cdga); 1457 redisplay_normalize_display_box (&cdb, &cdga);
1360 /* Offsets are now +ve again so be careful 1458 /* Offsets are now +ve again so be careful
1361 when fixing up the display line. */ 1459 when fixing up the display line. */
1362 xzero (dl); 1460 xzero (dl);
1363 /* Munge boxes into display lines. */ 1461 /* Munge boxes into display lines. */
1364 dl.ypos = (cdb.ypos - cdga.yoffset) 1462 dl.ypos = (cdb.ypos - cdga.yoffset)
1365 + glyph_ascent (child, window); 1463 + glyph_ascent (child, image_instance);
1366 dl.ascent = glyph_ascent (child, window); 1464 dl.ascent = glyph_ascent (child, image_instance);
1367 dl.descent = glyph_descent (child, window); 1465 dl.descent = glyph_descent (child, image_instance);
1368 dl.top_clip = cdga.yoffset; 1466 dl.top_clip = cdga.yoffset;
1369 dl.clip = (dl.ypos + dl.descent) - (cdb.ypos + cdb.height); 1467 dl.clip = (dl.ypos + dl.descent) - (cdb.ypos + cdb.height);
1370 /* output_string doesn't understand offsets in 1468 /* output_string doesn't understand offsets in
1371 the same way as other routines - we have to 1469 the same way as other routines - we have to
1372 add the offset to the width so that we 1470 add the offset to the width so that we
1380 } 1478 }
1381 break; 1479 break;
1382 1480
1383 case IMAGE_MONO_PIXMAP: 1481 case IMAGE_MONO_PIXMAP:
1384 case IMAGE_COLOR_PIXMAP: 1482 case IMAGE_COLOR_PIXMAP:
1385 if (frame_really_changed || IMAGE_INSTANCE_DIRTYP (childii)) 1483 if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii)
1484 || IMAGE_INSTANCE_DIRTYP (childii))
1386 redisplay_output_pixmap (w, child, &cdb, &cdga, findex, 1485 redisplay_output_pixmap (w, child, &cdb, &cdga, findex,
1387 0, 0, 0, 0); 1486 0, 0, 0, 0);
1388 break; 1487 break;
1389 1488
1390 case IMAGE_WIDGET: 1489 case IMAGE_WIDGET:
1490 if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (childii), Qlayout))
1491 {
1492 redisplay_output_layout (image_instance, child, &cdb, &cdga, findex,
1493 0, 0, 0);
1494 break;
1495 }
1391 case IMAGE_SUBWINDOW: 1496 case IMAGE_SUBWINDOW:
1392 if (frame_really_changed || IMAGE_INSTANCE_DIRTYP (childii)) 1497 if (!IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) ||
1498 IMAGE_INSTANCE_DIRTYP (childii))
1393 redisplay_output_subwindow (w, child, &cdb, &cdga, findex, 1499 redisplay_output_subwindow (w, child, &cdb, &cdga, findex,
1394 0, 0, 0); 1500 0, 0, 0);
1395 break;
1396
1397 case IMAGE_LAYOUT:
1398 redisplay_output_layout (w, child, &cdb, &cdga, findex,
1399 0, 0, 0);
1400 break; 1501 break;
1401 1502
1402 case IMAGE_NOTHING: 1503 case IMAGE_NOTHING:
1403 /* nothing is as nothing does */ 1504 /* nothing is as nothing does */
1404 break; 1505 break;
1406 case IMAGE_POINTER: 1507 case IMAGE_POINTER:
1407 default: 1508 default:
1408 abort (); 1509 abort ();
1409 } 1510 }
1410 } 1511 }
1411 } 1512 IMAGE_INSTANCE_OPTIMIZE_OUTPUT (childii) = 0;
1412 } 1513 }
1514 }
1515
1516 /* Update any display properties. I'm not sure whether this actually
1517 does anything for layouts except clear the changed flags. */
1518 redisplay_subwindow (image_instance);
1519
1413 Dynarr_free (buf); 1520 Dynarr_free (buf);
1414 } 1521 }
1415 1522
1416 /**************************************************************************** 1523 /****************************************************************************
1417 redisplay_output_pixmap 1524 redisplay_output_pixmap
1448 mask. */ 1555 mask. */
1449 if (!offset_bitmap) 1556 if (!offset_bitmap)
1450 { 1557 {
1451 redisplay_clear_clipped_region (window, findex, 1558 redisplay_clear_clipped_region (window, findex,
1452 db, dga, 1559 db, dga,
1453 (int)IMAGE_INSTANCE_PIXMAP_MASK (p), 1560 (IMAGE_INSTANCE_PIXMAP_MASK (p) != 0),
1454 Qnil); 1561 Qnil);
1455 1562
1456 /* This shrinks the display box to exactly enclose the glyph 1563 /* This shrinks the display box to exactly enclose the glyph
1457 area. */ 1564 area. */
1458 redisplay_normalize_display_box (db, dga); 1565 redisplay_normalize_display_box (db, dga);
1570 1677
1571 /**************************************************************************** 1678 /****************************************************************************
1572 redisplay_clear_clipped_region 1679 redisplay_clear_clipped_region
1573 1680
1574 Clear the area in the dest display_box not covered by the src 1681 Clear the area in the dest display_box not covered by the src
1575 display_glyph_area using the given face. This is a common occurance 1682 display_glyph_area using the given face. This is a common occurrence
1576 for images shorter than the display line. Clipping can be played 1683 for images shorter than the display line. Clipping can be played
1577 around with by altering these. glyphsrc should be normalized. 1684 around with by altering these. glyphsrc should be normalized.
1578 ****************************************************************************/ 1685 ****************************************************************************/
1579 static void 1686 static void
1580 redisplay_clear_clipped_region (Lisp_Object window, face_index findex, 1687 redisplay_clear_clipped_region (Lisp_Object window, face_index findex,
1950 struct device *d = XDEVICE (f->device); 2057 struct device *d = XDEVICE (f->device);
1951 2058
1952 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP); 2059 display_line_dynarr *cdla = window_display_lines (w, CURRENT_DISP);
1953 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP); 2060 display_line_dynarr *ddla = window_display_lines (w, DESIRED_DISP);
1954 2061
1955 DEVMETH (d, output_begin, (d)); 2062 MAYBE_DEVMETH (d, window_output_begin, (w));
1956 2063
1957 while (first_line <= last_line) 2064 while (first_line <= last_line)
1958 { 2065 {
1959 Charcount old_len = (Dynarr_atp (cdla, first_line)->end_bufpos - 2066 Charcount old_len = (Dynarr_atp (cdla, first_line)->end_bufpos -
1960 Dynarr_atp (cdla, first_line)->bufpos); 2067 Dynarr_atp (cdla, first_line)->bufpos);
2035 update_window_scrollbars (w, NULL, 1, stupid_vertical_scrollbar_drag_hack); 2142 update_window_scrollbars (w, NULL, 1, stupid_vertical_scrollbar_drag_hack);
2036 stupid_vertical_scrollbar_drag_hack = 1; 2143 stupid_vertical_scrollbar_drag_hack = 1;
2037 } 2144 }
2038 #endif 2145 #endif
2039 2146
2040 /* This has to be done after we've updated the values. We don't 2147 redisplay_redraw_cursor (f, 0);
2041 call output_end for tty frames. Redisplay will do this after all 2148 MAYBE_DEVMETH (d, window_output_end, (w));
2042 tty windows have been updated. This cuts down on cursor
2043 flicker. */
2044 if (FRAME_TTY_P (f))
2045 redisplay_redraw_cursor (f, 0);
2046 else
2047 DEVMETH (d, output_end, (d));
2048 } 2149 }
2049 2150
2050 /***************************************************************************** 2151 /*****************************************************************************
2051 redisplay_output_window 2152 redisplay_output_window
2052 2153
2156 } 2257 }
2157 } 2258 }
2158 } 2259 }
2159 2260
2160 /* Perform any output initialization. */ 2261 /* Perform any output initialization. */
2161 DEVMETH (d, output_begin, (d)); 2262 MAYBE_DEVMETH (d, window_output_begin, (w));
2162 2263
2163 /* If the window's structure has changed clear the internal border 2264 /* If the window's structure has changed clear the internal border
2164 above it if it is topmost (the function will check). */ 2265 above it if it is topmost (the function will check). */
2165 if (f->windows_structure_changed) 2266 if (f->windows_structure_changed)
2166 redisplay_clear_top_of_window (w); 2267 redisplay_clear_top_of_window (w);
2179 2280
2180 /* Output a vertical divider between windows, if necessary. */ 2281 /* Output a vertical divider between windows, if necessary. */
2181 if (window_needs_vertical_divider (w) 2282 if (window_needs_vertical_divider (w)
2182 && (f->windows_structure_changed || f->clear)) 2283 && (f->windows_structure_changed || f->clear))
2183 { 2284 {
2184 DEVMETH (d, output_vertical_divider, (w, f->windows_structure_changed)); 2285 MAYBE_DEVMETH (d, output_vertical_divider, (w, f->windows_structure_changed));
2185 } 2286 }
2186 2287
2187 /* Clear the rest of the window, if necessary. */ 2288 /* Clear the rest of the window, if necessary. */
2188 if (need_to_clear_bottom) 2289 if (need_to_clear_bottom)
2189 { 2290 {
2213 2314
2214 /* Overkill on invalidating the cache. It is very bad for it to not 2315 /* Overkill on invalidating the cache. It is very bad for it to not
2215 get invalidated when it should be. */ 2316 get invalidated when it should be. */
2216 INVALIDATE_DEVICE_PIXEL_TO_GLYPH_CACHE (d); 2317 INVALIDATE_DEVICE_PIXEL_TO_GLYPH_CACHE (d);
2217 2318
2218 /* We don't call output_end for tty frames. Redisplay will do this 2319 redisplay_redraw_cursor (f, 0);
2219 after all tty windows have been updated. This cuts down on 2320 MAYBE_DEVMETH (d, window_output_end, (w));
2220 cursor flicker. */
2221 if (FRAME_TTY_P (f))
2222 redisplay_redraw_cursor (f, 0);
2223 else
2224 DEVMETH (d, output_end, (d));
2225 2321
2226 #ifdef HAVE_SCROLLBARS 2322 #ifdef HAVE_SCROLLBARS
2227 update_window_scrollbars (w, NULL, !MINI_WINDOW_P (w), 0); 2323 update_window_scrollbars (w, NULL, !MINI_WINDOW_P (w), 0);
2228 #endif 2324 #endif
2229 } 2325 }