changeset 12969:6fc2c61660f2

Native multi-line text alignment. * txt-eng-ft.cc: Support horizontal and vertical alignment of multiline text. * txt-eng-ft.h: Ditto.
author Vanya Sergeev <vsergeev@gmail.com>
date Mon, 15 Aug 2011 17:35:30 -0400
parents 58e46be87180
children 7b4ec6f841a2
files src/txt-eng-ft.cc src/txt-eng-ft.h
diffstat 2 files changed, 35 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/txt-eng-ft.cc	Mon Aug 15 20:55:58 2011 +0200
+++ b/src/txt-eng-ft.cc	Mon Aug 15 17:35:30 2011 -0400
@@ -202,7 +202,8 @@
 
 ft_render::ft_render (void)
     : text_processor (), face (0), bbox (1, 4, 0.0),
-      xoffset (0), yoffset (0), mode (MODE_BBOX),
+      xoffset (0), yoffset (0), multiline_halign (0), 
+      multiline_align_xoffsets(), mode (MODE_BBOX),
       red (0), green (0), blue (0)
 {
 }
@@ -270,10 +271,16 @@
 {
   if (face)
     {
+      int line_index = 0;
       FT_UInt box_line_width = 0;
       std::string str = e.string_value ();
       FT_UInt glyph_index, previous = 0;
 
+      if (mode == MODE_BBOX)
+        multiline_align_xoffsets.clear();
+      else if (mode == MODE_RENDER)
+        xoffset += multiline_align_xoffsets[line_index];
+
       for (size_t i = 0; i < str.length (); i++)
         {
           glyph_index = FT_Get_Char_Index (face, str[i]);
@@ -297,7 +304,8 @@
                       } 
                     else 
                       {
-                        xoffset = 0;
+                        line_index++;
+                        xoffset = multiline_align_xoffsets[line_index];
                         yoffset -= (face->size->metrics.height >> 6);
                       }
                   } 
@@ -360,6 +368,7 @@
                       }
                     else
                       {
+                        multiline_align_xoffsets.push_back(box_line_width);
                         // Reset the pixel width for this newline, so we don't
                         // allocate a bounding box larger than the horizontal
                         // width of the multi-line
@@ -416,6 +425,24 @@
                   previous = glyph_index;
             }
         }
+      if (mode == MODE_BBOX)
+        {
+          /* Push last the width associated with the last line */ 
+          multiline_align_xoffsets.push_back(box_line_width);
+
+          for (unsigned int i = 0; i < multiline_align_xoffsets.size(); i++)
+            {
+            /* Center align */
+            if (multiline_halign == 1) 
+              multiline_align_xoffsets[i] = (bbox(2) - multiline_align_xoffsets[i])/2;
+            /* Right align */
+            else if (multiline_halign == 2)
+              multiline_align_xoffsets[i] = (bbox(2) - multiline_align_xoffsets[i]);
+            /* Left align */
+            else 
+              multiline_align_xoffsets[i] = 0;
+            }
+        }
     }
 }
 
@@ -556,6 +583,8 @@
 {
   // FIXME: clip "rotation" between 0 and 360
   int rot_mode = rotation_to_mode (rotation);
+  
+  multiline_halign = halign;
 
   text_element *elt = text_parser_none ().parse (txt);
   pixels_ = render (elt, box, rot_mode);
--- a/src/txt-eng-ft.h	Mon Aug 15 20:55:58 2011 +0200
+++ b/src/txt-eng-ft.h	Mon Aug 15 17:35:30 2011 -0400
@@ -25,6 +25,8 @@
 
 #if HAVE_FREETYPE
 
+#include <vector>
+
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
@@ -94,6 +96,8 @@
   uint8NDArray pixels;
   int xoffset;
   int yoffset;
+  int multiline_halign;
+  std::vector<int> multiline_align_xoffsets;
   int mode;
   uint8_t red, green, blue;
 };