Mercurial > octave
diff libinterp/corefcn/txt-eng-ft.cc @ 20622:caa5dabc7913
Let the freetype renderer return a list of parsed substrings (bug #31468)
* txt-eng-ft.h (ft_render::ft_string): new class based on ft_font, that stores substrings position and font data.
* txt-eng-ft.h (ft_render::text_to_strlist): new method that calls text_to_pixels and returns a list of parsed ft_string objects.
* txt-eng-ft.h (ft_render::strlist): new private attribute. A list of ft_string objects.
* txt-eng-ft.h (ft_render::line_xoffset): new private attribute.
* txt-eng-ft.h (ft_render::line_xoffset): new private attribute.
* txt-eng-ft.h (ft_render::text_to_pixels): add a boolean argument "handle_rotation" that defaults to true.
* txt-eng-ft.c (ft_render::text_to_pixels): don't rotate the bounding box when handle_rotation if false
* txt-eng-ft.c (ft_render::render): clear strlist before rendering
* txt-eng-ft.c (ft_render::visit (text_element_string)): feed strlist with a new ft_string for each substring
* txt-eng-ft.c (ft_render::visit (text_element_symbol& e)): feed strlist with a substring containing the symbol code
* txt-eng-ft.c (ft_render::push_new_line): store line_xoffset
author | Pantxo Diribarne <pantxo.diribarne@gmail.com> |
---|---|
date | Mon, 12 Oct 2015 22:14:25 +0200 |
parents | 25caa0deaabb |
children | 5b7643257978 |
line wrap: on
line diff
--- a/libinterp/corefcn/txt-eng-ft.cc Wed Oct 14 10:35:53 2015 -0700 +++ b/libinterp/corefcn/txt-eng-ft.cc Mon Oct 12 22:14:25 2015 +0200 @@ -366,7 +366,7 @@ line_bbox.pop_front (); Matrix new_bbox = line_bbox.front (); - xoffset = compute_line_xoffset (new_bbox); + xoffset = line_xoffset = compute_line_xoffset (new_bbox); line_yoffset += (old_bbox(1) - (new_bbox(1) + new_bbox(3))); yoffset = 0; } @@ -637,10 +637,14 @@ std::string str = e.string_value (); size_t n = str.length (); size_t curr = 0; + size_t idx = 0; mbstate_t ps; memset (&ps, 0, sizeof (ps)); // Initialize state to 0. wchar_t wc; + ft_string fs (str, font.get_angle (), font.get_weight (), + font.get_name (), font.get_size (), xoffset, yoffset); + while (n > 0) { size_t r = gnulib::mbrtowc (&wc, str.data () + curr, n, &ps); @@ -652,10 +656,32 @@ n -= r; curr += r; + if (wc == L'\n') + { + // Finish previous string in srtlist before processing + // the newline character + fs.set_y (line_yoffset + yoffset); + fs.set_color (color); + std::string s = str.substr (idx, curr - idx - 1); + if (! s.empty ()) + { + fs.set_string (s); + strlist.push_back (fs); + } + } + glyph_index = process_character (wc, previous); if (wc == L'\n') - previous = 0; + { + previous = 0; + // Start a new string in strlist + idx = curr; + fs = ft_string (str.substr (idx), font.get_angle (), + font.get_weight (), font.get_name (), + font.get_size (), line_xoffset, yoffset); + + } else previous = glyph_index; } @@ -668,6 +694,12 @@ break; } } + if (! fs.get_string ().empty ()) + { + fs.set_y (line_yoffset + yoffset); + fs.set_color (color); + strlist.push_back (fs); + } } } @@ -805,11 +837,24 @@ ft_render::visit (text_element_symbol& e) { uint32_t code = e.get_symbol_code (); + + ft_string fs (std::string ("-"), font.get_angle (), font.get_weight (), + font.get_name (), font.get_size (), xoffset, yoffset); if (code != text_element_symbol::invalid_code && font.is_valid ()) - process_character (code); + { + process_character (code); + fs.set_code (code); + } else if (font.is_valid ()) ::warning ("ignoring unknown symbol: %d", e.get_symbol ()); + + if (fs.get_code ()) + { + fs.set_y (line_yoffset + yoffset); + fs.set_color (color); + strlist.push_back (fs); + } } void @@ -857,6 +902,9 @@ box = bbox; set_mode (MODE_RENDER); + // Clear the list of parsed strings + strlist.clear (); + if (pixels.numel () > 0) { elt->accept (*this); @@ -976,7 +1024,8 @@ ft_render::text_to_pixels (const std::string& txt, uint8NDArray& pixels_, Matrix& box, int _halign, int valign, double rotation, - const caseless_str& interpreter) + const caseless_str& interpreter, + bool handle_rotation) { int rot_mode = rotation_to_mode (rotation); @@ -1007,23 +1056,24 @@ case 4: box(1) = -box(3)-box(1); break; } - switch (rot_mode) - { - case ROTATION_90: - std::swap (box(0), box(1)); - std::swap (box(2), box(3)); - box(0) = -box(0)-box(2); - break; - case ROTATION_180: - box(0) = -box(0)-box(2); - box(1) = -box(1)-box(3); - break; - case ROTATION_270: - std::swap (box(0), box(1)); - std::swap (box(2), box(3)); - box(1) = -box(1)-box(3); - break; - } + if (handle_rotation) + switch (rot_mode) + { + case ROTATION_90: + std::swap (box(0), box(1)); + std::swap (box(2), box(3)); + box(0) = -box(0)-box(2); + break; + case ROTATION_180: + box(0) = -box(0)-box(2); + box(1) = -box(1)-box(3); + break; + case ROTATION_270: + std::swap (box(0), box(1)); + std::swap (box(2), box(3)); + box(1) = -box(1)-box(3); + break; + } } ft_render::ft_font::ft_font (const ft_font& ft)