summaryrefslogtreecommitdiff
path: root/pango2/pango-color.c
diff options
context:
space:
mode:
Diffstat (limited to 'pango2/pango-color.c')
-rw-r--r--pango2/pango-color.c337
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;
+}