svg-color.cpp revision cc618cb0faf84b6f5ab2cc9802b29d03f6a22f97
#define __SP_SVG_COLOR_C__
/**
* \file
*/
/*
* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
*
* Copyright (C) 1999-2002 Lauris Kaplinski
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <cstdlib>
#include <cstdio> // sprintf
#include <cstring>
#include <string>
#include <cassert>
#include <math.h>
#include <glib.h> // g_assert
#include <glib/gmessages.h>
#include <glib/gstrfuncs.h>
#include <errno.h>
#include "strneq.h"
#include "preferences.h"
#include "svg-color.h"
#include "svg-icc-color.h"
#include "svg-device-color.h"
#if ENABLE_LCMS
#include <lcms.h>
#include "color.h"
#include "color-profile.h"
#include "document.h"
#include "inkscape.h"
#include "profile-manager.h"
#endif // ENABLE_LCMS
struct SPSVGColor {
unsigned long rgb;
char const *name;
};
/*
* These are the colors defined in the SVG standard
*/
static SPSVGColor const sp_svg_color_named[] = {
{ 0xF0F8FF, "aliceblue" },
{ 0xFAEBD7, "antiquewhite" },
{ 0x00FFFF, "aqua" },
{ 0x7FFFD4, "aquamarine" },
{ 0xF0FFFF, "azure" },
{ 0xF5F5DC, "beige" },
{ 0xFFE4C4, "bisque" },
{ 0x000000, "black" },
{ 0xFFEBCD, "blanchedalmond" },
{ 0x0000FF, "blue" },
{ 0x8A2BE2, "blueviolet" },
{ 0xA52A2A, "brown" },
{ 0xDEB887, "burlywood" },
{ 0x5F9EA0, "cadetblue" },
{ 0x7FFF00, "chartreuse" },
{ 0xD2691E, "chocolate" },
{ 0xFF7F50, "coral" },
{ 0x6495ED, "cornflowerblue" },
{ 0xFFF8DC, "cornsilk" },
{ 0xDC143C, "crimson" },
{ 0x00FFFF, "cyan" },
{ 0x00008B, "darkblue" },
{ 0x008B8B, "darkcyan" },
{ 0xB8860B, "darkgoldenrod" },
{ 0xA9A9A9, "darkgray" },
{ 0x006400, "darkgreen" },
{ 0xA9A9A9, "darkgrey" },
{ 0xBDB76B, "darkkhaki" },
{ 0x8B008B, "darkmagenta" },
{ 0x556B2F, "darkolivegreen" },
{ 0xFF8C00, "darkorange" },
{ 0x9932CC, "darkorchid" },
{ 0x8B0000, "darkred" },
{ 0xE9967A, "darksalmon" },
{ 0x8FBC8F, "darkseagreen" },
{ 0x483D8B, "darkslateblue" },
{ 0x2F4F4F, "darkslategray" },
{ 0x2F4F4F, "darkslategrey" },
{ 0x00CED1, "darkturquoise" },
{ 0x9400D3, "darkviolet" },
{ 0xFF1493, "deeppink" },
{ 0x00BFFF, "deepskyblue" },
{ 0x696969, "dimgray" },
{ 0x696969, "dimgrey" },
{ 0x1E90FF, "dodgerblue" },
{ 0xB22222, "firebrick" },
{ 0xFFFAF0, "floralwhite" },
{ 0x228B22, "forestgreen" },
{ 0xFF00FF, "fuchsia" },
{ 0xDCDCDC, "gainsboro" },
{ 0xF8F8FF, "ghostwhite" },
{ 0xFFD700, "gold" },
{ 0xDAA520, "goldenrod" },
{ 0x808080, "gray" },
{ 0x808080, "grey" },
{ 0x008000, "green" },
{ 0xADFF2F, "greenyellow" },
{ 0xF0FFF0, "honeydew" },
{ 0xFF69B4, "hotpink" },
{ 0xCD5C5C, "indianred" },
{ 0x4B0082, "indigo" },
{ 0xFFFFF0, "ivory" },
{ 0xF0E68C, "khaki" },
{ 0xE6E6FA, "lavender" },
{ 0xFFF0F5, "lavenderblush" },
{ 0x7CFC00, "lawngreen" },
{ 0xFFFACD, "lemonchiffon" },
{ 0xADD8E6, "lightblue" },
{ 0xF08080, "lightcoral" },
{ 0xE0FFFF, "lightcyan" },
{ 0xFAFAD2, "lightgoldenrodyellow" },
{ 0xD3D3D3, "lightgray" },
{ 0x90EE90, "lightgreen" },
{ 0xD3D3D3, "lightgrey" },
{ 0xFFB6C1, "lightpink" },
{ 0xFFA07A, "lightsalmon" },
{ 0x20B2AA, "lightseagreen" },
{ 0x87CEFA, "lightskyblue" },
{ 0x778899, "lightslategray" },
{ 0x778899, "lightslategrey" },
{ 0xB0C4DE, "lightsteelblue" },
{ 0xFFFFE0, "lightyellow" },
{ 0x00FF00, "lime" },
{ 0x32CD32, "limegreen" },
{ 0xFAF0E6, "linen" },
{ 0xFF00FF, "magenta" },
{ 0x800000, "maroon" },
{ 0x66CDAA, "mediumaquamarine" },
{ 0x0000CD, "mediumblue" },
{ 0xBA55D3, "mediumorchid" },
{ 0x9370DB, "mediumpurple" },
{ 0x3CB371, "mediumseagreen" },
{ 0x7B68EE, "mediumslateblue" },
{ 0x00FA9A, "mediumspringgreen" },
{ 0x48D1CC, "mediumturquoise" },
{ 0xC71585, "mediumvioletred" },
{ 0x191970, "midnightblue" },
{ 0xF5FFFA, "mintcream" },
{ 0xFFE4E1, "mistyrose" },
{ 0xFFE4B5, "moccasin" },
{ 0xFFDEAD, "navajowhite" },
{ 0x000080, "navy" },
{ 0xFDF5E6, "oldlace" },
{ 0x808000, "olive" },
{ 0x6B8E23, "olivedrab" },
{ 0xFFA500, "orange" },
{ 0xFF4500, "orangered" },
{ 0xDA70D6, "orchid" },
{ 0xEEE8AA, "palegoldenrod" },
{ 0x98FB98, "palegreen" },
{ 0xAFEEEE, "paleturquoise" },
{ 0xDB7093, "palevioletred" },
{ 0xFFEFD5, "papayawhip" },
{ 0xFFDAB9, "peachpuff" },
{ 0xCD853F, "peru" },
{ 0xFFC0CB, "pink" },
{ 0xDDA0DD, "plum" },
{ 0xB0E0E6, "powderblue" },
{ 0x800080, "purple" },
{ 0xFF0000, "red" },
{ 0xBC8F8F, "rosybrown" },
{ 0x4169E1, "royalblue" },
{ 0x8B4513, "saddlebrown" },
{ 0xFA8072, "salmon" },
{ 0xF4A460, "sandybrown" },
{ 0x2E8B57, "seagreen" },
{ 0xFFF5EE, "seashell" },
{ 0xA0522D, "sienna" },
{ 0xC0C0C0, "silver" },
{ 0x87CEEB, "skyblue" },
{ 0x6A5ACD, "slateblue" },
{ 0x708090, "slategray" },
{ 0x708090, "slategrey" },
{ 0xFFFAFA, "snow" },
{ 0x00FF7F, "springgreen" },
{ 0x4682B4, "steelblue" },
{ 0xD2B48C, "tan" },
{ 0x008080, "teal" },
{ 0xD8BFD8, "thistle" },
{ 0xFF6347, "tomato" },
{ 0x40E0D0, "turquoise" },
{ 0xEE82EE, "violet" },
{ 0xF5DEB3, "wheat" },
{ 0xFFFFFF, "white" },
{ 0xF5F5F5, "whitesmoke" },
{ 0xFFFF00, "yellow" },
{ 0x9ACD32, "yellowgreen" }
};
static GHashTable *sp_svg_create_color_hash();
{
}
static guint32
{
if (str[0] == '#') {
gint i;
for (i = 1; str[i]; i++) {
int hexval;
else
break;
}
/* handle #rgb case */
if (i == 1 + 3) {
(val & 0x00f);
} else if (i != 1 + 6) {
/* must be either 3 or 6 digits. */
return def;
}
if (end_ptr) {
}
gchar *s, *e;
gdouble r, g, b;
hasp = false;
hasd = false;
r = g_ascii_strtod(s, &e);
if (s == e) return def;
s = e;
if (*s == '%') {
hasp = true;
s += 1;
} else {
hasd = true;
}
while (*s && g_ascii_isspace(*s)) s += 1;
if (*s != ',') return def;
s += 1;
while (*s && g_ascii_isspace(*s)) s += 1;
g = g_ascii_strtod(s, &e);
if (s == e) return def;
s = e;
if (*s == '%') {
hasp = true;
s += 1;
} else {
hasd = true;
}
while (*s && g_ascii_isspace(*s)) s += 1;
if (*s != ',') return def;
s += 1;
while (*s && g_ascii_isspace(*s)) s += 1;
b = g_ascii_strtod(s, &e);
if (s == e) return def;
s = e;
if (*s == '%') {
hasp = true;
s += 1;
} else {
hasd = true;
}
while(*s && g_ascii_isspace(*s)) s += 1;
if (*s != ')') {
return def;
}
++s;
if (hasp) {
} else {
}
if (end_ptr) {
*end_ptr = s;
}
return val;
} else {
gint i;
if (!colors) {
}
gchar c[32];
for (i = 0; i < 31; i++) {
c[i] = '\0';
break;
}
c[i] = g_ascii_tolower(str[i]);
if (!str[i]) break;
}
c[31] = '\0';
if (rgb_ptr) {
} else {
return def;
}
if (end_ptr) {
}
}
return (val << 8);
}
{
/* I've been rather hurried in editing the above to add support for end_ptr, so I'm adding
* this check wrapper. */
|| (((ret & 0xff) == 0)
if ( end_ptr ) {
}
}
return ret;
}
/**
* The result is valid even in SVG Tiny or non-SVG CSS.
*/
static void
{
/* SVG 1.1 Full allows additional colour names not supported by SVG Tiny, but we don't bother
* with them: it's good for these colours to be copyable to non-SVG CSS stylesheets and for
* less meaningful than hex equivalents anyway. And it's easier for a person to map from the
* restricted set because the only component values are {00,80,ff}, other than silver 0xc0c0c0.
*/
switch (rgb24) {
/* Extracted mechanically from the table at
* http://www.w3.org/TR/REC-html40/types.html#h-6.5 .*/
default: {
/* Can use the shorter three-digit form #rgb instead of #rrggbb. */
rgb24 & 0xf);
} else {
}
break;
}
}
if (src) {
}
// assert(sp_svg_read_color(buf, 0xff) == (rgb24 << 8));
}
/**
* result is valid even in SVG Tiny or non-SVG CSS.
*
* \param rgba32 Colour expressed in form 0xrrggbbaa.
* \pre buflen \>= 8.
*/
void
{
} else {
}
}
static GHashTable *
{
for (unsigned i = 0 ; i < G_N_ELEMENTS(sp_svg_color_named) ; i++) {
}
return colors;
}
//helper function borrowed from src/widgets/sp-color-icc-selector.cpp:
void getThings( DWORD space, gchar const**& namers, gchar const**& tippies, guint const*& scalies );
if (icc){
if ( prof ) {
if ( trans ) {
if (count>4) count=4; //do we need it? Should we allow an arbitrary number of color values? Or should we limit to a maximum? (max==4?)
}
g_message("transform to sRGB done");
}
*r = color_out[0];
*g = color_out[1];
*b = color_out[2];
}
}
}
/*
* Some discussion at http://markmail.org/message/bhfvdfptt25kgtmj
* Allowed ASCII first characters: ':', 'A'-'Z', '_', 'a'-'z'
* Allowed ASCII remaining chars add: '-', '.', '0'-'9',
*/
{
bool good = true;
if ( end_ptr ) {
}
if ( dest ) {
}
if ( !str ) {
// invalid input
good = false;
} else {
while ( g_ascii_isspace(*str) ) {
str++;
}
if ( good ) {
str += 10;
while ( g_ascii_isspace(*str) ) {
str++;
}
if ( !g_ascii_isalpha(*str)
&& ( !(0x080 & *str) )
&& (*str != '_')
&& (*str != ':') ) {
// Name must start with a certain type of character
good = false;
} else {
if ( dest ) {
}
str++;
}
str++;
}
}
}
if ( good ) {
if ( !errno ) {
if ( dest ) {
}
} else {
good = false;
break;
}
str++;
}
} else {
break;
}
}
}
// We need to have ended on a closing parenthesis
if ( good ) {
while ( g_ascii_isspace(*str) ) {
str++;
}
}
}
if ( good ) {
if ( end_ptr ) {
}
} else {
if ( dest ) {
}
}
return good;
}
{
}
{
bool good = true;
unsigned int max_colors;
if ( end_ptr ) {
}
if ( dest ) {
}
if ( !str ) {
// invalid input
good = false;
} else {
while ( g_ascii_isspace(*str) ) {
str++;
}
max_colors=1;
str += 12;
}
max_colors=3;
str += 11;
}
max_colors=4;
str += 12;
}
max_colors=0;
str += 16;
}
while ( g_ascii_isspace(*str) ) {
str++;
}
if ( !errno ) {
if ( dest ) {
}
} else {
good = false;
break;
}
str++;
}
} else {
break;
}
}
}
// We need to have ended on a closing parenthesis
if ( good ) {
while ( g_ascii_isspace(*str) ) {
str++;
}
}
}
if ( good ) {
if ( end_ptr ) {
}
} else {
if ( dest ) {
}
}
return good;
}
{
}
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :