diff options
| author | Kim F. Storm | 2003-03-16 20:47:48 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2003-03-16 20:47:48 +0000 |
| commit | 6b6bd7266c28aae460bb6c2fcadc8759c4b1107c (patch) | |
| tree | 0af5bdb85b81496b54abd48f51059c011c8061cb /src | |
| parent | e83074af107fdf9d471fe131d592492e97471f45 (diff) | |
| download | emacs-6b6bd7266c28aae460bb6c2fcadc8759c4b1107c.tar.gz emacs-6b6bd7266c28aae460bb6c2fcadc8759c4b1107c.zip | |
Remove consolidated defines and code.
(BUILD_WCHAR_T, BYTE1, BYTE2): Macros removed; callers changed
to use STORE_XCHAR2B, XCHAR2B_BYTE1, XCHAR2B_BYTE2 instead.
(w32_per_char_metric): Change font_type arg to int for RIF.
(w32_encode_char): Return int according to RIF requirements.
(w32_compute_glyph_string_overhangs): Adapt to RIF.
(w32_get_glyph_overhangs): New function for RIF. Uses generic
x_get_glyph_overhangs.
(w32_redisplay_interface): Add new members.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32term.c | 2299 |
1 files changed, 34 insertions, 2265 deletions
diff --git a/src/w32term.c b/src/w32term.c index b5b919fa31f..fd0e85bb747 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -260,19 +260,6 @@ extern int errno; | |||
| 260 | 260 | ||
| 261 | extern EMACS_INT extra_keyboard_modifiers; | 261 | extern EMACS_INT extra_keyboard_modifiers; |
| 262 | 262 | ||
| 263 | /* Enumeration for overriding/changing the face to use for drawing | ||
| 264 | glyphs in x_draw_glyphs. */ | ||
| 265 | |||
| 266 | enum draw_glyphs_face | ||
| 267 | { | ||
| 268 | DRAW_NORMAL_TEXT, | ||
| 269 | DRAW_INVERSE_VIDEO, | ||
| 270 | DRAW_CURSOR, | ||
| 271 | DRAW_MOUSE_FACE, | ||
| 272 | DRAW_IMAGE_RAISED, | ||
| 273 | DRAW_IMAGE_SUNKEN | ||
| 274 | }; | ||
| 275 | |||
| 276 | static void x_update_window_end P_ ((struct window *, int, int)); | 263 | static void x_update_window_end P_ ((struct window *, int, int)); |
| 277 | static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); | 264 | static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); |
| 278 | void w32_delete_display P_ ((struct w32_display_info *)); | 265 | void w32_delete_display P_ ((struct w32_display_info *)); |
| @@ -344,9 +331,6 @@ void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int)); | |||
| 344 | static void w32_clip_to_row P_ ((struct window *, struct glyph_row *, | 331 | static void w32_clip_to_row P_ ((struct window *, struct glyph_row *, |
| 345 | HDC, int)); | 332 | HDC, int)); |
| 346 | static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *)); | 333 | static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *)); |
| 347 | static void notice_overwritten_cursor P_ ((struct window *, | ||
| 348 | enum glyph_row_area, | ||
| 349 | int, int, int, int)); | ||
| 350 | 334 | ||
| 351 | static Lisp_Object Qvendor_specific_keysyms; | 335 | static Lisp_Object Qvendor_specific_keysyms; |
| 352 | 336 | ||
| @@ -897,35 +881,9 @@ w32_cursor_to (vpos, hpos, y, x) | |||
| 897 | 881 | ||
| 898 | /* Function prototypes of this page. */ | 882 | /* Function prototypes of this page. */ |
| 899 | 883 | ||
| 900 | static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *, | ||
| 901 | struct glyph *, | ||
| 902 | wchar_t *, | ||
| 903 | int *)); | ||
| 904 | static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int, | ||
| 905 | int, wchar_t *, int)); | ||
| 906 | static XCharStruct *w32_per_char_metric P_ ((XFontStruct *, | 884 | static XCharStruct *w32_per_char_metric P_ ((XFontStruct *, |
| 907 | wchar_t *, | 885 | wchar_t *, int)); |
| 908 | enum w32_char_font_type)); | 886 | static int w32_encode_char P_ ((int, wchar_t *, struct font_info *, int *)); |
| 909 | static enum w32_char_font_type | ||
| 910 | w32_encode_char P_ ((int, wchar_t *, struct font_info *, int *)); | ||
| 911 | static void x_append_glyph P_ ((struct it *)); | ||
| 912 | static void x_append_composite_glyph P_ ((struct it *)); | ||
| 913 | static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object, | ||
| 914 | int, int, double)); | ||
| 915 | static void x_produce_glyphs P_ ((struct it *)); | ||
| 916 | static void x_produce_image_glyph P_ ((struct it *it)); | ||
| 917 | |||
| 918 | |||
| 919 | /* Dealing with bits of wchar_t as if they were an XChar2B. */ | ||
| 920 | #define BUILD_WCHAR_T(byte1, byte2) \ | ||
| 921 | ((wchar_t)((((byte1) & 0x00ff) << 8) | ((byte2) & 0x00ff))) | ||
| 922 | |||
| 923 | |||
| 924 | #define BYTE1(ch) \ | ||
| 925 | (((ch) & 0xff00) >> 8) | ||
| 926 | |||
| 927 | #define BYTE2(ch) \ | ||
| 928 | ((ch) & 0x00ff) | ||
| 929 | 887 | ||
| 930 | 888 | ||
| 931 | /* Get metrics of character CHAR2B in FONT. Value is always non-null. | 889 | /* Get metrics of character CHAR2B in FONT. Value is always non-null. |
| @@ -946,8 +904,8 @@ w32_bdf_per_char_metric (font, char2b, dim, pcm) | |||
| 946 | buf[0] = (char)(*char2b); | 904 | buf[0] = (char)(*char2b); |
| 947 | else | 905 | else |
| 948 | { | 906 | { |
| 949 | buf[0] = BYTE1 (*char2b); | 907 | buf[0] = XCHAR2B_BYTE1 (char2b); |
| 950 | buf[1] = BYTE2 (*char2b); | 908 | buf[1] = XCHAR2B_BYTE2 (char2b); |
| 951 | } | 909 | } |
| 952 | 910 | ||
| 953 | bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim); | 911 | bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim); |
| @@ -1065,7 +1023,7 @@ static XCharStruct * | |||
| 1065 | w32_per_char_metric (font, char2b, font_type) | 1023 | w32_per_char_metric (font, char2b, font_type) |
| 1066 | XFontStruct *font; | 1024 | XFontStruct *font; |
| 1067 | wchar_t *char2b; | 1025 | wchar_t *char2b; |
| 1068 | enum w32_char_font_type font_type; | 1026 | int /* enum w32_char_font_type */ font_type; |
| 1069 | { | 1027 | { |
| 1070 | /* The result metric information. */ | 1028 | /* The result metric information. */ |
| 1071 | XCharStruct *pcm; | 1029 | XCharStruct *pcm; |
| @@ -1166,7 +1124,7 @@ w32_use_unicode_for_codepage (codepage) | |||
| 1166 | /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is | 1124 | /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is |
| 1167 | the two-byte form of C. Encoding is returned in *CHAR2B. */ | 1125 | the two-byte form of C. Encoding is returned in *CHAR2B. */ |
| 1168 | 1126 | ||
| 1169 | static INLINE enum w32_char_font_type | 1127 | static int /* enum w32_char_font_type */ |
| 1170 | w32_encode_char (c, char2b, font_info, two_byte_p) | 1128 | w32_encode_char (c, char2b, font_info, two_byte_p) |
| 1171 | int c; | 1129 | int c; |
| 1172 | wchar_t *char2b; | 1130 | wchar_t *char2b; |
| @@ -1181,7 +1139,8 @@ w32_encode_char (c, char2b, font_info, two_byte_p) | |||
| 1181 | 1139 | ||
| 1182 | xassert (two_byte_p); | 1140 | xassert (two_byte_p); |
| 1183 | 1141 | ||
| 1184 | *two_byte_p = w32_font_is_double_byte (font); | 1142 | if (two_byte_p) |
| 1143 | *two_byte_p = w32_font_is_double_byte (font); | ||
| 1185 | 1144 | ||
| 1186 | /* FONT_INFO may define a scheme by which to encode byte1 and byte2. | 1145 | /* FONT_INFO may define a scheme by which to encode byte1 and byte2. |
| 1187 | This may be either a program in a special encoder language or a | 1146 | This may be either a program in a special encoder language or a |
| @@ -1194,14 +1153,14 @@ w32_encode_char (c, char2b, font_info, two_byte_p) | |||
| 1194 | if (CHARSET_DIMENSION (charset) == 1) | 1153 | if (CHARSET_DIMENSION (charset) == 1) |
| 1195 | { | 1154 | { |
| 1196 | ccl->reg[0] = charset; | 1155 | ccl->reg[0] = charset; |
| 1197 | ccl->reg[1] = BYTE2 (*char2b); | 1156 | ccl->reg[1] = XCHAR2B_BYTE2 (char2b); |
| 1198 | ccl->reg[2] = -1; | 1157 | ccl->reg[2] = -1; |
| 1199 | } | 1158 | } |
| 1200 | else | 1159 | else |
| 1201 | { | 1160 | { |
| 1202 | ccl->reg[0] = charset; | 1161 | ccl->reg[0] = charset; |
| 1203 | ccl->reg[1] = BYTE1 (*char2b); | 1162 | ccl->reg[1] = XCHAR2B_BYTE1 (char2b); |
| 1204 | ccl->reg[2] = BYTE2 (*char2b); | 1163 | ccl->reg[2] = XCHAR2B_BYTE2 (char2b); |
| 1205 | } | 1164 | } |
| 1206 | 1165 | ||
| 1207 | ccl_driver (ccl, NULL, NULL, 0, 0, NULL); | 1166 | ccl_driver (ccl, NULL, NULL, 0, 0, NULL); |
| @@ -1209,9 +1168,9 @@ w32_encode_char (c, char2b, font_info, two_byte_p) | |||
| 1209 | /* We assume that MSBs are appropriately set/reset by CCL | 1168 | /* We assume that MSBs are appropriately set/reset by CCL |
| 1210 | program. */ | 1169 | program. */ |
| 1211 | if (!*two_byte_p) /* 1-byte font */ | 1170 | if (!*two_byte_p) /* 1-byte font */ |
| 1212 | *char2b = BUILD_WCHAR_T (0, ccl->reg[1]); | 1171 | STORE_XCHAR2B (char2b, 0, ccl->reg[1]); |
| 1213 | else | 1172 | else |
| 1214 | *char2b = BUILD_WCHAR_T (ccl->reg[1], ccl->reg[2]); | 1173 | STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]); |
| 1215 | } | 1174 | } |
| 1216 | else if (font_info->encoding[charset]) | 1175 | else if (font_info->encoding[charset]) |
| 1217 | { | 1176 | { |
| @@ -1221,18 +1180,18 @@ w32_encode_char (c, char2b, font_info, two_byte_p) | |||
| 1221 | 1180 | ||
| 1222 | if ((enc == 1 || enc == 2) | 1181 | if ((enc == 1 || enc == 2) |
| 1223 | && CHARSET_DIMENSION (charset) == 2) | 1182 | && CHARSET_DIMENSION (charset) == 2) |
| 1224 | *char2b = BUILD_WCHAR_T (BYTE1 (*char2b) | 0x80, BYTE2 (*char2b)); | 1183 | STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b) | 0x80, XCHAR2B_BYTE2 (char2b)); |
| 1225 | 1184 | ||
| 1226 | if (enc == 1 || enc == 3 | 1185 | if (enc == 1 || enc == 3 |
| 1227 | || (enc == 4 && CHARSET_DIMENSION (charset) == 1)) | 1186 | || (enc == 4 && CHARSET_DIMENSION (charset) == 1)) |
| 1228 | *char2b = BUILD_WCHAR_T (BYTE1 (*char2b), BYTE2 (*char2b) | 0x80); | 1187 | STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b), XCHAR2B_BYTE2 (char2b) | 0x80); |
| 1229 | else if (enc == 4) | 1188 | else if (enc == 4) |
| 1230 | { | 1189 | { |
| 1231 | int sjis1, sjis2; | 1190 | int sjis1, sjis2; |
| 1232 | 1191 | ||
| 1233 | ENCODE_SJIS (BYTE1 (*char2b), BYTE2 (*char2b), | 1192 | ENCODE_SJIS (XCHAR2B_BYTE1 (char2b), XCHAR2B_BYTE2 (char2b), |
| 1234 | sjis1, sjis2); | 1193 | sjis1, sjis2); |
| 1235 | *char2b = BUILD_WCHAR_T (sjis1, sjis2); | 1194 | STORE_XCHAR2B (char2b, sjis1, sjis2); |
| 1236 | } | 1195 | } |
| 1237 | } | 1196 | } |
| 1238 | codepage = font_info->codepage; | 1197 | codepage = font_info->codepage; |
| @@ -1244,8 +1203,8 @@ w32_encode_char (c, char2b, font_info, two_byte_p) | |||
| 1244 | && charset != CHARSET_8_BIT_CONTROL && charset != CHARSET_8_BIT_GRAPHIC) | 1203 | && charset != CHARSET_8_BIT_CONTROL && charset != CHARSET_8_BIT_GRAPHIC) |
| 1245 | { | 1204 | { |
| 1246 | char temp[3]; | 1205 | char temp[3]; |
| 1247 | temp[0] = BYTE1 (*char2b); | 1206 | temp[0] = XCHAR2B_BYTE1 (char2b); |
| 1248 | temp[1] = BYTE2 (*char2b); | 1207 | temp[1] = XCHAR2B_BYTE2 (char2b); |
| 1249 | temp[2] = '\0'; | 1208 | temp[2] = '\0'; |
| 1250 | if (codepage != CP_UNICODE) | 1209 | if (codepage != CP_UNICODE) |
| 1251 | { | 1210 | { |
| @@ -1270,1091 +1229,6 @@ w32_encode_char (c, char2b, font_info, two_byte_p) | |||
| 1270 | } | 1229 | } |
| 1271 | 1230 | ||
| 1272 | 1231 | ||
| 1273 | /* Get face and two-byte form of character C in face FACE_ID on frame | ||
| 1274 | F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero | ||
| 1275 | means we want to display multibyte text. Value is a pointer to a | ||
| 1276 | realized face that is ready for display. */ | ||
| 1277 | |||
| 1278 | static INLINE struct face * | ||
| 1279 | x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p) | ||
| 1280 | struct frame *f; | ||
| 1281 | int c, face_id; | ||
| 1282 | wchar_t *char2b; | ||
| 1283 | int multibyte_p; | ||
| 1284 | { | ||
| 1285 | struct face *face = FACE_FROM_ID (f, face_id); | ||
| 1286 | |||
| 1287 | if (!multibyte_p) | ||
| 1288 | { | ||
| 1289 | /* Unibyte case. We don't have to encode, but we have to make | ||
| 1290 | sure to use a face suitable for unibyte. */ | ||
| 1291 | *char2b = BUILD_WCHAR_T (0, c); | ||
| 1292 | face_id = FACE_FOR_CHAR (f, face, c); | ||
| 1293 | face = FACE_FROM_ID (f, face_id); | ||
| 1294 | } | ||
| 1295 | else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL) | ||
| 1296 | { | ||
| 1297 | /* Case of ASCII in a face known to fit ASCII. */ | ||
| 1298 | *char2b = BUILD_WCHAR_T (0, c); | ||
| 1299 | } | ||
| 1300 | else | ||
| 1301 | { | ||
| 1302 | int c1, c2, charset; | ||
| 1303 | |||
| 1304 | /* Split characters into bytes. If c2 is -1 afterwards, C is | ||
| 1305 | really a one-byte character so that byte1 is zero. */ | ||
| 1306 | SPLIT_CHAR (c, charset, c1, c2); | ||
| 1307 | if (c2 > 0) | ||
| 1308 | *char2b = BUILD_WCHAR_T (c1, c2); | ||
| 1309 | else | ||
| 1310 | *char2b = BUILD_WCHAR_T (0, c1); | ||
| 1311 | |||
| 1312 | /* Maybe encode the character in *CHAR2B. */ | ||
| 1313 | if (face->font != NULL) | ||
| 1314 | { | ||
| 1315 | struct font_info *font_info | ||
| 1316 | = FONT_INFO_FROM_ID (f, face->font_info_id); | ||
| 1317 | if (font_info) | ||
| 1318 | w32_encode_char (c, char2b, font_info, &multibyte_p); | ||
| 1319 | } | ||
| 1320 | } | ||
| 1321 | |||
| 1322 | /* Make sure X resources of the face are allocated. */ | ||
| 1323 | xassert (face != NULL); | ||
| 1324 | PREPARE_FACE_FOR_DISPLAY (f, face); | ||
| 1325 | |||
| 1326 | return face; | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | |||
| 1330 | /* Get face and two-byte form of character glyph GLYPH on frame F. | ||
| 1331 | The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is | ||
| 1332 | a pointer to a realized face that is ready for display. */ | ||
| 1333 | |||
| 1334 | static INLINE struct face * | ||
| 1335 | x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p) | ||
| 1336 | struct frame *f; | ||
| 1337 | struct glyph *glyph; | ||
| 1338 | wchar_t *char2b; | ||
| 1339 | int *two_byte_p; | ||
| 1340 | { | ||
| 1341 | struct face *face; | ||
| 1342 | int dummy = 0; | ||
| 1343 | |||
| 1344 | xassert (glyph->type == CHAR_GLYPH); | ||
| 1345 | face = FACE_FROM_ID (f, glyph->face_id); | ||
| 1346 | |||
| 1347 | if (two_byte_p) | ||
| 1348 | *two_byte_p = 0; | ||
| 1349 | else | ||
| 1350 | two_byte_p = &dummy; | ||
| 1351 | |||
| 1352 | if (!glyph->multibyte_p) | ||
| 1353 | { | ||
| 1354 | /* Unibyte case. We don't have to encode, but we have to make | ||
| 1355 | sure to use a face suitable for unibyte. */ | ||
| 1356 | *char2b = BUILD_WCHAR_T (0, glyph->u.ch); | ||
| 1357 | } | ||
| 1358 | else if (glyph->u.ch < 128 | ||
| 1359 | && glyph->face_id < BASIC_FACE_ID_SENTINEL) | ||
| 1360 | { | ||
| 1361 | /* Case of ASCII in a face known to fit ASCII. */ | ||
| 1362 | *char2b = BUILD_WCHAR_T (0, glyph->u.ch); | ||
| 1363 | } | ||
| 1364 | else | ||
| 1365 | { | ||
| 1366 | int c1, c2, charset; | ||
| 1367 | |||
| 1368 | /* Split characters into bytes. If c2 is -1 afterwards, C is | ||
| 1369 | really a one-byte character so that byte1 is zero. */ | ||
| 1370 | SPLIT_CHAR (glyph->u.ch, charset, c1, c2); | ||
| 1371 | if (c2 > 0) | ||
| 1372 | *char2b = BUILD_WCHAR_T (c1, c2); | ||
| 1373 | else | ||
| 1374 | *char2b = BUILD_WCHAR_T (0, c1); | ||
| 1375 | |||
| 1376 | /* Maybe encode the character in *CHAR2B. */ | ||
| 1377 | if (charset != CHARSET_ASCII) | ||
| 1378 | { | ||
| 1379 | struct font_info *font_info | ||
| 1380 | = FONT_INFO_FROM_ID (f, face->font_info_id); | ||
| 1381 | if (font_info) | ||
| 1382 | { | ||
| 1383 | glyph->w32_font_type | ||
| 1384 | = w32_encode_char (glyph->u.ch, char2b, font_info, two_byte_p); | ||
| 1385 | } | ||
| 1386 | } | ||
| 1387 | } | ||
| 1388 | |||
| 1389 | /* Make sure X resources of the face are allocated. */ | ||
| 1390 | xassert (face != NULL); | ||
| 1391 | PREPARE_FACE_FOR_DISPLAY (f, face); | ||
| 1392 | return face; | ||
| 1393 | } | ||
| 1394 | |||
| 1395 | |||
| 1396 | /* Store one glyph for IT->char_to_display in IT->glyph_row. | ||
| 1397 | Called from x_produce_glyphs when IT->glyph_row is non-null. */ | ||
| 1398 | |||
| 1399 | static INLINE void | ||
| 1400 | x_append_glyph (it) | ||
| 1401 | struct it *it; | ||
| 1402 | { | ||
| 1403 | struct glyph *glyph; | ||
| 1404 | enum glyph_row_area area = it->area; | ||
| 1405 | |||
| 1406 | xassert (it->glyph_row); | ||
| 1407 | xassert (it->char_to_display != '\n' && it->char_to_display != '\t'); | ||
| 1408 | |||
| 1409 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 1410 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 1411 | { | ||
| 1412 | glyph->charpos = CHARPOS (it->position); | ||
| 1413 | glyph->object = it->object; | ||
| 1414 | glyph->pixel_width = it->pixel_width; | ||
| 1415 | glyph->voffset = it->voffset; | ||
| 1416 | glyph->type = CHAR_GLYPH; | ||
| 1417 | glyph->multibyte_p = it->multibyte_p; | ||
| 1418 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 1419 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 1420 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | ||
| 1421 | || it->phys_descent > it->descent); | ||
| 1422 | glyph->padding_p = 0; | ||
| 1423 | glyph->glyph_not_available_p = it->glyph_not_available_p; | ||
| 1424 | glyph->face_id = it->face_id; | ||
| 1425 | glyph->u.ch = it->char_to_display; | ||
| 1426 | glyph->w32_font_type = UNKNOWN_FONT; | ||
| 1427 | ++it->glyph_row->used[area]; | ||
| 1428 | } | ||
| 1429 | } | ||
| 1430 | |||
| 1431 | /* Store one glyph for the composition IT->cmp_id in IT->glyph_row. | ||
| 1432 | Called from x_produce_glyphs when IT->glyph_row is non-null. */ | ||
| 1433 | |||
| 1434 | static INLINE void | ||
| 1435 | x_append_composite_glyph (it) | ||
| 1436 | struct it *it; | ||
| 1437 | { | ||
| 1438 | struct glyph *glyph; | ||
| 1439 | enum glyph_row_area area = it->area; | ||
| 1440 | |||
| 1441 | xassert (it->glyph_row); | ||
| 1442 | |||
| 1443 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 1444 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 1445 | { | ||
| 1446 | glyph->charpos = CHARPOS (it->position); | ||
| 1447 | glyph->object = it->object; | ||
| 1448 | glyph->pixel_width = it->pixel_width; | ||
| 1449 | glyph->voffset = it->voffset; | ||
| 1450 | glyph->type = COMPOSITE_GLYPH; | ||
| 1451 | glyph->multibyte_p = it->multibyte_p; | ||
| 1452 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 1453 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 1454 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | ||
| 1455 | || it->phys_descent > it->descent); | ||
| 1456 | glyph->padding_p = 0; | ||
| 1457 | glyph->glyph_not_available_p = 0; | ||
| 1458 | glyph->face_id = it->face_id; | ||
| 1459 | glyph->u.cmp_id = it->cmp_id; | ||
| 1460 | glyph->w32_font_type = UNKNOWN_FONT; | ||
| 1461 | ++it->glyph_row->used[area]; | ||
| 1462 | } | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | |||
| 1466 | /* Change IT->ascent and IT->height according to the setting of | ||
| 1467 | IT->voffset. */ | ||
| 1468 | |||
| 1469 | static INLINE void | ||
| 1470 | take_vertical_position_into_account (it) | ||
| 1471 | struct it *it; | ||
| 1472 | { | ||
| 1473 | if (it->voffset) | ||
| 1474 | { | ||
| 1475 | if (it->voffset < 0) | ||
| 1476 | /* Increase the ascent so that we can display the text higher | ||
| 1477 | in the line. */ | ||
| 1478 | it->ascent += abs (it->voffset); | ||
| 1479 | else | ||
| 1480 | /* Increase the descent so that we can display the text lower | ||
| 1481 | in the line. */ | ||
| 1482 | it->descent += it->voffset; | ||
| 1483 | } | ||
| 1484 | } | ||
| 1485 | |||
| 1486 | |||
| 1487 | /* Produce glyphs/get display metrics for the image IT is loaded with. | ||
| 1488 | See the description of struct display_iterator in dispextern.h for | ||
| 1489 | an overview of struct display_iterator. */ | ||
| 1490 | |||
| 1491 | static void | ||
| 1492 | x_produce_image_glyph (it) | ||
| 1493 | struct it *it; | ||
| 1494 | { | ||
| 1495 | struct image *img; | ||
| 1496 | struct face *face; | ||
| 1497 | |||
| 1498 | xassert (it->what == IT_IMAGE); | ||
| 1499 | |||
| 1500 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1501 | img = IMAGE_FROM_ID (it->f, it->image_id); | ||
| 1502 | xassert (img); | ||
| 1503 | |||
| 1504 | /* Make sure X resources of the face and image are loaded. */ | ||
| 1505 | PREPARE_FACE_FOR_DISPLAY (it->f, face); | ||
| 1506 | prepare_image_for_display (it->f, img); | ||
| 1507 | |||
| 1508 | it->ascent = it->phys_ascent = image_ascent (img, face); | ||
| 1509 | it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent; | ||
| 1510 | it->pixel_width = img->width + 2 * img->hmargin; | ||
| 1511 | |||
| 1512 | it->nglyphs = 1; | ||
| 1513 | |||
| 1514 | if (face->box != FACE_NO_BOX) | ||
| 1515 | { | ||
| 1516 | if (face->box_line_width > 0) | ||
| 1517 | { | ||
| 1518 | it->ascent += face->box_line_width; | ||
| 1519 | it->descent += face->box_line_width; | ||
| 1520 | } | ||
| 1521 | |||
| 1522 | if (it->start_of_box_run_p) | ||
| 1523 | it->pixel_width += abs (face->box_line_width); | ||
| 1524 | if (it->end_of_box_run_p) | ||
| 1525 | it->pixel_width += abs (face->box_line_width); | ||
| 1526 | } | ||
| 1527 | |||
| 1528 | take_vertical_position_into_account (it); | ||
| 1529 | |||
| 1530 | if (it->glyph_row) | ||
| 1531 | { | ||
| 1532 | struct glyph *glyph; | ||
| 1533 | enum glyph_row_area area = it->area; | ||
| 1534 | |||
| 1535 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 1536 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 1537 | { | ||
| 1538 | glyph->charpos = CHARPOS (it->position); | ||
| 1539 | glyph->object = it->object; | ||
| 1540 | glyph->pixel_width = it->pixel_width; | ||
| 1541 | glyph->voffset = it->voffset; | ||
| 1542 | glyph->type = IMAGE_GLYPH; | ||
| 1543 | glyph->multibyte_p = it->multibyte_p; | ||
| 1544 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 1545 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 1546 | glyph->overlaps_vertically_p = 0; | ||
| 1547 | glyph->padding_p = 0; | ||
| 1548 | glyph->glyph_not_available_p = 0; | ||
| 1549 | glyph->face_id = it->face_id; | ||
| 1550 | glyph->u.img_id = img->id; | ||
| 1551 | glyph->w32_font_type = UNKNOWN_FONT; | ||
| 1552 | ++it->glyph_row->used[area]; | ||
| 1553 | } | ||
| 1554 | } | ||
| 1555 | } | ||
| 1556 | |||
| 1557 | |||
| 1558 | /* Append a stretch glyph to IT->glyph_row. OBJECT is the source | ||
| 1559 | of the glyph, WIDTH and HEIGHT are the width and height of the | ||
| 1560 | stretch. ASCENT is the percentage/100 of HEIGHT to use for the | ||
| 1561 | ascent of the glyph (0 <= ASCENT <= 1). */ | ||
| 1562 | |||
| 1563 | static void | ||
| 1564 | x_append_stretch_glyph (it, object, width, height, ascent) | ||
| 1565 | struct it *it; | ||
| 1566 | Lisp_Object object; | ||
| 1567 | int width, height; | ||
| 1568 | double ascent; | ||
| 1569 | { | ||
| 1570 | struct glyph *glyph; | ||
| 1571 | enum glyph_row_area area = it->area; | ||
| 1572 | |||
| 1573 | xassert (ascent >= 0 && ascent <= 1); | ||
| 1574 | |||
| 1575 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 1576 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 1577 | { | ||
| 1578 | glyph->charpos = CHARPOS (it->position); | ||
| 1579 | glyph->object = object; | ||
| 1580 | glyph->pixel_width = width; | ||
| 1581 | glyph->voffset = it->voffset; | ||
| 1582 | glyph->type = STRETCH_GLYPH; | ||
| 1583 | glyph->multibyte_p = it->multibyte_p; | ||
| 1584 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 1585 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 1586 | glyph->overlaps_vertically_p = 0; | ||
| 1587 | glyph->padding_p = 0; | ||
| 1588 | glyph->glyph_not_available_p = 0; | ||
| 1589 | glyph->face_id = it->face_id; | ||
| 1590 | glyph->u.stretch.ascent = height * ascent; | ||
| 1591 | glyph->u.stretch.height = height; | ||
| 1592 | glyph->w32_font_type = UNKNOWN_FONT; | ||
| 1593 | ++it->glyph_row->used[area]; | ||
| 1594 | } | ||
| 1595 | } | ||
| 1596 | |||
| 1597 | |||
| 1598 | /* Produce a stretch glyph for iterator IT. IT->object is the value | ||
| 1599 | of the glyph property displayed. The value must be a list | ||
| 1600 | `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs | ||
| 1601 | being recognized: | ||
| 1602 | |||
| 1603 | 1. `:width WIDTH' specifies that the space should be WIDTH * | ||
| 1604 | canonical char width wide. WIDTH may be an integer or floating | ||
| 1605 | point number. | ||
| 1606 | |||
| 1607 | 2. `:relative-width FACTOR' specifies that the width of the stretch | ||
| 1608 | should be computed from the width of the first character having the | ||
| 1609 | `glyph' property, and should be FACTOR times that width. | ||
| 1610 | |||
| 1611 | 3. `:align-to HPOS' specifies that the space should be wide enough | ||
| 1612 | to reach HPOS, a value in canonical character units. | ||
| 1613 | |||
| 1614 | Exactly one of the above pairs must be present. | ||
| 1615 | |||
| 1616 | 4. `:height HEIGHT' specifies that the height of the stretch produced | ||
| 1617 | should be HEIGHT, measured in canonical character units. | ||
| 1618 | |||
| 1619 | 5. `:relative-height FACTOR' specifies that the height of the | ||
| 1620 | stretch should be FACTOR times the height of the characters having | ||
| 1621 | the glyph property. | ||
| 1622 | |||
| 1623 | Either none or exactly one of 4 or 5 must be present. | ||
| 1624 | |||
| 1625 | 6. `:ascent ASCENT' specifies that ASCENT percent of the height | ||
| 1626 | of the stretch should be used for the ascent of the stretch. | ||
| 1627 | ASCENT must be in the range 0 <= ASCENT <= 100. */ | ||
| 1628 | |||
| 1629 | #define NUMVAL(X) \ | ||
| 1630 | ((INTEGERP (X) || FLOATP (X)) \ | ||
| 1631 | ? XFLOATINT (X) \ | ||
| 1632 | : - 1) | ||
| 1633 | |||
| 1634 | |||
| 1635 | static void | ||
| 1636 | x_produce_stretch_glyph (it) | ||
| 1637 | struct it *it; | ||
| 1638 | { | ||
| 1639 | /* (space :width WIDTH :height HEIGHT. */ | ||
| 1640 | #if GLYPH_DEBUG | ||
| 1641 | extern Lisp_Object Qspace; | ||
| 1642 | #endif | ||
| 1643 | extern Lisp_Object QCwidth, QCheight, QCascent; | ||
| 1644 | extern Lisp_Object QCrelative_width, QCrelative_height; | ||
| 1645 | extern Lisp_Object QCalign_to; | ||
| 1646 | Lisp_Object prop, plist; | ||
| 1647 | double width = 0, height = 0, ascent = 0; | ||
| 1648 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1649 | XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f); | ||
| 1650 | |||
| 1651 | PREPARE_FACE_FOR_DISPLAY (it->f, face); | ||
| 1652 | |||
| 1653 | /* List should start with `space'. */ | ||
| 1654 | xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace)); | ||
| 1655 | plist = XCDR (it->object); | ||
| 1656 | |||
| 1657 | /* Compute the width of the stretch. */ | ||
| 1658 | if (prop = Fplist_get (plist, QCwidth), | ||
| 1659 | NUMVAL (prop) > 0) | ||
| 1660 | /* Absolute width `:width WIDTH' specified and valid. */ | ||
| 1661 | width = NUMVAL (prop) * CANON_X_UNIT (it->f); | ||
| 1662 | else if (prop = Fplist_get (plist, QCrelative_width), | ||
| 1663 | NUMVAL (prop) > 0) | ||
| 1664 | { | ||
| 1665 | /* Relative width `:relative-width FACTOR' specified and valid. | ||
| 1666 | Compute the width of the characters having the `glyph' | ||
| 1667 | property. */ | ||
| 1668 | struct it it2; | ||
| 1669 | unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); | ||
| 1670 | |||
| 1671 | it2 = *it; | ||
| 1672 | if (it->multibyte_p) | ||
| 1673 | { | ||
| 1674 | int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT) | ||
| 1675 | - IT_BYTEPOS (*it)); | ||
| 1676 | it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len); | ||
| 1677 | } | ||
| 1678 | else | ||
| 1679 | it2.c = *p, it2.len = 1; | ||
| 1680 | |||
| 1681 | it2.glyph_row = NULL; | ||
| 1682 | it2.what = IT_CHARACTER; | ||
| 1683 | x_produce_glyphs (&it2); | ||
| 1684 | width = NUMVAL (prop) * it2.pixel_width; | ||
| 1685 | } | ||
| 1686 | else if (prop = Fplist_get (plist, QCalign_to), | ||
| 1687 | NUMVAL (prop) > 0) | ||
| 1688 | width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x; | ||
| 1689 | else | ||
| 1690 | /* Nothing specified -> width defaults to canonical char width. */ | ||
| 1691 | width = CANON_X_UNIT (it->f); | ||
| 1692 | |||
| 1693 | /* Compute height. */ | ||
| 1694 | if (prop = Fplist_get (plist, QCheight), | ||
| 1695 | NUMVAL (prop) > 0) | ||
| 1696 | height = NUMVAL (prop) * CANON_Y_UNIT (it->f); | ||
| 1697 | else if (prop = Fplist_get (plist, QCrelative_height), | ||
| 1698 | NUMVAL (prop) > 0) | ||
| 1699 | height = FONT_HEIGHT (font) * NUMVAL (prop); | ||
| 1700 | else | ||
| 1701 | height = FONT_HEIGHT (font); | ||
| 1702 | |||
| 1703 | /* Compute percentage of height used for ascent. If | ||
| 1704 | `:ascent ASCENT' is present and valid, use that. Otherwise, | ||
| 1705 | derive the ascent from the font in use. */ | ||
| 1706 | if (prop = Fplist_get (plist, QCascent), | ||
| 1707 | NUMVAL (prop) > 0 && NUMVAL (prop) <= 100) | ||
| 1708 | ascent = NUMVAL (prop) / 100.0; | ||
| 1709 | else | ||
| 1710 | ascent = (double) FONT_BASE (font) / FONT_HEIGHT (font); | ||
| 1711 | |||
| 1712 | if (width <= 0) | ||
| 1713 | width = 1; | ||
| 1714 | if (height <= 0) | ||
| 1715 | height = 1; | ||
| 1716 | |||
| 1717 | if (it->glyph_row) | ||
| 1718 | { | ||
| 1719 | Lisp_Object object = it->stack[it->sp - 1].string; | ||
| 1720 | if (!STRINGP (object)) | ||
| 1721 | object = it->w->buffer; | ||
| 1722 | x_append_stretch_glyph (it, object, width, height, ascent); | ||
| 1723 | } | ||
| 1724 | |||
| 1725 | it->pixel_width = width; | ||
| 1726 | it->ascent = it->phys_ascent = height * ascent; | ||
| 1727 | it->descent = it->phys_descent = height - it->ascent; | ||
| 1728 | it->nglyphs = 1; | ||
| 1729 | |||
| 1730 | if (face->box != FACE_NO_BOX) | ||
| 1731 | { | ||
| 1732 | if (face->box_line_width > 0) | ||
| 1733 | { | ||
| 1734 | it->ascent += face->box_line_width; | ||
| 1735 | it->descent += face->box_line_width; | ||
| 1736 | } | ||
| 1737 | |||
| 1738 | if (it->start_of_box_run_p) | ||
| 1739 | it->pixel_width += abs (face->box_line_width); | ||
| 1740 | if (it->end_of_box_run_p) | ||
| 1741 | it->pixel_width += abs (face->box_line_width); | ||
| 1742 | } | ||
| 1743 | |||
| 1744 | take_vertical_position_into_account (it); | ||
| 1745 | } | ||
| 1746 | |||
| 1747 | /* Return proper value to be used as baseline offset of font that has | ||
| 1748 | ASCENT and DESCENT to draw characters by the font at the vertical | ||
| 1749 | center of the line of frame F. | ||
| 1750 | |||
| 1751 | Here, out task is to find the value of BOFF in the following figure; | ||
| 1752 | |||
| 1753 | -------------------------+-----------+- | ||
| 1754 | -+-+---------+-+ | | | ||
| 1755 | | | | | | | | ||
| 1756 | | | | | F_ASCENT F_HEIGHT | ||
| 1757 | | | | ASCENT | | | ||
| 1758 | HEIGHT | | | | | | ||
| 1759 | | | |-|-+------+-----------|------- baseline | ||
| 1760 | | | | | BOFF | | | ||
| 1761 | | |---------|-+-+ | | | ||
| 1762 | | | | DESCENT | | | ||
| 1763 | -+-+---------+-+ F_DESCENT | | ||
| 1764 | -------------------------+-----------+- | ||
| 1765 | |||
| 1766 | -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT | ||
| 1767 | BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT | ||
| 1768 | DESCENT = FONT->descent | ||
| 1769 | HEIGHT = FONT_HEIGHT (FONT) | ||
| 1770 | F_DESCENT = (F->output_data.x->font->descent | ||
| 1771 | - F->output_data.x->baseline_offset) | ||
| 1772 | F_HEIGHT = FRAME_LINE_HEIGHT (F) | ||
| 1773 | */ | ||
| 1774 | |||
| 1775 | #define VCENTER_BASELINE_OFFSET(FONT, F) \ | ||
| 1776 | (FONT_DESCENT (FONT) \ | ||
| 1777 | + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \ | ||
| 1778 | + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \ | ||
| 1779 | - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F))) | ||
| 1780 | |||
| 1781 | /* Produce glyphs/get display metrics for the display element IT is | ||
| 1782 | loaded with. See the description of struct display_iterator in | ||
| 1783 | dispextern.h for an overview of struct display_iterator. */ | ||
| 1784 | |||
| 1785 | static void | ||
| 1786 | x_produce_glyphs (it) | ||
| 1787 | struct it *it; | ||
| 1788 | { | ||
| 1789 | it->glyph_not_available_p = 0; | ||
| 1790 | |||
| 1791 | if (it->what == IT_CHARACTER) | ||
| 1792 | { | ||
| 1793 | wchar_t char2b; | ||
| 1794 | XFontStruct *font; | ||
| 1795 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1796 | XCharStruct *pcm; | ||
| 1797 | int font_not_found_p; | ||
| 1798 | struct font_info *font_info; | ||
| 1799 | int boff; /* baseline offset */ | ||
| 1800 | /* We may change it->multibyte_p upon unibyte<->multibyte | ||
| 1801 | conversion. So, save the current value now and restore it | ||
| 1802 | later. | ||
| 1803 | |||
| 1804 | Note: It seems that we don't have to record multibyte_p in | ||
| 1805 | struct glyph because the character code itself tells if or | ||
| 1806 | not the character is multibyte. Thus, in the future, we must | ||
| 1807 | consider eliminating the field `multibyte_p' in the struct | ||
| 1808 | glyph. | ||
| 1809 | */ | ||
| 1810 | int saved_multibyte_p = it->multibyte_p; | ||
| 1811 | |||
| 1812 | /* Maybe translate single-byte characters to multibyte, or the | ||
| 1813 | other way. */ | ||
| 1814 | it->char_to_display = it->c; | ||
| 1815 | if (!ASCII_BYTE_P (it->c)) | ||
| 1816 | { | ||
| 1817 | if (unibyte_display_via_language_environment | ||
| 1818 | && SINGLE_BYTE_CHAR_P (it->c) | ||
| 1819 | && (it->c >= 0240 | ||
| 1820 | || !NILP (Vnonascii_translation_table))) | ||
| 1821 | { | ||
| 1822 | it->char_to_display = unibyte_char_to_multibyte (it->c); | ||
| 1823 | it->multibyte_p = 1; | ||
| 1824 | it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | ||
| 1825 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1826 | } | ||
| 1827 | else if (!SINGLE_BYTE_CHAR_P (it->c) | ||
| 1828 | && !it->multibyte_p) | ||
| 1829 | { | ||
| 1830 | it->multibyte_p = 1; | ||
| 1831 | it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | ||
| 1832 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1833 | } | ||
| 1834 | } | ||
| 1835 | |||
| 1836 | /* Get font to use. Encode IT->char_to_display. */ | ||
| 1837 | x_get_char_face_and_encoding (it->f, it->char_to_display, | ||
| 1838 | it->face_id, &char2b, | ||
| 1839 | it->multibyte_p); | ||
| 1840 | font = face->font; | ||
| 1841 | |||
| 1842 | /* When no suitable font found, use the default font. */ | ||
| 1843 | font_not_found_p = font == NULL; | ||
| 1844 | if (font_not_found_p) | ||
| 1845 | { | ||
| 1846 | font = FRAME_FONT (it->f); | ||
| 1847 | boff = it->f->output_data.w32->baseline_offset; | ||
| 1848 | font_info = NULL; | ||
| 1849 | } | ||
| 1850 | else | ||
| 1851 | { | ||
| 1852 | font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id); | ||
| 1853 | boff = font_info->baseline_offset; | ||
| 1854 | if (font_info->vertical_centering) | ||
| 1855 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | ||
| 1856 | } | ||
| 1857 | |||
| 1858 | if (it->char_to_display >= ' ' | ||
| 1859 | && (!it->multibyte_p || it->char_to_display < 128)) | ||
| 1860 | { | ||
| 1861 | /* Either unibyte or ASCII. */ | ||
| 1862 | int stretched_p; | ||
| 1863 | |||
| 1864 | it->nglyphs = 1; | ||
| 1865 | |||
| 1866 | pcm = w32_per_char_metric (font, &char2b, | ||
| 1867 | font->bdf ? BDF_1D_FONT : ANSI_FONT); | ||
| 1868 | it->ascent = FONT_BASE (font) + boff; | ||
| 1869 | it->descent = FONT_DESCENT (font) - boff; | ||
| 1870 | |||
| 1871 | if (pcm) | ||
| 1872 | { | ||
| 1873 | it->phys_ascent = pcm->ascent + boff; | ||
| 1874 | it->phys_descent = pcm->descent - boff; | ||
| 1875 | it->pixel_width = pcm->width; | ||
| 1876 | } | ||
| 1877 | else | ||
| 1878 | { | ||
| 1879 | it->glyph_not_available_p = 1; | ||
| 1880 | it->phys_ascent = FONT_BASE (font) + boff; | ||
| 1881 | it->phys_descent = FONT_DESCENT (font) - boff; | ||
| 1882 | it->pixel_width = FONT_WIDTH (font); | ||
| 1883 | } | ||
| 1884 | |||
| 1885 | /* If this is a space inside a region of text with | ||
| 1886 | `space-width' property, change its width. */ | ||
| 1887 | stretched_p = it->char_to_display == ' ' && !NILP (it->space_width); | ||
| 1888 | if (stretched_p) | ||
| 1889 | it->pixel_width *= XFLOATINT (it->space_width); | ||
| 1890 | |||
| 1891 | /* If face has a box, add the box thickness to the character | ||
| 1892 | height. If character has a box line to the left and/or | ||
| 1893 | right, add the box line width to the character's width. */ | ||
| 1894 | if (face->box != FACE_NO_BOX) | ||
| 1895 | { | ||
| 1896 | int thick = face->box_line_width; | ||
| 1897 | |||
| 1898 | if (thick > 0) | ||
| 1899 | { | ||
| 1900 | it->ascent += thick; | ||
| 1901 | it->descent += thick; | ||
| 1902 | } | ||
| 1903 | else | ||
| 1904 | thick = -thick; | ||
| 1905 | |||
| 1906 | if (it->start_of_box_run_p) | ||
| 1907 | it->pixel_width += thick; | ||
| 1908 | if (it->end_of_box_run_p) | ||
| 1909 | it->pixel_width += thick; | ||
| 1910 | } | ||
| 1911 | |||
| 1912 | /* If face has an overline, add the height of the overline | ||
| 1913 | (1 pixel) and a 1 pixel margin to the character height. */ | ||
| 1914 | if (face->overline_p) | ||
| 1915 | it->ascent += 2; | ||
| 1916 | |||
| 1917 | take_vertical_position_into_account (it); | ||
| 1918 | |||
| 1919 | /* If we have to actually produce glyphs, do it. */ | ||
| 1920 | if (it->glyph_row) | ||
| 1921 | { | ||
| 1922 | if (stretched_p) | ||
| 1923 | { | ||
| 1924 | /* Translate a space with a `space-width' property | ||
| 1925 | into a stretch glyph. */ | ||
| 1926 | double ascent = (double) FONT_BASE (font) | ||
| 1927 | / FONT_HEIGHT (font); | ||
| 1928 | x_append_stretch_glyph (it, it->object, it->pixel_width, | ||
| 1929 | it->ascent + it->descent, ascent); | ||
| 1930 | } | ||
| 1931 | else | ||
| 1932 | x_append_glyph (it); | ||
| 1933 | |||
| 1934 | /* If characters with lbearing or rbearing are displayed | ||
| 1935 | in this line, record that fact in a flag of the | ||
| 1936 | glyph row. This is used to optimize X output code. */ | ||
| 1937 | if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width)) | ||
| 1938 | it->glyph_row->contains_overlapping_glyphs_p = 1; | ||
| 1939 | } | ||
| 1940 | } | ||
| 1941 | else if (it->char_to_display == '\n') | ||
| 1942 | { | ||
| 1943 | /* A newline has no width but we need the height of the line. */ | ||
| 1944 | it->pixel_width = 0; | ||
| 1945 | it->nglyphs = 0; | ||
| 1946 | it->ascent = it->phys_ascent = FONT_BASE (font) + boff; | ||
| 1947 | it->descent = it->phys_descent = FONT_DESCENT (font) - boff; | ||
| 1948 | |||
| 1949 | if (face->box != FACE_NO_BOX | ||
| 1950 | && face->box_line_width > 0) | ||
| 1951 | { | ||
| 1952 | it->ascent += face->box_line_width; | ||
| 1953 | it->descent += face->box_line_width; | ||
| 1954 | } | ||
| 1955 | } | ||
| 1956 | else if (it->char_to_display == '\t') | ||
| 1957 | { | ||
| 1958 | int tab_width = it->tab_width * CANON_X_UNIT (it->f); | ||
| 1959 | int x = it->current_x + it->continuation_lines_width; | ||
| 1960 | int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width; | ||
| 1961 | |||
| 1962 | /* If the distance from the current position to the next tab | ||
| 1963 | stop is less than a canonical character width, use the | ||
| 1964 | tab stop after that. */ | ||
| 1965 | if (next_tab_x - x < CANON_X_UNIT (it->f)) | ||
| 1966 | next_tab_x += tab_width; | ||
| 1967 | |||
| 1968 | it->pixel_width = next_tab_x - x; | ||
| 1969 | it->nglyphs = 1; | ||
| 1970 | it->ascent = it->phys_ascent = FONT_BASE (font) + boff; | ||
| 1971 | it->descent = it->phys_descent = FONT_DESCENT (font) - boff; | ||
| 1972 | |||
| 1973 | if (it->glyph_row) | ||
| 1974 | { | ||
| 1975 | double ascent = (double) it->ascent / (it->ascent + it->descent); | ||
| 1976 | x_append_stretch_glyph (it, it->object, it->pixel_width, | ||
| 1977 | it->ascent + it->descent, ascent); | ||
| 1978 | } | ||
| 1979 | } | ||
| 1980 | else | ||
| 1981 | { | ||
| 1982 | /* A multi-byte character. | ||
| 1983 | If we found a font, this font should give us the right | ||
| 1984 | metrics. If we didn't find a font, use the frame's | ||
| 1985 | default font and calculate the width of the character | ||
| 1986 | from the charset width; this is what old redisplay code | ||
| 1987 | did. */ | ||
| 1988 | enum w32_char_font_type type; | ||
| 1989 | |||
| 1990 | if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1) | ||
| 1991 | type = BDF_1D_FONT; | ||
| 1992 | else if (font->bdf) | ||
| 1993 | type = BDF_2D_FONT; | ||
| 1994 | else | ||
| 1995 | type = UNICODE_FONT; | ||
| 1996 | |||
| 1997 | pcm = w32_per_char_metric (font, &char2b, type); | ||
| 1998 | |||
| 1999 | if (font_not_found_p || !pcm) | ||
| 2000 | { | ||
| 2001 | int charset = CHAR_CHARSET (it->char_to_display); | ||
| 2002 | |||
| 2003 | it->glyph_not_available_p = 1; | ||
| 2004 | it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f)) | ||
| 2005 | * CHARSET_WIDTH (charset)); | ||
| 2006 | it->phys_ascent = FONT_BASE (font) + boff; | ||
| 2007 | it->phys_descent = FONT_DESCENT (font) - boff; | ||
| 2008 | } | ||
| 2009 | else | ||
| 2010 | { | ||
| 2011 | it->pixel_width = pcm->width; | ||
| 2012 | it->phys_ascent = pcm->ascent + boff; | ||
| 2013 | it->phys_descent = pcm->descent - boff; | ||
| 2014 | if (it->glyph_row | ||
| 2015 | && (pcm->lbearing < 0 | ||
| 2016 | || pcm->rbearing > pcm->width)) | ||
| 2017 | it->glyph_row->contains_overlapping_glyphs_p = 1; | ||
| 2018 | } | ||
| 2019 | it->nglyphs = 1; | ||
| 2020 | it->ascent = FONT_BASE (font) + boff; | ||
| 2021 | it->descent = FONT_DESCENT (font) - boff; | ||
| 2022 | if (face->box != FACE_NO_BOX) | ||
| 2023 | { | ||
| 2024 | int thick = face->box_line_width; | ||
| 2025 | |||
| 2026 | if (thick > 0) | ||
| 2027 | { | ||
| 2028 | it->ascent += thick; | ||
| 2029 | it->descent += thick; | ||
| 2030 | } | ||
| 2031 | else | ||
| 2032 | thick = - thick; | ||
| 2033 | |||
| 2034 | if (it->start_of_box_run_p) | ||
| 2035 | it->pixel_width += thick; | ||
| 2036 | if (it->end_of_box_run_p) | ||
| 2037 | it->pixel_width += thick; | ||
| 2038 | } | ||
| 2039 | |||
| 2040 | /* If face has an overline, add the height of the overline | ||
| 2041 | (1 pixel) and a 1 pixel margin to the character height. */ | ||
| 2042 | if (face->overline_p) | ||
| 2043 | it->ascent += 2; | ||
| 2044 | |||
| 2045 | take_vertical_position_into_account (it); | ||
| 2046 | |||
| 2047 | if (it->glyph_row) | ||
| 2048 | x_append_glyph (it); | ||
| 2049 | } | ||
| 2050 | it->multibyte_p = saved_multibyte_p; | ||
| 2051 | } | ||
| 2052 | else if (it->what == IT_COMPOSITION) | ||
| 2053 | { | ||
| 2054 | /* Note: A composition is represented as one glyph in the | ||
| 2055 | glyph matrix. There are no padding glyphs. */ | ||
| 2056 | wchar_t char2b; | ||
| 2057 | XFontStruct *font; | ||
| 2058 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | ||
| 2059 | XCharStruct *pcm; | ||
| 2060 | int font_not_found_p; | ||
| 2061 | struct font_info *font_info; | ||
| 2062 | int boff; /* baseline offset */ | ||
| 2063 | struct composition *cmp = composition_table[it->cmp_id]; | ||
| 2064 | |||
| 2065 | /* Maybe translate single-byte characters to multibyte. */ | ||
| 2066 | it->char_to_display = it->c; | ||
| 2067 | if (unibyte_display_via_language_environment | ||
| 2068 | && SINGLE_BYTE_CHAR_P (it->c) | ||
| 2069 | && (it->c >= 0240 | ||
| 2070 | || (it->c >= 0200 | ||
| 2071 | && !NILP (Vnonascii_translation_table)))) | ||
| 2072 | { | ||
| 2073 | it->char_to_display = unibyte_char_to_multibyte (it->c); | ||
| 2074 | } | ||
| 2075 | |||
| 2076 | /* Get face and font to use. Encode IT->char_to_display. */ | ||
| 2077 | it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | ||
| 2078 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 2079 | x_get_char_face_and_encoding (it->f, it->char_to_display, | ||
| 2080 | it->face_id, &char2b, it->multibyte_p); | ||
| 2081 | font = face->font; | ||
| 2082 | |||
| 2083 | /* When no suitable font found, use the default font. */ | ||
| 2084 | font_not_found_p = font == NULL; | ||
| 2085 | if (font_not_found_p) | ||
| 2086 | { | ||
| 2087 | font = FRAME_FONT (it->f); | ||
| 2088 | boff = it->f->output_data.w32->baseline_offset; | ||
| 2089 | font_info = NULL; | ||
| 2090 | } | ||
| 2091 | else | ||
| 2092 | { | ||
| 2093 | font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id); | ||
| 2094 | boff = font_info->baseline_offset; | ||
| 2095 | if (font_info->vertical_centering) | ||
| 2096 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | ||
| 2097 | } | ||
| 2098 | |||
| 2099 | /* There are no padding glyphs, so there is only one glyph to | ||
| 2100 | produce for the composition. Important is that pixel_width, | ||
| 2101 | ascent and descent are the values of what is drawn by | ||
| 2102 | draw_glyphs (i.e. the values of the overall glyphs composed). */ | ||
| 2103 | it->nglyphs = 1; | ||
| 2104 | |||
| 2105 | /* If we have not yet calculated pixel size data of glyphs of | ||
| 2106 | the composition for the current face font, calculate them | ||
| 2107 | now. Theoretically, we have to check all fonts for the | ||
| 2108 | glyphs, but that requires much time and memory space. So, | ||
| 2109 | here we check only the font of the first glyph. This leads | ||
| 2110 | to incorrect display very rarely, and C-l (recenter) can | ||
| 2111 | correct the display anyway. */ | ||
| 2112 | if (cmp->font != (void *) font) | ||
| 2113 | { | ||
| 2114 | /* Ascent and descent of the font of the first character of | ||
| 2115 | this composition (adjusted by baseline offset). Ascent | ||
| 2116 | and descent of overall glyphs should not be less than | ||
| 2117 | them respectively. */ | ||
| 2118 | int font_ascent = FONT_BASE (font) + boff; | ||
| 2119 | int font_descent = FONT_DESCENT (font) - boff; | ||
| 2120 | /* Bounding box of the overall glyphs. */ | ||
| 2121 | int leftmost, rightmost, lowest, highest; | ||
| 2122 | int i, width, ascent, descent; | ||
| 2123 | enum w32_char_font_type font_type; | ||
| 2124 | |||
| 2125 | cmp->font = (void *) font; | ||
| 2126 | |||
| 2127 | if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (it->c)) == 1) | ||
| 2128 | font_type = BDF_1D_FONT; | ||
| 2129 | else if (font->bdf) | ||
| 2130 | font_type = BDF_2D_FONT; | ||
| 2131 | else | ||
| 2132 | font_type = UNICODE_FONT; | ||
| 2133 | |||
| 2134 | /* Initialize the bounding box. */ | ||
| 2135 | if (font_info | ||
| 2136 | && (pcm = w32_per_char_metric (font, &char2b, font_type))) | ||
| 2137 | { | ||
| 2138 | width = pcm->width; | ||
| 2139 | ascent = pcm->ascent; | ||
| 2140 | descent = pcm->descent; | ||
| 2141 | } | ||
| 2142 | else | ||
| 2143 | { | ||
| 2144 | width = FONT_WIDTH (font); | ||
| 2145 | ascent = FONT_BASE (font); | ||
| 2146 | descent = FONT_DESCENT (font); | ||
| 2147 | } | ||
| 2148 | |||
| 2149 | rightmost = width; | ||
| 2150 | lowest = - descent + boff; | ||
| 2151 | highest = ascent + boff; | ||
| 2152 | leftmost = 0; | ||
| 2153 | |||
| 2154 | if (font_info | ||
| 2155 | && font_info->default_ascent | ||
| 2156 | && CHAR_TABLE_P (Vuse_default_ascent) | ||
| 2157 | && !NILP (Faref (Vuse_default_ascent, | ||
| 2158 | make_number (it->char_to_display)))) | ||
| 2159 | highest = font_info->default_ascent + boff; | ||
| 2160 | |||
| 2161 | /* Draw the first glyph at the normal position. It may be | ||
| 2162 | shifted to right later if some other glyphs are drawn at | ||
| 2163 | the left. */ | ||
| 2164 | cmp->offsets[0] = 0; | ||
| 2165 | cmp->offsets[1] = boff; | ||
| 2166 | |||
| 2167 | /* Set cmp->offsets for the remaining glyphs. */ | ||
| 2168 | for (i = 1; i < cmp->glyph_len; i++) | ||
| 2169 | { | ||
| 2170 | int left, right, btm, top; | ||
| 2171 | int ch = COMPOSITION_GLYPH (cmp, i); | ||
| 2172 | int face_id = FACE_FOR_CHAR (it->f, face, ch); | ||
| 2173 | |||
| 2174 | face = FACE_FROM_ID (it->f, face_id); | ||
| 2175 | x_get_char_face_and_encoding (it->f, ch, face->id, &char2b, | ||
| 2176 | it->multibyte_p); | ||
| 2177 | font = face->font; | ||
| 2178 | if (font == NULL) | ||
| 2179 | { | ||
| 2180 | font = FRAME_FONT (it->f); | ||
| 2181 | boff = it->f->output_data.w32->baseline_offset; | ||
| 2182 | font_info = NULL; | ||
| 2183 | } | ||
| 2184 | else | ||
| 2185 | { | ||
| 2186 | font_info | ||
| 2187 | = FONT_INFO_FROM_ID (it->f, face->font_info_id); | ||
| 2188 | boff = font_info->baseline_offset; | ||
| 2189 | if (font_info->vertical_centering) | ||
| 2190 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | ||
| 2191 | } | ||
| 2192 | |||
| 2193 | if (font->bdf && CHARSET_DIMENSION (CHAR_CHARSET (ch)) == 1) | ||
| 2194 | font_type = BDF_1D_FONT; | ||
| 2195 | else if (font->bdf) | ||
| 2196 | font_type = BDF_2D_FONT; | ||
| 2197 | else | ||
| 2198 | font_type = UNICODE_FONT; | ||
| 2199 | |||
| 2200 | if (font_info | ||
| 2201 | && (pcm = w32_per_char_metric (font, &char2b, font_type))) | ||
| 2202 | { | ||
| 2203 | width = pcm->width; | ||
| 2204 | ascent = pcm->ascent; | ||
| 2205 | descent = pcm->descent; | ||
| 2206 | } | ||
| 2207 | else | ||
| 2208 | { | ||
| 2209 | width = FONT_WIDTH (font); | ||
| 2210 | ascent = 1; | ||
| 2211 | descent = 0; | ||
| 2212 | } | ||
| 2213 | |||
| 2214 | if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS) | ||
| 2215 | { | ||
| 2216 | /* Relative composition with or without | ||
| 2217 | alternate chars. */ | ||
| 2218 | left = (leftmost + rightmost - width) / 2; | ||
| 2219 | btm = - descent + boff; | ||
| 2220 | if (font_info && font_info->relative_compose | ||
| 2221 | && (! CHAR_TABLE_P (Vignore_relative_composition) | ||
| 2222 | || NILP (Faref (Vignore_relative_composition, | ||
| 2223 | make_number (ch))))) | ||
| 2224 | { | ||
| 2225 | |||
| 2226 | if (- descent >= font_info->relative_compose) | ||
| 2227 | /* One extra pixel between two glyphs. */ | ||
| 2228 | btm = highest + 1; | ||
| 2229 | else if (ascent <= 0) | ||
| 2230 | /* One extra pixel between two glyphs. */ | ||
| 2231 | btm = lowest - 1 - ascent - descent; | ||
| 2232 | } | ||
| 2233 | } | ||
| 2234 | else | ||
| 2235 | { | ||
| 2236 | /* A composition rule is specified by an integer | ||
| 2237 | value that encodes global and new reference | ||
| 2238 | points (GREF and NREF). GREF and NREF are | ||
| 2239 | specified by numbers as below: | ||
| 2240 | |||
| 2241 | 0---1---2 -- ascent | ||
| 2242 | | | | ||
| 2243 | | | | ||
| 2244 | | | | ||
| 2245 | 9--10--11 -- center | ||
| 2246 | | | | ||
| 2247 | ---3---4---5--- baseline | ||
| 2248 | | | | ||
| 2249 | 6---7---8 -- descent | ||
| 2250 | */ | ||
| 2251 | int rule = COMPOSITION_RULE (cmp, i); | ||
| 2252 | int gref, nref, grefx, grefy, nrefx, nrefy; | ||
| 2253 | |||
| 2254 | COMPOSITION_DECODE_RULE (rule, gref, nref); | ||
| 2255 | grefx = gref % 3, nrefx = nref % 3; | ||
| 2256 | grefy = gref / 3, nrefy = nref / 3; | ||
| 2257 | |||
| 2258 | left = (leftmost | ||
| 2259 | + grefx * (rightmost - leftmost) / 2 | ||
| 2260 | - nrefx * width / 2); | ||
| 2261 | btm = ((grefy == 0 ? highest | ||
| 2262 | : grefy == 1 ? 0 | ||
| 2263 | : grefy == 2 ? lowest | ||
| 2264 | : (highest + lowest) / 2) | ||
| 2265 | - (nrefy == 0 ? ascent + descent | ||
| 2266 | : nrefy == 1 ? descent - boff | ||
| 2267 | : nrefy == 2 ? 0 | ||
| 2268 | : (ascent + descent) / 2)); | ||
| 2269 | } | ||
| 2270 | |||
| 2271 | cmp->offsets[i * 2] = left; | ||
| 2272 | cmp->offsets[i * 2 + 1] = btm + descent; | ||
| 2273 | |||
| 2274 | /* Update the bounding box of the overall glyphs. */ | ||
| 2275 | right = left + width; | ||
| 2276 | top = btm + descent + ascent; | ||
| 2277 | if (left < leftmost) | ||
| 2278 | leftmost = left; | ||
| 2279 | if (right > rightmost) | ||
| 2280 | rightmost = right; | ||
| 2281 | if (top > highest) | ||
| 2282 | highest = top; | ||
| 2283 | if (btm < lowest) | ||
| 2284 | lowest = btm; | ||
| 2285 | } | ||
| 2286 | |||
| 2287 | /* If there are glyphs whose x-offsets are negative, | ||
| 2288 | shift all glyphs to the right and make all x-offsets | ||
| 2289 | non-negative. */ | ||
| 2290 | if (leftmost < 0) | ||
| 2291 | { | ||
| 2292 | for (i = 0; i < cmp->glyph_len; i++) | ||
| 2293 | cmp->offsets[i * 2] -= leftmost; | ||
| 2294 | rightmost -= leftmost; | ||
| 2295 | } | ||
| 2296 | |||
| 2297 | cmp->pixel_width = rightmost; | ||
| 2298 | cmp->ascent = highest; | ||
| 2299 | cmp->descent = - lowest; | ||
| 2300 | if (cmp->ascent < font_ascent) | ||
| 2301 | cmp->ascent = font_ascent; | ||
| 2302 | if (cmp->descent < font_descent) | ||
| 2303 | cmp->descent = font_descent; | ||
| 2304 | } | ||
| 2305 | |||
| 2306 | it->pixel_width = cmp->pixel_width; | ||
| 2307 | it->ascent = it->phys_ascent = cmp->ascent; | ||
| 2308 | it->descent = it->phys_descent = cmp->descent; | ||
| 2309 | |||
| 2310 | if (face->box != FACE_NO_BOX) | ||
| 2311 | { | ||
| 2312 | int thick = face->box_line_width; | ||
| 2313 | |||
| 2314 | if (thick > 0) | ||
| 2315 | { | ||
| 2316 | it->ascent += thick; | ||
| 2317 | it->descent += thick; | ||
| 2318 | } | ||
| 2319 | else | ||
| 2320 | thick = - thick; | ||
| 2321 | |||
| 2322 | if (it->start_of_box_run_p) | ||
| 2323 | it->pixel_width += thick; | ||
| 2324 | if (it->end_of_box_run_p) | ||
| 2325 | it->pixel_width += thick; | ||
| 2326 | } | ||
| 2327 | |||
| 2328 | /* If face has an overline, add the height of the overline | ||
| 2329 | (1 pixel) and a 1 pixel margin to the character height. */ | ||
| 2330 | if (face->overline_p) | ||
| 2331 | it->ascent += 2; | ||
| 2332 | |||
| 2333 | take_vertical_position_into_account (it); | ||
| 2334 | |||
| 2335 | if (it->glyph_row) | ||
| 2336 | x_append_composite_glyph (it); | ||
| 2337 | } | ||
| 2338 | else if (it->what == IT_IMAGE) | ||
| 2339 | x_produce_image_glyph (it); | ||
| 2340 | else if (it->what == IT_STRETCH) | ||
| 2341 | x_produce_stretch_glyph (it); | ||
| 2342 | |||
| 2343 | /* Accumulate dimensions. Note: can't assume that it->descent > 0 | ||
| 2344 | because this isn't true for images with `:ascent 100'. */ | ||
| 2345 | xassert (it->ascent >= 0 && it->descent >= 0); | ||
| 2346 | if (it->area == TEXT_AREA) | ||
| 2347 | it->current_x += it->pixel_width; | ||
| 2348 | |||
| 2349 | it->descent += it->extra_line_spacing; | ||
| 2350 | |||
| 2351 | it->max_ascent = max (it->max_ascent, it->ascent); | ||
| 2352 | it->max_descent = max (it->max_descent, it->descent); | ||
| 2353 | it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent); | ||
| 2354 | it->max_phys_descent = max (it->max_phys_descent, it->phys_descent); | ||
| 2355 | } | ||
| 2356 | |||
| 2357 | |||
| 2358 | /* Estimate the pixel height of the mode or top line on frame F. | 1232 | /* Estimate the pixel height of the mode or top line on frame F. |
| 2359 | FACE_ID specifies what line's height to estimate. */ | 1233 | FACE_ID specifies what line's height to estimate. */ |
| 2360 | 1234 | ||
| @@ -2387,123 +1261,6 @@ x_estimate_mode_line_height (f, face_id) | |||
| 2387 | Glyph display | 1261 | Glyph display |
| 2388 | ***********************************************************************/ | 1262 | ***********************************************************************/ |
| 2389 | 1263 | ||
| 2390 | /* A sequence of glyphs to be drawn in the same face. | ||
| 2391 | |||
| 2392 | This data structure is not really completely X specific, so it | ||
| 2393 | could possibly, at least partially, be useful for other systems. It | ||
| 2394 | is currently not part of the external redisplay interface because | ||
| 2395 | it's not clear what other systems will need. */ | ||
| 2396 | |||
| 2397 | struct glyph_string | ||
| 2398 | { | ||
| 2399 | /* X-origin of the string. */ | ||
| 2400 | int x; | ||
| 2401 | |||
| 2402 | /* Y-origin and y-position of the base line of this string. */ | ||
| 2403 | int y, ybase; | ||
| 2404 | |||
| 2405 | /* The width of the string, not including a face extension. */ | ||
| 2406 | int width; | ||
| 2407 | |||
| 2408 | /* The width of the string, including a face extension. */ | ||
| 2409 | int background_width; | ||
| 2410 | |||
| 2411 | /* The height of this string. This is the height of the line this | ||
| 2412 | string is drawn in, and can be different from the height of the | ||
| 2413 | font the string is drawn in. */ | ||
| 2414 | int height; | ||
| 2415 | |||
| 2416 | /* Number of pixels this string overwrites in front of its x-origin. | ||
| 2417 | This number is zero if the string has an lbearing >= 0; it is | ||
| 2418 | -lbearing, if the string has an lbearing < 0. */ | ||
| 2419 | int left_overhang; | ||
| 2420 | |||
| 2421 | /* Number of pixels this string overwrites past its right-most | ||
| 2422 | nominal x-position, i.e. x + width. Zero if the string's | ||
| 2423 | rbearing is <= its nominal width, rbearing - width otherwise. */ | ||
| 2424 | int right_overhang; | ||
| 2425 | |||
| 2426 | /* The frame on which the glyph string is drawn. */ | ||
| 2427 | struct frame *f; | ||
| 2428 | |||
| 2429 | /* The window on which the glyph string is drawn. */ | ||
| 2430 | struct window *w; | ||
| 2431 | |||
| 2432 | /* X display and window for convenience. */ | ||
| 2433 | Window window; | ||
| 2434 | |||
| 2435 | /* The glyph row for which this string was built. It determines the | ||
| 2436 | y-origin and height of the string. */ | ||
| 2437 | struct glyph_row *row; | ||
| 2438 | |||
| 2439 | /* The area within row. */ | ||
| 2440 | enum glyph_row_area area; | ||
| 2441 | |||
| 2442 | /* Characters to be drawn, and number of characters. */ | ||
| 2443 | wchar_t *char2b; | ||
| 2444 | int nchars; | ||
| 2445 | |||
| 2446 | /* A face-override for drawing cursors, mouse face and similar. */ | ||
| 2447 | enum draw_glyphs_face hl; | ||
| 2448 | |||
| 2449 | /* Face in which this string is to be drawn. */ | ||
| 2450 | struct face *face; | ||
| 2451 | |||
| 2452 | /* Font in which this string is to be drawn. */ | ||
| 2453 | XFontStruct *font; | ||
| 2454 | |||
| 2455 | /* Font info for this string. */ | ||
| 2456 | struct font_info *font_info; | ||
| 2457 | |||
| 2458 | /* Non-null means this string describes (part of) a composition. | ||
| 2459 | All characters from char2b are drawn composed. */ | ||
| 2460 | struct composition *cmp; | ||
| 2461 | |||
| 2462 | /* Index of this glyph string's first character in the glyph | ||
| 2463 | definition of CMP. If this is zero, this glyph string describes | ||
| 2464 | the first character of a composition. */ | ||
| 2465 | int gidx; | ||
| 2466 | |||
| 2467 | /* 1 means this glyph strings face has to be drawn to the right end | ||
| 2468 | of the window's drawing area. */ | ||
| 2469 | unsigned extends_to_end_of_line_p : 1; | ||
| 2470 | |||
| 2471 | /* 1 means the background of this string has been drawn. */ | ||
| 2472 | unsigned background_filled_p : 1; | ||
| 2473 | |||
| 2474 | /* 1 means glyph string must be drawn with 16-bit functions. */ | ||
| 2475 | unsigned two_byte_p : 1; | ||
| 2476 | |||
| 2477 | /* 1 means that the original font determined for drawing this glyph | ||
| 2478 | string could not be loaded. The member `font' has been set to | ||
| 2479 | the frame's default font in this case. */ | ||
| 2480 | unsigned font_not_found_p : 1; | ||
| 2481 | |||
| 2482 | /* 1 means that the face in which this glyph string is drawn has a | ||
| 2483 | stipple pattern. */ | ||
| 2484 | unsigned stippled_p : 1; | ||
| 2485 | |||
| 2486 | /* 1 means only the foreground of this glyph string must be drawn, | ||
| 2487 | and we should use the physical height of the line this glyph | ||
| 2488 | string appears in as clip rect. */ | ||
| 2489 | unsigned for_overlaps_p : 1; | ||
| 2490 | |||
| 2491 | /* The GC to use for drawing this glyph string. */ | ||
| 2492 | XGCValues *gc; | ||
| 2493 | |||
| 2494 | HDC hdc; | ||
| 2495 | |||
| 2496 | /* A pointer to the first glyph in the string. This glyph | ||
| 2497 | corresponds to char2b[0]. Needed to draw rectangles if | ||
| 2498 | font_not_found_p is 1. */ | ||
| 2499 | struct glyph *first_glyph; | ||
| 2500 | |||
| 2501 | /* Image, if any. */ | ||
| 2502 | struct image *img; | ||
| 2503 | |||
| 2504 | struct glyph_string *next, *prev; | ||
| 2505 | }; | ||
| 2506 | |||
| 2507 | 1264 | ||
| 2508 | /* Encapsulate the different ways of displaying text under W32. */ | 1265 | /* Encapsulate the different ways of displaying text under W32. */ |
| 2509 | 1266 | ||
| @@ -2519,62 +1276,15 @@ w32_text_out (s, x, y,chars,nchars) | |||
| 2519 | w32_BDF_TextOut (s->gc->font->bdf, s->hdc, | 1276 | w32_BDF_TextOut (s->gc->font->bdf, s->hdc, |
| 2520 | x, y, (char *) chars, charset_dim, | 1277 | x, y, (char *) chars, charset_dim, |
| 2521 | nchars * charset_dim, 0); | 1278 | nchars * charset_dim, 0); |
| 2522 | else if (s->first_glyph->w32_font_type == UNICODE_FONT) | 1279 | else if (s->first_glyph->font_type == UNICODE_FONT) |
| 2523 | ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL); | 1280 | ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL); |
| 2524 | else | 1281 | else |
| 2525 | ExtTextOutA (s->hdc, x, y, 0, NULL, (char *) chars, | 1282 | ExtTextOutA (s->hdc, x, y, 0, NULL, (char *) chars, |
| 2526 | nchars * charset_dim, NULL); | 1283 | nchars * charset_dim, NULL); |
| 2527 | } | 1284 | } |
| 2528 | 1285 | ||
| 2529 | #if GLYPH_DEBUG | ||
| 2530 | 1286 | ||
| 2531 | static void | 1287 | |
| 2532 | x_dump_glyph_string (s) | ||
| 2533 | struct glyph_string *s; | ||
| 2534 | { | ||
| 2535 | fprintf (stderr, "glyph string\n"); | ||
| 2536 | fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n", | ||
| 2537 | s->x, s->y, s->width, s->height); | ||
| 2538 | fprintf (stderr, " ybase = %d\n", s->ybase); | ||
| 2539 | fprintf (stderr, " hl = %d\n", s->hl); | ||
| 2540 | fprintf (stderr, " left overhang = %d, right = %d\n", | ||
| 2541 | s->left_overhang, s->right_overhang); | ||
| 2542 | fprintf (stderr, " nchars = %d\n", s->nchars); | ||
| 2543 | fprintf (stderr, " extends to end of line = %d\n", | ||
| 2544 | s->extends_to_end_of_line_p); | ||
| 2545 | fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font)); | ||
| 2546 | fprintf (stderr, " bg width = %d\n", s->background_width); | ||
| 2547 | } | ||
| 2548 | |||
| 2549 | #endif /* GLYPH_DEBUG */ | ||
| 2550 | |||
| 2551 | |||
| 2552 | |||
| 2553 | static void x_append_glyph_string_lists P_ ((struct glyph_string **, | ||
| 2554 | struct glyph_string **, | ||
| 2555 | struct glyph_string *, | ||
| 2556 | struct glyph_string *)); | ||
| 2557 | static void x_prepend_glyph_string_lists P_ ((struct glyph_string **, | ||
| 2558 | struct glyph_string **, | ||
| 2559 | struct glyph_string *, | ||
| 2560 | struct glyph_string *)); | ||
| 2561 | static void x_append_glyph_string P_ ((struct glyph_string **, | ||
| 2562 | struct glyph_string **, | ||
| 2563 | struct glyph_string *)); | ||
| 2564 | static int x_left_overwritten P_ ((struct glyph_string *)); | ||
| 2565 | static int x_left_overwriting P_ ((struct glyph_string *)); | ||
| 2566 | static int x_right_overwritten P_ ((struct glyph_string *)); | ||
| 2567 | static int x_right_overwriting P_ ((struct glyph_string *)); | ||
| 2568 | static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int, | ||
| 2569 | int)); | ||
| 2570 | static void w32_init_glyph_string P_ ((struct glyph_string *, HDC hdc, | ||
| 2571 | wchar_t *, struct window *, | ||
| 2572 | struct glyph_row *, | ||
| 2573 | enum glyph_row_area, int, | ||
| 2574 | enum draw_glyphs_face)); | ||
| 2575 | static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *, | ||
| 2576 | enum glyph_row_area, int, int, | ||
| 2577 | enum draw_glyphs_face, int)); | ||
| 2578 | static void x_set_glyph_string_clipping P_ ((struct glyph_string *)); | 1288 | static void x_set_glyph_string_clipping P_ ((struct glyph_string *)); |
| 2579 | static void x_set_glyph_string_gc P_ ((struct glyph_string *)); | 1289 | static void x_set_glyph_string_gc P_ ((struct glyph_string *)); |
| 2580 | static void x_draw_glyph_string_background P_ ((struct glyph_string *, | 1290 | static void x_draw_glyph_string_background P_ ((struct glyph_string *, |
| @@ -2583,14 +1293,9 @@ static void x_draw_glyph_string_foreground P_ ((struct glyph_string *)); | |||
| 2583 | static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *)); | 1293 | static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *)); |
| 2584 | static void x_draw_glyph_string_box P_ ((struct glyph_string *)); | 1294 | static void x_draw_glyph_string_box P_ ((struct glyph_string *)); |
| 2585 | static void x_draw_glyph_string P_ ((struct glyph_string *)); | 1295 | static void x_draw_glyph_string P_ ((struct glyph_string *)); |
| 2586 | static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *)); | ||
| 2587 | static void x_set_cursor_gc P_ ((struct glyph_string *)); | 1296 | static void x_set_cursor_gc P_ ((struct glyph_string *)); |
| 2588 | static void x_set_mode_line_face_gc P_ ((struct glyph_string *)); | 1297 | static void x_set_mode_line_face_gc P_ ((struct glyph_string *)); |
| 2589 | static void x_set_mouse_face_gc P_ ((struct glyph_string *)); | 1298 | static void x_set_mouse_face_gc P_ ((struct glyph_string *)); |
| 2590 | static void w32_get_glyph_overhangs P_ ((HDC hdc, struct glyph *, | ||
| 2591 | struct frame *, | ||
| 2592 | int *, int *)); | ||
| 2593 | static void x_compute_overhangs_and_x P_ ((struct glyph_string *, int, int)); | ||
| 2594 | static int w32_alloc_lighter_color (struct frame *, COLORREF *, double, int); | 1299 | static int w32_alloc_lighter_color (struct frame *, COLORREF *, double, int); |
| 2595 | static void w32_setup_relief_color P_ ((struct frame *, struct relief *, | 1300 | static void w32_setup_relief_color P_ ((struct frame *, struct relief *, |
| 2596 | double, int, COLORREF)); | 1301 | double, int, COLORREF)); |
| @@ -2599,7 +1304,6 @@ static void x_draw_image_glyph_string P_ ((struct glyph_string *)); | |||
| 2599 | static void x_draw_image_relief P_ ((struct glyph_string *)); | 1304 | static void x_draw_image_relief P_ ((struct glyph_string *)); |
| 2600 | static void x_draw_image_foreground P_ ((struct glyph_string *)); | 1305 | static void x_draw_image_foreground P_ ((struct glyph_string *)); |
| 2601 | static void w32_draw_image_foreground_1 P_ ((struct glyph_string *, HBITMAP)); | 1306 | static void w32_draw_image_foreground_1 P_ ((struct glyph_string *, HBITMAP)); |
| 2602 | static void x_fill_image_glyph_string P_ ((struct glyph_string *)); | ||
| 2603 | static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int, | 1307 | static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int, |
| 2604 | int, int, int)); | 1308 | int, int, int)); |
| 2605 | static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int, | 1309 | static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int, |
| @@ -2608,69 +1312,12 @@ static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, | |||
| 2608 | int, int, int, RECT *)); | 1312 | int, int, int, RECT *)); |
| 2609 | static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *, | 1313 | static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *, |
| 2610 | enum glyph_row_area)); | 1314 | enum glyph_row_area)); |
| 2611 | static int x_fill_stretch_glyph_string P_ ((struct glyph_string *, | ||
| 2612 | struct glyph_row *, | ||
| 2613 | enum glyph_row_area, int, int)); | ||
| 2614 | 1315 | ||
| 2615 | #if GLYPH_DEBUG | 1316 | #if GLYPH_DEBUG |
| 2616 | static void x_check_font P_ ((struct frame *, XFontStruct *)); | 1317 | static void x_check_font P_ ((struct frame *, XFontStruct *)); |
| 2617 | #endif | 1318 | #endif |
| 2618 | 1319 | ||
| 2619 | 1320 | ||
| 2620 | /* Append the list of glyph strings with head H and tail T to the list | ||
| 2621 | with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */ | ||
| 2622 | |||
| 2623 | static INLINE void | ||
| 2624 | x_append_glyph_string_lists (head, tail, h, t) | ||
| 2625 | struct glyph_string **head, **tail; | ||
| 2626 | struct glyph_string *h, *t; | ||
| 2627 | { | ||
| 2628 | if (h) | ||
| 2629 | { | ||
| 2630 | if (*head) | ||
| 2631 | (*tail)->next = h; | ||
| 2632 | else | ||
| 2633 | *head = h; | ||
| 2634 | h->prev = *tail; | ||
| 2635 | *tail = t; | ||
| 2636 | } | ||
| 2637 | } | ||
| 2638 | |||
| 2639 | |||
| 2640 | /* Prepend the list of glyph strings with head H and tail T to the | ||
| 2641 | list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the | ||
| 2642 | result. */ | ||
| 2643 | |||
| 2644 | static INLINE void | ||
| 2645 | x_prepend_glyph_string_lists (head, tail, h, t) | ||
| 2646 | struct glyph_string **head, **tail; | ||
| 2647 | struct glyph_string *h, *t; | ||
| 2648 | { | ||
| 2649 | if (h) | ||
| 2650 | { | ||
| 2651 | if (*head) | ||
| 2652 | (*head)->prev = t; | ||
| 2653 | else | ||
| 2654 | *tail = t; | ||
| 2655 | t->next = *head; | ||
| 2656 | *head = h; | ||
| 2657 | } | ||
| 2658 | } | ||
| 2659 | |||
| 2660 | |||
| 2661 | /* Append glyph string S to the list with head *HEAD and tail *TAIL. | ||
| 2662 | Set *HEAD and *TAIL to the resulting list. */ | ||
| 2663 | |||
| 2664 | static INLINE void | ||
| 2665 | x_append_glyph_string (head, tail, s) | ||
| 2666 | struct glyph_string **head, **tail; | ||
| 2667 | struct glyph_string *s; | ||
| 2668 | { | ||
| 2669 | s->next = s->prev = NULL; | ||
| 2670 | x_append_glyph_string_lists (head, tail, s, s); | ||
| 2671 | } | ||
| 2672 | |||
| 2673 | |||
| 2674 | /* Set S->gc to a suitable GC for drawing glyph string S in cursor | 1321 | /* Set S->gc to a suitable GC for drawing glyph string S in cursor |
| 2675 | face. */ | 1322 | face. */ |
| 2676 | 1323 | ||
| @@ -2933,11 +1580,12 @@ x_set_glyph_string_clipping (s) | |||
| 2933 | } | 1580 | } |
| 2934 | 1581 | ||
| 2935 | 1582 | ||
| 2936 | /* Compute left and right overhang of glyph string S. If S is a glyph | 1583 | /* RIF: |
| 1584 | Compute left and right overhang of glyph string S. If S is a glyph | ||
| 2937 | string for a composition, assume overhangs don't exist. */ | 1585 | string for a composition, assume overhangs don't exist. */ |
| 2938 | 1586 | ||
| 2939 | static INLINE void | 1587 | static void |
| 2940 | x_compute_glyph_string_overhangs (s) | 1588 | w32_compute_glyph_string_overhangs (s) |
| 2941 | struct glyph_string *s; | 1589 | struct glyph_string *s; |
| 2942 | { | 1590 | { |
| 2943 | /* TODO: Windows does not appear to have a method for | 1591 | /* TODO: Windows does not appear to have a method for |
| @@ -2946,198 +1594,19 @@ x_compute_glyph_string_overhangs (s) | |||
| 2946 | } | 1594 | } |
| 2947 | 1595 | ||
| 2948 | 1596 | ||
| 2949 | /* Compute overhangs and x-positions for glyph string S and its | ||
| 2950 | predecessors, or successors. X is the starting x-position for S. | ||
| 2951 | BACKWARD_P non-zero means process predecessors. */ | ||
| 2952 | |||
| 2953 | static void | ||
| 2954 | x_compute_overhangs_and_x (s, x, backward_p) | ||
| 2955 | struct glyph_string *s; | ||
| 2956 | int x; | ||
| 2957 | int backward_p; | ||
| 2958 | { | ||
| 2959 | if (backward_p) | ||
| 2960 | { | ||
| 2961 | while (s) | ||
| 2962 | { | ||
| 2963 | x_compute_glyph_string_overhangs (s); | ||
| 2964 | x -= s->width; | ||
| 2965 | s->x = x; | ||
| 2966 | s = s->prev; | ||
| 2967 | } | ||
| 2968 | } | ||
| 2969 | else | ||
| 2970 | { | ||
| 2971 | while (s) | ||
| 2972 | { | ||
| 2973 | x_compute_glyph_string_overhangs (s); | ||
| 2974 | s->x = x; | ||
| 2975 | x += s->width; | ||
| 2976 | s = s->next; | ||
| 2977 | } | ||
| 2978 | } | ||
| 2979 | } | ||
| 2980 | |||
| 2981 | |||
| 2982 | /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on | ||
| 2983 | frame F. Overhangs of glyphs other than type CHAR_GLYPH are | ||
| 2984 | assumed to be zero. */ | ||
| 2985 | |||
| 2986 | static void | ||
| 2987 | w32_get_glyph_overhangs (hdc, glyph, f, left, right) | ||
| 2988 | HDC hdc; | ||
| 2989 | struct glyph *glyph; | ||
| 2990 | struct frame *f; | ||
| 2991 | int *left, *right; | ||
| 2992 | { | ||
| 2993 | *left = *right = 0; | ||
| 2994 | |||
| 2995 | if (glyph->type == CHAR_GLYPH) | ||
| 2996 | { | ||
| 2997 | XFontStruct *font; | ||
| 2998 | struct face *face; | ||
| 2999 | wchar_t char2b; | ||
| 3000 | XCharStruct *pcm; | ||
| 3001 | |||
| 3002 | face = x_get_glyph_face_and_encoding (f, glyph, &char2b, NULL); | ||
| 3003 | font = face->font; | ||
| 3004 | |||
| 3005 | if (font | ||
| 3006 | && (pcm = w32_per_char_metric (font, &char2b, | ||
| 3007 | glyph->w32_font_type))) | ||
| 3008 | { | ||
| 3009 | if (pcm->rbearing > pcm->width) | ||
| 3010 | *right = pcm->rbearing - pcm->width; | ||
| 3011 | if (pcm->lbearing < 0) | ||
| 3012 | *left = -pcm->lbearing; | ||
| 3013 | } | ||
| 3014 | } | ||
| 3015 | } | ||
| 3016 | |||
| 3017 | |||
| 3018 | static void | 1597 | static void |
| 3019 | x_get_glyph_overhangs (glyph, f, left, right) | 1598 | w32_get_glyph_overhangs (glyph, f, left, right) |
| 3020 | struct glyph *glyph; | 1599 | struct glyph *glyph; |
| 3021 | struct frame *f; | 1600 | struct frame *f; |
| 3022 | int *left, *right; | 1601 | int *left, *right; |
| 3023 | { | 1602 | { |
| 3024 | HDC hdc = get_frame_dc (f); | 1603 | HDC hdc = get_frame_dc (f); |
| 3025 | /* Convert to unicode! */ | 1604 | /* Convert to unicode! */ |
| 3026 | w32_get_glyph_overhangs (hdc, glyph, f, left, right); | 1605 | x_get_glyph_overhangs (glyph, f, left, right); |
| 3027 | release_frame_dc (f, hdc); | 1606 | release_frame_dc (f, hdc); |
| 3028 | } | 1607 | } |
| 3029 | 1608 | ||
| 3030 | 1609 | ||
| 3031 | /* Return the index of the first glyph preceding glyph string S that | ||
| 3032 | is overwritten by S because of S's left overhang. Value is -1 | ||
| 3033 | if no glyphs are overwritten. */ | ||
| 3034 | |||
| 3035 | static int | ||
| 3036 | x_left_overwritten (s) | ||
| 3037 | struct glyph_string *s; | ||
| 3038 | { | ||
| 3039 | int k; | ||
| 3040 | |||
| 3041 | if (s->left_overhang) | ||
| 3042 | { | ||
| 3043 | int x = 0, i; | ||
| 3044 | struct glyph *glyphs = s->row->glyphs[s->area]; | ||
| 3045 | int first = s->first_glyph - glyphs; | ||
| 3046 | |||
| 3047 | for (i = first - 1; i >= 0 && x > -s->left_overhang; --i) | ||
| 3048 | x -= glyphs[i].pixel_width; | ||
| 3049 | |||
| 3050 | k = i + 1; | ||
| 3051 | } | ||
| 3052 | else | ||
| 3053 | k = -1; | ||
| 3054 | |||
| 3055 | return k; | ||
| 3056 | } | ||
| 3057 | |||
| 3058 | |||
| 3059 | /* Return the index of the first glyph preceding glyph string S that | ||
| 3060 | is overwriting S because of its right overhang. Value is -1 if no | ||
| 3061 | glyph in front of S overwrites S. */ | ||
| 3062 | |||
| 3063 | static int | ||
| 3064 | x_left_overwriting (s) | ||
| 3065 | struct glyph_string *s; | ||
| 3066 | { | ||
| 3067 | int i, k, x; | ||
| 3068 | struct glyph *glyphs = s->row->glyphs[s->area]; | ||
| 3069 | int first = s->first_glyph - glyphs; | ||
| 3070 | |||
| 3071 | k = -1; | ||
| 3072 | x = 0; | ||
| 3073 | for (i = first - 1; i >= 0; --i) | ||
| 3074 | { | ||
| 3075 | int left, right; | ||
| 3076 | w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right); | ||
| 3077 | if (x + right > 0) | ||
| 3078 | k = i; | ||
| 3079 | x -= glyphs[i].pixel_width; | ||
| 3080 | } | ||
| 3081 | |||
| 3082 | return k; | ||
| 3083 | } | ||
| 3084 | |||
| 3085 | |||
| 3086 | /* Return the index of the last glyph following glyph string S that is | ||
| 3087 | not overwritten by S because of S's right overhang. Value is -1 if | ||
| 3088 | no such glyph is found. */ | ||
| 3089 | |||
| 3090 | static int | ||
| 3091 | x_right_overwritten (s) | ||
| 3092 | struct glyph_string *s; | ||
| 3093 | { | ||
| 3094 | int k = -1; | ||
| 3095 | |||
| 3096 | if (s->right_overhang) | ||
| 3097 | { | ||
| 3098 | int x = 0, i; | ||
| 3099 | struct glyph *glyphs = s->row->glyphs[s->area]; | ||
| 3100 | int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); | ||
| 3101 | int end = s->row->used[s->area]; | ||
| 3102 | |||
| 3103 | for (i = first; i < end && s->right_overhang > x; ++i) | ||
| 3104 | x += glyphs[i].pixel_width; | ||
| 3105 | |||
| 3106 | k = i; | ||
| 3107 | } | ||
| 3108 | |||
| 3109 | return k; | ||
| 3110 | } | ||
| 3111 | |||
| 3112 | |||
| 3113 | /* Return the index of the last glyph following glyph string S that | ||
| 3114 | overwrites S because of its left overhang. Value is negative | ||
| 3115 | if no such glyph is found. */ | ||
| 3116 | |||
| 3117 | static int | ||
| 3118 | x_right_overwriting (s) | ||
| 3119 | struct glyph_string *s; | ||
| 3120 | { | ||
| 3121 | int i, k, x; | ||
| 3122 | int end = s->row->used[s->area]; | ||
| 3123 | struct glyph *glyphs = s->row->glyphs[s->area]; | ||
| 3124 | int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); | ||
| 3125 | |||
| 3126 | k = -1; | ||
| 3127 | x = 0; | ||
| 3128 | for (i = first; i < end; ++i) | ||
| 3129 | { | ||
| 3130 | int left, right; | ||
| 3131 | w32_get_glyph_overhangs (s->hdc, glyphs + i, s->f, &left, &right); | ||
| 3132 | if (x - left < 0) | ||
| 3133 | k = i; | ||
| 3134 | x += glyphs[i].pixel_width; | ||
| 3135 | } | ||
| 3136 | |||
| 3137 | return k; | ||
| 3138 | } | ||
| 3139 | |||
| 3140 | |||
| 3141 | /* Fill rectangle X, Y, W, H with background color of glyph string S. */ | 1610 | /* Fill rectangle X, Y, W, H with background color of glyph string S. */ |
| 3142 | 1611 | ||
| 3143 | static INLINE void | 1612 | static INLINE void |
| @@ -3265,7 +1734,7 @@ x_draw_glyph_string_foreground (s) | |||
| 3265 | /* If we can use 8-bit functions, condense S->char2b. */ | 1734 | /* If we can use 8-bit functions, condense S->char2b. */ |
| 3266 | if (!s->two_byte_p) | 1735 | if (!s->two_byte_p) |
| 3267 | for (i = 0; i < s->nchars; ++i) | 1736 | for (i = 0; i < s->nchars; ++i) |
| 3268 | char1b[i] = BYTE2 (s->char2b[i]); | 1737 | char1b[i] = XCHAR2B_BYTE2 (&s->char2b[i]); |
| 3269 | 1738 | ||
| 3270 | /* Draw text with TextOut and friends. */ | 1739 | /* Draw text with TextOut and friends. */ |
| 3271 | w32_text_out (s, x, s->ybase - boff, s->char2b, s->nchars); | 1740 | w32_text_out (s, x, s->ybase - boff, s->char2b, s->nchars); |
| @@ -4227,663 +2696,6 @@ x_draw_glyph_string (s) | |||
| 4227 | } | 2696 | } |
| 4228 | 2697 | ||
| 4229 | 2698 | ||
| 4230 | static int x_fill_composite_glyph_string P_ ((struct glyph_string *, | ||
| 4231 | struct face **, int)); | ||
| 4232 | |||
| 4233 | |||
| 4234 | /* Fill glyph string S with composition components specified by S->cmp. | ||
| 4235 | |||
| 4236 | FACES is an array of faces for all components of this composition. | ||
| 4237 | S->gidx is the index of the first component for S. | ||
| 4238 | OVERLAPS_P non-zero means S should draw the foreground only, and | ||
| 4239 | use its physical height for clipping. | ||
| 4240 | |||
| 4241 | Value is the index of a component not in S. */ | ||
| 4242 | |||
| 4243 | static int | ||
| 4244 | x_fill_composite_glyph_string (s, faces, overlaps_p) | ||
| 4245 | struct glyph_string *s; | ||
| 4246 | struct face **faces; | ||
| 4247 | int overlaps_p; | ||
| 4248 | { | ||
| 4249 | int i; | ||
| 4250 | |||
| 4251 | xassert (s); | ||
| 4252 | |||
| 4253 | s->for_overlaps_p = overlaps_p; | ||
| 4254 | |||
| 4255 | s->face = faces[s->gidx]; | ||
| 4256 | s->font = s->face->font; | ||
| 4257 | s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | ||
| 4258 | |||
| 4259 | /* For all glyphs of this composition, starting at the offset | ||
| 4260 | S->gidx, until we reach the end of the definition or encounter a | ||
| 4261 | glyph that requires the different face, add it to S. */ | ||
| 4262 | ++s->nchars; | ||
| 4263 | for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i) | ||
| 4264 | ++s->nchars; | ||
| 4265 | |||
| 4266 | /* All glyph strings for the same composition has the same width, | ||
| 4267 | i.e. the width set for the first component of the composition. */ | ||
| 4268 | |||
| 4269 | s->width = s->first_glyph->pixel_width; | ||
| 4270 | |||
| 4271 | /* If the specified font could not be loaded, use the frame's | ||
| 4272 | default font, but record the fact that we couldn't load it in | ||
| 4273 | the glyph string so that we can draw rectangles for the | ||
| 4274 | characters of the glyph string. */ | ||
| 4275 | if (s->font == NULL) | ||
| 4276 | { | ||
| 4277 | s->font_not_found_p = 1; | ||
| 4278 | s->font = FRAME_FONT (s->f); | ||
| 4279 | } | ||
| 4280 | |||
| 4281 | /* Adjust base line for subscript/superscript text. */ | ||
| 4282 | s->ybase += s->first_glyph->voffset; | ||
| 4283 | |||
| 4284 | xassert (s->face && s->face->gc); | ||
| 4285 | |||
| 4286 | /* This glyph string must always be drawn with 16-bit functions. */ | ||
| 4287 | s->two_byte_p = 1; | ||
| 4288 | |||
| 4289 | return s->gidx + s->nchars; | ||
| 4290 | } | ||
| 4291 | |||
| 4292 | |||
| 4293 | /* Fill glyph string S from a sequence of character glyphs. | ||
| 4294 | |||
| 4295 | FACE_ID is the face id of the string. START is the index of the | ||
| 4296 | first glyph to consider, END is the index of the last + 1. | ||
| 4297 | OVERLAPS_P non-zero means S should draw the foreground only, and | ||
| 4298 | use its physical height for clipping. | ||
| 4299 | |||
| 4300 | Value is the index of the first glyph not in S. */ | ||
| 4301 | |||
| 4302 | static int | ||
| 4303 | x_fill_glyph_string (s, face_id, start, end, overlaps_p) | ||
| 4304 | struct glyph_string *s; | ||
| 4305 | int face_id; | ||
| 4306 | int start, end, overlaps_p; | ||
| 4307 | { | ||
| 4308 | struct glyph *glyph, *last; | ||
| 4309 | int voffset; | ||
| 4310 | int glyph_not_available_p; | ||
| 4311 | |||
| 4312 | xassert (s->f == XFRAME (s->w->frame)); | ||
| 4313 | xassert (s->nchars == 0); | ||
| 4314 | xassert (start >= 0 && end > start); | ||
| 4315 | |||
| 4316 | s->for_overlaps_p = overlaps_p; | ||
| 4317 | glyph = s->row->glyphs[s->area] + start; | ||
| 4318 | last = s->row->glyphs[s->area] + end; | ||
| 4319 | voffset = glyph->voffset; | ||
| 4320 | |||
| 4321 | glyph_not_available_p = glyph->glyph_not_available_p; | ||
| 4322 | |||
| 4323 | while (glyph < last | ||
| 4324 | && glyph->type == CHAR_GLYPH | ||
| 4325 | && glyph->voffset == voffset | ||
| 4326 | /* Same face id implies same font, nowadays. */ | ||
| 4327 | && glyph->face_id == face_id | ||
| 4328 | && glyph->glyph_not_available_p == glyph_not_available_p) | ||
| 4329 | { | ||
| 4330 | int two_byte_p; | ||
| 4331 | |||
| 4332 | s->face = x_get_glyph_face_and_encoding (s->f, glyph, | ||
| 4333 | s->char2b + s->nchars, | ||
| 4334 | &two_byte_p); | ||
| 4335 | s->two_byte_p = two_byte_p; | ||
| 4336 | ++s->nchars; | ||
| 4337 | xassert (s->nchars <= end - start); | ||
| 4338 | s->width += glyph->pixel_width; | ||
| 4339 | ++glyph; | ||
| 4340 | } | ||
| 4341 | |||
| 4342 | s->font = s->face->font; | ||
| 4343 | s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | ||
| 4344 | |||
| 4345 | /* If the specified font could not be loaded, use the frame's font, | ||
| 4346 | but record the fact that we couldn't load it in | ||
| 4347 | S->font_not_found_p so that we can draw rectangles for the | ||
| 4348 | characters of the glyph string. */ | ||
| 4349 | if (s->font == NULL || glyph_not_available_p) | ||
| 4350 | { | ||
| 4351 | s->font_not_found_p = 1; | ||
| 4352 | s->font = FRAME_FONT (s->f); | ||
| 4353 | } | ||
| 4354 | |||
| 4355 | /* Adjust base line for subscript/superscript text. */ | ||
| 4356 | s->ybase += voffset; | ||
| 4357 | |||
| 4358 | xassert (s->face && s->face->gc); | ||
| 4359 | return glyph - s->row->glyphs[s->area]; | ||
| 4360 | } | ||
| 4361 | |||
| 4362 | |||
| 4363 | /* Fill glyph string S from image glyph S->first_glyph. */ | ||
| 4364 | |||
| 4365 | static void | ||
| 4366 | x_fill_image_glyph_string (s) | ||
| 4367 | struct glyph_string *s; | ||
| 4368 | { | ||
| 4369 | xassert (s->first_glyph->type == IMAGE_GLYPH); | ||
| 4370 | s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id); | ||
| 4371 | xassert (s->img); | ||
| 4372 | s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id); | ||
| 4373 | s->font = s->face->font; | ||
| 4374 | s->width = s->first_glyph->pixel_width; | ||
| 4375 | |||
| 4376 | /* Adjust base line for subscript/superscript text. */ | ||
| 4377 | s->ybase += s->first_glyph->voffset; | ||
| 4378 | } | ||
| 4379 | |||
| 4380 | |||
| 4381 | /* Fill glyph string S from a sequence of stretch glyphs. | ||
| 4382 | |||
| 4383 | ROW is the glyph row in which the glyphs are found, AREA is the | ||
| 4384 | area within the row. START is the index of the first glyph to | ||
| 4385 | consider, END is the index of the last + 1. | ||
| 4386 | |||
| 4387 | Value is the index of the first glyph not in S. */ | ||
| 4388 | |||
| 4389 | static int | ||
| 4390 | x_fill_stretch_glyph_string (s, row, area, start, end) | ||
| 4391 | struct glyph_string *s; | ||
| 4392 | struct glyph_row *row; | ||
| 4393 | enum glyph_row_area area; | ||
| 4394 | int start, end; | ||
| 4395 | { | ||
| 4396 | struct glyph *glyph, *last; | ||
| 4397 | int voffset, face_id; | ||
| 4398 | |||
| 4399 | xassert (s->first_glyph->type == STRETCH_GLYPH); | ||
| 4400 | |||
| 4401 | glyph = s->row->glyphs[s->area] + start; | ||
| 4402 | last = s->row->glyphs[s->area] + end; | ||
| 4403 | face_id = glyph->face_id; | ||
| 4404 | s->face = FACE_FROM_ID (s->f, face_id); | ||
| 4405 | s->font = s->face->font; | ||
| 4406 | s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | ||
| 4407 | s->width = glyph->pixel_width; | ||
| 4408 | voffset = glyph->voffset; | ||
| 4409 | |||
| 4410 | for (++glyph; | ||
| 4411 | (glyph < last | ||
| 4412 | && glyph->type == STRETCH_GLYPH | ||
| 4413 | && glyph->voffset == voffset | ||
| 4414 | && glyph->face_id == face_id); | ||
| 4415 | ++glyph) | ||
| 4416 | s->width += glyph->pixel_width; | ||
| 4417 | |||
| 4418 | /* Adjust base line for subscript/superscript text. */ | ||
| 4419 | s->ybase += voffset; | ||
| 4420 | |||
| 4421 | xassert (s->face); | ||
| 4422 | return glyph - s->row->glyphs[s->area]; | ||
| 4423 | } | ||
| 4424 | |||
| 4425 | |||
| 4426 | /* Initialize glyph string S. CHAR2B is a suitably allocated vector | ||
| 4427 | of XChar2b structures for S; it can't be allocated in | ||
| 4428 | x_init_glyph_string because it must be allocated via `alloca'. W | ||
| 4429 | is the window on which S is drawn. ROW and AREA are the glyph row | ||
| 4430 | and area within the row from which S is constructed. START is the | ||
| 4431 | index of the first glyph structure covered by S. HL is a | ||
| 4432 | face-override for drawing S. */ | ||
| 4433 | |||
| 4434 | static void | ||
| 4435 | w32_init_glyph_string (s, hdc, char2b, w, row, area, start, hl) | ||
| 4436 | struct glyph_string *s; | ||
| 4437 | HDC hdc; | ||
| 4438 | wchar_t *char2b; | ||
| 4439 | struct window *w; | ||
| 4440 | struct glyph_row *row; | ||
| 4441 | enum glyph_row_area area; | ||
| 4442 | int start; | ||
| 4443 | enum draw_glyphs_face hl; | ||
| 4444 | { | ||
| 4445 | bzero (s, sizeof *s); | ||
| 4446 | s->w = w; | ||
| 4447 | s->f = XFRAME (w->frame); | ||
| 4448 | s->hdc = hdc; | ||
| 4449 | s->window = FRAME_W32_WINDOW (s->f); | ||
| 4450 | s->char2b = char2b; | ||
| 4451 | s->hl = hl; | ||
| 4452 | s->row = row; | ||
| 4453 | s->area = area; | ||
| 4454 | s->first_glyph = row->glyphs[area] + start; | ||
| 4455 | s->height = row->height; | ||
| 4456 | s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); | ||
| 4457 | |||
| 4458 | /* Display the internal border below the tool-bar window. */ | ||
| 4459 | if (s->w == XWINDOW (s->f->tool_bar_window)) | ||
| 4460 | s->y -= s->f->output_data.w32->internal_border_width; | ||
| 4461 | |||
| 4462 | s->ybase = s->y + row->ascent; | ||
| 4463 | } | ||
| 4464 | |||
| 4465 | |||
| 4466 | /* Set background width of glyph string S. START is the index of the | ||
| 4467 | first glyph following S. LAST_X is the right-most x-position + 1 | ||
| 4468 | in the drawing area. */ | ||
| 4469 | |||
| 4470 | static INLINE void | ||
| 4471 | x_set_glyph_string_background_width (s, start, last_x) | ||
| 4472 | struct glyph_string *s; | ||
| 4473 | int start; | ||
| 4474 | int last_x; | ||
| 4475 | { | ||
| 4476 | /* If the face of this glyph string has to be drawn to the end of | ||
| 4477 | the drawing area, set S->extends_to_end_of_line_p. */ | ||
| 4478 | struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID); | ||
| 4479 | |||
| 4480 | if (start == s->row->used[s->area] | ||
| 4481 | && s->area == TEXT_AREA | ||
| 4482 | && ((s->hl == DRAW_NORMAL_TEXT | ||
| 4483 | && (s->row->fill_line_p | ||
| 4484 | || s->face->background != default_face->background | ||
| 4485 | || s->face->stipple != default_face->stipple | ||
| 4486 | || s->row->mouse_face_p)) | ||
| 4487 | || s->hl == DRAW_MOUSE_FACE | ||
| 4488 | || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN) | ||
| 4489 | && s->row->fill_line_p))) | ||
| 4490 | s->extends_to_end_of_line_p = 1; | ||
| 4491 | |||
| 4492 | /* If S extends its face to the end of the line, set its | ||
| 4493 | background_width to the distance to the right edge of the drawing | ||
| 4494 | area. */ | ||
| 4495 | if (s->extends_to_end_of_line_p) | ||
| 4496 | s->background_width = last_x - s->x + 1; | ||
| 4497 | else | ||
| 4498 | s->background_width = s->width; | ||
| 4499 | } | ||
| 4500 | |||
| 4501 | |||
| 4502 | /* Add a glyph string for a stretch glyph to the list of strings | ||
| 4503 | between HEAD and TAIL. START is the index of the stretch glyph in | ||
| 4504 | row area AREA of glyph row ROW. END is the index of the last glyph | ||
| 4505 | in that glyph row area. X is the current output position assigned | ||
| 4506 | to the new glyph string constructed. HL overrides that face of the | ||
| 4507 | glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X | ||
| 4508 | is the right-most x-position of the drawing area. */ | ||
| 4509 | |||
| 4510 | #define BUILD_STRETCH_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \ | ||
| 4511 | do \ | ||
| 4512 | { \ | ||
| 4513 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 4514 | w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \ | ||
| 4515 | START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \ | ||
| 4516 | x_append_glyph_string (&HEAD, &TAIL, s); \ | ||
| 4517 | s->x = (X); \ | ||
| 4518 | } \ | ||
| 4519 | while (0) | ||
| 4520 | |||
| 4521 | |||
| 4522 | /* Add a glyph string for an image glyph to the list of strings | ||
| 4523 | between HEAD and TAIL. START is the index of the image glyph in | ||
| 4524 | row area AREA of glyph row ROW. END is the index of the last glyph | ||
| 4525 | in that glyph row area. X is the current output position assigned | ||
| 4526 | to the new glyph string constructed. HL overrides that face of the | ||
| 4527 | glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X | ||
| 4528 | is the right-most x-position of the drawing area. */ | ||
| 4529 | |||
| 4530 | #define BUILD_IMAGE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \ | ||
| 4531 | do \ | ||
| 4532 | { \ | ||
| 4533 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 4534 | w32_init_glyph_string (s, hdc, NULL, W, ROW, AREA, START, HL); \ | ||
| 4535 | x_fill_image_glyph_string (s); \ | ||
| 4536 | x_append_glyph_string (&HEAD, &TAIL, s); \ | ||
| 4537 | ++START; \ | ||
| 4538 | s->x = (X); \ | ||
| 4539 | } \ | ||
| 4540 | while (0) | ||
| 4541 | |||
| 4542 | |||
| 4543 | /* Add a glyph string for a sequence of character glyphs to the list | ||
| 4544 | of strings between HEAD and TAIL. START is the index of the first | ||
| 4545 | glyph in row area AREA of glyph row ROW that is part of the new | ||
| 4546 | glyph string. END is the index of the last glyph in that glyph row | ||
| 4547 | area. X is the current output position assigned to the new glyph | ||
| 4548 | string constructed. HL overrides that face of the glyph; e.g. it | ||
| 4549 | is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the | ||
| 4550 | right-most x-position of the drawing area. */ | ||
| 4551 | |||
| 4552 | #define BUILD_CHAR_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \ | ||
| 4553 | do \ | ||
| 4554 | { \ | ||
| 4555 | int c, face_id; \ | ||
| 4556 | wchar_t *char2b; \ | ||
| 4557 | \ | ||
| 4558 | c = (ROW)->glyphs[AREA][START].u.ch; \ | ||
| 4559 | face_id = (ROW)->glyphs[AREA][START].face_id; \ | ||
| 4560 | \ | ||
| 4561 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 4562 | char2b = (wchar_t *) alloca ((END - START) * sizeof *char2b); \ | ||
| 4563 | w32_init_glyph_string (s, hdc, char2b, W, ROW, AREA, START, HL); \ | ||
| 4564 | x_append_glyph_string (&HEAD, &TAIL, s); \ | ||
| 4565 | s->x = (X); \ | ||
| 4566 | START = x_fill_glyph_string (s, face_id, START, END, \ | ||
| 4567 | OVERLAPS_P); \ | ||
| 4568 | } \ | ||
| 4569 | while (0) | ||
| 4570 | |||
| 4571 | |||
| 4572 | /* Add a glyph string for a composite sequence to the list of strings | ||
| 4573 | between HEAD and TAIL. START is the index of the first glyph in | ||
| 4574 | row area AREA of glyph row ROW that is part of the new glyph | ||
| 4575 | string. END is the index of the last glyph in that glyph row area. | ||
| 4576 | X is the current output position assigned to the new glyph string | ||
| 4577 | constructed. HL overrides that face of the glyph; e.g. it is | ||
| 4578 | DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most | ||
| 4579 | x-position of the drawing area. */ | ||
| 4580 | |||
| 4581 | #define BUILD_COMPOSITE_GLYPH_STRING(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \ | ||
| 4582 | do { \ | ||
| 4583 | int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \ | ||
| 4584 | int face_id = (ROW)->glyphs[AREA][START].face_id; \ | ||
| 4585 | struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \ | ||
| 4586 | struct composition *cmp = composition_table[cmp_id]; \ | ||
| 4587 | int glyph_len = cmp->glyph_len; \ | ||
| 4588 | wchar_t *char2b; \ | ||
| 4589 | struct face **faces; \ | ||
| 4590 | struct glyph_string *first_s = NULL; \ | ||
| 4591 | int n; \ | ||
| 4592 | \ | ||
| 4593 | base_face = base_face->ascii_face; \ | ||
| 4594 | char2b = (wchar_t *) alloca ((sizeof *char2b) * glyph_len); \ | ||
| 4595 | faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \ | ||
| 4596 | /* At first, fill in `char2b' and `faces'. */ \ | ||
| 4597 | for (n = 0; n < glyph_len; n++) \ | ||
| 4598 | { \ | ||
| 4599 | int c = COMPOSITION_GLYPH (cmp, n); \ | ||
| 4600 | int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \ | ||
| 4601 | faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \ | ||
| 4602 | x_get_char_face_and_encoding (XFRAME (w->frame), c, \ | ||
| 4603 | this_face_id, char2b + n, 1); \ | ||
| 4604 | } \ | ||
| 4605 | \ | ||
| 4606 | /* Make glyph_strings for each glyph sequence that is drawable by \ | ||
| 4607 | the same face, and append them to HEAD/TAIL. */ \ | ||
| 4608 | for (n = 0; n < cmp->glyph_len;) \ | ||
| 4609 | { \ | ||
| 4610 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 4611 | w32_init_glyph_string (s, hdc, char2b + n, W, ROW, AREA, START, HL); \ | ||
| 4612 | x_append_glyph_string (&(HEAD), &(TAIL), s); \ | ||
| 4613 | s->cmp = cmp; \ | ||
| 4614 | s->gidx = n; \ | ||
| 4615 | s->x = (X); \ | ||
| 4616 | \ | ||
| 4617 | if (n == 0) \ | ||
| 4618 | first_s = s; \ | ||
| 4619 | \ | ||
| 4620 | n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \ | ||
| 4621 | } \ | ||
| 4622 | \ | ||
| 4623 | ++START; \ | ||
| 4624 | s = first_s; \ | ||
| 4625 | } while (0) | ||
| 4626 | |||
| 4627 | |||
| 4628 | /* Build a list of glyph strings between HEAD and TAIL for the glyphs | ||
| 4629 | of AREA of glyph row ROW on window W between indices START and END. | ||
| 4630 | HL overrides the face for drawing glyph strings, e.g. it is | ||
| 4631 | DRAW_CURSOR to draw a cursor. X and LAST_X are start and end | ||
| 4632 | x-positions of the drawing area. | ||
| 4633 | |||
| 4634 | This is an ugly monster macro construct because we must use alloca | ||
| 4635 | to allocate glyph strings (because x_draw_glyphs can be called | ||
| 4636 | asynchronously). */ | ||
| 4637 | |||
| 4638 | #define BUILD_GLYPH_STRINGS(hdc, W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \ | ||
| 4639 | do \ | ||
| 4640 | { \ | ||
| 4641 | HEAD = TAIL = NULL; \ | ||
| 4642 | while (START < END) \ | ||
| 4643 | { \ | ||
| 4644 | struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \ | ||
| 4645 | switch (first_glyph->type) \ | ||
| 4646 | { \ | ||
| 4647 | case CHAR_GLYPH: \ | ||
| 4648 | BUILD_CHAR_GLYPH_STRINGS (hdc, W, ROW, AREA, START, END, \ | ||
| 4649 | HEAD, TAIL, HL, X, LAST_X, \ | ||
| 4650 | OVERLAPS_P); \ | ||
| 4651 | break; \ | ||
| 4652 | \ | ||
| 4653 | case COMPOSITE_GLYPH: \ | ||
| 4654 | BUILD_COMPOSITE_GLYPH_STRING (hdc, W, ROW, AREA, START, \ | ||
| 4655 | END, HEAD, TAIL, HL, X, \ | ||
| 4656 | LAST_X, OVERLAPS_P); \ | ||
| 4657 | break; \ | ||
| 4658 | \ | ||
| 4659 | case STRETCH_GLYPH: \ | ||
| 4660 | BUILD_STRETCH_GLYPH_STRING (hdc, W, ROW, AREA, START, END,\ | ||
| 4661 | HEAD, TAIL, HL, X, LAST_X); \ | ||
| 4662 | break; \ | ||
| 4663 | \ | ||
| 4664 | case IMAGE_GLYPH: \ | ||
| 4665 | BUILD_IMAGE_GLYPH_STRING (hdc, W, ROW, AREA, START, END, \ | ||
| 4666 | HEAD, TAIL, HL, X, LAST_X); \ | ||
| 4667 | break; \ | ||
| 4668 | \ | ||
| 4669 | default: \ | ||
| 4670 | abort (); \ | ||
| 4671 | } \ | ||
| 4672 | \ | ||
| 4673 | x_set_glyph_string_background_width (s, START, LAST_X); \ | ||
| 4674 | (X) += s->width; \ | ||
| 4675 | } \ | ||
| 4676 | } \ | ||
| 4677 | while (0) | ||
| 4678 | |||
| 4679 | |||
| 4680 | /* Draw glyphs between START and END in AREA of ROW on window W, | ||
| 4681 | starting at x-position X. X is relative to AREA in W. HL is a | ||
| 4682 | face-override with the following meaning: | ||
| 4683 | |||
| 4684 | DRAW_NORMAL_TEXT draw normally | ||
| 4685 | DRAW_CURSOR draw in cursor face | ||
| 4686 | DRAW_MOUSE_FACE draw in mouse face. | ||
| 4687 | DRAW_INVERSE_VIDEO draw in mode line face | ||
| 4688 | DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it | ||
| 4689 | DRAW_IMAGE_RAISED draw an image with a raised relief around it | ||
| 4690 | |||
| 4691 | If OVERLAPS_P is non-zero, draw only the foreground of characters | ||
| 4692 | and clip to the physical height of ROW. | ||
| 4693 | |||
| 4694 | Value is the x-position reached, relative to AREA of W. */ | ||
| 4695 | |||
| 4696 | static int | ||
| 4697 | x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p) | ||
| 4698 | struct window *w; | ||
| 4699 | int x; | ||
| 4700 | struct glyph_row *row; | ||
| 4701 | enum glyph_row_area area; | ||
| 4702 | int start, end; | ||
| 4703 | enum draw_glyphs_face hl; | ||
| 4704 | int overlaps_p; | ||
| 4705 | { | ||
| 4706 | struct glyph_string *head, *tail; | ||
| 4707 | struct glyph_string *s; | ||
| 4708 | int last_x, area_width; | ||
| 4709 | int x_reached; | ||
| 4710 | int i, j; | ||
| 4711 | HDC hdc = get_frame_dc (XFRAME (WINDOW_FRAME (w))); | ||
| 4712 | |||
| 4713 | /* Let's rather be paranoid than getting a SEGV. */ | ||
| 4714 | end = min (end, row->used[area]); | ||
| 4715 | start = max (0, start); | ||
| 4716 | start = min (end, start); | ||
| 4717 | |||
| 4718 | /* Translate X to frame coordinates. Set last_x to the right | ||
| 4719 | end of the drawing area. */ | ||
| 4720 | if (row->full_width_p) | ||
| 4721 | { | ||
| 4722 | /* X is relative to the left edge of W, without scroll bars | ||
| 4723 | or fringes. */ | ||
| 4724 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | ||
| 4725 | int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f); | ||
| 4726 | |||
| 4727 | x += window_left_x; | ||
| 4728 | area_width = XFASTINT (w->width) * CANON_X_UNIT (f); | ||
| 4729 | last_x = window_left_x + area_width; | ||
| 4730 | |||
| 4731 | if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)) | ||
| 4732 | { | ||
| 4733 | int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f); | ||
| 4734 | if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) | ||
| 4735 | last_x += width; | ||
| 4736 | else | ||
| 4737 | x -= width; | ||
| 4738 | } | ||
| 4739 | |||
| 4740 | x += FRAME_INTERNAL_BORDER_WIDTH (f); | ||
| 4741 | last_x -= FRAME_INTERNAL_BORDER_WIDTH (f); | ||
| 4742 | } | ||
| 4743 | else | ||
| 4744 | { | ||
| 4745 | x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x); | ||
| 4746 | area_width = window_box_width (w, area); | ||
| 4747 | last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width); | ||
| 4748 | } | ||
| 4749 | |||
| 4750 | /* Build a doubly-linked list of glyph_string structures between | ||
| 4751 | head and tail from what we have to draw. Note that the macro | ||
| 4752 | BUILD_GLYPH_STRINGS will modify its start parameter. That's | ||
| 4753 | the reason we use a separate variable `i'. */ | ||
| 4754 | i = start; | ||
| 4755 | BUILD_GLYPH_STRINGS (hdc, w, row, area, i, end, head, tail, hl, x, last_x, | ||
| 4756 | overlaps_p); | ||
| 4757 | if (tail) | ||
| 4758 | x_reached = tail->x + tail->background_width; | ||
| 4759 | else | ||
| 4760 | x_reached = x; | ||
| 4761 | |||
| 4762 | /* If there are any glyphs with lbearing < 0 or rbearing > width in | ||
| 4763 | the row, redraw some glyphs in front or following the glyph | ||
| 4764 | strings built above. */ | ||
| 4765 | if (head && !overlaps_p && row->contains_overlapping_glyphs_p) | ||
| 4766 | { | ||
| 4767 | int dummy_x = 0; | ||
| 4768 | struct glyph_string *h, *t; | ||
| 4769 | |||
| 4770 | /* Compute overhangs for all glyph strings. */ | ||
| 4771 | for (s = head; s; s = s->next) | ||
| 4772 | x_compute_glyph_string_overhangs (s); | ||
| 4773 | |||
| 4774 | /* Prepend glyph strings for glyphs in front of the first glyph | ||
| 4775 | string that are overwritten because of the first glyph | ||
| 4776 | string's left overhang. The background of all strings | ||
| 4777 | prepended must be drawn because the first glyph string | ||
| 4778 | draws over it. */ | ||
| 4779 | i = x_left_overwritten (head); | ||
| 4780 | if (i >= 0) | ||
| 4781 | { | ||
| 4782 | j = i; | ||
| 4783 | BUILD_GLYPH_STRINGS (hdc, w, row, area, j, start, h, t, | ||
| 4784 | DRAW_NORMAL_TEXT, dummy_x, last_x, | ||
| 4785 | overlaps_p); | ||
| 4786 | start = i; | ||
| 4787 | x_compute_overhangs_and_x (t, head->x, 1); | ||
| 4788 | x_prepend_glyph_string_lists (&head, &tail, h, t); | ||
| 4789 | } | ||
| 4790 | |||
| 4791 | /* Prepend glyph strings for glyphs in front of the first glyph | ||
| 4792 | string that overwrite that glyph string because of their | ||
| 4793 | right overhang. For these strings, only the foreground must | ||
| 4794 | be drawn, because it draws over the glyph string at `head'. | ||
| 4795 | The background must not be drawn because this would overwrite | ||
| 4796 | right overhangs of preceding glyphs for which no glyph | ||
| 4797 | strings exist. */ | ||
| 4798 | i = x_left_overwriting (head); | ||
| 4799 | if (i >= 0) | ||
| 4800 | { | ||
| 4801 | BUILD_GLYPH_STRINGS (hdc, w, row, area, i, start, h, t, | ||
| 4802 | DRAW_NORMAL_TEXT, dummy_x, last_x, | ||
| 4803 | overlaps_p); | ||
| 4804 | for (s = h; s; s = s->next) | ||
| 4805 | s->background_filled_p = 1; | ||
| 4806 | x_compute_overhangs_and_x (t, head->x, 1); | ||
| 4807 | x_prepend_glyph_string_lists (&head, &tail, h, t); | ||
| 4808 | } | ||
| 4809 | |||
| 4810 | /* Append glyphs strings for glyphs following the last glyph | ||
| 4811 | string tail that are overwritten by tail. The background of | ||
| 4812 | these strings has to be drawn because tail's foreground draws | ||
| 4813 | over it. */ | ||
| 4814 | i = x_right_overwritten (tail); | ||
| 4815 | if (i >= 0) | ||
| 4816 | { | ||
| 4817 | BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t, | ||
| 4818 | DRAW_NORMAL_TEXT, x, last_x, | ||
| 4819 | overlaps_p); | ||
| 4820 | x_compute_overhangs_and_x (h, tail->x + tail->width, 0); | ||
| 4821 | x_append_glyph_string_lists (&head, &tail, h, t); | ||
| 4822 | } | ||
| 4823 | |||
| 4824 | /* Append glyph strings for glyphs following the last glyph | ||
| 4825 | string tail that overwrite tail. The foreground of such | ||
| 4826 | glyphs has to be drawn because it writes into the background | ||
| 4827 | of tail. The background must not be drawn because it could | ||
| 4828 | paint over the foreground of following glyphs. */ | ||
| 4829 | i = x_right_overwriting (tail); | ||
| 4830 | if (i >= 0) | ||
| 4831 | { | ||
| 4832 | BUILD_GLYPH_STRINGS (hdc, w, row, area, end, i, h, t, | ||
| 4833 | DRAW_NORMAL_TEXT, x, last_x, | ||
| 4834 | overlaps_p); | ||
| 4835 | for (s = h; s; s = s->next) | ||
| 4836 | s->background_filled_p = 1; | ||
| 4837 | x_compute_overhangs_and_x (h, tail->x + tail->width, 0); | ||
| 4838 | x_append_glyph_string_lists (&head, &tail, h, t); | ||
| 4839 | } | ||
| 4840 | } | ||
| 4841 | |||
| 4842 | /* Draw all strings. */ | ||
| 4843 | for (s = head; s; s = s->next) | ||
| 4844 | x_draw_glyph_string (s); | ||
| 4845 | |||
| 4846 | if (area == TEXT_AREA | ||
| 4847 | && !row->full_width_p | ||
| 4848 | /* When drawing overlapping rows, only the glyph strings' | ||
| 4849 | foreground is drawn, which doesn't erase a cursor | ||
| 4850 | completely. */ | ||
| 4851 | && !overlaps_p) | ||
| 4852 | { | ||
| 4853 | int x0 = head ? head->x : x; | ||
| 4854 | int x1 = tail ? tail->x + tail->background_width : x; | ||
| 4855 | |||
| 4856 | x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0); | ||
| 4857 | x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1); | ||
| 4858 | |||
| 4859 | if (!row->full_width_p && XFASTINT (w->left_margin_width) != 0) | ||
| 4860 | { | ||
| 4861 | int left_area_width = window_box_width (w, LEFT_MARGIN_AREA); | ||
| 4862 | x0 -= left_area_width; | ||
| 4863 | x1 -= left_area_width; | ||
| 4864 | } | ||
| 4865 | |||
| 4866 | notice_overwritten_cursor (w, area, x0, x1, | ||
| 4867 | row->y, MATRIX_ROW_BOTTOM_Y (row)); | ||
| 4868 | } | ||
| 4869 | |||
| 4870 | /* Value is the x-position up to which drawn, relative to AREA of W. | ||
| 4871 | This doesn't include parts drawn because of overhangs. */ | ||
| 4872 | x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached); | ||
| 4873 | if (!row->full_width_p) | ||
| 4874 | { | ||
| 4875 | if (area > LEFT_MARGIN_AREA) | ||
| 4876 | x_reached -= window_box_width (w, LEFT_MARGIN_AREA); | ||
| 4877 | if (area > TEXT_AREA) | ||
| 4878 | x_reached -= window_box_width (w, TEXT_AREA); | ||
| 4879 | } | ||
| 4880 | |||
| 4881 | release_frame_dc (XFRAME (WINDOW_FRAME (w)), hdc); | ||
| 4882 | |||
| 4883 | return x_reached; | ||
| 4884 | } | ||
| 4885 | |||
| 4886 | |||
| 4887 | /* Fix the display of area AREA of overlapping row ROW in window W. */ | 2699 | /* Fix the display of area AREA of overlapping row ROW in window W. */ |
| 4888 | 2700 | ||
| 4889 | static void | 2701 | static void |
| @@ -5206,7 +3018,6 @@ w32_set_terminal_window (n) | |||
| 5206 | { | 3018 | { |
| 5207 | /* This function intentionally left blank. */ | 3019 | /* This function intentionally left blank. */ |
| 5208 | } | 3020 | } |
| 5209 | |||
| 5210 | 3021 | ||
| 5211 | 3022 | ||
| 5212 | /*********************************************************************** | 3023 | /*********************************************************************** |
| @@ -9173,52 +6984,6 @@ w32_read_socket (sd, bufp, numchars, expected) | |||
| 9173 | Text Cursor | 6984 | Text Cursor |
| 9174 | ***********************************************************************/ | 6985 | ***********************************************************************/ |
| 9175 | 6986 | ||
| 9176 | /* Notice when the text cursor of window W has been completely | ||
| 9177 | overwritten by a drawing operation that outputs glyphs in AREA | ||
| 9178 | starting at X0 and ending at X1 in the line starting at Y0 and | ||
| 9179 | ending at Y1. X coordinates are area-relative. X1 < 0 means all | ||
| 9180 | the rest of the line after X0 has been written. Y coordinates | ||
| 9181 | are window-relative. */ | ||
| 9182 | |||
| 9183 | static void | ||
| 9184 | notice_overwritten_cursor (w, area, x0, x1, y0, y1) | ||
| 9185 | struct window *w; | ||
| 9186 | enum glyph_row_area area; | ||
| 9187 | int x0, x1, y0, y1; | ||
| 9188 | { | ||
| 9189 | if (area == TEXT_AREA && w->phys_cursor_on_p) | ||
| 9190 | { | ||
| 9191 | int cx0 = w->phys_cursor.x; | ||
| 9192 | int cx1 = cx0 + w->phys_cursor_width; | ||
| 9193 | int cy0 = w->phys_cursor.y; | ||
| 9194 | int cy1 = cy0 + w->phys_cursor_height; | ||
| 9195 | |||
| 9196 | if (x0 <= cx0 && (x1 < 0 || x1 >= cx1)) | ||
| 9197 | { | ||
| 9198 | /* The cursor image will be completely removed from the | ||
| 9199 | screen if the output area intersects the cursor area in | ||
| 9200 | y-direction. When we draw in [y0 y1[, and some part of | ||
| 9201 | the cursor is at y < y0, that part must have been drawn | ||
| 9202 | before. When scrolling, the cursor is erased before | ||
| 9203 | actually scrolling, so we don't come here. When not | ||
| 9204 | scrolling, the rows above the old cursor row must have | ||
| 9205 | changed, and in this case these rows must have written | ||
| 9206 | over the cursor image. | ||
| 9207 | |||
| 9208 | Likewise if part of the cursor is below y1, with the | ||
| 9209 | exception of the cursor being in the first blank row at | ||
| 9210 | the buffer and window end because update_text_area | ||
| 9211 | doesn't draw that row. (Except when it does, but | ||
| 9212 | that's handled in update_text_area.) */ | ||
| 9213 | |||
| 9214 | if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1)) | ||
| 9215 | && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p) | ||
| 9216 | w->phys_cursor_on_p = 0; | ||
| 9217 | } | ||
| 9218 | } | ||
| 9219 | } | ||
| 9220 | |||
| 9221 | |||
| 9222 | /* Set clipping for output in glyph row ROW. W is the window in which | 6987 | /* Set clipping for output in glyph row ROW. W is the window in which |
| 9223 | we operate. GC is the graphics context to set clipping in. | 6988 | we operate. GC is the graphics context to set clipping in. |
| 9224 | WHOLE_LINE_P non-zero means include the areas used for truncation | 6989 | WHOLE_LINE_P non-zero means include the areas used for truncation |
| @@ -11041,9 +8806,13 @@ static struct redisplay_interface w32_redisplay_interface = | |||
| 11041 | w32_cursor_to, | 8806 | w32_cursor_to, |
| 11042 | x_flush, | 8807 | x_flush, |
| 11043 | x_clear_mouse_face, | 8808 | x_clear_mouse_face, |
| 11044 | x_get_glyph_overhangs, | 8809 | w32_get_glyph_overhangs, |
| 11045 | x_fix_overlapping_area, | 8810 | x_fix_overlapping_area, |
| 11046 | w32_draw_fringe_bitmap | 8811 | w32_draw_fringe_bitmap, |
| 8812 | w32_per_char_metric, | ||
| 8813 | w32_encode_char, | ||
| 8814 | NULL, /* w32_compute_glyph_string_overhangs */ | ||
| 8815 | x_draw_glyph_string | ||
| 11047 | }; | 8816 | }; |
| 11048 | 8817 | ||
| 11049 | void | 8818 | void |