[lasem] menclose: acceptable display for most notations



commit 2292ff81a07f606f51437f19fac63e8630116292
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Thu Jan 29 22:20:20 2015 +0100

    menclose: acceptable display for most notations
    
    Except for longdiv and radical.

 src/lsmmathmlencloseelement.c |   65 ++++++++++++--
 src/lsmmathmlencloseelement.h |    4 +
 src/lsmmathmlenums.h          |    3 +-
 src/lsmmathmltableelement.c   |   10 +-
 src/lsmmathmlutils.h          |   11 ++-
 src/lsmmathmlview.c           |  191 +++++++++++++++++++++++++++++++++++++++--
 src/lsmmathmlview.h           |   12 +++
 7 files changed, 272 insertions(+), 24 deletions(-)
---
diff --git a/src/lsmmathmlencloseelement.c b/src/lsmmathmlencloseelement.c
index 285cb73..f1324d7 100644
--- a/src/lsmmathmlencloseelement.c
+++ b/src/lsmmathmlencloseelement.c
@@ -22,21 +22,58 @@
  */
 
 #include <lsmmathmlencloseelement.h>
+#include <lsmmathmlview.h>
+
+static GObjectClass *parent_class;
 
 /* LsmDomNode implementation */
 
 static const char *
-lsm_mathml_enclose_element_get_node_name (LsmDomNode *node)
+_get_node_name (LsmDomNode *node)
 {
        return "menclose";
 }
 
-static gboolean
-lsm_mathml_enclose_element_can_append_child (LsmDomNode *self, LsmDomNode *child)
+/* LsmMathmlElement implementation */
+
+static void
+_update (LsmMathmlElement *self, LsmMathmlStyle *style)
+{
+}
+
+static const LsmMathmlBbox *
+_measure (LsmMathmlElement *self, LsmMathmlView *view, const LsmMathmlBbox *bbox)
+{
+       LsmMathmlEncloseElement *enclose = LSM_MATHML_ENCLOSE_ELEMENT (self);
+       LsmMathmlBbox stretch_bbox;
+
+       LSM_MATHML_ELEMENT_CLASS (parent_class)->measure (self, view, bbox);
+
+       stretch_bbox = self->bbox;
+
+       lsm_mathml_view_measure_notation (view, &self->style, enclose->notation.value, &stretch_bbox,
+                                         &self->bbox, &enclose->x_child_offset);
+
+       return &self->bbox;
+}
+
+static void
+_layout (LsmMathmlElement *self, LsmMathmlView *view,
+        double x, double y, const LsmMathmlBbox *bbox)
+{
+       LsmMathmlEncloseElement *enclose = LSM_MATHML_ENCLOSE_ELEMENT (self);
+
+       LSM_MATHML_ELEMENT_CLASS (parent_class)->layout (self, view, x + enclose->x_child_offset, y, bbox);
+}
+
+static void
+_render (LsmMathmlElement *self, LsmMathmlView *view)
 {
-       return (LSM_IS_MATHML_ELEMENT (child) &&
-               (self->first_child == NULL ||
-                self->first_child->next_sibling == NULL));
+       LsmMathmlEncloseElement *enclose = LSM_MATHML_ENCLOSE_ELEMENT (self);
+
+       LSM_MATHML_ELEMENT_CLASS (parent_class)->render (self, view);
+
+       lsm_mathml_view_show_notation (view, &self->style, enclose->notation.value, self->x, self->y, 
&self->bbox);
 }
 
 /* LsmMathmlEncloseElement implementation */
@@ -69,9 +106,21 @@ static void
 lsm_mathml_enclose_element_class_init (LsmMathmlEncloseElementClass *klass)
 {
        LsmDomNodeClass *d_node_class = LSM_DOM_NODE_CLASS (klass);
+       LsmMathmlElementClass *m_element_class = LSM_MATHML_ELEMENT_CLASS (klass);
+
+       parent_class = g_type_class_peek_parent (klass);
+
+       d_node_class->get_node_name = _get_node_name;
+
+       m_element_class->update = _update;
+       m_element_class->measure = _measure;
+       m_element_class->layout = _layout;
+       m_element_class->render = _render;
+       m_element_class->attribute_manager = lsm_attribute_manager_duplicate 
(m_element_class->attribute_manager);
 
-       d_node_class->get_node_name = lsm_mathml_enclose_element_get_node_name;
-       d_node_class->can_append_child = lsm_mathml_enclose_element_can_append_child;
+       lsm_attribute_manager_add_attributes (m_element_class->attribute_manager,
+                                             G_N_ELEMENTS (_attribute_infos),
+                                             _attribute_infos);
 }
 
 G_DEFINE_TYPE (LsmMathmlEncloseElement, lsm_mathml_enclose_element, LSM_TYPE_MATHML_PRESENTATION_CONTAINER)
