"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "pango-1.20.5/pango/pango-tabs.c" of archive pango-1.20.5.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /* Pango
    2  * pango-tabs.c: Tab-related stuff
    3  *
    4  * Copyright (C) 2000 Red Hat Software
    5  *
    6  * This library is free software; you can redistribute it and/or
    7  * modify it under the terms of the GNU Library General Public
    8  * License as published by the Free Software Foundation; either
    9  * version 2 of the License, or (at your option) any later version.
   10  *
   11  * This library is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
   14  * Library General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU Library General Public
   17  * License along with this library; if not, write to the
   18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   19  * Boston, MA 02111-1307, USA.
   20  */
   21 
   22 #include <config.h>
   23 #include "pango-tabs.h"
   24 #include "pango-impl-utils.h"
   25 #include <string.h>
   26 
   27 typedef struct _PangoTab PangoTab;
   28 
   29 struct _PangoTab
   30 {
   31   gint location;	        /* Offset in pixels of this tab stop
   32 				 * from the left margin of the text.
   33 				 */
   34   PangoTabAlign alignment;      /* Where the tab stop appears relative
   35 				 * to the text.
   36 				 */
   37 };
   38 
   39 struct _PangoTabArray
   40 {
   41   gint size;
   42   gint allocated;
   43   gboolean positions_in_pixels;
   44   PangoTab *tabs;
   45 };
   46 
   47 static void
   48 init_tabs (PangoTabArray *array, gint start, gint end)
   49 {
   50   while (start < end)
   51     {
   52       array->tabs[start].location = 0;
   53       array->tabs[start].alignment = PANGO_TAB_LEFT;
   54       ++start;
   55     }
   56 }
   57 
   58 /**
   59  * pango_tab_array_new:
   60  * @initial_size: Initial number of tab stops to allocate, can be 0
   61  * @positions_in_pixels: whether positions are in pixel units
   62  *
   63  * Creates an array of @initial_size tab stops. Tab stops are specified in
   64  * pixel units if @positions_in_pixels is %TRUE, otherwise in Pango
   65  * units. All stops are initially at position 0.
   66  *
   67  * Return value: the newly allocated #PangoTabArray, which should
   68  *               be freed with pango_tab_array_free().
   69  **/
   70 PangoTabArray*
   71 pango_tab_array_new (gint initial_size,
   72 		     gboolean positions_in_pixels)
   73 {
   74   PangoTabArray *array;
   75 
   76   g_return_val_if_fail (initial_size >= 0, NULL);
   77 
   78   /* alloc enough to treat array->tabs as an array of length
   79    * size, though it's declared as an array of length 1.
   80    * If we allowed tab array resizing we'd need to drop this
   81    * optimization.
   82    */
   83   array = g_slice_new (PangoTabArray);
   84   array->size = initial_size;
   85   array->allocated = initial_size;
   86 
   87   if (array->allocated > 0)
   88     {
   89       array->tabs = g_new (PangoTab, array->allocated);
   90       init_tabs (array, 0, array->allocated);
   91     }
   92   else
   93     array->tabs = NULL;
   94 
   95   array->positions_in_pixels = positions_in_pixels;
   96 
   97   return array;
   98 }
   99 
  100 /**
  101  * pango_tab_array_new_with_positions:
  102  * @size: number of tab stops in the array
  103  * @positions_in_pixels: whether positions are in pixel units
  104  * @first_alignment: alignment of first tab stop
  105  * @first_position: position of first tab stop
  106  * @varargs: additional alignment/position pairs
  107  *
  108  * This is a convenience function that creates a #PangoTabArray
  109  * and allows you to specify the alignment and position of each
  110  * tab stop. You <emphasis>must</emphasis> provide an alignment
  111  * and position for @size tab stops.
  112  *
  113  * Return value: the newly allocated #PangoTabArray, which should
  114  *               be freed with pango_tab_array_free().
  115  **/
  116 PangoTabArray  *
  117 pango_tab_array_new_with_positions (gint           size,
  118 				    gboolean       positions_in_pixels,
  119 				    PangoTabAlign  first_alignment,
  120 				    gint           first_position,
  121 				    ...)
  122 {
  123   PangoTabArray *array;
  124   va_list args;
  125   int i;
  126 
  127   g_return_val_if_fail (size >= 0, NULL);
  128 
  129   array = pango_tab_array_new (size, positions_in_pixels);
  130 
  131   if (size == 0)
  132     return array;
  133 
  134   array->tabs[0].alignment = first_alignment;
  135   array->tabs[0].location = first_position;
  136 
  137   if (size == 1)
  138     return array;
  139 
  140   va_start (args, first_position);
  141 
  142   i = 1;
  143   while (i < size)
  144     {
  145       PangoTabAlign align = va_arg (args, PangoTabAlign);
  146       int pos = va_arg (args, int);
  147 
  148       array->tabs[i].alignment = align;
  149       array->tabs[i].location = pos;
  150 
  151       ++i;
  152     }
  153 
  154   va_end (args);
  155 
  156   return array;
  157 }
  158 
  159 GType
  160 pango_tab_array_get_type (void)
  161 {
  162   static GType our_type = 0;
  163 
  164   if (G_UNLIKELY (our_type == 0))
  165     our_type = g_boxed_type_register_static (I_("PangoTabArray"),
  166 					     (GBoxedCopyFunc)pango_tab_array_copy,
  167 					     (GBoxedFreeFunc)pango_tab_array_free);
  168   return our_type;
  169 }
  170 
  171 /**
  172  * pango_tab_array_copy:
  173  * @src: #PangoTabArray to copy
  174  *
  175  * Copies a #PangoTabArray
  176  *
  177  * Return value: the newly allocated #PangoTabArray, which should
  178  *               be freed with pango_tab_array_free().
  179  **/
  180 PangoTabArray*
  181 pango_tab_array_copy (PangoTabArray *src)
  182 {
  183   PangoTabArray *copy;
  184 
  185   g_return_val_if_fail (src != NULL, NULL);
  186 
  187   copy = pango_tab_array_new (src->size, src->positions_in_pixels);
  188 
  189   memcpy (copy->tabs, src->tabs, sizeof(PangoTab)*src->size);
  190 
  191   return copy;
  192 }
  193 
  194 /**
  195  * pango_tab_array_free:
  196  * @tab_array: a #PangoTabArray
  197  *
  198  * Frees a tab array and associated resources.
  199  *
  200  **/
  201 void
  202 pango_tab_array_free   (PangoTabArray *tab_array)
  203 {
  204   g_return_if_fail (tab_array != NULL);
  205 
  206   g_free (tab_array->tabs);
  207 
  208   g_slice_free (PangoTabArray, tab_array);
  209 }
  210 
  211 /**
  212  * pango_tab_array_get_size:
  213  * @tab_array: a #PangoTabArray
  214  *
  215  * Gets the number of tab stops in @tab_array.
  216  *
  217  * Return value: the number of tab stops in the array.
  218  **/
  219 gint
  220 pango_tab_array_get_size (PangoTabArray *tab_array)
  221 {
  222   g_return_val_if_fail (tab_array != NULL, 0);
  223 
  224   return tab_array->size;
  225 }
  226 
  227 /**
  228  * pango_tab_array_resize:
  229  * @tab_array: a #PangoTabArray
  230  * @new_size: new size of the array
  231  *
  232  * Resizes a tab array. You must subsequently initialize any tabs that
  233  * were added as a result of growing the array.
  234  *
  235  **/
  236 void
  237 pango_tab_array_resize (PangoTabArray *tab_array,
  238 			gint           new_size)
  239 {
  240   if (new_size > tab_array->allocated)
  241     {
  242       gint current_end = tab_array->allocated;
  243 
  244       /* Ratchet allocated size up above the index. */
  245       if (tab_array->allocated == 0)
  246 	tab_array->allocated = 2;
  247 
  248       while (new_size > tab_array->allocated)
  249 	tab_array->allocated = tab_array->allocated * 2;
  250 
  251       tab_array->tabs = g_renew (PangoTab, tab_array->tabs,
  252 				 tab_array->allocated);
  253 
  254       init_tabs (tab_array, current_end, tab_array->allocated);
  255     }
  256 
  257   tab_array->size = new_size;
  258 }
  259 
  260 /**
  261  * pango_tab_array_set_tab:
  262  * @tab_array: a #PangoTabArray
  263  * @tab_index: the index of a tab stop
  264  * @alignment: tab alignment
  265  * @location: tab location in Pango units
  266  *
  267  * Sets the alignment and location of a tab stop.
  268  * @alignment must always be #PANGO_TAB_LEFT in the current
  269  * implementation.
  270  *
  271  **/
  272 void
  273 pango_tab_array_set_tab  (PangoTabArray *tab_array,
  274 			  gint           tab_index,
  275 			  PangoTabAlign  alignment,
  276 			  gint           location)
  277 {
  278   g_return_if_fail (tab_array != NULL);
  279   g_return_if_fail (tab_index >= 0);
  280   g_return_if_fail (alignment == PANGO_TAB_LEFT);
  281   g_return_if_fail (location >= 0);
  282 
  283   if (tab_index >= tab_array->size)
  284     pango_tab_array_resize (tab_array, tab_index + 1);
  285 
  286   tab_array->tabs[tab_index].alignment = alignment;
  287   tab_array->tabs[tab_index].location = location;
  288 }
  289 
  290 /**
  291  * pango_tab_array_get_tab:
  292  * @tab_array: a #PangoTabArray
  293  * @tab_index: tab stop index
  294  * @alignment: location to store alignment, or %NULL
  295  * @location: location to store tab position, or %NULL
  296  *
  297  * Gets the alignment and position of a tab stop.
  298  *
  299  **/
  300 void
  301 pango_tab_array_get_tab  (PangoTabArray *tab_array,
  302 			  gint           tab_index,
  303 			  PangoTabAlign *alignment,
  304 			  gint          *location)
  305 {
  306   g_return_if_fail (tab_array != NULL);
  307   g_return_if_fail (tab_index < tab_array->size);
  308   g_return_if_fail (tab_index >= 0);
  309 
  310   if (alignment)
  311     *alignment = tab_array->tabs[tab_index].alignment;
  312 
  313   if (location)
  314     *location = tab_array->tabs[tab_index].location;
  315 }
  316 
  317 /**
  318  * pango_tab_array_get_tabs:
  319  * @tab_array: a #PangoTabArray
  320  * @alignments: location to store an array of tab stop alignments, or %NULL
  321  * @locations: location to store an array of tab positions, or %NULL
  322  *
  323  * If non-%NULL, @alignments and @locations are filled with allocated
  324  * arrays of length pango_tab_array_get_size(). You must free the
  325  * returned array.
  326  *
  327  **/
  328 void
  329 pango_tab_array_get_tabs (PangoTabArray *tab_array,
  330 			  PangoTabAlign **alignments,
  331 			  gint          **locations)
  332 {
  333   gint i;
  334 
  335   g_return_if_fail (tab_array != NULL);
  336 
  337   if (alignments)
  338     *alignments = g_new (PangoTabAlign, tab_array->size);
  339 
  340   if (locations)
  341     *locations = g_new (gint, tab_array->size);
  342 
  343   i = 0;
  344   while (i < tab_array->size)
  345     {
  346       if (alignments)
  347 	(*alignments)[i] = tab_array->tabs[i].alignment;
  348       if (locations)
  349 	(*locations)[i] = tab_array->tabs[i].location;
  350 
  351       ++i;
  352     }
  353 }
  354 
  355 /**
  356  * pango_tab_array_get_positions_in_pixels:
  357  * @tab_array: a #PangoTabArray
  358  *
  359  * Returns %TRUE if the tab positions are in pixels, %FALSE if they are
  360  * in Pango units.
  361  *
  362  * Return value: whether positions are in pixels.
  363  **/
  364 gboolean
  365 pango_tab_array_get_positions_in_pixels (PangoTabArray *tab_array)
  366 {
  367   g_return_val_if_fail (tab_array != NULL, FALSE);
  368 
  369   return tab_array->positions_in_pixels;
  370 }