diff options
Diffstat (limited to 'pango2/pango-color.c')
-rw-r--r-- | pango2/pango-color.c | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/pango2/pango-color.c b/pango2/pango-color.c new file mode 100644 index 00000000..adc9a0d1 --- /dev/null +++ b/pango2/pango-color.c @@ -0,0 +1,337 @@ +/* pango + * pango-color.c: Color handling + * + * Copyright (C) 2000 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "pango-attributes.h" +#include "pango-impl-utils.h" + + +G_DEFINE_BOXED_TYPE (Pango2Color, pango2_color, + pango2_color_copy, + pango2_color_free); + +/** + * pango2_color_copy: + * @src: (nullable): color to copy + * + * Creates a copy of @src. + * + * The copy should be freed with [method@Pango2.Color.free]. + * Primarily used by language bindings, not that useful + * otherwise (since colors can just be copied by assignment + * in C). + * + * Return value: (nullable): the newly allocated `Pango2Color`, + * which should be freed with [method@Pango2.Color.free] + */ +Pango2Color* +pango2_color_copy (const Pango2Color *src) +{ + Pango2Color *ret; + + if (src == NULL) + return NULL; + + ret = g_slice_new (Pango2Color); + + *ret = *src; + + return ret; +} + +/** + * pango2_color_free: + * @color: (nullable): an allocated `Pango2Color` + * + * Frees a color allocated by [method@Pango2.Color.copy]. + */ +void +pango2_color_free (Pango2Color *color) +{ + if (color == NULL) + return; + + g_slice_free (Pango2Color, color); +} + +/** + * pango2_color_equal: + * @color1: (nullable): a `Pango2Color` + * @color2: (nullable): another `Pango2Color` + * + * Compares two colors for quality. + * + * Returns: `TRUE` if the colors are equal + */ +gboolean +pango2_color_equal (const Pango2Color *color1, + const Pango2Color *color2) +{ + return color1 == color2 || + (color1 && color2 && + color1->red == color2->red && + color1->green == color2->green && + color1->blue == color2->blue && + color1->alpha == color2->alpha); +} + +/** + * pango2_color_to_string: + * @color: a `Pango2Color` + * + * Returns a textual specification of @color. + * + * The string is in the hexadecimal form `#rrrrggggbbbbaaaa`, + * where `r`, `g`, `b` and `a` are hex digits representing the + * red, green, blue and alpha components respectively. + * + * Return value: a newly-allocated text string that must + * be freed with [GLib.free] + */ +char * +pango2_color_to_string (const Pango2Color *color) +{ + g_return_val_if_fail (color != NULL, NULL); + + return g_strdup_printf ("#%04x%04x%04x%04x", + color->red, + color->green, + color->blue, + color->alpha); +} + +/* Color parsing + */ + +/* The following 2 routines (parse_color, find_color) come from Tk, via the Win32 + * port of GDK. The licensing terms on these (longer than the functions) is: + * + * This software is copyrighted by the Regents of the University of + * California, Sun Microsystems, Inc., and other parties. The following + * terms apply to all files associated with the software unless explicitly + * disclaimed in individual files. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + * + * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY + * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY + * DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE + * IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE + * NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR + * MODIFICATIONS. + * + * GOVERNMENT USE: If you are acquiring this software on behalf of the + * U.S. government, the Government shall have only "Restricted Rights" + * in the software and related documentation as defined in the Federal + * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you + * are acquiring the software on behalf of the Department of Defense, the + * software shall be classified as "Commercial Computer Software" and the + * Government shall have only "Restricted Rights" as defined in Clause + * 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the + * authors grant the U.S. Government and others acting in its behalf + * permission to use and distribute the software in accordance with the + * terms specified in this license. + */ + +#include "pango-color-table.h" + +#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z') +#define TOLOWER(c) (ISUPPER (c) ? (c) - 'A' + 'a' : (c)) + +static int +compare_xcolor_entries (const void *a, const void *b) +{ + const guchar *s1 = (const guchar *) a; + const guchar *s2 = (const guchar *) (color_names + ((const ColorEntry *) b)->name_offset); + + while (*s1 && *s2) + { + int c1, c2; + while (*s1 == ' ') s1++; + while (*s2 == ' ') s1++; + c1 = (int)(guchar) TOLOWER (*s1); + c2 = (int)(guchar) TOLOWER (*s2); + if (c1 != c2) + return (c1 - c2); + s1++; s2++; + } + + return ((int) *s1) - ((int) *s2); +} + +static gboolean +find_color(const char *name, + Pango2Color *color) +{ + ColorEntry *found; + + found = bsearch (name, color_entries, G_N_ELEMENTS (color_entries), + sizeof (ColorEntry), + compare_xcolor_entries); + if (found == NULL) + return FALSE; + + if (color) + { + color->red = (found->red * 65535) / 255; + color->green = (found->green * 65535) / 255; + color->blue = (found->blue * 65535) / 255; + } + + return TRUE; +} + +static gboolean +hex (const char *spec, + int len, + unsigned int *c) +{ + const char *end; + *c = 0; + for (end = spec + len; spec != end; spec++) + if (g_ascii_isxdigit (*spec)) + *c = (*c << 4) | g_ascii_xdigit_value (*spec); + else + return FALSE; + return TRUE; +} + + +/** + * pango2_color_parse: + * @color: a `Pango2Color` structure in which to store the result + * @spec: a string specifying the new color + * + * Fill in the fields of a color from a string specification. + * + * The string can either one of a large set of standard names. + * (Taken from the CSS Color [specification](https://www.w3.org/TR/css-color-4/#named-colors), + * or it can be a hexadecimal value in the form `#rgb`, + * `#rrggbb`, `#rrrgggbbb` or `#rrrrggggbbbb` where `r`, `g` + * and `b` are hex digits of the red, green, and blue components + * of the color, respectively. (White in the four forms is + * `#fff`, `#ffffff`, `#fffffffff` and `#ffffffffffff`.) + * + * Additionally, parse strings of the form `#rgba`, `#rrggbbaa`, + * `#rrrrggggbbbbaaaa`, and set the alpha component of @color + * to the value specified by the hex digits for `a`. If no alpha + * component is found in @spec, alpha is set to 0xffff (for a + * solid color). + * + * Return value: %TRUE if parsing of the specifier succeeded, + * otherwise %FALSE + */ +gboolean +pango2_color_parse (Pango2Color *color, + const char *spec) +{ + g_return_val_if_fail (spec != NULL, FALSE); + + color->alpha = 0xffff; + + if (spec[0] == '#') + { + size_t len; + unsigned int r, g, b, a; + gboolean has_alpha; + + spec++; + len = strlen (spec); + switch (len) + { + case 3: + case 6: + case 9: + case 12: + len /= 3; + has_alpha = FALSE; + break; + case 4: + case 8: + case 16: + len /= 4; + has_alpha = TRUE; + break; + default: + return FALSE; + } + + if (!hex (spec, len, &r) || + !hex (spec + len, len, &g) || + !hex (spec + len * 2, len, &b) || + (has_alpha && !hex (spec + len * 3, len, &a))) + return FALSE; + + if (color) + { + int bits = len * 4; + r <<= 16 - bits; + g <<= 16 - bits; + b <<= 16 - bits; + while (bits < 16) + { + r |= (r >> bits); + g |= (g >> bits); + b |= (b >> bits); + bits *= 2; + } + color->red = r; + color->green = g; + color->blue = b; + } + + if (has_alpha) + { + int bits = len * 4; + a <<= 16 - bits; + while (bits < 16) + { + a |= (a >> bits); + bits *= 2; + } + color->alpha = a; + } + } + else + { + if (!find_color (spec, color)) + return FALSE; + } + return TRUE; +} |