diff --git a/src/lsmmathmlencloseelement.h b/src/lsmmathmlencloseelement.h
index 46a64f0..55e3dbe 100644
--- a/src/lsmmathmlencloseelement.h
+++ b/src/lsmmathmlencloseelement.h
@@ -42,6 +42,10 @@ struct _LsmMathmlEncloseElement {
        LsmMathmlPresentationContainer presentation_container;
 
        LsmMathmlEnumAttribute notation;
+
+       /* View data */
+
+       double x_child_offset;
 };
 
 struct _LsmMathmlEncloseElementClass {
diff --git a/src/lsmmathmlenums.h b/src/lsmmathmlenums.h
index 509e016..1beebdb 100644
--- a/src/lsmmathmlenums.h
+++ b/src/lsmmathmlenums.h
@@ -193,7 +193,8 @@ typedef enum {
        LSM_MATHML_NOTATION_VERTICAL_STRIKE,
        LSM_MATHML_NOTATION_HORIZONTAL_STRIKE,
        LSM_MATHML_NOTATION_MADRUWB,
-       LSM_MATHML_NOTATION_UP_DIAGONAL_ARROW
+       LSM_MATHML_NOTATION_UP_DIAGONAL_ARROW,
+       LSM_MATHML_NOTATION_LAST
 } LsmMathmlNotation;
 
 const char *           lsm_mathml_notation_to_string           (LsmMathmlNotation notation);
diff --git a/src/lsmmathmltableelement.c b/src/lsmmathmltableelement.c
index da15aa4..cf1fc1b 100644
--- a/src/lsmmathmltableelement.c
+++ b/src/lsmmathmltableelement.c
@@ -390,11 +390,11 @@ lsm_mathml_table_element_render (LsmMathmlElement *self, LsmMathmlView *view)
                spacing = table->column_spacing.values[MIN (i, table->column_spacing.n_values - 1)];
                x = position + 0.5 * (spacing + table->line_width);
                lsm_mathml_view_show_line (view, &self->style,
-                                       x, y0, x, y1,
-                                       table->column_lines.enum_list.values[MIN (i,
-                                                                                 
table->column_lines.enum_list.n_values
-                                                                                 - 1)],
-                                       table->line_width);
+                                          x, y0, x, y1,
+                                          table->column_lines.enum_list.values[MIN (i,
+                                                                                    
table->column_lines.enum_list.n_values
+                                                                                    - 1)],
+                                          table->line_width);
                position += spacing + table->line_width;
        }
 
diff --git a/src/lsmmathmlutils.h b/src/lsmmathmlutils.h
index c71d58b..6fe4476 100644
--- a/src/lsmmathmlutils.h
+++ b/src/lsmmathmlutils.h
@@ -35,15 +35,22 @@ typedef struct {
        gboolean is_defined;
 } LsmMathmlBbox;
 
+typedef struct {
+       double left;
+       double right;
+       double top;
+       double bottom;
+} LsmMathmlPadding;
+
 extern const LsmMathmlBbox lsm_mathml_bbox_null;
 
 void   lsm_mathml_bbox_add_horizontally                (LsmMathmlBbox *bbox, const LsmMathmlBbox *new_bbox);
 void   lsm_mathml_bbox_add_over                        (LsmMathmlBbox *self, const LsmMathmlBbox *bbox);
 void   lsm_mathml_bbox_add_under                       (LsmMathmlBbox *self, const LsmMathmlBbox *bbox);
 void   lsm_mathml_bbox_merge_vertically                (LsmMathmlBbox *self, const LsmMathmlBbox *bbox, 
double offset);
-void   lsm_mathml_bbox_stretch                 (LsmMathmlBbox *self, const LsmMathmlBbox *bbox);
+void   lsm_mathml_bbox_stretch                         (LsmMathmlBbox *self, const LsmMathmlBbox *bbox);
 void   lsm_mathml_bbox_stretch_vertically              (LsmMathmlBbox *self, const LsmMathmlBbox *bbox);
