# HG changeset patch # User Konstantinos Poulios # Date 1292979594 -3600 # Branch text-extents # Node ID ec67e099f1523f0a21f14469687023f16f390391 # Parent f94a71bf5e88151529c2ee7ecdf10c6f5ad29aa9 New text extent calculation and extent aware text drawing. diff -r f94a71bf5e88 -r ec67e099f152 src/ChangeLog --- a/src/ChangeLog Wed Dec 22 01:08:59 2010 +0100 +++ b/src/ChangeLog Wed Dec 22 01:59:54 2010 +0100 @@ -6,7 +6,24 @@ (ft_render::text_to_pixels) New method. * graphics.cc (text::properties::update_text_extent): Adapt the call to ft_render::set_font. + (text::properties::get_extent_matrix): New function. + (text::properties::update_text_extent): Function rewrite. * gl-render.cc (opengl_renderer::set_font): Likewise. + (opengl_renderer::text_to_pixels): + Make use of ft_render::text_to_pixels. + (opengl_renderer::render_text): Simplify. + (opengl_renderer::draw_text): Make text drawing aware of the text + extent property. + * gl-render.h (opengl_renderer::text_to_pixels) Arguments reordering. + * gl2ps-renderer.cc (glps_renderer::render_text) Adapt the call to + text_to_pixels. + * graphics.h.in: Add dependency on txt-eng-ft.h. + (class text::properties): Tag horizontalalignment and verticalalignment + with "u" qualifier. + (text::properties::get_extent_matrix, get_pixels, + update_horizontalalignment, update_verticalalignment): New functions. + (text::properties::renderer): New class member of type ft_render. + (text::properties::pixels): New class member of type uint8NDArray. 2012-12-17 Konstantinos Poulios diff -r f94a71bf5e88 -r ec67e099f152 src/gl-render.cc --- a/src/gl-render.cc Wed Dec 22 01:08:59 2010 +0100 +++ b/src/gl-render.cc Wed Dec 22 01:59:54 2010 +0100 @@ -2838,25 +2838,21 @@ set_color (props.get_color_rgb ()); const Matrix pos = xform.scale (props.get_data_position ()); - int halign = 0, valign = 0; - - if (props.horizontalalignment_is ("center")) - halign = 1; - else if (props.horizontalalignment_is ("right")) - halign = 2; - - if (props.verticalalignment_is ("top")) - valign = 2; - else if (props.verticalalignment_is ("baseline")) - valign = 3; - else if (props.verticalalignment_is ("middle")) - valign = 1; + const Matrix bbox = props.get_extent_matrix (); // FIXME: handle margin and surrounding box - - render_text (props.get_string (), - pos(0), pos(1), pos(2), - halign, valign, props.get_rotation ()); + bool blend = glIsEnabled (GL_BLEND); + + glEnable (GL_BLEND); + glEnable (GL_ALPHA_TEST); + glRasterPos3d (pos(0), pos(1), pos(2)); + glBitmap(0, 0, 0, 0, bbox(0), bbox(1), 0); + glDrawPixels (bbox(2), bbox(3), + GL_RGBA, GL_UNSIGNED_BYTE, props.get_pixels ().data ()); + glDisable (GL_ALPHA_TEST); + if (! blend) + glDisable (GL_BLEND); + } void @@ -3377,25 +3373,12 @@ void opengl_renderer::text_to_pixels (const std::string& txt, - double rotation, uint8NDArray& pixels, Matrix& bbox, - int& rot_mode) + int halign, int valign, double rotation) { - // FIXME: clip "rotation" between 0 and 360 - - rot_mode = ft_render::ROTATION_0; - - if (rotation == 90.0) - rot_mode = ft_render::ROTATION_90; - else if (rotation == 180.0) - rot_mode = ft_render::ROTATION_180; - else if (rotation == 270.0) - rot_mode = ft_render::ROTATION_270; - - text_element *elt = text_parser_none ().parse (txt); - pixels = text_renderer.render (elt, bbox, rot_mode); - delete elt; + text_renderer.text_to_pixels (txt, pixels, bbox, + halign, valign, rotation); } Matrix @@ -3407,59 +3390,17 @@ if (txt.empty ()) return Matrix (1, 4, 0.0); + uint8NDArray pixels; Matrix bbox; - uint8NDArray pixels; - int rot_mode; - text_to_pixels (txt, rotation, pixels, bbox, rot_mode); - - int x0 = 0, y0 = 0; - int w = bbox(2), h = bbox(3); - - if (pixels.numel () == 0) - { - // nothing to render - return bbox; - } - - switch (halign) - { - default: break; - case 1: x0 = -bbox(2)/2; break; - case 2: x0 = -bbox(2); break; - } - switch (valign) - { - default: break; - case 1: y0 = -bbox(3)/2; break; - case 2: y0 = -bbox(3); break; - case 3: y0 = bbox(1); break; - } - - switch (rot_mode) - { - case ft_render::ROTATION_90: - std::swap (x0, y0); - std::swap (w, h); - x0 = -x0-bbox(3); - break; - case ft_render::ROTATION_180: - x0 = -x0-bbox(2); - y0 = -y0-bbox(3); - break; - case ft_render::ROTATION_270: - std::swap (x0, y0); - std::swap (w, h); - y0 = -y0-bbox(2); - break; - } + text_to_pixels (txt, pixels, bbox, halign, valign, rotation); bool blend = glIsEnabled (GL_BLEND); glEnable (GL_BLEND); glEnable (GL_ALPHA_TEST); glRasterPos3d (x, y, z); - glBitmap(0, 0, 0, 0, x0, y0, 0); - glDrawPixels (w, h, + glBitmap(0, 0, 0, 0, bbox(0), bbox(1), 0); + glDrawPixels (bbox(2), bbox(3), GL_RGBA, GL_UNSIGNED_BYTE, pixels.data ()); glDisable (GL_ALPHA_TEST); if (! blend) diff -r f94a71bf5e88 -r ec67e099f152 src/gl-render.h --- a/src/gl-render.h Wed Dec 22 01:08:59 2010 +0100 +++ b/src/gl-render.h Wed Dec 22 01:59:54 2010 +0100 @@ -97,10 +97,10 @@ const Matrix& lc, const Matrix& fc); virtual void text_to_pixels (const std::string& txt, - double rotation, uint8NDArray& pixels, Matrix& bbox, - int& rot_mode); + int halign = 0, int valign = 0, + double rotation = 0.0); virtual Matrix render_text (const std::string& txt, double x, double y, double z, diff -r f94a71bf5e88 -r ec67e099f152 src/gl2ps-renderer.cc --- a/src/gl2ps-renderer.cc Wed Dec 22 01:08:59 2010 +0100 +++ b/src/gl2ps-renderer.cc Wed Dec 22 01:59:54 2010 +0100 @@ -133,9 +133,7 @@ // we use freetype Matrix bbox; uint8NDArray pixels; - int rot_mode; - text_to_pixels (txt, rotation, pixels, bbox, rot_mode); - + text_to_pixels (txt, pixels, bbox, 0, 0, rotation); return bbox; } diff -r f94a71bf5e88 -r ec67e099f152 src/graphics.cc --- a/src/graphics.cc Wed Dec 22 01:08:59 2010 +0100 +++ b/src/graphics.cc Wed Dec 22 01:59:54 2010 +0100 @@ -5057,6 +5057,12 @@ return pos; } +Matrix +text::properties::get_extent_matrix (void) const +{ + return extent.get ().matrix_value (); +} + octave_value text::properties::get_extent (void) const { @@ -5070,33 +5076,37 @@ { #ifdef HAVE_FREETYPE - text_element *elt; - ft_render text_renderer; - Matrix box; - - // FIXME: parsed content should be cached for efficiency + // FIXME: font and color should be set only when modified, for efficiency +#ifdef HAVE_FONTCONFIG + renderer.set_font (get ("fontname").string_value (), + get ("fontweight").string_value (), + get ("fontangle").string_value (), + get ("fontsize").double_value ()); +#endif + renderer.set_color (get_color_rgb ()); + + int halign = 0, valign = 0; + + if (horizontalalignment_is ("center")) + halign = 1; + else if (horizontalalignment_is ("right")) + halign = 2; - elt = text_parser_none ().parse (get_string ()); -#ifdef HAVE_FONTCONFIG - text_renderer.set_font (get ("fontname").string_value (), - get ("fontweight").string_value (), - get ("fontangle").string_value (), - get ("fontsize").double_value ()); -#endif - box = text_renderer.get_extent (elt, get_rotation ()); - - delete elt; - - Matrix ext (1, 4, 0.0); - - // FIXME: also handle left and bottom components - - ext(0) = ext(1) = 1; - ext(2) = box(0); - ext(3) = box(1); - - set_extent (ext); - + if (verticalalignment_is ("top")) + valign = 2; + else if (verticalalignment_is ("baseline")) + valign = 3; + else if (verticalalignment_is ("middle")) + valign = 1; + + Matrix bbox; + // FIXME: string should be parsed only when modified, for efficiency + renderer.text_to_pixels (get_string (), pixels, bbox, + halign, valign, get_rotation ()); + + set_extent (bbox); +#else + warning ("update_text_extent: cannot render text, Freetype library not available"); #endif } diff -r f94a71bf5e88 -r ec67e099f152 src/graphics.h.in --- a/src/graphics.h.in Wed Dec 22 01:08:59 2010 +0100 +++ b/src/graphics.h.in Wed Dec 22 01:59:54 2010 +0100 @@ -42,6 +42,7 @@ #include "oct-map.h" #include "oct-mutex.h" #include "ov.h" +#include "txt-eng-ft.h" // FIXME -- maybe this should be a configure option? // Matlab defaults to "Helvetica", but that causes problems for many @@ -3518,7 +3519,7 @@ radio_property units u , "{data}|pixels|normalized|inches|centimeters|points" array_property position mu , Matrix (1, 3, 0.0) double_property rotation mu , 0 - radio_property horizontalalignment m , "{left}|center|right" + radio_property horizontalalignment mu , "{left}|center|right" color_property color , color_values (0, 0, 0) string_property fontname u , OCTAVE_DEFAULT_FONTNAME double_property fontsize u , 10 @@ -3534,7 +3535,7 @@ radio_property linestyle , "{-}|--|:|-.|none" double_property linewidth , 0.5 double_property margin , 1 - radio_property verticalalignment m , "top|cap|{middle}|baseline|bottom" + radio_property verticalalignment mu , "top|cap|{middle}|baseline|bottom" array_property extent rG , Matrix (1, 4, 0.0) // hidden properties for limit computation row_vector_property xlim hlr , Matrix () @@ -3551,6 +3552,12 @@ END_PROPERTIES Matrix get_data_position (void) const; + Matrix get_extent_matrix (void) const; + const uint8NDArray& get_pixels (void) const { return pixels; } +#if HAVE_FREETYPE + // freetype render, used for text rendering + ft_render renderer; +#endif protected: void init (void) @@ -3594,11 +3601,14 @@ void update_fontangle (void) { update_text_extent (); } void update_fontweight (void) { update_text_extent (); } void update_interpreter (void) { update_text_extent (); } + void update_horizontalalignment (void) { update_text_extent (); } + void update_verticalalignment (void) { update_text_extent (); } void update_units (void); private: std::string cached_units; + uint8NDArray pixels; }; private: