changeset 17274:0a09d4b40767

Combine successive TeX super- and subscript elements. * libinterp/corefcn/oct-tex-parser.yy (combined_script_element): New rule. Add %nonassoc statements to control precedence and resolve shoft/reduce conflicts. * libinterp/corefcn/txt-eng.h (class text_element_combined): New class. (text_processor::visit(text_element_combined)): New method. * libinterp/corefcn/txt-eng-ft.h (ft_render::visit(text_element_combined)): Likewise. * libinterp/corefcn/txt-eng-ft.cc (ft_render::push_new_line): Reset xoffset/yoffset in MODE_BBOX mode. (ft_render::process_character): Use xoffset as the current X advancement and update the line bbox accordingly. (ft_render::visit(text_element_combined)): New method.
author Michael Goffioul <michael.goffioul@gmail.com>
date Sun, 18 Aug 2013 21:39:27 -0400
parents 9d584be736fc
children 8201f78a0064
files libinterp/corefcn/oct-tex-parser.yy libinterp/corefcn/txt-eng-ft.cc libinterp/corefcn/txt-eng-ft.h libinterp/corefcn/txt-eng.h
diffstat 4 files changed, 58 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/oct-tex-parser.yy	Sun Aug 18 18:19:48 2013 -0400
+++ b/libinterp/corefcn/oct-tex-parser.yy	Sun Aug 18 21:39:27 2013 -0400
@@ -65,7 +65,7 @@
 
 %type<str> simple_string identifier
 %type<e_base> string_element symbol_element
-%type<e_base> superscript_element subscript_element
+%type<e_base> superscript_element subscript_element combined_script_element
 %type<e_base> font_modifier_element fontname_element fontsize_element color_element
 %type<e_list> string_element_list scoped_string_element_list
 
@@ -73,6 +73,9 @@
 %destructor { } <ch> <num>
 %destructor { delete $$; } <*>
 
+%nonassoc SCRIPT
+%nonassoc SUB SUPER
+
 %nonassoc STR
 %nonassoc CH
 
@@ -144,8 +147,9 @@
 				| fontsize_element
 				| fontname_element
 				| color_element
-				| superscript_element
-				| subscript_element
+				| superscript_element %prec SCRIPT
+				| subscript_element %prec SCRIPT
+				| combined_script_element
 				;
 
 superscript_element		: SUPER CH
@@ -160,6 +164,12 @@
 				  { $$ = new text_element_subscript ($2); }
 				;
 
+combined_script_element		: subscript_element superscript_element
+				  { $$ = new text_element_combined ($1, $2); }
+				| superscript_element subscript_element
+				  { $$ = new text_element_combined ($1, $2); }
+				;
+
 string_element_list		: string_element
 				  { $$ = new text_element_list ($1); }
 				| string_element_list string_element
--- a/libinterp/corefcn/txt-eng-ft.cc	Sun Aug 18 18:19:48 2013 -0400
+++ b/libinterp/corefcn/txt-eng-ft.cc	Sun Aug 18 21:39:27 2013 -0400
@@ -354,6 +354,8 @@
               bb(4) = h;
 
               line_bbox.push_back (bb);
+
+              xoffset = yoffset = 0;
             }
         }
       break;
@@ -609,12 +611,14 @@
                       FT_Get_Kerning (face, previous, glyph_index,
                                       FT_KERNING_DEFAULT, &delta);
 
-                      bb(2) += (delta.x >> 6);
+                      xoffset += (delta.x >> 6);
                     }
 
-                  // Extend current line bounding box by the width of the
-                  // current glyph.
-                  bb(2) += (face->glyph->advance.x >> 6);
+                  // Extend current X offset box by the width of the current
+                  // glyph. Then extend the line bounding box if necessary.
+
+                  xoffset += (face->glyph->advance.x >> 6);
+                  bb(2) = xmax (bb(2), xoffset);
                 }
               break;
             }
@@ -781,6 +785,22 @@
 }
 
 void
+ft_render::visit (text_element_combined& e)
+{
+  int saved_xoffset = xoffset;
+  int max_xoffset = xoffset;
+
+  for (text_element_combined::iterator it = e.begin (); it != e.end (); ++it)
+    {
+      xoffset = saved_xoffset;
+      (*it)->accept (*this);
+      max_xoffset = xmax (xoffset, max_xoffset);
+    }
+
+  xoffset = max_xoffset;
+}
+
+void
 ft_render::reset (void)
 {
   set_mode (MODE_BBOX);
--- a/libinterp/corefcn/txt-eng-ft.h	Sun Aug 18 18:19:48 2013 -0400
+++ b/libinterp/corefcn/txt-eng-ft.h	Sun Aug 18 21:39:27 2013 -0400
@@ -75,6 +75,8 @@
 
   void visit (text_element_symbol& e);
 
+  void visit (text_element_combined& e);
+
   void reset (void);
 
   uint8NDArray get_pixels (void) const { return pixels; }
--- a/libinterp/corefcn/txt-eng.h	Sun Aug 18 18:19:48 2013 -0400
+++ b/libinterp/corefcn/txt-eng.h	Sun Aug 18 21:39:27 2013 -0400
@@ -36,6 +36,7 @@
 class text_element_list;
 class text_element_subscript;
 class text_element_superscript;
+class text_element_combined;
 class text_element_fontname;
 class text_element_fontsize;
 class text_element_fontstyle;
@@ -181,6 +182,21 @@
 
 class
 OCTINTERP_API
+text_element_combined : public text_element_list
+{
+public:
+  text_element_combined (text_element* e)
+    : text_element_list (e) { }
+
+  text_element_combined (text_element* e1, text_element* e2)
+    : text_element_list(e1)
+    { push_back (e2); }
+
+  void accept (text_processor& p);
+};
+
+class
+OCTINTERP_API
 text_element_fontstyle : public text_element
 {
 public:
@@ -315,6 +331,8 @@
   virtual void visit (text_element_superscript& e)
     { e.get_element ()->accept (*this); }
 
+  virtual void visit (text_element_combined&) { }
+
   virtual void visit (text_element_fontstyle&) { }
 
   virtual void visit (text_element_fontname&) { }
@@ -341,6 +359,7 @@
 TEXT_ELEMENT_ACCEPT(text_element_list)
 TEXT_ELEMENT_ACCEPT(text_element_subscript)
 TEXT_ELEMENT_ACCEPT(text_element_superscript)
+TEXT_ELEMENT_ACCEPT(text_element_combined)
 TEXT_ELEMENT_ACCEPT(text_element_fontstyle)
 TEXT_ELEMENT_ACCEPT(text_element_fontname)
 TEXT_ELEMENT_ACCEPT(text_element_fontsize)