? oldies
? pango-1.11.2.tar.gz
? tab.patch
? examples/TEST
? examples/TEST-ARABIC
? examples/TEST-IPA-I-GUESS
Index: docs/tmpl/tab-stops.sgml
===================================================================
RCS file: /cvs/gnome/pango/docs/tmpl/tab-stops.sgml,v
retrieving revision 1.14
diff -u -p -r1.14 tab-stops.sgml
--- docs/tmpl/tab-stops.sgml	29 Jan 2006 00:55:23 -0000	1.14
+++ docs/tmpl/tab-stops.sgml	29 Jan 2006 00:57:26 -0000
@@ -34,6 +34,8 @@ A #PangoTabAlign specifies where a tab s
 </para>
 
 @PANGO_TAB_LEFT: the tab stop appears to the left of the text.
+@PANGO_TAB_RIGHT: the tab stop appears to the right of the text.
+@PANGO_TAB_CENTER: the tab stop appears to the center of the text.
 
 <!-- ##### MACRO PANGO_TYPE_TAB_ALIGN ##### -->
 <para>
Index: examples/renderdemo.c
===================================================================
RCS file: /cvs/gnome/pango/examples/renderdemo.c,v
retrieving revision 1.25
diff -u -p -r1.25 renderdemo.c
--- examples/renderdemo.c	29 Jan 2006 00:55:24 -0000	1.25
+++ examples/renderdemo.c	29 Jan 2006 00:57:26 -0000
@@ -58,10 +58,14 @@ int opt_runs = 1;
 PangoEllipsizeMode opt_ellipsize = PANGO_ELLIPSIZE_NONE;
 HintMode opt_hinting = HINT_DEFAULT;
 const char *opt_pangorc = NULL;
+const char *opt_tab_spec;
 
 /* Text (or markup) to render */
 static char *text;
 
