Git init
[external/pango1.0.git] / pango / pango-color.c
1 /* pango
2  * pango-color.c: Color handling
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 <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "pango-attributes.h"
28 #include "pango-impl-utils.h"
29
30 GType
31 pango_color_get_type (void)
32 {
33   static GType our_type = 0;
34
35   if (G_UNLIKELY (our_type == 0))
36     our_type = g_boxed_type_register_static (I_("PangoColor"),
37                                              (GBoxedCopyFunc) pango_color_copy,
38                                              (GBoxedFreeFunc) pango_color_free);
39
40   return our_type;
41 }
42
43 /**
44  * pango_color_copy:
45  * @src: color to copy, may be %NULL
46  *
47  * Creates a copy of @src, which should be freed with
48  * pango_color_free(). Primarily used by language bindings,
49  * not that useful otherwise (since colors can just be copied
50  * by assignment in C).
51  *
52  * Return value: the newly allocated #PangoColor, which should
53  *               be freed with pango_color_free(), or %NULL
54  *               if @src was %NULL.
55  **/
56 PangoColor*
57 pango_color_copy (const PangoColor *src)
58 {
59   PangoColor *ret;
60
61   if (src == NULL)
62     return NULL;
63
64   ret = g_slice_new (PangoColor);
65
66   *ret = *src;
67
68   return ret;
69 }
70
71 /**
72  * pango_color_free:
73  * @color: an allocated #PangoColor, may be %NULL
74  *
75  * Frees a color allocated by pango_color_copy().
76  **/
77 void
78 pango_color_free (PangoColor *color)
79 {
80   if (color == NULL)
81     return;
82
83   g_slice_free (PangoColor, color);
84 }
85
86 /**
87  * pango_color_to_string:
88  * @color: a #PangoColor
89  *
90  * Returns a textual specification of @color in the hexadecimal form
91  * <literal>&num;rrrrggggbbbb</literal>, where <literal>r</literal>,
92  * <literal>g</literal> and <literal>b</literal> are hex digits representing
93  * the red, green, and blue components respectively.
94  *
95  * Return value: a newly-allocated text string that must be freed with g_free().
96  *
97  * Since: 1.16
98  **/
99 gchar *
100 pango_color_to_string (const PangoColor *color)
101 {
102   g_return_val_if_fail (color != NULL, NULL);
103
104   return g_strdup_printf ("#%04x%04x%04x", color->red, color->green, color->blue);
105 }
106
107 /* Color parsing
108  */
109
110 /* The following 2 routines (parse_color, find_color) come from Tk, via the Win32
111  * port of GDK. The licensing terms on these (longer than the functions) is:
112  *
113  * This software is copyrighted by the Regents of the University of
114  * California, Sun Microsystems, Inc., and other parties.  The following
115  * terms apply to all files associated with the software unless explicitly
116  * disclaimed in individual files.
117  *
118  * The authors hereby grant permission to use, copy, modify, distribute,
119  * and license this software and its documentation for any purpose, provided
120  * that existing copyright notices are retained in all copies and that this
121  * notice is included verbatim in any distributions. No written agreement,
122  * license, or royalty fee is required for any of the authorized uses.
123  * Modifications to this software may be copyrighted by their authors
124  * and need not follow the licensing terms described here, provided that
125  * the new terms are clearly indicated on the first page of each file where
126  * they apply.
127  *
128  * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
129  * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
130  * ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
131  * DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
132  * POSSIBILITY OF SUCH DAMAGE.
133  *
134  * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
135  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
136  * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
137  * IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
138  * NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
139  * MODIFICATIONS.
140  *
141  * GOVERNMENT USE: If you are acquiring this software on behalf of the
142  * U.S. government, the Government shall have only "Restricted Rights"
143  * in the software and related documentation as defined in the Federal
144  * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
145  * are acquiring the software on behalf of the Department of Defense, the
146  * software shall be classified as "Commercial Computer Software" and the
147  * Government shall have only "Restricted Rights" as defined in Clause
148  * 252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the
149  * authors grant the U.S. Government and others acting in its behalf
150  * permission to use and distribute the software in accordance with the
151  * terms specified in this license.
152  */
153
154 #include "pango-color-table.h"
155
156 static int
157 compare_xcolor_entries (const void *a, const void *b)
158 {
159   return g_ascii_strcasecmp ((const char *) a, color_names + ((const ColorEntry *) b)->name_offset);
160 }
161
162 static gboolean
163 find_color(const char *name,
164            PangoColor *color)
165 {
166   ColorEntry *found;
167
168   found = bsearch (name, color_entries, G_N_ELEMENTS (color_entries),
169                    sizeof (ColorEntry),
170                    compare_xcolor_entries);
171   if (found == NULL)
172     return FALSE;
173
174   if (color)
175     {
176       color->red = (found->red * 65535) / 255;
177       color->green = (found->green * 65535) / 255;
178       color->blue = (found->blue * 65535) / 255;
179     }
180
181   return TRUE;
182 }
183
184 static gboolean
185 hex (const char *spec,
186     int len,
187     unsigned int *c)
188 {
189   const char *end;
190   *c = 0;
191   for (end = spec + len; spec != end; spec++)
192     if (g_ascii_isxdigit (*spec))
193       *c = (*c << 4) | g_ascii_xdigit_value (*spec);
194     else
195       return FALSE;
196   return TRUE;
197 }
198
199 /**
200  * pango_color_parse:
201  * @color: a #PangoColor structure in which to store the result, or %NULL
202  * @spec: a string specifying the new color
203  *
204  * Fill in the fields of a color from a string specification. The
205  * string can either one of a large set of standard names. (Taken
206  * from the X11 <filename>rgb.txt</filename> file), or it can be a hex value in the
207  * form '&num;rgb' '&num;rrggbb' '&num;rrrgggbbb' or '&num;rrrrggggbbbb' where
208  * 'r', 'g' and 'b' are hex digits of the red, green, and blue
209  * components of the color, respectively. (White in the four
210  * forms is '&num;fff' '&num;ffffff' '&num;fffffffff' and '&num;ffffffffffff')
211  *
212  * Return value: %TRUE if parsing of the specifier succeeded,
213  *   otherwise false.
214  **/
215 gboolean
216 pango_color_parse (PangoColor *color,
217                    const char *spec)
218 {
219   g_return_val_if_fail (spec != NULL, FALSE);
220
221   if (spec[0] == '#')
222     {
223       size_t len;
224       unsigned int r, g, b;
225
226       spec++;
227       len = strlen (spec);
228       if (len % 3 || len < 3 || len > 12)
229         return FALSE;
230
231       len /= 3;
232
233       if (!hex (spec, len, &r) ||
234           !hex (spec + len, len, &g) ||
235           !hex (spec + len * 2, len, &b))
236         return FALSE;
237
238       if (color)
239         {
240           int bits = len * 4;
241           r <<= 16 - bits;
242           g <<= 16 - bits;
243           b <<= 16 - bits;
244           while (bits < 16)
245             {
246               r |= (r >> bits);
247               g |= (g >> bits);
248               b |= (b >> bits);
249               bits *= 2;
250             }
251           color->red   = r;
252           color->green = g;
253           color->blue  = b;
254         }
255     }
256   else
257     {
258       if (!find_color (spec, color))
259         return FALSE;
260     }
261   return TRUE;
262 }