diff options
| author | Kim F. Storm | 2003-03-16 20:46:42 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2003-03-16 20:46:42 +0000 |
| commit | 5da0698e5440dd047000e8acd79766efaff5c3b9 (patch) | |
| tree | 330cfbcb9295ba88e4c692ac99e1187692ee18be /src | |
| parent | 133c764e3110b91ed475e6e8313aed57d4020595 (diff) | |
| download | emacs-5da0698e5440dd047000e8acd79766efaff5c3b9.tar.gz emacs-5da0698e5440dd047000e8acd79766efaff5c3b9.zip | |
Remove consolidated defines and code.
(x_per_char_metric, x_encode_char)
(x_compute_glyph_string_overhangs): Adapt to RIF requirements.
(x_redisplay_interface): Add new members.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 2222 |
1 files changed, 17 insertions, 2205 deletions
diff --git a/src/xterm.c b/src/xterm.c index 0c15e6a5fdc..380e4c73d7c 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -333,19 +333,6 @@ extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *)); | |||
| 333 | extern Lisp_Object x_icon_type P_ ((struct frame *)); | 333 | extern Lisp_Object x_icon_type P_ ((struct frame *)); |
| 334 | 334 | ||
| 335 | 335 | ||
| 336 | /* Enumeration for overriding/changing the face to use for drawing | ||
| 337 | glyphs in x_draw_glyphs. */ | ||
| 338 | |||
| 339 | enum draw_glyphs_face | ||
| 340 | { | ||
| 341 | DRAW_NORMAL_TEXT, | ||
| 342 | DRAW_INVERSE_VIDEO, | ||
| 343 | DRAW_CURSOR, | ||
| 344 | DRAW_MOUSE_FACE, | ||
| 345 | DRAW_IMAGE_RAISED, | ||
| 346 | DRAW_IMAGE_SUNKEN | ||
| 347 | }; | ||
| 348 | |||
| 349 | static int cursor_in_mouse_face_p P_ ((struct window *)); | 336 | static int cursor_in_mouse_face_p P_ ((struct window *)); |
| 350 | static int clear_mouse_face P_ ((struct x_display_info *)); | 337 | static int clear_mouse_face P_ ((struct x_display_info *)); |
| 351 | static int x_alloc_nearest_color_1 P_ ((Display *, Colormap, XColor *)); | 338 | static int x_alloc_nearest_color_1 P_ ((Display *, Colormap, XColor *)); |
| @@ -433,15 +420,12 @@ void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int)); | |||
| 433 | static void x_clip_to_row P_ ((struct window *, struct glyph_row *, | 420 | static void x_clip_to_row P_ ((struct window *, struct glyph_row *, |
| 434 | GC, int)); | 421 | GC, int)); |
| 435 | static int x_phys_cursor_in_rect_p P_ ((struct window *, XRectangle *)); | 422 | static int x_phys_cursor_in_rect_p P_ ((struct window *, XRectangle *)); |
| 436 | static void notice_overwritten_cursor P_ ((struct window *, enum glyph_row_area, | ||
| 437 | int, int, int, int)); | ||
| 438 | static void x_flush P_ ((struct frame *f)); | 423 | static void x_flush P_ ((struct frame *f)); |
| 439 | static void x_update_begin P_ ((struct frame *)); | 424 | static void x_update_begin P_ ((struct frame *)); |
| 440 | static void x_update_window_begin P_ ((struct window *)); | 425 | static void x_update_window_begin P_ ((struct window *)); |
| 441 | static void x_draw_vertical_border P_ ((struct window *)); | 426 | static void x_draw_vertical_border P_ ((struct window *)); |
| 442 | static void x_after_update_window_line P_ ((struct glyph_row *)); | 427 | static void x_after_update_window_line P_ ((struct glyph_row *)); |
| 443 | static INLINE void take_vertical_position_into_account P_ ((struct it *)); | 428 | static INLINE void take_vertical_position_into_account P_ ((struct it *)); |
| 444 | static void x_produce_stretch_glyph P_ ((struct it *)); | ||
| 445 | static struct scroll_bar *x_window_to_scroll_bar P_ ((Window)); | 429 | static struct scroll_bar *x_window_to_scroll_bar P_ ((Window)); |
| 446 | static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *, | 430 | static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *, |
| 447 | enum scroll_bar_part *, | 431 | enum scroll_bar_part *, |
| @@ -923,30 +907,17 @@ XTcursor_to (vpos, hpos, y, x) | |||
| 923 | 907 | ||
| 924 | /* Function prototypes of this page. */ | 908 | /* Function prototypes of this page. */ |
| 925 | 909 | ||
| 926 | static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *, | 910 | static int x_encode_char P_ ((int, XChar2b *, struct font_info *, int *)); |
| 927 | struct glyph *, | ||
| 928 | XChar2b *, | ||
| 929 | int *)); | ||
| 930 | static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int, | ||
| 931 | int, XChar2b *, int, | ||
| 932 | int)); | ||
| 933 | static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *)); | ||
| 934 | static void x_encode_char P_ ((int, XChar2b *, struct font_info *)); | ||
| 935 | static void x_append_glyph P_ ((struct it *)); | ||
| 936 | static void x_append_composite_glyph P_ ((struct it *)); | ||
| 937 | static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object, | ||
| 938 | int, int, double)); | ||
| 939 | static void x_produce_glyphs P_ ((struct it *)); | ||
| 940 | static void x_produce_image_glyph P_ ((struct it *it)); | ||
| 941 | 911 | ||
| 942 | 912 | ||
| 943 | /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B | 913 | /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B |
| 944 | is not contained in the font. */ | 914 | is not contained in the font. */ |
| 945 | 915 | ||
| 946 | static INLINE XCharStruct * | 916 | static XCharStruct * |
| 947 | x_per_char_metric (font, char2b) | 917 | x_per_char_metric (font, char2b, font_type) |
| 948 | XFontStruct *font; | 918 | XFontStruct *font; |
| 949 | XChar2b *char2b; | 919 | XChar2b *char2b; |
| 920 | int font_type; /* unused on X */ | ||
| 950 | { | 921 | { |
| 951 | /* The result metric information. */ | 922 | /* The result metric information. */ |
| 952 | XCharStruct *pcm = NULL; | 923 | XCharStruct *pcm = NULL; |
| @@ -1014,11 +985,12 @@ x_per_char_metric (font, char2b) | |||
| 1014 | /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is | 985 | /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is |
| 1015 | the two-byte form of C. Encoding is returned in *CHAR2B. */ | 986 | the two-byte form of C. Encoding is returned in *CHAR2B. */ |
| 1016 | 987 | ||
| 1017 | static INLINE void | 988 | static int |
| 1018 | x_encode_char (c, char2b, font_info) | 989 | x_encode_char (c, char2b, font_info, two_byte_p) |
| 1019 | int c; | 990 | int c; |
| 1020 | XChar2b *char2b; | 991 | XChar2b *char2b; |
| 1021 | struct font_info *font_info; | 992 | struct font_info *font_info; |
| 993 | int *two_byte_p; | ||
| 1022 | { | 994 | { |
| 1023 | int charset = CHAR_CHARSET (c); | 995 | int charset = CHAR_CHARSET (c); |
| 1024 | XFontStruct *font = font_info->font; | 996 | XFontStruct *font = font_info->font; |
| @@ -1066,1070 +1038,11 @@ x_encode_char (c, char2b, font_info) | |||
| 1066 | if (enc == 1 || enc == 3) | 1038 | if (enc == 1 || enc == 3) |
| 1067 | char2b->byte2 |= 0x80; | 1039 | char2b->byte2 |= 0x80; |
| 1068 | } | 1040 | } |
| 1069 | } | ||
| 1070 | |||
| 1071 | |||
| 1072 | /* Get face and two-byte form of character C in face FACE_ID on frame | ||
| 1073 | F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero | ||
| 1074 | means we want to display multibyte text. DISPLAY_P non-zero means | ||
| 1075 | make sure that X resources for the face returned are allocated. | ||
| 1076 | Value is a pointer to a realized face that is ready for display if | ||
| 1077 | DISPLAY_P is non-zero. */ | ||
| 1078 | |||
| 1079 | static INLINE struct face * | ||
| 1080 | x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p) | ||
| 1081 | struct frame *f; | ||
| 1082 | int c, face_id; | ||
| 1083 | XChar2b *char2b; | ||
| 1084 | int multibyte_p, display_p; | ||
| 1085 | { | ||
| 1086 | struct face *face = FACE_FROM_ID (f, face_id); | ||
| 1087 | |||
| 1088 | if (!multibyte_p) | ||
| 1089 | { | ||
| 1090 | /* Unibyte case. We don't have to encode, but we have to make | ||
| 1091 | sure to use a face suitable for unibyte. */ | ||
| 1092 | char2b->byte1 = 0; | ||
| 1093 | char2b->byte2 = c; | ||
| 1094 | face_id = FACE_FOR_CHAR (f, face, c); | ||
| 1095 | face = FACE_FROM_ID (f, face_id); | ||
| 1096 | } | ||
| 1097 | else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL) | ||
| 1098 | { | ||
| 1099 | /* Case of ASCII in a face known to fit ASCII. */ | ||
| 1100 | char2b->byte1 = 0; | ||
| 1101 | char2b->byte2 = c; | ||
| 1102 | } | ||
| 1103 | else | ||
| 1104 | { | ||
| 1105 | int c1, c2, charset; | ||
| 1106 | |||
| 1107 | /* Split characters into bytes. If c2 is -1 afterwards, C is | ||
| 1108 | really a one-byte character so that byte1 is zero. */ | ||
| 1109 | SPLIT_CHAR (c, charset, c1, c2); | ||
| 1110 | if (c2 > 0) | ||
| 1111 | char2b->byte1 = c1, char2b->byte2 = c2; | ||
| 1112 | else | ||
| 1113 | char2b->byte1 = 0, char2b->byte2 = c1; | ||
| 1114 | |||
| 1115 | /* Maybe encode the character in *CHAR2B. */ | ||
| 1116 | if (face->font != NULL) | ||
| 1117 | { | ||
| 1118 | struct font_info *font_info | ||
| 1119 | = FONT_INFO_FROM_ID (f, face->font_info_id); | ||
| 1120 | if (font_info) | ||
| 1121 | x_encode_char (c, char2b, font_info); | ||
| 1122 | } | ||
| 1123 | } | ||
| 1124 | |||
| 1125 | /* Make sure X resources of the face are allocated. */ | ||
| 1126 | if (display_p) | ||
| 1127 | { | ||
| 1128 | xassert (face != NULL); | ||
| 1129 | PREPARE_FACE_FOR_DISPLAY (f, face); | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | return face; | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | |||
| 1136 | /* Get face and two-byte form of character glyph GLYPH on frame F. | ||
| 1137 | The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is | ||
| 1138 | a pointer to a realized face that is ready for display. */ | ||
| 1139 | |||
| 1140 | static INLINE struct face * | ||
| 1141 | x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p) | ||
| 1142 | struct frame *f; | ||
| 1143 | struct glyph *glyph; | ||
| 1144 | XChar2b *char2b; | ||
| 1145 | int *two_byte_p; | ||
| 1146 | { | ||
| 1147 | struct face *face; | ||
| 1148 | |||
| 1149 | xassert (glyph->type == CHAR_GLYPH); | ||
| 1150 | face = FACE_FROM_ID (f, glyph->face_id); | ||
| 1151 | 1041 | ||
| 1152 | if (two_byte_p) | 1042 | if (two_byte_p) |
| 1153 | *two_byte_p = 0; | 1043 | *two_byte_p = ((XFontStruct *) (font_info->font))->max_byte1 > 0; |
| 1154 | |||
| 1155 | if (!glyph->multibyte_p) | ||
| 1156 | { | ||
| 1157 | /* Unibyte case. We don't have to encode, but we have to make | ||
| 1158 | sure to use a face suitable for unibyte. */ | ||
| 1159 | char2b->byte1 = 0; | ||
| 1160 | char2b->byte2 = glyph->u.ch; | ||
| 1161 | } | ||
| 1162 | else if (glyph->u.ch < 128 | ||
| 1163 | && glyph->face_id < BASIC_FACE_ID_SENTINEL) | ||
| 1164 | { | ||
| 1165 | /* Case of ASCII in a face known to fit ASCII. */ | ||
| 1166 | char2b->byte1 = 0; | ||
| 1167 | char2b->byte2 = glyph->u.ch; | ||
| 1168 | } | ||
| 1169 | else | ||
| 1170 | { | ||
| 1171 | int c1, c2, charset; | ||
| 1172 | |||
| 1173 | /* Split characters into bytes. If c2 is -1 afterwards, C is | ||
| 1174 | really a one-byte character so that byte1 is zero. */ | ||
| 1175 | SPLIT_CHAR (glyph->u.ch, charset, c1, c2); | ||
| 1176 | if (c2 > 0) | ||
| 1177 | char2b->byte1 = c1, char2b->byte2 = c2; | ||
| 1178 | else | ||
| 1179 | char2b->byte1 = 0, char2b->byte2 = c1; | ||
| 1180 | |||
| 1181 | /* Maybe encode the character in *CHAR2B. */ | ||
| 1182 | if (charset != CHARSET_ASCII) | ||
| 1183 | { | ||
| 1184 | struct font_info *font_info | ||
| 1185 | = FONT_INFO_FROM_ID (f, face->font_info_id); | ||
| 1186 | if (font_info) | ||
| 1187 | { | ||
| 1188 | x_encode_char (glyph->u.ch, char2b, font_info); | ||
| 1189 | if (two_byte_p) | ||
| 1190 | *two_byte_p | ||
| 1191 | = ((XFontStruct *) (font_info->font))->max_byte1 > 0; | ||
| 1192 | } | ||
| 1193 | } | ||
| 1194 | } | ||
| 1195 | |||
| 1196 | /* Make sure X resources of the face are allocated. */ | ||
| 1197 | xassert (face != NULL); | ||
| 1198 | PREPARE_FACE_FOR_DISPLAY (f, face); | ||
| 1199 | return face; | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | |||
| 1203 | /* Store one glyph for IT->char_to_display in IT->glyph_row. | ||
| 1204 | Called from x_produce_glyphs when IT->glyph_row is non-null. */ | ||
| 1205 | |||
| 1206 | static INLINE void | ||
| 1207 | x_append_glyph (it) | ||
| 1208 | struct it *it; | ||
| 1209 | { | ||
| 1210 | struct glyph *glyph; | ||
| 1211 | enum glyph_row_area area = it->area; | ||
| 1212 | |||
| 1213 | xassert (it->glyph_row); | ||
| 1214 | xassert (it->char_to_display != '\n' && it->char_to_display != '\t'); | ||
| 1215 | |||
| 1216 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 1217 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 1218 | { | ||
| 1219 | glyph->charpos = CHARPOS (it->position); | ||
| 1220 | glyph->object = it->object; | ||
| 1221 | glyph->pixel_width = it->pixel_width; | ||
| 1222 | glyph->voffset = it->voffset; | ||
| 1223 | glyph->type = CHAR_GLYPH; | ||
| 1224 | glyph->multibyte_p = it->multibyte_p; | ||
| 1225 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 1226 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 1227 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | ||
| 1228 | || it->phys_descent > it->descent); | ||
| 1229 | glyph->padding_p = 0; | ||
| 1230 | glyph->glyph_not_available_p = it->glyph_not_available_p; | ||
| 1231 | glyph->face_id = it->face_id; | ||
| 1232 | glyph->u.ch = it->char_to_display; | ||
| 1233 | ++it->glyph_row->used[area]; | ||
| 1234 | } | ||
| 1235 | } | ||
| 1236 | |||
| 1237 | /* Store one glyph for the composition IT->cmp_id in IT->glyph_row. | ||
| 1238 | Called from x_produce_glyphs when IT->glyph_row is non-null. */ | ||
| 1239 | |||
| 1240 | static INLINE void | ||
| 1241 | x_append_composite_glyph (it) | ||
| 1242 | struct it *it; | ||
| 1243 | { | ||
| 1244 | struct glyph *glyph; | ||
| 1245 | enum glyph_row_area area = it->area; | ||
| 1246 | |||
| 1247 | xassert (it->glyph_row); | ||
| 1248 | |||
| 1249 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 1250 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 1251 | { | ||
| 1252 | glyph->charpos = CHARPOS (it->position); | ||
| 1253 | glyph->object = it->object; | ||
| 1254 | glyph->pixel_width = it->pixel_width; | ||
| 1255 | glyph->voffset = it->voffset; | ||
| 1256 | glyph->type = COMPOSITE_GLYPH; | ||
| 1257 | glyph->multibyte_p = it->multibyte_p; | ||
| 1258 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 1259 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 1260 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | ||
| 1261 | || it->phys_descent > it->descent); | ||
| 1262 | glyph->padding_p = 0; | ||
| 1263 | glyph->glyph_not_available_p = 0; | ||
| 1264 | glyph->face_id = it->face_id; | ||
| 1265 | glyph->u.cmp_id = it->cmp_id; | ||
| 1266 | ++it->glyph_row->used[area]; | ||
| 1267 | } | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | |||
| 1271 | /* Change IT->ascent and IT->height according to the setting of | ||
| 1272 | IT->voffset. */ | ||
| 1273 | |||
| 1274 | static INLINE void | ||
| 1275 | take_vertical_position_into_account (it) | ||
| 1276 | struct it *it; | ||
| 1277 | { | ||
| 1278 | if (it->voffset) | ||
| 1279 | { | ||
| 1280 | if (it->voffset < 0) | ||
| 1281 | /* Increase the ascent so that we can display the text higher | ||
| 1282 | in the line. */ | ||
| 1283 | it->ascent += abs (it->voffset); | ||
| 1284 | else | ||
| 1285 | /* Increase the descent so that we can display the text lower | ||
| 1286 | in the line. */ | ||
| 1287 | it->descent += it->voffset; | ||
| 1288 | } | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | |||
| 1292 | /* Produce glyphs/get display metrics for the image IT is loaded with. | ||
| 1293 | See the description of struct display_iterator in dispextern.h for | ||
| 1294 | an overview of struct display_iterator. */ | ||
| 1295 | |||
| 1296 | static void | ||
| 1297 | x_produce_image_glyph (it) | ||
| 1298 | struct it *it; | ||
| 1299 | { | ||
| 1300 | struct image *img; | ||
| 1301 | struct face *face; | ||
| 1302 | |||
| 1303 | xassert (it->what == IT_IMAGE); | ||
| 1304 | |||
| 1305 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1306 | img = IMAGE_FROM_ID (it->f, it->image_id); | ||
| 1307 | xassert (img); | ||
| 1308 | |||
| 1309 | /* Make sure X resources of the face and image are loaded. */ | ||
| 1310 | PREPARE_FACE_FOR_DISPLAY (it->f, face); | ||
| 1311 | prepare_image_for_display (it->f, img); | ||
| 1312 | |||
| 1313 | it->ascent = it->phys_ascent = image_ascent (img, face); | ||
| 1314 | it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent; | ||
| 1315 | it->pixel_width = img->width + 2 * img->hmargin; | ||
| 1316 | |||
| 1317 | it->nglyphs = 1; | ||
| 1318 | |||
| 1319 | if (face->box != FACE_NO_BOX) | ||
| 1320 | { | ||
| 1321 | if (face->box_line_width > 0) | ||
| 1322 | { | ||
| 1323 | it->ascent += face->box_line_width; | ||
| 1324 | it->descent += face->box_line_width; | ||
| 1325 | } | ||
| 1326 | |||
| 1327 | if (it->start_of_box_run_p) | ||
| 1328 | it->pixel_width += abs (face->box_line_width); | ||
| 1329 | if (it->end_of_box_run_p) | ||
| 1330 | it->pixel_width += abs (face->box_line_width); | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | take_vertical_position_into_account (it); | ||
| 1334 | |||
| 1335 | if (it->glyph_row) | ||
| 1336 | { | ||
| 1337 | struct glyph *glyph; | ||
| 1338 | enum glyph_row_area area = it->area; | ||
| 1339 | |||
| 1340 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 1341 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 1342 | { | ||
| 1343 | glyph->charpos = CHARPOS (it->position); | ||
| 1344 | glyph->object = it->object; | ||
| 1345 | glyph->pixel_width = it->pixel_width; | ||
| 1346 | glyph->voffset = it->voffset; | ||
| 1347 | glyph->type = IMAGE_GLYPH; | ||
| 1348 | glyph->multibyte_p = it->multibyte_p; | ||
| 1349 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 1350 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 1351 | glyph->overlaps_vertically_p = 0; | ||
| 1352 | glyph->padding_p = 0; | ||
| 1353 | glyph->glyph_not_available_p = 0; | ||
| 1354 | glyph->face_id = it->face_id; | ||
| 1355 | glyph->u.img_id = img->id; | ||
| 1356 | ++it->glyph_row->used[area]; | ||
| 1357 | } | ||
| 1358 | } | ||
| 1359 | } | ||
| 1360 | |||
| 1361 | |||
| 1362 | /* Append a stretch glyph to IT->glyph_row. OBJECT is the source | ||
| 1363 | of the glyph, WIDTH and HEIGHT are the width and height of the | ||
| 1364 | stretch. ASCENT is the percentage/100 of HEIGHT to use for the | ||
| 1365 | ascent of the glyph (0 <= ASCENT <= 1). */ | ||
| 1366 | |||
| 1367 | static void | ||
| 1368 | x_append_stretch_glyph (it, object, width, height, ascent) | ||
| 1369 | struct it *it; | ||
| 1370 | Lisp_Object object; | ||
| 1371 | int width, height; | ||
| 1372 | double ascent; | ||
| 1373 | { | ||
| 1374 | struct glyph *glyph; | ||
| 1375 | enum glyph_row_area area = it->area; | ||
| 1376 | |||
| 1377 | xassert (ascent >= 0 && ascent <= 1); | ||
| 1378 | |||
| 1379 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 1380 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 1381 | { | ||
| 1382 | glyph->charpos = CHARPOS (it->position); | ||
| 1383 | glyph->object = object; | ||
| 1384 | glyph->pixel_width = width; | ||
| 1385 | glyph->voffset = it->voffset; | ||
| 1386 | glyph->type = STRETCH_GLYPH; | ||
| 1387 | glyph->multibyte_p = it->multibyte_p; | ||
| 1388 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 1389 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 1390 | glyph->overlaps_vertically_p = 0; | ||
| 1391 | glyph->padding_p = 0; | ||
| 1392 | glyph->glyph_not_available_p = 0; | ||
| 1393 | glyph->face_id = it->face_id; | ||
| 1394 | glyph->u.stretch.ascent = height * ascent; | ||
| 1395 | glyph->u.stretch.height = height; | ||
| 1396 | ++it->glyph_row->used[area]; | ||
| 1397 | } | ||
| 1398 | } | ||
| 1399 | |||
| 1400 | |||
| 1401 | /* Produce a stretch glyph for iterator IT. IT->object is the value | ||
| 1402 | of the glyph property displayed. The value must be a list | ||
| 1403 | `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs | ||
| 1404 | being recognized: | ||
| 1405 | |||
| 1406 | 1. `:width WIDTH' specifies that the space should be WIDTH * | ||
| 1407 | canonical char width wide. WIDTH may be an integer or floating | ||
| 1408 | point number. | ||
| 1409 | |||
| 1410 | 2. `:relative-width FACTOR' specifies that the width of the stretch | ||
| 1411 | should be computed from the width of the first character having the | ||
| 1412 | `glyph' property, and should be FACTOR times that width. | ||
| 1413 | |||
| 1414 | 3. `:align-to HPOS' specifies that the space should be wide enough | ||
| 1415 | to reach HPOS, a value in canonical character units. | ||
| 1416 | |||
| 1417 | Exactly one of the above pairs must be present. | ||
| 1418 | |||
| 1419 | 4. `:height HEIGHT' specifies that the height of the stretch produced | ||
| 1420 | should be HEIGHT, measured in canonical character units. | ||
| 1421 | |||
| 1422 | 5. `:relative-height FACTOR' specifies that the height of the | ||
| 1423 | stretch should be FACTOR times the height of the characters having | ||
| 1424 | the glyph property. | ||
| 1425 | |||
| 1426 | Either none or exactly one of 4 or 5 must be present. | ||
| 1427 | |||
| 1428 | 6. `:ascent ASCENT' specifies that ASCENT percent of the height | ||
| 1429 | of the stretch should be used for the ascent of the stretch. | ||
| 1430 | ASCENT must be in the range 0 <= ASCENT <= 100. */ | ||
| 1431 | |||
| 1432 | #define NUMVAL(X) \ | ||
| 1433 | ((INTEGERP (X) || FLOATP (X)) \ | ||
| 1434 | ? XFLOATINT (X) \ | ||
| 1435 | : - 1) | ||
| 1436 | |||
| 1437 | |||
| 1438 | static void | ||
| 1439 | x_produce_stretch_glyph (it) | ||
| 1440 | struct it *it; | ||
| 1441 | { | ||
| 1442 | /* (space :width WIDTH :height HEIGHT. */ | ||
| 1443 | #if GLYPH_DEBUG | ||
| 1444 | extern Lisp_Object Qspace; | ||
| 1445 | #endif | ||
| 1446 | extern Lisp_Object QCwidth, QCheight, QCascent; | ||
| 1447 | extern Lisp_Object QCrelative_width, QCrelative_height; | ||
| 1448 | extern Lisp_Object QCalign_to; | ||
| 1449 | Lisp_Object prop, plist; | ||
| 1450 | double width = 0, height = 0, ascent = 0; | ||
| 1451 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1452 | XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f); | ||
| 1453 | |||
| 1454 | PREPARE_FACE_FOR_DISPLAY (it->f, face); | ||
| 1455 | |||
| 1456 | /* List should start with `space'. */ | ||
| 1457 | xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace)); | ||
| 1458 | plist = XCDR (it->object); | ||
| 1459 | |||
| 1460 | /* Compute the width of the stretch. */ | ||
| 1461 | if (prop = Fplist_get (plist, QCwidth), | ||
| 1462 | NUMVAL (prop) > 0) | ||
| 1463 | /* Absolute width `:width WIDTH' specified and valid. */ | ||
| 1464 | width = NUMVAL (prop) * CANON_X_UNIT (it->f); | ||
| 1465 | else if (prop = Fplist_get (plist, QCrelative_width), | ||
| 1466 | NUMVAL (prop) > 0) | ||
| 1467 | { | ||
| 1468 | /* Relative width `:relative-width FACTOR' specified and valid. | ||
| 1469 | Compute the width of the characters having the `glyph' | ||
| 1470 | property. */ | ||
| 1471 | struct it it2; | ||
| 1472 | unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); | ||
| 1473 | |||
| 1474 | it2 = *it; | ||
| 1475 | if (it->multibyte_p) | ||
| 1476 | { | ||
| 1477 | int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT) | ||
| 1478 | - IT_BYTEPOS (*it)); | ||
| 1479 | it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len); | ||
| 1480 | } | ||
| 1481 | else | ||
| 1482 | it2.c = *p, it2.len = 1; | ||
| 1483 | |||
| 1484 | it2.glyph_row = NULL; | ||
| 1485 | it2.what = IT_CHARACTER; | ||
| 1486 | x_produce_glyphs (&it2); | ||
| 1487 | width = NUMVAL (prop) * it2.pixel_width; | ||
| 1488 | } | ||
| 1489 | else if (prop = Fplist_get (plist, QCalign_to), | ||
| 1490 | NUMVAL (prop) > 0) | ||
| 1491 | width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x; | ||
| 1492 | else | ||
| 1493 | /* Nothing specified -> width defaults to canonical char width. */ | ||
| 1494 | width = CANON_X_UNIT (it->f); | ||
| 1495 | |||
| 1496 | /* Compute height. */ | ||
| 1497 | if (prop = Fplist_get (plist, QCheight), | ||
| 1498 | NUMVAL (prop) > 0) | ||
| 1499 | height = NUMVAL (prop) * CANON_Y_UNIT (it->f); | ||
| 1500 | else if (prop = Fplist_get (plist, QCrelative_height), | ||
| 1501 | NUMVAL (prop) > 0) | ||
| 1502 | height = FONT_HEIGHT (font) * NUMVAL (prop); | ||
| 1503 | else | ||
| 1504 | height = FONT_HEIGHT (font); | ||
| 1505 | |||
| 1506 | /* Compute percentage of height used for ascent. If | ||
| 1507 | `:ascent ASCENT' is present and valid, use that. Otherwise, | ||
| 1508 | derive the ascent from the font in use. */ | ||
| 1509 | if (prop = Fplist_get (plist, QCascent), | ||
| 1510 | NUMVAL (prop) > 0 && NUMVAL (prop) <= 100) | ||
| 1511 | ascent = NUMVAL (prop) / 100.0; | ||
| 1512 | else | ||
| 1513 | ascent = (double) font->ascent / FONT_HEIGHT (font); | ||
| 1514 | |||
| 1515 | if (width <= 0) | ||
| 1516 | width = 1; | ||
| 1517 | if (height <= 0) | ||
| 1518 | height = 1; | ||
| 1519 | |||
| 1520 | if (it->glyph_row) | ||
| 1521 | { | ||
| 1522 | Lisp_Object object = it->stack[it->sp - 1].string; | ||
| 1523 | if (!STRINGP (object)) | ||
| 1524 | object = it->w->buffer; | ||
| 1525 | x_append_stretch_glyph (it, object, width, height, ascent); | ||
| 1526 | } | ||
| 1527 | |||
| 1528 | it->pixel_width = width; | ||
| 1529 | it->ascent = it->phys_ascent = height * ascent; | ||
| 1530 | it->descent = it->phys_descent = height - it->ascent; | ||
| 1531 | it->nglyphs = 1; | ||
| 1532 | |||
| 1533 | if (face->box != FACE_NO_BOX) | ||
| 1534 | { | ||
| 1535 | if (face->box_line_width > 0) | ||
| 1536 | { | ||
| 1537 | it->ascent += face->box_line_width; | ||
| 1538 | it->descent += face->box_line_width; | ||
| 1539 | } | ||
| 1540 | |||
| 1541 | if (it->start_of_box_run_p) | ||
| 1542 | it->pixel_width += abs (face->box_line_width); | ||
| 1543 | if (it->end_of_box_run_p) | ||
| 1544 | it->pixel_width += abs (face->box_line_width); | ||
| 1545 | } | ||
| 1546 | |||
| 1547 | take_vertical_position_into_account (it); | ||
| 1548 | } | ||
| 1549 | |||
| 1550 | /* Return proper value to be used as baseline offset of font that has | ||
| 1551 | ASCENT and DESCENT to draw characters by the font at the vertical | ||
| 1552 | center of the line of frame F. | ||
| 1553 | |||
| 1554 | Here, out task is to find the value of BOFF in the following figure; | ||
| 1555 | |||
| 1556 | -------------------------+-----------+- | ||
| 1557 | -+-+---------+-+ | | | ||
| 1558 | | | | | | | | ||
| 1559 | | | | | F_ASCENT F_HEIGHT | ||
| 1560 | | | | ASCENT | | | ||
| 1561 | HEIGHT | | | | | | ||
| 1562 | | | |-|-+------+-----------|------- baseline | ||
| 1563 | | | | | BOFF | | | ||
| 1564 | | |---------|-+-+ | | | ||
| 1565 | | | | DESCENT | | | ||
| 1566 | -+-+---------+-+ F_DESCENT | | ||
| 1567 | -------------------------+-----------+- | ||
| 1568 | |||
| 1569 | -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT | ||
| 1570 | BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT | ||
| 1571 | DESCENT = FONT->descent | ||
| 1572 | HEIGHT = FONT_HEIGHT (FONT) | ||
| 1573 | F_DESCENT = (F->output_data.x->font->descent | ||
| 1574 | - F->output_data.x->baseline_offset) | ||
| 1575 | F_HEIGHT = FRAME_LINE_HEIGHT (F) | ||
| 1576 | */ | ||
| 1577 | |||
| 1578 | #define VCENTER_BASELINE_OFFSET(FONT, F) \ | ||
| 1579 | ((FONT)->descent \ | ||
| 1580 | + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \ | ||
| 1581 | + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \ | ||
| 1582 | - ((F)->output_data.x->font->descent - (F)->output_data.x->baseline_offset)) | ||
| 1583 | |||
| 1584 | /* Produce glyphs/get display metrics for the display element IT is | ||
| 1585 | loaded with. See the description of struct display_iterator in | ||
| 1586 | dispextern.h for an overview of struct display_iterator. */ | ||
| 1587 | |||
| 1588 | static void | ||
| 1589 | x_produce_glyphs (it) | ||
| 1590 | struct it *it; | ||
| 1591 | { | ||
| 1592 | it->glyph_not_available_p = 0; | ||
| 1593 | |||
| 1594 | if (it->what == IT_CHARACTER) | ||
| 1595 | { | ||
| 1596 | XChar2b char2b; | ||
| 1597 | XFontStruct *font; | ||
| 1598 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1599 | XCharStruct *pcm; | ||
| 1600 | int font_not_found_p; | ||
| 1601 | struct font_info *font_info; | ||
| 1602 | int boff; /* baseline offset */ | ||
| 1603 | /* We may change it->multibyte_p upon unibyte<->multibyte | ||
| 1604 | conversion. So, save the current value now and restore it | ||
| 1605 | later. | ||
| 1606 | |||
| 1607 | Note: It seems that we don't have to record multibyte_p in | ||
| 1608 | struct glyph because the character code itself tells if or | ||
| 1609 | not the character is multibyte. Thus, in the future, we must | ||
| 1610 | consider eliminating the field `multibyte_p' in the struct | ||
| 1611 | glyph. */ | ||
| 1612 | int saved_multibyte_p = it->multibyte_p; | ||
| 1613 | |||
| 1614 | /* Maybe translate single-byte characters to multibyte, or the | ||
| 1615 | other way. */ | ||
| 1616 | it->char_to_display = it->c; | ||
| 1617 | if (!ASCII_BYTE_P (it->c)) | ||
| 1618 | { | ||
| 1619 | if (unibyte_display_via_language_environment | ||
| 1620 | && SINGLE_BYTE_CHAR_P (it->c) | ||
| 1621 | && (it->c >= 0240 | ||
| 1622 | || !NILP (Vnonascii_translation_table))) | ||
| 1623 | { | ||
| 1624 | it->char_to_display = unibyte_char_to_multibyte (it->c); | ||
| 1625 | it->multibyte_p = 1; | ||
| 1626 | it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | ||
| 1627 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1628 | } | ||
| 1629 | else if (!SINGLE_BYTE_CHAR_P (it->c) | ||
| 1630 | && !it->multibyte_p) | ||
| 1631 | { | ||
| 1632 | it->multibyte_p = 1; | ||
| 1633 | it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | ||
| 1634 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1635 | } | ||
| 1636 | } | ||
| 1637 | |||
| 1638 | /* Get font to use. Encode IT->char_to_display. */ | ||
| 1639 | x_get_char_face_and_encoding (it->f, it->char_to_display, | ||
| 1640 | it->face_id, &char2b, | ||
| 1641 | it->multibyte_p, 0); | ||
| 1642 | font = face->font; | ||
| 1643 | |||
| 1644 | /* When no suitable font found, use the default font. */ | ||
| 1645 | font_not_found_p = font == NULL; | ||
| 1646 | if (font_not_found_p) | ||
| 1647 | { | ||
| 1648 | font = FRAME_FONT (it->f); | ||
| 1649 | boff = it->f->output_data.x->baseline_offset; | ||
| 1650 | font_info = NULL; | ||
| 1651 | } | ||
| 1652 | else | ||
| 1653 | { | ||
| 1654 | font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id); | ||
| 1655 | boff = font_info->baseline_offset; | ||
| 1656 | if (font_info->vertical_centering) | ||
| 1657 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | ||
| 1658 | } | ||
| 1659 | |||
| 1660 | if (it->char_to_display >= ' ' | ||
| 1661 | && (!it->multibyte_p || it->char_to_display < 128)) | ||
| 1662 | { | ||
| 1663 | /* Either unibyte or ASCII. */ | ||
| 1664 | int stretched_p; | ||
| 1665 | |||
| 1666 | it->nglyphs = 1; | ||
| 1667 | |||
| 1668 | pcm = x_per_char_metric (font, &char2b); | ||
| 1669 | it->ascent = font->ascent + boff; | ||
| 1670 | it->descent = font->descent - boff; | ||
| 1671 | |||
| 1672 | if (pcm) | ||
| 1673 | { | ||
| 1674 | it->phys_ascent = pcm->ascent + boff; | ||
| 1675 | it->phys_descent = pcm->descent - boff; | ||
| 1676 | it->pixel_width = pcm->width; | ||
| 1677 | } | ||
| 1678 | else | ||
| 1679 | { | ||
| 1680 | it->glyph_not_available_p = 1; | ||
| 1681 | it->phys_ascent = font->ascent + boff; | ||
| 1682 | it->phys_descent = font->descent - boff; | ||
| 1683 | it->pixel_width = FONT_WIDTH (font); | ||
| 1684 | } | ||
| 1685 | |||
| 1686 | /* If this is a space inside a region of text with | ||
| 1687 | `space-width' property, change its width. */ | ||
| 1688 | stretched_p = it->char_to_display == ' ' && !NILP (it->space_width); | ||
| 1689 | if (stretched_p) | ||
| 1690 | it->pixel_width *= XFLOATINT (it->space_width); | ||
| 1691 | |||
| 1692 | /* If face has a box, add the box thickness to the character | ||
| 1693 | height. If character has a box line to the left and/or | ||
| 1694 | right, add the box line width to the character's width. */ | ||
| 1695 | if (face->box != FACE_NO_BOX) | ||
| 1696 | { | ||
| 1697 | int thick = face->box_line_width; | ||
| 1698 | |||
| 1699 | if (thick > 0) | ||
| 1700 | { | ||
| 1701 | it->ascent += thick; | ||
| 1702 | it->descent += thick; | ||
| 1703 | } | ||
| 1704 | else | ||
| 1705 | thick = -thick; | ||
| 1706 | |||
| 1707 | if (it->start_of_box_run_p) | ||
| 1708 | it->pixel_width += thick; | ||
| 1709 | if (it->end_of_box_run_p) | ||
| 1710 | it->pixel_width += thick; | ||
| 1711 | } | ||
| 1712 | |||
| 1713 | /* If face has an overline, add the height of the overline | ||
| 1714 | (1 pixel) and a 1 pixel margin to the character height. */ | ||
| 1715 | if (face->overline_p) | ||
| 1716 | it->ascent += 2; | ||
| 1717 | |||
| 1718 | take_vertical_position_into_account (it); | ||
| 1719 | |||
| 1720 | /* If we have to actually produce glyphs, do it. */ | ||
| 1721 | if (it->glyph_row) | ||
| 1722 | { | ||
| 1723 | if (stretched_p) | ||
| 1724 | { | ||
| 1725 | /* Translate a space with a `space-width' property | ||
| 1726 | into a stretch glyph. */ | ||
| 1727 | double ascent = (double) font->ascent / FONT_HEIGHT (font); | ||
| 1728 | x_append_stretch_glyph (it, it->object, it->pixel_width, | ||
| 1729 | it->ascent + it->descent, ascent); | ||
| 1730 | } | ||
| 1731 | else | ||
| 1732 | x_append_glyph (it); | ||
| 1733 | |||
| 1734 | /* If characters with lbearing or rbearing are displayed | ||
| 1735 | in this line, record that fact in a flag of the | ||
| 1736 | glyph row. This is used to optimize X output code. */ | ||
| 1737 | if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width)) | ||
| 1738 | it->glyph_row->contains_overlapping_glyphs_p = 1; | ||
| 1739 | } | ||
| 1740 | } | ||
| 1741 | else if (it->char_to_display == '\n') | ||
| 1742 | { | ||
| 1743 | /* A newline has no width but we need the height of the line. */ | ||
| 1744 | it->pixel_width = 0; | ||
| 1745 | it->nglyphs = 0; | ||
| 1746 | it->ascent = it->phys_ascent = font->ascent + boff; | ||
| 1747 | it->descent = it->phys_descent = font->descent - boff; | ||
| 1748 | |||
| 1749 | if (face->box != FACE_NO_BOX | ||
| 1750 | && face->box_line_width > 0) | ||
| 1751 | { | ||
| 1752 | it->ascent += face->box_line_width; | ||
| 1753 | it->descent += face->box_line_width; | ||
| 1754 | } | ||
| 1755 | } | ||
| 1756 | else if (it->char_to_display == '\t') | ||
| 1757 | { | ||
| 1758 | int tab_width = it->tab_width * CANON_X_UNIT (it->f); | ||
| 1759 | int x = it->current_x + it->continuation_lines_width; | ||
| 1760 | int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width; | ||
| 1761 | |||
| 1762 | /* If the distance from the current position to the next tab | ||
| 1763 | stop is less than a canonical character width, use the | ||
| 1764 | tab stop after that. */ | ||
| 1765 | if (next_tab_x - x < CANON_X_UNIT (it->f)) | ||
| 1766 | next_tab_x += tab_width; | ||
| 1767 | |||
| 1768 | it->pixel_width = next_tab_x - x; | ||
| 1769 | it->nglyphs = 1; | ||
| 1770 | it->ascent = it->phys_ascent = font->ascent + boff; | ||
| 1771 | it->descent = it->phys_descent = font->descent - boff; | ||
| 1772 | |||
| 1773 | if (it->glyph_row) | ||
| 1774 | { | ||
| 1775 | double ascent = (double) it->ascent / (it->ascent + it->descent); | ||
| 1776 | x_append_stretch_glyph (it, it->object, it->pixel_width, | ||
| 1777 | it->ascent + it->descent, ascent); | ||
| 1778 | } | ||
| 1779 | } | ||
| 1780 | else | ||
| 1781 | { | ||
| 1782 | /* A multi-byte character. Assume that the display width of the | ||
| 1783 | character is the width of the character multiplied by the | ||
| 1784 | width of the font. */ | ||
| 1785 | |||
| 1786 | /* If we found a font, this font should give us the right | ||
| 1787 | metrics. If we didn't find a font, use the frame's | ||
| 1788 | default font and calculate the width of the character | ||
| 1789 | from the charset width; this is what old redisplay code | ||
| 1790 | did. */ | ||
| 1791 | pcm = x_per_char_metric (font, &char2b); | ||
| 1792 | if (font_not_found_p || !pcm) | ||
| 1793 | { | ||
| 1794 | int charset = CHAR_CHARSET (it->char_to_display); | ||
| 1795 | |||
| 1796 | it->glyph_not_available_p = 1; | ||
| 1797 | it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f)) | ||
| 1798 | * CHARSET_WIDTH (charset)); | ||
| 1799 | it->phys_ascent = font->ascent + boff; | ||
| 1800 | it->phys_descent = font->descent - boff; | ||
| 1801 | } | ||
| 1802 | else | ||
| 1803 | { | ||
| 1804 | it->pixel_width = pcm->width; | ||
| 1805 | it->phys_ascent = pcm->ascent + boff; | ||
| 1806 | it->phys_descent = pcm->descent - boff; | ||
| 1807 | if (it->glyph_row | ||
| 1808 | && (pcm->lbearing < 0 | ||
| 1809 | || pcm->rbearing > pcm->width)) | ||
| 1810 | it->glyph_row->contains_overlapping_glyphs_p = 1; | ||
| 1811 | } | ||
| 1812 | it->nglyphs = 1; | ||
| 1813 | it->ascent = font->ascent + boff; | ||
| 1814 | it->descent = font->descent - boff; | ||
| 1815 | if (face->box != FACE_NO_BOX) | ||
| 1816 | { | ||
| 1817 | int thick = face->box_line_width; | ||
| 1818 | |||
| 1819 | if (thick > 0) | ||
| 1820 | { | ||
| 1821 | it->ascent += thick; | ||
| 1822 | it->descent += thick; | ||
| 1823 | } | ||
| 1824 | else | ||
| 1825 | thick = - thick; | ||
| 1826 | |||
| 1827 | if (it->start_of_box_run_p) | ||
| 1828 | it->pixel_width += thick; | ||
| 1829 | if (it->end_of_box_run_p) | ||
| 1830 | it->pixel_width += thick; | ||
| 1831 | } | ||
| 1832 | |||
| 1833 | /* If face has an overline, add the height of the overline | ||
| 1834 | (1 pixel) and a 1 pixel margin to the character height. */ | ||
| 1835 | if (face->overline_p) | ||
| 1836 | it->ascent += 2; | ||
| 1837 | |||
| 1838 | take_vertical_position_into_account (it); | ||
| 1839 | 1044 | ||
| 1840 | if (it->glyph_row) | 1045 | return FONT_TYPE_UNKNOWN; |
| 1841 | x_append_glyph (it); | ||
| 1842 | } | ||
| 1843 | it->multibyte_p = saved_multibyte_p; | ||
| 1844 | } | ||
| 1845 | else if (it->what == IT_COMPOSITION) | ||
| 1846 | { | ||
| 1847 | /* Note: A composition is represented as one glyph in the | ||
| 1848 | glyph matrix. There are no padding glyphs. */ | ||
| 1849 | XChar2b char2b; | ||
| 1850 | XFontStruct *font; | ||
| 1851 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1852 | XCharStruct *pcm; | ||
| 1853 | int font_not_found_p; | ||
| 1854 | struct font_info *font_info; | ||
| 1855 | int boff; /* baseline offset */ | ||
| 1856 | struct composition *cmp = composition_table[it->cmp_id]; | ||
| 1857 | |||
| 1858 | /* Maybe translate single-byte characters to multibyte. */ | ||
| 1859 | it->char_to_display = it->c; | ||
| 1860 | if (unibyte_display_via_language_environment | ||
| 1861 | && SINGLE_BYTE_CHAR_P (it->c) | ||
| 1862 | && (it->c >= 0240 | ||
| 1863 | || (it->c >= 0200 | ||
| 1864 | && !NILP (Vnonascii_translation_table)))) | ||
| 1865 | { | ||
| 1866 | it->char_to_display = unibyte_char_to_multibyte (it->c); | ||
| 1867 | } | ||
| 1868 | |||
| 1869 | /* Get face and font to use. Encode IT->char_to_display. */ | ||
| 1870 | it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | ||
| 1871 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1872 | x_get_char_face_and_encoding (it->f, it->char_to_display, | ||
| 1873 | it->face_id, &char2b, it->multibyte_p, 0); | ||
| 1874 | font = face->font; | ||
| 1875 | |||
| 1876 | /* When no suitable font found, use the default font. */ | ||
| 1877 | font_not_found_p = font == NULL; | ||
| 1878 | if (font_not_found_p) | ||
| 1879 | { | ||
| 1880 | font = FRAME_FONT (it->f); | ||
| 1881 | boff = it->f->output_data.x->baseline_offset; | ||
| 1882 | font_info = NULL; | ||
| 1883 | } | ||
| 1884 | else | ||
| 1885 | { | ||
| 1886 | font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id); | ||
| 1887 | boff = font_info->baseline_offset; | ||
| 1888 | if (font_info->vertical_centering) | ||
| 1889 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | ||
| 1890 | } | ||
| 1891 | |||
| 1892 | /* There are no padding glyphs, so there is only one glyph to | ||
| 1893 | produce for the composition. Important is that pixel_width, | ||
| 1894 | ascent and descent are the values of what is drawn by | ||
| 1895 | draw_glyphs (i.e. the values of the overall glyphs composed). */ | ||
| 1896 | it->nglyphs = 1; | ||
| 1897 | |||
| 1898 | /* If we have not yet calculated pixel size data of glyphs of | ||
| 1899 | the composition for the current face font, calculate them | ||
| 1900 | now. Theoretically, we have to check all fonts for the | ||
| 1901 | glyphs, but that requires much time and memory space. So, | ||
| 1902 | here we check only the font of the first glyph. This leads | ||
| 1903 | to incorrect display very rarely, and C-l (recenter) can | ||
| 1904 | correct the display anyway. */ | ||
| 1905 | if (cmp->font != (void *) font) | ||
| 1906 | { | ||
| 1907 | /* Ascent and descent of the font of the first character of | ||
| 1908 | this composition (adjusted by baseline offset). Ascent | ||
| 1909 | and descent of overall glyphs should not be less than | ||
| 1910 | them respectively. */ | ||
| 1911 | int font_ascent = font->ascent + boff; | ||
| 1912 | int font_descent = font->descent - boff; | ||
| 1913 | /* Bounding box of the overall glyphs. */ | ||
| 1914 | int leftmost, rightmost, lowest, highest; | ||
| 1915 | int i, width, ascent, descent; | ||
| 1916 | |||
| 1917 | cmp->font = (void *) font; | ||
| 1918 | |||
| 1919 | /* Initialize the bounding box. */ | ||
| 1920 | if (font_info | ||
| 1921 | && (pcm = x_per_char_metric (font, &char2b))) | ||
| 1922 | { | ||
| 1923 | width = pcm->width; | ||
| 1924 | ascent = pcm->ascent; | ||
| 1925 | descent = pcm->descent; | ||
| 1926 | } | ||
| 1927 | else | ||
| 1928 | { | ||
| 1929 | width = FONT_WIDTH (font); | ||
| 1930 | ascent = font->ascent; | ||
| 1931 | descent = font->descent; | ||
| 1932 | } | ||
| 1933 | |||
| 1934 | rightmost = width; | ||
| 1935 | lowest = - descent + boff; | ||
| 1936 | highest = ascent + boff; | ||
| 1937 | leftmost = 0; | ||
| 1938 | |||
| 1939 | if (font_info | ||
| 1940 | && font_info->default_ascent | ||
| 1941 | && CHAR_TABLE_P (Vuse_default_ascent) | ||
| 1942 | && !NILP (Faref (Vuse_default_ascent, | ||
| 1943 | make_number (it->char_to_display)))) | ||
| 1944 | highest = font_info->default_ascent + boff; | ||
| 1945 | |||
| 1946 | /* Draw the first glyph at the normal position. It may be | ||
| 1947 | shifted to right later if some other glyphs are drawn at | ||
| 1948 | the left. */ | ||
| 1949 | cmp->offsets[0] = 0; | ||
| 1950 | cmp->offsets[1] = boff; | ||
| 1951 | |||
| 1952 | /* Set cmp->offsets for the remaining glyphs. */ | ||
| 1953 | for (i = 1; i < cmp->glyph_len; i++) | ||
| 1954 | { | ||
| 1955 | int left, right, btm, top; | ||
| 1956 | int ch = COMPOSITION_GLYPH (cmp, i); | ||
| 1957 | int face_id = FACE_FOR_CHAR (it->f, face, ch); | ||
| 1958 | |||
| 1959 | face = FACE_FROM_ID (it->f, face_id); | ||
| 1960 | x_get_char_face_and_encoding (it->f, ch, face->id, &char2b, | ||
| 1961 | it->multibyte_p, 0); | ||
| 1962 | font = face->font; | ||
| 1963 | if (font == NULL) | ||
| 1964 | { | ||
| 1965 | font = FRAME_FONT (it->f); | ||
| 1966 | boff = it->f->output_data.x->baseline_offset; | ||
| 1967 | font_info = NULL; | ||
| 1968 | } | ||
| 1969 | else | ||
| 1970 | { | ||
| 1971 | font_info | ||
| 1972 | = FONT_INFO_FROM_ID (it->f, face->font_info_id); | ||
| 1973 | boff = font_info->baseline_offset; | ||
| 1974 | if (font_info->vertical_centering) | ||
| 1975 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | ||
| 1976 | } | ||
| 1977 | |||
| 1978 | if (font_info | ||
| 1979 | && (pcm = x_per_char_metric (font, &char2b))) | ||
| 1980 | { | ||
| 1981 | width = pcm->width; | ||
| 1982 | ascent = pcm->ascent; | ||
| 1983 | descent = pcm->descent; | ||
| 1984 | } | ||
| 1985 | else | ||
| 1986 | { | ||
| 1987 | width = FONT_WIDTH (font); | ||
| 1988 | ascent = 1; | ||
| 1989 | descent = 0; | ||
| 1990 | } | ||
| 1991 | |||
| 1992 | if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS) | ||
| 1993 | { | ||
| 1994 | /* Relative composition with or without | ||
| 1995 | alternate chars. */ | ||
| 1996 | left = (leftmost + rightmost - width) / 2; | ||
| 1997 | btm = - descent + boff; | ||
| 1998 | if (font_info && font_info->relative_compose | ||
| 1999 | && (! CHAR_TABLE_P (Vignore_relative_composition) | ||
| 2000 | || NILP (Faref (Vignore_relative_composition, | ||
| 2001 | make_number (ch))))) | ||
| 2002 | { | ||
| 2003 | |||
| 2004 | if (- descent >= font_info->relative_compose) | ||
| 2005 | /* One extra pixel between two glyphs. */ | ||
| 2006 | btm = highest + 1; | ||
| 2007 | else if (ascent <= 0) | ||
| 2008 | /* One extra pixel between two glyphs. */ | ||
| 2009 | btm = lowest - 1 - ascent - descent; | ||
| 2010 | } | ||
| 2011 | } | ||
| 2012 | else | ||
| 2013 | { | ||
| 2014 | /* A composition rule is specified by an integer | ||
| 2015 | value that encodes global and new reference | ||
| 2016 | points (GREF and NREF). GREF and NREF are | ||
| 2017 | specified by numbers as below: | ||
| 2018 | |||
| 2019 | 0---1---2 -- ascent | ||
| 2020 | | | | ||
| 2021 | | | | ||
| 2022 | | | | ||
| 2023 | 9--10--11 -- center | ||
| 2024 | | | | ||
| 2025 | ---3---4---5--- baseline | ||
| 2026 | | | | ||
| 2027 | 6---7---8 -- descent | ||
| 2028 | */ | ||
| 2029 | int rule = COMPOSITION_RULE (cmp, i); | ||
| 2030 | int gref, nref, grefx, grefy, nrefx, nrefy; | ||
| 2031 | |||
| 2032 | COMPOSITION_DECODE_RULE (rule, gref, nref); | ||
| 2033 | grefx = gref % 3, nrefx = nref % 3; | ||
| 2034 | grefy = gref / 3, nrefy = nref / 3; | ||
| 2035 | |||
| 2036 | left = (leftmost | ||
| 2037 | + grefx * (rightmost - leftmost) / 2 | ||
| 2038 | - nrefx * width / 2); | ||
| 2039 | btm = ((grefy == 0 ? highest | ||
| 2040 | : grefy == 1 ? 0 | ||
| 2041 | : grefy == 2 ? lowest | ||
| 2042 | : (highest + lowest) / 2) | ||
| 2043 | - (nrefy == 0 ? ascent + descent | ||
| 2044 | : nrefy == 1 ? descent - boff | ||
| 2045 | : nrefy == 2 ? 0 | ||
| 2046 | : (ascent + descent) / 2)); | ||
| 2047 | } | ||
| 2048 | |||
| 2049 | cmp->offsets[i * 2] = left; | ||
| 2050 | cmp->offsets[i * 2 + 1] = btm + descent; | ||
| 2051 | |||
| 2052 | /* Update the bounding box of the overall glyphs. */ | ||
| 2053 | right = left + width; | ||
| 2054 | top = btm + descent + ascent; | ||
| 2055 | if (left < leftmost) | ||
| 2056 | leftmost = left; | ||
| 2057 | if (right > rightmost) | ||
| 2058 | rightmost = right; | ||
| 2059 | if (top > highest) | ||
| 2060 | highest = top; | ||
| 2061 | if (btm < lowest) | ||
| 2062 | lowest = btm; | ||
| 2063 | } | ||
| 2064 | |||
| 2065 | /* If there are glyphs whose x-offsets are negative, | ||
| 2066 | shift all glyphs to the right and make all x-offsets | ||
| 2067 | non-negative. */ | ||
| 2068 | if (leftmost < 0) | ||
| 2069 | { | ||
| 2070 | for (i = 0; i < cmp->glyph_len; i++) | ||
| 2071 | cmp->offsets[i * 2] -= leftmost; | ||
| 2072 | rightmost -= leftmost; | ||
| 2073 | } | ||
| 2074 | |||
| 2075 | cmp->pixel_width = rightmost; | ||
| 2076 | cmp->ascent = highest; | ||
| 2077 | cmp->descent = - lowest; | ||
| 2078 | if (cmp->ascent < font_ascent) | ||
| 2079 | cmp->ascent = font_ascent; | ||
| 2080 | if (cmp->descent < font_descent) | ||
| 2081 | cmp->descent = font_descent; | ||
| 2082 | } | ||
| 2083 | |||
| 2084 | it->pixel_width = cmp->pixel_width; | ||
| 2085 | it->ascent = it->phys_ascent = cmp->ascent; | ||
| 2086 | it->descent = it->phys_descent = cmp->descent; | ||
| 2087 | |||
| 2088 | if (face->box != FACE_NO_BOX) | ||
| 2089 | { | ||
| 2090 | int thick = face->box_line_width; | ||
| 2091 | |||
| 2092 | if (thick > 0) | ||
| 2093 | { | ||
| 2094 | it->ascent += thick; | ||
| 2095 | it->descent += thick; | ||
| 2096 | } | ||
| 2097 | else | ||
| 2098 | thick = - thick; | ||
| 2099 | |||
| 2100 | if (it->start_of_box_run_p) | ||
| 2101 | it->pixel_width += thick; | ||
| 2102 | if (it->end_of_box_run_p) | ||
| 2103 | it->pixel_width += thick; | ||
| 2104 | } | ||
| 2105 | |||
| 2106 | /* If face has an overline, add the height of the overline | ||
| 2107 | (1 pixel) and a 1 pixel margin to the character height. */ | ||
| 2108 | if (face->overline_p) | ||
| 2109 | it->ascent += 2; | ||
| 2110 | |||
| 2111 | take_vertical_position_into_account (it); | ||
| 2112 | |||
| 2113 | if (it->glyph_row) | ||
| 2114 | x_append_composite_glyph (it); | ||
| 2115 | } | ||
| 2116 | else if (it->what == IT_IMAGE) | ||
| 2117 | x_produce_image_glyph (it); | ||
| 2118 | else if (it->what == IT_STRETCH) | ||
| 2119 | x_produce_stretch_glyph (it); | ||
| 2120 | |||
| 2121 | /* Accumulate dimensions. Note: can't assume that it->descent > 0 | ||
| 2122 | because this isn't true for images with `:ascent 100'. */ | ||
| 2123 | xassert (it->ascent >= 0 && it->descent >= 0); | ||
| 2124 | if (it->area == TEXT_AREA) | ||
| 2125 | it->current_x += it->pixel_width; | ||
| 2126 | |||
| 2127 | it->descent += it->extra_line_spacing; | ||
| 2128 | |||
| 2129 | it->max_ascent = max (it->max_ascent, it->ascent); | ||
| 2130 | it->max_descent = max (it->max_descent, it->descent); | ||
| 2131 | it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent); | ||
| 2132 | it->max_phys_descent = max (it->max_phys_descent, it->phys_descent); | ||
| 2133 | } | 1046 | } |
| 2134 | 1047 | ||
| 2135 | 1048 | ||
| @@ -2165,172 +1078,8 @@ x_estimate_mode_line_height (f, face_id) | |||
| 2165 | Glyph display | 1078 | Glyph display |
| 2166 | ***********************************************************************/ | 1079 | ***********************************************************************/ |
| 2167 | 1080 | ||
| 2168 | /* A sequence of glyphs to be drawn in the same face. | ||
| 2169 | |||
| 2170 | This data structure is not really completely X specific, so it | ||
| 2171 | could possibly, at least partially, be useful for other systems. It | ||
| 2172 | is currently not part of the external redisplay interface because | ||
| 2173 | it's not clear what other systems will need. */ | ||
| 2174 | |||
| 2175 | struct glyph_string | ||
| 2176 | { | ||
| 2177 | /* X-origin of the string. */ | ||
| 2178 | int x; | ||
| 2179 | |||
| 2180 | /* Y-origin and y-position of the base line of this string. */ | ||
| 2181 | int y, ybase; | ||
| 2182 | |||
| 2183 | /* The width of the string, not including a face extension. */ | ||
| 2184 | int width; | ||
| 2185 | |||
| 2186 | /* The width of the string, including a face extension. */ | ||
| 2187 | int background_width; | ||
| 2188 | |||
| 2189 | /* The height of this string. This is the height of the line this | ||
| 2190 | string is drawn in, and can be different from the height of the | ||
| 2191 | font the string is drawn in. */ | ||
| 2192 | int height; | ||
| 2193 | |||
| 2194 | /* Number of pixels this string overwrites in front of its x-origin. | ||
| 2195 | This number is zero if the string has an lbearing >= 0; it is | ||
| 2196 | -lbearing, if the string has an lbearing < 0. */ | ||
| 2197 | int left_overhang; | ||
| 2198 | |||
| 2199 | /* Number of pixels this string overwrites past its right-most | ||
| 2200 | nominal x-position, i.e. x + width. Zero if the string's | ||
| 2201 | rbearing is <= its nominal width, rbearing - width otherwise. */ | ||
| 2202 | int right_overhang; | ||
| 2203 | |||
| 2204 | /* The frame on which the glyph string is drawn. */ | ||
| 2205 | struct frame *f; | ||
| 2206 | |||
| 2207 | /* The window on which the glyph string is drawn. */ | ||
| 2208 | struct window *w; | ||
| 2209 | |||
| 2210 | /* X display and window for convenience. */ | ||
| 2211 | Display *display; | ||
| 2212 | Window window; | ||
| 2213 | |||
| 2214 | /* The glyph row for which this string was built. It determines the | ||
| 2215 | y-origin and height of the string. */ | ||
| 2216 | struct glyph_row *row; | ||
| 2217 | |||
| 2218 | /* The area within row. */ | ||
| 2219 | enum glyph_row_area area; | ||
| 2220 | |||
| 2221 | /* Characters to be drawn, and number of characters. */ | ||
| 2222 | XChar2b *char2b; | ||
| 2223 | int nchars; | ||
| 2224 | |||
| 2225 | /* A face-override for drawing cursors, mouse face and similar. */ | ||
| 2226 | enum draw_glyphs_face hl; | ||
| 2227 | |||
| 2228 | /* Face in which this string is to be drawn. */ | ||
| 2229 | struct face *face; | ||
| 2230 | |||
| 2231 | /* Font in which this string is to be drawn. */ | ||
| 2232 | XFontStruct *font; | ||
| 2233 | |||
| 2234 | /* Font info for this string. */ | ||
| 2235 | struct font_info *font_info; | ||
| 2236 | |||
| 2237 | /* Non-null means this string describes (part of) a composition. | ||
| 2238 | All characters from char2b are drawn composed. */ | ||
| 2239 | struct composition *cmp; | ||
| 2240 | |||
| 2241 | /* Index of this glyph string's first character in the glyph | ||
| 2242 | definition of CMP. If this is zero, this glyph string describes | ||
| 2243 | the first character of a composition. */ | ||
| 2244 | int gidx; | ||
| 2245 | |||
| 2246 | /* 1 means this glyph strings face has to be drawn to the right end | ||
| 2247 | of the window's drawing area. */ | ||
| 2248 | unsigned extends_to_end_of_line_p : 1; | ||
| 2249 | |||
| 2250 | /* 1 means the background of this string has been drawn. */ | ||
| 2251 | unsigned background_filled_p : 1; | ||
| 2252 | |||
| 2253 | /* 1 means glyph string must be drawn with 16-bit functions. */ | ||
| 2254 | unsigned two_byte_p : 1; | ||
| 2255 | |||
| 2256 | /* 1 means that the original font determined for drawing this glyph | ||
| 2257 | string could not be loaded. The member `font' has been set to | ||
| 2258 | the frame's default font in this case. */ | ||
| 2259 | unsigned font_not_found_p : 1; | ||
| 2260 | |||
| 2261 | /* 1 means that the face in which this glyph string is drawn has a | ||
| 2262 | stipple pattern. */ | ||
| 2263 | unsigned stippled_p : 1; | ||
| 2264 | 1081 | ||
| 2265 | /* 1 means only the foreground of this glyph string must be drawn, | ||
| 2266 | and we should use the physical height of the line this glyph | ||
| 2267 | string appears in as clip rect. */ | ||
| 2268 | unsigned for_overlaps_p : 1; | ||
| 2269 | 1082 | ||
| 2270 | /* The GC to use for drawing this glyph string. */ | ||
| 2271 | GC gc; | ||
| 2272 | |||
| 2273 | /* A pointer to the first glyph in the string. This glyph | ||
| 2274 | corresponds to char2b[0]. Needed to draw rectangles if | ||
| 2275 | font_not_found_p is 1. */ | ||
| 2276 | struct glyph *first_glyph; | ||
| 2277 | |||
| 2278 | /* Image, if any. */ | ||
| 2279 | struct image *img; | ||
| 2280 | |||
| 2281 | struct glyph_string *next, *prev; | ||
| 2282 | }; | ||
| 2283 | |||
| 2284 | |||
| 2285 | #if GLYPH_DEBUG | ||
| 2286 | |||
| 2287 | static void | ||
| 2288 | x_dump_glyph_string (s) | ||
| 2289 | struct glyph_string *s; | ||
| 2290 | { | ||
| 2291 | fprintf (stderr, "glyph string\n"); | ||
| 2292 | fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n", | ||
| 2293 | s->x, s->y, s->width, s->height); | ||
| 2294 | fprintf (stderr, " ybase = %d\n", s->ybase); | ||
| 2295 | fprintf (stderr, " hl = %d\n", s->hl); | ||
| 2296 | fprintf (stderr, " left overhang = %d, right = %d\n", | ||
| 2297 | s->left_overhang, s->right_overhang); | ||
| 2298 | fprintf (stderr, " nchars = %d\n", s->nchars); | ||
| 2299 | fprintf (stderr, " extends to end of line = %d\n", | ||
| 2300 | s->extends_to_end_of_line_p); | ||
| 2301 | fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font)); | ||
| 2302 | fprintf (stderr, " bg width = %d\n", s->background_width); | ||
| 2303 | } | ||
| 2304 | |||
| 2305 | #endif /* GLYPH_DEBUG */ | ||
| 2306 | |||
| 2307 | |||
| 2308 | |||
| 2309 | static void x_append_glyph_string_lists P_ ((struct glyph_string **, | ||
| 2310 | struct glyph_string **, | ||
| 2311 | struct glyph_string *, | ||
| 2312 | struct glyph_string *)); | ||
| 2313 | static void x_prepend_glyph_string_lists P_ ((struct glyph_string **, | ||
| 2314 | struct glyph_string **, | ||
| 2315 | struct glyph_string *, | ||
| 2316 | struct glyph_string *)); | ||
| 2317 | static void x_append_glyph_string P_ ((struct glyph_string **, | ||
| 2318 | struct glyph_string **, | ||
| 2319 | struct glyph_string *)); | ||
| 2320 | static int x_left_overwritten P_ ((struct glyph_string *)); | ||
| 2321 | static int x_left_overwriting P_ ((struct glyph_string *)); | ||
| 2322 | static int x_right_overwritten P_ ((struct glyph_string *)); | ||
| 2323 | static int x_right_overwriting P_ ((struct glyph_string *)); | ||
| 2324 | static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int, | ||
| 2325 | int)); | ||
| 2326 | static void x_init_glyph_string P_ ((struct glyph_string *, | ||
| 2327 | XChar2b *, struct window *, | ||
| 2328 | struct glyph_row *, | ||
| 2329 | enum glyph_row_area, int, | ||
| 2330 | enum draw_glyphs_face)); | ||
| 2331 | static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *, | ||
| 2332 | enum glyph_row_area, int, int, | ||
| 2333 | enum draw_glyphs_face, int)); | ||
| 2334 | static void x_set_glyph_string_clipping P_ ((struct glyph_string *)); | 1083 | static void x_set_glyph_string_clipping P_ ((struct glyph_string *)); |
| 2335 | static void x_set_glyph_string_gc P_ ((struct glyph_string *)); | 1084 | static void x_set_glyph_string_gc P_ ((struct glyph_string *)); |
| 2336 | static void x_draw_glyph_string_background P_ ((struct glyph_string *, | 1085 | static void x_draw_glyph_string_background P_ ((struct glyph_string *, |
| @@ -2343,9 +1092,6 @@ static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *)); | |||
| 2343 | static void x_set_cursor_gc P_ ((struct glyph_string *)); | 1092 | static void x_set_cursor_gc P_ ((struct glyph_string *)); |
| 2344 | static void x_set_mode_line_face_gc P_ ((struct glyph_string *)); | 1093 | static void x_set_mode_line_face_gc P_ ((struct glyph_string *)); |
| 2345 | static void x_set_mouse_face_gc P_ ((struct glyph_string *)); | 1094 | static void x_set_mouse_face_gc P_ ((struct glyph_string *)); |
| 2346 | static void x_get_glyph_overhangs P_ ((struct glyph *, struct frame *, | ||
| 2347 | int *, int *)); | ||
| 2348 | static void x_compute_overhangs_and_x P_ ((struct glyph_string *, int, int)); | ||
| 2349 | static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap, | 1095 | static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap, |
| 2350 | unsigned long *, double, int)); | 1096 | unsigned long *, double, int)); |
| 2351 | static void x_setup_relief_color P_ ((struct frame *, struct relief *, | 1097 | static void x_setup_relief_color P_ ((struct frame *, struct relief *, |
| @@ -2355,7 +1101,6 @@ static void x_draw_image_glyph_string P_ ((struct glyph_string *)); | |||
| 2355 | static void x_draw_image_relief P_ ((struct glyph_string *)); | 1101 | static void x_draw_image_relief P_ ((struct glyph_string *)); |
| 2356 | static void x_draw_image_foreground P_ ((struct glyph_string *)); | 1102 | static void x_draw_image_foreground P_ ((struct glyph_string *)); |
| 2357 | static void x_draw_image_foreground_1 P_ ((struct glyph_string *, Pixmap)); | 1103 | static void x_draw_image_foreground_1 P_ ((struct glyph_string *, Pixmap)); |
| 2358 | static void x_fill_image_glyph_string P_ ((struct glyph_string *)); | ||
| 2359 | static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int, | 1104 | static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int, |
| 2360 | int, int, int)); | 1105 | int, int, int)); |
| 2361 | static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int, | 1106 | static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int, |
| @@ -2364,69 +1109,12 @@ static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, | |||
| 2364 | int, int, int, XRectangle *)); | 1109 | int, int, int, XRectangle *)); |
| 2365 | static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *, | 1110 | static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *, |
| 2366 | enum glyph_row_area)); | 1111 | enum glyph_row_area)); |
| 2367 | static int x_fill_stretch_glyph_string P_ ((struct glyph_string *, | ||
| 2368 | struct glyph_row *, | ||
| 2369 | enum glyph_row_area, int, int)); | ||
| 2370 | 1112 | ||
| 2371 | #if GLYPH_DEBUG | 1113 | #if GLYPH_DEBUG |
| 2372 | static void x_check_font P_ ((struct frame *, XFontStruct *)); | 1114 | static void x_check_font P_ ((struct frame *, XFontStruct *)); |
| 2373 | #endif | 1115 | #endif |
| 2374 | 1116 | ||
| 2375 | 1117 | ||
| 2376 | /* Append the list of glyph strings with head H and tail T to the list | ||
| 2377 | with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */ | ||
| 2378 | |||
| 2379 | static INLINE void | ||
| 2380 | x_append_glyph_string_lists (head, tail, h, t) | ||
| 2381 | struct glyph_string **head, **tail; | ||
| 2382 | struct glyph_string *h, *t; | ||
| 2383 | { | ||
| 2384 | if (h) | ||
| 2385 | { | ||
| 2386 | if (*head) | ||
| 2387 | (*tail)->next = h; | ||
| 2388 | else | ||
| 2389 | *head = h; | ||
| 2390 | h->prev = *tail; | ||
| 2391 | *tail = t; | ||
| 2392 | } | ||
| 2393 | } | ||
| 2394 | |||
| 2395 | |||
| 2396 | /* Prepend the list of glyph strings with head H and tail T to the | ||
| 2397 | list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the | ||
| 2398 | result. */ | ||
| 2399 | |||
| 2400 | static INLINE void | ||
| 2401 | x_prepend_glyph_string_lists (head, tail, h, t) | ||
| 2402 | struct glyph_string **head, **tail; | ||
| 2403 | struct glyph_string *h, *t; | ||
| 2404 | { | ||
| 2405 | if (h) | ||
| 2406 | { | ||
| 2407 | if (*head) | ||
| 2408 | (*head)->prev = t; | ||
| 2409 | else | ||
| 2410 | *tail = t; | ||
| 2411 | t->next = *head; | ||
| 2412 | *head = h; | ||
| 2413 | } | ||
| 2414 | } | ||
| 2415 | |||
| 2416 | |||
| 2417 | /* Append glyph string S to the list with head *HEAD and tail *TAIL. | ||
| 2418 | Set *HEAD and *TAIL to the resulting list. */ | ||
| 2419 | |||
| 2420 | static INLINE void | ||
| 2421 | x_append_glyph_string (head, tail, s) | ||
| 2422 | struct glyph_string **head, **tail; | ||
| 2423 | struct glyph_string *s; | ||
| 2424 | { | ||
| 2425 | s->next = s->prev = NULL; | ||
| 2426 | x_append_glyph_string_lists (head, tail, s, s); | ||
| 2427 | } | ||
| 2428 | |||
| 2429 | |||
| 2430 | /* Set S->gc to a suitable GC for drawing glyph string S in cursor | 1118 | /* Set S->gc to a suitable GC for drawing glyph string S in cursor |
| 2431 | face. */ | 1119 | face. */ |
| 2432 | 1120 | ||
| @@ -2674,10 +1362,11 @@ x_set_glyph_string_clipping (s) | |||
| 2674 | } | 1362 | } |
| 2675 | 1363 | ||
| 2676 | 1364 | ||
| 2677 | /* Compute left and right overhang of glyph string S. If S is a glyph | 1365 | /* RIF: |
| 1366 | Compute left and right overhang of glyph string S. If S is a glyph | ||
| 2678 | string for a composition, assume overhangs don't exist. */ | 1367 | string for a composition, assume overhangs don't exist. */ |
| 2679 | 1368 | ||
| 2680 | static INLINE void | 1369 | static void |
| 2681 | x_compute_glyph_string_overhangs (s) | 1370 | x_compute_glyph_string_overhangs (s) |
| 2682 | struct glyph_string *s; | 1371 | struct glyph_string *s; |
| 2683 | { | 1372 | { |
| @@ -2694,184 +1383,6 @@ x_compute_glyph_string_overhangs (s) | |||
| 2694 | } | 1383 | } |
| 2695 | 1384 | ||
| 2696 | 1385 | ||
| 2697 | /* Compute overhangs and x-positions for glyph string S and its | ||
| 2698 | predecessors, or successors. X is the starting x-position for S. | ||
| 2699 | BACKWARD_P non-zero means process predecessors. */ | ||
| 2700 | |||
| 2701 | static void | ||
| 2702 | x_compute_overhangs_and_x (s, x, backward_p) | ||
| 2703 | struct glyph_string *s; | ||
| 2704 | int x; | ||
| 2705 | int backward_p; | ||
| 2706 | { | ||
| 2707 | if (backward_p) | ||
| 2708 | { | ||
| 2709 | while (s) | ||
| 2710 | { | ||
| 2711 | x_compute_glyph_string_overhangs (s); | ||
| 2712 | x -= s->width; | ||
| 2713 | s->x = x; | ||
| 2714 | s = s->prev; | ||
| 2715 | } | ||
| 2716 | } | ||
| 2717 | else | ||
| 2718 | { | ||
| 2719 | while (s) | ||
| 2720 | { | ||
| 2721 | x_compute_glyph_string_overhangs (s); | ||
| 2722 | s->x = x; | ||
| 2723 | x += s->width; | ||
| 2724 | s = s->next; | ||
| 2725 | } | ||
| 2726 | } | ||
| 2727 | } | ||
| 2728 | |||
| 2729 | |||
| 2730 | /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on | ||
| 2731 | frame F. Overhangs of glyphs other than type CHAR_GLYPH are | ||
| 2732 | assumed to be zero. */ | ||
| 2733 | |||
| 2734 | static void | ||
| 2735 | x_get_glyph_overhangs (glyph, f, left, right) | ||
| 2736 | struct glyph *glyph; | ||
| 2737 | struct frame *f; | ||
| 2738 | int *left, *right; | ||
| 2739 | { | ||
| 2740 | *left = *right = 0; | ||
| 2741 | |||
| 2742 | if (glyph->type == CHAR_GLYPH) | ||
| 2743 | { | ||
| 2744 | XFontStruct *font; | ||
| 2745 | struct face *face; | ||
| 2746 | struct font_info *font_info; | ||
| 2747 | XChar2b char2b; | ||
| 2748 | XCharStruct *pcm; | ||
| 2749 | |||
| 2750 | face = x_get_glyph_face_and_encoding (f, glyph, &char2b, NULL); | ||
| 2751 | font = face->font; | ||
| 2752 | font_info = FONT_INFO_FROM_ID (f, face->font_info_id); | ||
| 2753 | if (font | ||
| 2754 | && (pcm = x_per_char_metric (font, &char2b))) | ||
| 2755 | { | ||
| 2756 | if (pcm->rbearing > pcm->width) | ||
| 2757 | *right = pcm->rbearing - pcm->width; | ||
| 2758 | if (pcm->lbearing < 0) | ||
| 2759 | *left = -pcm->lbearing; | ||
| 2760 | } | ||
| 2761 | } | ||
| 2762 | } | ||
| 2763 | |||
| 2764 | |||
| 2765 | /* Return the index of the first glyph preceding glyph string S that | ||
| 2766 | is overwritten by S because of S's left overhang. Value is -1 | ||
| 2767 | if no glyphs are overwritten. */ | ||
| 2768 | |||
| 2769 | static int | ||
| 2770 | x_left_overwritten (s) | ||
| 2771 | struct glyph_string *s; | ||
| 2772 | { | ||
| 2773 | int k; | ||
| 2774 | |||
| 2775 | if (s->left_overhang) | ||
| 2776 | { | ||
| 2777 | int x = 0, i; | ||
| 2778 | struct glyph *glyphs = s->row->glyphs[s->area]; | ||
| 2779 | int first = s->first_glyph - glyphs; | ||
| 2780 | |||
| 2781 | for (i = first - 1; i >= 0 && x > -s->left_overhang; --i) | ||
| 2782 | x -= glyphs[i].pixel_width; | ||
| 2783 | |||
| 2784 | k = i + 1; | ||
| 2785 | } | ||
| 2786 | else | ||
| 2787 | k = -1; | ||
| 2788 | |||
| 2789 | return k; | ||
| 2790 | } | ||
| 2791 | |||
| 2792 | |||
| 2793 | /* Return the index of the first glyph preceding glyph string S that | ||
| 2794 | is overwriting S because of its right overhang. Value is -1 if no | ||
| 2795 | glyph in front of S overwrites S. */ | ||
| 2796 | |||
| 2797 | static int | ||
| 2798 | x_left_overwriting (s) | ||
| 2799 | struct glyph_string *s; | ||
| 2800 | { | ||
| 2801 | int i, k, x; | ||
| 2802 | struct glyph *glyphs = s->row->glyphs[s->area]; | ||
| 2803 | int first = s->first_glyph - glyphs; | ||
| 2804 | |||
| 2805 | k = -1; | ||
| 2806 | x = 0; | ||
| 2807 | for (i = first - 1; i >= 0; --i) | ||
| 2808 | { | ||
| 2809 | int left, right; | ||
| 2810 | x_get_glyph_overhangs (glyphs + i, s->f, &left, &right); | ||
| 2811 | if (x + right > 0) | ||
| 2812 | k = i; | ||
| 2813 | x -= glyphs[i].pixel_width; | ||
| 2814 | } | ||
| 2815 | |||
| 2816 | return k; | ||
| 2817 | } | ||
| 2818 | |||
| 2819 | |||
| 2820 | /* Return the index of the last glyph following glyph string S that is | ||
| 2821 | not overwritten by S because of S's right overhang. Value is -1 if | ||
| 2822 | no such glyph is found. */ | ||
| 2823 | |||
| 2824 | static int | ||
| 2825 | x_right_overwritten (s) | ||
| 2826 | struct glyph_string *s; | ||
| 2827 | { | ||
| 2828 | int k = -1; | ||
| 2829 | |||
| 2830 | if (s->right_overhang) | ||
| 2831 | { | ||
| 2832 | int x = 0, i; | ||
| 2833 | struct glyph *glyphs = s->row->glyphs[s->area]; | ||
| 2834 | int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); | ||
| 2835 | int end = s->row->used[s->area]; | ||
| 2836 | |||
| 2837 | for (i = first; i < end && s->right_overhang > x; ++i) | ||
| 2838 | x += glyphs[i].pixel_width; | ||
| 2839 | |||
| 2840 | k = i; | ||
| 2841 | } | ||
| 2842 | |||
| 2843 | return k; | ||
| 2844 | } | ||
| 2845 | |||
| 2846 | |||
| 2847 | /* Return the index of the last glyph following glyph string S that | ||
| 2848 | overwrites S because of its left overhang. Value is negative | ||
| 2849 | if no such glyph is found. */ | ||
| 2850 | |||
| 2851 | static int | ||
| 2852 | x_right_overwriting (s) | ||
| 2853 | struct glyph_string *s; | ||
| 2854 | { | ||
| 2855 | int i, k, x; | ||
| 2856 | int end = s->row->used[s->area]; | ||
| 2857 | struct glyph *glyphs = s->row->glyphs[s->area]; | ||
| 2858 | int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); | ||
| 2859 | |||
| 2860 | k = -1; | ||
| 2861 | x = 0; | ||
| 2862 | for (i = first; i < end; ++i) | ||
| 2863 | { | ||
| 2864 | int left, right; | ||
| 2865 | x_get_glyph_overhangs (glyphs + i, s->f, &left, &right); | ||
| 2866 | if (x - left < 0) | ||
| 2867 | k = i; | ||
| 2868 | x += glyphs[i].pixel_width; | ||
| 2869 | } | ||
| 2870 | |||
| 2871 | return k; | ||
| 2872 | } | ||
| 2873 | |||
| 2874 | |||
| 2875 | /* Fill rectangle X, Y, W, H with background color of glyph string S. */ | 1386 | /* Fill rectangle X, Y, W, H with background color of glyph string S. */ |
| 2876 | 1387 | ||
| 2877 | static INLINE void | 1388 | static INLINE void |
| @@ -4410,663 +2921,6 @@ x_draw_glyph_string (s) | |||
| 4410 | } | 2921 | } |
| 4411 | 2922 | ||
| 4412 | 2923 | ||
| 4413 | static int x_fill_composite_glyph_string P_ ((struct glyph_string *, | ||
| 4414 | struct face **, int)); | ||
| 4415 | |||
| 4416 | |||
| 4417 | /* Fill glyph string S with composition components specified by S->cmp. | ||
| 4418 | |||
| 4419 | FACES is an array of faces for all components of this composition. | ||
| 4420 | S->gidx is the index of the first component for S. | ||
| 4421 | OVERLAPS_P non-zero means S should draw the foreground only, and | ||
| 4422 | use its physical height for clipping. | ||
| 4423 | |||
| 4424 | Value is the index of a component not in S. */ | ||
| 4425 | |||
| 4426 | static int | ||
| 4427 | x_fill_composite_glyph_string (s, faces, overlaps_p) | ||
| 4428 | struct glyph_string *s; | ||
| 4429 | struct face **faces; | ||
| 4430 | int overlaps_p; | ||
| 4431 | { | ||
| 4432 | int i; | ||
| 4433 | |||
| 4434 | xassert (s); | ||
| 4435 | |||
| 4436 | s->for_overlaps_p = overlaps_p; | ||
| 4437 | |||
| 4438 | s->face = faces[s->gidx]; | ||
| 4439 | s->font = s->face->font; | ||
| 4440 | s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | ||
| 4441 | |||
| 4442 | /* For all glyphs of this composition, starting at the offset | ||
| 4443 | S->gidx, until we reach the end of the definition or encounter a | ||
| 4444 | glyph that requires the different face, add it to S. */ | ||
| 4445 | ++s->nchars; | ||
| 4446 | for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i) | ||
| 4447 | ++s->nchars; | ||
| 4448 | |||
| 4449 | /* All glyph strings for the same composition has the same width, | ||
| 4450 | i.e. the width set for the first component of the composition. */ | ||
| 4451 | |||
| 4452 | s->width = s->first_glyph->pixel_width; | ||
| 4453 | |||
| 4454 | /* If the specified font could not be loaded, use the frame's | ||
| 4455 | default font, but record the fact that we couldn't load it in | ||
| 4456 | the glyph string so that we can draw rectangles for the | ||
| 4457 | characters of the glyph string. */ | ||
| 4458 | if (s->font == NULL) | ||
| 4459 | { | ||
| 4460 | s->font_not_found_p = 1; | ||
| 4461 | s->font = FRAME_FONT (s->f); | ||
| 4462 | } | ||
| 4463 | |||
| 4464 | /* Adjust base line for subscript/superscript text. */ | ||
| 4465 | s->ybase += s->first_glyph->voffset; | ||
| 4466 | |||
| 4467 | xassert (s->face && s->face->gc); | ||
| 4468 | |||
| 4469 | /* This glyph string must always be drawn with 16-bit functions. */ | ||
| 4470 | s->two_byte_p = 1; | ||
| 4471 | |||
| 4472 | return s->gidx + s->nchars; | ||
| 4473 | } | ||
| 4474 | |||
| 4475 | |||
| 4476 | /* Fill glyph string S from a sequence of character glyphs. | ||
| 4477 | |||
| 4478 | FACE_ID is the face id of the string. START is the index of the | ||
| 4479 | first glyph to consider, END is the index of the last + 1. | ||
| 4480 | OVERLAPS_P non-zero means S should draw the foreground only, and | ||
| 4481 | use its physical height for clipping. | ||
| 4482 | |||
| 4483 | Value is the index of the first glyph not in S. */ | ||
| 4484 | |||
| 4485 | static int | ||
| 4486 | x_fill_glyph_string (s, face_id, start, end, overlaps_p) | ||
| 4487 | struct glyph_string *s; | ||
| 4488 | int face_id; | ||
| 4489 | int start, end, overlaps_p; | ||
| 4490 | { | ||
| 4491 | struct glyph *glyph, *last; | ||
| 4492 | int voffset; | ||
| 4493 | int glyph_not_available_p; | ||
| 4494 | |||
| 4495 | xassert (s->f == XFRAME (s->w->frame)); | ||
| 4496 | xassert (s->nchars == 0); | ||
| 4497 | xassert (start >= 0 && end > start); | ||
| 4498 | |||
| 4499 | s->for_overlaps_p = overlaps_p, | ||
| 4500 | glyph = s->row->glyphs[s->area] + start; | ||
| 4501 | last = s->row->glyphs[s->area] + end; | ||
| 4502 | voffset = glyph->voffset; | ||
| 4503 | |||
| 4504 | glyph_not_available_p = glyph->glyph_not_available_p; | ||
| 4505 | |||
| 4506 | while (glyph < last | ||
| 4507 | && glyph->type == CHAR_GLYPH | ||
| 4508 | && glyph->voffset == voffset | ||
| 4509 | /* Same face id implies same font, nowadays. */ | ||
| 4510 | && glyph->face_id == face_id | ||
| 4511 | && glyph->glyph_not_available_p == glyph_not_available_p) | ||
| 4512 | { | ||
| 4513 | int two_byte_p; | ||
| 4514 | |||
| 4515 | s->face = x_get_glyph_face_and_encoding (s->f, glyph, | ||
| 4516 | s->char2b + s->nchars, | ||
| 4517 | &two_byte_p); | ||
| 4518 | s->two_byte_p = two_byte_p; | ||
| 4519 | ++s->nchars; | ||
| 4520 | xassert (s->nchars <= end - start); | ||
| 4521 | s->width += glyph->pixel_width; | ||
| 4522 | ++glyph; | ||
| 4523 | } | ||
| 4524 | |||
| 4525 | s->font = s->face->font; | ||
| 4526 | s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | ||
| 4527 | |||
| 4528 | /* If the specified font could not be loaded, use the frame's font, | ||
| 4529 | but record the fact that we couldn't load it in | ||
| 4530 | S->font_not_found_p so that we can draw rectangles for the | ||
| 4531 | characters of the glyph string. */ | ||
| 4532 | if (s->font == NULL || glyph_not_available_p) | ||
| 4533 | { | ||
| 4534 | s->font_not_found_p = 1; | ||
| 4535 | s->font = FRAME_FONT (s->f); | ||
| 4536 | } | ||
| 4537 | |||
| 4538 | /* Adjust base line for subscript/superscript text. */ | ||
| 4539 | s->ybase += voffset; | ||
| 4540 | |||
| 4541 | xassert (s->face && s->face->gc); | ||
| 4542 | return glyph - s->row->glyphs[s->area]; | ||
| 4543 | } | ||
| 4544 | |||
| 4545 | |||
| 4546 | /* Fill glyph string S from image glyph S->first_glyph. */ | ||
| 4547 | |||
| 4548 | static void | ||
| 4549 | x_fill_image_glyph_string (s) | ||
| 4550 | struct glyph_string *s; | ||
| 4551 | { | ||
| 4552 | xassert (s->first_glyph->type == IMAGE_GLYPH); | ||
| 4553 | s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id); | ||
| 4554 | xassert (s->img); | ||
| 4555 | s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id); | ||
| 4556 | s->font = s->face->font; | ||
| 4557 | s->width = s->first_glyph->pixel_width; | ||
| 4558 | |||
| 4559 | /* Adjust base line for subscript/superscript text. */ | ||
| 4560 | s->ybase += s->first_glyph->voffset; | ||
| 4561 | } | ||
| 4562 | |||
| 4563 | |||
| 4564 | /* Fill glyph string S from a sequence of stretch glyphs. | ||
| 4565 | |||
| 4566 | ROW is the glyph row in which the glyphs are found, AREA is the | ||
| 4567 | area within the row. START is the index of the first glyph to | ||
| 4568 | consider, END is the index of the last + 1. | ||
| 4569 | |||
| 4570 | Value is the index of the first glyph not in S. */ | ||
| 4571 | |||
| 4572 | static int | ||
| 4573 | x_fill_stretch_glyph_string (s, row, area, start, end) | ||
| 4574 | struct glyph_string *s; | ||
| 4575 | struct glyph_row *row; | ||
| 4576 | enum glyph_row_area area; | ||
| 4577 | int start, end; | ||
| 4578 | { | ||
| 4579 | struct glyph *glyph, *last; | ||
| 4580 | int voffset, face_id; | ||
| 4581 | |||
| 4582 | xassert (s->first_glyph->type == STRETCH_GLYPH); | ||
| 4583 | |||
| 4584 | glyph = s->row->glyphs[s->area] + start; | ||
| 4585 | last = s->row->glyphs[s->area] + end; | ||
| 4586 | face_id = glyph->face_id; | ||
| 4587 | s->face = FACE_FROM_ID (s->f, face_id); | ||
| 4588 | s->font = s->face->font; | ||
| 4589 | s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | ||
| 4590 | s->width = glyph->pixel_width; | ||
| 4591 | voffset = glyph->voffset; | ||
| 4592 | |||
| 4593 | for (++glyph; | ||
| 4594 | (glyph < last | ||
| 4595 | && glyph->type == STRETCH_GLYPH | ||
| 4596 | && glyph->voffset == voffset | ||
| 4597 | && glyph->face_id == face_id); | ||
| 4598 | ++glyph) | ||
| 4599 | s->width += glyph->pixel_width; | ||
| 4600 | |||
| 4601 | /* Adjust base line for subscript/superscript text. */ | ||
| 4602 | s->ybase += voffset; | ||
| 4603 | |||
| 4604 | /* The case that face->gc == 0 is handled when drawing the glyph | ||
| 4605 | string by calling PREPARE_FACE_FOR_DISPLAY. */ | ||
| 4606 | xassert (s->face); | ||
| 4607 | return glyph - s->row->glyphs[s->area]; | ||
| 4608 | } | ||
| 4609 | |||
| 4610 | |||
| 4611 | /* Initialize glyph string S. CHAR2B is a suitably allocated vector | ||
| 4612 | of XChar2b structures for S; it can't be allocated in | ||
| 4613 | x_init_glyph_string because it must be allocated via `alloca'. W | ||
| 4614 | is the window on which S is drawn. ROW and AREA are the glyph row | ||
| 4615 | and area within the row from which S is constructed. START is the | ||
| 4616 | index of the first glyph structure covered by S. HL is a | ||
| 4617 | face-override for drawing S. */ | ||
| 4618 | |||
| 4619 | static void | ||
| 4620 | x_init_glyph_string (s, char2b, w, row, area, start, hl) | ||
| 4621 | struct glyph_string *s; | ||
| 4622 | XChar2b *char2b; | ||
| 4623 | struct window *w; | ||
| 4624 | struct glyph_row *row; | ||
| 4625 | enum glyph_row_area area; | ||
| 4626 | int start; | ||
| 4627 | enum draw_glyphs_face hl; | ||
| 4628 | { | ||
| 4629 | bzero (s, sizeof *s); | ||
| 4630 | s->w = w; | ||
| 4631 | s->f = XFRAME (w->frame); | ||
| 4632 | s->display = FRAME_X_DISPLAY (s->f); | ||
| 4633 | s->window = FRAME_X_WINDOW (s->f); | ||
| 4634 | s->char2b = char2b; | ||
| 4635 | s->hl = hl; | ||
| 4636 | s->row = row; | ||
| 4637 | s->area = area; | ||
| 4638 | s->first_glyph = row->glyphs[area] + start; | ||
| 4639 | s->height = row->height; | ||
| 4640 | s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); | ||
| 4641 | |||
| 4642 | /* Display the internal border below the tool-bar window. */ | ||
| 4643 | if (s->w == XWINDOW (s->f->tool_bar_window)) | ||
| 4644 | s->y -= s->f->output_data.x->internal_border_width; | ||
| 4645 | |||
| 4646 | s->ybase = s->y + row->ascent; | ||
| 4647 | } | ||
| 4648 | |||
| 4649 | |||
| 4650 | /* Set background width of glyph string S. START is the index of the | ||
| 4651 | first glyph following S. LAST_X is the right-most x-position + 1 | ||
| 4652 | in the drawing area. */ | ||
| 4653 | |||
| 4654 | static INLINE void | ||
| 4655 | x_set_glyph_string_background_width (s, start, last_x) | ||
| 4656 | struct glyph_string *s; | ||
| 4657 | int start; | ||
| 4658 | int last_x; | ||
| 4659 | { | ||
| 4660 | /* If the face of this glyph string has to be drawn to the end of | ||
| 4661 | the drawing area, set S->extends_to_end_of_line_p. */ | ||
| 4662 | struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID); | ||
| 4663 | |||
| 4664 | if (start == s->row->used[s->area] | ||
| 4665 | && s->area == TEXT_AREA | ||
| 4666 | && ((s->hl == DRAW_NORMAL_TEXT | ||
| 4667 | && (s->row->fill_line_p | ||
| 4668 | || s->face->background != default_face->background | ||
| 4669 | || s->face->stipple != default_face->stipple | ||
| 4670 | || s->row->mouse_face_p)) | ||
| 4671 | || s->hl == DRAW_MOUSE_FACE | ||
| 4672 | || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN) | ||
| 4673 | && s->row->fill_line_p))) | ||
| 4674 | s->extends_to_end_of_line_p = 1; | ||
| 4675 | |||
| 4676 | /* If S extends its face to the end of the line, set its | ||
| 4677 | background_width to the distance to the right edge of the drawing | ||
| 4678 | area. */ | ||
| 4679 | if (s->extends_to_end_of_line_p) | ||
| 4680 | s->background_width = last_x - s->x + 1; | ||
| 4681 | else | ||
| 4682 | s->background_width = s->width; | ||
| 4683 | } | ||
| 4684 | |||
| 4685 | |||
| 4686 | /* Add a glyph string for a stretch glyph to the list of strings | ||
| 4687 | between HEAD and TAIL. START is the index of the stretch glyph in | ||
| 4688 | row area AREA of glyph row ROW. END is the index of the last glyph | ||
| 4689 | in that glyph row area. X is the current output position assigned | ||
| 4690 | to the new glyph string constructed. HL overrides that face of the | ||
| 4691 | glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X | ||
| 4692 | is the right-most x-position of the drawing area. */ | ||
| 4693 | |||
| 4694 | /* SunOS 4 bundled cc, barfed on continuations in the arg lists here | ||
| 4695 | and below -- keep them on one line. */ | ||
| 4696 | #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \ | ||
| 4697 | do \ | ||
| 4698 | { \ | ||
| 4699 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 4700 | x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \ | ||
| 4701 | START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \ | ||
| 4702 | x_append_glyph_string (&HEAD, &TAIL, s); \ | ||
| 4703 | s->x = (X); \ | ||
| 4704 | } \ | ||
| 4705 | while (0) | ||
| 4706 | |||
| 4707 | |||
| 4708 | /* Add a glyph string for an image glyph to the list of strings | ||
| 4709 | between HEAD and TAIL. START is the index of the image glyph in | ||
| 4710 | row area AREA of glyph row ROW. END is the index of the last glyph | ||
| 4711 | in that glyph row area. X is the current output position assigned | ||
| 4712 | to the new glyph string constructed. HL overrides that face of the | ||
| 4713 | glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X | ||
| 4714 | is the right-most x-position of the drawing area. */ | ||
| 4715 | |||
| 4716 | #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \ | ||
| 4717 | do \ | ||
| 4718 | { \ | ||
| 4719 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 4720 | x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \ | ||
| 4721 | x_fill_image_glyph_string (s); \ | ||
| 4722 | x_append_glyph_string (&HEAD, &TAIL, s); \ | ||
| 4723 | ++START; \ | ||
| 4724 | s->x = (X); \ | ||
| 4725 | } \ | ||
| 4726 | while (0) | ||
| 4727 | |||
| 4728 | |||
| 4729 | /* Add a glyph string for a sequence of character glyphs to the list | ||
| 4730 | of strings between HEAD and TAIL. START is the index of the first | ||
| 4731 | glyph in row area AREA of glyph row ROW that is part of the new | ||
| 4732 | glyph string. END is the index of the last glyph in that glyph row | ||
| 4733 | area. X is the current output position assigned to the new glyph | ||
| 4734 | string constructed. HL overrides that face of the glyph; e.g. it | ||
| 4735 | is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the | ||
| 4736 | right-most x-position of the drawing area. */ | ||
| 4737 | |||
| 4738 | #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \ | ||
| 4739 | do \ | ||
| 4740 | { \ | ||
| 4741 | int c, face_id; \ | ||
| 4742 | XChar2b *char2b; \ | ||
| 4743 | \ | ||
| 4744 | c = (ROW)->glyphs[AREA][START].u.ch; \ | ||
| 4745 | face_id = (ROW)->glyphs[AREA][START].face_id; \ | ||
| 4746 | \ | ||
| 4747 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 4748 | char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \ | ||
| 4749 | x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \ | ||
| 4750 | x_append_glyph_string (&HEAD, &TAIL, s); \ | ||
| 4751 | s->x = (X); \ | ||
| 4752 | START = x_fill_glyph_string (s, face_id, START, END, \ | ||
| 4753 | OVERLAPS_P); \ | ||
| 4754 | } \ | ||
| 4755 | while (0) | ||
| 4756 | |||
| 4757 | |||
| 4758 | /* Add a glyph string for a composite sequence to the list of strings | ||
| 4759 | between HEAD and TAIL. START is the index of the first glyph in | ||
| 4760 | row area AREA of glyph row ROW that is part of the new glyph | ||
| 4761 | string. END is the index of the last glyph in that glyph row area. | ||
| 4762 | X is the current output position assigned to the new glyph string | ||
| 4763 | constructed. HL overrides that face of the glyph; e.g. it is | ||
| 4764 | DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most | ||
| 4765 | x-position of the drawing area. */ | ||
| 4766 | |||
| 4767 | #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \ | ||
| 4768 | do { \ | ||
| 4769 | int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \ | ||
| 4770 | int face_id = (ROW)->glyphs[AREA][START].face_id; \ | ||
| 4771 | struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \ | ||
| 4772 | struct composition *cmp = composition_table[cmp_id]; \ | ||
| 4773 | int glyph_len = cmp->glyph_len; \ | ||
| 4774 | XChar2b *char2b; \ | ||
| 4775 | struct face **faces; \ | ||
| 4776 | struct glyph_string *first_s = NULL; \ | ||
| 4777 | int n; \ | ||
| 4778 | \ | ||
| 4779 | base_face = base_face->ascii_face; \ | ||
| 4780 | char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \ | ||
| 4781 | faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \ | ||
| 4782 | /* At first, fill in `char2b' and `faces'. */ \ | ||
| 4783 | for (n = 0; n < glyph_len; n++) \ | ||
| 4784 | { \ | ||
| 4785 | int c = COMPOSITION_GLYPH (cmp, n); \ | ||
| 4786 | int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \ | ||
| 4787 | faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \ | ||
| 4788 | x_get_char_face_and_encoding (XFRAME (w->frame), c, \ | ||
| 4789 | this_face_id, char2b + n, 1, 1); \ | ||
| 4790 | } \ | ||
| 4791 | \ | ||
| 4792 | /* Make glyph_strings for each glyph sequence that is drawable by \ | ||
| 4793 | the same face, and append them to HEAD/TAIL. */ \ | ||
| 4794 | for (n = 0; n < cmp->glyph_len;) \ | ||
| 4795 | { \ | ||
| 4796 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 4797 | x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \ | ||
| 4798 | x_append_glyph_string (&(HEAD), &(TAIL), s); \ | ||
| 4799 | s->cmp = cmp; \ | ||
| 4800 | s->gidx = n; \ | ||
| 4801 | s->x = (X); \ | ||
| 4802 | \ | ||
| 4803 | if (n == 0) \ | ||
| 4804 | first_s = s; \ | ||
| 4805 | \ | ||
| 4806 | n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \ | ||
| 4807 | } \ | ||
| 4808 | \ | ||
| 4809 | ++START; \ | ||
| 4810 | s = first_s; \ | ||
| 4811 | } while (0) | ||
| 4812 | |||
| 4813 | |||
| 4814 | /* Build a list of glyph strings between HEAD and TAIL for the glyphs | ||
| 4815 | of AREA of glyph row ROW on window W between indices START and END. | ||
| 4816 | HL overrides the face for drawing glyph strings, e.g. it is | ||
| 4817 | DRAW_CURSOR to draw a cursor. X and LAST_X are start and end | ||
| 4818 | x-positions of the drawing area. | ||
| 4819 | |||
| 4820 | This is an ugly monster macro construct because we must use alloca | ||
| 4821 | to allocate glyph strings (because x_draw_glyphs can be called | ||
| 4822 | asynchronously). */ | ||
| 4823 | |||
| 4824 | #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \ | ||
| 4825 | do \ | ||
| 4826 | { \ | ||
| 4827 | HEAD = TAIL = NULL; \ | ||
| 4828 | while (START < END) \ | ||
| 4829 | { \ | ||
| 4830 | struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \ | ||
| 4831 | switch (first_glyph->type) \ | ||
| 4832 | { \ | ||
| 4833 | case CHAR_GLYPH: \ | ||
| 4834 | BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \ | ||
| 4835 | TAIL, HL, X, LAST_X, \ | ||
| 4836 | OVERLAPS_P); \ | ||
| 4837 | break; \ | ||
| 4838 | \ | ||
| 4839 | case COMPOSITE_GLYPH: \ | ||
| 4840 | BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \ | ||
| 4841 | HEAD, TAIL, HL, X, LAST_X,\ | ||
| 4842 | OVERLAPS_P); \ | ||
| 4843 | break; \ | ||
| 4844 | \ | ||
| 4845 | case STRETCH_GLYPH: \ | ||
| 4846 | BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \ | ||
| 4847 | HEAD, TAIL, HL, X, LAST_X); \ | ||
| 4848 | break; \ | ||
| 4849 | \ | ||
| 4850 | case IMAGE_GLYPH: \ | ||
| 4851 | BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \ | ||
| 4852 | TAIL, HL, X, LAST_X); \ | ||
| 4853 | break; \ | ||
| 4854 | \ | ||
| 4855 | default: \ | ||
| 4856 | abort (); \ | ||
| 4857 | } \ | ||
| 4858 | \ | ||
| 4859 | x_set_glyph_string_background_width (s, START, LAST_X); \ | ||
| 4860 | (X) += s->width; \ | ||
| 4861 | } \ | ||
| 4862 | } \ | ||
| 4863 | while (0) | ||
| 4864 | |||
| 4865 | |||
| 4866 | /* Draw glyphs between START and END in AREA of ROW on window W, | ||
| 4867 | starting at x-position X. X is relative to AREA in W. HL is a | ||
| 4868 | face-override with the following meaning: | ||
| 4869 | |||
| 4870 | DRAW_NORMAL_TEXT draw normally | ||
| 4871 | DRAW_CURSOR draw in cursor face | ||
| 4872 | DRAW_MOUSE_FACE draw in mouse face. | ||
| 4873 | DRAW_INVERSE_VIDEO draw in mode line face | ||
| 4874 | DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it | ||
| 4875 | DRAW_IMAGE_RAISED draw an image with a raised relief around it | ||
| 4876 | |||
| 4877 | If OVERLAPS_P is non-zero, draw only the foreground of characters | ||
| 4878 | and clip to the physical height of ROW. | ||
| 4879 | |||
| 4880 | Value is the x-position reached, relative to AREA of W. */ | ||
| 4881 | |||
| 4882 | static int | ||
| 4883 | x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p) | ||
| 4884 | struct window *w; | ||
| 4885 | int x; | ||
| 4886 | struct glyph_row *row; | ||
| 4887 | enum glyph_row_area area; | ||
| 4888 | int start, end; | ||
| 4889 | enum draw_glyphs_face hl; | ||
| 4890 | int overlaps_p; | ||
| 4891 | { | ||
| 4892 | struct glyph_string *head, *tail; | ||
| 4893 | struct glyph_string *s; | ||
| 4894 | int last_x, area_width; | ||
| 4895 | int x_reached; | ||
| 4896 | int i, j; | ||
| 4897 | |||
| 4898 | /* Let's rather be paranoid than getting a SEGV. */ | ||
| 4899 | end = min (end, row->used[area]); | ||
| 4900 | start = max (0, start); | ||
| 4901 | start = min (end, start); | ||
| 4902 | |||
| 4903 | /* Translate X to frame coordinates. Set last_x to the right | ||
| 4904 | end of the drawing area. */ | ||
| 4905 | if (row->full_width_p) | ||
| 4906 | { | ||
| 4907 | /* X is relative to the left edge of W, without scroll bars | ||
| 4908 | or fringes. */ | ||
| 4909 | struct frame *f = XFRAME (w->frame); | ||
| 4910 | int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f); | ||
| 4911 | |||
| 4912 | x += window_left_x; | ||
| 4913 | area_width = XFASTINT (w->width) * CANON_X_UNIT (f); | ||
| 4914 | last_x = window_left_x + area_width; | ||
| 4915 | |||
| 4916 | if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)) | ||
| 4917 | { | ||
| 4918 | int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f); | ||
| 4919 | if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) | ||
| 4920 | last_x += width; | ||
| 4921 | else | ||
| 4922 | x -= width; | ||
| 4923 | } | ||
| 4924 | |||
| 4925 | x += FRAME_INTERNAL_BORDER_WIDTH (f); | ||
| 4926 | last_x += FRAME_INTERNAL_BORDER_WIDTH (f); | ||
| 4927 | } | ||
| 4928 | else | ||
| 4929 | { | ||
| 4930 | x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x); | ||
| 4931 | area_width = window_box_width (w, area); | ||
| 4932 | last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width); | ||
| 4933 | } | ||
| 4934 | |||
| 4935 | /* Build a doubly-linked list of glyph_string structures between | ||
| 4936 | head and tail from what we have to draw. Note that the macro | ||
| 4937 | BUILD_GLYPH_STRINGS will modify its start parameter. That's | ||
| 4938 | the reason we use a separate variable `i'. */ | ||
| 4939 | i = start; | ||
| 4940 | BUILD_GLYPH_STRINGS (w, row, area, i, end, head, tail, hl, x, last_x, | ||
| 4941 | overlaps_p); | ||
| 4942 | if (tail) | ||
| 4943 | x_reached = tail->x + tail->background_width; | ||
| 4944 | else | ||
| 4945 | x_reached = x; | ||
| 4946 | |||
| 4947 | /* If there are any glyphs with lbearing < 0 or rbearing > width in | ||
| 4948 | the row, redraw some glyphs in front or following the glyph | ||
| 4949 | strings built above. */ | ||
| 4950 | if (head && !overlaps_p && row->contains_overlapping_glyphs_p) | ||
| 4951 | { | ||
| 4952 | int dummy_x = 0; | ||
| 4953 | struct glyph_string *h, *t; | ||
| 4954 | |||
| 4955 | /* Compute overhangs for all glyph strings. */ | ||
| 4956 | for (s = head; s; s = s->next) | ||
| 4957 | x_compute_glyph_string_overhangs (s); | ||
| 4958 | |||
| 4959 | /* Prepend glyph strings for glyphs in front of the first glyph | ||
| 4960 | string that are overwritten because of the first glyph | ||
| 4961 | string's left overhang. The background of all strings | ||
| 4962 | prepended must be drawn because the first glyph string | ||
| 4963 | draws over it. */ | ||
| 4964 | i = x_left_overwritten (head); | ||
| 4965 | if (i >= 0) | ||
| 4966 | { | ||
| 4967 | j = i; | ||
| 4968 | BUILD_GLYPH_STRINGS (w, row, area, j, start, h, t, | ||
| 4969 | DRAW_NORMAL_TEXT, dummy_x, last_x, | ||
| 4970 | overlaps_p); | ||
| 4971 | start = i; | ||
| 4972 | x_compute_overhangs_and_x (t, head->x, 1); | ||
| 4973 | x_prepend_glyph_string_lists (&head, &tail, h, t); | ||
| 4974 | } | ||
| 4975 | |||
| 4976 | /* Prepend glyph strings for glyphs in front of the first glyph | ||
| 4977 | string that overwrite that glyph string because of their | ||
| 4978 | right overhang. For these strings, only the foreground must | ||
| 4979 | be drawn, because it draws over the glyph string at `head'. | ||
| 4980 | The background must not be drawn because this would overwrite | ||
| 4981 | right overhangs of preceding glyphs for which no glyph | ||
| 4982 | strings exist. */ | ||
| 4983 | i = x_left_overwriting (head); | ||
| 4984 | if (i >= 0) | ||
| 4985 | { | ||
| 4986 | BUILD_GLYPH_STRINGS (w, row, area, i, start, h, t, | ||
| 4987 | DRAW_NORMAL_TEXT, dummy_x, last_x, | ||
| 4988 | overlaps_p); | ||
| 4989 | for (s = h; s; s = s->next) | ||
| 4990 | s->background_filled_p = 1; | ||
| 4991 | x_compute_overhangs_and_x (t, head->x, 1); | ||
| 4992 | x_prepend_glyph_string_lists (&head, &tail, h, t); | ||
| 4993 | } | ||
| 4994 | |||
| 4995 | /* Append glyphs strings for glyphs following the last glyph | ||
| 4996 | string tail that are overwritten by tail. The background of | ||
| 4997 | these strings has to be drawn because tail's foreground draws | ||
| 4998 | over it. */ | ||
| 4999 | i = x_right_overwritten (tail); | ||
| 5000 | if (i >= 0) | ||
| 5001 | { | ||
| 5002 | BUILD_GLYPH_STRINGS (w, row, area, end, i, h, t, | ||
| 5003 | DRAW_NORMAL_TEXT, x, last_x, | ||
| 5004 | overlaps_p); | ||
| 5005 | x_compute_overhangs_and_x (h, tail->x + tail->width, 0); | ||
| 5006 | x_append_glyph_string_lists (&head, &tail, h, t); | ||
| 5007 | } | ||
| 5008 | |||
| 5009 | /* Append glyph strings for glyphs following the last glyph | ||
| 5010 | string tail that overwrite tail. The foreground of such | ||
| 5011 | glyphs has to be drawn because it writes into the background | ||
| 5012 | of tail. The background must not be drawn because it could | ||
| 5013 | paint over the foreground of following glyphs. */ | ||
| 5014 | i = x_right_overwriting (tail); | ||
| 5015 | if (i >= 0) | ||
| 5016 | { | ||
| 5017 | BUILD_GLYPH_STRINGS (w, row, area, end, i, h, t, | ||
| 5018 | DRAW_NORMAL_TEXT, x, last_x, | ||
| 5019 | overlaps_p); | ||
| 5020 | for (s = h; s; s = s->next) | ||
| 5021 | s->background_filled_p = 1; | ||
| 5022 | x_compute_overhangs_and_x (h, tail->x + tail->width, 0); | ||
| 5023 | x_append_glyph_string_lists (&head, &tail, h, t); | ||
| 5024 | } | ||
| 5025 | } | ||
| 5026 | |||
| 5027 | /* Draw all strings. */ | ||
| 5028 | for (s = head; s; s = s->next) | ||
| 5029 | x_draw_glyph_string (s); | ||
| 5030 | |||
| 5031 | if (area == TEXT_AREA | ||
| 5032 | && !row->full_width_p | ||
| 5033 | /* When drawing overlapping rows, only the glyph strings' | ||
| 5034 | foreground is drawn, which doesn't erase a cursor | ||
| 5035 | completely. */ | ||
| 5036 | && !overlaps_p) | ||
| 5037 | { | ||
| 5038 | int x0 = head ? head->x : x; | ||
| 5039 | int x1 = tail ? tail->x + tail->background_width : x; | ||
| 5040 | |||
| 5041 | x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0); | ||
| 5042 | x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1); | ||
| 5043 | |||
| 5044 | if (XFASTINT (w->left_margin_width) != 0) | ||
| 5045 | { | ||
| 5046 | int left_area_width = window_box_width (w, LEFT_MARGIN_AREA); | ||
| 5047 | x0 -= left_area_width; | ||
| 5048 | x1 -= left_area_width; | ||
| 5049 | } | ||
| 5050 | |||
| 5051 | notice_overwritten_cursor (w, area, x0, x1, | ||
| 5052 | row->y, MATRIX_ROW_BOTTOM_Y (row)); | ||
| 5053 | } | ||
| 5054 | |||
| 5055 | /* Value is the x-position up to which drawn, relative to AREA of W. | ||
| 5056 | This doesn't include parts drawn because of overhangs. */ | ||
| 5057 | x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached); | ||
| 5058 | if (!row->full_width_p) | ||
| 5059 | { | ||
| 5060 | if (area > LEFT_MARGIN_AREA && XFASTINT (w->left_margin_width) != 0) | ||
| 5061 | x_reached -= window_box_width (w, LEFT_MARGIN_AREA); | ||
| 5062 | if (area > TEXT_AREA) | ||
| 5063 | x_reached -= window_box_width (w, TEXT_AREA); | ||
| 5064 | } | ||
| 5065 | |||
| 5066 | return x_reached; | ||
| 5067 | } | ||
| 5068 | |||
| 5069 | |||
| 5070 | /* Fix the display of area AREA of overlapping row ROW in window W. */ | 2924 | /* Fix the display of area AREA of overlapping row ROW in window W. */ |
| 5071 | 2925 | ||
| 5072 | static void | 2926 | static void |
| @@ -11553,52 +9407,6 @@ XTread_socket (sd, bufp, numchars, expected) | |||
| 11553 | Text Cursor | 9407 | Text Cursor |
| 11554 | ***********************************************************************/ | 9408 | ***********************************************************************/ |
| 11555 | 9409 | ||
| 11556 | /* Notice when the text cursor of window W has been completely | ||
| 11557 | overwritten by a drawing operation that outputs glyphs in AREA | ||
| 11558 | starting at X0 and ending at X1 in the line starting at Y0 and | ||
| 11559 | ending at Y1. X coordinates are area-relative. X1 < 0 means all | ||
| 11560 | the rest of the line after X0 has been written. Y coordinates | ||
| 11561 | are window-relative. */ | ||
| 11562 | |||
| 11563 | static void | ||
| 11564 | notice_overwritten_cursor (w, area, x0, x1, y0, y1) | ||
| 11565 | struct window *w; | ||
| 11566 | enum glyph_row_area area; | ||
| 11567 | int x0, y0, x1, y1; | ||
| 11568 | { | ||
| 11569 | if (area == TEXT_AREA && w->phys_cursor_on_p) | ||
| 11570 | { | ||
| 11571 | int cx0 = w->phys_cursor.x; | ||
| 11572 | int cx1 = cx0 + w->phys_cursor_width; | ||
| 11573 | int cy0 = w->phys_cursor.y; | ||
| 11574 | int cy1 = cy0 + w->phys_cursor_height; | ||
| 11575 | |||
| 11576 | if (x0 <= cx0 && (x1 < 0 || x1 >= cx1)) | ||
| 11577 | { | ||
| 11578 | /* The cursor image will be completely removed from the | ||
| 11579 | screen if the output area intersects the cursor area in | ||
| 11580 | y-direction. When we draw in [y0 y1[, and some part of | ||
| 11581 | the cursor is at y < y0, that part must have been drawn | ||
| 11582 | before. When scrolling, the cursor is erased before | ||
| 11583 | actually scrolling, so we don't come here. When not | ||
| 11584 | scrolling, the rows above the old cursor row must have | ||
| 11585 | changed, and in this case these rows must have written | ||
| 11586 | over the cursor image. | ||
| 11587 | |||
| 11588 | Likewise if part of the cursor is below y1, with the | ||
| 11589 | exception of the cursor being in the first blank row at | ||
| 11590 | the buffer and window end because update_text_area | ||
| 11591 | doesn't draw that row. (Except when it does, but | ||
| 11592 | that's handled in update_text_area.) */ | ||
| 11593 | |||
| 11594 | if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1)) | ||
| 11595 | && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p) | ||
| 11596 | w->phys_cursor_on_p = 0; | ||
| 11597 | } | ||
| 11598 | } | ||
| 11599 | } | ||
| 11600 | |||
| 11601 | |||
| 11602 | /* Set clipping for output in glyph row ROW. W is the window in which | 9410 | /* Set clipping for output in glyph row ROW. W is the window in which |
| 11603 | we operate. GC is the graphics context to set clipping in. | 9411 | we operate. GC is the graphics context to set clipping in. |
| 11604 | WHOLE_LINE_P non-zero means include the areas used for truncation | 9412 | WHOLE_LINE_P non-zero means include the areas used for truncation |
| @@ -15363,7 +13171,11 @@ static struct redisplay_interface x_redisplay_interface = | |||
| 15363 | x_clear_mouse_face, | 13171 | x_clear_mouse_face, |
| 15364 | x_get_glyph_overhangs, | 13172 | x_get_glyph_overhangs, |
| 15365 | x_fix_overlapping_area, | 13173 | x_fix_overlapping_area, |
| 15366 | x_draw_fringe_bitmap | 13174 | x_draw_fringe_bitmap, |
| 13175 | x_per_char_metric, | ||
| 13176 | x_encode_char, | ||
| 13177 | x_compute_glyph_string_overhangs, | ||
| 13178 | x_draw_glyph_string | ||
| 15367 | }; | 13179 | }; |
| 15368 | 13180 | ||
| 15369 | void | 13181 | void |