/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/utils/SkParse.h"
#include "include/core/SkColor.h"
#include "include/core/SkTypes.h"
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <iterator>
static constexpr const char * gColorNames[] = {
"aliceblue" ,
"antiquewhite" ,
"aqua" ,
"aquamarine" ,
"azure" ,
"beige" ,
"bisque" ,
"black" ,
"blanchedalmond" ,
"blue" ,
"blueviolet" ,
"brown" ,
"burlywood" ,
"cadetblue" ,
"chartreuse" ,
"chocolate" ,
"coral" ,
"cornflowerblue" ,
"cornsilk" ,
"crimson" ,
"cyan" ,
"darkblue" ,
"darkcyan" ,
"darkgoldenrod" ,
"darkgray" ,
"darkgreen" ,
"darkkhaki" ,
"darkmagenta" ,
"darkolivegreen" ,
"darkorange" ,
"darkorchid" ,
"darkred" ,
"darksalmon" ,
"darkseagreen" ,
"darkslateblue" ,
"darkslategray" ,
"darkturquoise" ,
"darkviolet" ,
"deeppink" ,
"deepskyblue" ,
"dimgray" ,
"dodgerblue" ,
"firebrick" ,
"floralwhite" ,
"forestgreen" ,
"fuchsia" ,
"gainsboro" ,
"ghostwhite" ,
"gold" ,
"goldenrod" ,
"gray" ,
"green" ,
"greenyellow" ,
"honeydew" ,
"hotpink" ,
"indianred" ,
"indigo" ,
"ivory" ,
"khaki" ,
"lavender" ,
"lavenderblush" ,
"lawngreen" ,
"lemonchiffon" ,
"lightblue" ,
"lightcoral" ,
"lightcyan" ,
"lightgoldenrodyellow" ,
"lightgreen" ,
"lightgrey" ,
"lightpink" ,
"lightsalmon" ,
"lightseagreen" ,
"lightskyblue" ,
"lightslategray" ,
"lightsteelblue" ,
"lightyellow" ,
"lime" ,
"limegreen" ,
"linen" ,
"magenta" ,
"maroon" ,
"mediumaquamarine" ,
"mediumblue" ,
"mediumorchid" ,
"mediumpurple" ,
"mediumseagreen" ,
"mediumslateblue" ,
"mediumspringgreen" ,
"mediumturquoise" ,
"mediumvioletred" ,
"midnightblue" ,
"mintcream" ,
"mistyrose" ,
"moccasin" ,
"navajowhite" ,
"navy" ,
"oldlace" ,
"olive" ,
"olivedrab" ,
"orange" ,
"orangered" ,
"orchid" ,
"palegoldenrod" ,
"palegreen" ,
"paleturquoise" ,
"palevioletred" ,
"papayawhip" ,
"peachpuff" ,
"peru" ,
"pink" ,
"plum" ,
"powderblue" ,
"purple" ,
"red" ,
"rosybrown" ,
"royalblue" ,
"saddlebrown" ,
"salmon" ,
"sandybrown" ,
"seagreen" ,
"seashell" ,
"sienna" ,
"silver" ,
"skyblue" ,
"slateblue" ,
"slategray" ,
"snow" ,
"springgreen" ,
"steelblue" ,
"tan" ,
"teal" ,
"thistle" ,
"tomato" ,
"turquoise" ,
"violet" ,
"wheat" ,
"white" ,
"whitesmoke" ,
"yellow" ,
"yellowgreen" ,
};
static constexpr struct ColorRec {
uint8_t r, g, b;
} gColors[] = {
{ 0 xf0,0 xf8,0 xff }, // aliceblue
{ 0 xfa,0 xeb,0 xd7 }, // antiquewhite
{ 0 x00,0 xff,0 xff }, // aqua
{ 0 x7f,0 xff,0 xd4 }, // aquamarine
{ 0 xf0,0 xff,0 xff }, // azure
{ 0 xf5,0 xf5,0 xdc }, // beige
{ 0 xff,0 xe4,0 xc4 }, // bisque
{ 0 x00,0 x00,0 x00 }, // black
{ 0 xff,0 xeb,0 xcd }, // blanchedalmond
{ 0 x00,0 x00,0 xff }, // blue
{ 0 x8a,0 x2b,0 xe2 }, // blueviolet
{ 0 xa5,0 x2a,0 x2a }, // brown
{ 0 xde,0 xb8,0 x87 }, // burlywood
{ 0 x5f,0 x9e,0 xa0 }, // cadetblue
{ 0 x7f,0 xff,0 x00 }, // chartreuse
{ 0 xd2,0 x69,0 x1e }, // chocolate
{ 0 xff,0 x7f,0 x50 }, // coral
{ 0 x64,0 x95,0 xed }, // cornflowerblue
{ 0 xff,0 xf8,0 xdc }, // cornsilk
{ 0 xdc,0 x14,0 x3c }, // crimson
{ 0 x00,0 xff,0 xff }, // cyan
{ 0 x00,0 x00,0 x8b }, // darkblue
{ 0 x00,0 x8b,0 x8b }, // darkcyan
{ 0 xb8,0 x86,0 x0b }, // darkgoldenrod
{ 0 xa9,0 xa9,0 xa9 }, // darkgray
{ 0 x00,0 x64,0 x00 }, // darkgreen
{ 0 xbd,0 xb7,0 x6b }, // darkkhaki
{ 0 x8b,0 x00,0 x8b }, // darkmagenta
{ 0 x55,0 x6b,0 x2f }, // darkolivegreen
{ 0 xff,0 x8c,0 x00 }, // darkorange
{ 0 x99,0 x32,0 xcc }, // darkorchid
{ 0 x8b,0 x00,0 x00 }, // darkred
{ 0 xe9,0 x96,0 x7a }, // darksalmon
{ 0 x8f,0 xbc,0 x8f }, // darkseagreen
{ 0 x48,0 x3d,0 x8b }, // darkslateblue
{ 0 x2f,0 x4f,0 x4f }, // darkslategray
{ 0 x00,0 xce,0 xd1 }, // darkturquoise
{ 0 x94,0 x00,0 xd3 }, // darkviolet
{ 0 xff,0 x14,0 x93 }, // deeppink
{ 0 x00,0 xbf,0 xff }, // deepskyblue
{ 0 x69,0 x69,0 x69 }, // dimgray
{ 0 x1e,0 x90,0 xff }, // dodgerblue
{ 0 xb2,0 x22,0 x22 }, // firebrick
{ 0 xff,0 xfa,0 xf0 }, // floralwhite
{ 0 x22,0 x8b,0 x22 }, // forestgreen
{ 0 xff,0 x00,0 xff }, // fuchsia
{ 0 xdc,0 xdc,0 xdc }, // gainsboro
{ 0 xf8,0 xf8,0 xff }, // ghostwhite
{ 0 xff,0 xd7,0 x00 }, // gold
{ 0 xda,0 xa5,0 x20 }, // goldenrod
{ 0 x80,0 x80,0 x80 }, // gray
{ 0 x00,0 x80,0 x00 }, // green
{ 0 xad,0 xff,0 x2f }, // greenyellow
{ 0 xf0,0 xff,0 xf0 }, // honeydew
{ 0 xff,0 x69,0 xb4 }, // hotpink
{ 0 xcd,0 x5c,0 x5c }, // indianred
{ 0 x4b,0 x00,0 x82 }, // indigo
{ 0 xff,0 xff,0 xf0 }, // ivory
{ 0 xf0,0 xe6,0 x8c }, // khaki
{ 0 xe6,0 xe6,0 xfa }, // lavender
{ 0 xff,0 xf0,0 xf5 }, // lavenderblush
{ 0 x7c,0 xfc,0 x00 }, // lawngreen
{ 0 xff,0 xfa,0 xcd }, // lemonchiffon
{ 0 xad,0 xd8,0 xe6 }, // lightblue
{ 0 xf0,0 x80,0 x80 }, // lightcoral
{ 0 xe0,0 xff,0 xff }, // lightcyan
{ 0 xfa,0 xfa,0 xd2 }, // lightgoldenrodyellow
{ 0 x90,0 xee,0 x90 }, // lightgreen
{ 0 xd3,0 xd3,0 xd3 }, // lightgrey
{ 0 xff,0 xb6,0 xc1 }, // lightpink
{ 0 xff,0 xa0,0 x7a }, // lightsalmon
{ 0 x20,0 xb2,0 xaa }, // lightseagreen
{ 0 x87,0 xce,0 xfa }, // lightskyblue
{ 0 x77,0 x88,0 x99 }, // lightslategray
{ 0 xb0,0 xc4,0 xde }, // lightsteelblue
{ 0 xff,0 xff,0 xe0 }, // lightyellow
{ 0 x00,0 xff,0 x00 }, // lime
{ 0 x32,0 xcd,0 x32 }, // limegreen
{ 0 xfa,0 xf0,0 xe6 }, // linen
{ 0 xff,0 x00,0 xff }, // magenta
{ 0 x80,0 x00,0 x00 }, // maroon
{ 0 x66,0 xcd,0 xaa }, // mediumaquamarine
{ 0 x00,0 x00,0 xcd }, // mediumblue
{ 0 xba,0 x55,0 xd3 }, // mediumorchid
{ 0 x93,0 x70,0 xdb }, // mediumpurple
{ 0 x3c,0 xb3,0 x71 }, // mediumseagreen
{ 0 x7b,0 x68,0 xee }, // mediumslateblue
{ 0 x00,0 xfa,0 x9a }, // mediumspringgreen
{ 0 x48,0 xd1,0 xcc }, // mediumturquoise
{ 0 xc7,0 x15,0 x85 }, // mediumvioletred
{ 0 x19,0 x19,0 x70 }, // midnightblue
{ 0 xf5,0 xff,0 xfa }, // mintcream
{ 0 xff,0 xe4,0 xe1 }, // mistyrose
{ 0 xff,0 xe4,0 xb5 }, // moccasin
{ 0 xff,0 xde,0 xad }, // navajowhite
{ 0 x00,0 x00,0 x80 }, // navy
{ 0 xfd,0 xf5,0 xe6 }, // oldlace
{ 0 x80,0 x80,0 x00 }, // olive
{ 0 x6b,0 x8e,0 x23 }, // olivedrab
{ 0 xff,0 xa5,0 x00 }, // orange
{ 0 xff,0 x45,0 x00 }, // orangered
{ 0 xda,0 x70,0 xd6 }, // orchid
{ 0 xee,0 xe8,0 xaa }, // palegoldenrod
{ 0 x98,0 xfb,0 x98 }, // palegreen
{ 0 xaf,0 xee,0 xee }, // paleturquoise
{ 0 xdb,0 x70,0 x93 }, // palevioletred
{ 0 xff,0 xef,0 xd5 }, // papayawhip
{ 0 xff,0 xda,0 xb9 }, // peachpuff
{ 0 xcd,0 x85,0 x3f }, // peru
{ 0 xff,0 xc0,0 xcb }, // pink
{ 0 xdd,0 xa0,0 xdd }, // plum
{ 0 xb0,0 xe0,0 xe6 }, // powderblue
{ 0 x80,0 x00,0 x80 }, // purple
{ 0 xff,0 x00,0 x00 }, // red
{ 0 xbc,0 x8f,0 x8f }, // rosybrown
{ 0 x41,0 x69,0 xe1 }, // royalblue
{ 0 x8b,0 x45,0 x13 }, // saddlebrown
{ 0 xfa,0 x80,0 x72 }, // salmon
{ 0 xf4,0 xa4,0 x60 }, // sandybrown
{ 0 x2e,0 x8b,0 x57 }, // seagreen
{ 0 xff,0 xf5,0 xee }, // seashell
{ 0 xa0,0 x52,0 x2d }, // sienna
{ 0 xc0,0 xc0,0 xc0 }, // silver
{ 0 x87,0 xce,0 xeb }, // skyblue
{ 0 x6a,0 x5a,0 xcd }, // slateblue
{ 0 x70,0 x80,0 x90 }, // slategray
{ 0 xff,0 xfa,0 xfa }, // snow
{ 0 x00,0 xff,0 x7f }, // springgreen
{ 0 x46,0 x82,0 xb4 }, // steelblue
{ 0 xd2,0 xb4,0 x8c }, // tan
{ 0 x00,0 x80,0 x80 }, // teal
{ 0 xd8,0 xbf,0 xd8 }, // thistle
{ 0 xff,0 x63,0 x47 }, // tomato
{ 0 x40,0 xe0,0 xd0 }, // turquoise
{ 0 xee,0 x82,0 xee }, // violet
{ 0 xf5,0 xde,0 xb3 }, // wheat
{ 0 xff,0 xff,0 xff }, // white
{ 0 xf5,0 xf5,0 xf5 }, // whitesmoke
{ 0 xff,0 xff,0 x00 }, // yellow
{ 0 x9a,0 xcd,0 x32 }, // yellowgreen
};
const char * SkParse::FindNamedColor(const char * name, size_t len, SkColor* color) {
const auto rec = std::lower_bound(std::begin(gColorNames),
std::end (gColorNames),
name, // key
[](const char * name, const char * key) {
return strcmp(name, key) < 0 ;
});
if (rec == std::end(gColorNames) || 0 != strcmp(name, *rec)) {
return nullptr;
}
if (color) {
int index = rec - gColorNames;
*color = SkColorSetRGB(gColors[index].r, gColors[index].g, gColors[index].b);
}
return name + strlen(*rec);
}
// !!! move to char utilities
//static int count_separators(const char* str, const char* sep) {
// char c;
// int separators = 0;
// while ((c = *str++) != '\0') {
// if (strchr(sep, c) == nullptr)
// continue;
// do {
// if ((c = *str++) == '\0')
// goto goHome;
// } while (strchr(sep, c) != nullptr);
// separators++;
// }
//goHome:
// return separators;
//}
static inline unsigned nib2byte(unsigned n)
{
SkASSERT((n & ~0 xF) == 0 );
return (n << 4 ) | n;
}
const char * SkParse::FindColor(const char * value, SkColor* colorPtr) {
unsigned int oldAlpha = SkColorGetA(*colorPtr);
if (value[0 ] == '#' ) {
uint32_t hex;
const char * end = SkParse::FindHex(value + 1 , &hex);
// SkASSERT(end);
if (end == nullptr)
return end;
size_t len = end - value - 1 ;
if (len == 3 || len == 4 ) {
unsigned a = len == 4 ? nib2byte(hex >> 12 ) : oldAlpha;
unsigned r = nib2byte((hex >> 8 ) & 0 xF);
unsigned g = nib2byte((hex >> 4 ) & 0 xF);
unsigned b = nib2byte(hex & 0 xF);
*colorPtr = SkColorSetARGB(a, r, g, b);
return end;
} else if (len == 6 || len == 8 ) {
if (len == 6 )
hex |= oldAlpha << 24 ;
*colorPtr = hex;
return end;
} else {
// SkASSERT(0);
return nullptr;
}
// } else if (strchr(value, ',')) {
// SkScalar array[4];
// int count = count_separators(value, ",") + 1; // !!! count commas, add 1
// SkASSERT(count == 3 || count == 4);
// array[0] = SK_Scalar1 * 255;
// const char* end = SkParse::FindScalars(value, &array[4 - count], count);
// if (end == nullptr)
// return nullptr;
// !!! range check for errors?
// *colorPtr = SkColorSetARGB(SkScalarRoundToInt(array[0]), SkScalarRoundToInt(array[1]),
// SkScalarRoundToInt(array[2]), SkScalarRoundToInt(array[3]));
// return end;
} else
return FindNamedColor(value, strlen(value), colorPtr);
}
Messung V0.5 in Prozent C=91 H=93 G=91
¤ Dauer der Verarbeitung: 0.21 Sekunden
(vorverarbeitet am 2026-06-04)
¤
*© Formatika GbR, Deutschland