[pango/pango2] PangoTabArray: API tweaks



commit 9358657155f78e22db99f6dded4aacee45663479
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jul 8 16:09:27 2022 -0400

    PangoTabArray: API tweaks
    
    Allow specifying tab positions in spaces.

 pango2/pango-line-breaker.c | 32 ++++++++++------
 pango2/pango-tabs.c         | 92 ++++++++++++++++++++++++++++-----------------
 pango2/pango-tabs.h         | 26 ++++++++++---
 pango2/serializer.c         | 18 ++++++---
 tests/testtabs.c            |  8 ++--
 5 files changed, 114 insertions(+), 62 deletions(-)
---
diff --git a/pango2/pango-line-breaker.c b/pango2/pango-line-breaker.c
index cd17968e9..2bfe2c74e 100644
--- a/pango2/pango-line-breaker.c
+++ b/pango2/pango-line-breaker.c
@@ -678,31 +678,42 @@ get_tab_pos (Pango2LineBreaker *self,
              gboolean          *is_default)
 {
   int n_tabs;
-  gboolean in_pixels;
+  Pango2TabPositions positions;
   int offset = 0;
+  int tab_unit;
 
   offset = self->line_x;
 
   if (self->tabs)
     {
       n_tabs = pango2_tab_array_get_size (self->tabs);
-      in_pixels = pango2_tab_array_get_positions_in_pixels (self->tabs);
+      switch (pango2_tab_array_get_positions (self->tabs))
+        {
+        case PANGO2_TAB_POSITIONS_DEFAULT:
+          tab_unit = PANGO2_SCALE;
+          break;
+        case PANGO2_TAB_POSITIONS_PIXELS:
+          tab_unit = 1;
+          break;
+        case PANGO2_TAB_POSITIONS_SPACES:
+          tab_unit = self->tab_width / 8;
+          break;
+        default:
+          g_assert_not_reached ();
+        }
       *is_default = FALSE;
     }
   else
     {
       n_tabs = 0;
-      in_pixels = FALSE;
+       tab_unit = PANGO2_SCALE;
       *is_default = TRUE;
     }
 
   if (index < n_tabs)
     {
       pango2_tab_array_get_tab (self->tabs, index, alignment, tab_pos);
-
-      if (in_pixels)
-        *tab_pos *= PANGO2_SCALE;
-
+      *tab_pos *= tab_unit;
       *decimal = pango2_tab_array_get_decimal_point (self->tabs, index);
     }
   else if (n_tabs > 0)
@@ -720,11 +731,8 @@ get_tab_pos (Pango2LineBreaker *self,
       else
         next_to_last_pos = 0;
 
-      if (in_pixels)
-        {
-          next_to_last_pos *= PANGO2_SCALE;
-          last_pos *= PANGO2_SCALE;
-        }
+      next_to_last_pos *= tab_unit;
+      last_pos *= tab_unit;
 
       if (last_pos > next_to_last_pos)
         tab_width = last_pos - next_to_last_pos;
diff --git a/pango2/pango-tabs.c b/pango2/pango-tabs.c
index 3801f62c4..b01749168 100644
--- a/pango2/pango-tabs.c
+++ b/pango2/pango-tabs.c
@@ -47,7 +47,7 @@ struct _Pango2TabArray
 {
   int size;
   int allocated;
-  gboolean positions_in_pixels;
+  Pango2TabPositions positions;
   Pango2Tab *tabs;
 };
 
@@ -66,19 +66,19 @@ init_tabs (Pango2TabArray *array, int start, int end)
 /**
  * pango2_tab_array_new:
  * @initial_size: Initial number of tab stops to allocate, can be 0
- * @positions_in_pixels: whether positions are in pixel units
+ * @positions: the unit positions are specified in
  *
  * Creates an array of @initial_size tab stops.
  *
- * Tab stops are specified in pixel units if @positions_in_pixels is %TRUE,
- * otherwise in Pango units. All stops are initially at position 0.
+ * Tab stops are specified in units according to @position.
+ * All stops are initially at position 0.
  *
  * Return value: the newly allocated `Pango2TabArray`, which should
  *   be freed with [method Pango2 TabArray free].
  */
 Pango2TabArray*
-pango2_tab_array_new (int     initial_size,
-                      gboolean positions_in_pixels)
+pango2_tab_array_new (int                 initial_size,
+                      Pango2TabPositions  positions)
 {
   Pango2TabArray *array;
 
@@ -100,7 +100,7 @@ pango2_tab_array_new (int     initial_size,
   else
     array->tabs = NULL;
 
-  array->positions_in_pixels = positions_in_pixels;
+  array->positions = positions;
 
   return array;
 }
@@ -108,7 +108,7 @@ pango2_tab_array_new (int     initial_size,
 /**
  * pango2_tab_array_new_with_positions:
  * @size: number of tab stops in the array
- * @positions_in_pixels: whether positions are in pixel units
+ * @positions: unit for positions
  * @first_alignment: alignment of first tab stop
  * @first_position: position of first tab stop
  * @...: additional alignment/position pairs
@@ -122,10 +122,10 @@ pango2_tab_array_new (int     initial_size,
  *   be freed with [method Pango2 TabArray free].
  */
 Pango2TabArray  *
-pango2_tab_array_new_with_positions (int             size,
-                                     gboolean        positions_in_pixels,
-                                     Pango2TabAlign  first_alignment,
-                                     int             first_position,
+pango2_tab_array_new_with_positions (int                size,
+                                     Pango2TabPositions positions,
+                                     Pango2TabAlign     first_alignment,
+                                     int                first_position,
                                      ...)
 {
   Pango2TabArray *array;
@@ -134,7 +134,7 @@ pango2_tab_array_new_with_positions (int             size,
 
   g_return_val_if_fail (size >= 0, NULL);
 
-  array = pango2_tab_array_new (size, positions_in_pixels);
+  array = pango2_tab_array_new (size, positions);
 
   if (size == 0)
     return array;
@@ -186,7 +186,7 @@ pango2_tab_array_copy (Pango2TabArray *src)
 
   g_return_val_if_fail (src != NULL, NULL);
 
-  copy = pango2_tab_array_new (src->size, src->positions_in_pixels);
+  copy = pango2_tab_array_new (src->size, src->positions);
 
   if (copy->tabs)
     memcpy (copy->tabs, src->tabs, sizeof(Pango2Tab) * src->size);
@@ -354,37 +354,35 @@ pango2_tab_array_get_tabs (Pango2TabArray  *tab_array,
 }
 
 /**
- * pango2_tab_array_get_positions_in_pixels:
+ * pango2_tab_array_get_positions:
  * @tab_array: a `Pango2TabArray`
  *
- * Returns %TRUE if the tab positions are in pixels,
- * %FALSE if they are in Pango units.
+ * Returns the unit used for tab positions.
  *
- * Return value: whether positions are in pixels.
+ * Return value: the unit for tab positions
  */
-gboolean
-pango2_tab_array_get_positions_in_pixels (Pango2TabArray *tab_array)
+Pango2TabPositions
+pango2_tab_array_get_positions (Pango2TabArray *tab_array)
 {
   g_return_val_if_fail (tab_array != NULL, FALSE);
 
-  return tab_array->positions_in_pixels;
+  return tab_array->positions;
 }
 
 /**
- * pango2_tab_array_set_positions_in_pixels:
+ * pango2_tab_array_set_positions:
  * @tab_array: a `Pango2TabArray`
- * @positions_in_pixels: whether positions are in pixels
+ * @positions: unit for tab postions
  *
- * Sets whether positions in this array are specified in
- * pixels.
+ * Sets the unit to use for positions in this array.
  */
 void
-pango2_tab_array_set_positions_in_pixels (Pango2TabArray *tab_array,
-                                          gboolean        positions_in_pixels)
+pango2_tab_array_set_positions (Pango2TabArray     *tab_array,
+                                Pango2TabPositions  positions)
 {
   g_return_if_fail (tab_array != NULL);
 
-  tab_array->positions_in_pixels = positions_in_pixels;
+  tab_array->positions = positions;
 }
 
 /**
@@ -422,8 +420,20 @@ pango2_tab_array_to_string (Pango2TabArray *tab_array)
         g_string_append (s, "decimal:");
 
       g_string_append_printf (s, "%d", tab_array->tabs[i].location);
-      if (tab_array->positions_in_pixels)
-        g_string_append (s, "px");
+      switch (tab_array->positions)
+        {
+        case PANGO2_TAB_POSITIONS_DEFAULT:
+          break;
+        case PANGO2_TAB_POSITIONS_PIXELS:
+          g_string_append (s, "px");
+          break;
+        case PANGO2_TAB_POSITIONS_SPACES:
+          g_string_append (s, "sp");
+          break;
+        default:
+          g_assert_not_reached ();
+          break;
+        }
 
       if (tab_array->tabs[i].decimal_point != 0)
         g_string_append_printf (s, ":%d", tab_array->tabs[i].decimal_point);
@@ -458,10 +468,16 @@ pango2_tab_array_from_string (const char *text)
   gboolean pixels;
   const char *p;
   int i;
+  Pango2TabPositions positions;
 
-  pixels = strstr (text, "px") != NULL;
+  if (strstr (text, "px"))
+    positions = PANGO2_TAB_POSITIONS_PIXELS;
+  else if (strstr (text, "sp"))
+    positions = PANGO2_TAB_POSITIONS_SPACES;
+  else
+    positions = PANGO2_TAB_POSITIONS_DEFAULT;
 
-  array = pango2_tab_array_new (0, pixels);
+  array = pango2_tab_array_new (0, positions);
 
   p = skip_whitespace (text);
 
@@ -499,17 +515,23 @@ pango2_tab_array_from_string (const char *text)
 
       pos = g_ascii_strtoll (p, &endp, 10);
       if (pos < 0 ||
-          (pixels && *endp != 'p') ||
-          (!pixels && !g_ascii_isspace (*endp) && *endp != ':' && *endp != '\0')) goto fail;
+          (positions == PANGO2_TAB_POSITIONS_PIXELS && *endp != 'p') ||
+          (positions == PANGO2_TAB_POSITIONS_SPACES && *endp != 's') ||
+          ((positions == PANGO2_TAB_POSITIONS_DEFAULT) && !g_ascii_isspace (*endp) && *endp != ':' && *endp 
!= '\0')) goto fail;
 
       pango2_tab_array_set_tab (array, i, align, pos);
 
       p = (const char *)endp;
-      if (pixels)
+      if (positions == PANGO2_TAB_POSITIONS_PIXELS)
         {
           if (p[0] != 'p' || p[1] != 'x') goto fail;
           p += 2;
         }
+      else if (positions == PANGO2_TAB_POSITIONS_SPACES)
+        {
+          if (p[0] != 's' || p[1] != 'p') goto fail;
+          p += 2;
+        }
 
       if (p[0] == ':')
         {
diff --git a/pango2/pango-tabs.h b/pango2/pango-tabs.h
index b53037896..c84fc6df2 100644
--- a/pango2/pango-tabs.h
+++ b/pango2/pango-tabs.h
@@ -47,17 +47,31 @@ typedef enum
   PANGO2_TAB_DECIMAL
 } Pango2TabAlign;
 
+/**
+ * Pango2TabPositions:
+ * @PANGO2_TAB_POSITIONS_DEFAULT: Positions are in Pango units
+ * @PANGO2_TAB_POSITIONS_PIXELS: Positions are in pixls
+ * @PANGO2_TAB_POSITIONS_SPACES: Positions are in spaces
+ *
+ * `Pango2TabPositions` specifies the unit for tab positions.
+ */
+typedef enum {
+  PANGO2_TAB_POSITIONS_DEFAULT,
+  PANGO2_TAB_POSITIONS_PIXELS,
+  PANGO2_TAB_POSITIONS_SPACES,
+} Pango2TabPositions;
+
 #define PANGO2_TYPE_TAB_ARRAY (pango2_tab_array_get_type ())
 
 PANGO2_AVAILABLE_IN_ALL
 GType                   pango2_tab_array_get_type                (void) G_GNUC_CONST;
 
 PANGO2_AVAILABLE_IN_ALL
-Pango2TabArray *        pango2_tab_array_new                     (int              initial_size,
-                                                                  gboolean         positions_in_pixels);
+Pango2TabArray *        pango2_tab_array_new                     (int                 initial_size,
+                                                                  Pango2TabPositions  positions);
 PANGO2_AVAILABLE_IN_ALL
 Pango2TabArray *        pango2_tab_array_new_with_positions      (int              size,
-                                                                  gboolean         positions_in_pixels,
+                                                                  Pango2TabPositions positions,
                                                                   Pango2TabAlign   first_alignment,
                                                                   int              first_position,
                                                                   ...);
@@ -86,11 +100,11 @@ void                    pango2_tab_array_get_tabs                (Pango2TabArray
                                                                   int            **locations);
 
 PANGO2_AVAILABLE_IN_ALL
-gboolean                pango2_tab_array_get_positions_in_pixels (Pango2TabArray  *tab_array);
+Pango2TabPositions      pango2_tab_array_get_positions           (Pango2TabArray  *tab_array);
 
 PANGO2_AVAILABLE_IN_ALL
-void                    pango2_tab_array_set_positions_in_pixels (Pango2TabArray  *tab_array,
-                                                                  gboolean         positions_in_pixels);
+void                    pango2_tab_array_set_positions           (Pango2TabArray  *tab_array,
+                                                                  Pango2TabPositions positions);
 
 PANGO2_AVAILABLE_IN_ALL
 char *                  pango2_tab_array_to_string               (Pango2TabArray  *tab_array);
diff --git a/pango2/serializer.c b/pango2/serializer.c
index 03ffb4cd8..8f18f11bd 100644
--- a/pango2/serializer.c
+++ b/pango2/serializer.c
@@ -260,6 +260,13 @@ static const char *ellipsize_names[] = {
   NULL
 };
 
+static const char *tab_unit_names[] = {
+  "default",
+  "pixels",
+  "spaces",
+  NULL
+};
+
 /* }}} */
 /* {{{ Serialization */
 
@@ -434,7 +441,8 @@ add_tab_array (GtkJsonPrinter *printer,
 
   gtk_json_printer_start_object (printer, "tabs");
 
-  gtk_json_printer_add_boolean (printer, "positions-in-pixels", pango2_tab_array_get_positions_in_pixels 
(tabs));
+  gtk_json_printer_add_string (printer, "position-units", tab_unit_names[pango2_tab_array_get_positions 
(tabs)]);
+
   gtk_json_printer_start_array (printer, "positions");
   for (int i = 0; i < pango2_tab_array_get_size (tabs); i++)
     {
@@ -1274,12 +1282,12 @@ json_parser_fill_tabs (GtkJsonParser *parser,
 }
 
 enum {
-  TABS_POSITIONS_IN_PIXELS,
+  TABS_POSITION_UNITS,
   TABS_POSITIONS
 };
 
 static const char *tabs_members[] = {
-  "positions-in-pixels",
+  "position-units",
   "positions",
   NULL
 };
@@ -1294,8 +1302,8 @@ json_parser_fill_tab_array (GtkJsonParser *parser,
     {
       switch (gtk_json_parser_select_member (parser, tabs_members))
         {
-        case TABS_POSITIONS_IN_PIXELS:
-          pango2_tab_array_set_positions_in_pixels (tabs, gtk_json_parser_get_boolean (parser));
+        case TABS_POSITION_UNITS:
+          pango2_tab_array_set_positions (tabs, (Pango2TabPositions) parser_select_string (parser, 
tab_unit_names));
           break;
 
         case TABS_POSITIONS:
diff --git a/tests/testtabs.c b/tests/testtabs.c
index 7e33cb86b..b62075b74 100644
--- a/tests/testtabs.c
+++ b/tests/testtabs.c
@@ -29,9 +29,9 @@ test_tabs_basic (void)
   Pango2TabAlign align;
   int location;
 
-  tabs = pango2_tab_array_new (1, TRUE);
+  tabs = pango2_tab_array_new (1, PANGO2_TAB_POSITIONS_DEFAULT);
 
-  g_assert_true (pango2_tab_array_get_positions_in_pixels (tabs));
+  g_assert_true (pango2_tab_array_get_positions (tabs) == PANGO2_TAB_POSITIONS_DEFAULT);
   g_assert_true (pango2_tab_array_get_size (tabs) == 1);
 
   pango2_tab_array_set_tab (tabs, 0, PANGO2_TAB_LEFT, 10);
@@ -49,7 +49,7 @@ test_tabs_copy (void)
   Pango2TabAlign *alignments;
   int *locations;
 
-  tabs = pango2_tab_array_new_with_positions (2, TRUE,
+  tabs = pango2_tab_array_new_with_positions (2, PANGO2_TAB_POSITIONS_DEFAULT,
                                              PANGO2_TAB_LEFT, 10,
                                              PANGO2_TAB_LEFT, 20);
 
@@ -74,7 +74,7 @@ test_tabs_resize (void)
   Pango2TabAlign *alignments;
   int *locations;
 
-  tabs = pango2_tab_array_new (1, TRUE);
+  tabs = pango2_tab_array_new (1, PANGO2_TAB_POSITIONS_DEFAULT);
 
   pango2_tab_array_set_tab (tabs, 0, PANGO2_TAB_LEFT, 10);
 


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