Mercurial > emacs
comparison src/xterm.c @ 50151:0e12b5894d99
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.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Sun, 16 Mar 2003 20:46:42 +0000 |
parents | 66a7f2850b56 |
children | 297925dd73b1 |
comparison
equal
deleted
inserted
replaced
50150:288ffa39e234 | 50151:0e12b5894d99 |
---|---|
330 static Lisp_Object Qlatin_1, Qutf_8; | 330 static Lisp_Object Qlatin_1, Qutf_8; |
331 | 331 |
332 extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *)); | 332 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 | |
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 | 335 |
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 *)); |
352 static void x_set_window_size_1 P_ ((struct frame *, int, int, int)); | 339 static void x_set_window_size_1 P_ ((struct frame *, int, int, int)); |
431 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int)); | 418 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int)); |
432 | 419 |
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 *, |
448 Lisp_Object *, Lisp_Object *, | 432 Lisp_Object *, Lisp_Object *, |
449 unsigned long *)); | 433 unsigned long *)); |
921 Display Iterator | 905 Display Iterator |
922 ***********************************************************************/ | 906 ***********************************************************************/ |
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; |
953 | 924 |
954 xassert (font && char2b); | 925 xassert (font && char2b); |
1012 | 983 |
1013 | 984 |
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; |
1025 | 997 |
1026 /* FONT_INFO may define a scheme by which to encode byte1 and byte2. | 998 /* FONT_INFO may define a scheme by which to encode byte1 and byte2. |
1064 char2b->byte1 |= 0x80; | 1036 char2b->byte1 |= 0x80; |
1065 | 1037 |
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 | 1044 |
1155 if (!glyph->multibyte_p) | 1045 return FONT_TYPE_UNKNOWN; |
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 | |
1840 if (it->glyph_row) | |
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 |
2136 /* Estimate the pixel height of the mode or top line on frame F. | 1049 /* Estimate the pixel height of the mode or top line on frame F. |
2137 FACE_ID specifies what line's height to estimate. */ | 1050 FACE_ID specifies what line's height to estimate. */ |
2163 | 1076 |
2164 /*********************************************************************** | 1077 /*********************************************************************** |
2165 Glyph display | 1078 Glyph display |
2166 ***********************************************************************/ | 1079 ***********************************************************************/ |
2167 | 1080 |
2168 /* A sequence of glyphs to be drawn in the same face. | 1081 |
2169 | 1082 |
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 | |
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 | |
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 *, |
2337 int)); | 1086 int)); |
2338 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *)); | 1087 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *)); |
2341 static void x_draw_glyph_string P_ ((struct glyph_string *)); | 1090 static void x_draw_glyph_string P_ ((struct glyph_string *)); |
2342 static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *)); | 1091 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 *, |
2352 double, int, unsigned long)); | 1098 double, int, unsigned long)); |
2353 static void x_setup_relief_colors P_ ((struct glyph_string *)); | 1099 static void x_setup_relief_colors P_ ((struct glyph_string *)); |
2354 static void x_draw_image_glyph_string P_ ((struct glyph_string *)); | 1100 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, |
2362 int, int, int, int, XRectangle *)); | 1107 int, int, int, int, XRectangle *)); |
2363 static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, | 1108 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 | |
2375 | |
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 | 1116 |
2429 | 1117 |
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 |
2672 x_get_glyph_string_clip_rect (s, &r); | 1360 x_get_glyph_string_clip_rect (s, &r); |
2673 XSetClipRectangles (s->display, s->gc, 0, 0, &r, 1, Unsorted); | 1361 XSetClipRectangles (s->display, s->gc, 0, 0, &r, 1, Unsorted); |
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 { |
2684 if (s->cmp == NULL | 1373 if (s->cmp == NULL |
2685 && s->first_glyph->type == CHAR_GLYPH) | 1374 && s->first_glyph->type == CHAR_GLYPH) |
2689 XTextExtents16 (s->font, s->char2b, s->nchars, &direction, | 1378 XTextExtents16 (s->font, s->char2b, s->nchars, &direction, |
2690 &font_ascent, &font_descent, &cs); | 1379 &font_ascent, &font_descent, &cs); |
2691 s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0; | 1380 s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0; |
2692 s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0; | 1381 s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0; |
2693 } | 1382 } |
2694 } | |
2695 | |
2696 | |
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 } | 1383 } |
2873 | 1384 |
2874 | 1385 |
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 |
4405 x_draw_glyph_string_box (s); | 2916 x_draw_glyph_string_box (s); |
4406 } | 2917 } |
4407 | 2918 |
4408 /* Reset clipping. */ | 2919 /* Reset clipping. */ |
4409 XSetClipMask (s->display, s->gc, None); | 2920 XSetClipMask (s->display, s->gc, None); |
4410 } | |
4411 | |
4412 | |
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 } | 2921 } |
5068 | 2922 |
5069 | 2923 |
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 |
11551 | 9405 |
11552 /*********************************************************************** | 9406 /*********************************************************************** |
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 |
11605 mark display and alike in the clipping rectangle. | 9413 mark display and alike in the clipping rectangle. |
11606 | 9414 |
15361 XTcursor_to, | 13169 XTcursor_to, |
15362 x_flush, | 13170 x_flush, |
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 |
15370 x_initialize () | 13182 x_initialize () |
15371 { | 13183 { |