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