-void   lsm_mathml_bbox_stretch_horizontally    (LsmMathmlBbox *self, const LsmMathmlBbox *bbox);
+void   lsm_mathml_bbox_stretch_horizontally            (LsmMathmlBbox *self, const LsmMathmlBbox *bbox);
 
 G_END_DECLS
 
diff --git a/src/lsmmathmlview.c b/src/lsmmathmlview.c
index d5c3cbc..d867970 100644
--- a/src/lsmmathmlview.c
+++ b/src/lsmmathmlview.c
@@ -33,6 +33,13 @@
 #include <math.h>
 #include <string.h>
 
+typedef enum {
+       _GMATHML_STROKE_WIDTH_EVEN,
+       _GMATHML_STROKE_WIDTH_ODD,
+       _GMATHML_STROKE_WIDTH_NULL,
+       _GMATHML_STROKE_WIDTH_VECTOR
+} _LsmMathmlStrokeWidth;
+
 #define LSM_MATHML_LARGE_OP_SCALE      1.6
 
 static const char *lsm_mathml_font_names[] = {
@@ -631,7 +638,7 @@ lsm_mathml_view_measure_radical (LsmMathmlView *view,
        radical_stretch_bbox.depth += LSM_MATHML_SPACE_EM_THICK * style->math_size;
 
        lsm_mathml_view_measure_operator (view, style, LSM_MATHML_RADICAL_UTF8,
-                                      FALSE, FALSE, 0.0, &radical_stretch_bbox, bbox);
+                                         FALSE, FALSE, 0.0, &radical_stretch_bbox, bbox);
 
        if (x_offset != NULL) {
                *x_offset = bbox->width * LSM_MATHML_RADICAL_ORDER_X_OFFSET;
@@ -715,13 +722,6 @@ lsm_mathml_view_show_radical (LsmMathmlView *view,
        cairo_restore (cairo);
 }
 
-typedef enum {
-       _GMATHML_STROKE_WIDTH_EVEN,
-       _GMATHML_STROKE_WIDTH_ODD,
-       _GMATHML_STROKE_WIDTH_NULL,
-       _GMATHML_STROKE_WIDTH_VECTOR
-} _LsmMathmlStrokeWidth;
-
 static void
 _round_rectangle_coordinates (cairo_t *cairo,
                              _LsmMathmlStrokeWidth stroke_width,
@@ -809,6 +809,181 @@ _emit_stroke_attributes (LsmMathmlView *view, LsmMathmlLine line, double line_wi
        return stroke_width;
 }
 
+const LsmMathmlPadding notation_padding[] = {
+       {       .left = 1.0,    .right = 0.0,   .top = 1.0,     .bottom = 0.0 },        /* longdiv */
+       {       .left = 1.0,    .right = 1.0,   .top = 1.0,     .bottom = 1.0 },        /* actuarial */
+       {       .left = 0.0,    .right = 0.0,   .top = 0.0,     .bottom = 0.0 },        /* radical */
+       {       .left = 1.0,    .right = 1.0,   .top = 1.0,     .bottom = 1.0 },        /* box */
+       {       .left = 1.0,    .right = 1.0,   .top = 1.0,     .bottom = 1.0 },        /* boundedbox */
+       {       .left = 1.0,    .right = 1.0,   .top = 1.0,     .bottom = 1.0 },        /* circle */
+       {       .left = 1.0,    .right = 0.0,   .top = 1.0,     .bottom = 1.0 },        /* left */
+       {       .left = 0.0,    .right = 1.0,   .top = 1.0,     .bottom = 1.0 },        /* right */
+       {       .left = 1.0,    .right = 1.0,   .top = 1.0,     .bottom = 0.0 },        /* top */
+       {       .left = 1.0,    .right = 1.0,   .top = 0.0,     .bottom = 1.0 },        /* bottom */
+       {       .left = 0.0,    .right = 0.0,   .top = 1.0,     .bottom = 1.0 },        /* updiagonalstrike */
+       {       .left = 0.0,    .right = 0.0,   .top = 1.0,     .bottom = 1.0 },        /* downdiagonalstrike 
*/
+       {       .left = 0.0,    .right = 0.0,   .top = 1.0,     .bottom = 1.0 },        /* verticalstrike */
+       {       .left = 1.0,    .right = 1.0,   .top = 0.0,     .bottom = 0.0 },        /* horizontalstrike */
+       {       .left = 1.0,    .right = 1.0,   .top = 1.0,     .bottom = 1.0 },        /* madruwb */
+       {       .left = 0.0,    .right = 2.0,   .top = 1.0,     .bottom = 1.0 }         /* updiagonalarrow */
+};
+
+void
+lsm_mathml_view_measure_notation (LsmMathmlView *view,
+                                 const LsmMathmlElementStyle *style,
+                                 LsmMathmlNotation notation,
+                                 const LsmMathmlBbox *stretch_bbox,
+                                 LsmMathmlBbox *bbox,
+                                 double *x_child_offset)
+{
+       LsmMathmlLength padding_x = {.value = 0.5, .unit = LSM_MATHML_UNIT_EX};
+       LsmMathmlLength padding_y = {.value = 0.4, .unit = LSM_MATHML_UNIT_EM};
+       double base_x;
+       double base_y;
+
+       g_return_if_fail (LSM_IS_MATHML_VIEW (view));
+       g_return_if_fail (style != NULL);
+       g_return_if_fail (stretch_bbox != NULL);
+       g_return_if_fail (bbox != NULL);
+
+       if (notation == LSM_MATHML_NOTATION_RADICAL) {
+               lsm_mathml_view_measure_radical (view, style, stretch_bbox, bbox, NULL, NULL);
+               if (x_child_offset != NULL)
+                       *x_child_offset = bbox->width;
+               return;
+       }
+
+       base_x = lsm_mathml_length_normalize (&padding_x, 0.0, style->math_size);
+       base_y = lsm_mathml_length_normalize (&padding_y, 0.0, style->math_size);
+
+       *bbox = *stretch_bbox;
+
+       if (notation >= 0 && notation < LSM_MATHML_NOTATION_LAST) {
+               bbox->width += base_x * (notation_padding[notation].left + notation_padding[notation].right);
+               bbox->height += base_y * (notation_padding[notation].top + notation_padding[notation].bottom);
+               bbox->depth += base_y * (notation_padding[notation].bottom);
+
+               if (x_child_offset != NULL)
+                       *x_child_offset = base_x * notation_padding[notation].left;
+       } else {
+               if (x_child_offset != NULL)
+                       *x_child_offset = 0;
+       }
+
+}
+
+void
+lsm_mathml_view_show_notation (LsmMathmlView *view,
+                              const LsmMathmlElementStyle *style,
+                              LsmMathmlNotation notation,
+                              double x, double y,
+                              const LsmMathmlBbox *bbox)
+{
+       _LsmMathmlStrokeWidth stroke_width;
+       cairo_t *cairo;
+       double x1, y1;
+
+       g_return_if_fail (LSM_IS_MATHML_VIEW (view));
+       g_return_if_fail (style != NULL);
+       g_return_if_fail (bbox != NULL);
+
+       stroke_width = _emit_stroke_attributes (view, LSM_MATHML_LINE_SOLID, 1.0, &style->math_color);
+
+       if (stroke_width == _GMATHML_STROKE_WIDTH_NULL)
+               return;
+
+       y = y + bbox->depth;
+       x1 = x + bbox->width;
+       y1 = y - bbox->height;
+
+       cairo = view->dom_view.cairo;
+
+       _round_rectangle_coordinates (cairo, stroke_width, &x, &y, &x1, &y1);
+
+       cairo_new_path (cairo);
+
+       switch (notation) {
+               case LSM_MATHML_NOTATION_ACTUARIAL:
+                       cairo_move_to (cairo, x, y1);
+                       cairo_line_to (cairo, x1, y1);
+                       cairo_line_to (cairo, x1, y);
+                       break;
+               case LSM_MATHML_NOTATION_RADICAL:
+                       break;
+               case LSM_MATHML_NOTATION_BOX:
+                       cairo_move_to (cairo, x, y);
+                       cairo_line_to (cairo, x, y1);
+                       cairo_line_to (cairo, x1, y1);
+                       cairo_line_to (cairo, x1, y);
+                       cairo_close_path (cairo);
+                       break;
+               case LSM_MATHML_NOTATION_ROUNDED_BOX:
+                       cairo_move_to (cairo, x, y);
+                       cairo_line_to (cairo, x, y1);
+                       cairo_line_to (cairo, x1, y1);
+                       cairo_line_to (cairo, x1, y);
+                       cairo_close_path (cairo);
+                       break;
+               case LSM_MATHML_NOTATION_CIRCLE:
+                       cairo_save (cairo);
+                       cairo_translate (cairo, (x + x1) / 2.0, (y + y1) / 2.0);
+                       cairo_scale (cairo, (x - x1) / 2.0, (y - y1) / 2.0);
+                       cairo_arc (cairo, 0., 0., 1., 0., 2 * M_PI);
+                       cairo_restore (cairo);
+                       break;
+               case LSM_MATHML_NOTATION_LEFT:
+                       cairo_move_to (cairo, x, y);
+                       cairo_line_to (cairo, x, y1);
+                       break;
+               case LSM_MATHML_NOTATION_RIGHT:
+                       cairo_move_to (cairo, x1, y);
+                       cairo_line_to (cairo, x1, y1);
+                       break;
+               case LSM_MATHML_NOTATION_TOP:
+                       cairo_move_to (cairo, x, y1);
+                       cairo_line_to (cairo, x1, y1);
+                       break;
+               case LSM_MATHML_NOTATION_BOTTOM:
+                       cairo_move_to (cairo, x, y);
+                       cairo_line_to (cairo, x1, y);
+                       break;
+               case LSM_MATHML_NOTATION_UP_DIAGONAL_STRIKE:
+                       cairo_move_to (cairo, x, y);
+                       cairo_line_to (cairo, x1, y1);
+                       break;
+               case LSM_MATHML_NOTATION_DOWN_DIAGONAL_STRIKE:
+                       cairo_move_to (cairo, x, y1);
+                       cairo_line_to (cairo, x1, y);
+                       break;
+               case LSM_MATHML_NOTATION_HORIZONTAL_STRIKE:
+                       cairo_move_to (cairo, x, (y + y1) / 2.0);
+                       cairo_line_to (cairo, x1,(y + y1) / 2.0);
+                       break;
+               case LSM_MATHML_NOTATION_VERTICAL_STRIKE:
+                       cairo_move_to (cairo, (x + x1) / 2.0, y);
+                       cairo_line_to (cairo, (x + x1) / 2.0, y1);
+                       break;
+               case LSM_MATHML_NOTATION_MADRUWB:
+                       cairo_move_to (cairo, x, y);
+                       cairo_line_to (cairo, x1, y);
+                       cairo_line_to (cairo, x1, y1);
+                       break;
+               case LSM_MATHML_NOTATION_UP_DIAGONAL_ARROW:
+                       cairo_move_to (cairo, x, y);
+                       cairo_line_to (cairo, x1, y1);
+                       break;
+               case LSM_MATHML_NOTATION_ERROR:
+               case LSM_MATHML_NOTATION_LONGDIV:
+               default:
+                       cairo_move_to (cairo, x, y);
+                       cairo_line_to (cairo, x, y1);
+                       cairo_line_to (cairo, x1, y1);
+                       break;
+       }
+
+       cairo_stroke (cairo);
+}
+
 void
 lsm_mathml_view_show_background (LsmMathmlView *view,
                              const LsmMathmlElementStyle *style,
diff --git a/src/lsmmathmlview.h b/src/lsmmathmlview.h
index 594d7c7..2c91ef6 100644
--- a/src/lsmmathmlview.h
+++ b/src/lsmmathmlview.h
@@ -132,6 +132,18 @@ void               lsm_mathml_view_show_radical            (LsmMathmlView *view,
                                                         double x, double y, double width,
                                                         const LsmMathmlBbox *stretch_bbox);
 
+void           lsm_mathml_view_measure_notation        (LsmMathmlView *view,
+                                                        const LsmMathmlElementStyle *style,
+                                                        LsmMathmlNotation notation,
+                                                        const LsmMathmlBbox *stretch_bbox,
+                                                        LsmMathmlBbox *bbox,
+                                                        double *x_child_offset);
+void           lsm_mathml_view_show_notation           (LsmMathmlView *view,
+                                                        const LsmMathmlElementStyle *style,
+                                                        LsmMathmlNotation notation,
+                                                        double x, double y,
+                                                        const LsmMathmlBbox *bbox);
+
 void           lsm_mathml_view_show_background         (LsmMathmlView *view,
                                                         const LsmMathmlElementStyle *style,
                                                         double x, double y,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]