Upload tizen 2.0 beta source
[external/pango1.0.git] / pango / pango-impl-utils.h
1 /* Pango
2  * pango-impl-utils.h: Macros for get_type() functions
3  * Inspired by Jody Goldberg's gsf-impl-utils.h
4  *
5  * Copyright (C) 2003 Red Hat Software
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #ifndef __PANGO_IMPL_UTILS_H__
24 #define __PANGO_IMPL_UTILS_H__
25
26 #include <glib.h>
27 #include <glib-object.h>
28 #include <pango/pango.h>
29
30 G_BEGIN_DECLS
31
32 #define PANGO_DEFINE_TYPE_FULL(name, prefix,                               \
33                                class_init, instance_init,                  \
34                                parent_type, abstract)                      \
35 GType                                                                      \
36 prefix ## _get_type (void)                                                 \
37 {                                                                          \
38   static GType object_type = 0;                                            \
39                                                                            \
40   if (!object_type)                                                        \
41     {                                                                      \
42       static const GTypeInfo object_info =                                 \
43         {                                                                  \
44           sizeof (name ## Class),                                          \
45           (GBaseInitFunc) NULL,                                            \
46           (GBaseFinalizeFunc) NULL,                                        \
47           (GClassInitFunc) class_init,                                     \
48           (GClassFinalizeFunc) NULL,                                       \
49           NULL,          /* class_data */                                  \
50           sizeof (name),                                                   \
51           0,             /* n_prelocs */                                   \
52           (GInstanceInitFunc) instance_init,                               \
53           NULL           /* value_table */                                 \
54         };                                                                 \
55                                                                            \
56       object_type = g_type_register_static (parent_type,                   \
57                                             g_intern_static_string (# name), \
58                                             &object_info, abstract);       \
59     }                                                                      \
60                                                                            \
61   return object_type;                                                      \
62 }
63
64 #define PANGO_DEFINE_TYPE(name, prefix,                 \
65                           class_init, instance_init,    \
66                           parent_type)                  \
67  PANGO_DEFINE_TYPE_FULL (name, prefix,                  \
68                          class_init, instance_init,     \
69                          parent_type, 0)
70
71 #define PANGO_DEFINE_TYPE_ABSTRACT(name, prefix,                \
72                           class_init, instance_init,            \
73                           parent_type)                          \
74  PANGO_DEFINE_TYPE_FULL (name, prefix,                          \
75                          class_init, instance_init,             \
76                          parent_type, G_TYPE_FLAG_ABSTRACT)
77
78
79 /* String interning for static strings */
80 #define I_(string) g_intern_static_string (string)
81
82
83 /* Some functions for handling PANGO_ATTR_SHAPE */
84 void _pango_shape_shape (const char       *text,
85                          gint              n_chars,
86                          PangoRectangle   *shape_ink,
87                          PangoRectangle   *shape_logical,
88                          PangoGlyphString *glyphs);
89
90 void _pango_shape_get_extents (gint              n_chars,
91                                PangoRectangle   *shape_ink,
92                                PangoRectangle   *shape_logical,
93                                PangoRectangle   *ink_rect,
94                                PangoRectangle   *logical_rect);
95
96
97 /* We define these functions static here because we don't want to add public API
98  * for them (if anything, it belongs to glib, but glib found it trivial enough
99  * not to add API for).  At some point metrics calculations will be
100  * centralized and this mess can be minimized.  Or so I hope.
101  */
102
103 static inline G_GNUC_UNUSED int
104 pango_unichar_width (gunichar c)
105 {
106   return G_UNLIKELY (g_unichar_iszerowidth (c)) ? 0 :
107            G_UNLIKELY (g_unichar_iswide (c)) ? 2 : 1;
108 }
109
110 static G_GNUC_UNUSED glong
111 pango_utf8_strwidth (const gchar *p)
112 {
113   glong len = 0;
114   g_return_val_if_fail (p != NULL, 0);
115
116   while (*p)
117     {
118       len += pango_unichar_width (g_utf8_get_char (p));
119       p = g_utf8_next_char (p);
120     }
121
122   return len;
123 }
124
125 /* Glib's g_utf8_strlen() is broken and stops at embedded NUL's.
126  * Wrap it here. */
127 static G_GNUC_UNUSED glong
128 pango_utf8_strlen (const gchar *p, gssize max)
129 {
130   glong len = 0;
131   const gchar *start = p;
132   g_return_val_if_fail (p != NULL || max == 0, 0);
133
134   if (max <= 0)
135     return g_utf8_strlen (p, max);
136
137   p = g_utf8_next_char (p);
138   while (p - start < max)
139     {
140       ++len;
141       p = g_utf8_next_char (p);
142     }
143
144   /* only do the last len increment if we got a complete
145    * char (don't count partial chars)
146    */
147   if (p - start <= max)
148     ++len;
149
150   return len;
151 }
152
153
154 /* To be made public at some point */
155
156 static G_GNUC_UNUSED void
157 pango_glyph_string_reverse_range (PangoGlyphString *glyphs,
158                                   int start, int end)
159 {
160   int i, j;
161
162   for (i = start, j = end - 1; i < j; i++, j--)
163     {
164       PangoGlyphInfo glyph_info;
165       gint log_cluster;
166
167       glyph_info = glyphs->glyphs[i];
168       glyphs->glyphs[i] = glyphs->glyphs[j];
169       glyphs->glyphs[j] = glyph_info;
170
171       log_cluster = glyphs->log_clusters[i];
172       glyphs->log_clusters[i] = glyphs->log_clusters[j];
173       glyphs->log_clusters[j] = log_cluster;
174     }
175 }
176
177
178 G_END_DECLS
179
180 #endif /* __PANGO_IMPL_UTILS_H__ */