Mercurial > octave
changeset 24173:730227072acb
Add support for text background area for OpenGL toolkits (bug #39692).
* gl-render.h, gl-render.cc (opengl_renderer::draw_text_background): New method.
(opengl_renderer::draw_axes_planes) Increase polygon_offset to 9 for axes
planes.
(opengl_renderer::draw_text) Call draw_text_background prior to drawing text.
* gl2ps-print.cc (gl2ps_renderer::draw_text): Ditto.
* genpropdoc.m (get_doc): Document relevant text properties.
* text.m: Modify second demo to include background properties.
* NEWS: Announce new functionality.
author | Pantxo Diribarne <pantxo.diribarne@gmail.com> |
---|---|
date | Sun, 15 Oct 2017 21:06:47 +0200 |
parents | 90903d915625 |
children | cc631e9926e1 |
files | NEWS doc/interpreter/genpropdoc.m libinterp/corefcn/gl-render.cc libinterp/corefcn/gl-render.h libinterp/corefcn/gl2ps-print.cc scripts/plot/appearance/text.m |
diffstat | 6 files changed, 140 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Mon Oct 23 18:21:12 2017 -0400 +++ b/NEWS Sun Oct 15 21:06:47 2017 +0200 @@ -59,6 +59,10 @@ warning ("off", "Octave:quadcc:RelTol-conversion") + ** The properties "BackgroundColor", "EdgeColor", "LineStyle", + "LineWidth", and "Margin" are now implemented for text objects using + an OpenGL toolkit. + ** Other new functions added in 4.4: camlookat
--- a/doc/interpreter/genpropdoc.m Mon Oct 23 18:21:12 2017 -0400 +++ b/doc/interpreter/genpropdoc.m Sun Oct 15 21:06:47 2017 +0200 @@ -1004,7 +1004,8 @@ ## Specific properties case "backgroundcolor" - s.doc = sprintf (doc_notimpl, "Background area"); + s.doc = "Color of the background area. \ +@xref{Colors, , colorspec}."; s.valid = valid_color; case "color" @@ -1013,7 +1014,8 @@ case "displayname" case "edgecolor" - s.doc = sprintf (doc_notimpl, "Background area"); + s.doc = "Color of the outline of the background area. \ +@xref{Colors, , colorspec}."; s.valid = valid_color; case "editing" @@ -1048,14 +1050,16 @@ @xref{XREFinterpreterusage, , @w{Use of the interpreter property}}."; case "linestyle" - s.doc = sprintf (doc_notimpl, "Background area"); + s.doc = "Style of the outline. @xref{Line Styles}."; case "linewidth" - s.doc = sprintf (doc_notimpl, "Background area"); + s.doc = "Width of the outline."; s.valid = "scalar"; case "margin" - s.doc = sprintf (doc_notimpl, "Background area"); + s.doc = "Margins between the borders of the background area \ +and the texts. The value is currently interpreted as pixels, regardless \ +of the @qcode{\"fontunits\"} property."; s.valid = "scalar"; case "position"
--- a/libinterp/corefcn/gl-render.cc Mon Oct 23 18:21:12 2017 -0400 +++ b/libinterp/corefcn/gl-render.cc Sun Oct 15 21:06:47 2017 +0200 @@ -1196,7 +1196,7 @@ // Axes planes set_color (axe_color); - set_polygon_offset (true, 2.5); + set_polygon_offset (true, 9.0); glBegin (GL_QUADS); @@ -2401,7 +2401,7 @@ glEnable (GL_LIGHTING); glShadeModel ((fc_mode == INTERP || fl_mode == GOURAUD) ? GL_SMOOTH : GL_FLAT); - set_polygon_offset (true, 1); + set_polygon_offset (true, 1.0); if (fc_mode == TEXTURE) glEnable (GL_TEXTURE_2D); @@ -3431,12 +3431,22 @@ if (props.get_string ().isempty ()) return; + Matrix pos = xform.scale (props.get_data_position ()); + + // Handle clipping manually when drawing text background + if (! props.is_clipping () || + (clip_code (pos(0), pos(1), pos.numel () > 2 ? pos(2) : 0.0) == + octave_uint8 (0x40))) + { + set_clipping (false); + draw_text_background (props); + set_clipping (props.is_clipping ()); + } + set_font (props); - Matrix pos = xform.scale (props.get_data_position ()); const Matrix bbox = props.get_extent_matrix (); - // FIXME: handle margin and surrounding box bool blend = glIsEnabled (GL_BLEND); glEnable (GL_BLEND); @@ -3462,6 +3472,110 @@ } void + opengl_renderer::draw_text_background (const text::properties& props, + bool do_rotate) + { +#if defined (HAVE_OPENGL) + + Matrix bgcol = props.get_backgroundcolor_rgb (); + Matrix ecol = props.get_edgecolor_rgb (); + + if (bgcol.isempty () && ecol.isempty ()) + return; + + Matrix pos = xform.scale (props.get_data_position ()); + ColumnVector pixpos = get_transform ().transform (pos(0), pos(1), + pos(2), false); + const Matrix bbox = props.get_extent_matrix (); + +# if defined (HAVE_FRAMEWORK_OPENGL) + GLint vp[4]; +# else + int vp[4]; +# endif + + glGetIntegerv (GL_VIEWPORT, vp); + + // Save current transform matrices and set orthogonal window coordinates + glMatrixMode (GL_PROJECTION); + glPushMatrix (); + glLoadIdentity (); + glOrtho (0, vp[2], vp[3], 0, xZ1, xZ2); + glMatrixMode (GL_MODELVIEW); + glPushMatrix (); + glLoadIdentity (); + + // Translate coordinates so that the text anchor is (0,0) + glTranslated (pixpos(0), pixpos(1), -pixpos(2)); + + // FIXME: Only multiples of 90° are handled by the text renderer. + // Handle others here. + double rotation = props.get_rotation (); + + if (do_rotate && rotation != 0.0 && rotation != 90.0 + && rotation != 180.0 && rotation != 270.0) + glRotated (-rotation, 0.0, 0.0, 1.0); + + double m = props.get_margin (); + double x0 = bbox (0) - m; + double x1 = x0 + bbox(2) + 2 * m; + double y0 = -(bbox (1) - m); + double y1 = y0 - (bbox(3) + 2 * m); + + if (! bgcol.isempty ()) + { + glColor3f (bgcol(0), bgcol(1), bgcol(2)); + + bool depth_test = glIsEnabled (GL_DEPTH_TEST); + if (depth_test) + set_polygon_offset (true, 4.0); + + glBegin (GL_QUADS); + glVertex2d (x0, y0); + glVertex2d (x1, y0); + glVertex2d (x1, y1); + glVertex2d (x0, y1); + glEnd (); + + if (depth_test) + set_polygon_offset (false); + } + + if (! ecol.isempty ()) + { + glColor3f (ecol(0), ecol(1), ecol(2)); + + set_linestyle (props.get_linestyle (), false, props.get_linewidth ()); + set_linewidth (props.get_linewidth ()); + + glBegin (GL_LINE_STRIP); + glVertex2d (x0, y0); + glVertex2d (x1, y0); + glVertex2d (x1, y1); + glVertex2d (x0, y1); + glVertex2d (x0, y0); + glEnd (); + } + + // Restore previous coordinate system + glPopMatrix(); + glMatrixMode (GL_PROJECTION); + glPopMatrix(); + +#else + + octave_unused_parameter (props); + octave_unused_parameter (do_rotate); + + // This shouldn't happen because construction of opengl_renderer + // objects is supposed to be impossible if OpenGL is not available. + + panic_impossible (); + +#endif + } + + void opengl_renderer::draw_image (const image::properties& props) { #if defined (HAVE_OPENGL)
--- a/libinterp/corefcn/gl-render.h Mon Oct 23 18:21:12 2017 -0400 +++ b/libinterp/corefcn/gl-render.h Sun Oct 15 21:06:47 2017 +0200 @@ -76,6 +76,8 @@ virtual void draw_light (const light::properties& props); virtual void draw_hggroup (const hggroup::properties& props); virtual void draw_text (const text::properties& props); + virtual void draw_text_background (const text::properties& props, + bool do_rotate = false); virtual void draw_image (const image::properties& props); virtual void draw_uipanel (const uipanel::properties& props, const graphics_object& go);
--- a/libinterp/corefcn/gl2ps-print.cc Mon Oct 23 18:21:12 2017 -0400 +++ b/libinterp/corefcn/gl2ps-print.cc Sun Oct 15 21:06:47 2017 +0200 @@ -947,6 +947,8 @@ if (props.get_string ().isempty ()) return; + draw_text_background (props, true); + // First set font properties: freetype will use them to compute // coordinates and gl2ps will retrieve the color directly from the // feedback buffer
--- a/scripts/plot/appearance/text.m Mon Oct 23 18:21:12 2017 -0400 +++ b/scripts/plot/appearance/text.m Sun Oct 15 21:06:47 2017 +0200 @@ -201,10 +201,15 @@ %! h = mesh (peaks, "edgecolor", 0.7 * [1 1 1], ... %! "facecolor", "none", ... %! "facealpha", 0); +%! colors = jet (9); +%! ii = 1; %! for t = 0:45:359; +%! ii = ii +1; %! text (25, 25, 0, "Vertical Alignment = Bottom", ... %! "rotation", t, ... %! "horizontalalignment", "left", ... +%! "backgroundcolor", colors(ii,:), ... +%! "edgecolor", "k", ... %! "verticalalignment", "bottom"); %! endfor %! caxis ([-100 100]);