From 69b84a8f6c789726815261c2e86692de7a65d6e8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 12 Apr 2012 15:50:40 -0400 Subject: [PATCH] Fix hb-view surface size calc for vertical text For some reason it doesn't quite work with IranianNastaliq, but that looks like a font issue. --- util/helper-cairo.hh | 5 +++-- util/options.hh | 7 +++++++ util/view-cairo.cc | 31 +++++++++++++++++++++---------- util/view-cairo.hh | 1 + 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/util/helper-cairo.hh b/util/helper-cairo.hh index 5edfc3a..bc3fe1d 100644 --- a/util/helper-cairo.hh +++ b/util/helper-cairo.hh @@ -64,8 +64,9 @@ struct helper_cairo_line_t { g_free (utf8); } - double get_width (void) { - return glyphs[num_glyphs].x; + void get_advance (double *x_advance, double *y_advance) { + *x_advance = glyphs[num_glyphs].x; + *y_advance = glyphs[num_glyphs].y; } }; diff --git a/util/options.hh b/util/options.hh index 165e7a1..da95017 100644 --- a/util/options.hh +++ b/util/options.hh @@ -48,6 +48,13 @@ #include #include +#undef MIN +template static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; } + +#undef MAX +template static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; } + + void fail (hb_bool_t suggest_help, const char *format, ...) G_GNUC_NORETURN; diff --git a/util/view-cairo.cc b/util/view-cairo.cc index f766a4f..ce578ed 100644 --- a/util/view-cairo.cc +++ b/util/view-cairo.cc @@ -38,6 +38,7 @@ view_cairo_t::consume_line (hb_buffer_t *buffer, const char *text, unsigned int text_len) { + direction = hb_buffer_get_direction (buffer); helper_cairo_line_t l; helper_cairo_line_from_buffer (&l, buffer, text, text_len, scale); g_array_append_val (lines, l); @@ -63,14 +64,17 @@ view_cairo_t::get_surface_size (cairo_scaled_font_t *scaled_font, cairo_scaled_font_extents (scaled_font, &font_extents); - *h = font_extents.ascent - + font_extents.descent - + ((int) lines->len - 1) * (font_extents.height + line_space); - *w = 0; + bool vertical = HB_DIRECTION_IS_VERTICAL (direction); + (vertical ? *w : *h) = (int) lines->len * (font_extents.height + line_space) - line_space; + (vertical ? *h : *w) = 0; for (unsigned int i = 0; i < lines->len; i++) { helper_cairo_line_t &line = g_array_index (lines, helper_cairo_line_t, i); - double line_width = line.get_width (); - *w = MAX (*w, line_width); + double x_advance, y_advance; + line.get_advance (&x_advance, &y_advance); + if (vertical) + *h = MAX (*h, y_advance); + else + *w = MAX (*w, x_advance); } *w += margin.l + margin.r; @@ -97,17 +101,26 @@ view_cairo_t::draw (cairo_t *cr) { cairo_save (cr); + bool vertical = HB_DIRECTION_IS_VERTICAL (direction); + int v = vertical ? 1 : 0; + int h = vertical ? 0 : 1; cairo_font_extents_t font_extents; cairo_font_extents (cr, &font_extents); cairo_translate (cr, margin.l, margin.t); + double descent; + if (vertical) + descent = font_extents.height * .5; + else + descent = font_extents.height - font_extents.ascent; + cairo_translate (cr, v * -descent, h * -descent); for (unsigned int i = 0; i < lines->len; i++) { helper_cairo_line_t &l = g_array_index (lines, helper_cairo_line_t, i); if (i) - cairo_translate (cr, 0, line_space); + cairo_translate (cr, v * line_space, h * line_space); - cairo_translate (cr, 0, font_extents.ascent); + cairo_translate (cr, v * font_extents.height, h * font_extents.height); if (annotate) { cairo_save (cr); @@ -137,8 +150,6 @@ view_cairo_t::draw (cairo_t *cr) l.cluster_flags); else cairo_show_glyphs (cr, l.glyphs, l.num_glyphs); - - cairo_translate (cr, 0, font_extents.height - font_extents.ascent); } cairo_restore (cr); diff --git a/util/view-cairo.hh b/util/view-cairo.hh index 564f5c7..0f4fe94 100644 --- a/util/view-cairo.hh +++ b/util/view-cairo.hh @@ -52,6 +52,7 @@ struct view_cairo_t : output_options_t, view_options_t { void get_surface_size (cairo_scaled_font_t *scaled_font, double *w, double *h); void draw (cairo_t *cr); + hb_direction_t direction; // Remove this, make segment_properties accessible GArray *lines; double scale; }; -- 2.7.4