Upload tizen 2.0 beta source
[external/pango1.0.git] / pango / reorder-items.c
1 /* Pango
2  * reorder-items.c:
3  *
4  * Copyright (C) 1999 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-glyph.h"
24
25 /*
26  * NB: The contents of the file implement the exact same algorithm
27  *     pango-layout.c:pango_layout_line_reorder().
28  */
29
30 static GList *reorder_items_recurse (GList *items, int n_items);
31
32 /**
33  * pango_reorder_items:
34  * @logical_items:  a #GList of #PangoItem in logical order.
35  *
36  * From a list of items in logical order and the associated
37  * directional levels, produce a list in visual order.
38  * The original list is unmodified.
39  *
40  * Returns: a #GList of #PangoItem structures in visual order.
41  *
42  * (Please open a bug if you use this function.
43  *  It is not a particularly convenient interface, and the code
44  *  is duplicated elsewhere in Pango for that reason.)
45  */
46 GList *
47 pango_reorder_items (GList *logical_items)
48 {
49   return reorder_items_recurse (logical_items, g_list_length (logical_items));
50 }
51
52 static GList *
53 reorder_items_recurse (GList *items, int n_items)
54 {
55   GList *tmp_list, *level_start_node;
56   int i, level_start_i;
57   int min_level = G_MAXINT;
58   GList *result = NULL;
59
60   if (n_items == 0)
61     return NULL;
62
63   tmp_list = items;
64   for (i=0; i<n_items; i++)
65     {
66       PangoItem *item = tmp_list->data;
67
68       min_level = MIN (min_level, item->analysis.level);
69
70       tmp_list = tmp_list->next;
71     }
72
73   level_start_i = 0;
74   level_start_node = items;
75   tmp_list = items;
76   for (i=0; i<n_items; i++)
77     {
78       PangoItem *item = tmp_list->data;
79
80       if (item->analysis.level == min_level)
81         {
82           if (min_level % 2)
83             {
84               if (i > level_start_i)
85                 result = g_list_concat (reorder_items_recurse (level_start_node, i - level_start_i), result);
86               result = g_list_prepend (result, item);
87             }
88           else
89             {
90               if (i > level_start_i)
91                 result = g_list_concat (result, reorder_items_recurse (level_start_node, i - level_start_i));
92               result = g_list_append (result, item);
93             }
94
95           level_start_i = i + 1;
96           level_start_node = tmp_list->next;
97         }
98
99       tmp_list = tmp_list->next;
100     }
101
102   if (min_level % 2)
103     {
104       if (i > level_start_i)
105         result = g_list_concat (reorder_items_recurse (level_start_node, i - level_start_i), result);
106     }
107   else
108     {
109       if (i > level_start_i)
110         result = g_list_concat (result, reorder_items_recurse (level_start_node, i - level_start_i));
111     }
112
113   return result;
114 }