2 * pango-tabs.c: Tab-related stuff
4 * Copyright (C) 2000 Red Hat Software
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.
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.
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.
23 #include "pango-tabs.h"
24 #include "pango-impl-utils.h"
27 typedef struct _PangoTab PangoTab;
31 gint location; /* Offset in pixels of this tab stop
32 * from the left margin of the text.
34 PangoTabAlign alignment; /* Where the tab stop appears relative
43 gboolean positions_in_pixels;
48 init_tabs (PangoTabArray *array, gint start, gint end)
52 array->tabs[start].location = 0;
53 array->tabs[start].alignment = PANGO_TAB_LEFT;
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
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.
67 * Return value: the newly allocated #PangoTabArray, which should
68 * be freed with pango_tab_array_free().
71 pango_tab_array_new (gint initial_size,
72 gboolean positions_in_pixels)
76 g_return_val_if_fail (initial_size >= 0, NULL);
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
83 array = g_slice_new (PangoTabArray);
84 array->size = initial_size;
85 array->allocated = initial_size;
87 if (array->allocated > 0)
89 array->tabs = g_new (PangoTab, array->allocated);
90 init_tabs (array, 0, array->allocated);
95 array->positions_in_pixels = positions_in_pixels;
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
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.
113 * Return value: the newly allocated #PangoTabArray, which should
114 * be freed with pango_tab_array_free().
117 pango_tab_array_new_with_positions (gint size,
118 gboolean positions_in_pixels,
119 PangoTabAlign first_alignment,
123 PangoTabArray *array;
127 g_return_val_if_fail (size >= 0, NULL);
129 array = pango_tab_array_new (size, positions_in_pixels);
134 array->tabs[0].alignment = first_alignment;
135 array->tabs[0].location = first_position;
140 va_start (args, first_position);
145 PangoTabAlign align = va_arg (args, PangoTabAlign);
146 int pos = va_arg (args, int);
148 array->tabs[i].alignment = align;
149 array->tabs[i].location = pos;
160 pango_tab_array_get_type (void)
162 static GType our_type = 0;
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);
172 * pango_tab_array_copy:
173 * @src: #PangoTabArray to copy
175 * Copies a #PangoTabArray
177 * Return value: the newly allocated #PangoTabArray, which should
178 * be freed with pango_tab_array_free().
181 pango_tab_array_copy (PangoTabArray *src)
185 g_return_val_if_fail (src != NULL, NULL);
187 copy = pango_tab_array_new (src->size, src->positions_in_pixels);
189 memcpy (copy->tabs, src->tabs, sizeof(PangoTab)*src->size);
195 * pango_tab_array_free:
196 * @tab_array: a #PangoTabArray
198 * Frees a tab array and associated resources.
202 pango_tab_array_free (PangoTabArray *tab_array)
204 g_return_if_fail (tab_array != NULL);
206 g_free (tab_array->tabs);
208 g_slice_free (PangoTabArray, tab_array);
212 * pango_tab_array_get_size:
213 * @tab_array: a #PangoTabArray
215 * Gets the number of tab stops in @tab_array.
217 * Return value: the number of tab stops in the array.
220 pango_tab_array_get_size (PangoTabArray *tab_array)
222 g_return_val_if_fail (tab_array != NULL, 0);
224 return tab_array->size;
228 * pango_tab_array_resize:
229 * @tab_array: a #PangoTabArray
230 * @new_size: new size of the array
232 * Resizes a tab array. You must subsequently initialize any tabs that
233 * were added as a result of growing the array.
237 pango_tab_array_resize (PangoTabArray *tab_array,
240 if (new_size > tab_array->allocated)
242 gint current_end = tab_array->allocated;
244 /* Ratchet allocated size up above the index. */
245 if (tab_array->allocated == 0)
246 tab_array->allocated = 2;
248 while (new_size > tab_array->allocated)
249 tab_array->allocated = tab_array->allocated * 2;
251 tab_array->tabs = g_renew (PangoTab, tab_array->tabs,
252 tab_array->allocated);
254 init_tabs (tab_array, current_end, tab_array->allocated);
257 tab_array->size = new_size;
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
267 * Sets the alignment and location of a tab stop.
268 * @alignment must always be #PANGO_TAB_LEFT in the current
273 pango_tab_array_set_tab (PangoTabArray *tab_array,
275 PangoTabAlign alignment,
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);
283 if (tab_index >= tab_array->size)
284 pango_tab_array_resize (tab_array, tab_index + 1);
286 tab_array->tabs[tab_index].alignment = alignment;
287 tab_array->tabs[tab_index].location = location;
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
297 * Gets the alignment and position of a tab stop.
301 pango_tab_array_get_tab (PangoTabArray *tab_array,
303 PangoTabAlign *alignment,
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);
311 *alignment = tab_array->tabs[tab_index].alignment;
314 *location = tab_array->tabs[tab_index].location;
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
323 * If non-%NULL, @alignments and @locations are filled with allocated
324 * arrays of length pango_tab_array_get_size(). You must free the
329 pango_tab_array_get_tabs (PangoTabArray *tab_array,
330 PangoTabAlign **alignments,
335 g_return_if_fail (tab_array != NULL);
338 *alignments = g_new (PangoTabAlign, tab_array->size);
341 *locations = g_new (gint, tab_array->size);
344 while (i < tab_array->size)
347 (*alignments)[i] = tab_array->tabs[i].alignment;
349 (*locations)[i] = tab_array->tabs[i].location;
356 * pango_tab_array_get_positions_in_pixels:
357 * @tab_array: a #PangoTabArray
359 * Returns %TRUE if the tab positions are in pixels, %FALSE if they are
362 * Return value: whether positions are in pixels.
365 pango_tab_array_get_positions_in_pixels (PangoTabArray *tab_array)
367 g_return_val_if_fail (tab_array != NULL, FALSE);
369 return tab_array->positions_in_pixels;