Mercurial > emacs
comparison src/xdisp.c @ 50150:288ffa39e234
Consolidate gui-independent "glyph string" code here.
(dump_glyph_string): Moved here.
(init_glyph_string, append_glyph_string_lists, append_glyph_string)
(prepend_glyph_string_lists, get_glyph_face_and_encoding)
(fill_composite_glyph_string, fill_glyph_string)
(fill_image_glyph_string, fill_stretch_glyph_string)
(left_overwritten, left_overwriting, right_overwritten)
(right_overwriting, get_char_face_and_encoding)
(set_glyph_string_background_width, compute_overhangs_and_x)
(append_glyph, append_composite_glyph, produce_image_glyph)
(take_vertical_position_into_account, append_stretch_glyph)
(produce_stretch_glyph): New generic functions (based on X version).
Call platform specific functions through rif.
(INIT_GLYPH_STRING): New macro, hides W32 details.
(BUILD_STRETCH_GLYPH_STRING, BUILD_IMAGE_GLYPH_STRING)
(BUILD_CHAR_GLYPH_STRINGS, BUILD_COMPOSITE_GLYPH_STRING)
(BUILD_GLYPH_STRINGS): Generic macros (based on X version).
(x_draw_glyphs, x_get_glyph_overhangs, x_produce_glyphs)
(notice_overwritten_cursor):
Generic functions exported to platform modules. Users changed.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Sun, 16 Mar 2003 20:45:46 +0000 |
parents | 784ca069adf2 |
children | 9eab4eab96b9 |
comparison
equal
deleted
inserted
replaced
50149:5d83d663737a | 50150:288ffa39e234 |
---|---|
278 | 278 |
279 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height; | 279 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height; |
280 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise; | 280 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise; |
281 Lisp_Object Qmargin; | 281 Lisp_Object Qmargin; |
282 extern Lisp_Object Qheight; | 282 extern Lisp_Object Qheight; |
283 extern Lisp_Object QCwidth, QCheight, QCascent; | |
283 | 284 |
284 /* Non-nil means highlight trailing whitespace. */ | 285 /* Non-nil means highlight trailing whitespace. */ |
285 | 286 |
286 Lisp_Object Vshow_trailing_whitespace; | 287 Lisp_Object Vshow_trailing_whitespace; |
287 | 288 |
15658 return 0; | 15659 return 0; |
15659 } | 15660 } |
15660 | 15661 |
15661 | 15662 |
15662 /*********************************************************************** | 15663 /*********************************************************************** |
15664 Glyph Display | |
15665 ***********************************************************************/ | |
15666 | |
15667 #if GLYPH_DEBUG | |
15668 | |
15669 void | |
15670 dump_glyph_string (s) | |
15671 struct glyph_string *s; | |
15672 { | |
15673 fprintf (stderr, "glyph string\n"); | |
15674 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n", | |
15675 s->x, s->y, s->width, s->height); | |
15676 fprintf (stderr, " ybase = %d\n", s->ybase); | |
15677 fprintf (stderr, " hl = %d\n", s->hl); | |
15678 fprintf (stderr, " left overhang = %d, right = %d\n", | |
15679 s->left_overhang, s->right_overhang); | |
15680 fprintf (stderr, " nchars = %d\n", s->nchars); | |
15681 fprintf (stderr, " extends to end of line = %d\n", | |
15682 s->extends_to_end_of_line_p); | |
15683 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font)); | |
15684 fprintf (stderr, " bg width = %d\n", s->background_width); | |
15685 } | |
15686 | |
15687 #endif /* GLYPH_DEBUG */ | |
15688 | |
15689 /* Initialize glyph string S. CHAR2B is a suitably allocated vector | |
15690 of XChar2b structures for S; it can't be allocated in | |
15691 init_glyph_string because it must be allocated via `alloca'. W | |
15692 is the window on which S is drawn. ROW and AREA are the glyph row | |
15693 and area within the row from which S is constructed. START is the | |
15694 index of the first glyph structure covered by S. HL is a | |
15695 face-override for drawing S. */ | |
15696 | |
15697 #ifdef HAVE_NTGUI | |
15698 #define OPTIONAL_HDC(hdc) hdc, | |
15699 #define DECLARE_HDC(hdc) HDC hdc; | |
15700 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f)) | |
15701 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc)) | |
15702 #endif | |
15703 | |
15704 #ifndef OPTIONAL_HDC | |
15705 #define OPTIONAL_HDC(hdc) | |
15706 #define DECLARE_HDC(hdc) | |
15707 #define ALLOCATE_HDC(hdc, f) | |
15708 #define RELEASE_HDC(hdc, f) | |
15709 #endif | |
15710 | |
15711 static void | |
15712 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl) | |
15713 struct glyph_string *s; | |
15714 DECLARE_HDC (hdc) | |
15715 XChar2b *char2b; | |
15716 struct window *w; | |
15717 struct glyph_row *row; | |
15718 enum glyph_row_area area; | |
15719 int start; | |
15720 enum draw_glyphs_face hl; | |
15721 { | |
15722 bzero (s, sizeof *s); | |
15723 s->w = w; | |
15724 s->f = XFRAME (w->frame); | |
15725 #ifdef HAVE_NTGUI | |
15726 s->hdc = hdc; | |
15727 #endif | |
15728 s->display = FRAME_X_DISPLAY (s->f); | |
15729 s->window = FRAME_X_WINDOW (s->f); | |
15730 s->char2b = char2b; | |
15731 s->hl = hl; | |
15732 s->row = row; | |
15733 s->area = area; | |
15734 s->first_glyph = row->glyphs[area] + start; | |
15735 s->height = row->height; | |
15736 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); | |
15737 | |
15738 /* Display the internal border below the tool-bar window. */ | |
15739 if (s->w == XWINDOW (s->f->tool_bar_window)) | |
15740 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f); | |
15741 | |
15742 s->ybase = s->y + row->ascent; | |
15743 } | |
15744 | |
15745 | |
15746 /* Append the list of glyph strings with head H and tail T to the list | |
15747 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */ | |
15748 | |
15749 static INLINE void | |
15750 append_glyph_string_lists (head, tail, h, t) | |
15751 struct glyph_string **head, **tail; | |
15752 struct glyph_string *h, *t; | |
15753 { | |
15754 if (h) | |
15755 { | |
15756 if (*head) | |
15757 (*tail)->next = h; | |
15758 else | |
15759 *head = h; | |
15760 h->prev = *tail; | |
15761 *tail = t; | |
15762 } | |
15763 } | |
15764 | |
15765 | |
15766 /* Prepend the list of glyph strings with head H and tail T to the | |
15767 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the | |
15768 result. */ | |
15769 | |
15770 static INLINE void | |
15771 prepend_glyph_string_lists (head, tail, h, t) | |
15772 struct glyph_string **head, **tail; | |
15773 struct glyph_string *h, *t; | |
15774 { | |
15775 if (h) | |
15776 { | |
15777 if (*head) | |
15778 (*head)->prev = t; | |
15779 else | |
15780 *tail = t; | |
15781 t->next = *head; | |
15782 *head = h; | |
15783 } | |
15784 } | |
15785 | |
15786 | |
15787 /* Append glyph string S to the list with head *HEAD and tail *TAIL. | |
15788 Set *HEAD and *TAIL to the resulting list. */ | |
15789 | |
15790 static INLINE void | |
15791 append_glyph_string (head, tail, s) | |
15792 struct glyph_string **head, **tail; | |
15793 struct glyph_string *s; | |
15794 { | |
15795 s->next = s->prev = NULL; | |
15796 append_glyph_string_lists (head, tail, s, s); | |
15797 } | |
15798 | |
15799 | |
15800 /* Get face and two-byte form of character glyph GLYPH on frame F. | |
15801 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is | |
15802 a pointer to a realized face that is ready for display. */ | |
15803 | |
15804 static INLINE struct face * | |
15805 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p) | |
15806 struct frame *f; | |
15807 struct glyph *glyph; | |
15808 XChar2b *char2b; | |
15809 int *two_byte_p; | |
15810 { | |
15811 struct face *face; | |
15812 | |
15813 xassert (glyph->type == CHAR_GLYPH); | |
15814 face = FACE_FROM_ID (f, glyph->face_id); | |
15815 | |
15816 if (two_byte_p) | |
15817 *two_byte_p = 0; | |
15818 | |
15819 if (!glyph->multibyte_p) | |
15820 { | |
15821 /* Unibyte case. We don't have to encode, but we have to make | |
15822 sure to use a face suitable for unibyte. */ | |
15823 STORE_XCHAR2B (char2b, 0, glyph->u.ch); | |
15824 } | |
15825 else if (glyph->u.ch < 128 | |
15826 && glyph->face_id < BASIC_FACE_ID_SENTINEL) | |
15827 { | |
15828 /* Case of ASCII in a face known to fit ASCII. */ | |
15829 STORE_XCHAR2B (char2b, 0, glyph->u.ch); | |
15830 } | |
15831 else | |
15832 { | |
15833 int c1, c2, charset; | |
15834 | |
15835 /* Split characters into bytes. If c2 is -1 afterwards, C is | |
15836 really a one-byte character so that byte1 is zero. */ | |
15837 SPLIT_CHAR (glyph->u.ch, charset, c1, c2); | |
15838 if (c2 > 0) | |
15839 STORE_XCHAR2B (char2b, c1, c2); | |
15840 else | |
15841 STORE_XCHAR2B (char2b, 0, c1); | |
15842 | |
15843 /* Maybe encode the character in *CHAR2B. */ | |
15844 if (charset != CHARSET_ASCII) | |
15845 { | |
15846 struct font_info *font_info | |
15847 = FONT_INFO_FROM_ID (f, face->font_info_id); | |
15848 if (font_info) | |
15849 glyph->font_type | |
15850 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p); | |
15851 } | |
15852 } | |
15853 | |
15854 /* Make sure X resources of the face are allocated. */ | |
15855 xassert (face != NULL); | |
15856 PREPARE_FACE_FOR_DISPLAY (f, face); | |
15857 return face; | |
15858 } | |
15859 | |
15860 | |
15861 /* Fill glyph string S with composition components specified by S->cmp. | |
15862 | |
15863 FACES is an array of faces for all components of this composition. | |
15864 S->gidx is the index of the first component for S. | |
15865 OVERLAPS_P non-zero means S should draw the foreground only, and | |
15866 use its physical height for clipping. | |
15867 | |
15868 Value is the index of a component not in S. */ | |
15869 | |
15870 static int | |
15871 fill_composite_glyph_string (s, faces, overlaps_p) | |
15872 struct glyph_string *s; | |
15873 struct face **faces; | |
15874 int overlaps_p; | |
15875 { | |
15876 int i; | |
15877 | |
15878 xassert (s); | |
15879 | |
15880 s->for_overlaps_p = overlaps_p; | |
15881 | |
15882 s->face = faces[s->gidx]; | |
15883 s->font = s->face->font; | |
15884 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | |
15885 | |
15886 /* For all glyphs of this composition, starting at the offset | |
15887 S->gidx, until we reach the end of the definition or encounter a | |
15888 glyph that requires the different face, add it to S. */ | |
15889 ++s->nchars; | |
15890 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i) | |
15891 ++s->nchars; | |
15892 | |
15893 /* All glyph strings for the same composition has the same width, | |
15894 i.e. the width set for the first component of the composition. */ | |
15895 | |
15896 s->width = s->first_glyph->pixel_width; | |
15897 | |
15898 /* If the specified font could not be loaded, use the frame's | |
15899 default font, but record the fact that we couldn't load it in | |
15900 the glyph string so that we can draw rectangles for the | |
15901 characters of the glyph string. */ | |
15902 if (s->font == NULL) | |
15903 { | |
15904 s->font_not_found_p = 1; | |
15905 s->font = FRAME_FONT (s->f); | |
15906 } | |
15907 | |
15908 /* Adjust base line for subscript/superscript text. */ | |
15909 s->ybase += s->first_glyph->voffset; | |
15910 | |
15911 xassert (s->face && s->face->gc); | |
15912 | |
15913 /* This glyph string must always be drawn with 16-bit functions. */ | |
15914 s->two_byte_p = 1; | |
15915 | |
15916 return s->gidx + s->nchars; | |
15917 } | |
15918 | |
15919 | |
15920 /* Fill glyph string S from a sequence of character glyphs. | |
15921 | |
15922 FACE_ID is the face id of the string. START is the index of the | |
15923 first glyph to consider, END is the index of the last + 1. | |
15924 OVERLAPS_P non-zero means S should draw the foreground only, and | |
15925 use its physical height for clipping. | |
15926 | |
15927 Value is the index of the first glyph not in S. */ | |
15928 | |
15929 static int | |
15930 fill_glyph_string (s, face_id, start, end, overlaps_p) | |
15931 struct glyph_string *s; | |
15932 int face_id; | |
15933 int start, end, overlaps_p; | |
15934 { | |
15935 struct glyph *glyph, *last; | |
15936 int voffset; | |
15937 int glyph_not_available_p; | |
15938 | |
15939 xassert (s->f == XFRAME (s->w->frame)); | |
15940 xassert (s->nchars == 0); | |
15941 xassert (start >= 0 && end > start); | |
15942 | |
15943 s->for_overlaps_p = overlaps_p, | |
15944 glyph = s->row->glyphs[s->area] + start; | |
15945 last = s->row->glyphs[s->area] + end; | |
15946 voffset = glyph->voffset; | |
15947 | |
15948 glyph_not_available_p = glyph->glyph_not_available_p; | |
15949 | |
15950 while (glyph < last | |
15951 && glyph->type == CHAR_GLYPH | |
15952 && glyph->voffset == voffset | |
15953 /* Same face id implies same font, nowadays. */ | |
15954 && glyph->face_id == face_id | |
15955 && glyph->glyph_not_available_p == glyph_not_available_p) | |
15956 { | |
15957 int two_byte_p; | |
15958 | |
15959 s->face = get_glyph_face_and_encoding (s->f, glyph, | |
15960 s->char2b + s->nchars, | |
15961 &two_byte_p); | |
15962 s->two_byte_p = two_byte_p; | |
15963 ++s->nchars; | |
15964 xassert (s->nchars <= end - start); | |
15965 s->width += glyph->pixel_width; | |
15966 ++glyph; | |
15967 } | |
15968 | |
15969 s->font = s->face->font; | |
15970 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | |
15971 | |
15972 /* If the specified font could not be loaded, use the frame's font, | |
15973 but record the fact that we couldn't load it in | |
15974 S->font_not_found_p so that we can draw rectangles for the | |
15975 characters of the glyph string. */ | |
15976 if (s->font == NULL || glyph_not_available_p) | |
15977 { | |
15978 s->font_not_found_p = 1; | |
15979 s->font = FRAME_FONT (s->f); | |
15980 } | |
15981 | |
15982 /* Adjust base line for subscript/superscript text. */ | |
15983 s->ybase += voffset; | |
15984 | |
15985 xassert (s->face && s->face->gc); | |
15986 return glyph - s->row->glyphs[s->area]; | |
15987 } | |
15988 | |
15989 | |
15990 /* Fill glyph string S from image glyph S->first_glyph. */ | |
15991 | |
15992 static void | |
15993 fill_image_glyph_string (s) | |
15994 struct glyph_string *s; | |
15995 { | |
15996 xassert (s->first_glyph->type == IMAGE_GLYPH); | |
15997 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id); | |
15998 xassert (s->img); | |
15999 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id); | |
16000 s->font = s->face->font; | |
16001 s->width = s->first_glyph->pixel_width; | |
16002 | |
16003 /* Adjust base line for subscript/superscript text. */ | |
16004 s->ybase += s->first_glyph->voffset; | |
16005 } | |
16006 | |
16007 | |
16008 /* Fill glyph string S from a sequence of stretch glyphs. | |
16009 | |
16010 ROW is the glyph row in which the glyphs are found, AREA is the | |
16011 area within the row. START is the index of the first glyph to | |
16012 consider, END is the index of the last + 1. | |
16013 | |
16014 Value is the index of the first glyph not in S. */ | |
16015 | |
16016 static int | |
16017 fill_stretch_glyph_string (s, row, area, start, end) | |
16018 struct glyph_string *s; | |
16019 struct glyph_row *row; | |
16020 enum glyph_row_area area; | |
16021 int start, end; | |
16022 { | |
16023 struct glyph *glyph, *last; | |
16024 int voffset, face_id; | |
16025 | |
16026 xassert (s->first_glyph->type == STRETCH_GLYPH); | |
16027 | |
16028 glyph = s->row->glyphs[s->area] + start; | |
16029 last = s->row->glyphs[s->area] + end; | |
16030 face_id = glyph->face_id; | |
16031 s->face = FACE_FROM_ID (s->f, face_id); | |
16032 s->font = s->face->font; | |
16033 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | |
16034 s->width = glyph->pixel_width; | |
16035 voffset = glyph->voffset; | |
16036 | |
16037 for (++glyph; | |
16038 (glyph < last | |
16039 && glyph->type == STRETCH_GLYPH | |
16040 && glyph->voffset == voffset | |
16041 && glyph->face_id == face_id); | |
16042 ++glyph) | |
16043 s->width += glyph->pixel_width; | |
16044 | |
16045 /* Adjust base line for subscript/superscript text. */ | |
16046 s->ybase += voffset; | |
16047 | |
16048 /* The case that face->gc == 0 is handled when drawing the glyph | |
16049 string by calling PREPARE_FACE_FOR_DISPLAY. */ | |
16050 xassert (s->face); | |
16051 return glyph - s->row->glyphs[s->area]; | |
16052 } | |
16053 | |
16054 | |
16055 /* EXPORT for RIF: | |
16056 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on | |
16057 frame F. Overhangs of glyphs other than type CHAR_GLYPH are | |
16058 assumed to be zero. */ | |
16059 | |
16060 void | |
16061 x_get_glyph_overhangs (glyph, f, left, right) | |
16062 struct glyph *glyph; | |
16063 struct frame *f; | |
16064 int *left, *right; | |
16065 { | |
16066 *left = *right = 0; | |
16067 | |
16068 if (glyph->type == CHAR_GLYPH) | |
16069 { | |
16070 XFontStruct *font; | |
16071 struct face *face; | |
16072 struct font_info *font_info; | |
16073 XChar2b char2b; | |
16074 XCharStruct *pcm; | |
16075 | |
16076 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL); | |
16077 font = face->font; | |
16078 font_info = FONT_INFO_FROM_ID (f, face->font_info_id); | |
16079 if (font /* ++KFS: Should this be font_info ? */ | |
16080 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type))) | |
16081 { | |
16082 if (pcm->rbearing > pcm->width) | |
16083 *right = pcm->rbearing - pcm->width; | |
16084 if (pcm->lbearing < 0) | |
16085 *left = -pcm->lbearing; | |
16086 } | |
16087 } | |
16088 } | |
16089 | |
16090 | |
16091 /* Return the index of the first glyph preceding glyph string S that | |
16092 is overwritten by S because of S's left overhang. Value is -1 | |
16093 if no glyphs are overwritten. */ | |
16094 | |
16095 static int | |
16096 left_overwritten (s) | |
16097 struct glyph_string *s; | |
16098 { | |
16099 int k; | |
16100 | |
16101 if (s->left_overhang) | |
16102 { | |
16103 int x = 0, i; | |
16104 struct glyph *glyphs = s->row->glyphs[s->area]; | |
16105 int first = s->first_glyph - glyphs; | |
16106 | |
16107 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i) | |
16108 x -= glyphs[i].pixel_width; | |
16109 | |
16110 k = i + 1; | |
16111 } | |
16112 else | |
16113 k = -1; | |
16114 | |
16115 return k; | |
16116 } | |
16117 | |
16118 | |
16119 /* Return the index of the first glyph preceding glyph string S that | |
16120 is overwriting S because of its right overhang. Value is -1 if no | |
16121 glyph in front of S overwrites S. */ | |
16122 | |
16123 static int | |
16124 left_overwriting (s) | |
16125 struct glyph_string *s; | |
16126 { | |
16127 int i, k, x; | |
16128 struct glyph *glyphs = s->row->glyphs[s->area]; | |
16129 int first = s->first_glyph - glyphs; | |
16130 | |
16131 k = -1; | |
16132 x = 0; | |
16133 for (i = first - 1; i >= 0; --i) | |
16134 { | |
16135 int left, right; | |
16136 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right); | |
16137 if (x + right > 0) | |
16138 k = i; | |
16139 x -= glyphs[i].pixel_width; | |
16140 } | |
16141 | |
16142 return k; | |
16143 } | |
16144 | |
16145 | |
16146 /* Return the index of the last glyph following glyph string S that is | |
16147 not overwritten by S because of S's right overhang. Value is -1 if | |
16148 no such glyph is found. */ | |
16149 | |
16150 static int | |
16151 right_overwritten (s) | |
16152 struct glyph_string *s; | |
16153 { | |
16154 int k = -1; | |
16155 | |
16156 if (s->right_overhang) | |
16157 { | |
16158 int x = 0, i; | |
16159 struct glyph *glyphs = s->row->glyphs[s->area]; | |
16160 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); | |
16161 int end = s->row->used[s->area]; | |
16162 | |
16163 for (i = first; i < end && s->right_overhang > x; ++i) | |
16164 x += glyphs[i].pixel_width; | |
16165 | |
16166 k = i; | |
16167 } | |
16168 | |
16169 return k; | |
16170 } | |
16171 | |
16172 | |
16173 /* Return the index of the last glyph following glyph string S that | |
16174 overwrites S because of its left overhang. Value is negative | |
16175 if no such glyph is found. */ | |
16176 | |
16177 static int | |
16178 right_overwriting (s) | |
16179 struct glyph_string *s; | |
16180 { | |
16181 int i, k, x; | |
16182 int end = s->row->used[s->area]; | |
16183 struct glyph *glyphs = s->row->glyphs[s->area]; | |
16184 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); | |
16185 | |
16186 k = -1; | |
16187 x = 0; | |
16188 for (i = first; i < end; ++i) | |
16189 { | |
16190 int left, right; | |
16191 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right); | |
16192 if (x - left < 0) | |
16193 k = i; | |
16194 x += glyphs[i].pixel_width; | |
16195 } | |
16196 | |
16197 return k; | |
16198 } | |
16199 | |
16200 | |
16201 /* Get face and two-byte form of character C in face FACE_ID on frame | |
16202 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero | |
16203 means we want to display multibyte text. DISPLAY_P non-zero means | |
16204 make sure that X resources for the face returned are allocated. | |
16205 Value is a pointer to a realized face that is ready for display if | |
16206 DISPLAY_P is non-zero. */ | |
16207 | |
16208 static INLINE struct face * | |
16209 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p) | |
16210 struct frame *f; | |
16211 int c, face_id; | |
16212 XChar2b *char2b; | |
16213 int multibyte_p, display_p; | |
16214 { | |
16215 struct face *face = FACE_FROM_ID (f, face_id); | |
16216 | |
16217 if (!multibyte_p) | |
16218 { | |
16219 /* Unibyte case. We don't have to encode, but we have to make | |
16220 sure to use a face suitable for unibyte. */ | |
16221 STORE_XCHAR2B (char2b, 0, c); | |
16222 face_id = FACE_FOR_CHAR (f, face, c); | |
16223 face = FACE_FROM_ID (f, face_id); | |
16224 } | |
16225 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL) | |
16226 { | |
16227 /* Case of ASCII in a face known to fit ASCII. */ | |
16228 STORE_XCHAR2B (char2b, 0, c); | |
16229 } | |
16230 else | |
16231 { | |
16232 int c1, c2, charset; | |
16233 | |
16234 /* Split characters into bytes. If c2 is -1 afterwards, C is | |
16235 really a one-byte character so that byte1 is zero. */ | |
16236 SPLIT_CHAR (c, charset, c1, c2); | |
16237 if (c2 > 0) | |
16238 STORE_XCHAR2B (char2b, c1, c2); | |
16239 else | |
16240 STORE_XCHAR2B (char2b, 0, c1); | |
16241 | |
16242 /* Maybe encode the character in *CHAR2B. */ | |
16243 if (face->font != NULL) | |
16244 { | |
16245 struct font_info *font_info | |
16246 = FONT_INFO_FROM_ID (f, face->font_info_id); | |
16247 if (font_info) | |
16248 rif->encode_char (c, char2b, font_info, 0); | |
16249 } | |
16250 } | |
16251 | |
16252 /* Make sure X resources of the face are allocated. */ | |
16253 #ifdef HAVE_X_WINDOWS | |
16254 if (display_p) | |
16255 #endif | |
16256 { | |
16257 xassert (face != NULL); | |
16258 PREPARE_FACE_FOR_DISPLAY (f, face); | |
16259 } | |
16260 | |
16261 return face; | |
16262 } | |
16263 | |
16264 | |
16265 /* Set background width of glyph string S. START is the index of the | |
16266 first glyph following S. LAST_X is the right-most x-position + 1 | |
16267 in the drawing area. */ | |
16268 | |
16269 static INLINE void | |
16270 set_glyph_string_background_width (s, start, last_x) | |
16271 struct glyph_string *s; | |
16272 int start; | |
16273 int last_x; | |
16274 { | |
16275 /* If the face of this glyph string has to be drawn to the end of | |
16276 the drawing area, set S->extends_to_end_of_line_p. */ | |
16277 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID); | |
16278 | |
16279 if (start == s->row->used[s->area] | |
16280 && s->area == TEXT_AREA | |
16281 && ((s->hl == DRAW_NORMAL_TEXT | |
16282 && (s->row->fill_line_p | |
16283 || s->face->background != default_face->background | |
16284 || s->face->stipple != default_face->stipple | |
16285 || s->row->mouse_face_p)) | |
16286 || s->hl == DRAW_MOUSE_FACE | |
16287 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN) | |
16288 && s->row->fill_line_p))) | |
16289 s->extends_to_end_of_line_p = 1; | |
16290 | |
16291 /* If S extends its face to the end of the line, set its | |
16292 background_width to the distance to the right edge of the drawing | |
16293 area. */ | |
16294 if (s->extends_to_end_of_line_p) | |
16295 s->background_width = last_x - s->x + 1; | |
16296 else | |
16297 s->background_width = s->width; | |
16298 } | |
16299 | |
16300 | |
16301 /* Compute overhangs and x-positions for glyph string S and its | |
16302 predecessors, or successors. X is the starting x-position for S. | |
16303 BACKWARD_P non-zero means process predecessors. */ | |
16304 | |
16305 static void | |
16306 compute_overhangs_and_x (s, x, backward_p) | |
16307 struct glyph_string *s; | |
16308 int x; | |
16309 int backward_p; | |
16310 { | |
16311 if (backward_p) | |
16312 { | |
16313 while (s) | |
16314 { | |
16315 if (rif->compute_glyph_string_overhangs) | |
16316 rif->compute_glyph_string_overhangs (s); | |
16317 x -= s->width; | |
16318 s->x = x; | |
16319 s = s->prev; | |
16320 } | |
16321 } | |
16322 else | |
16323 { | |
16324 while (s) | |
16325 { | |
16326 if (rif->compute_glyph_string_overhangs) | |
16327 rif->compute_glyph_string_overhangs (s); | |
16328 s->x = x; | |
16329 x += s->width; | |
16330 s = s->next; | |
16331 } | |
16332 } | |
16333 } | |
16334 | |
16335 | |
16336 | |
16337 /* The following macros are only called from x_draw_glyphs below. | |
16338 They reference the following parameters of that function directly: | |
16339 `w', `row', `area', and `overlap_p' | |
16340 as well as the following local variables: | |
16341 `s', `f', and `hdc' (in W32) */ | |
16342 | |
16343 #ifdef HAVE_NTGUI | |
16344 /* On W32, silently add local `hdc' variable to argument list of | |
16345 init_glyph_string. */ | |
16346 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \ | |
16347 init_glyph_string (s, hdc, char2b, w, row, area, start, hl) | |
16348 #else | |
16349 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \ | |
16350 init_glyph_string (s, char2b, w, row, area, start, hl) | |
16351 #endif | |
16352 | |
16353 /* Add a glyph string for a stretch glyph to the list of strings | |
16354 between HEAD and TAIL. START is the index of the stretch glyph in | |
16355 row area AREA of glyph row ROW. END is the index of the last glyph | |
16356 in that glyph row area. X is the current output position assigned | |
16357 to the new glyph string constructed. HL overrides that face of the | |
16358 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X | |
16359 is the right-most x-position of the drawing area. */ | |
16360 | |
16361 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here | |
16362 and below -- keep them on one line. */ | |
16363 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \ | |
16364 do \ | |
16365 { \ | |
16366 s = (struct glyph_string *) alloca (sizeof *s); \ | |
16367 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \ | |
16368 START = fill_stretch_glyph_string (s, row, area, START, END); \ | |
16369 append_glyph_string (&HEAD, &TAIL, s); \ | |
16370 s->x = (X); \ | |
16371 } \ | |
16372 while (0) | |
16373 | |
16374 | |
16375 /* Add a glyph string for an image glyph to the list of strings | |
16376 between HEAD and TAIL. START is the index of the image glyph in | |
16377 row area AREA of glyph row ROW. END is the index of the last glyph | |
16378 in that glyph row area. X is the current output position assigned | |
16379 to the new glyph string constructed. HL overrides that face of the | |
16380 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X | |
16381 is the right-most x-position of the drawing area. */ | |
16382 | |
16383 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \ | |
16384 do \ | |
16385 { \ | |
16386 s = (struct glyph_string *) alloca (sizeof *s); \ | |
16387 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \ | |
16388 fill_image_glyph_string (s); \ | |
16389 append_glyph_string (&HEAD, &TAIL, s); \ | |
16390 ++START; \ | |
16391 s->x = (X); \ | |
16392 } \ | |
16393 while (0) | |
16394 | |
16395 | |
16396 /* Add a glyph string for a sequence of character glyphs to the list | |
16397 of strings between HEAD and TAIL. START is the index of the first | |
16398 glyph in row area AREA of glyph row ROW that is part of the new | |
16399 glyph string. END is the index of the last glyph in that glyph row | |
16400 area. X is the current output position assigned to the new glyph | |
16401 string constructed. HL overrides that face of the glyph; e.g. it | |
16402 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the | |
16403 right-most x-position of the drawing area. */ | |
16404 | |
16405 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \ | |
16406 do \ | |
16407 { \ | |
16408 int c, face_id; \ | |
16409 XChar2b *char2b; \ | |
16410 \ | |
16411 c = (row)->glyphs[area][START].u.ch; \ | |
16412 face_id = (row)->glyphs[area][START].face_id; \ | |
16413 \ | |
16414 s = (struct glyph_string *) alloca (sizeof *s); \ | |
16415 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \ | |
16416 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \ | |
16417 append_glyph_string (&HEAD, &TAIL, s); \ | |
16418 s->x = (X); \ | |
16419 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \ | |
16420 } \ | |
16421 while (0) | |
16422 | |
16423 | |
16424 /* Add a glyph string for a composite sequence to the list of strings | |
16425 between HEAD and TAIL. START is the index of the first glyph in | |
16426 row area AREA of glyph row ROW that is part of the new glyph | |
16427 string. END is the index of the last glyph in that glyph row area. | |
16428 X is the current output position assigned to the new glyph string | |
16429 constructed. HL overrides that face of the glyph; e.g. it is | |
16430 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most | |
16431 x-position of the drawing area. */ | |
16432 | |
16433 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \ | |
16434 do { \ | |
16435 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \ | |
16436 int face_id = (row)->glyphs[area][START].face_id; \ | |
16437 struct face *base_face = FACE_FROM_ID (f, face_id); \ | |
16438 struct composition *cmp = composition_table[cmp_id]; \ | |
16439 int glyph_len = cmp->glyph_len; \ | |
16440 XChar2b *char2b; \ | |
16441 struct face **faces; \ | |
16442 struct glyph_string *first_s = NULL; \ | |
16443 int n; \ | |
16444 \ | |
16445 base_face = base_face->ascii_face; \ | |
16446 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \ | |
16447 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \ | |
16448 /* At first, fill in `char2b' and `faces'. */ \ | |
16449 for (n = 0; n < glyph_len; n++) \ | |
16450 { \ | |
16451 int c = COMPOSITION_GLYPH (cmp, n); \ | |
16452 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \ | |
16453 faces[n] = FACE_FROM_ID (f, this_face_id); \ | |
16454 get_char_face_and_encoding (f, c, this_face_id, \ | |
16455 char2b + n, 1, 1); \ | |
16456 } \ | |
16457 \ | |
16458 /* Make glyph_strings for each glyph sequence that is drawable by \ | |
16459 the same face, and append them to HEAD/TAIL. */ \ | |
16460 for (n = 0; n < cmp->glyph_len;) \ | |
16461 { \ | |
16462 s = (struct glyph_string *) alloca (sizeof *s); \ | |
16463 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \ | |
16464 append_glyph_string (&(HEAD), &(TAIL), s); \ | |
16465 s->cmp = cmp; \ | |
16466 s->gidx = n; \ | |
16467 s->x = (X); \ | |
16468 \ | |
16469 if (n == 0) \ | |
16470 first_s = s; \ | |
16471 \ | |
16472 n = fill_composite_glyph_string (s, faces, overlaps_p); \ | |
16473 } \ | |
16474 \ | |
16475 ++START; \ | |
16476 s = first_s; \ | |
16477 } while (0) | |
16478 | |
16479 | |
16480 /* Build a list of glyph strings between HEAD and TAIL for the glyphs | |
16481 of AREA of glyph row ROW on window W between indices START and END. | |
16482 HL overrides the face for drawing glyph strings, e.g. it is | |
16483 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end | |
16484 x-positions of the drawing area. | |
16485 | |
16486 This is an ugly monster macro construct because we must use alloca | |
16487 to allocate glyph strings (because x_draw_glyphs can be called | |
16488 asynchronously). */ | |
16489 | |
16490 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \ | |
16491 do \ | |
16492 { \ | |
16493 HEAD = TAIL = NULL; \ | |
16494 while (START < END) \ | |
16495 { \ | |
16496 struct glyph *first_glyph = (row)->glyphs[area] + START; \ | |
16497 switch (first_glyph->type) \ | |
16498 { \ | |
16499 case CHAR_GLYPH: \ | |
16500 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \ | |
16501 HL, X, LAST_X); \ | |
16502 break; \ | |
16503 \ | |
16504 case COMPOSITE_GLYPH: \ | |
16505 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \ | |
16506 HL, X, LAST_X); \ | |
16507 break; \ | |
16508 \ | |
16509 case STRETCH_GLYPH: \ | |
16510 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \ | |
16511 HL, X, LAST_X); \ | |
16512 break; \ | |
16513 \ | |
16514 case IMAGE_GLYPH: \ | |
16515 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \ | |
16516 HL, X, LAST_X); \ | |
16517 break; \ | |
16518 \ | |
16519 default: \ | |
16520 abort (); \ | |
16521 } \ | |
16522 \ | |
16523 set_glyph_string_background_width (s, START, LAST_X); \ | |
16524 (X) += s->width; \ | |
16525 } \ | |
16526 } \ | |
16527 while (0) | |
16528 | |
16529 | |
16530 /* Draw glyphs between START and END in AREA of ROW on window W, | |
16531 starting at x-position X. X is relative to AREA in W. HL is a | |
16532 face-override with the following meaning: | |
16533 | |
16534 DRAW_NORMAL_TEXT draw normally | |
16535 DRAW_CURSOR draw in cursor face | |
16536 DRAW_MOUSE_FACE draw in mouse face. | |
16537 DRAW_INVERSE_VIDEO draw in mode line face | |
16538 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it | |
16539 DRAW_IMAGE_RAISED draw an image with a raised relief around it | |
16540 | |
16541 If OVERLAPS_P is non-zero, draw only the foreground of characters | |
16542 and clip to the physical height of ROW. | |
16543 | |
16544 Value is the x-position reached, relative to AREA of W. */ | |
16545 | |
16546 int | |
16547 x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p) | |
16548 struct window *w; | |
16549 int x; | |
16550 struct glyph_row *row; | |
16551 enum glyph_row_area area; | |
16552 int start, end; | |
16553 enum draw_glyphs_face hl; | |
16554 int overlaps_p; | |
16555 { | |
16556 struct glyph_string *head, *tail; | |
16557 struct glyph_string *s; | |
16558 int last_x, area_width; | |
16559 int x_reached; | |
16560 int i, j; | |
16561 struct frame *f = XFRAME (WINDOW_FRAME (w)); | |
16562 DECLARE_HDC (hdc); | |
16563 | |
16564 ALLOCATE_HDC (hdc, f); | |
16565 | |
16566 /* Let's rather be paranoid than getting a SEGV. */ | |
16567 end = min (end, row->used[area]); | |
16568 start = max (0, start); | |
16569 start = min (end, start); | |
16570 | |
16571 /* Translate X to frame coordinates. Set last_x to the right | |
16572 end of the drawing area. */ | |
16573 if (row->full_width_p) | |
16574 { | |
16575 /* X is relative to the left edge of W, without scroll bars | |
16576 or fringes. */ | |
16577 int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f); | |
16578 | |
16579 x += window_left_x; | |
16580 area_width = XFASTINT (w->width) * CANON_X_UNIT (f); | |
16581 last_x = window_left_x + area_width; | |
16582 | |
16583 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)) | |
16584 { | |
16585 int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f); | |
16586 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) | |
16587 last_x += width; | |
16588 else | |
16589 x -= width; | |
16590 } | |
16591 | |
16592 x += FRAME_INTERNAL_BORDER_WIDTH (f); | |
16593 /* ++KFS: W32 and MAC versions had -= in next line (bug??) */ | |
16594 last_x += FRAME_INTERNAL_BORDER_WIDTH (f); | |
16595 } | |
16596 else | |
16597 { | |
16598 x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x); | |
16599 area_width = window_box_width (w, area); | |
16600 last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width); | |
16601 } | |
16602 | |
16603 /* Build a doubly-linked list of glyph_string structures between | |
16604 head and tail from what we have to draw. Note that the macro | |
16605 BUILD_GLYPH_STRINGS will modify its start parameter. That's | |
16606 the reason we use a separate variable `i'. */ | |
16607 i = start; | |
16608 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x); | |
16609 if (tail) | |
16610 x_reached = tail->x + tail->background_width; | |
16611 else | |
16612 x_reached = x; | |
16613 | |
16614 /* If there are any glyphs with lbearing < 0 or rbearing > width in | |
16615 the row, redraw some glyphs in front or following the glyph | |
16616 strings built above. */ | |
16617 if (head && !overlaps_p && row->contains_overlapping_glyphs_p) | |
16618 { | |
16619 int dummy_x = 0; | |
16620 struct glyph_string *h, *t; | |
16621 | |
16622 /* Compute overhangs for all glyph strings. */ | |
16623 if (rif->compute_glyph_string_overhangs) | |
16624 for (s = head; s; s = s->next) | |
16625 rif->compute_glyph_string_overhangs (s); | |
16626 | |
16627 /* Prepend glyph strings for glyphs in front of the first glyph | |
16628 string that are overwritten because of the first glyph | |
16629 string's left overhang. The background of all strings | |
16630 prepended must be drawn because the first glyph string | |
16631 draws over it. */ | |
16632 i = left_overwritten (head); | |
16633 if (i >= 0) | |
16634 { | |
16635 j = i; | |
16636 BUILD_GLYPH_STRINGS (j, start, h, t, | |
16637 DRAW_NORMAL_TEXT, dummy_x, last_x); | |
16638 start = i; | |
16639 compute_overhangs_and_x (t, head->x, 1); | |
16640 prepend_glyph_string_lists (&head, &tail, h, t); | |
16641 } | |
16642 | |
16643 /* Prepend glyph strings for glyphs in front of the first glyph | |
16644 string that overwrite that glyph string because of their | |
16645 right overhang. For these strings, only the foreground must | |
16646 be drawn, because it draws over the glyph string at `head'. | |
16647 The background must not be drawn because this would overwrite | |
16648 right overhangs of preceding glyphs for which no glyph | |
16649 strings exist. */ | |
16650 i = left_overwriting (head); | |
16651 if (i >= 0) | |
16652 { | |
16653 BUILD_GLYPH_STRINGS (i, start, h, t, | |
16654 DRAW_NORMAL_TEXT, dummy_x, last_x); | |
16655 for (s = h; s; s = s->next) | |
16656 s->background_filled_p = 1; | |
16657 compute_overhangs_and_x (t, head->x, 1); | |
16658 prepend_glyph_string_lists (&head, &tail, h, t); | |
16659 } | |
16660 | |
16661 /* Append glyphs strings for glyphs following the last glyph | |
16662 string tail that are overwritten by tail. The background of | |
16663 these strings has to be drawn because tail's foreground draws | |
16664 over it. */ | |
16665 i = right_overwritten (tail); | |
16666 if (i >= 0) | |
16667 { | |
16668 BUILD_GLYPH_STRINGS (end, i, h, t, | |
16669 DRAW_NORMAL_TEXT, x, last_x); | |
16670 compute_overhangs_and_x (h, tail->x + tail->width, 0); | |
16671 append_glyph_string_lists (&head, &tail, h, t); | |
16672 } | |
16673 | |
16674 /* Append glyph strings for glyphs following the last glyph | |
16675 string tail that overwrite tail. The foreground of such | |
16676 glyphs has to be drawn because it writes into the background | |
16677 of tail. The background must not be drawn because it could | |
16678 paint over the foreground of following glyphs. */ | |
16679 i = right_overwriting (tail); | |
16680 if (i >= 0) | |
16681 { | |
16682 BUILD_GLYPH_STRINGS (end, i, h, t, | |
16683 DRAW_NORMAL_TEXT, x, last_x); | |
16684 for (s = h; s; s = s->next) | |
16685 s->background_filled_p = 1; | |
16686 compute_overhangs_and_x (h, tail->x + tail->width, 0); | |
16687 append_glyph_string_lists (&head, &tail, h, t); | |
16688 } | |
16689 } | |
16690 | |
16691 /* Draw all strings. */ | |
16692 for (s = head; s; s = s->next) | |
16693 rif->draw_glyph_string (s); | |
16694 | |
16695 if (area == TEXT_AREA | |
16696 && !row->full_width_p | |
16697 /* When drawing overlapping rows, only the glyph strings' | |
16698 foreground is drawn, which doesn't erase a cursor | |
16699 completely. */ | |
16700 && !overlaps_p) | |
16701 { | |
16702 int x0 = head ? head->x : x; | |
16703 int x1 = tail ? tail->x + tail->background_width : x; | |
16704 | |
16705 x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0); | |
16706 x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1); | |
16707 | |
16708 /* ++KFS: W32 and MAC versions had following test here: | |
16709 if (!row->full_width_p && XFASTINT (w->left_margin_width) != 0) | |
16710 */ | |
16711 | |
16712 if (XFASTINT (w->left_margin_width) != 0) | |
16713 { | |
16714 int left_area_width = window_box_width (w, LEFT_MARGIN_AREA); | |
16715 x0 -= left_area_width; | |
16716 x1 -= left_area_width; | |
16717 } | |
16718 | |
16719 notice_overwritten_cursor (w, area, x0, x1, | |
16720 row->y, MATRIX_ROW_BOTTOM_Y (row)); | |
16721 } | |
16722 | |
16723 /* Value is the x-position up to which drawn, relative to AREA of W. | |
16724 This doesn't include parts drawn because of overhangs. */ | |
16725 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached); | |
16726 if (!row->full_width_p) | |
16727 { | |
16728 /* ++KFS: W32 and MAC versions only had this test here: | |
16729 if (area > LEFT_MARGIN_AREA) | |
16730 */ | |
16731 | |
16732 if (area > LEFT_MARGIN_AREA && XFASTINT (w->left_margin_width) != 0) | |
16733 x_reached -= window_box_width (w, LEFT_MARGIN_AREA); | |
16734 if (area > TEXT_AREA) | |
16735 x_reached -= window_box_width (w, TEXT_AREA); | |
16736 } | |
16737 | |
16738 RELEASE_HDC (hdc, f); | |
16739 | |
16740 return x_reached; | |
16741 } | |
16742 | |
16743 | |
16744 /* Store one glyph for IT->char_to_display in IT->glyph_row. | |
16745 Called from x_produce_glyphs when IT->glyph_row is non-null. */ | |
16746 | |
16747 static INLINE void | |
16748 append_glyph (it) | |
16749 struct it *it; | |
16750 { | |
16751 struct glyph *glyph; | |
16752 enum glyph_row_area area = it->area; | |
16753 | |
16754 xassert (it->glyph_row); | |
16755 xassert (it->char_to_display != '\n' && it->char_to_display != '\t'); | |
16756 | |
16757 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | |
16758 if (glyph < it->glyph_row->glyphs[area + 1]) | |
16759 { | |
16760 glyph->charpos = CHARPOS (it->position); | |
16761 glyph->object = it->object; | |
16762 glyph->pixel_width = it->pixel_width; | |
16763 glyph->voffset = it->voffset; | |
16764 glyph->type = CHAR_GLYPH; | |
16765 glyph->multibyte_p = it->multibyte_p; | |
16766 glyph->left_box_line_p = it->start_of_box_run_p; | |
16767 glyph->right_box_line_p = it->end_of_box_run_p; | |
16768 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | |
16769 || it->phys_descent > it->descent); | |
16770 glyph->padding_p = 0; | |
16771 glyph->glyph_not_available_p = it->glyph_not_available_p; | |
16772 glyph->face_id = it->face_id; | |
16773 glyph->u.ch = it->char_to_display; | |
16774 glyph->font_type = FONT_TYPE_UNKNOWN; | |
16775 ++it->glyph_row->used[area]; | |
16776 } | |
16777 } | |
16778 | |
16779 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row. | |
16780 Called from x_produce_glyphs when IT->glyph_row is non-null. */ | |
16781 | |
16782 static INLINE void | |
16783 append_composite_glyph (it) | |
16784 struct it *it; | |
16785 { | |
16786 struct glyph *glyph; | |
16787 enum glyph_row_area area = it->area; | |
16788 | |
16789 xassert (it->glyph_row); | |
16790 | |
16791 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | |
16792 if (glyph < it->glyph_row->glyphs[area + 1]) | |
16793 { | |
16794 glyph->charpos = CHARPOS (it->position); | |
16795 glyph->object = it->object; | |
16796 glyph->pixel_width = it->pixel_width; | |
16797 glyph->voffset = it->voffset; | |
16798 glyph->type = COMPOSITE_GLYPH; | |
16799 glyph->multibyte_p = it->multibyte_p; | |
16800 glyph->left_box_line_p = it->start_of_box_run_p; | |
16801 glyph->right_box_line_p = it->end_of_box_run_p; | |
16802 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | |
16803 || it->phys_descent > it->descent); | |
16804 glyph->padding_p = 0; | |
16805 glyph->glyph_not_available_p = 0; | |
16806 glyph->face_id = it->face_id; | |
16807 glyph->u.cmp_id = it->cmp_id; | |
16808 glyph->font_type = FONT_TYPE_UNKNOWN; | |
16809 ++it->glyph_row->used[area]; | |
16810 } | |
16811 } | |
16812 | |
16813 | |
16814 /* Change IT->ascent and IT->height according to the setting of | |
16815 IT->voffset. */ | |
16816 | |
16817 static INLINE void | |
16818 take_vertical_position_into_account (it) | |
16819 struct it *it; | |
16820 { | |
16821 if (it->voffset) | |
16822 { | |
16823 if (it->voffset < 0) | |
16824 /* Increase the ascent so that we can display the text higher | |
16825 in the line. */ | |
16826 it->ascent += abs (it->voffset); | |
16827 else | |
16828 /* Increase the descent so that we can display the text lower | |
16829 in the line. */ | |
16830 it->descent += it->voffset; | |
16831 } | |
16832 } | |
16833 | |
16834 | |
16835 /* Produce glyphs/get display metrics for the image IT is loaded with. | |
16836 See the description of struct display_iterator in dispextern.h for | |
16837 an overview of struct display_iterator. */ | |
16838 | |
16839 static void | |
16840 produce_image_glyph (it) | |
16841 struct it *it; | |
16842 { | |
16843 struct image *img; | |
16844 struct face *face; | |
16845 | |
16846 xassert (it->what == IT_IMAGE); | |
16847 | |
16848 face = FACE_FROM_ID (it->f, it->face_id); | |
16849 img = IMAGE_FROM_ID (it->f, it->image_id); | |
16850 xassert (img); | |
16851 | |
16852 /* Make sure X resources of the face and image are loaded. */ | |
16853 PREPARE_FACE_FOR_DISPLAY (it->f, face); | |
16854 prepare_image_for_display (it->f, img); | |
16855 | |
16856 it->ascent = it->phys_ascent = image_ascent (img, face); | |
16857 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent; | |
16858 it->pixel_width = img->width + 2 * img->hmargin; | |
16859 | |
16860 it->nglyphs = 1; | |
16861 | |
16862 if (face->box != FACE_NO_BOX) | |
16863 { | |
16864 if (face->box_line_width > 0) | |
16865 { | |
16866 it->ascent += face->box_line_width; | |
16867 it->descent += face->box_line_width; | |
16868 } | |
16869 | |
16870 if (it->start_of_box_run_p) | |
16871 it->pixel_width += abs (face->box_line_width); | |
16872 if (it->end_of_box_run_p) | |
16873 it->pixel_width += abs (face->box_line_width); | |
16874 } | |
16875 | |
16876 take_vertical_position_into_account (it); | |
16877 | |
16878 if (it->glyph_row) | |
16879 { | |
16880 struct glyph *glyph; | |
16881 enum glyph_row_area area = it->area; | |
16882 | |
16883 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | |
16884 if (glyph < it->glyph_row->glyphs[area + 1]) | |
16885 { | |
16886 glyph->charpos = CHARPOS (it->position); | |
16887 glyph->object = it->object; | |
16888 glyph->pixel_width = it->pixel_width; | |
16889 glyph->voffset = it->voffset; | |
16890 glyph->type = IMAGE_GLYPH; | |
16891 glyph->multibyte_p = it->multibyte_p; | |
16892 glyph->left_box_line_p = it->start_of_box_run_p; | |
16893 glyph->right_box_line_p = it->end_of_box_run_p; | |
16894 glyph->overlaps_vertically_p = 0; | |
16895 glyph->padding_p = 0; | |
16896 glyph->glyph_not_available_p = 0; | |
16897 glyph->face_id = it->face_id; | |
16898 glyph->u.img_id = img->id; | |
16899 glyph->font_type = FONT_TYPE_UNKNOWN; | |
16900 ++it->glyph_row->used[area]; | |
16901 } | |
16902 } | |
16903 } | |
16904 | |
16905 | |
16906 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source | |
16907 of the glyph, WIDTH and HEIGHT are the width and height of the | |
16908 stretch. ASCENT is the percentage/100 of HEIGHT to use for the | |
16909 ascent of the glyph (0 <= ASCENT <= 1). */ | |
16910 | |
16911 static void | |
16912 append_stretch_glyph (it, object, width, height, ascent) | |
16913 struct it *it; | |
16914 Lisp_Object object; | |
16915 int width, height; | |
16916 double ascent; | |
16917 { | |
16918 struct glyph *glyph; | |
16919 enum glyph_row_area area = it->area; | |
16920 | |
16921 xassert (ascent >= 0 && ascent <= 1); | |
16922 | |
16923 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | |
16924 if (glyph < it->glyph_row->glyphs[area + 1]) | |
16925 { | |
16926 glyph->charpos = CHARPOS (it->position); | |
16927 glyph->object = object; | |
16928 glyph->pixel_width = width; | |
16929 glyph->voffset = it->voffset; | |
16930 glyph->type = STRETCH_GLYPH; | |
16931 glyph->multibyte_p = it->multibyte_p; | |
16932 glyph->left_box_line_p = it->start_of_box_run_p; | |
16933 glyph->right_box_line_p = it->end_of_box_run_p; | |
16934 glyph->overlaps_vertically_p = 0; | |
16935 glyph->padding_p = 0; | |
16936 glyph->glyph_not_available_p = 0; | |
16937 glyph->face_id = it->face_id; | |
16938 glyph->u.stretch.ascent = height * ascent; | |
16939 glyph->u.stretch.height = height; | |
16940 glyph->font_type = FONT_TYPE_UNKNOWN; | |
16941 ++it->glyph_row->used[area]; | |
16942 } | |
16943 } | |
16944 | |
16945 | |
16946 /* Produce a stretch glyph for iterator IT. IT->object is the value | |
16947 of the glyph property displayed. The value must be a list | |
16948 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs | |
16949 being recognized: | |
16950 | |
16951 1. `:width WIDTH' specifies that the space should be WIDTH * | |
16952 canonical char width wide. WIDTH may be an integer or floating | |
16953 point number. | |
16954 | |
16955 2. `:relative-width FACTOR' specifies that the width of the stretch | |
16956 should be computed from the width of the first character having the | |
16957 `glyph' property, and should be FACTOR times that width. | |
16958 | |
16959 3. `:align-to HPOS' specifies that the space should be wide enough | |
16960 to reach HPOS, a value in canonical character units. | |
16961 | |
16962 Exactly one of the above pairs must be present. | |
16963 | |
16964 4. `:height HEIGHT' specifies that the height of the stretch produced | |
16965 should be HEIGHT, measured in canonical character units. | |
16966 | |
16967 5. `:relative-height FACTOR' specifies that the height of the | |
16968 stretch should be FACTOR times the height of the characters having | |
16969 the glyph property. | |
16970 | |
16971 Either none or exactly one of 4 or 5 must be present. | |
16972 | |
16973 6. `:ascent ASCENT' specifies that ASCENT percent of the height | |
16974 of the stretch should be used for the ascent of the stretch. | |
16975 ASCENT must be in the range 0 <= ASCENT <= 100. */ | |
16976 | |
16977 #define NUMVAL(X) \ | |
16978 ((INTEGERP (X) || FLOATP (X)) \ | |
16979 ? XFLOATINT (X) \ | |
16980 : - 1) | |
16981 | |
16982 | |
16983 static void | |
16984 produce_stretch_glyph (it) | |
16985 struct it *it; | |
16986 { | |
16987 /* (space :width WIDTH :height HEIGHT. */ | |
16988 Lisp_Object prop, plist; | |
16989 int width = 0, height = 0; | |
16990 double ascent = 0; | |
16991 struct face *face = FACE_FROM_ID (it->f, it->face_id); | |
16992 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f); | |
16993 | |
16994 PREPARE_FACE_FOR_DISPLAY (it->f, face); | |
16995 | |
16996 /* List should start with `space'. */ | |
16997 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace)); | |
16998 plist = XCDR (it->object); | |
16999 | |
17000 /* Compute the width of the stretch. */ | |
17001 if (prop = Fplist_get (plist, QCwidth), | |
17002 NUMVAL (prop) > 0) | |
17003 /* Absolute width `:width WIDTH' specified and valid. */ | |
17004 width = NUMVAL (prop) * CANON_X_UNIT (it->f); | |
17005 else if (prop = Fplist_get (plist, QCrelative_width), | |
17006 NUMVAL (prop) > 0) | |
17007 { | |
17008 /* Relative width `:relative-width FACTOR' specified and valid. | |
17009 Compute the width of the characters having the `glyph' | |
17010 property. */ | |
17011 struct it it2; | |
17012 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); | |
17013 | |
17014 it2 = *it; | |
17015 if (it->multibyte_p) | |
17016 { | |
17017 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT) | |
17018 - IT_BYTEPOS (*it)); | |
17019 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len); | |
17020 } | |
17021 else | |
17022 it2.c = *p, it2.len = 1; | |
17023 | |
17024 it2.glyph_row = NULL; | |
17025 it2.what = IT_CHARACTER; | |
17026 x_produce_glyphs (&it2); | |
17027 width = NUMVAL (prop) * it2.pixel_width; | |
17028 } | |
17029 else if (prop = Fplist_get (plist, QCalign_to), | |
17030 NUMVAL (prop) > 0) | |
17031 width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x; | |
17032 else | |
17033 /* Nothing specified -> width defaults to canonical char width. */ | |
17034 width = CANON_X_UNIT (it->f); | |
17035 | |
17036 /* Compute height. */ | |
17037 if (prop = Fplist_get (plist, QCheight), | |
17038 NUMVAL (prop) > 0) | |
17039 height = NUMVAL (prop) * CANON_Y_UNIT (it->f); | |
17040 else if (prop = Fplist_get (plist, QCrelative_height), | |
17041 NUMVAL (prop) > 0) | |
17042 height = FONT_HEIGHT (font) * NUMVAL (prop); | |
17043 else | |
17044 height = FONT_HEIGHT (font); | |
17045 | |
17046 /* Compute percentage of height used for ascent. If | |
17047 `:ascent ASCENT' is present and valid, use that. Otherwise, | |
17048 derive the ascent from the font in use. */ | |
17049 if (prop = Fplist_get (plist, QCascent), | |
17050 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100) | |
17051 ascent = NUMVAL (prop) / 100.0; | |
17052 else | |
17053 ascent = (double) FONT_BASE (font) / FONT_HEIGHT (font); | |
17054 | |
17055 if (width <= 0) | |
17056 width = 1; | |
17057 if (height <= 0) | |
17058 height = 1; | |
17059 | |
17060 if (it->glyph_row) | |
17061 { | |
17062 Lisp_Object object = it->stack[it->sp - 1].string; | |
17063 if (!STRINGP (object)) | |
17064 object = it->w->buffer; | |
17065 append_stretch_glyph (it, object, width, height, ascent); | |
17066 } | |
17067 | |
17068 it->pixel_width = width; | |
17069 it->ascent = it->phys_ascent = height * ascent; | |
17070 it->descent = it->phys_descent = height - it->ascent; | |
17071 it->nglyphs = 1; | |
17072 | |
17073 if (face->box != FACE_NO_BOX) | |
17074 { | |
17075 if (face->box_line_width > 0) | |
17076 { | |
17077 it->ascent += face->box_line_width; | |
17078 it->descent += face->box_line_width; | |
17079 } | |
17080 | |
17081 if (it->start_of_box_run_p) | |
17082 it->pixel_width += abs (face->box_line_width); | |
17083 if (it->end_of_box_run_p) | |
17084 it->pixel_width += abs (face->box_line_width); | |
17085 } | |
17086 | |
17087 take_vertical_position_into_account (it); | |
17088 } | |
17089 | |
17090 /* RIF: | |
17091 Produce glyphs/get display metrics for the display element IT is | |
17092 loaded with. See the description of struct display_iterator in | |
17093 dispextern.h for an overview of struct display_iterator. */ | |
17094 | |
17095 void | |
17096 x_produce_glyphs (it) | |
17097 struct it *it; | |
17098 { | |
17099 it->glyph_not_available_p = 0; | |
17100 | |
17101 if (it->what == IT_CHARACTER) | |
17102 { | |
17103 XChar2b char2b; | |
17104 XFontStruct *font; | |
17105 struct face *face = FACE_FROM_ID (it->f, it->face_id); | |
17106 XCharStruct *pcm; | |
17107 int font_not_found_p; | |
17108 struct font_info *font_info; | |
17109 int boff; /* baseline offset */ | |
17110 /* We may change it->multibyte_p upon unibyte<->multibyte | |
17111 conversion. So, save the current value now and restore it | |
17112 later. | |
17113 | |
17114 Note: It seems that we don't have to record multibyte_p in | |
17115 struct glyph because the character code itself tells if or | |
17116 not the character is multibyte. Thus, in the future, we must | |
17117 consider eliminating the field `multibyte_p' in the struct | |
17118 glyph. */ | |
17119 int saved_multibyte_p = it->multibyte_p; | |
17120 | |
17121 /* Maybe translate single-byte characters to multibyte, or the | |
17122 other way. */ | |
17123 it->char_to_display = it->c; | |
17124 if (!ASCII_BYTE_P (it->c)) | |
17125 { | |
17126 if (unibyte_display_via_language_environment | |
17127 && SINGLE_BYTE_CHAR_P (it->c) | |
17128 && (it->c >= 0240 | |
17129 || !NILP (Vnonascii_translation_table))) | |
17130 { | |
17131 it->char_to_display = unibyte_char_to_multibyte (it->c); | |
17132 it->multibyte_p = 1; | |
17133 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | |
17134 face = FACE_FROM_ID (it->f, it->face_id); | |
17135 } | |
17136 else if (!SINGLE_BYTE_CHAR_P (it->c) | |
17137 && !it->multibyte_p) | |
17138 { | |
17139 it->multibyte_p = 1; | |
17140 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | |
17141 face = FACE_FROM_ID (it->f, it->face_id); | |
17142 } | |
17143 } | |
17144 | |
17145 /* Get font to use. Encode IT->char_to_display. */ | |
17146 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id, | |
17147 &char2b, it->multibyte_p, 0); | |
17148 font = face->font; | |
17149 | |
17150 /* When no suitable font found, use the default font. */ | |
17151 font_not_found_p = font == NULL; | |
17152 if (font_not_found_p) | |
17153 { | |
17154 font = FRAME_FONT (it->f); | |
17155 boff = FRAME_BASELINE_OFFSET (it->f); | |
17156 font_info = NULL; | |
17157 } | |
17158 else | |
17159 { | |
17160 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id); | |
17161 boff = font_info->baseline_offset; | |
17162 if (font_info->vertical_centering) | |
17163 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | |
17164 } | |
17165 | |
17166 if (it->char_to_display >= ' ' | |
17167 && (!it->multibyte_p || it->char_to_display < 128)) | |
17168 { | |
17169 /* Either unibyte or ASCII. */ | |
17170 int stretched_p; | |
17171 | |
17172 it->nglyphs = 1; | |
17173 | |
17174 pcm = rif->per_char_metric (font, &char2b, | |
17175 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display)); | |
17176 it->ascent = FONT_BASE (font) + boff; | |
17177 it->descent = FONT_DESCENT (font) - boff; | |
17178 | |
17179 if (pcm) | |
17180 { | |
17181 it->phys_ascent = pcm->ascent + boff; | |
17182 it->phys_descent = pcm->descent - boff; | |
17183 it->pixel_width = pcm->width; | |
17184 } | |
17185 else | |
17186 { | |
17187 it->glyph_not_available_p = 1; | |
17188 it->phys_ascent = FONT_BASE (font) + boff; | |
17189 it->phys_descent = FONT_DESCENT (font) - boff; | |
17190 it->pixel_width = FONT_WIDTH (font); | |
17191 } | |
17192 | |
17193 /* If this is a space inside a region of text with | |
17194 `space-width' property, change its width. */ | |
17195 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width); | |
17196 if (stretched_p) | |
17197 it->pixel_width *= XFLOATINT (it->space_width); | |
17198 | |
17199 /* If face has a box, add the box thickness to the character | |
17200 height. If character has a box line to the left and/or | |
17201 right, add the box line width to the character's width. */ | |
17202 if (face->box != FACE_NO_BOX) | |
17203 { | |
17204 int thick = face->box_line_width; | |
17205 | |
17206 if (thick > 0) | |
17207 { | |
17208 it->ascent += thick; | |
17209 it->descent += thick; | |
17210 } | |
17211 else | |
17212 thick = -thick; | |
17213 | |
17214 if (it->start_of_box_run_p) | |
17215 it->pixel_width += thick; | |
17216 if (it->end_of_box_run_p) | |
17217 it->pixel_width += thick; | |
17218 } | |
17219 | |
17220 /* If face has an overline, add the height of the overline | |
17221 (1 pixel) and a 1 pixel margin to the character height. */ | |
17222 if (face->overline_p) | |
17223 it->ascent += 2; | |
17224 | |
17225 take_vertical_position_into_account (it); | |
17226 | |
17227 /* If we have to actually produce glyphs, do it. */ | |
17228 if (it->glyph_row) | |
17229 { | |
17230 if (stretched_p) | |
17231 { | |
17232 /* Translate a space with a `space-width' property | |
17233 into a stretch glyph. */ | |
17234 double ascent = (double) FONT_BASE (font) | |
17235 / FONT_HEIGHT (font); | |
17236 append_stretch_glyph (it, it->object, it->pixel_width, | |
17237 it->ascent + it->descent, ascent); | |
17238 } | |
17239 else | |
17240 append_glyph (it); | |
17241 | |
17242 /* If characters with lbearing or rbearing are displayed | |
17243 in this line, record that fact in a flag of the | |
17244 glyph row. This is used to optimize X output code. */ | |
17245 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width)) | |
17246 it->glyph_row->contains_overlapping_glyphs_p = 1; | |
17247 } | |
17248 } | |
17249 else if (it->char_to_display == '\n') | |
17250 { | |
17251 /* A newline has no width but we need the height of the line. */ | |
17252 it->pixel_width = 0; | |
17253 it->nglyphs = 0; | |
17254 it->ascent = it->phys_ascent = FONT_BASE (font) + boff; | |
17255 it->descent = it->phys_descent = FONT_DESCENT (font) - boff; | |
17256 | |
17257 if (face->box != FACE_NO_BOX | |
17258 && face->box_line_width > 0) | |
17259 { | |
17260 it->ascent += face->box_line_width; | |
17261 it->descent += face->box_line_width; | |
17262 } | |
17263 } | |
17264 else if (it->char_to_display == '\t') | |
17265 { | |
17266 int tab_width = it->tab_width * CANON_X_UNIT (it->f); | |
17267 int x = it->current_x + it->continuation_lines_width; | |
17268 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width; | |
17269 | |
17270 /* If the distance from the current position to the next tab | |
17271 stop is less than a canonical character width, use the | |
17272 tab stop after that. */ | |
17273 if (next_tab_x - x < CANON_X_UNIT (it->f)) | |
17274 next_tab_x += tab_width; | |
17275 | |
17276 it->pixel_width = next_tab_x - x; | |
17277 it->nglyphs = 1; | |
17278 it->ascent = it->phys_ascent = FONT_BASE (font) + boff; | |
17279 it->descent = it->phys_descent = FONT_DESCENT (font) - boff; | |
17280 | |
17281 if (it->glyph_row) | |
17282 { | |
17283 double ascent = (double) it->ascent / (it->ascent + it->descent); | |
17284 append_stretch_glyph (it, it->object, it->pixel_width, | |
17285 it->ascent + it->descent, ascent); | |
17286 } | |
17287 } | |
17288 else | |
17289 { | |
17290 /* A multi-byte character. Assume that the display width of the | |
17291 character is the width of the character multiplied by the | |
17292 width of the font. */ | |
17293 | |
17294 /* If we found a font, this font should give us the right | |
17295 metrics. If we didn't find a font, use the frame's | |
17296 default font and calculate the width of the character | |
17297 from the charset width; this is what old redisplay code | |
17298 did. */ | |
17299 | |
17300 pcm = rif->per_char_metric (font, &char2b, | |
17301 FONT_TYPE_FOR_MULTIBYTE (font, it->c)); | |
17302 | |
17303 if (font_not_found_p || !pcm) | |
17304 { | |
17305 int charset = CHAR_CHARSET (it->char_to_display); | |
17306 | |
17307 it->glyph_not_available_p = 1; | |
17308 it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f)) | |
17309 * CHARSET_WIDTH (charset)); | |
17310 it->phys_ascent = FONT_BASE (font) + boff; | |
17311 it->phys_descent = FONT_DESCENT (font) - boff; | |
17312 } | |
17313 else | |
17314 { | |
17315 it->pixel_width = pcm->width; | |
17316 it->phys_ascent = pcm->ascent + boff; | |
17317 it->phys_descent = pcm->descent - boff; | |
17318 if (it->glyph_row | |
17319 && (pcm->lbearing < 0 | |
17320 || pcm->rbearing > pcm->width)) | |
17321 it->glyph_row->contains_overlapping_glyphs_p = 1; | |
17322 } | |
17323 it->nglyphs = 1; | |
17324 it->ascent = FONT_BASE (font) + boff; | |
17325 it->descent = FONT_DESCENT (font) - boff; | |
17326 if (face->box != FACE_NO_BOX) | |
17327 { | |
17328 int thick = face->box_line_width; | |
17329 | |
17330 if (thick > 0) | |
17331 { | |
17332 it->ascent += thick; | |
17333 it->descent += thick; | |
17334 } | |
17335 else | |
17336 thick = - thick; | |
17337 | |
17338 if (it->start_of_box_run_p) | |
17339 it->pixel_width += thick; | |
17340 if (it->end_of_box_run_p) | |
17341 it->pixel_width += thick; | |
17342 } | |
17343 | |
17344 /* If face has an overline, add the height of the overline | |
17345 (1 pixel) and a 1 pixel margin to the character height. */ | |
17346 if (face->overline_p) | |
17347 it->ascent += 2; | |
17348 | |
17349 take_vertical_position_into_account (it); | |
17350 | |
17351 if (it->glyph_row) | |
17352 append_glyph (it); | |
17353 } | |
17354 it->multibyte_p = saved_multibyte_p; | |
17355 } | |
17356 else if (it->what == IT_COMPOSITION) | |
17357 { | |
17358 /* Note: A composition is represented as one glyph in the | |
17359 glyph matrix. There are no padding glyphs. */ | |
17360 XChar2b char2b; | |
17361 XFontStruct *font; | |
17362 struct face *face = FACE_FROM_ID (it->f, it->face_id); | |
17363 XCharStruct *pcm; | |
17364 int font_not_found_p; | |
17365 struct font_info *font_info; | |
17366 int boff; /* baseline offset */ | |
17367 struct composition *cmp = composition_table[it->cmp_id]; | |
17368 | |
17369 /* Maybe translate single-byte characters to multibyte. */ | |
17370 it->char_to_display = it->c; | |
17371 if (unibyte_display_via_language_environment | |
17372 && SINGLE_BYTE_CHAR_P (it->c) | |
17373 && (it->c >= 0240 | |
17374 || (it->c >= 0200 | |
17375 && !NILP (Vnonascii_translation_table)))) | |
17376 { | |
17377 it->char_to_display = unibyte_char_to_multibyte (it->c); | |
17378 } | |
17379 | |
17380 /* Get face and font to use. Encode IT->char_to_display. */ | |
17381 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | |
17382 face = FACE_FROM_ID (it->f, it->face_id); | |
17383 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id, | |
17384 &char2b, it->multibyte_p, 0); | |
17385 font = face->font; | |
17386 | |
17387 /* When no suitable font found, use the default font. */ | |
17388 font_not_found_p = font == NULL; | |
17389 if (font_not_found_p) | |
17390 { | |
17391 font = FRAME_FONT (it->f); | |
17392 boff = FRAME_BASELINE_OFFSET (it->f); | |
17393 font_info = NULL; | |
17394 } | |
17395 else | |
17396 { | |
17397 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id); | |
17398 boff = font_info->baseline_offset; | |
17399 if (font_info->vertical_centering) | |
17400 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | |
17401 } | |
17402 | |
17403 /* There are no padding glyphs, so there is only one glyph to | |
17404 produce for the composition. Important is that pixel_width, | |
17405 ascent and descent are the values of what is drawn by | |
17406 draw_glyphs (i.e. the values of the overall glyphs composed). */ | |
17407 it->nglyphs = 1; | |
17408 | |
17409 /* If we have not yet calculated pixel size data of glyphs of | |
17410 the composition for the current face font, calculate them | |
17411 now. Theoretically, we have to check all fonts for the | |
17412 glyphs, but that requires much time and memory space. So, | |
17413 here we check only the font of the first glyph. This leads | |
17414 to incorrect display very rarely, and C-l (recenter) can | |
17415 correct the display anyway. */ | |
17416 if (cmp->font != (void *) font) | |
17417 { | |
17418 /* Ascent and descent of the font of the first character of | |
17419 this composition (adjusted by baseline offset). Ascent | |
17420 and descent of overall glyphs should not be less than | |
17421 them respectively. */ | |
17422 int font_ascent = FONT_BASE (font) + boff; | |
17423 int font_descent = FONT_DESCENT (font) - boff; | |
17424 /* Bounding box of the overall glyphs. */ | |
17425 int leftmost, rightmost, lowest, highest; | |
17426 int i, width, ascent, descent; | |
17427 | |
17428 cmp->font = (void *) font; | |
17429 | |
17430 /* Initialize the bounding box. */ | |
17431 if (font_info | |
17432 && (pcm = rif->per_char_metric (font, &char2b, | |
17433 FONT_TYPE_FOR_MULTIBYTE (font, it->c)))) | |
17434 { | |
17435 width = pcm->width; | |
17436 ascent = pcm->ascent; | |
17437 descent = pcm->descent; | |
17438 } | |
17439 else | |
17440 { | |
17441 width = FONT_WIDTH (font); | |
17442 ascent = FONT_BASE (font); | |
17443 descent = FONT_DESCENT (font); | |
17444 } | |
17445 | |
17446 rightmost = width; | |
17447 lowest = - descent + boff; | |
17448 highest = ascent + boff; | |
17449 leftmost = 0; | |
17450 | |
17451 if (font_info | |
17452 && font_info->default_ascent | |
17453 && CHAR_TABLE_P (Vuse_default_ascent) | |
17454 && !NILP (Faref (Vuse_default_ascent, | |
17455 make_number (it->char_to_display)))) | |
17456 highest = font_info->default_ascent + boff; | |
17457 | |
17458 /* Draw the first glyph at the normal position. It may be | |
17459 shifted to right later if some other glyphs are drawn at | |
17460 the left. */ | |
17461 cmp->offsets[0] = 0; | |
17462 cmp->offsets[1] = boff; | |
17463 | |
17464 /* Set cmp->offsets for the remaining glyphs. */ | |
17465 for (i = 1; i < cmp->glyph_len; i++) | |
17466 { | |
17467 int left, right, btm, top; | |
17468 int ch = COMPOSITION_GLYPH (cmp, i); | |
17469 int face_id = FACE_FOR_CHAR (it->f, face, ch); | |
17470 | |
17471 face = FACE_FROM_ID (it->f, face_id); | |
17472 get_char_face_and_encoding (it->f, ch, face->id, | |
17473 &char2b, it->multibyte_p, 0); | |
17474 font = face->font; | |
17475 if (font == NULL) | |
17476 { | |
17477 font = FRAME_FONT (it->f); | |
17478 boff = it->f->output_data.x->baseline_offset; | |
17479 font_info = NULL; | |
17480 } | |
17481 else | |
17482 { | |
17483 font_info | |
17484 = FONT_INFO_FROM_ID (it->f, face->font_info_id); | |
17485 boff = font_info->baseline_offset; | |
17486 if (font_info->vertical_centering) | |
17487 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | |
17488 } | |
17489 | |
17490 if (font_info | |
17491 && (pcm = rif->per_char_metric (font, &char2b, | |
17492 FONT_TYPE_FOR_MULTIBYTE (font, ch)))) | |
17493 { | |
17494 width = pcm->width; | |
17495 ascent = pcm->ascent; | |
17496 descent = pcm->descent; | |
17497 } | |
17498 else | |
17499 { | |
17500 width = FONT_WIDTH (font); | |
17501 ascent = 1; | |
17502 descent = 0; | |
17503 } | |
17504 | |
17505 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS) | |
17506 { | |
17507 /* Relative composition with or without | |
17508 alternate chars. */ | |
17509 left = (leftmost + rightmost - width) / 2; | |
17510 btm = - descent + boff; | |
17511 if (font_info && font_info->relative_compose | |
17512 && (! CHAR_TABLE_P (Vignore_relative_composition) | |
17513 || NILP (Faref (Vignore_relative_composition, | |
17514 make_number (ch))))) | |
17515 { | |
17516 | |
17517 if (- descent >= font_info->relative_compose) | |
17518 /* One extra pixel between two glyphs. */ | |
17519 btm = highest + 1; | |
17520 else if (ascent <= 0) | |
17521 /* One extra pixel between two glyphs. */ | |
17522 btm = lowest - 1 - ascent - descent; | |
17523 } | |
17524 } | |
17525 else | |
17526 { | |
17527 /* A composition rule is specified by an integer | |
17528 value that encodes global and new reference | |
17529 points (GREF and NREF). GREF and NREF are | |
17530 specified by numbers as below: | |
17531 | |
17532 0---1---2 -- ascent | |
17533 | | | |
17534 | | | |
17535 | | | |
17536 9--10--11 -- center | |
17537 | | | |
17538 ---3---4---5--- baseline | |
17539 | | | |
17540 6---7---8 -- descent | |
17541 */ | |
17542 int rule = COMPOSITION_RULE (cmp, i); | |
17543 int gref, nref, grefx, grefy, nrefx, nrefy; | |
17544 | |
17545 COMPOSITION_DECODE_RULE (rule, gref, nref); | |
17546 grefx = gref % 3, nrefx = nref % 3; | |
17547 grefy = gref / 3, nrefy = nref / 3; | |
17548 | |
17549 left = (leftmost | |
17550 + grefx * (rightmost - leftmost) / 2 | |
17551 - nrefx * width / 2); | |
17552 btm = ((grefy == 0 ? highest | |
17553 : grefy == 1 ? 0 | |
17554 : grefy == 2 ? lowest | |
17555 : (highest + lowest) / 2) | |
17556 - (nrefy == 0 ? ascent + descent | |
17557 : nrefy == 1 ? descent - boff | |
17558 : nrefy == 2 ? 0 | |
17559 : (ascent + descent) / 2)); | |
17560 } | |
17561 | |
17562 cmp->offsets[i * 2] = left; | |
17563 cmp->offsets[i * 2 + 1] = btm + descent; | |
17564 | |
17565 /* Update the bounding box of the overall glyphs. */ | |
17566 right = left + width; | |
17567 top = btm + descent + ascent; | |
17568 if (left < leftmost) | |
17569 leftmost = left; | |
17570 if (right > rightmost) | |
17571 rightmost = right; | |
17572 if (top > highest) | |
17573 highest = top; | |
17574 if (btm < lowest) | |
17575 lowest = btm; | |
17576 } | |
17577 | |
17578 /* If there are glyphs whose x-offsets are negative, | |
17579 shift all glyphs to the right and make all x-offsets | |
17580 non-negative. */ | |
17581 if (leftmost < 0) | |
17582 { | |
17583 for (i = 0; i < cmp->glyph_len; i++) | |
17584 cmp->offsets[i * 2] -= leftmost; | |
17585 rightmost -= leftmost; | |
17586 } | |
17587 | |
17588 cmp->pixel_width = rightmost; | |
17589 cmp->ascent = highest; | |
17590 cmp->descent = - lowest; | |
17591 if (cmp->ascent < font_ascent) | |
17592 cmp->ascent = font_ascent; | |
17593 if (cmp->descent < font_descent) | |
17594 cmp->descent = font_descent; | |
17595 } | |
17596 | |
17597 it->pixel_width = cmp->pixel_width; | |
17598 it->ascent = it->phys_ascent = cmp->ascent; | |
17599 it->descent = it->phys_descent = cmp->descent; | |
17600 | |
17601 if (face->box != FACE_NO_BOX) | |
17602 { | |
17603 int thick = face->box_line_width; | |
17604 | |
17605 if (thick > 0) | |
17606 { | |
17607 it->ascent += thick; | |
17608 it->descent += thick; | |
17609 } | |
17610 else | |
17611 thick = - thick; | |
17612 | |
17613 if (it->start_of_box_run_p) | |
17614 it->pixel_width += thick; | |
17615 if (it->end_of_box_run_p) | |
17616 it->pixel_width += thick; | |
17617 } | |
17618 | |
17619 /* If face has an overline, add the height of the overline | |
17620 (1 pixel) and a 1 pixel margin to the character height. */ | |
17621 if (face->overline_p) | |
17622 it->ascent += 2; | |
17623 | |
17624 take_vertical_position_into_account (it); | |
17625 | |
17626 if (it->glyph_row) | |
17627 append_composite_glyph (it); | |
17628 } | |
17629 else if (it->what == IT_IMAGE) | |
17630 produce_image_glyph (it); | |
17631 else if (it->what == IT_STRETCH) | |
17632 produce_stretch_glyph (it); | |
17633 | |
17634 /* Accumulate dimensions. Note: can't assume that it->descent > 0 | |
17635 because this isn't true for images with `:ascent 100'. */ | |
17636 xassert (it->ascent >= 0 && it->descent >= 0); | |
17637 if (it->area == TEXT_AREA) | |
17638 it->current_x += it->pixel_width; | |
17639 | |
17640 it->descent += it->extra_line_spacing; | |
17641 | |
17642 it->max_ascent = max (it->max_ascent, it->ascent); | |
17643 it->max_descent = max (it->max_descent, it->descent); | |
17644 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent); | |
17645 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent); | |
17646 } | |
17647 | |
17648 | |
17649 | |
17650 | |
17651 | |
17652 | |
17653 /*********************************************************************** | |
15663 Cursor types | 17654 Cursor types |
15664 ***********************************************************************/ | 17655 ***********************************************************************/ |
15665 | 17656 |
15666 /* Value is the internal representation of the specified cursor type | 17657 /* Value is the internal representation of the specified cursor type |
15667 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width | 17658 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width |
15853 *width = 1; | 17844 *width = 1; |
15854 return cursor_type; | 17845 return cursor_type; |
15855 } | 17846 } |
15856 | 17847 |
15857 return NO_CURSOR; | 17848 return NO_CURSOR; |
17849 } | |
17850 | |
17851 | |
17852 /* Notice when the text cursor of window W has been completely | |
17853 overwritten by a drawing operation that outputs glyphs in AREA | |
17854 starting at X0 and ending at X1 in the line starting at Y0 and | |
17855 ending at Y1. X coordinates are area-relative. X1 < 0 means all | |
17856 the rest of the line after X0 has been written. Y coordinates | |
17857 are window-relative. */ | |
17858 | |
17859 void | |
17860 notice_overwritten_cursor (w, area, x0, x1, y0, y1) | |
17861 struct window *w; | |
17862 enum glyph_row_area area; | |
17863 int x0, y0, x1, y1; | |
17864 { | |
17865 #ifdef HAVE_CARBON | |
17866 /* ++KFS: Why is there a special version of this for the mac ? */ | |
17867 if (area == TEXT_AREA | |
17868 && w->phys_cursor_on_p | |
17869 && y0 <= w->phys_cursor.y | |
17870 && y1 >= w->phys_cursor.y + w->phys_cursor_height | |
17871 && x0 <= w->phys_cursor.x | |
17872 && (x1 < 0 || x1 > w->phys_cursor.x)) | |
17873 w->phys_cursor_on_p = 0; | |
17874 #else | |
17875 if (area == TEXT_AREA && w->phys_cursor_on_p) | |
17876 { | |
17877 int cx0 = w->phys_cursor.x; | |
17878 int cx1 = cx0 + w->phys_cursor_width; | |
17879 int cy0 = w->phys_cursor.y; | |
17880 int cy1 = cy0 + w->phys_cursor_height; | |
17881 | |
17882 if (x0 <= cx0 && (x1 < 0 || x1 >= cx1)) | |
17883 { | |
17884 /* The cursor image will be completely removed from the | |
17885 screen if the output area intersects the cursor area in | |
17886 y-direction. When we draw in [y0 y1[, and some part of | |
17887 the cursor is at y < y0, that part must have been drawn | |
17888 before. When scrolling, the cursor is erased before | |
17889 actually scrolling, so we don't come here. When not | |
17890 scrolling, the rows above the old cursor row must have | |
17891 changed, and in this case these rows must have written | |
17892 over the cursor image. | |
17893 | |
17894 Likewise if part of the cursor is below y1, with the | |
17895 exception of the cursor being in the first blank row at | |
17896 the buffer and window end because update_text_area | |
17897 doesn't draw that row. (Except when it does, but | |
17898 that's handled in update_text_area.) */ | |
17899 | |
17900 if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1)) | |
17901 && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p) | |
17902 w->phys_cursor_on_p = 0; | |
17903 } | |
17904 } | |
17905 #endif | |
15858 } | 17906 } |
15859 | 17907 |
15860 | 17908 |
15861 /*********************************************************************** | 17909 /*********************************************************************** |
15862 Initialization | 17910 Initialization |