summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFelipe Corr??a da Silva Sanches <juca@members.fsf.org>2009-12-06 08:00:44 +0000
committerFelipe C. da S. Sanches <juca@members.fsf.org>2009-12-06 08:00:44 +0000
commit2e19b78376f047bbde8eda750522d7250b05cdc6 (patch)
treec93ca0dd6a9d1a72eaddeb4098bedde6d20af494 /src
parentadded an icon to the color picker dialog to alert when there is too much ink ... (diff)
downloadinkscape-2e19b78376f047bbde8eda750522d7250b05cdc6.tar.gz
inkscape-2e19b78376f047bbde8eda750522d7250b05cdc6.zip
* infrastructure to store device colors as described in http://www.w3.org/TR/2009/WD-SVGColor12-20091001/#device
* related to https://bugs.launchpad.net/inkscape/+bug/444021 (bzr r8871)
Diffstat (limited to 'src')
-rw-r--r--src/color.cpp58
-rw-r--r--src/color.h2
-rw-r--r--src/style.cpp12
-rw-r--r--src/svg/svg-color.cpp107
-rw-r--r--src/svg/svg-color.h3
-rw-r--r--src/svg/svg-device-color.h26
6 files changed, 202 insertions, 6 deletions
diff --git a/src/color.cpp b/src/color.cpp
index b16d9950f..abaab6310 100644
--- a/src/color.cpp
+++ b/src/color.cpp
@@ -17,6 +17,7 @@
#include <math.h>
#include "color.h"
#include "svg/svg-icc-color.h"
+#include "svg/svg-device-color.h"
#include "svg/svg-color.h"
#include "svg/css-ostringstream.h"
@@ -29,7 +30,8 @@ static bool profileMatches( SVGICCColor const* first, SVGICCColor const* second
#define PROFILE_EPSILON 0.00000001
SPColor::SPColor() :
- icc(0)
+ icc(0),
+ device(0)
{
v.c[0] = 0;
v.c[1] = 0;
@@ -37,19 +39,22 @@ SPColor::SPColor() :
}
SPColor::SPColor( SPColor const& other ) :
- icc(0)
+ icc(0),
+ device(0)
{
*this = other;
}
SPColor::SPColor( float r, float g, float b ) :
- icc(0)
+ icc(0),
+ device(0)
{
set( r, g, b );
}
SPColor::SPColor( guint32 value ) :
- icc(0)
+ icc(0),
+ device(0)
{
set( value );
}
@@ -57,20 +62,29 @@ SPColor::SPColor( guint32 value ) :
SPColor::~SPColor()
{
delete icc;
+ delete device;
icc = 0;
+ device = 0;
}
SPColor& SPColor::operator= (SPColor const& other)
{
- SVGICCColor* tmp = other.icc ? new SVGICCColor(*other.icc) : 0;
+ SVGICCColor* tmp_icc = other.icc ? new SVGICCColor(*other.icc) : 0;
+ SVGDeviceColor* tmp_device = other.device ? new SVGDeviceColor(*other.device) : 0;
+
v.c[0] = other.v.c[0];
v.c[1] = other.v.c[1];
v.c[2] = other.v.c[2];
if ( icc ) {
delete icc;
}
- icc = tmp;
+ icc = tmp_icc;
+
+ if ( device ) {
+ delete device;
+ }
+ device = tmp_device;
return *this;
}
@@ -86,6 +100,7 @@ bool SPColor::operator == (SPColor const& other) const
&& (v.c[2] != other.v.c[2]);
match &= profileMatches( icc, other.icc );
+//TODO?: match &= devicecolorMatches( device, other.device );
return match;
}
@@ -204,6 +219,37 @@ std::string SPColor::toString() const
css << ')';
}
+ if ( device && device->type != DEVICE_COLOR_INVALID) {
+ if ( !css.str().empty() ) {
+ css << " ";
+ }
+
+ switch(device->type){
+ case DEVICE_GRAY:
+ css << "device-gray(";
+ break;
+ case DEVICE_RGB:
+ css << "device-rgb(";
+ break;
+ case DEVICE_CMYK:
+ css << "device-cmyk(";
+ break;
+ case DEVICE_NCHANNEL:
+ css << "device-nchannel(";
+ break;
+ case DEVICE_COLOR_INVALID:
+ //should not be reached
+ break;
+ }
+
+ for (vector<double>::const_iterator i(device->colors.begin()),
+ iEnd(device->colors.end());
+ i != iEnd; ++i) {
+ css << ", " << *i;
+ }
+ css << ')';
+ }
+
return css.str();
}
diff --git a/src/color.h b/src/color.h
index bebeaec60..7fd351360 100644
--- a/src/color.h
+++ b/src/color.h
@@ -34,6 +34,7 @@
#define SP_RGBA32_F_COMPOSE(r,g,b,a) SP_RGBA32_U_COMPOSE (SP_COLOR_F_TO_U (r), SP_COLOR_F_TO_U (g), SP_COLOR_F_TO_U (b), SP_COLOR_F_TO_U (a))
struct SVGICCColor;
+struct SVGDeviceColor;
/**
* An RGB color with optional icc-color part
@@ -59,6 +60,7 @@ struct SPColor {
std::string toString() const;
SVGICCColor* icc;
+ SVGDeviceColor* device;
union {
float c[3];
} v;
diff --git a/src/style.cpp b/src/style.cpp
index 0b946f348..111018c2a 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -28,6 +28,7 @@
#include "svg/svg.h"
#include "svg/svg-color.h"
#include "svg/svg-icc-color.h"
+#include "svg/svg-device-color.h"
#include "display/canvas-bpath.h"
#include "attributes.h"
@@ -3184,6 +3185,17 @@ sp_style_read_ipaint(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocume
}
paint->value.color.icc = tmp;
}
+ if (strneq(str, "device-gray(", 12) ||
+ strneq(str, "device-rgb(", 11) ||
+ strneq(str, "device-cmyk(", 12) ||
+ strneq(str, "device-nchannel(", 16)) {
+ SVGDeviceColor* tmp = new SVGDeviceColor();
+ if ( ! sp_svg_read_device_color( str, &str, tmp ) ) {
+ delete tmp;
+ tmp = 0;
+ }
+ paint->value.color.device = tmp;
+ }
}
}
}
diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp
index d6b33402f..0eaa4431a 100644
--- a/src/svg/svg-color.cpp
+++ b/src/svg/svg-color.cpp
@@ -35,6 +35,7 @@
#include "preferences.h"
#include "svg-color.h"
#include "svg-icc-color.h"
+#include "svg-device-color.h"
#if ENABLE_LCMS
#include <lcms.h>
@@ -604,6 +605,112 @@ bool sp_svg_read_icc_color( gchar const *str, SVGICCColor* dest )
return sp_svg_read_icc_color(str, NULL, dest);
}
+bool sp_svg_read_device_color( gchar const *str, gchar const **end_ptr, SVGDeviceColor* dest)
+{
+ bool good = true;
+ unsigned int max_colors;
+
+ if ( end_ptr ) {
+ *end_ptr = str;
+ }
+ if ( dest ) {
+ dest->colors.clear();
+ }
+
+ if ( !str ) {
+ // invalid input
+ good = false;
+ } else {
+ while ( g_ascii_isspace(*str) ) {
+ str++;
+ }
+
+ dest->type = DEVICE_COLOR_INVALID;
+ if (strneq( str, "device-gray(", 12 )){
+ dest->type = DEVICE_GRAY;
+ max_colors=1;
+ str += 12;
+ }
+
+ if (strneq( str, "device-rgb(", 11 )){
+ dest->type = DEVICE_RGB;
+ max_colors=3;
+ str += 11;
+ }
+
+ if (strneq( str, "device-cmyk(", 12 )){
+ dest->type = DEVICE_CMYK;
+ max_colors=4;
+ str += 12;
+ }
+
+ if (strneq( str, "device-nchannel(", 16 )){
+ dest->type = DEVICE_NCHANNEL;
+ max_colors=0;
+ str += 16;
+ }
+
+ if ( dest->type != DEVICE_COLOR_INVALID ) {
+ while ( g_ascii_isspace(*str) ) {
+ str++;
+ }
+
+ while ( *str && *str != ')' ) {
+ if ( g_ascii_isdigit(*str) || *str == '.' || *str == '-' || *str == '+') {
+ gchar* endPtr = 0;
+ gdouble dbl = g_ascii_strtod( str, &endPtr );
+ if ( !errno ) {
+ if ( dest ) {
+ dest->colors.push_back( dbl );
+g_message("color: %f", dbl);
+ }
+ str = endPtr;
+ } else {
+ good = false;
+ break;
+ }
+
+ while ( g_ascii_isspace(*str) || *str == ',' ) {
+ str++;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ // We need to have ended on a closing parenthesis
+ if ( good ) {
+ while ( g_ascii_isspace(*str) ) {
+ str++;
+ }
+ good &= (*str == ')');
+ }
+ }
+
+ if ( dest->colors.size() == 0) good=false;
+ if ( dest->type != DEVICE_NCHANNEL && (dest->colors.size() != max_colors)) good=false;
+
+ if ( good ) {
+ if ( end_ptr ) {
+ *end_ptr = str;
+ }
+ } else {
+ if ( dest ) {
+ dest->type = DEVICE_COLOR_INVALID;
+ dest->colors.clear();
+ }
+ }
+
+ return good;
+}
+
+
+bool sp_svg_read_device_color( gchar const *str, SVGDeviceColor* dest)
+{
+ return sp_svg_read_device_color(str, NULL, dest);
+}
+
/*
Local Variables:
mode:c++
diff --git a/src/svg/svg-color.h b/src/svg/svg-color.h
index a3868c149..f4e534652 100644
--- a/src/svg/svg-color.h
+++ b/src/svg/svg-color.h
@@ -4,6 +4,7 @@
#include <glib/gtypes.h>
class SVGICCColor;
+class SVGDeviceColor;
guint32 sp_svg_read_color(gchar const *str, unsigned int dfl);
guint32 sp_svg_read_color(gchar const *str, gchar const **end_ptr, guint32 def);
@@ -11,6 +12,8 @@ void sp_svg_write_color(char *buf, unsigned int buflen, unsigned int rgba32);
bool sp_svg_read_icc_color( gchar const *str, gchar const **end_ptr, SVGICCColor* dest );
bool sp_svg_read_icc_color( gchar const *str, SVGICCColor* dest );
+bool sp_svg_read_device_color( gchar const *str, gchar const **end_ptr, SVGDeviceColor* dest );
+bool sp_svg_read_device_color( gchar const *str, SVGDeviceColor* dest );
void icc_color_to_sRGB(SVGICCColor* dest, guchar* r, guchar* g, guchar* b);
#endif /* !SVG_SVG_COLOR_H_SEEN */
diff --git a/src/svg/svg-device-color.h b/src/svg/svg-device-color.h
new file mode 100644
index 000000000..305133ed3
--- /dev/null
+++ b/src/svg/svg-device-color.h
@@ -0,0 +1,26 @@
+#ifndef SVG_DEVICE_COLOR_H_SEEN
+#define SVG_DEVICE_COLOR_H_SEEN
+
+#include <string>
+#include <vector>
+
+typedef enum {DEVICE_COLOR_INVALID, DEVICE_GRAY, DEVICE_RGB, DEVICE_CMYK, DEVICE_NCHANNEL} SVGDeviceColorType;
+
+struct SVGDeviceColor {
+ SVGDeviceColorType type;
+ std::vector<double> colors;
+};
+
+
+#endif /* !SVG_DEVICE_COLOR_H_SEEN */
+
+/*
+ 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 :