Mercurial > octave
changeset 26858:0adb232f93b9
Implement axes and text "fontsmoothing" property (bug #55833).
* NEWS: Announce new property.
* base-text-renderer.h (base_text_renderer::set_anti_aliasing): New pure virtual
method
* ft-text-renderer.[h,cc] (text_renderer::m_antialias): New bool data member.
(ft_text_renderer::set_anti_aliasing): Implement
base_text_renderer::set_anti_aliasing.
(is_opaque): New function to determine if a pixel is opaque.
(ft_text_renderer::process_charater): Render glyph monochrome or antialiased
depending on m_antialias.
* text-renderer.[h,cc] (text_renderer::set_anti_aliasing): New method.
* graphics.in.h (axes::properties::fontsmoothing): Add "u" and corresponding
updater.
(text::properties::fontsmoothing,text::properties::update_fontsmoothing): New
property and corresponding updater.
* grpahics.cc (text::properties::update_font): Update the text_renderer
anti-aliasing.
* grpahics.cc (opengl_renderer::set_font): Update the text-renderer
anti-aliasing.
* genpropdoc: Document "fontsmoothnig" property.
author | Pantxo Diribarne <pantxo.diribarne@gmail.com> |
---|---|
date | Tue, 05 Mar 2019 13:51:16 +0100 |
parents | 65c036b78040 |
children | 7c9a681c4474 |
files | NEWS doc/interpreter/genpropdoc.m libinterp/corefcn/base-text-renderer.h libinterp/corefcn/ft-text-renderer.cc libinterp/corefcn/gl-render.cc libinterp/corefcn/graphics.cc libinterp/corefcn/graphics.in.h libinterp/corefcn/text-renderer.cc libinterp/corefcn/text-renderer.h |
diffstat | 9 files changed, 60 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Wed Mar 06 09:51:21 2019 -0800 +++ b/NEWS Tue Mar 05 13:51:16 2019 +0100 @@ -14,6 +14,11 @@ (for example, the Y-axis of an axes object with `"ycolor" = "none"`) without hiding the entire primitive `"visibility" = "off"`. +- A new property `"FontSmoothing"` has been added to text and axes + objects that controls whether anti-aliasing is used during the + rendering of characters. The default is "on" which produces smooth, + more visually appealing text. + - The appearance of patterned lines `"LineStyle" = ":"|"--"|"-."` has been improved for small widths (`"LineWidth"` less than 1.5 pixels) which is a common scenario.
--- a/doc/interpreter/genpropdoc.m Wed Mar 06 09:51:21 2019 -0800 +++ b/doc/interpreter/genpropdoc.m Tue Mar 05 13:51:16 2019 +0100 @@ -696,12 +696,12 @@ s.doc = doc_fontsize; s.valid = "scalar"; + case "fontsmoothing" + s.doc = "Control whether any text associated with __objname__ is anti-aliased."; + case "fontunits" s.doc = doc_fontunits; - case "fontsmoothing" - s.doc = doc_unused; - case "fontweight" s.doc = doc_fontweight; @@ -1082,6 +1082,9 @@ s.doc = doc_fontname; s.valid = valid_string; + case "fontsmoothing" + s.doc = "Control whether anti-aliasing is used when rendering text."; + case "fontsize" s.doc = doc_fontsize; s.valid = "scalar";
--- a/libinterp/corefcn/base-text-renderer.h Wed Mar 06 09:51:21 2019 -0800 +++ b/libinterp/corefcn/base-text-renderer.h Tue Mar 05 13:51:16 2019 +0100 @@ -52,6 +52,9 @@ virtual ~base_text_renderer (void) = default; + virtual void + set_anti_aliasing (bool val) = 0; + virtual Matrix get_extent (text_element *elt, double rotation) = 0;
--- a/libinterp/corefcn/ft-text-renderer.cc Wed Mar 06 09:51:21 2019 -0800 +++ b/libinterp/corefcn/ft-text-renderer.cc Tue Mar 05 13:51:16 2019 +0100 @@ -369,7 +369,7 @@ xoffset (0), line_yoffset (0), yoffset (0), mode (MODE_BBOX), color (dim_vector (1, 3), 0), m_do_strlist (false), m_strlist (), line_xoffset (0), m_ymin (0), m_ymax (0), m_deltax (0), - m_max_fontsize (0) + m_max_fontsize (0), m_antialias (true) { } // No copying! @@ -413,6 +413,8 @@ Matrix get_extent (const std::string& txt, double rotation, const caseless_str& interpreter); + void set_anti_aliasing (bool val) { m_antialias = val; }; + void set_font (const std::string& name, const std::string& weight, const std::string& angle, double size); @@ -537,6 +539,9 @@ // Used for computing the distance between lines. double m_max_fontsize; + + // Anti-aliasing. + bool m_antialias; }; @@ -703,7 +708,17 @@ break; } } - + bool is_opaque (const FT_GlyphSlot &glyph, const int x, const int y) + { + // Borrowed from https://stackoverflow.com/questions/14800827/ + // indexing-pixels-in-a-monochrome-freetype-glyph-buffer + int pitch = std::abs (glyph->bitmap.pitch); + unsigned char *row = &glyph->bitmap.buffer[pitch * y]; + char cvalue = row[x >> 3]; + + return ((cvalue & (128 >> (x & 7))) != 0); + } + FT_UInt ft_text_renderer::process_character (FT_ULong code, FT_UInt previous) { @@ -745,7 +760,9 @@ switch (mode) { case MODE_RENDER: - if (FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL)) + if (FT_Render_Glyph (face->glyph, (m_antialias + ? FT_RENDER_MODE_NORMAL + : FT_RENDER_MODE_MONO))) { glyph_index = 0; warn_glyph_render (code); @@ -777,7 +794,11 @@ for (int r = 0; static_cast<unsigned int> (r) < bitmap.rows; r++) for (int c = 0; static_cast<unsigned int> (c) < bitmap.width; c++) { - unsigned char pix = bitmap.buffer[r*bitmap.width+c]; + unsigned char pix + = (m_antialias + ? bitmap.buffer[r*bitmap.width+c] + : (is_opaque (face->glyph, c, r) ? 255 : 0)); + if (x0+c < 0 || x0+c >= pixels.dim2 () || y0-r < 0 || y0-r >= pixels.dim3 ()) {
--- a/libinterp/corefcn/gl-render.cc Wed Mar 06 09:51:21 2019 -0800 +++ b/libinterp/corefcn/gl-render.cc Tue Mar 05 13:51:16 2019 +0100 @@ -4008,6 +4008,8 @@ void opengl_renderer::set_font (const base_properties& props) { + bool do_anti_alias = props.get ("fontsmoothing").string_value () == "on"; + txt_renderer.set_anti_aliasing (do_anti_alias); txt_renderer.set_font (props.get ("fontname").string_value (), props.get ("fontweight").string_value (), props.get ("fontangle").string_value (),
--- a/libinterp/corefcn/graphics.cc Wed Mar 06 09:51:21 2019 -0800 +++ b/libinterp/corefcn/graphics.cc Tue Mar 05 13:51:16 2019 +0100 @@ -9182,6 +9182,8 @@ get ("fontangle").string_value (), get ("__fontsize_points__").double_value () * dpr); + txt_renderer.set_anti_aliasing (is_fontsmoothing ()); + Matrix c = get_color_rgb (); if (! c.isempty ()) txt_renderer.set_color (c); @@ -9474,7 +9476,7 @@ // check coplanarity for 3D-faces with more than 3 corners int fcmax = idx.rows (); - if (fcmax > 3 && vert.columns () > 2 && + if (fcmax > 3 && vert.columns () > 2 && ! (facecolor_is ("none") && edgecolor_is ("none"))) { for (octave_idx_type jj = 0; jj < idx.columns (); jj++)
--- a/libinterp/corefcn/graphics.in.h Wed Mar 06 09:51:21 2019 -0800 +++ b/libinterp/corefcn/graphics.in.h Tue Mar 05 13:51:16 2019 +0100 @@ -3630,8 +3630,8 @@ radio_property fontangle u , "{normal}|italic" string_property fontname u , OCTAVE_DEFAULT_FONTNAME double_property fontsize u , 10 + bool_property fontsmoothing u , "on" radio_property fontunits SU , "{points}|inches|centimeters|normalized|pixels" - bool_property fontsmoothing , "on" radio_property fontweight u , "{normal}|bold" double_property gridalpha m , 0.15 radio_property gridalphamode , "{auto}|manual" @@ -3968,6 +3968,10 @@ update_font ("fontsize"); sync_positions (); } + void update_fontsmoothing (void) + { + update_font ("fontsmoothing"); + } void update_fontangle (void) { update_font ("fontangle"); @@ -4347,6 +4351,7 @@ radio_property fontangle u , "{normal}|italic|oblique" string_property fontname u , OCTAVE_DEFAULT_FONTNAME double_property fontsize u , 10 + bool_property fontsmoothing u , "on" radio_property fontunits SU , "inches|centimeters|normalized|{points}|pixels" radio_property fontweight u , "{normal}|bold" radio_property horizontalalignment mu , "{left}|center|right" @@ -4435,6 +4440,7 @@ void update_rotation (void) { update_text_extent (); } void update_fontname (void) { update_font (); update_text_extent (); } void update_fontsize (void) { update_font (); update_text_extent (); } + void update_fontsmoothing (void) { update_font (); update_text_extent (); } void update_color (void) {
--- a/libinterp/corefcn/text-renderer.cc Wed Mar 06 09:51:21 2019 -0800 +++ b/libinterp/corefcn/text-renderer.cc Tue Mar 05 13:51:16 2019 +0100 @@ -87,6 +87,13 @@ } void + text_renderer::set_anti_aliasing (bool val) + { + if (ok ()) + rep->set_anti_aliasing (val); + } + + void text_renderer::set_font (const std::string& name, const std::string& weight, const std::string& angle, double size) {
--- a/libinterp/corefcn/text-renderer.h Wed Mar 06 09:51:21 2019 -0800 +++ b/libinterp/corefcn/text-renderer.h Tue Mar 05 13:51:16 2019 +0100 @@ -62,6 +62,8 @@ Matrix get_extent (const std::string& txt, double rotation = 0.0, const caseless_str& interpreter = "tex"); + void set_anti_aliasing (bool val); + void set_font (const std::string& name, const std::string& weight, const std::string& angle, double size);