diff options
| author | Jan D | 2015-05-10 19:30:39 +0200 |
|---|---|---|
| committer | Jan D | 2015-05-10 19:33:06 +0200 |
| commit | b9ace209580458c694926200f9308c290bd911cd (patch) | |
| tree | 27e6061cec3abab112fe470cbb1dd9d3f762ac0a | |
| parent | ae4e3dd50f1b19a8a3b30e5a7012a9317934c0ab (diff) | |
| download | emacs-b9ace209580458c694926200f9308c290bd911cd.tar.gz emacs-b9ace209580458c694926200f9308c290bd911cd.zip | |
Draw composite string correctly (Bug#20537).
* nsterm.m (ns_draw_composite_glyph_string_foreground): New function.
(ns_draw_glyph_string): Call it (Bug#20537).
| -rw-r--r-- | src/nsterm.m | 103 |
1 files changed, 97 insertions, 6 deletions
diff --git a/src/nsterm.m b/src/nsterm.m index e90c3d70db3..187086cf826 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -3188,6 +3188,96 @@ ns_dumpglyphs_stretch (struct glyph_string *s) | |||
| 3188 | 3188 | ||
| 3189 | 3189 | ||
| 3190 | static void | 3190 | static void |
| 3191 | ns_draw_composite_glyph_string_foreground (struct glyph_string *s) | ||
| 3192 | { | ||
| 3193 | int i, j, x; | ||
| 3194 | struct font *font = s->font; | ||
| 3195 | |||
| 3196 | /* If first glyph of S has a left box line, start drawing the text | ||
| 3197 | of S to the right of that box line. */ | ||
| 3198 | if (s->face && s->face->box != FACE_NO_BOX | ||
| 3199 | && s->first_glyph->left_box_line_p) | ||
| 3200 | x = s->x + eabs (s->face->box_line_width); | ||
| 3201 | else | ||
| 3202 | x = s->x; | ||
| 3203 | |||
| 3204 | /* S is a glyph string for a composition. S->cmp_from is the index | ||
| 3205 | of the first character drawn for glyphs of this composition. | ||
| 3206 | S->cmp_from == 0 means we are drawing the very first character of | ||
| 3207 | this composition. */ | ||
| 3208 | |||
| 3209 | /* Draw a rectangle for the composition if the font for the very | ||
| 3210 | first character of the composition could not be loaded. */ | ||
| 3211 | if (s->font_not_found_p) | ||
| 3212 | { | ||
| 3213 | if (s->cmp_from == 0) | ||
| 3214 | { | ||
| 3215 | NSRect r = NSMakeRect (s->x, s->y, s->width-1, s->height -1); | ||
| 3216 | ns_draw_box (r, 1, FRAME_CURSOR_COLOR (s->f), 1, 1); | ||
| 3217 | } | ||
| 3218 | } | ||
| 3219 | else if (! s->first_glyph->u.cmp.automatic) | ||
| 3220 | { | ||
| 3221 | int y = s->ybase; | ||
| 3222 | |||
| 3223 | for (i = 0, j = s->cmp_from; i < s->nchars; i++, j++) | ||
| 3224 | /* TAB in a composition means display glyphs with padding | ||
| 3225 | space on the left or right. */ | ||
| 3226 | if (COMPOSITION_GLYPH (s->cmp, j) != '\t') | ||
| 3227 | { | ||
| 3228 | int xx = x + s->cmp->offsets[j * 2]; | ||
| 3229 | int yy = y - s->cmp->offsets[j * 2 + 1]; | ||
| 3230 | |||
| 3231 | font->driver->draw (s, j, j + 1, xx, yy, false); | ||
| 3232 | if (s->face->overstrike) | ||
| 3233 | font->driver->draw (s, j, j + 1, xx + 1, yy, false); | ||
| 3234 | } | ||
| 3235 | } | ||
| 3236 | else | ||
| 3237 | { | ||
| 3238 | Lisp_Object gstring = composition_gstring_from_id (s->cmp_id); | ||
| 3239 | Lisp_Object glyph; | ||
| 3240 | int y = s->ybase; | ||
| 3241 | int width = 0; | ||
| 3242 | |||
| 3243 | for (i = j = s->cmp_from; i < s->cmp_to; i++) | ||
| 3244 | { | ||
| 3245 | glyph = LGSTRING_GLYPH (gstring, i); | ||
| 3246 | if (NILP (LGLYPH_ADJUSTMENT (glyph))) | ||
| 3247 | width += LGLYPH_WIDTH (glyph); | ||
| 3248 | else | ||
| 3249 | { | ||
| 3250 | int xoff, yoff, wadjust; | ||
| 3251 | |||
| 3252 | if (j < i) | ||
| 3253 | { | ||
| 3254 | font->driver->draw (s, j, i, x, y, false); | ||
| 3255 | if (s->face->overstrike) | ||
| 3256 | font->driver->draw (s, j, i, x + 1, y, false); | ||
| 3257 | x += width; | ||
| 3258 | } | ||
| 3259 | xoff = LGLYPH_XOFF (glyph); | ||
| 3260 | yoff = LGLYPH_YOFF (glyph); | ||
| 3261 | wadjust = LGLYPH_WADJUST (glyph); | ||
| 3262 | font->driver->draw (s, i, i + 1, x + xoff, y + yoff, false); | ||
| 3263 | if (s->face->overstrike) | ||
| 3264 | font->driver->draw (s, i, i + 1, x + xoff + 1, y + yoff, | ||
| 3265 | false); | ||
| 3266 | x += wadjust; | ||
| 3267 | j = i + 1; | ||
| 3268 | width = 0; | ||
| 3269 | } | ||
| 3270 | } | ||
| 3271 | if (j < i) | ||
| 3272 | { | ||
| 3273 | font->driver->draw (s, j, i, x, y, false); | ||
| 3274 | if (s->face->overstrike) | ||
| 3275 | font->driver->draw (s, j, i, x + 1, y, false); | ||
| 3276 | } | ||
| 3277 | } | ||
| 3278 | } | ||
| 3279 | |||
| 3280 | static void | ||
| 3191 | ns_draw_glyph_string (struct glyph_string *s) | 3281 | ns_draw_glyph_string (struct glyph_string *s) |
| 3192 | /* -------------------------------------------------------------------------- | 3282 | /* -------------------------------------------------------------------------- |
| 3193 | External (RIF): Main draw-text call. | 3283 | External (RIF): Main draw-text call. |
| @@ -3279,13 +3369,14 @@ ns_draw_glyph_string (struct glyph_string *s) | |||
| 3279 | 3369 | ||
| 3280 | { | 3370 | { |
| 3281 | BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH; | 3371 | BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH; |
| 3282 | int end = isComposite ? s->cmp_to : s->nchars; | ||
| 3283 | |||
| 3284 | font->driver->draw | ||
| 3285 | (s, s->cmp_from, end, s->x, s->ybase, | ||
| 3286 | (flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p) | ||
| 3287 | || flags == NS_DUMPGLYPH_MOUSEFACE); | ||
| 3288 | 3372 | ||
| 3373 | if (isComposite) | ||
| 3374 | ns_draw_composite_glyph_string_foreground (s); | ||
| 3375 | else | ||
| 3376 | font->driver->draw | ||
| 3377 | (s, s->cmp_from, s->nchars, s->x, s->ybase, | ||
| 3378 | (flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p) | ||
| 3379 | || flags == NS_DUMPGLYPH_MOUSEFACE); | ||
| 3289 | } | 3380 | } |
| 3290 | 3381 | ||
| 3291 | { | 3382 | { |