+
+static PangoTabArray * parse_tab_spec (const char *p);
+
 void
 fail (const char *format, ...)
 {
@@ -128,6 +132,15 @@ make_layout(PangoContext *context,
 
   pango_font_description_free (font_description);
 
+  if (opt_tab_spec != NULL)
+    {
+      PangoTabArray *tabs;
+
+      tabs = parse_tab_spec (opt_tab_spec);
+      pango_layout_set_tabs (layout, tabs);
+      pango_tab_array_free (tabs);
+    }
+
   return layout;
 }
 
@@ -369,11 +382,6 @@ parse_hinting (ArgContext *arg_context,
 	       const char *arg,
 	       gpointer    data)
 {
-  static GEnumClass *class = NULL;
-
-  if (!class)
-    class = g_type_class_ref (PANGO_TYPE_ELLIPSIZE_MODE);
-
   if (strcmp (arg, "none") == 0)
     opt_hinting = HINT_NONE;
   else if (strcmp (arg, "auto") == 0)
@@ -384,6 +392,68 @@ parse_hinting (ArgContext *arg_context,
     fail ("--hinting option must be one of none/auto/full");
 }
 
+static PangoTabArray *
+parse_tab_spec (const char *p)
+{
+  PangoTabArray *tabs;
+  int tab_index;
+
+  tab_index = 0;
+  tabs = pango_tab_array_new (0, FALSE);
+
+  while (*p)
+    {
+      double pos;
+      int pos_units;
+      PangoTabAlign tab_align;
+      char *endpos;
+
+      pos = g_ascii_strtod (p, &endpos);
+      if (p == (const char *)endpos)
+        goto failed;
+      p = endpos;
+
+      pos_units =  (pos * opt_dpi * PANGO_SCALE + 32) / 72;
+
+      switch (*p)
+	{
+	  case 'c':
+	    p++;
+	    tab_align = PANGO_TAB_CENTER;
+	    break;
+
+	  case 'r':
+	    p++;
+	    tab_align = PANGO_TAB_RIGHT;
+	    break;
+
+	  case 'l':
+	    p++;
+	    tab_align = PANGO_TAB_LEFT;
+	    break;
+
+	  default:
+	    break;
+	}
+
+      if (*p == ',')
+        p++;
+      else if (*p)
+        goto failed;
+
+      pango_tab_array_set_tab (tabs, tab_index, tab_align, pos_units);
+      tab_index++;
+   }
+
+  return tabs;
+
+failed:
+  fail ("invalid --tab-spec option.\n"
+	"A tab spec should consist of a comma-separated list of tab-stop\n"
+	"positions in points optionally followed by one of 'l', 'c', and 'r'.");
+  return NULL;
+}
+
 void
 parse_options (int argc, char *argv[])
 {
@@ -422,6 +492,8 @@ parse_options (int argc, char *argv[])
       ARG_INT,      &opt_width, NULL },
     { "indent",     "Width in points to indent paragraphs",
       ARG_INT,      &opt_indent, NULL },
+    { "tab-spec",   "Tab stops and alignment in points, like '100l,300r,500c,700'",
+      ARG_STRING,   &opt_tab_spec, NULL },
     { "runs",       "Render text this many times",
       ARG_INT,      &opt_runs, NULL },
     { "pangorc",    "pangorc file to use (default is ./pangorc if available)",
Index: examples/renderdemo.h
===================================================================
RCS file: /cvs/gnome/pango/examples/renderdemo.h,v
retrieving revision 1.10
diff -u -p -r1.10 renderdemo.h
--- examples/renderdemo.h	29 Jan 2006 00:55:24 -0000	1.10
+++ examples/renderdemo.h	29 Jan 2006 00:57:26 -0000
@@ -73,3 +73,4 @@ extern int opt_runs;
 extern PangoEllipsizeMode opt_ellipsize;
 extern HintMode opt_hinting;
 extern const char *opt_pangorc;
+extern const char *opt_tab_spec;
Index: pango/pango-layout.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-layout.c,v
retrieving revision 1.157
diff -u -p -r1.157 pango-layout.c
--- pango/pango-layout.c	29 Jan 2006 00:55:24 -0000	1.157
+++ pango/pango-layout.c	29 Jan 2006 00:57:27 -0000
@@ -109,6 +109,8 @@ struct _PangoLayoutLinePrivate
 {
   PangoLayoutLine line;
   guint ref_count;
+  PangoGlyphString *last_tab_glyph;
+  PangoTabAlign last_tab_alignment;
 };
 
 struct _PangoLayoutClass
@@ -2495,11 +2497,8 @@ ensure_tab_width (PangoLayout *layout)
     }
 }
 
-/* For now we only need the tab position, we assume
- * all tabs are left-aligned.
- */
 static int
-get_tab_pos (PangoLayout *layout, int index)
+get_tab_pos (PangoLayout *layout, int index, PangoTabAlign *alignment)
 {
   gint n_tabs;
   gboolean in_pixels;
@@ -2519,7 +2518,7 @@ get_tab_pos (PangoLayout *layout, int in
     {
       gint pos = 0;
 
-      pango_tab_array_get_tab (layout->tabs, index, NULL, &pos);
+      pango_tab_array_get_tab (layout->tabs, index, alignment, &pos);
 
       if (in_pixels)
         return pos * PANGO_SCALE;
@@ -2536,10 +2535,10 @@ get_tab_pos (PangoLayout *layout, int in
       int next_to_last_pos = 0;
       int tab_width;
       
-      pango_tab_array_get_tab (layout->tabs, n_tabs - 1, NULL, &last_pos);
+      pango_tab_array_get_tab (layout->tabs, n_tabs - 1, alignment, &last_pos);
 
       if (n_tabs > 1)
-        pango_tab_array_get_tab (layout->tabs, n_tabs - 2, NULL, &next_to_last_pos);
+        pango_tab_array_get_tab (layout->tabs, n_tabs - 2, alignment, &next_to_last_pos);
       else
         next_to_last_pos = 0;
 
@@ -2597,6 +2596,8 @@ shape_tab (PangoLayoutLine  *line,
 {
   int i;
 
+  PangoTabAlign tab_alignment;
+
   int current_width = line_width (line);
 
   pango_glyph_string_set_size (glyphs, 1);
@@ -2610,13 +2611,23 @@ shape_tab (PangoLayoutLine  *line,
 
   for (i=0;;i++)
     {
-      int tab_pos = get_tab_pos (line->layout, i);
+      int tab_pos = get_tab_pos (line->layout, i, &tab_alignment);
       if (tab_pos > current_width)
 	{
 	  glyphs->glyphs[0].geometry.width = tab_pos - current_width;
 	  break;
 	}
     }
+  PangoLayoutLinePrivate *private = (PangoLayoutLinePrivate *)line;
+
+  /* left-aligned tabs are the default, do not need to remember */
+  if (tab_alignment != PANGO_TAB_LEFT)
+    {
+      private->last_tab_glyph = glyphs;
+      private->last_tab_alignment =  tab_alignment;
+    }
+  else
+    private->last_tab_glyph = NULL;
 }
 
 static inline gboolean
@@ -2689,6 +2700,16 @@ struct _ParaBreakState
 				 * to the remaining portion of the first item */
 };
 
+static int
+glyphstring_width (PangoGlyphString* glyphs)
+{
+  int i;
+  int width = 0;
+  for (i=0; i < glyphs->num_glyphs; i++)
+    width += glyphs->glyphs[i].geometry.width;
+  return width;
+}
+
 static PangoGlyphString *
 shape_run (PangoLayoutLine *line,
 	   ParaBreakState  *state,
@@ -2701,6 +2722,10 @@ shape_run (PangoLayoutLine *line,
     shape_tab (line, glyphs);
   else
     {
+      PangoLayoutLinePrivate *private = (PangoLayoutLinePrivate *)line;
+      
+      g_return_val_if_fail (line != NULL, glyphs);
+      
       if (state->properties.shape_set)
 	imposed_shape (layout->text + item->offset, item->num_chars,
 		       state->properties.shape_ink_rect, state->properties.shape_logical_rect,
@@ -2708,6 +2733,34 @@ shape_run (PangoLayoutLine *line,
       else 
 	pango_shape (layout->text + item->offset, item->length, &item->analysis, glyphs);
 
+      if (private->last_tab_glyph != NULL)
+	{
+	  int w;
+	  
+	  g_assert (private->last_tab_glyph->num_glyphs == 1);
+
+	  w = private->last_tab_glyph->glyphs[0].geometry.width;
+
+	  switch (private->last_tab_alignment)
+	    {
+	      case PANGO_TAB_RIGHT:
+	        w -= glyphstring_width (glyphs);
+	        break;
+
+	      case PANGO_TAB_CENTER:
+	        w -= glyphstring_width (glyphs) / 2;
+	        break;
+
+	      case PANGO_TAB_LEFT:
+		break;
+	    }
+	  
+	  if (w < 0)
+	    w = 0;
+
+	  private->last_tab_glyph->glyphs[0].geometry.width = w;
+	}
+
       if (state->properties.letter_spacing)
 	{
 	  PangoGlyphItem glyph_item;
@@ -4034,6 +4087,8 @@ pango_layout_line_new (PangoLayout *layo
   private->line.layout = layout;
   private->line.runs = 0;
   private->line.length = 0;
+  private->last_tab_glyph = NULL;
+  private->last_tab_alignment = PANGO_TAB_LEFT;
 
   /* Note that we leave start_index, resolved_dir, and is_paragraph_start
    *  uninitialized */
Index: pango/pango-tabs.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-tabs.c,v
retrieving revision 1.13
diff -u -p -r1.13 pango-tabs.c
--- pango/pango-tabs.c	29 Jan 2006 00:55:24 -0000	1.13
+++ pango/pango-tabs.c	29 Jan 2006 00:57:27 -0000
@@ -257,13 +257,12 @@ pango_tab_array_resize (PangoTabArray *t
 /**
  * pango_tab_array_set_tab:
  * @tab_array: a #PangoTabArray
- * @tab_index: the index of a tab stop
+ * @tab_index: the index of a tab stop, starting from zero
  * @alignment: tab alignment
  * @location: tab location in Pango units
  *
- * Sets the alignment and location of a tab stop.
- * @alignment must always be #PANGO_TAB_LEFT in the current
- * implementation.
+ * Sets the alignment and location of a tab stop.  Resizes the
+ * tab array if needed.
  * 
  **/
 void
@@ -274,7 +273,6 @@ pango_tab_array_set_tab  (PangoTabArray 
 {
   g_return_if_fail (tab_array != NULL);
   g_return_if_fail (tab_index >= 0);
-  g_return_if_fail (alignment == PANGO_TAB_LEFT);
   g_return_if_fail (location >= 0);
 
   if (tab_index >= tab_array->size)
Index: pango/pango-tabs.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-tabs.h,v
retrieving revision 1.6
diff -u -p -r1.6 pango-tabs.h
--- pango/pango-tabs.h	29 Jan 2006 00:55:24 -0000	1.6
+++ pango/pango-tabs.h	29 Jan 2006 00:57:27 -0000
@@ -30,13 +30,13 @@ typedef struct _PangoTabArray PangoTabAr
 
 typedef enum
 {
-  PANGO_TAB_LEFT
+  PANGO_TAB_LEFT,
+  PANGO_TAB_RIGHT,
+  PANGO_TAB_CENTER
 
   /* These are not supported now, but may be in the
    * future.
    *
-   *  PANGO_TAB_RIGHT,
-   *  PANGO_TAB_CENTER,
    *  PANGO_TAB_NUMERIC
    */
 } PangoTabAlign;

