summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/2geom/sbasis-to-bezier.cpp18
-rw-r--r--src/attributes-test.h34
-rw-r--r--src/desktop-style.cpp95
-rw-r--r--src/desktop-style.h2
-rw-r--r--src/display/drawing-text.cpp3
-rw-r--r--src/extension/CMakeLists.txt22
-rw-r--r--src/extension/internal/cairo-render-context.cpp17
-rw-r--r--src/extension/internal/emf-print.cpp8
-rw-r--r--src/extension/internal/filter/color.h2
-rw-r--r--src/extension/internal/text_reassemble.c12
-rw-r--r--src/extension/internal/wmf-inout.cpp6
-rw-r--r--src/extension/internal/wmf-print.cpp4
-rw-r--r--src/extension/param/color.cpp71
-rw-r--r--src/extension/param/color.h9
-rw-r--r--src/extension/param/parameter.cpp7
-rw-r--r--src/knot-holder-entity.cpp18
-rw-r--r--src/libnrtype/font-lister.cpp2
-rw-r--r--src/libuemf/uemf.h11
-rw-r--r--src/libuemf/uemf_print.c48
-rw-r--r--src/libuemf/uemf_print.h7
-rw-r--r--src/libuemf/upmf.c12
-rw-r--r--src/libuemf/upmf_print.c21
-rw-r--r--src/libuemf/upmf_print.h6
-rw-r--r--src/libuemf/uwmf.c42
-rw-r--r--src/libuemf/uwmf.h10
-rw-r--r--src/libuemf/uwmf_endian.c20
-rw-r--r--src/libuemf/uwmf_endian.h8
-rw-r--r--src/libuemf/uwmf_print.c25
-rw-r--r--src/live_effects/effect.cpp3
-rw-r--r--src/live_effects/effect.h1
-rw-r--r--src/live_effects/lpe-fillet-chamfer.cpp7
-rw-r--r--src/live_effects/lpe-fillet-chamfer.h1
-rw-r--r--src/live_effects/lpe-roughen.cpp22
-rw-r--r--src/live_effects/lpe-roughen.h2
-rw-r--r--src/live_effects/parameter/filletchamferpointarray.cpp12
-rw-r--r--src/live_effects/parameter/filletchamferpointarray.h4
-rw-r--r--src/rdf.cpp14
-rw-r--r--src/selection-chemistry.cpp164
-rw-r--r--src/selection-chemistry.h2
-rw-r--r--src/selection.cpp1
-rw-r--r--src/sp-clippath.cpp9
-rw-r--r--src/sp-clippath.h2
-rw-r--r--src/sp-item.cpp48
-rw-r--r--src/sp-mask.cpp9
-rw-r--r--src/sp-mask.h2
-rw-r--r--src/sp-offset.cpp2
-rw-r--r--src/sp-pattern.cpp649
-rw-r--r--src/sp-pattern.h157
-rw-r--r--src/sp-use.cpp62
-rw-r--r--src/style-enums.h81
-rw-r--r--src/style-internal.cpp252
-rw-r--r--src/style-internal.h71
-rw-r--r--src/style-test.h34
-rw-r--r--src/style.cpp4
-rw-r--r--src/style.h4
-rw-r--r--src/ui/CMakeLists.txt16
-rw-r--r--src/ui/Makefile_insert2
-rw-r--r--src/ui/dialog/layers.cpp12
-rw-r--r--src/ui/dialog/lpe-fillet-chamfer-properties.cpp22
-rw-r--r--src/ui/dialog/lpe-fillet-chamfer-properties.h8
-rw-r--r--src/ui/dialog/object-properties.cpp6
-rw-r--r--src/ui/dialog/objects.cpp33
-rw-r--r--src/ui/dialog/objects.h9
-rw-r--r--src/ui/dialog/tags.cpp2
-rw-r--r--src/ui/dialog/text-edit.cpp29
-rw-r--r--src/ui/dialog/text-edit.h17
-rw-r--r--src/ui/selected-color.cpp163
-rw-r--r--src/ui/selected-color.h96
-rw-r--r--src/ui/widget/Makefile_insert18
-rw-r--r--src/ui/widget/color-entry.cpp114
-rw-r--r--src/ui/widget/color-entry.h54
-rw-r--r--src/ui/widget/color-icc-selector.cpp1079
-rw-r--r--src/ui/widget/color-icc-selector.h78
-rw-r--r--src/ui/widget/color-notebook.cpp379
-rw-r--r--src/ui/widget/color-notebook.h99
-rw-r--r--src/ui/widget/color-picker.cpp70
-rw-r--r--src/ui/widget/color-picker.h8
-rw-r--r--src/ui/widget/color-scales.cpp677
-rw-r--r--src/ui/widget/color-scales.h112
-rw-r--r--src/ui/widget/color-slider.cpp633
-rw-r--r--src/ui/widget/color-slider.h110
-rw-r--r--src/ui/widget/color-wheel-selector.cpp302
-rw-r--r--src/ui/widget/color-wheel-selector.h101
-rw-r--r--src/ui/widget/font-variants.cpp512
-rw-r--r--src/ui/widget/font-variants.h152
-rw-r--r--src/verbs.cpp36
-rw-r--r--src/widgets/CMakeLists.txt10
-rw-r--r--src/widgets/Makefile_insert10
-rw-r--r--src/widgets/fill-style.cpp10
-rw-r--r--src/widgets/gradient-selector.cpp4
-rw-r--r--src/widgets/gradient-vector.cpp82
-rw-r--r--src/widgets/paint-selector.cpp128
-rw-r--r--src/widgets/paint-selector.h19
-rw-r--r--src/widgets/sp-color-icc-selector.cpp1113
-rw-r--r--src/widgets/sp-color-icc-selector.h72
-rw-r--r--src/widgets/sp-color-notebook.cpp826
-rw-r--r--src/widgets/sp-color-notebook.h120
-rw-r--r--src/widgets/sp-color-scales.cpp760
-rw-r--r--src/widgets/sp-color-scales.h102
-rw-r--r--src/widgets/sp-color-selector.cpp7
-rw-r--r--src/widgets/sp-color-selector.h8
-rw-r--r--src/widgets/sp-color-slider.cpp749
-rw-r--r--src/widgets/sp-color-slider.h60
-rw-r--r--src/widgets/sp-color-wheel-selector.cpp348
-rw-r--r--src/widgets/sp-color-wheel-selector.h82
-rw-r--r--src/widgets/swatch-selector.cpp106
-rw-r--r--src/widgets/swatch-selector.h12
107 files changed, 6396 insertions, 5340 deletions
diff --git a/src/2geom/sbasis-to-bezier.cpp b/src/2geom/sbasis-to-bezier.cpp
index fe7bbc91c..dfd07d84c 100644
--- a/src/2geom/sbasis-to-bezier.cpp
+++ b/src/2geom/sbasis-to-bezier.cpp
@@ -239,6 +239,8 @@ void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb)
midx = 8*midx - 4*bz[0][X] - 4*bz[3][X]; // re-define relative to center
midy = 8*midy - 4*bz[0][Y] - 4*bz[3][Y];
+ if ((std::abs(midx) < EPSILON) && (std::abs(midy) < EPSILON))
+ return;
if ((std::abs(xprime[0]) < EPSILON) && (std::abs(yprime[0]) < EPSILON)
&& ((std::abs(xprime[1]) > EPSILON) || (std::abs(yprime[1]) > EPSILON))) { // degenerate handle at 0 : use distance of closest approach
@@ -258,11 +260,15 @@ void sbasis_to_cubic_bezier (std::vector<Point> & bz, D2<SBasis> const& sb)
dely[1] = 0;
} else if (std::abs(xprime[1]*yprime[0] - yprime[1]*xprime[0]) > // general case : fit mid fxn value
0.002 * std::abs(xprime[1]*xprime[0] + yprime[1]*yprime[0])) { // approx. 0.1 degree of angle
- denom = 3.0*(xprime[1]*yprime[0] - yprime[1]*xprime[0]);
+ double test1 = (bz[1][Y] - bz[0][Y])*(bz[3][X] - bz[0][X]) - (bz[1][X] - bz[0][X])*(bz[3][Y] - bz[0][Y]);
+ double test2 = (bz[2][Y] - bz[0][Y])*(bz[3][X] - bz[0][X]) - (bz[2][X] - bz[0][X])*(bz[3][Y] - bz[0][Y]);
+ if (test1*test2 < 0) // reject anti-symmetric case, LP Bug 1428267 & Bug 1428683
+ return;
+ denom = xprime[1]*yprime[0] - yprime[1]*xprime[0];
for (int i = 0; i < 2; ++i) {
numer = xprime[1 - i]*midy - yprime[1 - i]*midx;
- delx[i] = xprime[i]*numer/denom;
- dely[i] = yprime[i]*numer/denom;
+ delx[i] = xprime[i]*numer/denom/3;
+ dely[i] = yprime[i]*numer/denom/3;
}
} else if ((xprime[0]*xprime[1] < 0) || (yprime[0]*yprime[1] < 0)) { // symmetric case : use distance of closest approach
numer = midx*xprime[0] + midy*yprime[0];
@@ -509,10 +515,10 @@ path_from_sbasis(D2<SBasis> const &B, double tol, bool only_cubicbeziers) {
TODO: some of this logic should be lifted into svg-path
*/
PathVector
-path_from_piecewise(Geom::Piecewise<Geom::D2<Geom::SBasis> > const &B, double tol, bool only_cubicbeziers) {
- Geom::PathBuilder pb;
+path_from_piecewise(Piecewise<D2<SBasis> > const &B, double tol, bool only_cubicbeziers) {
+ PathBuilder pb;
if(B.size() == 0) return pb.peek();
- Geom::Point start = B[0].at0();
+ Point start = B[0].at0();
pb.moveTo(start);
for(unsigned i = 0; ; i++) {
if ( (i+1 == B.size())
diff --git a/src/attributes-test.h b/src/attributes-test.h
index 7379e4e85..411304ec3 100644
--- a/src/attributes-test.h
+++ b/src/attributes-test.h
@@ -40,6 +40,10 @@ public:
I've added these manually.
SVG 2: white-space, shape-inside, shape-outside, shape-padding, shape-margin
+ SVG 2: text-decoration-fill, text-decoration-stroke
+ SVG 2: solid-color, solid-opacity
+ SVG 2: Hatches and Meshes
+ CSS 3: font-variant-xxx, font-feature-settings
*/
struct {char const *attr; bool supported;} const all_attrs[] = {
{"attributeName", true},
@@ -124,11 +128,18 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"flood-color", true},
{"flood-opacity", true},
{"font-family", true},
+ {"font-feature-settings", true},
{"font-size", true},
{"font-size-adjust", true},
{"font-stretch", true},
{"font-style", true},
{"font-variant", true},
+ {"font-variant-ligatures", true},
+ {"font-variant-position", true},
+ {"font-variant-caps", true},
+ {"font-variant-numeric", true},
+ {"font-variant-east-asian", true},
+ {"font-variant-alternates", true},
{"font-weight", true},
{"format", false},
{"from", true},
@@ -288,6 +299,8 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"text-decoration-line", true},
{"text-decoration-style", true},
{"text-decoration-color", true},
+ {"text-decoration-fill", true},
+ {"text-decoration-stroke", true},
{"text-indent", true},
{"text-rendering", true},
{"text-transform", true},
@@ -381,8 +394,11 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"inkscape:pageopacity", true},
{"inkscape:pageshadow", true},
{"inkscape:path-effect", true},
+ // SPItem
{"inkscape:transform-center-x", true},
{"inkscape:transform-center-y", true},
+ {"inkscape:highlight-color", true},
+ // Namedview
{"inkscape:zoom", true},
{"inkscape:cx", true},
{"inkscape:cy", true},
@@ -392,6 +408,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"inkscape:window-y", true},
{"inkscape:window-maximized", true},
{"inkscape:current-layer", true},
+ // Connector tool
{"inkscape:connector-type", true},
{"inkscape:connection-start", true},
{"inkscape:connection-end", true},
@@ -401,10 +418,12 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"inkscape:connector-curvature", true},
{"inkscape:connector-avoid", true},
{"inkscape:connector-spacing", true},
+ // Ellipse, Spiral, Star
{"sodipodi:cx", true},
{"sodipodi:cy", true},
{"sodipodi:rx", true},
{"sodipodi:ry", true},
+ // Box tool
{"inkscape:perspectiveID", true},
{"inkscape:corner0", true},
{"inkscape:corner7", true},
@@ -414,6 +433,7 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"inkscape:vp_y", true},
{"inkscape:vp_z", true},
{"inkscape:persp3d-origin", true},
+ // Star tool
{"sodipodi:start", true},
{"sodipodi:end", true},
{"sodipodi:open", true},
@@ -446,9 +466,19 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"inkscape:layoutOptions", true},
{"osb:paint", true},
+ /* SPSolidColor" */
+ {"solid-color", true},
+ {"solid-opacity", true},
+
/* SPMeshPatch */
{"tensor", true},
+ /* SPHash */
+ {"hatchUnits", true},
+ {"hatchContentUnits", true},
+ {"hatchTransform", true},
+ {"pitch", true},
+
/* SPNamedView */
{"fit-margin-top", true},
{"fit-margin-left", true},
@@ -485,8 +515,10 @@ struct {char const *attr; bool supported;} const all_attrs[] = {
{"pagecolor", true},
/* SPGuide */
- {"position", true}
+ {"position", true},
+ /* SPTag */
+ {"inkscape:expanded", true}
};
diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp
index afdc3064a..d2109c03c 100644
--- a/src/desktop-style.cpp
+++ b/src/desktop-style.cpp
@@ -576,8 +576,8 @@ objects_query_fillstroke (const std::vector<SPItem*> &objects, SPStyle *style_re
return QUERY_STYLE_MULTIPLE_DIFFERENT; // different kind of server
}
- SPPattern *pat = pattern_getroot (pattern);
- SPPattern *pat_res = pattern_getroot (pattern_res);
+ SPPattern *pat = SP_PATTERN (server)->rootPattern();
+ SPPattern *pat_res = SP_PATTERN (server_res)->rootPattern();
if (pat_res != pat) {
return QUERY_STYLE_MULTIPLE_DIFFERENT; // different pattern roots
}
@@ -1168,6 +1168,94 @@ objects_query_fontstyle (const std::vector<SPItem*> &objects, SPStyle *style_res
}
}
+int
+objects_query_fontvariants (const std::vector<SPItem*> &objects, SPStyle *style_res)
+{
+ bool set = false;
+
+ int texts = 0;
+
+ SPILigatures* ligatures_res = &(style_res->font_variant_ligatures);
+ SPIEnum* position_res = &(style_res->font_variant_position);
+ SPIEnum* caps_res = &(style_res->font_variant_caps);
+ SPINumeric* numeric_res = &(style_res->font_variant_numeric);
+
+ // Stores 'and' of all values
+ ligatures_res->computed = SP_CSS_FONT_VARIANT_LIGATURES_NORMAL;
+ position_res->computed = SP_CSS_FONT_VARIANT_POSITION_NORMAL;
+ caps_res->computed = SP_CSS_FONT_VARIANT_CAPS_NORMAL;
+ numeric_res->computed = SP_CSS_FONT_VARIANT_NUMERIC_NORMAL;
+
+ // Stores only differences
+ ligatures_res->value = 0;
+ position_res->value = 0;
+ caps_res->value = 0;
+ numeric_res->value = 0;
+
+ for (std::vector<SPItem*>::const_iterator i = objects.begin(); i != objects.end(); i++) {
+ SPObject *obj = *i;
+
+ if (!isTextualItem(obj)) {
+ continue;
+ }
+
+ SPStyle *style = obj->style;
+ if (!style) {
+ continue;
+ }
+
+ texts ++;
+
+ SPILigatures* ligatures_in = &(style->font_variant_ligatures);
+ SPIEnum* position_in = &(style->font_variant_position);
+ SPIEnum* caps_in = &(style->font_variant_caps);
+ SPINumeric* numeric_in = &(style->font_variant_numeric);
+ // computed stores which bits are on/off, only valid if same between all selected objects.
+ // value stores which bits are different between objects. This is a bit of an abuse of
+ // the values but then we don't need to add new variables to class.
+ if (set) {
+ ligatures_res->value |= (ligatures_res->computed ^ ligatures_in->computed );
+ ligatures_res->computed &= ligatures_in->computed;
+
+ position_res->value |= (position_res->computed ^ position_in->computed );
+ position_res->computed &= position_in->computed;
+
+ caps_res->value |= (caps_res->computed ^ caps_in->computed );
+ caps_res->computed &= caps_in->computed;
+
+ numeric_res->value |= (numeric_res->computed ^ numeric_in->computed );
+ numeric_res->computed &= numeric_in->computed;
+
+ } else {
+ ligatures_res->computed = ligatures_in->computed;
+ position_res->computed = position_in->computed;
+ caps_res->computed = caps_in->computed;
+ numeric_res->computed = numeric_in->computed;
+ }
+
+ set = true;
+ }
+
+ bool different = (style_res->font_variant_ligatures.value != 0 ||
+ style_res->font_variant_position.value != 0 ||
+ style_res->font_variant_caps.value != 0 ||
+ style_res->font_variant_numeric.value != 0 );
+
+ if (texts == 0 || !set)
+ return QUERY_STYLE_NOTHING;
+
+ if (texts > 1) {
+ if (different) {
+ return QUERY_STYLE_MULTIPLE_DIFFERENT;
+ } else {
+ return QUERY_STYLE_MULTIPLE_SAME;
+ }
+ } else {
+ return QUERY_STYLE_SINGLE;
+ }
+}
+
+
/**
* Write to style_res the baseline numbers.
*/
@@ -1577,6 +1665,8 @@ sp_desktop_query_style_from_list (const std::vector<SPItem*> &list, SPStyle *sty
return objects_query_fontfamily (list, style);
} else if (property == QUERY_STYLE_PROPERTY_FONTSTYLE) {
return objects_query_fontstyle (list, style);
+ } else if (property == QUERY_STYLE_PROPERTY_FONTVARIANTS) {
+ return objects_query_fontvariants (list, style);
} else if (property == QUERY_STYLE_PROPERTY_FONTNUMBERS) {
return objects_query_fontnumbers (list, style);
} else if (property == QUERY_STYLE_PROPERTY_BASELINES) {
@@ -1598,6 +1688,7 @@ sp_desktop_query_style_from_list (const std::vector<SPItem*> &list, SPStyle *sty
int
sp_desktop_query_style(SPDesktop *desktop, SPStyle *style, int property)
{
+ // Used by text tool and in gradient dragging
int ret = desktop->_query_style_signal.emit(style, property);
if (ret != QUERY_STYLE_NOTHING)
diff --git a/src/desktop-style.h b/src/desktop-style.h
index a72f49776..e5fe50440 100644
--- a/src/desktop-style.h
+++ b/src/desktop-style.h
@@ -47,6 +47,7 @@ enum { // which property was queried (add when you need more)
QUERY_STYLE_PROPERTY_FONT_SPECIFICATION, //-inkscape-font-specification
QUERY_STYLE_PROPERTY_FONTFAMILY, // font-family
QUERY_STYLE_PROPERTY_FONTSTYLE, // font style
+ QUERY_STYLE_PROPERTY_FONTVARIANTS, // font variants (OpenType features)
QUERY_STYLE_PROPERTY_FONTNUMBERS, // size, spacings
QUERY_STYLE_PROPERTY_BASELINES, // baseline-shift
QUERY_STYLE_PROPERTY_MASTEROPACITY, // opacity
@@ -71,6 +72,7 @@ int objects_query_fillstroke (const std::vector<SPItem*> &objects, SPStyle *styl
int objects_query_fontnumbers (const std::vector<SPItem*> &objects, SPStyle *style_res);
int objects_query_fontstyle (const std::vector<SPItem*> &objects, SPStyle *style_res);
int objects_query_fontfamily (const std::vector<SPItem*> &objects, SPStyle *style_res);
+int objects_query_fontvariants (const std::vector<SPItem*> &objects, SPStyle *style_res);
int objects_query_opacity (const std::vector<SPItem*> &objects, SPStyle *style_res);
int objects_query_strokewidth (const std::vector<SPItem*> &objects, SPStyle *style_res);
int objects_query_miterlimit (const std::vector<SPItem*> &objects, SPStyle *style_res);
diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp
index e20a7ff2a..3928ad796 100644
--- a/src/display/drawing-text.cpp
+++ b/src/display/drawing-text.cpp
@@ -367,7 +367,7 @@ void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphas
/* returns scaled line thickness */
void DrawingText::decorateItem(DrawingContext &dc, double phase_length, bool under)
{
- if (_nrstyle.font_size < 1.0e-32)return; // would cause a divide by zero and nothing would be visible anyway
+ if ( _nrstyle.font_size <= 1.0e-32 )return; // might cause a divide by zero or overflow and nothing would be visible anyway
double tsp_width_adj = _nrstyle.tspan_width / _nrstyle.font_size;
double tsp_asc_adj = _nrstyle.ascender / _nrstyle.font_size;
double tsp_size_adj = (_nrstyle.ascender + _nrstyle.descender) / _nrstyle.font_size;
@@ -381,6 +381,7 @@ void DrawingText::decorateItem(DrawingContext &dc, double phase_length, bool und
Geom::Point p2;
// All lines must be the same thickness, in combinations, line_through trumps underline
double thickness = final_underline_thickness;
+ if ( thickness <= 1.0e-32 )return; // might cause a divide by zero or overflow and nothing would be visible anyway
dc.setTolerance(0.5); // Is this really necessary... could effect dots.
if( under ) {
diff --git a/src/extension/CMakeLists.txt b/src/extension/CMakeLists.txt
index d1104f3cc..21e652563 100644
--- a/src/extension/CMakeLists.txt
+++ b/src/extension/CMakeLists.txt
@@ -36,7 +36,6 @@ set(extension_SRC
internal/cairo-render-context.cpp
internal/cairo-renderer.cpp
internal/cairo-renderer-pdf-out.cpp
- internal/cdr-input.cpp
internal/emf-inout.cpp
internal/emf-print.cpp
internal/gdkpixbuf-input.cpp
@@ -54,10 +53,8 @@ set(extension_SRC
internal/svg.cpp
internal/svgz.cpp
internal/text_reassemble.c
- internal/vsd-input.cpp
internal/wmf-inout.cpp
internal/wmf-print.cpp
- internal/wpg-input.cpp
internal/filter/filter-all.cpp
internal/filter/filter-file.cpp
@@ -104,7 +101,6 @@ set(extension_SRC
internal/cairo-render-context.h
internal/cairo-renderer-pdf-out.h
internal/cairo-renderer.h
- internal/cdr-input.h
internal/clear-n_.h
internal/emf-inout.h
internal/emf-print.h
@@ -140,10 +136,8 @@ set(extension_SRC
internal/svg.h
internal/svgz.h
internal/text_reassemble.h
- internal/vsd-input.h
internal/wmf-inout.h
internal/wmf-print.h
- internal/wpg-input.h
)
if(WIN32)
@@ -151,6 +145,20 @@ if(WIN32)
)
endif()
+if(WITH_LIBCDR)
+ list(APPEND extension_SRC
+ internal/cdr-input.cpp
+ internal/cdr-input.h
+ )
+endif()
+
+if(WITH_LIBVISIO)
+ list(APPEND extension_SRC
+ internal/vsd-input.cpp
+ internal/vsd-input.h
+ )
+endif()
+
if(WITH_LIBWPG)
list(APPEND extension_SRC
internal/wpg-input.cpp
@@ -158,7 +166,7 @@ if(WITH_LIBWPG)
)
endif()
-if(ImageMagick_FOUND)
+if(WITH_IMAGE_MAGICK)
list(APPEND extension_SRC
internal/bitmap/adaptiveThreshold.cpp
internal/bitmap/adaptiveThreshold.h
diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp
index 27e34dbcf..c3e416184 100644
--- a/src/extension/internal/cairo-render-context.cpp
+++ b/src/extension/internal/cairo-render-context.cpp
@@ -1008,17 +1008,16 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
ps2user = Geom::identity();
pcs2dev = Geom::identity();
- double x = pattern_x(pat);
- double y = pattern_y(pat);
- double width = pattern_width(pat);
- double height = pattern_height(pat);
+ double x = pat->x();
+ double y = pat->y();
+ double width = pat->width();
+ double height = pat->height();
double bbox_width_scaler;
double bbox_height_scaler;
TRACE(("%f x %f pattern\n", width, height));
- if (pbox && pattern_patternUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
- //Geom::Affine bbox2user (pbox->x1 - pbox->x0, 0.0, 0.0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0);
+ if (pbox && pat->patternUnits() == SPPattern::UNITS_OBJECTBOUNDINGBOX) {
bbox_width_scaler = pbox->width();
bbox_height_scaler = pbox->height();
ps2user[4] = x * bbox_width_scaler + pbox->left();
@@ -1031,13 +1030,13 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
}
// apply pattern transformation
- Geom::Affine pattern_transform(pattern_patternTransform(pat));
+ Geom::Affine pattern_transform(pat->getTransform());
ps2user *= pattern_transform;
Geom::Point ori (ps2user[4], ps2user[5]);
// create pattern contents coordinate system
if (pat->viewBox_set) {
- Geom::Rect view_box = *pattern_viewBox(pat);
+ Geom::Rect view_box = *pat->viewbox();
double x, y, w, h;
x = 0;
@@ -1050,7 +1049,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
pcs2dev[3] = h / view_box.height();
pcs2dev[4] = x - view_box.left() * pcs2dev[0];
pcs2dev[5] = y - view_box.top() * pcs2dev[3];
- } else if (pbox && pattern_patternContentUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) {
+ } else if (pbox && pat->patternContentUnits() == SPPattern::UNITS_OBJECTBOUNDINGBOX) {
pcs2dev[0] = pbox->width();
pcs2dev[3] = pbox->height();
}
diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp
index 7c514d6e7..5b8aae655 100644
--- a/src/extension/internal/emf-print.cpp
+++ b/src/extension/internal/emf-print.cpp
@@ -388,8 +388,8 @@ int PrintEmf::create_brush(SPStyle const *style, PU_COLORREF fcolor)
} else if (SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style))) { // must be paint-server
SPPaintServer *paintserver = style->fill.value.href->getObject();
SPPattern *pat = SP_PATTERN(paintserver);
- double dwidth = pattern_width(pat);
- double dheight = pattern_height(pat);
+ double dwidth = pat->width();
+ double dheight = pat->height();
width = dwidth;
height = dheight;
brush_classify(pat, 0, &pixbuf, &hatchType, &hatchColor, &bkColor);
@@ -573,8 +573,8 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform)
if (SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style))) { // must be paint-server
SPPaintServer *paintserver = style->stroke.value.href->getObject();
SPPattern *pat = SP_PATTERN(paintserver);
- double dwidth = pattern_width(pat);
- double dheight = pattern_height(pat);
+ double dwidth = pat->width();
+ double dheight = pat->height();
width = dwidth;
height = dheight;
brush_classify(pat, 0, &pixbuf, &hatchType, &hatchColor, &bkColor);
diff --git a/src/extension/internal/filter/color.h b/src/extension/internal/filter/color.h
index c3c26bf8b..b9c76615c 100644
--- a/src/extension/internal/filter/color.h
+++ b/src/extension/internal/filter/color.h
@@ -258,7 +258,7 @@ public:
"<param name=\"type\" gui-text=\"" N_("Blindness type:") "\" type=\"enum\">\n"
"<_item value=\"0.618 0.32 0.062 0 0 0.163 0.775 0.062 0 0 0.163 0.32 0.516 0 0 0 0 0 1 0 \">" N_("Rod monochromacy (atypical achromatopsia)") "</_item>\n"
"<_item value=\"0.299 0.587 0.114 0 0 0.299 0.587 0.114 0 0 0.299 0.587 0.114 0 0 0 0 0 1 0 \">" N_("Cone monochromacy (typical achromatopsia)") "</_item>\n"
- "<_item value=\"0.8 0.2 0 0 0 0.2583 0.74167 0 0 0 0 0.14167 0.85833 0 0 0 0 0 1 0 \">" N_("Geen weak (deuteranomaly)") "</_item>\n"
+ "<_item value=\"0.8 0.2 0 0 0 0.2583 0.74167 0 0 0 0 0.14167 0.85833 0 0 0 0 0 1 0 \">" N_("Green weak (deuteranomaly)") "</_item>\n"
"<_item value=\"0.625 0.375 0 0 0 0.7 0.3 0 0 0 0 0.3 0.7 0 0 0 0 0 1 0 \">" N_("Green blind (deuteranopia)") "</_item>\n"
"<_item value=\"0.8166 0.1833 0 0 0 0.333 0.666 0 0 0 0 0.125 0.875 0 0 0 0 0 1 0 \">" N_("Red weak (protanomaly)") "</_item>\n"
"<_item value=\"0.566 0.43333 0 0 0 0.55833 0.4416 0 0 0 0 0.24167 0.75833 0 0 0 0 0 1 0 \">" N_("Red blind (protanopia)") "</_item>\n"
diff --git a/src/extension/internal/text_reassemble.c b/src/extension/internal/text_reassemble.c
index d3aafef12..fa983b83d 100644
--- a/src/extension/internal/text_reassemble.c
+++ b/src/extension/internal/text_reassemble.c
@@ -67,8 +67,8 @@ Optional compiler switches for development:
File: text_reassemble.c
-Version: 0.0.16
-Date: 25-FEB-2015
+Version: 0.0.17
+Date: 21-MAY-2015
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2015 David Mathog and California Institute of Technology (Caltech)
@@ -2204,10 +2204,10 @@ void TR_layout_2_svg(TR_INFO *tri){
sprintf(obuf,"text-decoration:");
/* multiple text decoration styles may be set */
utmp = tsp->decoration & TXTDECOR_TMASK;
- if(utmp & TXTDECOR_UNDER ){ strcat(obuf,"underline"); }
- if(utmp & TXTDECOR_OVER ){ strcat(obuf,"overline"); }
- if(utmp & TXTDECOR_BLINK ){ strcat(obuf,"blink"); }
- if(utmp & TXTDECOR_STRIKE){ strcat(obuf,"line-through");}
+ if(utmp & TXTDECOR_UNDER ){ strcat(obuf," underline"); }
+ if(utmp & TXTDECOR_OVER ){ strcat(obuf," overline"); }
+ if(utmp & TXTDECOR_BLINK ){ strcat(obuf," blink"); }
+ if(utmp & TXTDECOR_STRIKE){ strcat(obuf," line-through");}
if(*obuf){
/* only a single text decoration line type may be set */
switch(tsp->decoration & TXTDECOR_LMASK){
diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp
index f76fa16b4..d17180d91 100644
--- a/src/extension/internal/wmf-inout.cpp
+++ b/src/extension/internal/wmf-inout.cpp
@@ -449,7 +449,8 @@ uint32_t Wmf::add_dib_image(PWMF_CALLBACK_DATA d, const char *dib, uint32_t iUsa
char *rgba_px = NULL; // RGBA pixels
const char *px = NULL; // DIB pixels
const U_RGBQUAD *ct = NULL; // DIB color table
- int32_t width, height, colortype, numCt, invert; // if needed these values will be set by wget_DIB_params
+ uint32_t numCt;
+ int32_t width, height, colortype, invert; // if needed these values will be set by wget_DIB_params
if(iUsage == U_DIB_RGB_COLORS){
// next call returns pointers and values, but allocates no memory
dibparams = wget_DIB_params(dib, &px, &ct, &numCt, &width, &height, &colortype, &invert);
@@ -1318,7 +1319,8 @@ void Wmf::common_dib_to_image(PWMF_CALLBACK_DATA d, const char *dib,
char *sub_px = NULL; // RGBA pixels, subarray
const char *px = NULL; // DIB pixels
const U_RGBQUAD *ct = NULL; // color table
- int32_t width, height, colortype, numCt, invert; // if needed these values will be set in wget_DIB_params
+ uint32_t numCt;
+ int32_t width, height, colortype, invert; // if needed these values will be set in wget_DIB_params
if(iUsage == U_DIB_RGB_COLORS){
// next call returns pointers and values, but allocates no memory
dibparams = wget_DIB_params(dib, &px, &ct, &numCt, &width, &height, &colortype, &invert);
diff --git a/src/extension/internal/wmf-print.cpp b/src/extension/internal/wmf-print.cpp
index 127030832..271dec702 100644
--- a/src/extension/internal/wmf-print.cpp
+++ b/src/extension/internal/wmf-print.cpp
@@ -379,8 +379,8 @@ int PrintWmf::create_brush(SPStyle const *style, U_COLORREF *fcolor)
} else if (SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style))) { // must be paint-server
SPPaintServer *paintserver = style->fill.value.href->getObject();
SPPattern *pat = SP_PATTERN(paintserver);
- double dwidth = pattern_width(pat);
- double dheight = pattern_height(pat);
+ double dwidth = pat->width();
+ double dheight = pat->height();
width = dwidth;
height = dheight;
brush_classify(pat, 0, &pixbuf, &hatchType, &hatchColor, &bkColor);
diff --git a/src/extension/param/color.cpp b/src/extension/param/color.cpp
index b774bac83..3162e8a40 100644
--- a/src/extension/param/color.cpp
+++ b/src/extension/param/color.cpp
@@ -24,41 +24,37 @@
#include "color.h"
#include <color.h>
-#include "widgets/sp-color-selector.h"
-#include "widgets/sp-color-notebook.h"
+#include "ui/widget/color-notebook.h"
#include "preferences.h"
-
namespace Inkscape {
namespace Extension {
-void sp_color_param_changed(SPColorSelector *csel, GObject *cp);
-
-
ParamColor::~ParamColor(void)
{
-
+ _color_changed.disconnect();
}
guint32 ParamColor::set( guint32 in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/ )
{
- _value = in;
+ _color_changed.block(true);
+ _color.setValue(in);
+ _color_changed.block(false);
gchar * prefname = this->pref_name();
std::string value;
string(value);
-
+
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setString(extension_pref_root + prefname, value);
g_free(prefname);
- return _value;
+ return in;
}
-ParamColor::ParamColor(const gchar *name, const gchar *guitext, const gchar *desc, const Parameter::_scope_t scope,
- bool gui_hidden, const gchar *gui_tip, Inkscape::Extension::Extension *ext,
- Inkscape::XML::Node *xml)
- : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext), _value(0), _changeSignal(0)
+ParamColor::ParamColor (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext),
+ _changeSignal(0)
{
const char * defaulthex = NULL;
if (xml->firstChild() != NULL)
@@ -72,51 +68,46 @@ ParamColor::ParamColor(const gchar *name, const gchar *guitext, const gchar *des
if (!paramval.empty())
defaulthex = paramval.data();
- if (defaulthex)
- _value = atoi(defaulthex);
+ if (defaulthex) {
+ _color.setValue(atoi(defaulthex));
+ }
+ _color_changed = _color.signal_changed.connect(sigc::mem_fun(this, &ParamColor::_onColorChanged));
+
}
void ParamColor::string(std::string &string) const
{
char str[16];
- sprintf(str, "%i", _value);
+ snprintf(str, 16, "%i", _color.value());
string += str;
}
Gtk::Widget *ParamColor::get_widget( SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal<void> * changeSignal )
{
- if (_gui_hidden) return NULL;
+ using Inkscape::UI::Widget::ColorNotebook;
+
+ if (_gui_hidden) return NULL;
_changeSignal = new sigc::signal<void>(*changeSignal);
- Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
- SPColorSelector* spColorSelector = (SPColorSelector*)sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK);
- ColorSelector* colorSelector = spColorSelector->base;
- if (_value < 1) {
- _value = 0xFF000000;
+ if (_color.value() < 1) {
+ _color_changed.block(true);
+ _color.setValue(0xFF000000);
+ _color_changed.block(false);
}
- SPColor *color = new SPColor( _value );
- float alpha = (_value & 0xff) / 255.0F;
- colorSelector->setColorAlpha(*color, alpha);
-
- hbox->pack_start (*Glib::wrap(&spColorSelector->vbox), true, true, 0);
- g_signal_connect(G_OBJECT(spColorSelector), "changed", G_CALLBACK(sp_color_param_changed), (void*)this);
- gtk_widget_show(GTK_WIDGET(spColorSelector));
+ Gtk::HBox *hbox = Gtk::manage(new Gtk::HBox(false, 4));
+ Gtk::Widget *selector = Gtk::manage(new ColorNotebook(_color));
+ hbox->pack_start (*selector, true, true, 0);
+ selector->show();
hbox->show();
-
- return dynamic_cast<Gtk::Widget *>(hbox);
+ return hbox;
}
-void sp_color_param_changed(SPColorSelector *csel, GObject *obj)
+void ParamColor::_onColorChanged()
{
- const SPColor color = csel->base->getColor();
- float alpha = csel->base->getAlpha();
-
- ParamColor* ptr = reinterpret_cast<ParamColor*>(obj);
- ptr->set(color.toRGBA32( alpha ), NULL, NULL);
-
- ptr->_changeSignal->emit();
+ if (_changeSignal)
+ _changeSignal->emit();
}
}; /* namespace Extension */
diff --git a/src/extension/param/color.h b/src/extension/param/color.h
index 9894965a9..ed2e57ceb 100644
--- a/src/extension/param/color.h
+++ b/src/extension/param/color.h
@@ -9,6 +9,7 @@
*/
#include "parameter.h"
+#include "ui/selected-color.h"
class SPDocument;
@@ -25,14 +26,17 @@ namespace Extension {
class ParamColor : public Parameter {
private:
- guint32 _value;
+ void _onColorChanged();
+
+ Inkscape::UI::SelectedColor _color;
+ sigc::connection _color_changed;
public:
ParamColor(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
virtual ~ParamColor(void);
/** Returns \c _value, with a \i const to protect it. */
- guint32 get( SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/ ) const { return _value; }
+ guint32 get( SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/ ) const { return _color.value(); }
guint32 set (guint32 in, SPDocument * doc, Inkscape::XML::Node * node);
@@ -44,6 +48,7 @@ public:
virtual void string (std::string &string) const;
sigc::signal<void> * _changeSignal;
+
}; // class ParamColor
} // namespace Extension
diff --git a/src/extension/param/parameter.cpp b/src/extension/param/parameter.cpp
index 202b8110f..8c99ee55d 100644
--- a/src/extension/param/parameter.cpp
+++ b/src/extension/param/parameter.cpp
@@ -15,6 +15,10 @@
# include "config.h"
#endif
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#ifdef linux // does the dollar sign need escaping when passed as string parameter?
# define ESCAPE_DOLLAR_COMMANDLINE
#endif
@@ -26,8 +30,7 @@
#include "document-private.h"
#include "sp-object.h"
#include <color.h>
-#include "widgets/sp-color-selector.h"
-#include "widgets/sp-color-notebook.h"
+#include "ui/widget/color-notebook.h"
#include "parameter.h"
#include "bool.h"
diff --git a/src/knot-holder-entity.cpp b/src/knot-holder-entity.cpp
index b66156b09..173025920 100644
--- a/src/knot-holder-entity.cpp
+++ b/src/knot-holder-entity.cpp
@@ -140,19 +140,19 @@ KnotHolderEntity::snap_knot_position_constrained(Geom::Point const &p, Inkscape:
static gdouble sp_pattern_extract_theta(SPPattern const *pat)
{
- Geom::Affine transf = pat->patternTransform;
+ Geom::Affine transf = pat->getTransform();
return Geom::atan2(transf.xAxis());
}
static Geom::Point sp_pattern_extract_scale(SPPattern const *pat)
{
- Geom::Affine transf = pat->patternTransform;
+ Geom::Affine transf = pat->getTransform();
return Geom::Point( transf.expansionX(), transf.expansionY() );
}
static Geom::Point sp_pattern_extract_trans(SPPattern const *pat)
{
- return Geom::Point(pat->patternTransform[4], pat->patternTransform[5]);
+ return Geom::Point(pat->getTransform()[4], pat->getTransform()[5]);
}
void
@@ -191,7 +191,7 @@ PatternKnotHolderEntityAngle::knot_get() const
{
SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer());
- gdouble x = pattern_width(pat);
+ gdouble x = pat->width();
gdouble y = 0;
Geom::Point delta = Geom::Point(x,y);
Geom::Point scale = sp_pattern_extract_scale(pat);
@@ -240,8 +240,8 @@ PatternKnotHolderEntityScale::knot_set(Geom::Point const &p, Geom::Point const &
// Get the new scale from the position of the knotholder
Geom::Point d = p_snapped - sp_pattern_extract_trans(pat);
- gdouble pat_x = pattern_width(pat);
- gdouble pat_y = pattern_height(pat);
+ gdouble pat_x = pat->width();
+ gdouble pat_y = pat->height();
Geom::Scale scl(1);
if ( state & GDK_CONTROL_MASK ) {
// if ctrl is pressed: use 1:1 scaling
@@ -267,10 +267,10 @@ PatternKnotHolderEntityScale::knot_get() const
{
SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer());
- gdouble x = pattern_width(pat);
- gdouble y = pattern_height(pat);
+ gdouble x = pat->width();
+ gdouble y = pat->height();
Geom::Point delta = Geom::Point(x,y);
- Geom::Affine a = pat->patternTransform;
+ Geom::Affine a = pat->getTransform();
a[4] = 0;
a[5] = 0;
delta = delta * a;
diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp
index a6ab3b239..70374864a 100644
--- a/src/libnrtype/font-lister.cpp
+++ b/src/libnrtype/font-lister.cpp
@@ -335,7 +335,7 @@ Glib::ustring FontLister::system_fontspec(Glib::ustring fontspec)
PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str());
font_instance *res = (font_factory::Default())->Face(descr);
- if (res->pFont) {
+ if (res && res->pFont) {
PangoFontDescription *nFaceDesc = pango_font_describe(res->pFont);
out = sp_font_description_get_family(nFaceDesc);
}
diff --git a/src/libuemf/uemf.h b/src/libuemf/uemf.h
index 53426cb55..f6ed7da03 100644
--- a/src/libuemf/uemf.h
+++ b/src/libuemf/uemf.h
@@ -95,8 +95,8 @@ these WMF enumerations is by referencing the following table:
/*
File: uemf.h
-Version: 0.0.31
-Date: 23-APR-2015
+Version: 0.0.32
+Date: 28-APR-2015
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2015 David Mathog and California Institute of Technology (Caltech)
@@ -168,7 +168,12 @@ extern "C" {
#define U_ROUND(A) ( (A) > 0 ? floor((A)+0.5) : ( (A) < 0 ? -floor(-(A)+0.5) : (A) ) )
#define MAKE_MIN_PTR(A,B) ( A < B ? A : B)
-#define IS_MEM_UNSAFE(A,B,C) ( (int8_t *)(A) > (int8_t *)(C) ? 1 : ((int8_t *)(C) - (int8_t *)(A) >= (int)(B) ? 0 : 1 )) //!< Return 1 when a region of memory starting at A of B bytes extends beyond pointer C
+/* This is tricky. The next one can be called with a size which is either an int or an unsigned int.
+ The former can be negative, which is obviously wrong, but testing for that means that the size cannot
+ be more than INT_MAX/2. Accept that limitation since no reasonable EMF record or file should ever be that large.
+ B must be an INT or size_t.
+ If a uint16_t is used gcc complains about the first test. Force B to be at least as big as int (at run time) */
+#define IS_MEM_UNSAFE(A,B,C) ( (sizeof(B) < sizeof(int) || (int)(B)) < 0 ? 1 : ((int8_t *)(A) > (int8_t *)(C) ? 1 : ((int8_t *)(C) - (int8_t *)(A) >= (int)(B) ? 0 : 1 ))) //!< Return 1 when a region of memory starting at A of B bytes extends beyond pointer C
/** @} */
diff --git a/src/libuemf/uemf_print.c b/src/libuemf/uemf_print.c
index adcf54c0f..4bc9f0206 100644
--- a/src/libuemf/uemf_print.c
+++ b/src/libuemf/uemf_print.c
@@ -6,8 +6,8 @@
/*
File: uemf_print.c
-Version: 0.0.18
-Date: 25-MAR-2015
+Version: 0.0.20
+Date: 21-MAY-2015
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2015 David Mathog and California Institute of Technology (Caltech)
@@ -35,6 +35,31 @@ void U_swap4(void *ul, unsigned int count);
//! \endcond
/**
+ \brief calculate a CRC32 value for record
+ \returns CRC32 value calculated for record
+ \param record pointer to the first byte
+ \param Size number of bytes in the record
+
+Code based on example crc32b here:
+ http://www.hackersdelight.org/hdcodetxt/crc.c.txt
+*/
+uint32_t lu_crc32(const char *record, uint32_t Size){
+ const unsigned char *message = record;
+ uint32_t i, j;
+ uint32_t crc, mask;
+
+ crc = 0xFFFFFFFF;
+ for(i=0;i<Size;i++){ // over all bytes
+ crc = crc ^ *message++;
+ for (j = 0; j < 8; j++) { // over all bits
+ mask = -(crc & 1);
+ crc = (crc >> 1) ^ (0xEDB88320 & mask);
+ }
+ }
+ return ~crc;
+}
+
+/**
\brief Print some number of hex bytes
\param buf pointer to the first byte
\param num number of bytes
@@ -45,6 +70,7 @@ void hexbytes_print(uint8_t *buf,unsigned int num){
}
}
+
/* **********************************************************************************************
These functions print standard objects used in the EMR records.
The low level ones do not append EOL.
@@ -2505,7 +2531,7 @@ int U_emf_onerec_print(const char *contents, const char *blimit, int recnum, siz
uint32_t nSize;
uint32_t iType;
const char *record = contents + off;
-
+
if(record < contents)return(-1); // offset wrapped
/* Check that COMMON data in record can be touched without an access violation. If it cannot be
@@ -2514,7 +2540,21 @@ int U_emf_onerec_print(const char *contents, const char *blimit, int recnum, siz
*/
if(!U_emf_record_sizeok(record, blimit, &nSize, &iType, 1))return(-1);
- printf("%-30srecord:%5d type:%-4d offset:%8d rsize:%8d\n",U_emr_names(iType),recnum,iType,(int) off,nSize);
+ uint32_t crc;
+#if U_BYTE_SWAP
+ //This is a Big Endian machine, EMF crc values must be calculated on Little Endian form
+ char *swapbuf=malloc(nSize);
+ if(!swapbuf)return(-1);
+ memcpy(swapbuf,record,nSize);
+ U_emf_endian(swapbuf,nSize,1); // BE to LE
+ crc=lu_crc32(swapbuf,nSize);
+ free(swapbuf);
+#else
+ crc=lu_crc32(record,nSize);
+#endif
+ printf("%-30srecord:%5d type:%-4d offset:%8d rsize:%8d crc32:%8.8X\n",
+ U_emr_names(iType),recnum,iType,(int) off,nSize,crc);
+
fflush(stdout);
/* print the record header before checking further.
diff --git a/src/libuemf/uemf_print.h b/src/libuemf/uemf_print.h
index 6568b4cfa..088a8a302 100644
--- a/src/libuemf/uemf_print.h
+++ b/src/libuemf/uemf_print.h
@@ -6,8 +6,8 @@
/*
File: uemf_print.h
-Version: 0.0.7
-Date: 24-MAR-2015
+Version: 0.0.9
+Date: 21-MAY-2015
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2015 David Mathog and California Institute of Technology (Caltech)
@@ -21,6 +21,9 @@ extern "C" {
#endif
//! \cond
+/* prototypes for miscellaneous */
+uint32_t lu_crc32(const char *record, uint32_t Size);
+
/* prototypes for objects used in EMR records */
void hexbytes_print(uint8_t *buf,unsigned int num);
void colorref_print(U_COLORREF color);
diff --git a/src/libuemf/upmf.c b/src/libuemf/upmf.c
index 7d6349185..2ba818fa4 100644
--- a/src/libuemf/upmf.c
+++ b/src/libuemf/upmf.c
@@ -21,8 +21,8 @@
/*
File: upmf.c
-Version: 0.0.9
-Date: 25-MAR-2015
+Version: 0.0.10
+Date: 27-APR-2015
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2015 David Mathog and California Institute of Technology (Caltech)
@@ -6575,15 +6575,17 @@ int U_PMF_VARPOINTS_get(const char *contents, uint16_t Flags, int Elements, U_PM
}
}
else if(Flags & U_PPF_C){
- for(XFS = YFS = 0.0; Elements; Elements--, pts++){
+ for(XF = YF = 0.0; Elements; Elements--, pts++){
if(!U_PMF_POINT_get(&contents, &XF, &XF, blimit))break; /* this should never happen */
pts->X = XF;
pts->Y = YF;
}
}
else {
- for(XFS = YFS = 0.0; Elements; Elements--, pts++){
- (void) U_PMF_POINTF_get(&contents, &(pts->X), &(pts->Y), blimit);
+ for(XF = YF = 0.0; Elements; Elements--, pts++){
+ (void) U_PMF_POINTF_get(&contents, &XF, &YF, blimit);
+ pts->X = XF;
+ pts->Y = YF;
}
}
if(Elements){ /* some error in the preceding */
diff --git a/src/libuemf/upmf_print.c b/src/libuemf/upmf_print.c
index 7d9598b0d..58ff4edd0 100644
--- a/src/libuemf/upmf_print.c
+++ b/src/libuemf/upmf_print.c
@@ -6,8 +6,8 @@
/*
File: upmf_print.c
-Version: 0.0.5
-Date: 24-MAR-2015
+Version: 0.0.7
+Date: 21-MAY-2015
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2015 David Mathog and California Institute of Technology (Caltech)
@@ -142,7 +142,7 @@ int U_pmf_onerec_print(const char *contents, const char *blimit, int recnum, int
int type = Header.Type & U_PMR_TYPE_MASK; /* strip the U_PMR_RECFLAG bit, leaving the indexable part */
if(type < U_PMR_MIN || type > U_PMR_MAX)return(-1); /* unknown EMF+ record type */
- status = U_PMF_CMN_HDR_print(Header, recnum, off); /* EMF+ part */
+ status = U_PMF_CMN_HDR_print(contents, Header, recnum, off); /* EMF+ part */
/* Buggy EMF+ can set the continue bit and then do something else. In that case, force out the pending
Object. Side effect - clears the pending object. */
@@ -222,14 +222,16 @@ int U_pmf_onerec_print(const char *contents, const char *blimit, int recnum, int
/**
\brief Print data from a U_PMF_CMN_HDR object
\return number of bytes in record, 0 on error
+ \param contents pointer to a buffer holding this EMF+ record
\param Header Header of the record
\param precnum EMF+ record number in file.
\param off Offset in file to the start of this EMF+ record.
common structure present at the beginning of all(*) EMF+ records
*/
-int U_PMF_CMN_HDR_print(U_PMF_CMN_HDR Header, int precnum, int off){
- printf(" %-29srec+:%5d type:%X offset:%8d rsize:%8u dsize:%8u flags:%4.4X\n",
- U_pmr_names(Header.Type &U_PMR_TYPE_MASK),precnum, Header.Type,off,Header.Size,Header.DataSize,Header.Flags);
+int U_PMF_CMN_HDR_print(const char *contents, U_PMF_CMN_HDR Header, int precnum, int off){
+ printf(" %-29srec+:%5d type:%X offset:%8d rsize:%8u dsize:%8u flags:%4.4X crc32:%8.8X\n",
+ U_pmr_names(Header.Type &U_PMR_TYPE_MASK),precnum, Header.Type,off,Header.Size,Header.DataSize,Header.Flags,
+ lu_crc32(contents,Header.Size));
return((int) Header.Size);
}
@@ -1852,7 +1854,12 @@ int U_PMF_TRANSFORMMATRIX_print(const char *contents, const char *blimit){
EMF+ manual 2.2.2.47, Microsoft name: EmfPlusTransformMatrix Object
*/
int U_PMF_TRANSFORMMATRIX2_print(U_PMF_TRANSFORMMATRIX *Tm){
- printf(" Matrix:{%f,%f,%f,%f,%f,%f}", Tm->m11, Tm->m12, Tm->m21, Tm->m22, Tm->dX, Tm->dY);
+ if(Tm){
+ printf(" Matrix:{%f,%f,%f,%f,%f,%f}", Tm->m11, Tm->m12, Tm->m21, Tm->m22, Tm->dX, Tm->dY);
+ }
+ else {
+ printf(" Matrix:(None)");
+ }
return(1);
}
diff --git a/src/libuemf/upmf_print.h b/src/libuemf/upmf_print.h
index fe1c57d60..a25374487 100644
--- a/src/libuemf/upmf_print.h
+++ b/src/libuemf/upmf_print.h
@@ -6,8 +6,8 @@
/*
File: upmf_print.h
-Version: 0.0.4
-Date: 24-MAR-2015
+Version: 0.0.5
+Date: 28-APR-2015
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2015 David Mathog and California Institute of Technology (Caltech)
@@ -23,7 +23,7 @@ extern "C" {
#include "upmf.h" /* includes uemf.h */
/* prototypes for simple types and enums used in PMR records */
-int U_PMF_CMN_HDR_print(U_PMF_CMN_HDR Header, int precnum, int off);
+int U_PMF_CMN_HDR_print(const char *contents, U_PMF_CMN_HDR Header, int precnum, int off);
int U_PMF_UINT8_ARRAY_print(const char *Start, const uint8_t *Array, int Elements, char *End);
int U_PMF_BRUSHTYPEENUMERATION_print(int otype);
int U_PMF_HATCHSTYLEENUMERATION_print(int hstype);
diff --git a/src/libuemf/uwmf.c b/src/libuemf/uwmf.c
index 35d38f69a..62e3d3c06 100644
--- a/src/libuemf/uwmf.c
+++ b/src/libuemf/uwmf.c
@@ -19,8 +19,8 @@
/*
File: uwmf.c
-Version: 0.0.16
-Date: 25-MAR-2015
+Version: 0.0.17
+Date: 28-MAR-2015
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
@@ -696,7 +696,8 @@ int packed_DIB_safe(
int usedbytes;
if(!bitmapinfo_safe(record, blimit))return(0); // this DIB has issues with colors fitting into the record
- uint32_t width, height, colortype, numCt, invert; // these values will be set in get_DIB_params
+ uint32_t numCt; // these values will be set in get_DIB_params
+ int32_t width, height, colortype, invert; // these values will be set in get_DIB_params
// next call returns pointers and values, but allocates no memory
dibparams = wget_DIB_params(record, &px, (const U_RGBQUAD **) &ct, &numCt, &width, &height, &colortype, &invert);
// sanity checking
@@ -1564,7 +1565,7 @@ int wmf_finish(
#if U_BYTE_SWAP
//This is a Big Endian machine, WMF data must be Little Endian
- U_wmf_endian(wt->buf,wt->used,1);
+ U_wmf_endian(wt->buf,wt->used,1,0); // BE to LE, entire file
#endif
(void) U_wmr_properties(U_WMR_INVALID); /* force the release of the lookup table memory, returned value is irrelevant */
@@ -1610,7 +1611,7 @@ int wmf_readdata(
else {
#if U_BYTE_SWAP
//This is a Big Endian machine, WMF data is Little Endian
- U_wmf_endian(*contents,*length,0); // LE to BE
+ U_wmf_endian(*contents,*length,0,0); // LE to BE, entire file
#endif
}
}
@@ -4720,10 +4721,10 @@ int U_WMRCORE_PALETTE_get(
*/
void U_BITMAPCOREHEADER_get(
const char *BmiCh,
- int32_t *Size,
- int32_t *Width,
- int32_t *Height,
- int32_t *BitCount
+ uint32_t *Size,
+ int32_t *Width,
+ int32_t *Height,
+ int32_t *BitCount
){
uint32_t utmp4;
uint16_t utmp2;
@@ -4800,14 +4801,14 @@ int wget_DIB_params(
const char *dib,
const char **px,
const U_RGBQUAD **ct,
- int32_t *numCt,
- int32_t *width,
- int32_t *height,
- int32_t *colortype,
- int32_t *invert
+ uint32_t *numCt,
+ int32_t *width,
+ int32_t *height,
+ int32_t *colortype,
+ int32_t *invert
){
uint32_t bic;
- int32_t Size;
+ uint32_t Size;
bic = U_BI_RGB; // this information is not in the coreheader;
U_BITMAPCOREHEADER_get(dib, &Size, width, height, colortype);
if(Size != 0xC ){ //BitmapCoreHeader
@@ -4816,7 +4817,7 @@ int wget_DIB_params(
*/
uint32_t uig4;
int32_t ig4;
- U_BITMAPINFOHEADER_get(dib, &uig4, width, height,&uig4, (uint32_t *) colortype, &bic, &uig4, &ig4, &ig4,&uig4, &uig4);
+ U_BITMAPINFOHEADER_get(dib, &uig4, width, height,&uig4, (uint32_t *) colortype, &bic, &uig4, &ig4, &ig4, &uig4, &uig4);
}
if(*height < 0){
*height = -*height;
@@ -5559,7 +5560,8 @@ int U_WMRPOLYGON_get(
){
int size = U_WMRCORE_2U16_N16_get(contents, (U_SIZE_WMRPOLYGON), NULL, Length, Data);
if(size){
- if(IS_MEM_UNSAFE(*Data, (*Length)*sizeof(U_POINT16), contents+size))return(0);
+ int iLength = (*Length)*sizeof(U_POINT16);
+ if(IS_MEM_UNSAFE(*Data, iLength, contents+size))return(0);
}
return size;
}
@@ -5578,7 +5580,8 @@ int U_WMRPOLYLINE_get(
){
int size = U_WMRCORE_2U16_N16_get(contents, (U_SIZE_WMRPOLYGON), NULL, Length, Data);
if(size){
- if(IS_MEM_UNSAFE(*Data, (*Length)*sizeof(U_POINT16), contents+size))return(0);
+ int iLength = (*Length)*sizeof(U_POINT16);
+ if(IS_MEM_UNSAFE(*Data, iLength, contents+size))return(0);
}
return size;
}
@@ -5605,7 +5608,8 @@ int U_WMRESCAPE_get(
){
int size = U_WMRCORE_2U16_N16_get(contents, (U_SIZE_WMRESCAPE), Escape, Length, Data);
if(size){
- if(IS_MEM_UNSAFE(*Data, *Length, contents+size))return(0);
+ int iLength=*Length;
+ if(IS_MEM_UNSAFE(*Data, iLength, contents+size))return(0);
}
return size;
}
diff --git a/src/libuemf/uwmf.h b/src/libuemf/uwmf.h
index 2237d2221..027de8e06 100644
--- a/src/libuemf/uwmf.h
+++ b/src/libuemf/uwmf.h
@@ -36,11 +36,11 @@
/*
File: uwmf.h
-Version: 0.0.11
-Date: 23-APR-2014
+Version: 0.0.12
+Date: 28-APR-2015
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
-Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
+Copyright: 2015 David Mathog and California Institute of Technology (Caltech)
*/
#ifndef _UWMF_
@@ -2407,8 +2407,8 @@ int wmr_arc_points(U_RECT16 rclBox, U_POINT16 ArcStart, U_POINT16 ArcEn
void U_BITMAPINFOHEADER_get(const char *Bmih, uint32_t *Size, int32_t *Width, int32_t *Height,
uint32_t *Planes, uint32_t *BitCount, uint32_t *Compression, uint32_t *SizeImage,
int32_t *XPelsPerMeter, int32_t *YPelsPerMeter, uint32_t *ClrUsed, uint32_t *ClrImportant);
-void U_BITMAPCOREHEADER_get(const char *BmiCh, int32_t *Size, int32_t *Width, int32_t *Height, int32_t *BitCount);
-int wget_DIB_params(const char *dib, const char **px, const U_RGBQUAD **ct, int32_t *numCt,
+void U_BITMAPCOREHEADER_get(const char *BmiCh, uint32_t *Size, int32_t *Width, int32_t *Height, int32_t *BitCount);
+int wget_DIB_params(const char *dib, const char **px, const U_RGBQUAD **ct, uint32_t *numCt,
int32_t *width, int32_t *height, int32_t *colortype, int32_t *invert);
int U_WMREOF_get(const char *contents);
int U_WMRSETBKCOLOR_get(const char *contents, U_COLORREF *Color);
diff --git a/src/libuemf/uwmf_endian.c b/src/libuemf/uwmf_endian.c
index 38a321ad0..de0b3ef87 100644
--- a/src/libuemf/uwmf_endian.c
+++ b/src/libuemf/uwmf_endian.c
@@ -6,11 +6,11 @@
/*
File: uwmf_endian.c
-Version: 0.1.3
-Date: 27-MAR-2014
+Version: 0.1.4
+Date: 28-APR-2015
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
-Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
+Copyright: 2015 David Mathog and California Institute of Technology (Caltech)
*/
#ifdef __cplusplus
@@ -1470,21 +1470,24 @@ void U_WMRCREATEREGION_swap(char *record, int torev){
\param contents pointer to the buffer holding the entire EMF in memory
\param length number of bytes in the buffer
\param torev 1 for native to reversed, 0 for reversed to native
+ \param onerec 1 if this is operating on a single record instead of an entire file
Normally this would be called immediately before writing the data to a file
or immediately after reading the data from a file.
*/
-int U_wmf_endian(char *contents, size_t length, int torev){
- size_t off;
+int U_wmf_endian(char *contents, size_t length, int torev, int onerec){
+ size_t off=0;
uint32_t OK, Size16;
uint8_t iType;
char *record;
int recnum, offset;
record = contents;
- off = wmfheader_swap(record,torev); fflush(stdout); /* WMF header is not a normal record, handle it separately */
- record += off;
- offset = off;
+ if(!onerec){
+ off = wmfheader_swap(record,torev); fflush(stdout); /* WMF header is not a normal record, handle it separately */
+ record += off;
+ offset = off;
+ }
OK = 1;
recnum = 1; /* used when debugging */
@@ -1759,6 +1762,7 @@ int U_wmf_endian(char *contents, size_t length, int torev){
record += 2*Size16;
offset += 2*Size16;
recnum++;
+ if(onerec)break;
} //end of while
return(1);
}
diff --git a/src/libuemf/uwmf_endian.h b/src/libuemf/uwmf_endian.h
index 57fd4ae44..6ce7f1984 100644
--- a/src/libuemf/uwmf_endian.h
+++ b/src/libuemf/uwmf_endian.h
@@ -6,11 +6,11 @@
/*
File: uwmf_endian.h
-Version: 0.0.2
-Date: 26-NOV-2013
+Version: 0.0.3
+Date: 28-APR-2015
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
-Copyright: 2013 David Mathog and California Institute of Technology (Caltech)
+Copyright: 2015 David Mathog and California Institute of Technology (Caltech)
*/
#ifndef _UWMF_ENDIAN_
@@ -24,7 +24,7 @@ extern "C" {
//! \cond
// prototypes
-int U_wmf_endian(char *contents, size_t length, int torev);
+int U_wmf_endian(char *contents, size_t length, int torev, int onerec);
//! \endcond
#ifdef __cplusplus
diff --git a/src/libuemf/uwmf_print.c b/src/libuemf/uwmf_print.c
index dd460b2b0..d6d1b584e 100644
--- a/src/libuemf/uwmf_print.c
+++ b/src/libuemf/uwmf_print.c
@@ -6,11 +6,11 @@
/*
File: uwmf_print.c
-Version: 0.0.4
-Date: 05-FEB-2014
+Version: 0.0.6
+Date: 21-MAY-2015
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
-Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
+Copyright: 2015 David Mathog and California Institute of Technology (Caltech)
*/
#ifdef __cplusplus
@@ -1351,13 +1351,20 @@ int U_wmf_onerec_print(const char *contents, const char *blimit, int recnum, siz
iType = *(uint8_t *)(contents + offsetof(U_METARECORD, iType ) );
-#if 1
- printf("%-30srecord:%5d type:%-4u offset:%8d rsize:%8u\n",
- U_wmr_names(iType), recnum, iType, (int) off, (int) size);
-#else /* show record checksums, this is NOT portable, result changes with endian type, useful for debugging */
- printf("%-30srecord:%5d type:%-4u offset:%8d size:%8u recchecksum:%u\n",
- U_wmr_names(iType), recnum, iType, (int) off, (int) size, U_16_checksum((int16_t *)contents, size));
+ uint32_t crc;
+#if U_BYTE_SWAP
+ //This is a Big Endian machine, WMF crc values must be calculated on Little Endian form
+ char *swapbuf=malloc(size);
+ if(!swapbuf)return(-1);
+ memcpy(swapbuf,contents,size);
+ U_wmf_endian(swapbuf,size,1,1); // BE to LE
+ crc=lu_crc32(swapbuf,size);
+ free(swapbuf);
+#else
+ crc=lu_crc32(contents,size);
#endif
+ printf("%-30srecord:%5d type:%-4u offset:%8d rsize:%8u crc32:%8.8X\n",
+ U_wmr_names(iType), recnum, iType, (int) off, (int) size, crc);
switch (iType)
{
diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp
index d3ca781e9..332d81777 100644
--- a/src/live_effects/effect.cpp
+++ b/src/live_effects/effect.cpp
@@ -358,7 +358,6 @@ Effect::Effect(LivePathEffectObject *lpeobject)
lpeobj(lpeobject),
concatenate_before_pwd2(false),
sp_lpe_item(NULL),
- defaultUnit("px"),
current_zoom(1),
sp_curve(NULL),
provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden
@@ -448,7 +447,6 @@ void Effect::doOnRemove (SPLPEItem const* /*lpeitem*/)
void Effect::doOnApply_impl(SPLPEItem const* lpeitem)
{
sp_lpe_item = const_cast<SPLPEItem *>(lpeitem);
- defaultUnit = sp_lpe_item->document->getDisplayUnit()->abbr;
/*sp_curve = SP_SHAPE(sp_lpe_item)->getCurve();
pathvector_before_effect = sp_curve->get_pathvector();*/
doOnApply(lpeitem);
@@ -457,7 +455,6 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem)
void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem)
{
sp_lpe_item = const_cast<SPLPEItem *>(lpeitem);
- defaultUnit = sp_lpe_item->document->getDisplayUnit()->abbr;
//printf("(SPLPEITEM*) %p\n", sp_lpe_item);
SPShape * shape = dynamic_cast<SPShape *>(sp_lpe_item);
if(shape){
diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h
index 63d357481..ea57ff243 100644
--- a/src/live_effects/effect.h
+++ b/src/live_effects/effect.h
@@ -159,7 +159,6 @@ protected:
bool concatenate_before_pwd2;
SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them.
- Glib::ustring defaultUnit; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them.
double current_zoom;
std::vector<Geom::Point> selectedNodesPoints;
SPCurve * sp_curve;
diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp
index fe03781d4..992c45a43 100644
--- a/src/live_effects/lpe-fillet-chamfer.cpp
+++ b/src/live_effects/lpe-fillet-chamfer.cpp
@@ -29,7 +29,6 @@
// for programmatically updating knots
#include "ui/tools-switch.h"
-#include <util/units.h>
// TODO due to internal breakage in glibmm headers, this must be last:
#include <glibmm/i18n.h>
@@ -57,7 +56,6 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) :
only_selected(_("Change only selected nodes"), _("Change only selected nodes"), "only_selected", &wr, this, false),
flexible(_("Flexible radius size (%)"), _("Flexible radius size (%)"), "flexible", &wr, this, false),
use_knot_distance(_("Use knots distance instead radius"), _("Use knots distance instead radius"), "use_knot_distance", &wr, this, false),
- unit(_("Unit:"), _("Unit"), "unit", &wr, this),
method(_("Method:"), _("Fillets methods"), "method", FMConverter, &wr, this, FM_AUTO),
radius(_("Radius (unit or %):"), _("Radius, in unit or %"), "radius", &wr, this, 0.),
chamfer_steps(_("Chamfer steps:"), _("Chamfer steps"), "chamfer_steps", &wr, this, 0),
@@ -65,7 +63,6 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) :
helper_size(_("Helper size with direction:"), _("Helper size with direction"), "helper_size", &wr, this, 0)
{
registerParameter(&fillet_chamfer_values);
- registerParameter(&unit);
registerParameter(&method);
registerParameter(&radius);
registerParameter(&chamfer_steps);
@@ -223,7 +220,7 @@ void LPEFilletChamfer::updateFillet()
{
double power = 0;
if (!flexible) {
- power = Inkscape::Util::Quantity::convert(radius, unit.get_abbreviation(), defaultUnit) * -1;
+ power = radius * -1;
} else {
power = radius;
}
@@ -444,9 +441,7 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem)
} else {
fillet_chamfer_values.set_helper_size(helper_size);
}
- fillet_chamfer_values.set_document_unit(defaultUnit);
fillet_chamfer_values.set_use_distance(use_knot_distance);
- fillet_chamfer_values.set_unit(unit.get_abbreviation());
SPCurve *c = SP_IS_PATH(lpeItem) ? static_cast<SPPath const *>(lpeItem)
->get_original_curve()
: SP_SHAPE(lpeItem)->getCurve();
diff --git a/src/live_effects/lpe-fillet-chamfer.h b/src/live_effects/lpe-fillet-chamfer.h
index 9c91a18b5..290a37f92 100644
--- a/src/live_effects/lpe-fillet-chamfer.h
+++ b/src/live_effects/lpe-fillet-chamfer.h
@@ -66,7 +66,6 @@ private:
BoolParam only_selected;
BoolParam flexible;
BoolParam use_knot_distance;
- UnitParam unit;
EnumParam<FilletMethod> method;
ScalarParam radius;
ScalarParam chamfer_steps;
diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp
index 44ff54554..33ffd96d6 100644
--- a/src/live_effects/lpe-roughen.cpp
+++ b/src/live_effects/lpe-roughen.cpp
@@ -20,7 +20,6 @@
#include "live_effects/parameter/parameter.h"
#include "helper/geom.h"
#include <glibmm/i18n.h>
-#include <util/units.h>
#include <cmath>
namespace Inkscape {
@@ -36,7 +35,6 @@ DMConverter(DivisionMethodData, DM_END);
LPERoughen::LPERoughen(LivePathEffectObject *lpeobject)
: Effect(lpeobject),
// initialise your parameters here:
- unit(_("Unit"), _("Unit"), "unit", &wr, this),
method(_("Method"), _("Division method"), "method", DMConverter, &wr,
this, DM_SEGMENTS),
max_segment_size(_("Max. segment size"), _("Max. segment size"),
@@ -54,7 +52,6 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject)
shift_node_handles(_("Shift node handles"), _("Shift node handles"),
"shift_node_handles", &wr, this, true)
{
- registerParameter(&unit);
registerParameter(&method);
registerParameter(&max_segment_size);
registerParameter(&segments);
@@ -98,14 +95,6 @@ Gtk::Widget *LPERoughen::newWidget()
if ((*it)->widget_is_visible) {
Parameter *param = *it;
Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
- if (param->param_key == "unit") {
- Gtk::Label *unit_label = Gtk::manage(new Gtk::Label(
- Glib::ustring(_("<b>Roughen unit</b>")), Gtk::ALIGN_START));
- unit_label->set_use_markup(true);
- vbox->pack_start(*unit_label, false, false, 2);
- vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()),
- Gtk::PACK_EXPAND_WIDGET);
- }
if (param->param_key == "method") {
Gtk::Label *method_label = Gtk::manage(new Gtk::Label(
Glib::ustring(_("<b>Add nodes</b> Subdivide each segment")),
@@ -160,11 +149,8 @@ double LPERoughen::sign(double random_number)
Geom::Point LPERoughen::randomize()
{
- Inkscape::Util::Unit const *svg_units = SP_ACTIVE_DESKTOP->namedview->svg_units;
- double displace_x_parsed = Inkscape::Util::Quantity::convert(
- displace_x * global_randomize, unit.get_abbreviation(), svg_units->abbr);
- double displace_y_parsed = Inkscape::Util::Quantity::convert(
- displace_y * global_randomize, unit.get_abbreviation(), svg_units->abbr);
+ double displace_x_parsed = displace_x * global_randomize;
+ double displace_y_parsed = displace_y * global_randomize;
Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed));
return output;
@@ -175,7 +161,6 @@ void LPERoughen::doEffect(SPCurve *curve)
Geom::PathVector const original_pathv =
pathv_to_linear_and_cubic_beziers(curve->get_pathvector());
curve->reset();
- Inkscape::Util::Unit const *svg_units = SP_ACTIVE_DESKTOP->namedview->svg_units;
for (Geom::PathVector::const_iterator path_it = original_pathv.begin();
path_it != original_pathv.end(); ++path_it) {
if (path_it->empty())
@@ -220,8 +205,7 @@ void LPERoughen::doEffect(SPCurve *curve)
} else {
nCurve->lineto(point3);
}
- double length = Inkscape::Util::Quantity::convert(
- curve_it1->length(0.001), svg_units->abbr, unit.get_abbreviation());
+ double length = curve_it1->length(0.001);
std::size_t splits = 0;
if (method == DM_SEGMENTS) {
splits = segments;
diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h
index ed9f06cf7..2b285cd40 100644
--- a/src/live_effects/lpe-roughen.h
+++ b/src/live_effects/lpe-roughen.h
@@ -17,7 +17,6 @@
#include "live_effects/parameter/parameter.h"
#include "live_effects/parameter/path.h"
#include "live_effects/parameter/bool.h"
-#include "live_effects/parameter/unit.h"
#include "live_effects/parameter/random.h"
namespace Inkscape {
@@ -45,7 +44,6 @@ public:
virtual Gtk::Widget *newWidget();
private:
- UnitParam unit;
EnumParam<DivisionMethod> method;
ScalarParam max_segment_size;
ScalarParam segments;
diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp
index cf11d52fc..a3ff4c96f 100644
--- a/src/live_effects/parameter/filletchamferpointarray.cpp
+++ b/src/live_effects/parameter/filletchamferpointarray.cpp
@@ -354,11 +354,6 @@ void FilletChamferPointArrayParam::set_pwd2(
last_pwd2_normal = pwd2_normal_in;
}
-void FilletChamferPointArrayParam::set_document_unit(Glib::ustring value_document_unit)
-{
- documentUnit = value_document_unit;
-}
-
void FilletChamferPointArrayParam::set_helper_size(int hs)
{
helper_size = hs;
@@ -374,11 +369,6 @@ void FilletChamferPointArrayParam::set_use_distance(bool use_knot_distance )
use_distance = use_knot_distance;
}
-void FilletChamferPointArrayParam::set_unit(const gchar *abbr)
-{
- unit = abbr;
-}
-
void FilletChamferPointArrayParam::updateCanvasIndicators()
{
std::vector<Point> ts = data();
@@ -812,7 +802,7 @@ void FilletChamferPointArrayParamKnotHolderEntity::knot_click(guint state)
bool aprox = (A[0].degreesOfFreedom() != 2 || B[0].degreesOfFreedom() != 2) && !_pparam->use_distance?true:false;
Geom::Point offset = Geom::Point(xModified, _pparam->_vector.at(_index).y());
Inkscape::UI::Dialogs::FilletChamferPropertiesDialog::showDialog(
- this->desktop, offset, this, _pparam->unit, _pparam->use_distance, aprox, _pparam->documentUnit);
+ this->desktop, offset, this, _pparam->use_distance, aprox);
}
}
diff --git a/src/live_effects/parameter/filletchamferpointarray.h b/src/live_effects/parameter/filletchamferpointarray.h
index bc05ecfc4..48cd26d2d 100644
--- a/src/live_effects/parameter/filletchamferpointarray.h
+++ b/src/live_effects/parameter/filletchamferpointarray.h
@@ -53,8 +53,6 @@ public:
virtual void set_helper_size(int hs);
virtual void set_use_distance(bool use_knot_distance);
virtual void set_chamfer_steps(int value_chamfer_steps);
- virtual void set_document_unit(Glib::ustring value_document_unit);
- virtual void set_unit(const gchar *abbr);
virtual void addCanvasIndicators(SPLPEItem const *lpeitem,
std::vector<Geom::PathVector> &hp_vec);
virtual bool providesKnotHolderEntities() const {
@@ -89,8 +87,6 @@ private:
int helper_size;
int chamfer_steps;
bool use_distance;
- const gchar *unit;
- Glib::ustring documentUnit;
Geom::PathVector hp;
Geom::Piecewise<Geom::D2<Geom::SBasis> > last_pwd2;
diff --git a/src/rdf.cpp b/src/rdf.cpp
index 16344e520..938dc60c6 100644
--- a/src/rdf.cpp
+++ b/src/rdf.cpp
@@ -39,7 +39,7 @@
</Agent></dc:rights>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:source rdf:resource="source"/>
- <license rdf:resource="http://creativecommons.org/licenses/by/2.0/"
+ <license rdf:resource="http://creativecommons.org/licenses/by/4.0/"
/>
</Work>
@@ -173,32 +173,32 @@ struct rdf_double_t rdf_license_ofl [] = {
struct rdf_license_t rdf_licenses [] = {
{ N_("CC Attribution"),
- "http://creativecommons.org/licenses/by/3.0/",
+ "http://creativecommons.org/licenses/by/4.0/",
rdf_license_cc_a,
},
{ N_("CC Attribution-ShareAlike"),
- "http://creativecommons.org/licenses/by-sa/3.0/",
+ "http://creativecommons.org/licenses/by-sa/4.0/",
rdf_license_cc_a_sa,
},
{ N_("CC Attribution-NoDerivs"),
- "http://creativecommons.org/licenses/by-nd/3.0/",
+ "http://creativecommons.org/licenses/by-nd/4.0/",
rdf_license_cc_a_nd,
},
{ N_("CC Attribution-NonCommercial"),
- "http://creativecommons.org/licenses/by-nc/3.0/",
+ "http://creativecommons.org/licenses/by-nc/4.0/",
rdf_license_cc_a_nc,
},
{ N_("CC Attribution-NonCommercial-ShareAlike"),
- "http://creativecommons.org/licenses/by-nc-sa/3.0/",
+ "http://creativecommons.org/licenses/by-nc-sa/4.0/",
rdf_license_cc_a_nc_sa,
},
{ N_("CC Attribution-NonCommercial-NoDerivs"),
- "http://creativecommons.org/licenses/by-nc-nd/3.0/",
+ "http://creativecommons.org/licenses/by-nc-nd/4.0/",
rdf_license_cc_a_nc_nd,
},
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index 2cd4f6b4e..16585413e 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -107,6 +107,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS;
#include "live_effects/effect.h"
#include "live_effects/effect-enum.h"
#include "live_effects/parameter/originalpath.h"
+#include "layer-manager.h"
#include "enums.h"
#include "sp-item-group.h"
@@ -438,7 +439,7 @@ static void add_ids_recursive(std::vector<const gchar *> &ids, SPObject *obj)
}
}
-void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone)
+void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone, bool duplicateLayer)
{
if (desktop == NULL) {
return;
@@ -449,12 +450,17 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone)
Inkscape::Selection *selection = desktop->getSelection();
// check if something is selected
- if (selection->isEmpty()) {
+ if (selection->isEmpty() && !duplicateLayer) {
desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to duplicate."));
return;
}
std::vector<Inkscape::XML::Node*> reprs(selection->reprList());
+ if(duplicateLayer){
+ reprs.clear();
+ reprs.push_back(desktop->currentLayer()->getRepr());
+ }
+
selection->clear();
// sorting items from different parents sorts each parent's subset without possibly mixing
@@ -474,7 +480,10 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone)
Inkscape::XML::Node *parent = old_repr->parent();
Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc);
- parent->appendChild(copy);
+ if(! duplicateLayer)
+ parent->appendChild(copy);
+ else
+ parent->addChild(copy, old_repr);
if (relink_clones) {
SPObject *old_obj = doc->getObjectByRepr(old_repr);
@@ -535,8 +544,14 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone)
DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_DUPLICATE,
_("Duplicate"));
}
-
- selection->setReprList(newsel);
+ if(!duplicateLayer)
+ selection->setReprList(newsel);
+ else{
+ SPObject* new_layer = doc->getObjectByRepr(newsel[0]);
+ gchar* name = g_strdup_printf(_("%s copy"), new_layer->label());
+ desktop->layer_manager->renameLayer( new_layer, name, TRUE );
+ g_free(name);
+ }
}
void sp_edit_clear_all(Inkscape::Selection *selection)
@@ -1948,8 +1963,8 @@ std::vector<SPItem*> sp_get_same_fill_or_stroke_color(SPItem *sel, std::vector<S
}
} else if (dynamic_cast<SPPattern *>(sel_server) && dynamic_cast<SPPattern *>(iter_server)) {
- SPPattern *sel_pat = pattern_getroot(dynamic_cast<SPPattern *>(sel_server));
- SPPattern *iter_pat = pattern_getroot(dynamic_cast<SPPattern *>(iter_server));
+ SPPattern *sel_pat = dynamic_cast<SPPattern *>(sel_server)->rootPattern();
+ SPPattern *iter_pat = dynamic_cast<SPPattern *>(iter_server)->rootPattern();
if (sel_pat == iter_pat) {
match = true;
}
@@ -3297,7 +3312,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply)
int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
- gchar const *pat_id = pattern_tile(repr_copies, bbox, doc,
+ gchar const *pat_id = SPPattern::produce(repr_copies, bbox, doc,
( Geom::Affine(Geom::Translate(desktop->dt2doc(Geom::Point(r->min()[Geom::X],
r->max()[Geom::Y]))))
* parent_transform.inverse() ),
@@ -3375,9 +3390,9 @@ void sp_selection_untile(SPDesktop *desktop)
did = true;
- SPPattern *pattern = pattern_getroot(basePat);
+ SPPattern *pattern = basePat->rootPattern();
- Geom::Affine pat_transform = pattern_patternTransform(basePat);
+ Geom::Affine pat_transform = basePat->getTransform();
pat_transform *= item->transform;
for (SPObject *child = pattern->firstChild() ; child != NULL; child = child->next ) {
@@ -3787,13 +3802,11 @@ void sp_selection_set_clipgroup(SPDesktop *desktop)
clone->setAttribute("inkscape:transform-center-y", inner->attribute("inkscape:transform-center-y"), false);
const Geom::Affine maskTransform(Geom::Affine::identity());
- GSList *templist = NULL;
-
- templist = g_slist_append(templist, clone);
+ std::vector<Inkscape::XML::Node*> templist;
+ templist.push_back(clone);
// add the new clone to the top of the original's parent
gchar const *mask_id = SPClipPath::create(templist, doc, &maskTransform);
- g_slist_free(templist);
outer->setAttribute("clip-path", g_strdup_printf("url(#%s)", mask_id));
@@ -3851,9 +3864,9 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_
selection->clear();
// create a list of duplicates
- GSList *mask_items = NULL;
- GSList *apply_to_items = NULL;
- GSList *items_to_delete = NULL;
+ std::vector<Inkscape::XML::Node*> mask_items;
+ std::vector<SPItem*> apply_to_items;
+ std::vector<SPItem*> items_to_delete;
std::vector<SPItem*> items_to_select;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -3863,54 +3876,36 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_
if (apply_to_layer) {
// all selected items are used for mask, which is applied to a layer
- apply_to_items = g_slist_prepend(apply_to_items, desktop->currentLayer());
+ apply_to_items.push_back(SP_ITEM(desktop->currentLayer()));
+ }
+
+ for (std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++) {
+ if((!topmost && !apply_to_layer && *i == items.front())
+ || (topmost && !apply_to_layer && *i == items.back())
+ || apply_to_layer){
- for (std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++) {
+ Geom::Affine oldtr=(*i)->transform;
+ (*i)->doWriteTransform((*i)->getRepr(), (*i)->i2doc_affine());
Inkscape::XML::Node *dup = (*i)->getRepr()->duplicate(xml_doc);
- mask_items = g_slist_prepend(mask_items, dup);
+ (*i)->doWriteTransform((*i)->getRepr(), oldtr);
+ mask_items.push_back(dup);
- SPObject *item = *i;
if (remove_original) {
- items_to_delete = g_slist_prepend(items_to_delete, item);
+ items_to_delete.push_back(*i);
}
else {
- items_to_select.push_back((SPItem*)item);
+ items_to_select.push_back(*i);
}
- }
- } else if (!topmost) {
- // topmost item is used as a mask, which is applied to other items in a selection
- Inkscape::XML::Node *dup = items[0]->getRepr()->duplicate(xml_doc);
- mask_items = g_slist_prepend(mask_items, dup);
-
- if (remove_original) {
- SPObject *item = items.front();
- items_to_delete = g_slist_prepend(items_to_delete, item);
- }
-
- for (std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++) {
- if(i==items.begin())continue;
- apply_to_items = g_slist_prepend(apply_to_items, *i);
+ continue;
+ }else{
+ apply_to_items.push_back(*i);
items_to_select.push_back(*i);
}
- } else {
- SPItem *i = NULL;
- for (std::vector<SPItem*>::const_iterator j=items.begin();j!=items.end();j++) {
- i=*j;
- apply_to_items = g_slist_prepend(apply_to_items, i);
- items_to_select.push_back(i);
- }
-
- Inkscape::XML::Node *dup = SP_OBJECT(i)->getRepr()->duplicate(xml_doc);
- mask_items = g_slist_prepend(mask_items, dup);
-
- if (remove_original) {
- SPObject *item = reinterpret_cast<SPObject*>(i);
- items_to_delete = g_slist_prepend(items_to_delete, item);
- }
}
+
items.clear();
- if (apply_to_items && grouping == PREFS_MASKOBJECT_GROUPING_ALL) {
+ if (grouping == PREFS_MASKOBJECT_GROUPING_ALL) {
// group all those objects into one group
// and apply mask to that
Inkscape::XML::Node *group = xml_doc->createElement("svg:g");
@@ -3919,48 +3914,35 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_
group->setAttribute("inkscape:groupmode", "maskhelper");
std::vector<Inkscape::XML::Node*> reprs_to_group;
-
- for (GSList *i = apply_to_items ; NULL != i ; i = i->next) {
- reprs_to_group.push_back(static_cast<SPObject*>(i->data)->getRepr());
- items_to_select.erase(remove(items_to_select.begin(), items_to_select.end(), static_cast<SPObject*>(i->data)), items_to_select.end());
+ for (std::vector<SPItem*>::const_iterator i = apply_to_items.begin(); i != apply_to_items.end(); i++) {
+ reprs_to_group.push_back(static_cast<SPObject*>(*i)->getRepr());
}
+ items_to_select.clear();
sp_selection_group_impl(reprs_to_group, group, xml_doc, doc);
// apply clip/mask only to newly created group
- g_slist_free(apply_to_items);
- apply_to_items = NULL;
- apply_to_items = g_slist_prepend(apply_to_items, doc->getObjectByRepr(group));
+ apply_to_items.clear();
+ apply_to_items.push_back(dynamic_cast<SPItem*>(doc->getObjectByRepr(group)));
items_to_select.push_back((SPItem*)(doc->getObjectByRepr(group)));
Inkscape::GC::release(group);
}
+ if (grouping == PREFS_MASKOBJECT_GROUPING_SEPARATE) {
+ items_to_select.clear();
+ }
+
gchar const *attributeName = apply_clip_path ? "clip-path" : "mask";
- for (GSList *i = apply_to_items; NULL != i; i = i->next) {
- SPItem *item = reinterpret_cast<SPItem *>(i->data);
+ for (std::vector<SPItem*>::const_reverse_iterator i = apply_to_items.rbegin(); i != apply_to_items.rend(); i++) {
+ SPItem *item = reinterpret_cast<SPItem *>(*i);
// inverted object transform should be applied to a mask object,
// as mask is calculated in user space (after applying transform)
- Geom::Affine maskTransform(item->transform.inverse());
-
- GSList *mask_items_dup = NULL;
- for (GSList *mask_item = mask_items; NULL != mask_item; mask_item = mask_item->next) {
- Inkscape::XML::Node *dup = reinterpret_cast<Inkscape::XML::Node *>(mask_item->data)->duplicate(xml_doc);
- mask_items_dup = g_slist_prepend(mask_items_dup, dup);
- }
-
- gchar const *mask_id = NULL;
- if (apply_clip_path) {
- mask_id = SPClipPath::create(mask_items_dup, doc, &maskTransform);
- } else {
- mask_id = sp_mask_create(mask_items_dup, doc, &maskTransform);
- }
-
- g_slist_free(mask_items_dup);
- mask_items_dup = NULL;
-
- Inkscape::XML::Node *current = SP_OBJECT(i->data)->getRepr();
+ std::vector<Inkscape::XML::Node*> mask_items_dup;
+ for(std::vector<Inkscape::XML::Node*>::const_iterator it=mask_items.begin();it!=mask_items.end();it++)
+ mask_items_dup.push_back((*it)->duplicate(xml_doc));
+ Inkscape::XML::Node *current = SP_OBJECT(*i)->getRepr();
// Node to apply mask to
Inkscape::XML::Node *apply_mask_to = current;
@@ -3972,7 +3954,6 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_
Inkscape::XML::Node *spnew = current->duplicate(xml_doc);
gint position = current->position();
- items_to_select.erase(remove(items_to_select.begin(), items_to_select.end(), item), items_to_select.end());
current->parent()->appendChild(group);
sp_repr_unparent(current);
group->appendChild(spnew);
@@ -3981,24 +3962,29 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_
// Apply clip/mask to group instead
apply_mask_to = group;
- items_to_select.push_back((SPItem*)(doc->getObjectByRepr(group)));
+ items_to_select.push_back(item = (SPItem*)(doc->getObjectByRepr(group)));
Inkscape::GC::release(spnew);
Inkscape::GC::release(group);
}
+ Geom::Affine maskTransform(item->i2doc_affine().inverse());
+
+ gchar const *mask_id = NULL;
+ if (apply_clip_path) {
+ mask_id = SPClipPath::create(mask_items_dup, doc, &maskTransform);
+ } else {
+ mask_id = sp_mask_create(mask_items_dup, doc, &maskTransform);
+ }
+
apply_mask_to->setAttribute(attributeName, Glib::ustring("url(#") + mask_id + ')');
}
- g_slist_free(mask_items);
- g_slist_free(apply_to_items);
-
- for (GSList *i = items_to_delete; NULL != i; i = i->next) {
- SPObject *item = reinterpret_cast<SPObject*>(i->data);
+ for (std::vector<SPItem*>::const_iterator i = items_to_delete.begin(); i != items_to_delete.end(); i++) {
+ SPObject *item = reinterpret_cast<SPObject*>(*i);
item->deleteObject(false);
items_to_select.erase(remove(items_to_select.begin(), items_to_select.end(), item), items_to_select.end());
}
- g_slist_free(items_to_delete);
selection->addList(items_to_select);
diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h
index 8bcab664b..5bcc5b1ea 100644
--- a/src/selection-chemistry.h
+++ b/src/selection-chemistry.h
@@ -52,7 +52,7 @@ namespace LivePathEffect {
} // namespace Inkscape
void sp_selection_delete(SPDesktop *desktop);
-void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone = false);
+void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone = false, bool duplicateLayer = false);
void sp_edit_clear_all(Inkscape::Selection *selection);
void sp_edit_select_all(SPDesktop *desktop);
diff --git a/src/selection.cpp b/src/selection.cpp
index 7979b5d61..77a507eec 100644
--- a/src/selection.cpp
+++ b/src/selection.cpp
@@ -125,6 +125,7 @@ Selection::_releaseContext(SPObject *obj)
void Selection::_invalidateCachedLists() {
_items.clear();
_reprs.clear();
+ _objs_vector.clear();
}
void Selection::_clear() {
diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp
index 3c6167438..d66508eae 100644
--- a/src/sp-clippath.cpp
+++ b/src/sp-clippath.cpp
@@ -296,7 +296,7 @@ sp_clippath_view_list_remove(SPClipPathView *list, SPClipPathView *view)
}
// Create a mask element (using passed elements), add it to <defs>
-const gchar *SPClipPath::create (GSList *reprs, SPDocument *document, Geom::Affine const* applyTransform)
+const gchar *SPClipPath::create (std::vector<Inkscape::XML::Node*> &reprs, SPDocument *document, Geom::Affine const* applyTransform)
{
Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr();
@@ -308,13 +308,12 @@ const gchar *SPClipPath::create (GSList *reprs, SPDocument *document, Geom::Affi
const gchar *id = repr->attribute("id");
SPObject *clip_path_object = document->getObjectById(id);
- for (GSList *it = reprs; it != NULL; it = it->next) {
- Inkscape::XML::Node *node = (Inkscape::XML::Node *)(it->data);
+ for (std::vector<Inkscape::XML::Node*>::const_iterator it = reprs.begin(); it != reprs.end(); it++) {
+ Inkscape::XML::Node *node = (*it);
SPItem *item = SP_ITEM(clip_path_object->appendChildRepr(node));
if (NULL != applyTransform) {
- Geom::Affine transform (item->transform);
- transform *= (*applyTransform);
+ Geom::Affine transform (item->transform * (*applyTransform));
item->doWriteTransform(item->getRepr(), transform);
}
}
diff --git a/src/sp-clippath.h b/src/sp-clippath.h
index eb8b14174..91dcfd625 100644
--- a/src/sp-clippath.h
+++ b/src/sp-clippath.h
@@ -45,7 +45,7 @@ public:
unsigned int clipPathUnits : 1;
SPClipPathView *display;
- static char const *create(GSList *reprs, SPDocument *document, Geom::Affine const* applyTransform);
+ static char const *create(std::vector<Inkscape::XML::Node*> &reprs, SPDocument *document, Geom::Affine const* applyTransform);
//static GType sp_clippath_get_type(void);
Inkscape::DrawingItem *show(Inkscape::Drawing &drawing, unsigned int key);
diff --git a/src/sp-item.cpp b/src/sp-item.cpp
index 8c99e9bcf..410fd9b37 100644
--- a/src/sp-item.cpp
+++ b/src/sp-item.cpp
@@ -349,17 +349,11 @@ void SPItem::lowerToBottom() {
using Inkscape::Util::MutableList;
using Inkscape::Util::reverse_list;
- MutableList<SPObject &> bottom=find_last_if(
- reverse_list<SPObject::SiblingIterator>(
- parent->firstChild(), this
- ),
- MutableList<SPObject &>(),
- &is_item
- );
+ SPObject * bottom=parent->firstChild();
+ while(dynamic_cast<SPObject*>(bottom) && dynamic_cast<SPObject*>(bottom->next) && bottom!=this && !is_item(*(bottom->next))) bottom=bottom->next;
if (bottom) {
- ++bottom;
Inkscape::XML::Node *ref = ( bottom ? bottom->getRepr() : NULL );
- getRepr()->parent()->changeOrder(getRepr(), ref);
+ parent->getRepr()->changeOrder(getRepr(), ref);
}
}
@@ -367,20 +361,20 @@ void SPItem::moveTo(SPItem *target, bool intoafter) {
Inkscape::XML::Node *target_ref = ( target ? target->getRepr() : NULL );
Inkscape::XML::Node *our_ref = getRepr();
- gboolean first = FALSE;
-
- if (target_ref == our_ref) {
- // Move to ourself ignore
- return;
- }
if (!target_ref) {
// Assume move to the "first" in the top node, find the top node
- target_ref = our_ref;
- while (target_ref->parent() != target_ref->root()) {
- target_ref = target_ref->parent();
+ intoafter = false;
+ SPObject* bottom = this->document->getObjectByRepr(our_ref->root())->firstChild();
+ while(!dynamic_cast<SPItem*>(bottom->next)){
+ bottom=bottom->next;
}
- first = TRUE;
+ target_ref = bottom->getRepr();
+ }
+
+ if (target_ref == our_ref) {
+ // Move to ourself ignore
+ return;
}
if (intoafter) {
@@ -391,16 +385,10 @@ void SPItem::moveTo(SPItem *target, bool intoafter) {
// Change in parent, need to remove and add
our_ref->parent()->removeChild(our_ref);
target_ref->parent()->addChild(our_ref, target_ref);
- } else if (!first) {
+ } else {
// Same parent, just move
our_ref->parent()->changeOrder(our_ref, target_ref);
}
-
- if (first && parent) {
- // If "first" ensure it appears after the defs etc
- lowerToBottom();
- return;
- }
}
void SPItem::build(SPDocument *document, Inkscape::XML::Node *repr) {
@@ -1234,8 +1222,8 @@ void SPItem::adjust_pattern(Geom::Affine const &postmul, bool set, PatternTransf
SPObject *server = style->getFillPaintServer();
SPPattern *serverPatt = dynamic_cast<SPPattern *>(server);
if ( serverPatt ) {
- SPPattern *pattern = sp_pattern_clone_if_necessary(this, serverPatt, "fill");
- sp_pattern_transform_multiply(pattern, postmul, set);
+ SPPattern *pattern = serverPatt->clone_if_necessary(this, "fill");
+ pattern->transform_multiply(postmul, set);
}
}
@@ -1244,8 +1232,8 @@ void SPItem::adjust_pattern(Geom::Affine const &postmul, bool set, PatternTransf
SPObject *server = style->getStrokePaintServer();
SPPattern *serverPatt = dynamic_cast<SPPattern *>(server);
if ( serverPatt ) {
- SPPattern *pattern = sp_pattern_clone_if_necessary(this, serverPatt, "stroke");
- sp_pattern_transform_multiply(pattern, postmul, set);
+ SPPattern *pattern = serverPatt->clone_if_necessary(this, "stroke");
+ pattern->transform_multiply(postmul, set);
}
}
}
diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp
index d60473e1d..f8fb7aff4 100644
--- a/src/sp-mask.cpp
+++ b/src/sp-mask.cpp
@@ -209,7 +209,7 @@ Inkscape::XML::Node* SPMask::write(Inkscape::XML::Document* xml_doc, Inkscape::X
// Create a mask element (using passed elements), add it to <defs>
const gchar *
-sp_mask_create (GSList *reprs, SPDocument *document, Geom::Affine const* applyTransform)
+sp_mask_create (std::vector<Inkscape::XML::Node*> &reprs, SPDocument *document, Geom::Affine const* applyTransform)
{
Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr();
@@ -221,13 +221,12 @@ sp_mask_create (GSList *reprs, SPDocument *document, Geom::Affine const* applyTr
const gchar *mask_id = repr->attribute("id");
SPObject *mask_object = document->getObjectById(mask_id);
- for (GSList *it = reprs; it != NULL; it = it->next) {
- Inkscape::XML::Node *node = (Inkscape::XML::Node *)(it->data);
+ for (std::vector<Inkscape::XML::Node*>::const_iterator it = reprs.begin(); it != reprs.end(); it++) {
+ Inkscape::XML::Node *node = (*it);
SPItem *item = SP_ITEM(mask_object->appendChildRepr(node));
if (NULL != applyTransform) {
- Geom::Affine transform (item->transform);
- transform *= (*applyTransform);
+ Geom::Affine transform (item->transform * (*applyTransform));
item->doWriteTransform(item->getRepr(), transform);
}
}
diff --git a/src/sp-mask.h b/src/sp-mask.h
index e991fedb6..3559483bb 100644
--- a/src/sp-mask.h
+++ b/src/sp-mask.h
@@ -108,6 +108,6 @@ protected:
}
};
-const char *sp_mask_create (GSList *reprs, SPDocument *document, Geom::Affine const* applyTransform);
+const char *sp_mask_create (std::vector<Inkscape::XML::Node*> &reprs, SPDocument *document, Geom::Affine const* applyTransform);
#endif // SEEN_SP_MASK_H
diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp
index c5336955c..7c3d0bd03 100644
--- a/src/sp-offset.cpp
+++ b/src/sp-offset.cpp
@@ -83,7 +83,7 @@ static void sp_offset_source_modified (SPObject *iSource, guint flags, SPItem *i
// fast is not mathematically correct, because computing the offset of a single
// cubic bezier patch is not trivial; in particular, there are problems with holes
// reappearing in offset when the radius becomes too large
-static bool use_slow_but_correct_offset_method=false;
+static bool use_slow_but_correct_offset_method=true;
SPOffset::SPOffset() : SPShape() {
this->rad = 1.0;
diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp
index e89ed77ba..755d3d162 100644
--- a/src/sp-pattern.cpp
+++ b/src/sp-pattern.cpp
@@ -5,7 +5,7 @@
* Lauris Kaplinski <lauris@kaplinski.com>
* bulia byak <buliabyak@users.sf.net>
* Jon A. Cruz <jon@joncruz.org>
- * Abhishek Sharma
+ * Abhishek Sharma
*
* Copyright (C) 2002 Lauris Kaplinski
*
@@ -13,15 +13,15 @@
*/
#ifdef HAVE_CONFIG_H
-# include "config.h"
+#include "config.h"
#endif
#include <cstring>
#include <string>
#include <glibmm.h>
#include <2geom/transforms.h>
+#include <sigc++/functors/mem_fun.h>
-#include "macros.h"
#include "svg/svg.h"
#include "display/cairo-utils.h"
#include "display/drawing-context.h"
@@ -34,67 +34,61 @@
#include "style.h"
#include "sp-pattern.h"
#include "xml/repr.h"
-#include "display/grayscale.h"
-#include <sigc++/functors/ptr_fun.h>
-#include <sigc++/adaptors/bind.h>
+#include "sp-factory.h"
-/*
- * Pattern
- */
-static void pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat);
-static void pattern_ref_modified (SPObject *ref, guint flags, SPPattern *pattern);
-
-SPPattern::SPPattern() : SPPaintServer(), SPViewBox() {
- this->href = NULL;
-
- this->ref = new SPPatternReference(this);
- this->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(pattern_ref_changed), this));
+SPPattern::SPPattern()
+ : SPPaintServer()
+ , SPViewBox()
+{
+ this->ref = new SPPatternReference(this);
+ this->ref->changedSignal().connect(sigc::mem_fun(this, &SPPattern::_onRefChanged));
- this->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX;
- this->patternUnits_set = FALSE;
+ this->_pattern_units = UNITS_OBJECTBOUNDINGBOX;
+ this->_pattern_units_set = false;
- this->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE;
- this->patternContentUnits_set = FALSE;
+ this->_pattern_content_units = UNITS_USERSPACEONUSE;
+ this->_pattern_content_units_set = false;
- this->patternTransform = Geom::identity();
- this->patternTransform_set = FALSE;
+ this->_pattern_transform = Geom::identity();
+ this->_pattern_transform_set = false;
- this->x.unset();
- this->y.unset();
- this->width.unset();
- this->height.unset();
+ this->_x.unset();
+ this->_y.unset();
+ this->_width.unset();
+ this->_height.unset();
}
-SPPattern::~SPPattern() {
-}
+SPPattern::~SPPattern() {}
-void SPPattern::build(SPDocument* doc, Inkscape::XML::Node* repr) {
- SPPaintServer::build(doc, repr);
-
- this->readAttr( "patternUnits" );
- this->readAttr( "patternContentUnits" );
- this->readAttr( "patternTransform" );
- this->readAttr( "x" );
- this->readAttr( "y" );
- this->readAttr( "width" );
- this->readAttr( "height" );
- this->readAttr( "viewBox" );
- this->readAttr( "preserveAspectRatio" );
- this->readAttr( "xlink:href" );
-
- /* Register ourselves */
- doc->addResource("pattern", this);
+void SPPattern::build(SPDocument *doc, Inkscape::XML::Node *repr)
+{
+ SPPaintServer::build(doc, repr);
+
+ this->readAttr("patternUnits");
+ this->readAttr("patternContentUnits");
+ this->readAttr("patternTransform");
+ this->readAttr("x");
+ this->readAttr("y");
+ this->readAttr("width");
+ this->readAttr("height");
+ this->readAttr("viewBox");
+ this->readAttr("preserveAspectRatio");
+ this->readAttr("xlink:href");
+
+ /* Register ourselves */
+ doc->addResource("pattern", this);
}
-void SPPattern::release() {
+void SPPattern::release()
+{
if (this->document) {
// Unregister ourselves
this->document->removeResource("pattern", this);
}
if (this->ref) {
- this->modified_connection.disconnect();
+ this->_modified_connection.disconnect();
this->ref->detach();
delete this->ref;
this->ref = NULL;
@@ -103,113 +97,121 @@ void SPPattern::release() {
SPPaintServer::release();
}
-void SPPattern::set(unsigned int key, const gchar* value) {
- switch (key) {
- case SP_ATTR_PATTERNUNITS:
- if (value) {
- if (!strcmp (value, "userSpaceOnUse")) {
- this->patternUnits = SP_PATTERN_UNITS_USERSPACEONUSE;
- } else {
- this->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX;
- }
-
- this->patternUnits_set = TRUE;
- } else {
- this->patternUnits_set = FALSE;
- }
-
- this->requestModified(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_PATTERNCONTENTUNITS:
- if (value) {
- if (!strcmp (value, "userSpaceOnUse")) {
- this->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE;
- } else {
- this->patternContentUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX;
- }
-
- this->patternContentUnits_set = TRUE;
- } else {
- this->patternContentUnits_set = FALSE;
- }
-
- this->requestModified(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_PATTERNTRANSFORM: {
- Geom::Affine t;
-
- if (value && sp_svg_transform_read (value, &t)) {
- this->patternTransform = t;
- this->patternTransform_set = TRUE;
- } else {
- this->patternTransform = Geom::identity();
- this->patternTransform_set = FALSE;
- }
-
- this->requestModified(SP_OBJECT_MODIFIED_FLAG);
- break;
- }
- case SP_ATTR_X:
- this->x.readOrUnset(value);
- this->requestModified(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_Y:
- this->y.readOrUnset(value);
- this->requestModified(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_WIDTH:
- this->width.readOrUnset(value);
- this->requestModified(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_HEIGHT:
- this->height.readOrUnset(value);
- this->requestModified(SP_OBJECT_MODIFIED_FLAG);
- break;
-
- case SP_ATTR_VIEWBOX:
- set_viewBox( value );
+void SPPattern::set(unsigned int key, const gchar *value)
+{
+ switch (key) {
+ case SP_ATTR_PATTERNUNITS:
+ if (value) {
+ if (!strcmp(value, "userSpaceOnUse")) {
+ this->_pattern_units = UNITS_USERSPACEONUSE;
+ }
+ else {
+ this->_pattern_units = UNITS_OBJECTBOUNDINGBOX;
+ }
+
+ this->_pattern_units_set = true;
+ }
+ else {
+ this->_pattern_units_set = false;
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_PATTERNCONTENTUNITS:
+ if (value) {
+ if (!strcmp(value, "userSpaceOnUse")) {
+ this->_pattern_content_units = UNITS_USERSPACEONUSE;
+ }
+ else {
+ this->_pattern_content_units = UNITS_OBJECTBOUNDINGBOX;
+ }
+
+ this->_pattern_content_units_set = true;
+ }
+ else {
+ this->_pattern_content_units_set = false;
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_PATTERNTRANSFORM: {
+ Geom::Affine t;
+
+ if (value && sp_svg_transform_read(value, &t)) {
+ this->_pattern_transform = t;
+ this->_pattern_transform_set = true;
+ }
+ else {
+ this->_pattern_transform = Geom::identity();
+ this->_pattern_transform_set = false;
+ }
+
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+ }
+ case SP_ATTR_X:
+ this->_x.readOrUnset(value);
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_Y:
+ this->_y.readOrUnset(value);
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_WIDTH:
+ this->_width.readOrUnset(value);
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_HEIGHT:
+ this->_height.readOrUnset(value);
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
+
+ case SP_ATTR_VIEWBOX:
+ set_viewBox(value);
this->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
break;
case SP_ATTR_PRESERVEASPECTRATIO:
- set_preserveAspectRatio( value );
+ set_preserveAspectRatio(value);
this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG);
break;
- case SP_ATTR_XLINK_HREF:
- if ( value && this->href && ( strcmp(value, this->href) == 0 ) ) {
- /* Href unchanged, do nothing. */
- } else {
- g_free(this->href);
- this->href = NULL;
-
- if (value) {
- // First, set the href field; it's only used in the "unchanged" check above.
- this->href = g_strdup(value);
- // Now do the attaching, which emits the changed signal.
- if (value) {
- try {
- this->ref->attach(Inkscape::URI(value));
- } catch (Inkscape::BadURIException &e) {
- g_warning("%s", e.what());
- this->ref->detach();
- }
- } else {
- this->ref->detach();
- }
- }
- }
- break;
-
- default:
- SPPaintServer::set(key, value);
- break;
- }
+ case SP_ATTR_XLINK_HREF:
+ if (value && this->href == value) {
+ /* Href unchanged, do nothing. */
+ }
+ else {
+ this->href.clear();
+
+ if (value) {
+ // First, set the href field; it's only used in the "unchanged" check above.
+ this->href = value;
+ // Now do the attaching, which emits the changed signal.
+ if (value) {
+ try {
+ this->ref->attach(Inkscape::URI(value));
+ }
+ catch (Inkscape::BadURIException &e) {
+ g_warning("%s", e.what());
+ this->ref->detach();
+ }
+ }
+ else {
+ this->ref->detach();
+ }
+ }
+ }
+ break;
+
+ default:
+ SPPaintServer::set(key, value);
+ break;
+ }
}
@@ -217,104 +219,90 @@ void SPPattern::set(unsigned int key, const gchar* value) {
/* fixme: We need ::order_changed handler too (Lauris) */
-static GSList *pattern_getchildren(SPPattern *pat)
+void SPPattern::_getChildren(std::list<SPObject *> &l)
{
- GSList *l = NULL;
-
- for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ for (SPPattern *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (pat_i->firstChild()) { // find the first one with children
- for (SPObject *child = pat->firstChild() ; child ; child = child->getNext() ) {
- l = g_slist_prepend (l, child);
- }
- break; // do not go further up the chain if children are found
+ for (SPObject *child = pat_i->firstChild(); child; child = child->getNext()) {
+ l.push_back(child);
+ }
+ break; // do not go further up the chain if children are found
}
}
-
- return l;
}
-void SPPattern::update(SPCtx* ctx, unsigned int flags) {
- if (flags & SP_OBJECT_MODIFIED_FLAG) {
- flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
- }
+void SPPattern::update(SPCtx *ctx, unsigned int flags)
+{
+ typedef std::list<SPObject *>::iterator SPObjectIterator;
+
+ if (flags & SP_OBJECT_MODIFIED_FLAG) {
+ flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
+ }
- flags &= SP_OBJECT_MODIFIED_CASCADE;
+ flags &= SP_OBJECT_MODIFIED_CASCADE;
- GSList *l = pattern_getchildren (this);
- l = g_slist_reverse (l);
+ std::list<SPObject *> l;
+ _getChildren(l);
- while (l) {
- SPObject *child = SP_OBJECT (l->data);
+ for (SPObjectIterator it = l.begin(); it != l.end(); it++) {
+ SPObject *child = *it;
- sp_object_ref (child, NULL);
- l = g_slist_remove (l, child);
+ sp_object_ref(child, NULL);
- if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
- child->updateDisplay(ctx, flags);
- }
+ if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
+ child->updateDisplay(ctx, flags);
+ }
- sp_object_unref (child, NULL);
- }
+ sp_object_unref(child, NULL);
+ }
}
-void SPPattern::modified(unsigned int flags) {
- if (flags & SP_OBJECT_MODIFIED_FLAG) {
- flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
- }
+void SPPattern::modified(unsigned int flags)
+{
+ typedef std::list<SPObject *>::iterator SPObjectIterator;
+
+ if (flags & SP_OBJECT_MODIFIED_FLAG) {
+ flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
+ }
- flags &= SP_OBJECT_MODIFIED_CASCADE;
+ flags &= SP_OBJECT_MODIFIED_CASCADE;
- GSList *l = pattern_getchildren (this);
- l = g_slist_reverse (l);
+ std::list<SPObject *> l;
+ _getChildren(l);
- while (l) {
- SPObject *child = SP_OBJECT (l->data);
+ for (SPObjectIterator it = l.begin(); it != l.end(); it++) {
+ SPObject *child = *it;
- sp_object_ref (child, NULL);
- l = g_slist_remove (l, child);
+ sp_object_ref(child, NULL);
- if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
- child->emitModified(flags);
- }
+ if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
+ child->emitModified(flags);
+ }
- sp_object_unref (child, NULL);
- }
+ sp_object_unref(child, NULL);
+ }
}
-/**
-Gets called when the pattern is reattached to another <pattern>
-*/
-static void
-pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat)
+void SPPattern::_onRefChanged(SPObject *old_ref, SPObject *ref)
{
- if (old_ref) {
- pat->modified_connection.disconnect();
- }
+ if (old_ref) {
+ _modified_connection.disconnect();
+ }
- if (SP_IS_PATTERN (ref)) {
- pat->modified_connection = ref->connectModified(sigc::bind<2>(sigc::ptr_fun(&pattern_ref_modified), pat));
- }
+ if (SP_IS_PATTERN(ref)) {
+ _modified_connection = ref->connectModified(sigc::mem_fun(this, &SPPattern::_onRefModified));
+ }
- pattern_ref_modified (ref, 0, pat);
+ _onRefModified(ref, 0);
}
-/**
-Gets called when the referenced <pattern> is changed
-*/
-static void pattern_ref_modified (SPObject */*ref*/, guint /*flags*/, SPPattern *pattern)
+void SPPattern::_onRefModified(SPObject * /*ref*/, guint /*flags*/)
{
- if ( SP_IS_OBJECT(pattern) ) {
- pattern->requestModified(SP_OBJECT_MODIFIED_FLAG);
- }
+ requestModified(SP_OBJECT_MODIFIED_FLAG);
// Conditional to avoid causing infinite loop if there's a cycle in the href chain.
}
-
-/**
-Count how many times pat is used by the styles of o and its descendants
-*/
-static guint
-count_pattern_hrefs(SPObject *o, SPPattern *pat)
+guint SPPattern::_countHrefs(SPObject *o) const
{
if (!o)
return 1;
@@ -322,84 +310,79 @@ count_pattern_hrefs(SPObject *o, SPPattern *pat)
guint i = 0;
SPStyle *style = o->style;
- if (style
- && style->fill.isPaintserver()
- && SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style))
- && SP_PATTERN(SP_STYLE_FILL_SERVER(style)) == pat)
- {
- i ++;
+ if (style && style->fill.isPaintserver() && SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style)) &&
+ SP_PATTERN(SP_STYLE_FILL_SERVER(style)) == this) {
+ i++;
}
- if (style
- && style->stroke.isPaintserver()
- && SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style))
- && SP_PATTERN(SP_STYLE_STROKE_SERVER(style)) == pat)
- {
- i ++;
+ if (style && style->stroke.isPaintserver() && SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style)) &&
+ SP_PATTERN(SP_STYLE_STROKE_SERVER(style)) == this) {
+ i++;
}
- for ( SPObject *child = o->firstChild(); child != NULL; child = child->next ) {
- i += count_pattern_hrefs(child, pat);
+ for (SPObject *child = o->firstChild(); child != NULL; child = child->next) {
+ i += _countHrefs(child);
}
return i;
}
-SPPattern *pattern_chain(SPPattern *pattern)
+SPPattern *SPPattern::_chain() const
{
- SPDocument *document = pattern->document;
- Inkscape::XML::Document *xml_doc = document->getReprDoc();
+ Inkscape::XML::Document *xml_doc = document->getReprDoc();
Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr();
Inkscape::XML::Node *repr = xml_doc->createElement("svg:pattern");
repr->setAttribute("inkscape:collect", "always");
- gchar *parent_ref = g_strconcat("#", pattern->getRepr()->attribute("id"), NULL);
- repr->setAttribute("xlink:href", parent_ref);
- g_free (parent_ref);
+ Glib::ustring parent_ref = Glib::ustring::compose("#%1", getRepr()->attribute("id"));
+ repr->setAttribute("xlink:href", parent_ref);
defsrepr->addChild(repr, NULL);
const gchar *child_id = repr->attribute("id");
SPObject *child = document->getObjectById(child_id);
- g_assert (SP_IS_PATTERN (child));
+ g_assert(SP_IS_PATTERN(child));
- return SP_PATTERN (child);
+ return SP_PATTERN(child);
}
-SPPattern *
-sp_pattern_clone_if_necessary (SPItem *item, SPPattern *pattern, const gchar *property)
+SPPattern *SPPattern::clone_if_necessary(SPItem *item, const gchar *property)
{
- if (!pattern->href || pattern->hrefcount > count_pattern_hrefs(item, pattern)) {
- pattern = pattern_chain (pattern);
- gchar *href = g_strconcat("url(#", pattern->getRepr()->attribute("id"), ")", NULL);
+ SPPattern *pattern = this;
+ if (pattern->href.empty() || pattern->hrefcount > _countHrefs(item)) {
+ pattern = _chain();
+ Glib::ustring href = Glib::ustring::compose("url(#%1)", pattern->getRepr()->attribute("id"));
- SPCSSAttr *css = sp_repr_css_attr_new ();
- sp_repr_css_set_property (css, property, href);
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ sp_repr_css_set_property(css, property, href.c_str());
sp_repr_css_change_recursive(item->getRepr(), css, "style");
}
return pattern;
}
-void
-sp_pattern_transform_multiply (SPPattern *pattern, Geom::Affine postmul, bool set)
+void SPPattern::transform_multiply(Geom::Affine postmul, bool set)
{
// this formula is for a different interpretation of pattern transforms as described in (*) in sp-pattern.cpp
// for it to work, we also need sp_object_read_attr( item, "transform");
- //pattern->patternTransform = premul * item->transform * pattern->patternTransform * item->transform.inverse() * postmul;
+ // pattern->patternTransform = premul * item->transform * pattern->patternTransform * item->transform.inverse() *
+ // postmul;
// otherwise the formula is much simpler
if (set) {
- pattern->patternTransform = postmul;
- } else {
- pattern->patternTransform = pattern_patternTransform(pattern) * postmul;
+ _pattern_transform = postmul;
}
- pattern->patternTransform_set = TRUE;
+ else {
+ _pattern_transform = getTransform() * postmul;
+ }
+ _pattern_transform_set = true;
- gchar *c=sp_svg_transform_write(pattern->patternTransform);
- pattern->getRepr()->setAttribute("patternTransform", c);
- g_free(c);
+ Glib::ustring c = sp_svg_transform_write(_pattern_transform);
+ getRepr()->setAttribute("patternTransform", c);
}
-const gchar *pattern_tile(const std::vector<Inkscape::XML::Node*> &reprs, Geom::Rect bounds, SPDocument *document, Geom::Affine transform, Geom::Affine move)
+const gchar *SPPattern::produce(const std::vector<Inkscape::XML::Node *> &reprs, Geom::Rect bounds,
+ SPDocument *document, Geom::Affine transform, Geom::Affine move)
{
+ typedef std::vector<Inkscape::XML::Node *>::const_iterator NodePtrIterator;
+
Inkscape::XML::Document *xml_doc = document->getReprDoc();
Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr();
@@ -408,20 +391,19 @@ const gchar *pattern_tile(const std::vector<Inkscape::XML::Node*> &reprs, Geom::
sp_repr_set_svg_double(repr, "width", bounds.dimensions()[Geom::X]);
sp_repr_set_svg_double(repr, "height", bounds.dimensions()[Geom::Y]);
- gchar *t=sp_svg_transform_write(transform);
+ Glib::ustring t = sp_svg_transform_write(transform);
repr->setAttribute("patternTransform", t);
- g_free(t);
defsrepr->appendChild(repr);
const gchar *pat_id = repr->attribute("id");
SPObject *pat_object = document->getObjectById(pat_id);
- for (std::vector<Inkscape::XML::Node*>::const_iterator i=reprs.begin();i!=reprs.end();i++){
+ for (NodePtrIterator i = reprs.begin(); i != reprs.end(); i++) {
Inkscape::XML::Node *node = *i;
SPItem *copy = SP_ITEM(pat_object->appendChildRepr(node));
Geom::Affine dup_transform;
- if (!sp_svg_transform_read (node->attribute("transform"), &dup_transform))
+ if (!sp_svg_transform_read(node->attribute("transform"), &dup_transform))
dup_transform = Geom::identity();
dup_transform *= move;
@@ -432,14 +414,15 @@ const gchar *pattern_tile(const std::vector<Inkscape::XML::Node*> &reprs, Geom::
return pat_id;
}
-SPPattern *pattern_getroot(SPPattern *pat)
+SPPattern *SPPattern::rootPattern()
{
- for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
- if ( pat_i->firstChild() ) { // find the first one with children
+ for (SPPattern *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ if (pat_i->firstChild()) { // find the first one with children
return pat_i;
}
}
- return pat; // document is broken, we can't get to root; but at least we can return pat which is supposedly a valid pattern
+ return this; // document is broken, we can't get to root; but at least we can return pat which is supposedly a valid
+ // pattern
}
@@ -447,73 +430,73 @@ SPPattern *pattern_getroot(SPPattern *pat)
// Access functions that look up fields up the chain of referenced patterns and return the first one which is set
// FIXME: all of them must use chase_hrefs the same as in SPGradient, to avoid lockup on circular refs
-guint pattern_patternUnits (SPPattern const *pat)
+SPPattern::PatternUnits SPPattern::patternUnits() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
- if (pat_i->patternUnits_set)
- return pat_i->patternUnits;
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ if (pat_i->_pattern_units_set)
+ return pat_i->_pattern_units;
}
- return pat->patternUnits;
+ return _pattern_units;
}
-guint pattern_patternContentUnits (SPPattern const *pat)
+SPPattern::PatternUnits SPPattern::patternContentUnits() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
- if (pat_i->patternContentUnits_set)
- return pat_i->patternContentUnits;
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ if (pat_i->_pattern_content_units_set)
+ return pat_i->_pattern_content_units;
}
- return pat->patternContentUnits;
+ return _pattern_content_units;
}
-Geom::Affine const &pattern_patternTransform(SPPattern const *pat)
+Geom::Affine const &SPPattern::getTransform() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
- if (pat_i->patternTransform_set)
- return pat_i->patternTransform;
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ if (pat_i->_pattern_transform_set)
+ return pat_i->_pattern_transform;
}
- return pat->patternTransform;
+ return _pattern_transform;
}
-gdouble pattern_x (SPPattern const *pat)
+gdouble SPPattern::x() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
- if (pat_i->x._set)
- return pat_i->x.computed;
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ if (pat_i->_x._set)
+ return pat_i->_x.computed;
}
return 0;
}
-gdouble pattern_y (SPPattern const *pat)
+gdouble SPPattern::y() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
- if (pat_i->y._set)
- return pat_i->y.computed;
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ if (pat_i->_y._set)
+ return pat_i->_y.computed;
}
return 0;
}
-gdouble pattern_width (SPPattern const* pat)
+gdouble SPPattern::width() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
- if (pat_i->width._set)
- return pat_i->width.computed;
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ if (pat_i->_width._set)
+ return pat_i->_width.computed;
}
return 0;
}
-gdouble pattern_height (SPPattern const *pat)
+gdouble SPPattern::height() const
{
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
- if (pat_i->height._set)
- return pat_i->height.computed;
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ if (pat_i->_height._set)
+ return pat_i->_height.computed;
}
return 0;
}
-Geom::OptRect pattern_viewBox (SPPattern const *pat)
+Geom::OptRect SPPattern::viewbox() const
{
Geom::OptRect viewbox;
- for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
+ for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
if (pat_i->viewBox_set) {
viewbox = pat_i->viewBox;
break;
@@ -522,10 +505,10 @@ Geom::OptRect pattern_viewBox (SPPattern const *pat)
return viewbox;
}
-static bool pattern_hasItemChildren (SPPattern const *pat)
+bool SPPattern::_hasItemChildren() const
{
bool hasChildren = false;
- for (SPObject const *child = pat->firstChild() ; child && !hasChildren ; child = child->getNext() ) {
+ for (SPObject const *child = firstChild(); child && !hasChildren; child = child->getNext()) {
if (SP_IS_ITEM(child)) {
hasChildren = true;
}
@@ -535,15 +518,16 @@ static bool pattern_hasItemChildren (SPPattern const *pat)
bool SPPattern::isValid() const
{
- double tile_width = pattern_width(this);
- double tile_height = pattern_height(this);
+ double tile_width = width();
+ double tile_height = height();
- if (tile_width <= 0 || tile_height <= 0)
- return false;
- return true;
+ if (tile_width <= 0 || tile_height <= 0)
+ return false;
+ return true;
}
-cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) {
+cairo_pattern_t *SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity)
+{
bool needs_opacity = (1.0 - opacity) >= 1e-3;
bool visible = opacity >= 1e-3;
@@ -557,28 +541,28 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
for (SPPattern *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) {
// find the first one with item children
- if (pat_i && SP_IS_OBJECT(pat_i) && pattern_hasItemChildren(pat_i)) {
+ if (pat_i && SP_IS_OBJECT(pat_i) && pat_i->_hasItemChildren()) {
shown = pat_i;
break; // do not go further up the chain if children are found
}
}
if (!shown) {
- return cairo_pattern_create_rgba(0,0,0,0);
+ return cairo_pattern_create_rgba(0, 0, 0, 0);
}
/* Create drawing for rendering */
Inkscape::Drawing drawing;
- unsigned int dkey = SPItem::display_key_new (1);
+ unsigned int dkey = SPItem::display_key_new(1);
Inkscape::DrawingGroup *root = new Inkscape::DrawingGroup(drawing);
drawing.setRoot(root);
- for (SPObject *child = shown->firstChild(); child != NULL; child = child->getNext() ) {
- if (SP_IS_ITEM (child)) {
+ for (SPObject *child = shown->firstChild(); child != NULL; child = child->getNext()) {
+ if (SP_IS_ITEM(child)) {
// for each item in pattern, show it on our drawing, add to the group,
// and connect to the release signal in case the item gets deleted
Inkscape::DrawingItem *cai;
- cai = SP_ITEM(child)->invoke_show (drawing, dkey, SP_ITEM_SHOW_DISPLAY);
+ cai = SP_ITEM(child)->invoke_show(drawing, dkey, SP_ITEM_SHOW_DISPLAY);
root->appendChild(cai);
}
}
@@ -591,40 +575,41 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
// * "x", "y", and "patternTransform" transform tile to user space after tile is generated.
// These functions recursively search up the tree to find the values.
- double tile_x = pattern_x(this);
- double tile_y = pattern_y(this);
- double tile_width = pattern_width(this);
- double tile_height = pattern_height(this);
- if ( bbox && (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) ) {
- tile_x *= bbox->width();
- tile_y *= bbox->height();
- tile_width *= bbox->width();
+ double tile_x = x();
+ double tile_y = y();
+ double tile_width = width();
+ double tile_height = height();
+ if (bbox && (patternUnits() == UNITS_OBJECTBOUNDINGBOX)) {
+ tile_x *= bbox->width();
+ tile_y *= bbox->height();
+ tile_width *= bbox->width();
tile_height *= bbox->height();
}
// Pattern size in pattern space
Geom::Rect pattern_tile = Geom::Rect::from_xywh(0, 0, tile_width, tile_height);
-
+
// Content to tile (pattern space)
Geom::Affine content2ps;
- Geom::OptRect effective_view_box = pattern_viewBox(this);
+ Geom::OptRect effective_view_box = viewbox();
if (effective_view_box) {
- // viewBox to pattern server (using SPViewBox)
+ // viewBox to pattern server (using SPViewBox)
viewBox = *effective_view_box;
c2p.setIdentity();
- apply_viewbox( pattern_tile );
+ apply_viewbox(pattern_tile);
content2ps = c2p;
- } else {
+ }
+ else {
// Content to bbox
- if (bbox && (pattern_patternContentUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) ) {
- content2ps = Geom::Affine(bbox->width(), 0.0, 0.0, bbox->height(), 0,0);
+ if (bbox && (patternContentUnits() == UNITS_OBJECTBOUNDINGBOX)) {
+ content2ps = Geom::Affine(bbox->width(), 0.0, 0.0, bbox->height(), 0, 0);
}
}
// Tile (pattern space) to user.
- Geom::Affine ps2user = Geom::Translate(tile_x,tile_y) * pattern_patternTransform(this);
+ Geom::Affine ps2user = Geom::Translate(tile_x, tile_y) * getTransform();
// Transform of object with pattern (includes screen scaling)
@@ -644,7 +629,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
// to find the optimum tile size for rendering
// c is number of pixels in buffer x and y.
// Scale factor of 1.1 is too small... see bug #1251039
- Geom::Point c(pattern_tile.dimensions()*ps2user.descrim()*full.descrim()*2.0);
+ Geom::Point c(pattern_tile.dimensions() * ps2user.descrim() * full.descrim() * 2.0);
// Create drawing surface with size of pattern tile (in pattern space) but with number of pixels
// based on required resolution (c).
@@ -660,16 +645,16 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
}
// TODO: make sure there are no leaks.
- Inkscape::UpdateContext ctx; // UpdateContext is structure with only ctm!
+ Inkscape::UpdateContext ctx; // UpdateContext is structure with only ctm!
ctx.ctm = content2ps * pattern_surface.drawingTransform();
- dc.transform( pattern_surface.drawingTransform().inverse() );
+ dc.transform(pattern_surface.drawingTransform().inverse());
drawing.update(Geom::IntRect::infinite(), ctx);
// Render drawing to pattern_surface via drawing context, this calls root->render
// which is really DrawingItem->render().
drawing.render(dc, one_tile);
- for (SPObject *child = shown->firstChild() ; child != NULL; child = child->getNext() ) {
- if (SP_IS_ITEM (child)) {
+ for (SPObject *child = shown->firstChild(); child != NULL; child = child->getNext()) {
+ if (SP_IS_ITEM(child)) {
SP_ITEM(child)->invoke_hide(dkey);
}
}
@@ -685,12 +670,12 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b
if (needs_opacity) {
dc.popGroupToSource(); // pop raw pattern
- dc.paint(opacity); // apply opacity
+ dc.paint(opacity); // apply opacity
}
cairo_pattern_t *cp = cairo_pattern_create_for_surface(pattern_surface.raw());
// Apply transformation to user space. Also compensate for oversampling.
- ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * pattern_surface.drawingTransform() );
+ ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * pattern_surface.drawingTransform());
cairo_pattern_set_extend(cp, CAIRO_EXTEND_REPEAT);
diff --git a/src/sp-pattern.h b/src/sp-pattern.h
index 34dd5a05b..145bb934e 100644
--- a/src/sp-pattern.h
+++ b/src/sp-pattern.h
@@ -1,9 +1,6 @@
-#ifndef SEEN_SP_PATTERN_H
-#define SEEN_SP_PATTERN_H
-
-/*
+/** @file
* SVG <pattern> implementation
- *
+ *//*
* Author:
* Lauris Kaplinski <lauris@kaplinski.com>
* Abhishek Sharma
@@ -13,95 +10,131 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#define SP_PATTERN(obj) (dynamic_cast<SPPattern*>((SPObject*)obj))
-#define SP_IS_PATTERN(obj) (dynamic_cast<const SPPattern*>((SPObject*)obj) != NULL)
+#ifndef SEEN_SP_PATTERN_H
+#define SEEN_SP_PATTERN_H
-class SPPatternReference;
-class SPItem;
-typedef struct _GSList GSList;
+#include <list>
+#include <stddef.h>
+#include <glibmm/ustring.h>
+#include <sigc++/connection.h>
#include "svg/svg-length.h"
#include "sp-paint-server.h"
#include "uri-references.h"
#include "viewbox.h"
-#include <sigc++/connection.h>
+class SPPatternReference;
+class SPItem;
+namespace Inkscape {
+namespace XML {
+
+class Node;
+}
+}
+
+#define SP_PATTERN(obj) (dynamic_cast<SPPattern *>((SPObject *)obj))
+#define SP_IS_PATTERN(obj) (dynamic_cast<const SPPattern *>((SPObject *)obj) != NULL)
class SPPattern : public SPPaintServer, public SPViewBox {
public:
- SPPattern();
- virtual ~SPPattern();
+ enum PatternUnits { UNITS_USERSPACEONUSE, UNITS_OBJECTBOUNDINGBOX };
+
+ SPPattern();
+ virtual ~SPPattern();
/* Reference (href) */
- char *href;
+ Glib::ustring href;
SPPatternReference *ref;
- /* patternUnits and patternContentUnits attribute */
- unsigned int patternUnits : 1;
- unsigned int patternUnits_set : 1;
- unsigned int patternContentUnits : 1;
- unsigned int patternContentUnits_set : 1;
- /* patternTransform attribute */
- Geom::Affine patternTransform;
- unsigned int patternTransform_set : 1;
- /* Tile rectangle */
- SVGLength x;
- SVGLength y;
- SVGLength width;
- SVGLength height;
-
- sigc::connection modified_connection;
+ gdouble x() const;
+ gdouble y() const;
+ gdouble width() const;
+ gdouble height() const;
+ Geom::OptRect viewbox() const;
+ SPPattern::PatternUnits patternUnits() const;
+ SPPattern::PatternUnits patternContentUnits() const;
+ Geom::Affine const &getTransform() const;
+ SPPattern *rootPattern(); // TODO: const
+
+ SPPattern *clone_if_necessary(SPItem *item, const gchar *property);
+ void transform_multiply(Geom::Affine postmul, bool set);
+
+ /**
+ * @brief create a new pattern in XML tree
+ * @return created pattern id
+ */
+ static const gchar *produce(const std::vector<Inkscape::XML::Node *> &reprs, Geom::Rect bounds,
+ SPDocument *document, Geom::Affine transform, Geom::Affine move);
bool isValid() const;
- virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity);
+ virtual cairo_pattern_t *pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity);
protected:
- virtual void build(SPDocument* doc, Inkscape::XML::Node* repr);
- virtual void release();
- virtual void set(unsigned int key, const gchar* value);
- virtual void update(SPCtx* ctx, unsigned int flags);
- virtual void modified(unsigned int flags);
+ virtual void build(SPDocument *doc, Inkscape::XML::Node *repr);
+ virtual void release();
+ virtual void set(unsigned int key, const gchar *value);
+ virtual void update(SPCtx *ctx, unsigned int flags);
+ virtual void modified(unsigned int flags);
+
+private:
+ bool _hasItemChildren() const;
+ void _getChildren(std::list<SPObject *> &l);
+ SPPattern *_chain() const;
+
+ /**
+ Count how many times pattern is used by the styles of o and its descendants
+ */
+ guint _countHrefs(SPObject *o) const;
+
+ /**
+ Gets called when the pattern is reattached to another <pattern>
+ */
+ void _onRefChanged(SPObject *old_ref, SPObject *ref);
+
+ /**
+ Gets called when the referenced <pattern> is changed
+ */
+ void _onRefModified(SPObject *ref, guint flags);
+
+ /* patternUnits and patternContentUnits attribute */
+ PatternUnits _pattern_units : 1;
+ bool _pattern_units_set : 1;
+ PatternUnits _pattern_content_units : 1;
+ bool _pattern_content_units_set : 1;
+ /* patternTransform attribute */
+ Geom::Affine _pattern_transform;
+ bool _pattern_transform_set : 1;
+ /* Tile rectangle */
+ SVGLength _x;
+ SVGLength _y;
+ SVGLength _width;
+ SVGLength _height;
+
+ sigc::connection _modified_connection;
};
class SPPatternReference : public Inkscape::URIReference {
public:
- SPPatternReference (SPObject *obj) : URIReference(obj) {}
- SPPattern *getObject() const {
+ SPPatternReference(SPObject *obj)
+ : URIReference(obj)
+ {
+ }
+
+ SPPattern *getObject() const
+ {
return reinterpret_cast<SPPattern *>(URIReference::getObject());
}
protected:
- virtual bool _acceptObject(SPObject *obj) const {
- return SP_IS_PATTERN (obj);
+ virtual bool _acceptObject(SPObject *obj) const
+ {
+ return SP_IS_PATTERN(obj);
}
};
-enum {
- SP_PATTERN_UNITS_USERSPACEONUSE,
- SP_PATTERN_UNITS_OBJECTBOUNDINGBOX
-};
-
-unsigned int pattern_users (SPPattern *pattern);
-SPPattern *pattern_chain (SPPattern *pattern);
-SPPattern *sp_pattern_clone_if_necessary (SPItem *item, SPPattern *pattern, const char *property);
-void sp_pattern_transform_multiply (SPPattern *pattern, Geom::Affine postmul, bool set);
-
-const char *pattern_tile (const std::vector<Inkscape::XML::Node*> &reprs, Geom::Rect bounds, SPDocument *document, Geom::Affine transform, Geom::Affine move);
-
-SPPattern *pattern_getroot (SPPattern *pat);
-
-unsigned int pattern_patternUnits (SPPattern const *pat);
-unsigned int pattern_patternContentUnits (SPPattern const *pat);
-Geom::Affine const &pattern_patternTransform(SPPattern const *pat);
-double pattern_x (SPPattern const *pat);
-double pattern_y (SPPattern const *pat);
-double pattern_width (SPPattern const *pat);
-double pattern_height (SPPattern const *pat);
-Geom::OptRect pattern_viewBox (SPPattern const *pat);
-
#endif // SEEN_SP_PATTERN_H
/*
diff --git a/src/sp-use.cpp b/src/sp-use.cpp
index 239f487a4..c8a0830c1 100644
--- a/src/sp-use.cpp
+++ b/src/sp-use.cpp
@@ -22,6 +22,8 @@
#include "display/drawing-group.h"
#include "attributes.h"
#include "document.h"
+#include "sp-clippath.h"
+#include "sp-mask.h"
#include "sp-factory.h"
#include "sp-flowregion.h"
#include "uri.h"
@@ -426,16 +428,43 @@ void SPUse::move_compensate(Geom::Affine const *mp) {
return;
Geom::Affine m(*mp);
+ Geom::Affine t = this->get_parent_transform();
+ Geom::Affine clone_move = t.inverse() * m * t;
// this is not a simple move, do not try to compensate
- if (!(m.isTranslation()))
+ if (!(m.isTranslation())){
+ //BUT move clippaths accordingly.
+ //if clone has a clippath, move it accordingly
+ if(clip_ref->getObject()){
+ SPObject *clip = clip_ref->getObject()->firstChild() ;
+ while(clip){
+ SPItem *item = (SPItem*) clip;
+ if(item){
+ item->transform *= m;
+ Geom::Affine identity;
+ item->doWriteTransform(clip->getRepr(),item->transform, &identity);
+ }
+ clip = clip->getNext();
+ }
+ }
+ if(mask_ref->getObject()){
+ SPObject *mask = mask_ref->getObject()->firstChild() ;
+ while(mask){
+ SPItem *item = (SPItem*) mask;
+ if(item){
+ item->transform *= m;
+ Geom::Affine identity;
+ item->doWriteTransform(mask->getRepr(),item->transform, &identity);
+ }
+ mask = mask->getNext();
+ }
+ }
return;
+ }
// restore item->transform field from the repr, in case it was changed by seltrans
this->readAttr ("transform");
- Geom::Affine t = this->get_parent_transform();
- Geom::Affine clone_move = t.inverse() * m * t;
// calculate the compensation matrix and the advertized movement matrix
Geom::Affine advertized_move;
@@ -449,6 +478,33 @@ void SPUse::move_compensate(Geom::Affine const *mp) {
g_assert_not_reached();
}
+ //if clone has a clippath, move it accordingly
+ if(clip_ref->getObject()){
+ SPObject *clip = clip_ref->getObject()->firstChild() ;
+ while(clip){
+ SPItem *item = (SPItem*) clip;
+ if(item){
+ item->transform *= clone_move.inverse();
+ Geom::Affine identity;
+ item->doWriteTransform(clip->getRepr(),item->transform, &identity);
+ }
+ clip = clip->getNext();
+ }
+ }
+ if(mask_ref->getObject()){
+ SPObject *mask = mask_ref->getObject()->firstChild() ;
+ while(mask){
+ SPItem *item = (SPItem*) mask;
+ if(item){
+ item->transform *= clone_move.inverse();
+ Geom::Affine identity;
+ item->doWriteTransform(mask->getRepr(),item->transform, &identity);
+ }
+ mask = mask->getNext();
+ }
+ }
+
+
// commit the compensation
this->transform *= clone_move;
this->doWriteTransform(this->getRepr(), this->transform, &advertized_move);
diff --git a/src/style-enums.h b/src/style-enums.h
index f235b6699..29b8e2130 100644
--- a/src/style-enums.h
+++ b/src/style-enums.h
@@ -74,44 +74,45 @@ enum SPCSSFontStretch {
// Can select more than one
enum SPCSSFontVariantLigatures {
- SP_CSS_FONT_VARIANT_LIGATURES_NORMAL,
- SP_CSS_FONT_VARIANT_LIGATURES_NONE,
- SP_CSS_FONT_VARIANT_LIGATURES_COMMON,
- SP_CSS_FONT_VARIANT_LIGATURES_NO_COMMON,
- SP_CSS_FONT_VARIANT_LIGATURES_DISCRETIONARY,
- SP_CSS_FONT_VARIANT_LIGATURES_NO_DISCRETIONARY,
- SP_CSS_FONT_VARIANT_LIGATURES_HISTORICAL,
- SP_CSS_FONT_VARIANT_LIGATURES_NO_HISTORICAL,
- SP_CSS_FONT_VARIANT_LIGATURES_CONTEXTUAL,
- SP_CSS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL
+ SP_CSS_FONT_VARIANT_LIGATURES_NONE = 0,
+ SP_CSS_FONT_VARIANT_LIGATURES_COMMON = 1,
+ SP_CSS_FONT_VARIANT_LIGATURES_DISCRETIONARY = 2,
+ SP_CSS_FONT_VARIANT_LIGATURES_HISTORICAL = 4,
+ SP_CSS_FONT_VARIANT_LIGATURES_CONTEXTUAL = 8,
+ SP_CSS_FONT_VARIANT_LIGATURES_NORMAL = 9, // Special case
+ SP_CSS_FONT_VARIANT_LIGATURES_NOCOMMON = 16,
+ SP_CSS_FONT_VARIANT_LIGATURES_NODISCRETIONARY = 32,
+ SP_CSS_FONT_VARIANT_LIGATURES_NOHISTORICAL = 64,
+ SP_CSS_FONT_VARIANT_LIGATURES_NOCONTEXTUAL = 128
};
enum SPCSSFontVariantPosition {
- SP_CSS_FONT_VARIANT_POSITION_NORMAL,
- SP_CSS_FONT_VARIANT_POSITION_SUB,
- SP_CSS_FONT_VARIANT_POSITION_SUPER
+ SP_CSS_FONT_VARIANT_POSITION_NORMAL = 1,
+ SP_CSS_FONT_VARIANT_POSITION_SUB = 2,
+ SP_CSS_FONT_VARIANT_POSITION_SUPER = 4
};
enum SPCSSFontVariantCaps {
- SP_CSS_FONT_VARIANT_CAPS_NORMAL,
- SP_CSS_FONT_VARIANT_CAPS_SMALL,
- SP_CSS_FONT_VARIANT_CAPS_ALL_SMALL,
- SP_CSS_FONT_VARIANT_CAPS_PETITE,
- SP_CSS_FONT_VARIANT_CAPS_ALL_PETITE,
- SP_CSS_FONT_VARIANT_CAPS_UNICASE,
- SP_CSS_FONT_VARIANT_CAPS_TITLING,
+ SP_CSS_FONT_VARIANT_CAPS_NORMAL = 1,
+ SP_CSS_FONT_VARIANT_CAPS_SMALL = 2,
+ SP_CSS_FONT_VARIANT_CAPS_ALL_SMALL = 4,
+ SP_CSS_FONT_VARIANT_CAPS_PETITE = 8,
+ SP_CSS_FONT_VARIANT_CAPS_ALL_PETITE = 16,
+ SP_CSS_FONT_VARIANT_CAPS_UNICASE = 32,
+ SP_CSS_FONT_VARIANT_CAPS_TITLING = 64
};
+// Can select more than one (see spec)
enum SPCSSFontVariantNumeric {
- SP_CSS_FONT_VARIANT_NUMERIC_NORMAL,
- SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS,
- SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS,
- SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS,
- SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS,
- SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS,
- SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS,
- SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL,
- SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO
+ SP_CSS_FONT_VARIANT_NUMERIC_NORMAL = 0,
+ SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS = 1,
+ SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS = 2,
+ SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS = 4,
+ SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS = 8,
+ SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS = 16,
+ SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS = 32,
+ SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL = 64,
+ SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO = 128
};
enum SPCSSFontVariantAlternates {
@@ -376,16 +377,16 @@ static SPStyleEnum const enum_font_stretch[] = {
};
static SPStyleEnum const enum_font_variant_ligatures[] = {
- {"normal", SP_CSS_FONT_VARIANT_LIGATURES_NORMAL},
- {"none", SP_CSS_FONT_VARIANT_LIGATURES_NONE},
- {"common-ligatures", SP_CSS_FONT_VARIANT_LIGATURES_COMMON},
- {"no-common-ligatures", SP_CSS_FONT_VARIANT_LIGATURES_NO_COMMON},
- {"discretionary-ligatures", SP_CSS_FONT_VARIANT_LIGATURES_DISCRETIONARY},
- {"no-discretionary-ligatures", SP_CSS_FONT_VARIANT_LIGATURES_NO_DISCRETIONARY},
- {"historical-ligatures", SP_CSS_FONT_VARIANT_LIGATURES_HISTORICAL},
- {"nohistorical-ligatures", SP_CSS_FONT_VARIANT_LIGATURES_NO_HISTORICAL},
- {"contextual", SP_CSS_FONT_VARIANT_LIGATURES_CONTEXTUAL},
- {"no-contextual", SP_CSS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL},
+ {"none", SP_CSS_FONT_VARIANT_LIGATURES_NONE},
+ {"common-ligatures", SP_CSS_FONT_VARIANT_LIGATURES_COMMON},
+ {"discretionary-ligatures", SP_CSS_FONT_VARIANT_LIGATURES_DISCRETIONARY},
+ {"historical-ligatures", SP_CSS_FONT_VARIANT_LIGATURES_HISTORICAL},
+ {"contextual", SP_CSS_FONT_VARIANT_LIGATURES_CONTEXTUAL},
+ {"normal", SP_CSS_FONT_VARIANT_LIGATURES_NORMAL},
+ {"no-common-ligatures", SP_CSS_FONT_VARIANT_LIGATURES_NOCOMMON},
+ {"no-discretionary-ligatures", SP_CSS_FONT_VARIANT_LIGATURES_NODISCRETIONARY},
+ {"no-historical-ligatures", SP_CSS_FONT_VARIANT_LIGATURES_NOHISTORICAL},
+ {"no-contextual", SP_CSS_FONT_VARIANT_LIGATURES_NOCONTEXTUAL},
{NULL, -1}
};
@@ -401,7 +402,7 @@ static SPStyleEnum const enum_font_variant_caps[] = {
{"small-caps", SP_CSS_FONT_VARIANT_CAPS_SMALL},
{"all-small-caps", SP_CSS_FONT_VARIANT_CAPS_ALL_SMALL},
{"petite-caps", SP_CSS_FONT_VARIANT_CAPS_PETITE},
- {"all_petite-caps", SP_CSS_FONT_VARIANT_CAPS_ALL_PETITE},
+ {"all-petite-caps", SP_CSS_FONT_VARIANT_CAPS_ALL_PETITE},
{"unicase", SP_CSS_FONT_VARIANT_CAPS_UNICASE},
{"titling", SP_CSS_FONT_VARIANT_CAPS_TITLING},
{NULL, -1}
diff --git a/src/style-internal.cpp b/src/style-internal.cpp
index 915282301..c117a97f9 100644
--- a/src/style-internal.cpp
+++ b/src/style-internal.cpp
@@ -45,6 +45,8 @@
#include <sigc++/functors/ptr_fun.h>
#include <sigc++/adaptors/bind.h>
+#include <glibmm/regex.h>
+
// TODO REMOVE OR MAKE MEMBER FUNCTIONS
void sp_style_fill_paint_server_ref_changed( SPObject *old_ref, SPObject *ref, SPStyle *style);
void sp_style_stroke_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style);
@@ -664,6 +666,241 @@ SPIEnum::operator==(const SPIBase& rhs) {
}
+// SPIEnumBits ----------------------------------------------------------
+// Used for 'font-variant-xxx'
+void
+SPIEnumBits::read( gchar const *str ) {
+
+ if( !str ) return;
+ std::cout << "SPIEnumBits: " << name << ": " << str << std::endl;
+ if( !strcmp(str, "inherit") ) {
+ set = true;
+ inherit = true;
+ } else {
+ for (unsigned i = 0; enums[i].key; i++) {
+ if (!strcmp(str, enums[i].key)) {
+ std::cout << " found: " << enums[i].key << std::endl;
+ set = true;
+ inherit = false;
+ value += enums[i].value;
+ /* Save copying for values not needing it */
+ computed = value;
+ }
+ }
+ }
+}
+
+const Glib::ustring
+SPIEnumBits::write( guint const flags, SPIBase const *const base) const {
+
+ SPIEnum const *const my_base = dynamic_cast<const SPIEnum*>(base);
+ if ( (flags & SP_STYLE_FLAG_ALWAYS) ||
+ ((flags & SP_STYLE_FLAG_IFSET) && this->set) ||
+ ((flags & SP_STYLE_FLAG_IFDIFF) && this->set
+ && (!my_base->set || this != my_base )))
+ {
+ if (this->inherit) {
+ return (name + ":inherit;");
+ }
+ if (this->value == 0 ) {
+ return (name + ":normal");
+ }
+ Glib::ustring return_string = name + ":";
+ unsigned j = 1;
+ for (unsigned i = 0; enums[i].key; ++i) {
+ if (j & this->value ) {
+ return_string += enums[i].value + " ";
+ }
+ j *= 2;
+ }
+ return return_string;
+ }
+ return Glib::ustring("");
+}
+
+
+// SPILigatures -----------------------------------------------------
+// Used for 'font-variant-ligatures'
+void
+SPILigatures::read( gchar const *str ) {
+
+ if( !str ) return;
+
+ value = SP_CSS_FONT_VARIANT_LIGATURES_NORMAL;
+ if( !strcmp(str, "inherit") ) {
+ set = true;
+ inherit = true;
+ } else if (!strcmp(str, "normal" )) {
+ // Defaults for TrueType
+ inherit = false;
+ set = true;
+ } else if (!strcmp(str, "none" )) {
+ value = SP_CSS_FONT_VARIANT_LIGATURES_NONE;
+ inherit = false;
+ set = true;
+ } else {
+ // We need to parse in order
+ std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("\\s+", str );
+ for( unsigned i = 0; i < tokens.size(); ++i ) {
+ for (unsigned j = 0; enums[j].key; ++j ) {
+ if (tokens[i].compare( enums[j].key ) == 0 ) {
+ set = true;
+ inherit = false;
+ if( enums[j].value < SP_CSS_FONT_VARIANT_LIGATURES_NOCOMMON ) {
+ // Turn on
+ value |= enums[j].value;
+ } else {
+ // Turn off
+ value &= ~(enums[j].value >> 4);
+ }
+ }
+ }
+ }
+ }
+ computed = value;
+}
+
+const Glib::ustring
+SPILigatures::write( guint const flags, SPIBase const *const base) const {
+
+ SPIEnum const *const my_base = dynamic_cast<const SPIEnum*>(base);
+ if ( (flags & SP_STYLE_FLAG_ALWAYS) ||
+ ((flags & SP_STYLE_FLAG_IFSET) && this->set) ||
+ ((flags & SP_STYLE_FLAG_IFDIFF) && this->set
+ && (!my_base->set || this != my_base )))
+ {
+ if (this->inherit) {
+ return (name + ":inherit;");
+ }
+ if (value == SP_CSS_FONT_VARIANT_LIGATURES_NONE ) {
+ return (name + ":none;");
+ }
+ if (value == SP_CSS_FONT_VARIANT_LIGATURES_NORMAL ) {
+ return (name + ":normal;");
+ }
+
+ Glib::ustring return_string = name + ":";
+ if ( !(value & SP_CSS_FONT_VARIANT_LIGATURES_COMMON) )
+ return_string += "no-common-ligatures ";
+ if ( value & SP_CSS_FONT_VARIANT_LIGATURES_DISCRETIONARY )
+ return_string += "discretionary-ligatures ";
+ if ( value & SP_CSS_FONT_VARIANT_LIGATURES_HISTORICAL )
+ return_string += "historical-ligatures ";
+ if ( !(value & SP_CSS_FONT_VARIANT_LIGATURES_CONTEXTUAL) )
+ return_string += "no-contextual ";
+ return_string.erase( return_string.size() - 1 );
+ return_string += ";";
+ return return_string;
+ }
+ return Glib::ustring("");
+}
+
+
+// SPINumeric -----------------------------------------------------
+// Used for 'font-variant-numeric'
+void
+SPINumeric::read( gchar const *str ) {
+
+ if( !str ) return;
+
+ value = SP_CSS_FONT_VARIANT_NUMERIC_NORMAL;
+ if( !strcmp(str, "inherit") ) {
+ set = true;
+ inherit = true;
+ } else if (!strcmp(str, "normal" )) {
+ // Defaults for TrueType
+ inherit = false;
+ set = true;
+ } else {
+ // We need to parse in order
+ std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("\\s+", str );
+ for( unsigned i = 0; i < tokens.size(); ++i ) {
+ for (unsigned j = 0; enums[j].key; ++j ) {
+ if (tokens[i].compare( enums[j].key ) == 0 ) {
+ set = true;
+ inherit = false;
+ value |= enums[j].value;
+
+ // Must switch off incompatible value
+ switch (enums[j].value ) {
+ case SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS:
+ value &= ~SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS;
+ break;
+ case SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS:
+ value &= ~SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS;
+ break;
+
+ case SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS:
+ value &= ~SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS;
+ break;
+ case SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS:
+ value &= ~SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS;
+ break;
+
+ case SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS:
+ value &= ~SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS;
+ break;
+ case SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS:
+ value &= ~SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS;
+ break;
+
+ case SP_CSS_FONT_VARIANT_NUMERIC_NORMAL:
+ case SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL:
+ case SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO:
+ // Do nothing
+ break;
+
+ default:
+ std::cerr << "SPINumeric::read(): Invalid value." << std::endl;
+ break;
+ }
+ }
+ }
+ }
+ }
+ computed = value;
+}
+
+const Glib::ustring
+SPINumeric::write( guint const flags, SPIBase const *const base) const {
+
+ SPIEnum const *const my_base = dynamic_cast<const SPIEnum*>(base);
+ if ( (flags & SP_STYLE_FLAG_ALWAYS) ||
+ ((flags & SP_STYLE_FLAG_IFSET) && this->set) ||
+ ((flags & SP_STYLE_FLAG_IFDIFF) && this->set
+ && (!my_base->set || this != my_base )))
+ {
+ if (this->inherit) {
+ return (name + ":inherit;");
+ }
+ if (value == SP_CSS_FONT_VARIANT_NUMERIC_NORMAL ) {
+ return (name + ":normal;");
+ }
+
+ Glib::ustring return_string = name + ":";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS )
+ return_string += "lining-nums ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS )
+ return_string += "oldstyle-nums ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS )
+ return_string += "proportional-nums ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS )
+ return_string += "tabular-nums ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS )
+ return_string += "diagonal-fractions ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS )
+ return_string += "stacked-fractions ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL )
+ return_string += "ordinal ";
+ if ( value & SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO )
+ return_string += "slashed-zero ";
+ return_string.erase( return_string.size() - 1 );
+ return_string += ";";
+ return return_string;
+ }
+ return Glib::ustring("");
+}
+
// SPIString ------------------------------------------------------------
@@ -1694,6 +1931,11 @@ SPIFontSize::read( gchar const *str ) {
unit = length.unit;
value = length.value;
computed = length.computed;
+ /* Set a minimum font size to something much smaller than should ever (ever!) be encountered in a real file.
+ If a bad SVG file is encountered and this is zero odd things
+ might happen because the inverse is used in some scaling actions.
+ */
+ if ( computed <= 1.0e-32 ) { computed = 1.0e-32; }
if( unit == SP_CSS_UNIT_PERCENT ) {
type = SP_FONT_SIZE_PERCENTAGE;
} else {
@@ -1774,6 +2016,11 @@ SPIFontSize::cascade( const SPIBase* const parent ) {
break;
}
}
+ /* Set a minimum font size to something much smaller than should ever (ever!) be encountered in a real file.
+ If a bad SVG file is encountered and this is zero odd things
+ might happen because the inverse is used in some scaling actions.
+ */
+ if ( computed <= 1.0e-32 ) { computed = 1.0e-32; }
} else {
std::cerr << "SPIFontSize::cascade(): Incorrect parent type" << std::endl;
}
@@ -1862,6 +2109,11 @@ SPIFontSize::merge( const SPIBase* const parent ) {
}
}
} // Relative size
+ /* Set a minimum font size to something much smaller than should ever (ever!) be encountered in a real file.
+ If a bad SVG file is encountered and this is zero odd things
+ might happen because the inverse is used in some scaling actions.
+ */
+ if ( computed <= 1.0e-32 ) { computed = 1.0e-32; }
} // Parent set and not inherit
} else {
std::cerr << "SPIFontSize::merge(): Incorrect parent type" << std::endl;
diff --git a/src/style-internal.h b/src/style-internal.h
index a8f0c5096..bd2a92c8c 100644
--- a/src/style-internal.h
+++ b/src/style-internal.h
@@ -510,6 +510,77 @@ private:
};
+/// SPIEnum w/ bits, allows values with multiple key words.
+class SPIEnumBits : public SPIEnum
+{
+
+public:
+ SPIEnumBits() :
+ SPIEnum( "anonymous_enumbits", NULL )
+ {}
+
+ SPIEnumBits( Glib::ustring const &name, SPStyleEnum const *enums, unsigned value = 0, bool inherits = true ) :
+ SPIEnum( name, enums, value, inherit )
+ {}
+
+ virtual ~SPIEnumBits()
+ {}
+
+ virtual void read( gchar const *str );
+ virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET,
+ SPIBase const *const base = NULL ) const;
+
+};
+
+
+/// SPIEnum w/ extra bits. The 'font-variants-ligatures' property is a complete mess that needs
+/// special handling. For OpenType fonts the values 'common-ligatures', 'contextual',
+/// 'no-discretionary-ligatures', and 'no-historical-ligatures' are not useful but we still must be
+/// able to parse them.
+class SPILigatures : public SPIEnum
+{
+
+public:
+ SPILigatures() :
+ SPIEnum( "anonymous_enumligatures", NULL )
+ {}
+
+ SPILigatures( Glib::ustring const &name, SPStyleEnum const *enums) :
+ SPIEnum( name, enums, SP_CSS_FONT_VARIANT_NORMAL )
+ {}
+
+ virtual ~SPILigatures()
+ {}
+
+ virtual void read( gchar const *str );
+ virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET,
+ SPIBase const *const base = NULL ) const;
+};
+
+
+/// SPIEnum w/ extra bits. The 'font-variants-numeric' property is a complete mess that needs
+/// special handling. Multiple key words can be specified, some exclusive of others.
+class SPINumeric : public SPIEnum
+{
+
+public:
+ SPINumeric() :
+ SPIEnum( "anonymous_enumnumeric", NULL )
+ {}
+
+ SPINumeric( Glib::ustring const &name, SPStyleEnum const *enums) :
+ SPIEnum( name, enums, SP_CSS_FONT_VARIANT_NUMERIC_NORMAL )
+ {}
+
+ virtual ~SPINumeric()
+ {}
+
+ virtual void read( gchar const *str );
+ virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET,
+ SPIBase const *const base = NULL ) const;
+};
+
+
/// String type internal to SPStyle.
// Used for 'marker', ..., 'font', 'font-family', 'inkscape-font-specification'
class SPIString : public SPIBase
diff --git a/src/style-test.h b/src/style-test.h
index cd6769b24..c6bb665e0 100644
--- a/src/style-test.h
+++ b/src/style-test.h
@@ -109,13 +109,13 @@ public:
TestCase("font: 12pt/15pt sans-serif",
"font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:15pt;font-family:sans-serif"),
TestCase("font: 80% sans-serif",
- "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:80.00000119%;line-height:normal;font-family:sans-serif"),
+ "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:80%;line-height:normal;font-family:sans-serif"),
TestCase("font: x-large/110% 'new century schoolbook', serif",
- "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:x-large;line-height:110.00000238%;font-family:\'new century schoolbook\', serif"),
+ "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:x-large;line-height:110%;font-family:\'new century schoolbook\', serif"),
TestCase("font: bold italic large Palatino, serif",
"font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:large;line-height:normal;font-family:Palatino, serif"),
TestCase("font: normal small-caps 120%/120% fantasy",
- "font-style:normal;font-variant:small-caps;font-weight:normal;font-stretch:normal;font-size:120.00000477%;line-height:120.00000477%;font-family:fantasy"),
+ "font-style:normal;font-variant:small-caps;font-weight:normal;font-stretch:normal;font-size:120%;line-height:120%;font-family:fantasy"),
TestCase("font: condensed oblique 12pt 'Helvetica Neue', serif;",
"font-style:oblique;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:16px;line-height:normal;font-family:\'Helvetica Neue\', serif"),
@@ -137,6 +137,34 @@ public:
TestCase("font-weight:bolder"),
TestCase("font-stretch:condensed"), // SPIEnum
+ TestCase("font-variant-ligatures:none"), // SPILigatures
+ TestCase("font-variant-ligatures:normal"),
+ TestCase("font-variant-ligatures:no-common-ligatures"),
+ TestCase("font-variant-ligatures:discretionary-ligatures"),
+ TestCase("font-variant-ligatures:historical-ligatures"),
+ TestCase("font-variant-ligatures:no-contextual"),
+ TestCase("font-variant-ligatures:common-ligatures", "font-variant-ligatures:normal"),
+ TestCase("font-variant-ligatures:contextual", "font-variant-ligatures:normal"),
+ TestCase("font-variant-ligatures:no-common-ligatures historical-ligatures"),
+ TestCase("font-variant-ligatures:historical-ligatures no-contextual"),
+ TestCase("font-variant-position:normal"),
+ TestCase("font-variant-position:sub"),
+ TestCase("font-variant-position:super"),
+ TestCase("font-variant-caps:normal"),
+ TestCase("font-variant-caps:small-caps"),
+ TestCase("font-variant-caps:all-small-caps"),
+ TestCase("font-variant-numeric:normal"),
+ TestCase("font-variant-numeric:lining-nums"),
+ TestCase("font-variant-numeric:oldstyle-nums"),
+ TestCase("font-variant-numeric:proportional-nums"),
+ TestCase("font-variant-numeric:tabular-nums"),
+ TestCase("font-variant-numeric:diagonal-fractions"),
+ TestCase("font-variant-numeric:stacked-fractions"),
+ TestCase("font-variant-numeric:ordinal"),
+ TestCase("font-variant-numeric:slashed-zero"),
+ TestCase("font-variant-numeric:tabular-nums slashed-zero"),
+ TestCase("font-variant-numeric:tabular-nums proportional-nums", "font-variant-numeric:proportional-nums"),
+
// Should be moved down
TestCase("text-indent:12em"), // SPILength?
TestCase("text-align:center"), // SPIEnum
diff --git a/src/style.cpp b/src/style.cpp
index 49a13604b..b218f4e4d 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -119,10 +119,10 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) :
font_specification( "-inkscape-font-specification" ), // SPIString
// Font variants
- font_variant_ligatures( "font-variant-ligatures", enum_font_variant_ligatures, SP_CSS_FONT_VARIANT_LIGATURES_NORMAL ),
+ font_variant_ligatures( "font-variant-ligatures", enum_font_variant_ligatures ),
font_variant_position( "font-variant-position", enum_font_variant_position, SP_CSS_FONT_VARIANT_POSITION_NORMAL ),
font_variant_caps( "font-variant-caps", enum_font_variant_caps, SP_CSS_FONT_VARIANT_CAPS_NORMAL ),
- font_variant_numeric( "font-variant-numeric", enum_font_variant_numeric, SP_CSS_FONT_VARIANT_NUMERIC_NORMAL ),
+ font_variant_numeric( "font-variant-numeric", enum_font_variant_numeric ),
font_variant_alternates("font-variant-alternates", enum_font_variant_alternates, SP_CSS_FONT_VARIANT_ALTERNATES_NORMAL ),
font_variant_east_asian("font-variant-east_asian", enum_font_variant_east_asian, SP_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL ),
font_feature_settings( "font-feature-settings", "normal" ),
diff --git a/src/style.h b/src/style.h
index 2618662f5..8e22b3121 100644
--- a/src/style.h
+++ b/src/style.h
@@ -113,13 +113,13 @@ public:
/* Font variants -------------------- */
/** Font variant ligatures */
- SPIEnum font_variant_ligatures;
+ SPILigatures font_variant_ligatures;
/** Font variant position (subscript/superscript) */
SPIEnum font_variant_position;
/** Font variant caps (small caps) */
SPIEnum font_variant_caps;
/** Font variant numeric (numerical formatting) */
- SPIEnum font_variant_numeric;
+ SPINumeric font_variant_numeric;
/** Font variant alternates (alternates/swatches) */
SPIEnum font_variant_alternates;
/** Font variant East Asian */
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index 991d11feb..fbf25d039 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -6,6 +6,7 @@ set(ui_SRC
interface.cpp
object-edit.cpp
previewholder.cpp
+ selected-color.cpp
shape-editor.cpp
tool-factory.cpp
tools-switch.cpp
@@ -115,13 +116,20 @@ set(ui_SRC
widget/anchor-selector.cpp
widget/button.cpp
widget/clipmaskicon.cpp
+ widget/color-entry.cpp
+ widget/color-icc-selector.cpp
+ widget/color-notebook.cpp
widget/color-picker.cpp
widget/color-preview.cpp
+ widget/color-scales.cpp
+ widget/color-slider.cpp
+ widget/color-wheel-selector.cpp
widget/dock-item.cpp
widget/dock.cpp
widget/entity-entry.cpp
widget/entry.cpp
widget/filter-effect-chooser.cpp
+ widget/font-variants.cpp
widget/frame.cpp
widget/gimpcolorwheel.c
widget/gimpspinscale.c
@@ -174,6 +182,7 @@ set(ui_SRC
previewable.h
previewfillable.h
previewholder.h
+ selected-color.h
shape-editor.h
tool-factory.h
tools-switch.h
@@ -287,14 +296,21 @@ set(ui_SRC
widget/anchor-selector.h
widget/attr-widget.h
widget/button.h
+ widget/color-entry.h
+ widget/color-icc-selector.h
+ widget/color-notebook.h
widget/color-picker.h
widget/color-preview.h
+ widget/color-scales.h
+ widget/color-slider.h
+ widget/color-wheel-selector.h
widget/combo-enums.h
widget/dock-item.h
widget/dock.h
widget/entity-entry.h
widget/entry.h
widget/filter-effect-chooser.h
+ widget/font-variants.h
widget/frame.h
widget/gimpspinscale.h
widget/gimpcolorwheel.h
diff --git a/src/ui/Makefile_insert b/src/ui/Makefile_insert
index f94cba4e9..bbfdb532c 100644
--- a/src/ui/Makefile_insert
+++ b/src/ui/Makefile_insert
@@ -19,6 +19,8 @@ ink_common_sources += \
ui/previewfillable.h \
ui/previewholder.cpp \
ui/previewholder.h \
+ ui/selected-color.h \
+ ui/selected-color.cpp \
ui/shape-editor.cpp \
ui/shape-editor.h \
ui/tool-factory.cpp \
diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp
index 65351cb68..c6888386f 100644
--- a/src/ui/dialog/layers.cpp
+++ b/src/ui/dialog/layers.cpp
@@ -713,13 +713,21 @@ bool LayersPanel::_handleDragDrop(const Glib::RefPtr<Gdk::DragContext>& /*contex
*/
void LayersPanel::_doTreeMove( )
{
- if (_dnd_source ) {
+ if (_dnd_source && _dnd_source->getRepr() ) {
+ if(!_dnd_target){
+ _dnd_source->doWriteTransform(_dnd_source->getRepr(), _dnd_source->document->getRoot()->i2doc_affine().inverse() * _dnd_source->i2doc_affine());
+ }else{
+ SPItem* parent = _dnd_into ? _dnd_target : dynamic_cast<SPItem*>(_dnd_target->parent);
+ if(parent){
+ Geom::Affine move = parent->i2doc_affine().inverse() * _dnd_source->i2doc_affine();
+ _dnd_source->doWriteTransform(_dnd_source->getRepr(), move);
+ }
+ }
_dnd_source->moveTo(_dnd_target, _dnd_into);
_selectLayer(_dnd_source);
_dnd_source = NULL;
DocumentUndo::done( _desktop->doc() , SP_VERB_NONE,
_("Moved layer"));
-
}
}
diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp
index f63b19e86..061055feb 100644
--- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp
+++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp
@@ -27,7 +27,6 @@
#include "selection-chemistry.h"
#include "ui/icon-names.h"
#include "ui/widget/imagetoggler.h"
-#include "util/units.h"
#include <cmath>
//#include "event-context.h"
@@ -122,18 +121,14 @@ void FilletChamferPropertiesDialog::showDialog(
SPDesktop *desktop, Geom::Point knotpoint,
const Inkscape::LivePathEffect::
FilletChamferPointArrayParamKnotHolderEntity *pt,
- const gchar *unit,
bool use_distance,
- bool aprox_radius,
- Glib::ustring documentUnit)
+ bool aprox_radius)
{
FilletChamferPropertiesDialog *dialog = new FilletChamferPropertiesDialog();
dialog->_set_desktop(desktop);
- dialog->_set_unit(unit);
dialog->_set_use_distance(use_distance);
dialog->_set_aprox(aprox_radius);
- dialog->_set_document_unit(documentUnit);
dialog->_set_knot_point(knotpoint);
dialog->_set_pt(pt);
@@ -168,7 +163,6 @@ void FilletChamferPropertiesDialog::_apply()
}
d_pos = _index + (d_pos / 100);
} else {
- d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, document_unit);
d_pos = d_pos * -1;
}
_knotpoint->knot_set_offset(Geom::Point(d_pos, d_width));
@@ -218,11 +212,9 @@ void FilletChamferPropertiesDialog::_set_knot_point(Geom::Point knotpoint)
_fillet_chamfer_position_label.set_label(_("Position (%):"));
} else {
_flexible = false;
- std::string posConcat = Glib::ustring::compose (_("%1 (%2):"), distance_or_radius, unit);
+ std::string posConcat = Glib::ustring::compose (_("%1:"), distance_or_radius);
_fillet_chamfer_position_label.set_label(_(posConcat.c_str()));
position = knotpoint[Geom::X] * -1;
-
- position = Inkscape::Util::Quantity::convert(position, document_unit, unit);
}
_fillet_chamfer_position_numeric.set_value(position);
if (knotpoint.y() == 1) {
@@ -247,16 +239,6 @@ void FilletChamferPropertiesDialog::_set_pt(
pt);
}
-void FilletChamferPropertiesDialog::_set_unit(const gchar *abbr)
-{
- unit = abbr;
-}
-
-void FilletChamferPropertiesDialog::_set_document_unit(Glib::ustring abbr)
-{
- document_unit = abbr;
-}
-
void FilletChamferPropertiesDialog::_set_use_distance(bool use_knot_distance)
{
use_distance = use_knot_distance;
diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h
index 870a1734f..99494bd63 100644
--- a/src/ui/dialog/lpe-fillet-chamfer-properties.h
+++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h
@@ -30,10 +30,8 @@ public:
static void showDialog(SPDesktop *desktop, Geom::Point knotpoint,
const Inkscape::LivePathEffect::
FilletChamferPointArrayParamKnotHolderEntity *pt,
- const gchar *unit,
bool use_distance,
- bool aprox_radius,
- Glib::ustring documentUnit);
+ bool aprox_radius);
protected:
@@ -68,15 +66,11 @@ protected:
void _set_desktop(SPDesktop *desktop);
void _set_pt(const Inkscape::LivePathEffect::
FilletChamferPointArrayParamKnotHolderEntity *pt);
- void _set_unit(const gchar *abbr);
- void _set_document_unit(Glib::ustring abbr);
void _set_use_distance(bool use_knot_distance);
void _set_aprox(bool aprox_radius);
void _apply();
void _close();
bool _flexible;
- const gchar *unit;
- Glib::ustring document_unit;
bool use_distance;
bool aprox;
void _set_knot_point(Geom::Point knotpoint);
diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp
index fc21a30d4..75430ed44 100644
--- a/src/ui/dialog/object-properties.cpp
+++ b/src/ui/dialog/object-properties.cpp
@@ -529,10 +529,12 @@ void ObjectProperties::_imageRenderingChanged()
SPCSSAttr *css = sp_repr_css_attr_new();
sp_repr_css_set_property(css, "image-rendering", scale.c_str());
Inkscape::XML::Node *image_node = item->getRepr();
- if( image_node ) {
+ if (image_node) {
sp_repr_css_change(image_node, css, "style");
+ DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM,
+ _("Set image rendering option"));
}
- sp_repr_css_attr_unref( css );
+ sp_repr_css_attr_unref(css);
_blocked = false;
}
diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp
index 781c6ef93..be04e7149 100644
--- a/src/ui/dialog/objects.cpp
+++ b/src/ui/dialog/objects.cpp
@@ -45,6 +45,7 @@
#include "style.h"
#include "ui/tools-switch.h"
#include "ui/icon-names.h"
+#include "ui/selected-color.h"
#include "ui/widget/imagetoggler.h"
#include "ui/widget/layertypeicon.h"
#include "ui/widget/insertordericon.h"
@@ -53,7 +54,7 @@
#include "ui/tools/node-tool.h"
#include "ui/tools/tool-base.h"
#include "verbs.h"
-#include "widgets/sp-color-notebook.h"
+#include "ui/widget/color-notebook.h"
#include "widgets/icon.h"
#include "xml/node.h"
#include "xml/node-observer.h"
@@ -928,12 +929,12 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event)
//If the current item is not selected, store only it in the highlight source
_storeHighlightTarget(iter);
}
- if (_colorSelector)
+ if (_selectedColor)
{
//Set up the color selector
SPColor color;
color.set( row[_model->_colHighlight] );
- _colorSelector->base->setColorAlpha(color, SP_RGBA32_A_F(row[_model->_colHighlight]));
+ _selectedColor->setColorAlpha(color, SP_RGBA32_A_F(row[_model->_colHighlight]));
}
//Show the color selector dialog
_colorSelectorDialog.show();
@@ -1440,17 +1441,16 @@ void ObjectsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk:
* @param csel Color selector
* @param cp Objects panel
*/
-void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp)
+void ObjectsPanel::_highlightPickerColorMod()
{
SPColor color;
float alpha = 0;
- csel->base->getColorAlpha(color, alpha);
+ _selectedColor->colorAlpha(color, alpha);
+
guint32 rgba = color.toRGBA32( alpha );
-
- ObjectsPanel *ptr = reinterpret_cast<ObjectsPanel *>(cp);
//Set the highlight color for all items in the _highlight_target (all selected items)
- for (std::vector<SPItem *>::iterator iter = ptr->_highlight_target.begin(); iter != ptr->_highlight_target.end(); ++iter)
+ for (std::vector<SPItem *>::iterator iter = _highlight_target.begin(); iter != _highlight_target.end(); ++iter)
{
SPItem * target = *iter;
target->setHighlightColor(rgba);
@@ -1922,18 +1922,16 @@ ObjectsPanel::ObjectsPanel() :
_colorSelectorDialog.set_title (_("Select Highlight Color"));
_colorSelectorDialog.set_border_width (4);
_colorSelectorDialog.property_modal() = true;
- _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK));
+ _selectedColor.reset(new Inkscape::UI::SelectedColor);
+ Gtk::Widget *color_selector = Gtk::manage(new Inkscape::UI::Widget::ColorNotebook(*_selectedColor));
_colorSelectorDialog.get_vbox()->pack_start (
- *Glib::wrap(&_colorSelector->vbox), true, true, 0);
+ *color_selector, true, true, 0);
- g_signal_connect(G_OBJECT(_colorSelector), "dragged",
- G_CALLBACK(sp_highlight_picker_color_mod), (void *)this);
- g_signal_connect(G_OBJECT(_colorSelector), "released",
- G_CALLBACK(sp_highlight_picker_color_mod), (void *)this);
- g_signal_connect(G_OBJECT(_colorSelector), "changed",
- G_CALLBACK(sp_highlight_picker_color_mod), (void *)this);
+ _selectedColor->signal_dragged.connect(sigc::mem_fun(*this, &ObjectsPanel::_highlightPickerColorMod));
+ _selectedColor->signal_released.connect(sigc::mem_fun(*this, &ObjectsPanel::_highlightPickerColorMod));
+ _selectedColor->signal_changed.connect(sigc::mem_fun(*this, &ObjectsPanel::_highlightPickerColorMod));
- gtk_widget_show(GTK_WIDGET(_colorSelector));
+ color_selector->show();
setDesktop( targetDesktop );
@@ -1951,7 +1949,6 @@ ObjectsPanel::~ObjectsPanel()
{
//Close the highlight selection dialog
_colorSelectorDialog.hide();
- _colorSelector = NULL;
//Set the desktop to null, which will disconnect all object watchers
setDesktop(NULL);
diff --git a/src/ui/dialog/objects.h b/src/ui/dialog/objects.h
index 1842fea11..7a826d02e 100644
--- a/src/ui/dialog/objects.h
+++ b/src/ui/dialog/objects.h
@@ -16,6 +16,7 @@
# include <config.h>
#endif
+#include <boost/scoped_ptr.hpp>
#include <gtkmm/box.h>
#include <gtkmm/treeview.h>
#include <gtkmm/treestore.h>
@@ -36,6 +37,9 @@ struct SPColorSelector;
namespace Inkscape {
namespace UI {
+
+class SelectedColor;
+
namespace Dialog {
@@ -166,8 +170,7 @@ private:
Gtk::Alignment _blur_alignment;
Gtk::Dialog _colorSelectorDialog;
- SPColorSelector *_colorSelector;
-
+ boost::scoped_ptr<Inkscape::UI::SelectedColor> _selectedColor;
//Methods:
@@ -233,7 +236,7 @@ private:
void setupDialog(const Glib::ustring &title);
- friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp);
+ void _highlightPickerColorMod();
};
diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp
index ed71c826f..f36e3f18d 100644
--- a/src/ui/dialog/tags.cpp
+++ b/src/ui/dialog/tags.cpp
@@ -51,7 +51,7 @@
#include "ui/tools/tool-base.h" //"event-context.h"
#include "selection.h"
//#include "dialogs/dialog-events.h"
-#include "widgets/sp-color-notebook.h"
+#include "ui/widget/color-notebook.h"
#include "style.h"
#include "filter-chemistry.h"
#include "filters/blend.h"
diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp
index 815aa12ef..1a696c820 100644
--- a/src/ui/dialog/text-edit.cpp
+++ b/src/ui/dialog/text-edit.cpp
@@ -69,6 +69,7 @@ TextEdit::TextEdit()
font_label(_("_Font"), true),
layout_frame(),
text_label(_("_Text"), true),
+ vari_label(_("_Variants"), true),
setasdefault_button(_("Set as _default")),
close_button(Gtk::Stock::CLOSE),
apply_button(Gtk::Stock::APPLY),
@@ -195,7 +196,8 @@ TextEdit::TextEdit()
notebook.append_page(font_vbox, font_label);
notebook.append_page(text_vbox, text_label);
-
+ notebook.append_page(vari_vbox, vari_label);
+
/* Buttons */
setasdefault_button.set_use_underline(true);
apply_button.set_can_default();
@@ -216,6 +218,7 @@ TextEdit::TextEdit()
setasdefault_button.signal_clicked().connect(sigc::mem_fun(*this, &TextEdit::onSetDefault));
apply_button.signal_clicked().connect(sigc::mem_fun(*this, &TextEdit::onApply));
close_button.signal_clicked().connect(sigc::bind(_signal_response.make_slot(), GTK_RESPONSE_CLOSE));
+ fontVariantChangedConn = vari_vbox.connectChanged(sigc::bind(sigc::ptr_fun(&onFontVariantChange), this));
desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TextEdit::setTargetDesktop) );
deskTrack.connect(GTK_WIDGET(gobj()));
@@ -230,6 +233,7 @@ TextEdit::~TextEdit()
selectChangedConn.disconnect();
desktopChangeConn.disconnect();
deskTrack.disconnect();
+ fontVariantChangedConn.disconnect();
}
void TextEdit::styleButton(Gtk::RadioButton *button, gchar const *tooltip, gchar const *icon_name, Gtk::RadioButton *group_button )
@@ -384,6 +388,11 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ )
gtk_entry_set_text ((GtkEntry *) gtk_bin_get_child ((GtkBin *) spacing_combo), sstr);
g_free(sstr);
+ // Update font variant widget
+ //int result_variants =
+ sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTVARIANTS);
+ vari_vbox.update( &query );
+
}
blocked = false;
}
@@ -510,12 +519,15 @@ SPCSSAttr *TextEdit::fillTextStyle ()
sp_repr_css_set_property (css, "writing-mode", "tb");
}
- // Note that CSS 1.1 does not support line-height; we set it for consistency, but also set
+ // Note that SVG 1.1 does not support line-height; we set it for consistency, but also set
// sodipodi:linespacing for backwards compatibility; in 1.2 we use line-height for flowtext
const gchar *sstr = gtk_combo_box_text_get_active_text ((GtkComboBoxText *) spacing_combo);
sp_repr_css_set_property (css, "line-height", sstr);
+ // Font variants
+ vari_vbox.fill_css( css );
+
return css;
}
@@ -646,6 +658,19 @@ void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, gchar* fontspec, TextE
}
+void TextEdit::onFontVariantChange(TextEdit *self)
+{
+ if( self->blocked )
+ return;
+
+ SPItem *text = self->getSelectedTextItem ();
+
+ if (text) {
+ self->apply_button.set_sensitive ( true );
+ }
+ self->setasdefault_button.set_sensitive ( true );
+}
+
void TextEdit::onStartOffsetChange(GtkTextBuffer * /*text_buffer*/, TextEdit *self)
{
SPItem *text = self->getSelectedTextItem();
diff --git a/src/ui/dialog/text-edit.h b/src/ui/dialog/text-edit.h
index 117ad2e28..41f89b3e7 100644
--- a/src/ui/dialog/text-edit.h
+++ b/src/ui/dialog/text-edit.h
@@ -32,9 +32,11 @@
#include "ui/widget/panel.h"
#include "ui/widget/frame.h"
#include "ui/dialog/desktop-tracker.h"
+#include "ui/widget/font-variants.h"
class SPItem;
struct SPFontSelector;
+class FontVariants;
class font_instance;
class SPCSSAttr;
@@ -111,6 +113,17 @@ protected:
static void onFontChange (SPFontSelector *fontsel, gchar* fontspec, TextEdit *self);
/**
+ * Callback invoked when the user modifies the font variant through the dialog.
+ *
+ * onFontChange updates the dialog UI. The subfunction setPreviewText updates the preview label.
+ *
+ * @param fontsel pointer to FontVariant (currently not used).
+ * @param fontspec for the text to be previewed.
+ * @param self pointer to the current instance of the dialog.
+ */
+ static void onFontVariantChange (TextEdit *self);
+
+ /**
* Callback invoked when the user modifies the startOffset of text on a path.
*
* @param text_buffer pointer to the GtkTextBuffer with the text of the selected text object.
@@ -213,6 +226,9 @@ private:
GtkWidget *text_view; // TODO - Convert this to a Gtk::TextView, but GtkSpell doesn't seem to work with it
GtkTextBuffer *text_buffer;
+ Inkscape::UI::Widget::FontVariants vari_vbox;
+ Gtk::Label vari_label;
+
Gtk::HBox button_row;
Gtk::Button setasdefault_button;
Gtk::Button close_button;
@@ -224,6 +240,7 @@ private:
sigc::connection selectChangedConn;
sigc::connection subselChangedConn;
sigc::connection selectModifiedConn;
+ sigc::connection fontVariantChangedConn;
bool blocked;
const Glib::ustring samplephrase;
diff --git a/src/ui/selected-color.cpp b/src/ui/selected-color.cpp
new file mode 100644
index 000000000..8c37ee7e0
--- /dev/null
+++ b/src/ui/selected-color.cpp
@@ -0,0 +1,163 @@
+/** @file
+ * Color selected in color selector widget.
+ * This file was created during the refactoring of SPColorSelector
+ *//*
+ * Authors:
+ * bulia byak <buliabyak@users.sf.net>
+ * Jon A. Cruz <jon@joncruz.org>
+ * Tomasz Boczkowski <penginsbacon@gmail.com>
+ *
+ * Copyright (C) 2014 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glibmm/ustring.h>
+#include <cmath>
+
+#include "svg/svg-icc-color.h"
+#include "ui/selected-color.h"
+
+namespace Inkscape {
+namespace UI {
+
+double const SelectedColor::_EPSILON = 1e-4;
+
+SelectedColor::SelectedColor()
+ : _color(0)
+ , _alpha(1.0)
+ , _held(false)
+ , _virgin(true)
+ , _updating(false)
+{
+
+}
+
+SelectedColor::~SelectedColor() {
+
+}
+
+void SelectedColor::setColor(SPColor const &color)
+{
+ setColorAlpha( color, _alpha);
+}
+
+SPColor SelectedColor::color() const
+{
+ return _color;
+}
+
+void SelectedColor::setAlpha(gfloat alpha)
+{
+ g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) );
+ setColorAlpha( _color, alpha);
+}
+
+gfloat SelectedColor::alpha() const
+{
+ return _alpha;
+}
+
+void SelectedColor::setValue(guint32 value)
+{
+ SPColor color(value);
+ gfloat alpha = SP_RGBA32_A_F(value);
+ setColorAlpha(color, alpha);
+}
+
+guint32 SelectedColor::value() const
+{
+ return color().toRGBA32(_alpha);
+}
+
+void SelectedColor::setColorAlpha(SPColor const &color, gfloat alpha, bool emit_signal)
+{
+#ifdef DUMP_CHANGE_INFO
+ g_message("SelectedColor::setColorAlpha( this=%p, %f, %f, %f, %s, %f, %s)", this, color.v.c[0], color.v.c[1], color.v.c[2], (color.icc?color.icc->colorProfile.c_str():"<null>"), alpha, (emit_signal?"YES":"no"));
+#endif
+ g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) );
+
+ if (_updating) {
+ return;
+ }
+
+#ifdef DUMP_CHANGE_INFO
+ g_message("---- SelectedColor::setColorAlpha virgin:%s !close:%s alpha is:%s",
+ (_virgin?"YES":"no"),
+ (!color.isClose( _color, _EPSILON )?"YES":"no"),
+ ((fabs((_alpha) - (alpha)) >= _EPSILON )?"YES":"no")
+ );
+#endif
+
+ if ( _virgin || !color.isClose( _color, _EPSILON ) ||
+ (fabs((_alpha) - (alpha)) >= _EPSILON )) {
+
+ _virgin = false;
+
+ _color = color;
+ _alpha = alpha;
+
+ if (emit_signal)
+ {
+ _updating = true;
+ if (_held) {
+ signal_dragged.emit();
+ } else {
+ signal_changed.emit();
+ }
+ _updating = false;
+ }
+
+#ifdef DUMP_CHANGE_INFO
+ } else {
+ g_message("++++ SelectedColor::setColorAlpha color:%08x ==> _color:%08X isClose:%s", color.toRGBA32(alpha), _color.toRGBA32(_alpha),
+ (color.isClose( _color, _EPSILON )?"YES":"no"));
+#endif
+ }
+}
+
+void SelectedColor::colorAlpha(SPColor &color, gfloat &alpha) const {
+ color = _color;
+ alpha = _alpha;
+}
+
+void SelectedColor::setHeld(bool held) {
+ if (_updating) {
+ return;
+ }
+ bool grabbed = held && !_held;
+ bool released = !held && _held;
+
+ _held = held;
+
+ _updating = true;
+ if (grabbed) {
+ signal_grabbed.emit();
+ }
+
+ if (released) {
+ signal_released.emit();
+ signal_changed.emit();
+ }
+ _updating = false;
+}
+
+void SelectedColor::preserveICC() {
+ _color.icc = _color.icc ? new SVGICCColor(*_color.icc) : 0;
+}
+
+}
+}
+
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/selected-color.h b/src/ui/selected-color.h
new file mode 100644
index 000000000..e9e702d43
--- /dev/null
+++ b/src/ui/selected-color.h
@@ -0,0 +1,96 @@
+/** @file
+ * Color selected in color selector widget.
+ * This file was created during the refactoring of SPColorSelector
+ *//*
+ * Authors:
+ * bulia byak <buliabyak@users.sf.net>
+ * Jon A. Cruz <jon@joncruz.org>
+ * Tomasz Boczkowski <penginsbacon@gmail.com>
+ *
+ * Copyright (C) 2014 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#ifndef SEEN_SELECTED_COLOR
+#define SEEN_SELECTED_COLOR
+
+#include <sigc++/signal.h>
+#include "color.h"
+
+namespace Gtk
+{
+ class Widget;
+}
+
+namespace Inkscape {
+namespace UI {
+
+class SelectedColor {
+public:
+ SelectedColor();
+ virtual ~SelectedColor();
+
+ void setColor(SPColor const &color);
+ SPColor color() const;
+
+ void setAlpha(gfloat alpha);
+ gfloat alpha() const;
+
+ void setValue(guint32 value);
+ guint32 value() const;
+
+ void setColorAlpha(SPColor const &color, gfloat alpha, bool emit_signal = true);
+ void colorAlpha(SPColor &color, gfloat &alpha) const;
+
+ void setHeld(bool held);
+
+ void preserveICC();
+
+ sigc::signal<void> signal_grabbed;
+ sigc::signal<void> signal_dragged;
+ sigc::signal<void> signal_released;
+ sigc::signal<void> signal_changed;
+private:
+ // By default, disallow copy constructor and assignment operator
+ SelectedColor(SelectedColor const &obj);
+ SelectedColor& operator=(SelectedColor const &obj);
+
+ SPColor _color;
+ /**
+ * Color alpha value guaranteed to be in [0, 1].
+ */
+ gfloat _alpha;
+
+ bool _held;
+ /**
+ * This flag is true if no color is set yet
+ */
+ bool _virgin;
+
+ bool _updating;
+
+ static double const _EPSILON;
+};
+
+class ColorSelectorFactory {
+public:
+ virtual ~ColorSelectorFactory() {
+ }
+
+ virtual Gtk::Widget* createWidget(SelectedColor &color) const = 0;
+ virtual Glib::ustring modeName() const = 0;
+};
+
+}
+}
+
+#endif
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert
index e18b790bd..eb98e6872 100644
--- a/src/ui/widget/Makefile_insert
+++ b/src/ui/widget/Makefile_insert
@@ -6,10 +6,22 @@ ink_common_sources += \
ui/widget/attr-widget.h \
ui/widget/button.h \
ui/widget/button.cpp \
+ ui/widget/color-entry.cpp \
+ ui/widget/color-entry.h \
+ ui/widget/color-icc-selector.cpp \
+ ui/widget/color-icc-selector.h \
+ ui/widget/color-notebook.cpp \
+ ui/widget/color-notebook.h \
+ ui/widget/color-wheel-selector.cpp \
+ ui/widget/color-wheel-selector.h \
ui/widget/color-picker.cpp \
ui/widget/color-picker.h \
ui/widget/color-preview.cpp \
ui/widget/color-preview.h \
+ ui/widget/color-slider.cpp \
+ ui/widget/color-slider.h \
+ ui/widget/color-scales.cpp \
+ ui/widget/color-scales.h \
ui/widget/combo-enums.h \
ui/widget/dock.h \
ui/widget/dock.cpp \
@@ -21,8 +33,10 @@ ink_common_sources += \
ui/widget/entry.h \
ui/widget/filter-effect-chooser.h \
ui/widget/filter-effect-chooser.cpp \
- ui/widget/gimpspinscale.c \
- ui/widget/gimpspinscale.h \
+ ui/widget/font-variants.h \
+ ui/widget/font-variants.cpp \
+ ui/widget/gimpspinscale.c \
+ ui/widget/gimpspinscale.h \
ui/widget/gimpcolorwheel.c \
ui/widget/gimpcolorwheel.h \
ui/widget/frame.cpp \
diff --git a/src/ui/widget/color-entry.cpp b/src/ui/widget/color-entry.cpp
new file mode 100644
index 000000000..f5658c3a6
--- /dev/null
+++ b/src/ui/widget/color-entry.cpp
@@ -0,0 +1,114 @@
+/** @file
+ * Entry widget for typing color value in css form
+ *//*
+ * Authors:
+ * Tomasz Boczkowski <penginsbacon@gmail.com>
+ *
+ * Copyright (C) 2014 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+#include <glibmm.h>
+#include <glibmm/i18n.h>
+#include <iomanip>
+
+#include "color-entry.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+ColorEntry::ColorEntry(SelectedColor &color)
+ : _color(color)
+ , _updating(false)
+ , _updatingrgba(false)
+{
+ _color_changed_connection = color.signal_changed.connect(sigc::mem_fun(this, &ColorEntry::_onColorChanged));
+ _color_dragged_connection = color.signal_dragged.connect(sigc::mem_fun(this, &ColorEntry::_onColorChanged));
+ _onColorChanged();
+
+ set_max_length(8);
+ set_width_chars(8);
+ set_tooltip_text(_("Hexadecimal RGBA value of the color"));
+}
+
+ColorEntry::~ColorEntry()
+{
+ _color_changed_connection.disconnect();
+ _color_dragged_connection.disconnect();
+}
+
+void ColorEntry::on_changed()
+{
+ if (_updating) {
+ return;
+ }
+ if (_updatingrgba) {
+ return; // Typing text into entry box
+ }
+
+ Glib::ustring text = get_text();
+ bool changed = false;
+
+ // Coerce the value format to eight hex digits
+ if (!text.empty() && text[0] == '#') {
+ changed = true;
+ text.erase(0, 1);
+ if (text.size() == 6) {
+ // it was a standard RGB hex
+ unsigned int alpha = SP_COLOR_F_TO_U(_color.alpha());
+ text += Glib::ustring::format(std::hex, std::setw(2), std::setfill(L'0'), alpha);
+ }
+ }
+
+ gchar *str = g_strdup(text.c_str());
+ gchar *end = 0;
+ guint64 rgba = g_ascii_strtoull(str, &end, 16);
+ if (end != str) {
+ ptrdiff_t len = end - str;
+ if (len < 8) {
+ rgba = rgba << (4 * (8 - len));
+ }
+ _updatingrgba = true;
+ if (changed) {
+ set_text(str);
+ }
+ SPColor color(rgba);
+ _color.setColorAlpha(color, SP_RGBA32_A_F(rgba));
+ _updatingrgba = false;
+ }
+ g_free(str);
+}
+
+
+void ColorEntry::_onColorChanged()
+{
+ if (_updatingrgba) {
+ return;
+ }
+
+ SPColor color = _color.color();
+ gdouble alpha = _color.alpha();
+
+ guint32 rgba = color.toRGBA32(alpha);
+ Glib::ustring text = Glib::ustring::format(std::hex, std::setw(8), std::setfill(L'0'), rgba);
+
+ Glib::ustring old_text = get_text();
+ if (old_text != text) {
+ _updating = true;
+ set_text(text);
+ _updating = false;
+ }
+}
+}
+}
+}
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/color-entry.h b/src/ui/widget/color-entry.h
new file mode 100644
index 000000000..edabe1980
--- /dev/null
+++ b/src/ui/widget/color-entry.h
@@ -0,0 +1,54 @@
+/** @file
+ * Entry widget for typing color value in css form
+ *//*
+ * Authors:
+ * Tomasz Boczkowski <penginsbacon@gmail.com>
+ *
+ * Copyright (C) 2014 Authors
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef SEEN_COLOR_ENTRY_H
+#define SEEN_COLOR_ENTRY_H_
+
+#include <gtkmm/entry.h>
+#include "ui/selected-color.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+class ColorEntry : public Gtk::Entry
+{
+public:
+ ColorEntry(SelectedColor &color);
+ virtual ~ColorEntry();
+
+protected:
+ void on_changed();
+
+private:
+ void _onColorChanged();
+
+ SelectedColor &_color;
+ sigc::connection _color_changed_connection;
+ sigc::connection _color_dragged_connection;
+ bool _updating;
+ bool _updatingrgba;
+};
+
+}
+}
+}
+
+#endif
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/color-icc-selector.cpp b/src/ui/widget/color-icc-selector.cpp
new file mode 100644
index 000000000..1c31ae33a
--- /dev/null
+++ b/src/ui/widget/color-icc-selector.cpp
@@ -0,0 +1,1079 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include <gtkmm/adjustment.h>
+#include <glibmm/i18n.h>
+
+#include <gtk/gtk.h>
+#include <map>
+#include <set>
+#include <vector>
+
+#include "ui/dialog-events.h"
+#include "ui/widget/color-icc-selector.h"
+#include "ui/widget/color-scales.h"
+#include "ui/widget/color-slider.h"
+#include "svg/svg-icc-color.h"
+#include "colorspace.h"
+#include "document.h"
+#include "inkscape.h"
+#include "profile-manager.h"
+#include "widgets/gradient-vector.h"
+
+#define noDEBUG_LCMS
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+#include "color-profile.h"
+#include "cms-system.h"
+#include "color-profile-cms-fns.h"
+
+#ifdef DEBUG_LCMS
+#include "preferences.h"
+#endif // DEBUG_LCMS
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
+#ifdef DEBUG_LCMS
+extern guint update_in_progress;
+#define DEBUG_MESSAGE(key, ...) \
+ { \
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); \
+ bool dump = prefs->getBool("/options/scislac/" #key); \
+ bool dumpD = prefs->getBool("/options/scislac/" #key "D"); \
+ bool dumpD2 = prefs->getBool("/options/scislac/" #key "D2"); \
+ dumpD && = ((update_in_progress == 0) || dumpD2); \
+ if (dump) { \
+ g_message(__VA_ARGS__); \
+ } \
+ if (dumpD) { \
+ GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, \
+ GTK_BUTTONS_OK, __VA_ARGS__); \
+ g_signal_connect_swapped(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog); \
+ gtk_widget_show_all(dialog); \
+ } \
+ }
+#endif // DEBUG_LCMS
+
+
+#define XPAD 4
+#define YPAD 1
+
+namespace {
+
+size_t maxColorspaceComponentCount = 0;
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
+/**
+ * Internal variable to track all known colorspaces.
+ */
+std::set<cmsUInt32Number> knownColorspaces;
+
+#endif
+
+
+/**
+ * Simple helper to allow bitwise or on GtkAttachOptions.
+ */
+GtkAttachOptions operator|(GtkAttachOptions lhs, GtkAttachOptions rhs)
+{
+ return static_cast<GtkAttachOptions>(static_cast<int>(lhs) | static_cast<int>(rhs));
+}
+
+/**
+ * Helper function to handle GTK2/GTK3 attachment #ifdef code.
+ */
+void attachToGridOrTable(GtkWidget *parent, GtkWidget *child, guint left, guint top, guint width, guint height,
+ bool hexpand = false, bool centered = false, guint xpadding = XPAD, guint ypadding = YPAD)
+{
+#if GTK_CHECK_VERSION(3, 0, 0)
+ #if GTK_CHECK_VERSION(3, 12, 0)
+ gtk_widget_set_margin_start(child, xpadding);
+ gtk_widget_set_margin_end(child, xpadding);
+ #else
+ gtk_widget_set_margin_left(child, xpadding);
+ gtk_widget_set_margin_right(child, xpadding);
+ #endif
+
+ gtk_widget_set_margin_top(child, ypadding);
+ gtk_widget_set_margin_bottom(child, ypadding);
+ if (hexpand) {
+ gtk_widget_set_hexpand(child, TRUE);
+ }
+ if (centered) {
+ gtk_widget_set_halign(child, GTK_ALIGN_CENTER);
+ gtk_widget_set_valign(child, GTK_ALIGN_CENTER);
+ }
+ gtk_grid_attach(GTK_GRID(parent), child, left, top, width, height);
+#else
+ GtkAttachOptions xoptions =
+ centered ? static_cast<GtkAttachOptions>(0) : hexpand ? (GTK_EXPAND | GTK_FILL) : GTK_FILL;
+ GtkAttachOptions yoptions = centered ? static_cast<GtkAttachOptions>(0) : GTK_FILL;
+
+ gtk_table_attach(GTK_TABLE(parent), child, left, left + width, top, top + height, xoptions, yoptions, xpadding,
+ ypadding);
+#endif
+}
+
+} // namespace
+
+/*
+icSigRgbData
+icSigCmykData
+icSigCmyData
+*/
+#define SPACE_ID_RGB 0
+#define SPACE_ID_CMY 1
+#define SPACE_ID_CMYK 2
+
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+static cmsUInt16Number *getScratch()
+{
+ // bytes per pixel * input channels * width
+ static cmsUInt16Number *scritch = static_cast<cmsUInt16Number *>(g_new(cmsUInt16Number, 4 * 1024));
+
+ return scritch;
+}
+
+colorspace::Component::Component()
+ : name()
+ , tip()
+ , scale(1)
+{
+}
+
+colorspace::Component::Component(std::string const &name, std::string const &tip, guint scale)
+ : name(name)
+ , tip(tip)
+ , scale(scale)
+{
+}
+
+std::vector<colorspace::Component> colorspace::getColorSpaceInfo(uint32_t space)
+{
+ static std::map<cmsUInt32Number, std::vector<Component> > sets;
+ if (sets.empty()) {
+ sets[cmsSigXYZData].push_back(Component("_X", "X", 2)); // TYPE_XYZ_16
+ sets[cmsSigXYZData].push_back(Component("_Y", "Y", 1));
+ sets[cmsSigXYZData].push_back(Component("_Z", "Z", 2));
+
+ sets[cmsSigLabData].push_back(Component("_L", "L", 100)); // TYPE_Lab_16
+ sets[cmsSigLabData].push_back(Component("_a", "a", 256));
+ sets[cmsSigLabData].push_back(Component("_b", "b", 256));
+
+ // cmsSigLuvData
+
+ sets[cmsSigYCbCrData].push_back(Component("_Y", "Y", 1)); // TYPE_YCbCr_16
+ sets[cmsSigYCbCrData].push_back(Component("C_b", "Cb", 1));
+ sets[cmsSigYCbCrData].push_back(Component("C_r", "Cr", 1));
+
+ sets[cmsSigYxyData].push_back(Component("_Y", "Y", 1)); // TYPE_Yxy_16
+ sets[cmsSigYxyData].push_back(Component("_x", "x", 1));
+ sets[cmsSigYxyData].push_back(Component("y", "y", 1));
+
+ sets[cmsSigRgbData].push_back(Component(_("_R:"), _("Red"), 1)); // TYPE_RGB_16
+ sets[cmsSigRgbData].push_back(Component(_("_G:"), _("Green"), 1));
+ sets[cmsSigRgbData].push_back(Component(_("_B:"), _("Blue"), 1));
+
+ sets[cmsSigGrayData].push_back(Component(_("G:"), _("Gray"), 1)); // TYPE_GRAY_16
+
+ sets[cmsSigHsvData].push_back(Component(_("_H:"), _("Hue"), 360)); // TYPE_HSV_16
+ sets[cmsSigHsvData].push_back(Component(_("_S:"), _("Saturation"), 1));
+ sets[cmsSigHsvData].push_back(Component("_V:", "Value", 1));
+
+ sets[cmsSigHlsData].push_back(Component(_("_H:"), _("Hue"), 360)); // TYPE_HLS_16
+ sets[cmsSigHlsData].push_back(Component(_("_L:"), _("Lightness"), 1));
+ sets[cmsSigHlsData].push_back(Component(_("_S:"), _("Saturation"), 1));
+
+ sets[cmsSigCmykData].push_back(Component(_("_C:"), _("Cyan"), 1)); // TYPE_CMYK_16
+ sets[cmsSigCmykData].push_back(Component(_("_M:"), _("Magenta"), 1));
+ sets[cmsSigCmykData].push_back(Component(_("_Y:"), _("Yellow"), 1));
+ sets[cmsSigCmykData].push_back(Component(_("_K:"), _("Black"), 1));
+
+ sets[cmsSigCmyData].push_back(Component(_("_C:"), _("Cyan"), 1)); // TYPE_CMY_16
+ sets[cmsSigCmyData].push_back(Component(_("_M:"), _("Magenta"), 1));
+ sets[cmsSigCmyData].push_back(Component(_("_Y:"), _("Yellow"), 1));
+
+ for (std::map<cmsUInt32Number, std::vector<Component> >::iterator it = sets.begin(); it != sets.end(); ++it) {
+ knownColorspaces.insert(it->first);
+ maxColorspaceComponentCount = std::max(maxColorspaceComponentCount, it->second.size());
+ }
+ }
+
+ std::vector<Component> target;
+
+ if (sets.find(space) != sets.end()) {
+ target = sets[space];
+ }
+ return target;
+}
+
+
+std::vector<colorspace::Component> colorspace::getColorSpaceInfo(Inkscape::ColorProfile *prof)
+{
+ return getColorSpaceInfo(asICColorSpaceSig(prof->getColorSpace()));
+}
+
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+/**
+ * Class containing the parts for a single color component's UI presence.
+ */
+class ComponentUI {
+ public:
+ ComponentUI()
+ : _component()
+ , _adj(0)
+ , _slider(0)
+ , _btn(0)
+ , _label(0)
+ , _map(0)
+ {
+ }
+
+ ComponentUI(colorspace::Component const &component)
+ : _component(component)
+ , _adj(0)
+ , _slider(0)
+ , _btn(0)
+ , _label(0)
+ , _map(0)
+ {
+ }
+
+ colorspace::Component _component;
+ GtkAdjustment *_adj; // Component adjustment
+ Inkscape::UI::Widget::ColorSlider *_slider;
+ GtkWidget *_btn; // spinbutton
+ GtkWidget *_label; // Label
+ guchar *_map;
+};
+
+/**
+ * Class that implements the internals of the selector.
+ */
+class ColorICCSelectorImpl {
+ public:
+ ColorICCSelectorImpl(ColorICCSelector *owner, SelectedColor &color);
+
+ ~ColorICCSelectorImpl();
+
+ static void _adjustmentChanged(GtkAdjustment *adjustment, ColorICCSelectorImpl *cs);
+
+ void _sliderGrabbed();
+ void _sliderReleased();
+ void _sliderChanged();
+
+ static void _profileSelected(GtkWidget *src, gpointer data);
+ static void _fixupHit(GtkWidget *src, gpointer data);
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ void _setProfile(SVGICCColor *profile);
+ void _switchToProfile(gchar const *name);
+#endif
+ void _updateSliders(gint ignore);
+ void _profilesChanged(std::string const &name);
+
+ ColorICCSelector *_owner;
+ SelectedColor &_color;
+
+ gboolean _updating : 1;
+ gboolean _dragging : 1;
+
+ guint32 _fixupNeeded;
+ GtkWidget *_fixupBtn;
+ GtkWidget *_profileSel;
+
+ std::vector<ComponentUI> _compUI;
+
+ GtkAdjustment *_adj; // Channel adjustment
+ Inkscape::UI::Widget::ColorSlider *_slider;
+ GtkWidget *_sbtn; // Spinbutton
+ GtkWidget *_label; // Label
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ std::string _profileName;
+ Inkscape::ColorProfile *_prof;
+ guint _profChannelCount;
+ gulong _profChangedID;
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+};
+
+
+
+const gchar *ColorICCSelector::MODE_NAME = N_("CMS");
+
+ColorICCSelector::ColorICCSelector(SelectedColor &color)
+ : _impl(NULL)
+{
+ _impl = new ColorICCSelectorImpl(this, color);
+ init();
+ color.signal_changed.connect(sigc::mem_fun(this, &ColorICCSelector::_colorChanged));
+ // color.signal_dragged.connect(sigc::mem_fun(this, &ColorICCSelector::_colorChanged));
+}
+
+ColorICCSelector::~ColorICCSelector()
+{
+ if (_impl) {
+ delete _impl;
+ _impl = 0;
+ }
+}
+
+
+
+ColorICCSelectorImpl::ColorICCSelectorImpl(ColorICCSelector *owner, SelectedColor &color)
+ : _owner(owner)
+ , _color(color)
+ , _updating(FALSE)
+ , _dragging(FALSE)
+ , _fixupNeeded(0)
+ , _fixupBtn(0)
+ , _profileSel(0)
+ , _compUI()
+ , _adj(0)
+ , _slider(0)
+ , _sbtn(0)
+ , _label(0)
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ , _profileName()
+ , _prof(0)
+ , _profChannelCount(0)
+ , _profChangedID(0)
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+{
+}
+
+ColorICCSelectorImpl::~ColorICCSelectorImpl()
+{
+ _adj = 0;
+ _sbtn = 0;
+ _label = 0;
+}
+
+void ColorICCSelector::init()
+{
+ gint row = 0;
+
+ _impl->_updating = FALSE;
+ _impl->_dragging = FALSE;
+
+ GtkWidget *t = GTK_WIDGET(gobj());
+
+ _impl->_compUI.clear();
+
+ // Create components
+ row = 0;
+
+
+ _impl->_fixupBtn = gtk_button_new_with_label(_("Fix"));
+ g_signal_connect(G_OBJECT(_impl->_fixupBtn), "clicked", G_CALLBACK(ColorICCSelectorImpl::_fixupHit),
+ (gpointer)_impl);
+ gtk_widget_set_sensitive(_impl->_fixupBtn, FALSE);
+ gtk_widget_set_tooltip_text(_impl->_fixupBtn, _("Fix RGB fallback to match icc-color() value."));
+ // gtk_misc_set_alignment( GTK_MISC (_impl->_fixupBtn), 1.0, 0.5 );
+ gtk_widget_show(_impl->_fixupBtn);
+
+ attachToGridOrTable(t, _impl->_fixupBtn, 0, row, 1, 1);
+
+ // Combobox and store with 2 columns : label (0) and full name (1)
+ GtkListStore *store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
+ _impl->_profileSel = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
+
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(_impl->_profileSel), renderer, TRUE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(_impl->_profileSel), renderer, "text", 0, NULL);
+
+ GtkTreeIter iter;
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter, 0, _("<none>"), 1, _("<none>"), -1);
+
+ gtk_widget_show(_impl->_profileSel);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(_impl->_profileSel), 0);
+
+ attachToGridOrTable(t, _impl->_profileSel, 1, row, 1, 1);
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ _impl->_profChangedID = g_signal_connect(G_OBJECT(_impl->_profileSel), "changed",
+ G_CALLBACK(ColorICCSelectorImpl::_profileSelected), (gpointer)_impl);
+#else
+ gtk_widget_set_sensitive(_impl->_profileSel, false);
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
+
+ row++;
+
+// populate the data for colorspaces and channels:
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ std::vector<colorspace::Component> things = colorspace::getColorSpaceInfo(cmsSigRgbData);
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
+ for (size_t i = 0; i < maxColorspaceComponentCount; i++) {
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ if (i < things.size()) {
+ _impl->_compUI.push_back(ComponentUI(things[i]));
+ }
+ else {
+ _impl->_compUI.push_back(ComponentUI());
+ }
+
+ std::string labelStr = (i < things.size()) ? things[i].name.c_str() : "";
+#else
+ _impl->_compUI.push_back(ComponentUI());
+
+ std::string labelStr = ".";
+#endif
+
+ _impl->_compUI[i]._label = gtk_label_new_with_mnemonic(labelStr.c_str());
+ gtk_misc_set_alignment(GTK_MISC(_impl->_compUI[i]._label), 1.0, 0.5);
+ gtk_widget_show(_impl->_compUI[i]._label);
+ gtk_widget_set_no_show_all(_impl->_compUI[i]._label, TRUE);
+
+ attachToGridOrTable(t, _impl->_compUI[i]._label, 0, row, 1, 1);
+
+ // Adjustment
+ guint scaleValue = _impl->_compUI[i]._component.scale;
+ gdouble step = static_cast<gdouble>(scaleValue) / 100.0;
+ gdouble page = static_cast<gdouble>(scaleValue) / 10.0;
+ gint digits = (step > 0.9) ? 0 : 2;
+ _impl->_compUI[i]._adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, scaleValue, step, page, page));
+
+ // Slider
+ _impl->_compUI[i]._slider =
+ Gtk::manage(new Inkscape::UI::Widget::ColorSlider(Glib::wrap(_impl->_compUI[i]._adj, true)));
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ _impl->_compUI[i]._slider->set_tooltip_text((i < things.size()) ? things[i].tip.c_str() : "");
+#else
+ _impl->_compUI[i]._slider->set_tooltip_text(".");
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ _impl->_compUI[i]._slider->show();
+ _impl->_compUI[i]._slider->set_no_show_all();
+
+ attachToGridOrTable(t, _impl->_compUI[i]._slider->gobj(), 1, row, 1, 1, true);
+
+ _impl->_compUI[i]._btn = gtk_spin_button_new(_impl->_compUI[i]._adj, step, digits);
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ gtk_widget_set_tooltip_text(_impl->_compUI[i]._btn, (i < things.size()) ? things[i].tip.c_str() : "");
+#else
+ gtk_widget_set_tooltip_text(_impl->_compUI[i]._btn, ".");
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ sp_dialog_defocus_on_enter(_impl->_compUI[i]._btn);
+ gtk_label_set_mnemonic_widget(GTK_LABEL(_impl->_compUI[i]._label), _impl->_compUI[i]._btn);
+ gtk_widget_show(_impl->_compUI[i]._btn);
+ gtk_widget_set_no_show_all(_impl->_compUI[i]._btn, TRUE);
+
+ attachToGridOrTable(t, _impl->_compUI[i]._btn, 2, row, 1, 1, false, true);
+
+ _impl->_compUI[i]._map = g_new(guchar, 4 * 1024);
+ memset(_impl->_compUI[i]._map, 0x0ff, 1024 * 4);
+
+
+ // Signals
+ g_signal_connect(G_OBJECT(_impl->_compUI[i]._adj), "value_changed",
+ G_CALLBACK(ColorICCSelectorImpl::_adjustmentChanged), _impl);
+
+ _impl->_compUI[i]._slider->signal_grabbed.connect(sigc::mem_fun(_impl, &ColorICCSelectorImpl::_sliderGrabbed));
+ _impl->_compUI[i]._slider->signal_released.connect(
+ sigc::mem_fun(_impl, &ColorICCSelectorImpl::_sliderReleased));
+ _impl->_compUI[i]._slider->signal_value_changed.connect(
+ sigc::mem_fun(_impl, &ColorICCSelectorImpl::_sliderChanged));
+
+ row++;
+ }
+
+ // Label
+ _impl->_label = gtk_label_new_with_mnemonic(_("_A:"));
+ gtk_misc_set_alignment(GTK_MISC(_impl->_label), 1.0, 0.5);
+ gtk_widget_show(_impl->_label);
+
+ attachToGridOrTable(t, _impl->_label, 0, row, 1, 1);
+
+ // Adjustment
+ _impl->_adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 255.0, 1.0, 10.0, 10.0));
+
+ // Slider
+ _impl->_slider = Gtk::manage(new Inkscape::UI::Widget::ColorSlider(Glib::wrap(_impl->_adj, true)));
+ _impl->_slider->set_tooltip_text(_("Alpha (opacity)"));
+ _impl->_slider->show();
+
+ attachToGridOrTable(t, _impl->_slider->gobj(), 1, row, 1, 1, true);
+
+ _impl->_slider->setColors(SP_RGBA32_F_COMPOSE(1.0, 1.0, 1.0, 0.0), SP_RGBA32_F_COMPOSE(1.0, 1.0, 1.0, 0.5),
+ SP_RGBA32_F_COMPOSE(1.0, 1.0, 1.0, 1.0));
+
+
+ // Spinbutton
+ _impl->_sbtn = gtk_spin_button_new(GTK_ADJUSTMENT(_impl->_adj), 1.0, 0);
+ gtk_widget_set_tooltip_text(_impl->_sbtn, _("Alpha (opacity)"));
+ sp_dialog_defocus_on_enter(_impl->_sbtn);
+ gtk_label_set_mnemonic_widget(GTK_LABEL(_impl->_label), _impl->_sbtn);
+ gtk_widget_show(_impl->_sbtn);
+
+ attachToGridOrTable(t, _impl->_sbtn, 2, row, 1, 1, false, true);
+
+ // Signals
+ g_signal_connect(G_OBJECT(_impl->_adj), "value_changed", G_CALLBACK(ColorICCSelectorImpl::_adjustmentChanged),
+ _impl);
+
+ _impl->_slider->signal_grabbed.connect(sigc::mem_fun(_impl, &ColorICCSelectorImpl::_sliderGrabbed));
+ _impl->_slider->signal_released.connect(sigc::mem_fun(_impl, &ColorICCSelectorImpl::_sliderReleased));
+ _impl->_slider->signal_value_changed.connect(sigc::mem_fun(_impl, &ColorICCSelectorImpl::_sliderChanged));
+
+ gtk_widget_show(t);
+}
+
+void ColorICCSelectorImpl::_fixupHit(GtkWidget * /*src*/, gpointer data)
+{
+ ColorICCSelectorImpl *self = reinterpret_cast<ColorICCSelectorImpl *>(data);
+ gtk_widget_set_sensitive(self->_fixupBtn, FALSE);
+ self->_adjustmentChanged(self->_compUI[0]._adj, self);
+}
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+void ColorICCSelectorImpl::_profileSelected(GtkWidget * /*src*/, gpointer data)
+{
+ ColorICCSelectorImpl *self = reinterpret_cast<ColorICCSelectorImpl *>(data);
+
+ GtkTreeIter iter;
+ if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(self->_profileSel), &iter)) {
+ GtkTreeModel *store = gtk_combo_box_get_model(GTK_COMBO_BOX(self->_profileSel));
+ gchar *name = 0;
+
+ gtk_tree_model_get(store, &iter, 1, &name, -1);
+ self->_switchToProfile(name);
+ gtk_widget_set_tooltip_text(self->_profileSel, name);
+
+ if (name) {
+ g_free(name);
+ }
+ }
+}
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+void ColorICCSelectorImpl::_switchToProfile(gchar const *name)
+{
+ bool dirty = false;
+ SPColor tmp(_color.color());
+
+ if (name) {
+ if (tmp.icc && tmp.icc->colorProfile == name) {
+#ifdef DEBUG_LCMS
+ g_message("Already at name [%s]", name);
+#endif // DEBUG_LCMS
+ }
+ else {
+#ifdef DEBUG_LCMS
+ g_message("Need to switch to profile [%s]", name);
+#endif // DEBUG_LCMS
+ if (tmp.icc) {
+ tmp.icc->colors.clear();
+ }
+ else {
+ tmp.icc = new SVGICCColor();
+ }
+ tmp.icc->colorProfile = name;
+ Inkscape::ColorProfile *newProf = SP_ACTIVE_DOCUMENT->profileManager->find(name);
+ if (newProf) {
+ cmsHTRANSFORM trans = newProf->getTransfFromSRGB8();
+ if (trans) {
+ guint32 val = _color.color().toRGBA32(0);
+ guchar pre[4] = {
+ static_cast<guchar>(SP_RGBA32_R_U(val)),
+ static_cast<guchar>(SP_RGBA32_G_U(val)),
+ static_cast<guchar>(SP_RGBA32_B_U(val)),
+ 255};
+#ifdef DEBUG_LCMS
+ g_message("Shoving in [%02x] [%02x] [%02x]", pre[0], pre[1], pre[2]);
+#endif // DEBUG_LCMS
+ cmsUInt16Number post[4] = { 0, 0, 0, 0 };
+ cmsDoTransform(trans, pre, post, 1);
+#ifdef DEBUG_LCMS
+ g_message("got on out [%04x] [%04x] [%04x] [%04x]", post[0], post[1], post[2], post[3]);
+#endif // DEBUG_LCMS
+#if HAVE_LIBLCMS1
+ guint count = _cmsChannelsOf(asICColorSpaceSig(newProf->getColorSpace()));
+#elif HAVE_LIBLCMS2
+ guint count = cmsChannelsOf(asICColorSpaceSig(newProf->getColorSpace()));
+#endif
+
+ std::vector<colorspace::Component> things =
+ colorspace::getColorSpaceInfo(asICColorSpaceSig(newProf->getColorSpace()));
+
+ for (guint i = 0; i < count; i++) {
+ gdouble val =
+ (((gdouble)post[i]) / 65535.0) * (gdouble)((i < things.size()) ? things[i].scale : 1);
+#ifdef DEBUG_LCMS
+ g_message(" scaled %d by %d to be %f", i, ((i < things.size()) ? things[i].scale : 1), val);
+#endif // DEBUG_LCMS
+ tmp.icc->colors.push_back(val);
+ }
+ cmsHTRANSFORM retrans = newProf->getTransfToSRGB8();
+ if (retrans) {
+ cmsDoTransform(retrans, post, pre, 1);
+#ifdef DEBUG_LCMS
+ g_message(" back out [%02x] [%02x] [%02x]", pre[0], pre[1], pre[2]);
+#endif // DEBUG_LCMS
+ tmp.set(SP_RGBA32_U_COMPOSE(pre[0], pre[1], pre[2], 0xff));
+ }
+ }
+ }
+ dirty = true;
+ }
+ }
+ else {
+#ifdef DEBUG_LCMS
+ g_message("NUKE THE ICC");
+#endif // DEBUG_LCMS
+ if (tmp.icc) {
+ delete tmp.icc;
+ tmp.icc = 0;
+ dirty = true;
+ _fixupHit(0, this);
+ }
+ else {
+#ifdef DEBUG_LCMS
+ g_message("No icc to nuke");
+#endif // DEBUG_LCMS
+ }
+ }
+
+ if (dirty) {
+#ifdef DEBUG_LCMS
+ g_message("+----------------");
+ g_message("+ new color is [%s]", tmp.toString().c_str());
+#endif // DEBUG_LCMS
+ _setProfile(tmp.icc);
+ //_adjustmentChanged( _compUI[0]._adj, SP_COLOR_ICC_SELECTOR(_csel) );
+ _color.setColor(tmp);
+#ifdef DEBUG_LCMS
+ g_message("+_________________");
+#endif // DEBUG_LCMS
+ }
+}
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+void ColorICCSelectorImpl::_profilesChanged(std::string const &name)
+{
+ GtkComboBox *combo = GTK_COMBO_BOX(_profileSel);
+
+ g_signal_handler_block(G_OBJECT(_profileSel), _profChangedID);
+
+ GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(combo));
+ gtk_list_store_clear(store);
+
+ GtkTreeIter iter;
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter, 0, _("<none>"), 1, _("<none>"), -1);
+
+ gtk_combo_box_set_active(combo, 0);
+
+ int index = 1;
+ const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList("iccprofile");
+ while (current) {
+ SPObject *obj = SP_OBJECT(current->data);
+ Inkscape::ColorProfile *prof = reinterpret_cast<Inkscape::ColorProfile *>(obj);
+
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter, 0, gr_ellipsize_text(prof->name, 25).c_str(), 1, prof->name, -1);
+
+ if (name == prof->name) {
+ gtk_combo_box_set_active(combo, index);
+ gtk_widget_set_tooltip_text(_profileSel, prof->name);
+ }
+
+ index++;
+ current = g_slist_next(current);
+ }
+
+ g_signal_handler_unblock(G_OBJECT(_profileSel), _profChangedID);
+}
+#else
+void ColorICCSelectorImpl::_profilesChanged(std::string const & /*name*/) {}
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
+void ColorICCSelector::on_show()
+{
+#if GTK_CHECK_VERSION(3, 0, 0)
+ Gtk::Grid::on_show();
+#else
+ Gtk::Table::on_show();
+#endif
+ _colorChanged();
+}
+
+// Helpers for setting color value
+
+void ColorICCSelector::_colorChanged()
+{
+ _impl->_updating = TRUE;
+// sp_color_icc_set_color( SP_COLOR_ICC( _icc ), &color );
+
+#ifdef DEBUG_LCMS
+ g_message("/^^^^^^^^^ %p::_colorChanged(%08x:%s)", this, _impl->_color.color().toRGBA32(_impl->_color.alpha()),
+ ((_impl->_color.color().icc) ? _impl->_color.color().icc->colorProfile.c_str() : "<null>"));
+#endif // DEBUG_LCMS
+
+#ifdef DEBUG_LCMS
+ g_message("FLIPPIES!!!! %p '%s'", _impl->_color.color().icc,
+ (_impl->_color.color().icc ? _impl->_color.color().icc->colorProfile.c_str() : "<null>"));
+#endif // DEBUG_LCMS
+
+ _impl->_profilesChanged((_impl->_color.color().icc) ? _impl->_color.color().icc->colorProfile : std::string(""));
+ ColorScales::setScaled(_impl->_adj, _impl->_color.alpha());
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ _impl->_setProfile(_impl->_color.color().icc);
+ _impl->_fixupNeeded = 0;
+ gtk_widget_set_sensitive(_impl->_fixupBtn, FALSE);
+
+ if (_impl->_prof) {
+ if (_impl->_prof->getTransfToSRGB8()) {
+ cmsUInt16Number tmp[4];
+ for (guint i = 0; i < _impl->_profChannelCount; i++) {
+ gdouble val = 0.0;
+ if (_impl->_color.color().icc->colors.size() > i) {
+ if (_impl->_compUI[i]._component.scale == 256) {
+ val = (_impl->_color.color().icc->colors[i] + 128.0) /
+ static_cast<gdouble>(_impl->_compUI[i]._component.scale);
+ }
+ else {
+ val = _impl->_color.color().icc->colors[i] /
+ static_cast<gdouble>(_impl->_compUI[i]._component.scale);
+ }
+ }
+ tmp[i] = val * 0x0ffff;
+ }
+ guchar post[4] = { 0, 0, 0, 0 };
+ cmsHTRANSFORM trans = _impl->_prof->getTransfToSRGB8();
+ if (trans) {
+ cmsDoTransform(trans, tmp, post, 1);
+ guint32 other = SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255);
+ if (other != _impl->_color.color().toRGBA32(255)) {
+ _impl->_fixupNeeded = other;
+ gtk_widget_set_sensitive(_impl->_fixupBtn, TRUE);
+#ifdef DEBUG_LCMS
+ g_message("Color needs to change 0x%06x to 0x%06x", _color.toRGBA32(255) >> 8, other >> 8);
+#endif // DEBUG_LCMS
+ }
+ }
+ }
+ }
+#else
+//(void)color;
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ _impl->_updateSliders(-1);
+
+
+ _impl->_updating = FALSE;
+#ifdef DEBUG_LCMS
+ g_message("\\_________ %p::_colorChanged()", this);
+#endif // DEBUG_LCMS
+}
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+void ColorICCSelectorImpl::_setProfile(SVGICCColor *profile)
+{
+#ifdef DEBUG_LCMS
+ g_message("/^^^^^^^^^ %p::_setProfile(%s)", this, ((profile) ? profile->colorProfile.c_str() : "<null>"));
+#endif // DEBUG_LCMS
+ bool profChanged = false;
+ if (_prof && (!profile || (_profileName != profile->colorProfile))) {
+ // Need to clear out the prior one
+ profChanged = true;
+ _profileName.clear();
+ _prof = 0;
+ _profChannelCount = 0;
+ }
+ else if (profile && !_prof) {
+ profChanged = true;
+ }
+
+ for (size_t i = 0; i < _compUI.size(); i++) {
+ gtk_widget_hide(_compUI[i]._label);
+ _compUI[i]._slider->hide();
+ gtk_widget_hide(_compUI[i]._btn);
+ }
+
+ if (profile) {
+ _prof = SP_ACTIVE_DOCUMENT->profileManager->find(profile->colorProfile.c_str());
+ if (_prof && (asICColorProfileClassSig(_prof->getProfileClass()) != cmsSigNamedColorClass)) {
+#if HAVE_LIBLCMS1
+ _profChannelCount = _cmsChannelsOf(asICColorSpaceSig(_prof->getColorSpace()));
+#elif HAVE_LIBLCMS2
+ _profChannelCount = cmsChannelsOf(asICColorSpaceSig(_prof->getColorSpace()));
+#endif
+
+ if (profChanged) {
+ std::vector<colorspace::Component> things =
+ colorspace::getColorSpaceInfo(asICColorSpaceSig(_prof->getColorSpace()));
+ for (size_t i = 0; (i < things.size()) && (i < _profChannelCount); ++i) {
+ _compUI[i]._component = things[i];
+ }
+
+ for (guint i = 0; i < _profChannelCount; i++) {
+ gtk_label_set_text_with_mnemonic(GTK_LABEL(_compUI[i]._label),
+ (i < things.size()) ? things[i].name.c_str() : "");
+
+ _compUI[i]._slider->set_tooltip_text((i < things.size()) ? things[i].tip.c_str() : "");
+ gtk_widget_set_tooltip_text(_compUI[i]._btn, (i < things.size()) ? things[i].tip.c_str() : "");
+
+ _compUI[i]._slider->setColors(SPColor(0.0, 0.0, 0.0).toRGBA32(0xff),
+ SPColor(0.5, 0.5, 0.5).toRGBA32(0xff),
+ SPColor(1.0, 1.0, 1.0).toRGBA32(0xff));
+ /*
+ _compUI[i]._adj = GTK_ADJUSTMENT( gtk_adjustment_new( val, 0.0, _fooScales[i],
+ step, page, page ) );
+ g_signal_connect( G_OBJECT( _compUI[i]._adj ), "value_changed", G_CALLBACK(
+ _adjustmentChanged ), _csel );
+
+ sp_color_slider_set_adjustment( SP_COLOR_SLIDER(_compUI[i]._slider),
+ _compUI[i]._adj );
+ gtk_spin_button_set_adjustment( GTK_SPIN_BUTTON(_compUI[i]._btn),
+ _compUI[i]._adj );
+ gtk_spin_button_set_digits( GTK_SPIN_BUTTON(_compUI[i]._btn), digits );
+ */
+ gtk_widget_show(_compUI[i]._label);
+ _compUI[i]._slider->show();
+ gtk_widget_show(_compUI[i]._btn);
+ // gtk_adjustment_set_value( _compUI[i]._adj, 0.0 );
+ // gtk_adjustment_set_value( _compUI[i]._adj, val );
+ }
+ for (size_t i = _profChannelCount; i < _compUI.size(); i++) {
+ gtk_widget_hide(_compUI[i]._label);
+ _compUI[i]._slider->hide();
+ gtk_widget_hide(_compUI[i]._btn);
+ }
+ }
+ }
+ else {
+ // Give up for now on named colors
+ _prof = 0;
+ }
+ }
+
+#ifdef DEBUG_LCMS
+ g_message("\\_________ %p::_setProfile()", this);
+#endif // DEBUG_LCMS
+}
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
+void ColorICCSelectorImpl::_updateSliders(gint ignore)
+{
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ if (_color.color().icc) {
+ for (guint i = 0; i < _profChannelCount; i++) {
+ gdouble val = 0.0;
+ if (_color.color().icc->colors.size() > i) {
+ if (_compUI[i]._component.scale == 256) {
+ val = (_color.color().icc->colors[i] + 128.0) / static_cast<gdouble>(_compUI[i]._component.scale);
+ }
+ else {
+ val = _color.color().icc->colors[i] / static_cast<gdouble>(_compUI[i]._component.scale);
+ }
+ }
+ gtk_adjustment_set_value(_compUI[i]._adj, val);
+ }
+
+ if (_prof) {
+ if (_prof->getTransfToSRGB8()) {
+ for (guint i = 0; i < _profChannelCount; i++) {
+ if (static_cast<gint>(i) != ignore) {
+ cmsUInt16Number *scratch = getScratch();
+ cmsUInt16Number filler[4] = { 0, 0, 0, 0 };
+ for (guint j = 0; j < _profChannelCount; j++) {
+ filler[j] = 0x0ffff * ColorScales::getScaled(_compUI[j]._adj);
+ }
+
+ cmsUInt16Number *p = scratch;
+ for (guint x = 0; x < 1024; x++) {
+ for (guint j = 0; j < _profChannelCount; j++) {
+ if (j == i) {
+ *p++ = x * 0x0ffff / 1024;
+ }
+ else {
+ *p++ = filler[j];
+ }
+ }
+ }
+
+ cmsHTRANSFORM trans = _prof->getTransfToSRGB8();
+ if (trans) {
+ cmsDoTransform(trans, scratch, _compUI[i]._map, 1024);
+ if (_compUI[i]._slider)
+ {
+ _compUI[i]._slider->setMap(_compUI[i]._map);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#else
+ (void)ignore;
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
+ guint32 start = _color.color().toRGBA32(0x00);
+ guint32 mid = _color.color().toRGBA32(0x7f);
+ guint32 end = _color.color().toRGBA32(0xff);
+
+ _slider->setColors(start, mid, end);
+}
+
+
+void ColorICCSelectorImpl::_adjustmentChanged(GtkAdjustment *adjustment, ColorICCSelectorImpl *cs)
+{
+// // TODO check this. It looks questionable:
+// // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255 or 0..100
+// if (adjustment->value > 0.0 && adjustment->value < 1.0) {
+// gtk_adjustment_set_value( adjustment, floor ((adjustment->value) * adjustment->upper + 0.5) );
+// }
+
+#ifdef DEBUG_LCMS
+ g_message("/^^^^^^^^^ %p::_adjustmentChanged()", cs);
+#endif // DEBUG_LCMS
+
+ ColorICCSelector *iccSelector = cs->_owner;
+ if (iccSelector->_impl->_updating) {
+ return;
+ }
+
+ iccSelector->_impl->_updating = TRUE;
+
+ gint match = -1;
+
+ SPColor newColor(iccSelector->_impl->_color.color());
+ gfloat scaled = ColorScales::getScaled(iccSelector->_impl->_adj);
+ if (iccSelector->_impl->_adj == adjustment) {
+#ifdef DEBUG_LCMS
+ g_message("ALPHA");
+#endif // DEBUG_LCMS
+ }
+ else {
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ for (size_t i = 0; i < iccSelector->_impl->_compUI.size(); i++) {
+ if (iccSelector->_impl->_compUI[i]._adj == adjustment) {
+ match = i;
+ break;
+ }
+ }
+ if (match >= 0) {
+#ifdef DEBUG_LCMS
+ g_message(" channel %d", match);
+#endif // DEBUG_LCMS
+ }
+
+
+ cmsUInt16Number tmp[4];
+ for (guint i = 0; i < 4; i++) {
+ tmp[i] = ColorScales::getScaled(iccSelector->_impl->_compUI[i]._adj) * 0x0ffff;
+ }
+ guchar post[4] = { 0, 0, 0, 0 };
+
+ cmsHTRANSFORM trans = iccSelector->_impl->_prof->getTransfToSRGB8();
+ if (trans) {
+ cmsDoTransform(trans, tmp, post, 1);
+ }
+
+ SPColor other(SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255));
+ other.icc = new SVGICCColor();
+ if (iccSelector->_impl->_color.color().icc) {
+ other.icc->colorProfile = iccSelector->_impl->_color.color().icc->colorProfile;
+ }
+
+ guint32 prior = iccSelector->_impl->_color.color().toRGBA32(255);
+ guint32 newer = other.toRGBA32(255);
+
+ if (prior != newer) {
+#ifdef DEBUG_LCMS
+ g_message("Transformed color from 0x%08x to 0x%08x", prior, newer);
+ g_message(" ~~~~ FLIP");
+#endif // DEBUG_LCMS
+ newColor = other;
+ newColor.icc->colors.clear();
+ for (guint i = 0; i < iccSelector->_impl->_profChannelCount; i++) {
+ gdouble val = ColorScales::getScaled(iccSelector->_impl->_compUI[i]._adj);
+ val *= iccSelector->_impl->_compUI[i]._component.scale;
+ if (iccSelector->_impl->_compUI[i]._component.scale == 256) {
+ val -= 128;
+ }
+ newColor.icc->colors.push_back(val);
+ }
+ }
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ }
+ iccSelector->_impl->_color.setColorAlpha(newColor, scaled);
+ // iccSelector->_updateInternals( newColor, scaled, iccSelector->_impl->_dragging );
+ iccSelector->_impl->_updateSliders(match);
+
+ iccSelector->_impl->_updating = FALSE;
+#ifdef DEBUG_LCMS
+ g_message("\\_________ %p::_adjustmentChanged()", cs);
+#endif // DEBUG_LCMS
+}
+
+void ColorICCSelectorImpl::_sliderGrabbed()
+{
+ // ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base);
+ // if (!iccSelector->_dragging) {
+ // iccSelector->_dragging = TRUE;
+ // iccSelector->_grabbed();
+ // iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_impl->_adj ),
+ // iccSelector->_dragging );
+ // }
+}
+
+void ColorICCSelectorImpl::_sliderReleased()
+{
+ // ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base);
+ // if (iccSelector->_dragging) {
+ // iccSelector->_dragging = FALSE;
+ // iccSelector->_released();
+ // iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ),
+ // iccSelector->_dragging );
+ // }
+}
+
+#ifdef DEBUG_LCMS
+void ColorICCSelectorImpl::_sliderChanged(SPColorSlider *slider, SPColorICCSelector *cs)
+#else
+void ColorICCSelectorImpl::_sliderChanged()
+#endif // DEBUG_LCMS
+{
+#ifdef DEBUG_LCMS
+ g_message("Changed %p and %p", slider, cs);
+#endif // DEBUG_LCMS
+ // ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base);
+
+ // iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ),
+ // iccSelector->_dragging );
+}
+
+Gtk::Widget *ColorICCSelectorFactory::createWidget(Inkscape::UI::SelectedColor &color) const
+{
+ Gtk::Widget *w = Gtk::manage(new ColorICCSelector(color));
+ return w;
+}
+
+Glib::ustring ColorICCSelectorFactory::modeName() const { return gettext(ColorICCSelector::MODE_NAME); }
+}
+}
+}
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/color-icc-selector.h b/src/ui/widget/color-icc-selector.h
new file mode 100644
index 000000000..1bcb0a540
--- /dev/null
+++ b/src/ui/widget/color-icc-selector.h
@@ -0,0 +1,78 @@
+#ifndef SEEN_SP_COLOR_ICC_SELECTOR_H
+#define SEEN_SP_COLOR_ICC_SELECTOR_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtkmm/widget.h>
+#if WITH_GTKMM_3_0
+#include <gtkmm/grid.h>
+#else
+#include <gtkmm/table.h>
+#endif
+
+#include "ui/selected-color.h"
+
+namespace Inkscape {
+
+class ColorProfile;
+
+namespace UI {
+namespace Widget {
+
+class ColorICCSelectorImpl;
+
+class ColorICCSelector
+#if GTK_CHECK_VERSION(3, 0, 0)
+ : public Gtk::Grid
+#else
+ : public Gtk::Table
+#endif
+ {
+ public:
+ static const gchar *MODE_NAME;
+
+ ColorICCSelector(SelectedColor &color);
+ virtual ~ColorICCSelector();
+
+ virtual void init();
+
+ protected:
+ void on_show();
+
+ virtual void _colorChanged();
+
+ void _recalcColor(gboolean changing);
+
+ private:
+ friend class ColorICCSelectorImpl;
+
+ // By default, disallow copy constructor and assignment operator
+ ColorICCSelector(const ColorICCSelector &obj);
+ ColorICCSelector &operator=(const ColorICCSelector &obj);
+
+ ColorICCSelectorImpl *_impl;
+};
+
+
+class ColorICCSelectorFactory : public ColorSelectorFactory {
+ public:
+ Gtk::Widget *createWidget(SelectedColor &color) const;
+ Glib::ustring modeName() const;
+};
+}
+}
+}
+#endif // SEEN_SP_COLOR_ICC_SELECTOR_H
+
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/color-notebook.cpp b/src/ui/widget/color-notebook.cpp
new file mode 100644
index 000000000..60abf43bf
--- /dev/null
+++ b/src/ui/widget/color-notebook.cpp
@@ -0,0 +1,379 @@
+/**
+ * @file
+ * A notebook with RGB, CMYK, CMS, HSL, and Wheel pages - implementation
+ */
+/* Authors:
+ * Lauris Kaplinski <lauris@kaplinski.com>
+ * bulia byak <buliabyak@users.sf.net>
+ * Tomasz Boczkowski <penginsbacon@gmail.com> (c++-sification)
+ *
+ * Copyright (C) 2001-2014 Authors
+ *
+ * This code is in public domain
+ */
+
+#undef SPCS_PREVIEW
+#define noDUMP_CHANGE_INFO
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "widgets/icon.h"
+#include <cstring>
+#include <string>
+#include <cstdlib>
+#include <cstddef>
+#include <glibmm/i18n.h>
+#include <gtkmm/label.h>
+#include <gtkmm/notebook.h>
+
+#include "preferences.h"
+#include "widgets/spw-utilities.h"
+#include "svg/svg-icc-color.h"
+#include "inkscape.h"
+#include "document.h"
+#include "profile-manager.h"
+#include "color-profile.h"
+#include "cms-system.h"
+#include "ui/dialog-events.h"
+#include "ui/tools-switch.h"
+#include "ui/tools/tool-base.h"
+#include "ui/widget/color-entry.h"
+#include "ui/widget/color-icc-selector.h"
+#include "ui/widget/color-notebook.h"
+#include "ui/widget/color-scales.h"
+#include "ui/widget/color-wheel-selector.h"
+
+using Inkscape::CMSSystem;
+
+#define XPAD 4
+#define YPAD 1
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+
+ColorNotebook::ColorNotebook(SelectedColor &color)
+#if GTK_CHECK_VERSION(3, 0, 0)
+ : Gtk::Grid()
+#else
+ : Gtk::Table(2, 3, false)
+#endif
+ , _selected_color(color)
+
+{
+ Page *page;
+
+ page = new Page(new ColorScalesFactory(SP_COLOR_SCALES_MODE_RGB), true);
+ _available_pages.push_back(page);
+ page = new Page(new ColorScalesFactory(SP_COLOR_SCALES_MODE_HSV), true);
+ _available_pages.push_back(page);
+ page = new Page(new ColorScalesFactory(SP_COLOR_SCALES_MODE_CMYK), true);
+ _available_pages.push_back(page);
+ page = new Page(new ColorWheelSelectorFactory, true);
+ _available_pages.push_back(page);
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ page = new Page(new ColorICCSelectorFactory, true);
+ _available_pages.push_back(page);
+#endif
+
+ _initUI();
+
+ _selected_color.signal_changed.connect(sigc::mem_fun(this, &ColorNotebook::_onSelectedColorChanged));
+ _selected_color.signal_dragged.connect(sigc::mem_fun(this, &ColorNotebook::_onSelectedColorChanged));
+}
+
+ColorNotebook::~ColorNotebook()
+{
+ if (_buttons) {
+ delete[] _buttons;
+ _buttons = 0;
+ }
+}
+
+ColorNotebook::Page::Page(Inkscape::UI::ColorSelectorFactory *selector_factory, bool enabled_full)
+ : selector_factory(selector_factory)
+ , enabled_full(enabled_full)
+{
+}
+
+
+void ColorNotebook::_initUI()
+{
+ guint row = 0;
+
+ Gtk::Notebook *notebook = Gtk::manage(new Gtk::Notebook);
+ notebook->show();
+ notebook->set_show_border(false);
+ notebook->set_show_tabs(false);
+ _book = GTK_WIDGET(notebook->gobj());
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ _buttonbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
+ gtk_box_set_homogeneous(GTK_BOX(_buttonbox), TRUE);
+#else
+ _buttonbox = gtk_hbox_new(TRUE, 2);
+#endif
+
+ gtk_widget_show(_buttonbox);
+ _buttons = new GtkWidget *[_available_pages.size()];
+
+ for (int i = 0; static_cast<size_t>(i) < _available_pages.size(); i++) {
+ _addPage(_available_pages[i]);
+ }
+
+ sp_set_font_size_smaller(_buttonbox);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ #if GTK_CHECK_VERSION(3, 12, 0)
+ gtk_widget_set_margin_start(_buttonbox, XPAD);
+ gtk_widget_set_margin_end(_buttonbox, XPAD);
+ #else
+ gtk_widget_set_margin_left(_buttonbox, XPAD);
+ gtk_widget_set_margin_right(_buttonbox, XPAD);
+ #endif
+ gtk_widget_set_margin_top(_buttonbox, YPAD);
+ gtk_widget_set_margin_bottom(_buttonbox, YPAD);
+ gtk_widget_set_hexpand(_buttonbox, TRUE);
+ gtk_widget_set_valign(_buttonbox, GTK_ALIGN_CENTER);
+ attach(*Glib::wrap(_buttonbox), 0, row, 2, 1);
+#else
+ attach(*Glib::wrap(_buttonbox), 0, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, static_cast<Gtk::AttachOptions>(0),
+ XPAD, YPAD);
+#endif
+
+ row++;
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+#if GTK_CHECK_VERSION(3, 12, 0)
+ gtk_widget_set_margin_start(_book, XPAD * 2);
+ gtk_widget_set_margin_end(_book, XPAD * 2);
+#else
+ gtk_widget_set_margin_left(_book, XPAD * 2);
+ gtk_widget_set_margin_right(_book, XPAD * 2);
+#endif
+ gtk_widget_set_margin_top(_book, YPAD);
+ gtk_widget_set_margin_bottom(_book, YPAD);
+ gtk_widget_set_hexpand(_book, TRUE);
+ gtk_widget_set_vexpand(_book, TRUE);
+ attach(*notebook, 0, row, 2, 1);
+#else
+ attach(*notebook, 0, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::EXPAND | Gtk::FILL, XPAD * 2, YPAD);
+#endif
+
+ // restore the last active page
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ _setCurrentPage(prefs->getInt("/colorselector/page", 0));
+ row++;
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ GtkWidget *rgbabox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+#else
+ GtkWidget *rgbabox = gtk_hbox_new(FALSE, 0);
+#endif
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ /* Create color management icons */
+ _box_colormanaged = gtk_event_box_new();
+ GtkWidget *colormanaged = gtk_image_new_from_icon_name("color-management-icon", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_container_add(GTK_CONTAINER(_box_colormanaged), colormanaged);
+ gtk_widget_set_tooltip_text(_box_colormanaged, _("Color Managed"));
+ gtk_widget_set_sensitive(_box_colormanaged, false);
+ gtk_box_pack_start(GTK_BOX(rgbabox), _box_colormanaged, FALSE, FALSE, 2);
+
+ _box_outofgamut = gtk_event_box_new();
+ GtkWidget *outofgamut = gtk_image_new_from_icon_name("out-of-gamut-icon", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_container_add(GTK_CONTAINER(_box_outofgamut), outofgamut);
+ gtk_widget_set_tooltip_text(_box_outofgamut, _("Out of gamut!"));
+ gtk_widget_set_sensitive(_box_outofgamut, false);
+ gtk_box_pack_start(GTK_BOX(rgbabox), _box_outofgamut, FALSE, FALSE, 2);
+
+ _box_toomuchink = gtk_event_box_new();
+ GtkWidget *toomuchink = gtk_image_new_from_icon_name("too-much-ink-icon", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ gtk_container_add(GTK_CONTAINER(_box_toomuchink), toomuchink);
+ gtk_widget_set_tooltip_text(_box_toomuchink, _("Too much ink!"));
+ gtk_widget_set_sensitive(_box_toomuchink, false);
+ gtk_box_pack_start(GTK_BOX(rgbabox), _box_toomuchink, FALSE, FALSE, 2);
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
+
+ /* Color picker */
+ GtkWidget *picker = gtk_image_new_from_icon_name("color-picker", GTK_ICON_SIZE_SMALL_TOOLBAR);
+ _btn_picker = gtk_button_new();
+ gtk_button_set_relief(GTK_BUTTON(_btn_picker), GTK_RELIEF_NONE);
+ gtk_container_add(GTK_CONTAINER(_btn_picker), picker);
+ gtk_widget_set_tooltip_text(_btn_picker, _("Pick colors from image"));
+ gtk_box_pack_start(GTK_BOX(rgbabox), _btn_picker, FALSE, FALSE, 2);
+ g_signal_connect(G_OBJECT(_btn_picker), "clicked", G_CALLBACK(ColorNotebook::_onPickerClicked), this);
+
+ /* Create RGBA entry and color preview */
+ _rgbal = gtk_label_new_with_mnemonic(_("RGBA_:"));
+ gtk_misc_set_alignment(GTK_MISC(_rgbal), 1.0, 0.5);
+ gtk_box_pack_start(GTK_BOX(rgbabox), _rgbal, TRUE, TRUE, 2);
+
+ ColorEntry *rgba_entry = Gtk::manage(new ColorEntry(_selected_color));
+ sp_dialog_defocus_on_enter(GTK_WIDGET(rgba_entry->gobj()));
+ gtk_box_pack_start(GTK_BOX(rgbabox), GTK_WIDGET(rgba_entry->gobj()), FALSE, FALSE, 0);
+ gtk_label_set_mnemonic_widget(GTK_LABEL(_rgbal), GTK_WIDGET(rgba_entry->gobj()));
+
+ sp_set_font_size_smaller(rgbabox);
+ gtk_widget_show_all(rgbabox);
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ // the "too much ink" icon is initially hidden
+ gtk_widget_hide(GTK_WIDGET(_box_toomuchink));
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ #if GTK_CHECK_VERSION(3, 12, 0)
+ gtk_widget_set_margin_start(rgbabox, XPAD);
+ gtk_widget_set_margin_end(rgbabox, XPAD);
+ #else
+ gtk_widget_set_margin_left(rgbabox, XPAD);
+ gtk_widget_set_margin_right(rgbabox, XPAD);
+ #endif
+ gtk_widget_set_margin_top(rgbabox, YPAD);
+ gtk_widget_set_margin_bottom(rgbabox, YPAD);
+ attach(*Glib::wrap(rgbabox), 0, row, 2, 1);
+#else
+ attach(*Glib::wrap(rgbabox), 0, 2, row, row + 1, Gtk::FILL, Gtk::SHRINK, XPAD, YPAD);
+#endif
+
+#ifdef SPCS_PREVIEW
+ _p = sp_color_preview_new(0xffffffff);
+ gtk_widget_show(_p);
+ attach(*Glib::wrap(_p), 2, 3, row, row + 1, Gtk::FILL, Gtk::FILL, XPAD, YPAD);
+#endif
+
+ g_signal_connect(G_OBJECT(_book), "switch-page", G_CALLBACK(ColorNotebook::_onPageSwitched), this);
+}
+
+void ColorNotebook::_onPickerClicked(GtkWidget * /*widget*/, ColorNotebook * /*colorbook*/)
+{
+ // Set the dropper into a "one click" mode, so it reverts to the previous tool after a click
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setBool("/tools/dropper/onetimepick", true);
+ Inkscape::UI::Tools::sp_toggle_dropper(SP_ACTIVE_DESKTOP);
+}
+
+void ColorNotebook::_onButtonClicked(GtkWidget *widget, ColorNotebook *nb)
+{
+ if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
+ return;
+ }
+
+ for (gint i = 0; i < gtk_notebook_get_n_pages(GTK_NOTEBOOK(nb->_book)); i++) {
+ if (nb->_buttons[i] == widget) {
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(nb->_book), i);
+ }
+ }
+}
+
+void ColorNotebook::_onSelectedColorChanged() { _updateICCButtons(); }
+
+void ColorNotebook::_onPageSwitched(GtkNotebook *notebook, GtkWidget *page, guint page_num, ColorNotebook *colorbook)
+{
+ if (colorbook->get_visible()) {
+ // remember the page we switched to
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setInt("/colorselector/page", page_num);
+ }
+}
+
+
+// TODO pass in param so as to avoid the need for SP_ACTIVE_DOCUMENT
+void ColorNotebook::_updateICCButtons()
+{
+ SPColor color = _selected_color.color();
+ gfloat alpha = _selected_color.alpha();
+
+ g_return_if_fail((0.0 <= alpha) && (alpha <= 1.0));
+
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ /* update color management icon*/
+ gtk_widget_set_sensitive(_box_colormanaged, color.icc != NULL);
+
+ /* update out-of-gamut icon */
+ gtk_widget_set_sensitive(_box_outofgamut, false);
+ if (color.icc) {
+ Inkscape::ColorProfile *target_profile =
+ SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str());
+ if (target_profile)
+ gtk_widget_set_sensitive(_box_outofgamut, target_profile->GamutCheck(color));
+ }
+
+ /* update too-much-ink icon */
+ gtk_widget_set_sensitive(_box_toomuchink, false);
+ if (color.icc) {
+ Inkscape::ColorProfile *prof = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str());
+ if (prof && CMSSystem::isPrintColorSpace(prof)) {
+ gtk_widget_show(GTK_WIDGET(_box_toomuchink));
+ double ink_sum = 0;
+ for (unsigned int i = 0; i < color.icc->colors.size(); i++) {
+ ink_sum += color.icc->colors[i];
+ }
+
+ /* Some literature states that when the sum of paint values exceed 320%, it is considered to be a satured
+ color,
+ which means the paper can get too wet due to an excessive ammount of ink. This may lead to several
+ issues
+ such as misalignment and poor quality of printing in general.*/
+ if (ink_sum > 3.2)
+ gtk_widget_set_sensitive(_box_toomuchink, true);
+ }
+ else {
+ gtk_widget_hide(GTK_WIDGET(_box_toomuchink));
+ }
+ }
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+}
+
+void ColorNotebook::_setCurrentPage(int i)
+{
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(_book), i);
+
+ if (_buttons && (static_cast<size_t>(i) < _available_pages.size())) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_buttons[i]), TRUE);
+ }
+}
+
+void ColorNotebook::_addPage(Page &page)
+{
+ Gtk::Widget *selector_widget;
+
+ selector_widget = page.selector_factory->createWidget(_selected_color);
+ if (selector_widget) {
+ selector_widget->show();
+
+ Glib::ustring mode_name = page.selector_factory->modeName();
+ Gtk::Widget *tab_label = Gtk::manage(new Gtk::Label(mode_name));
+ gint page_num = gtk_notebook_append_page(GTK_NOTEBOOK(_book), selector_widget->gobj(), tab_label->gobj());
+
+ _buttons[page_num] = gtk_radio_button_new_with_label(NULL, mode_name.c_str());
+ gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(_buttons[page_num]), FALSE);
+ if (page_num > 0) {
+ GSList *group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(_buttons[0]));
+ gtk_radio_button_set_group(GTK_RADIO_BUTTON(_buttons[page_num]), group);
+ }
+ gtk_widget_show(_buttons[page_num]);
+ gtk_box_pack_start(GTK_BOX(_buttonbox), _buttons[page_num], TRUE, TRUE, 0);
+
+ g_signal_connect(G_OBJECT(_buttons[page_num]), "clicked", G_CALLBACK(_onButtonClicked), this);
+ }
+}
+}
+}
+}
+
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/color-notebook.h b/src/ui/widget/color-notebook.h
new file mode 100644
index 000000000..d28028c72
--- /dev/null
+++ b/src/ui/widget/color-notebook.h
@@ -0,0 +1,99 @@
+/**
+ * @file
+ * A notebook with RGB, CMYK, CMS, HSL, and Wheel pages
+ */
+/* Authors:
+ * Lauris Kaplinski <lauris@kaplinski.com>
+ * bulia byak <buliabyak@users.sf.net>
+ * Tomasz Boczkowski <penginsbacon@gmail.com> (c++-sification)
+ *
+ * Copyright (C) 2001-2014 Authors
+ *
+ * This code is in public domain
+ */
+#ifndef SEEN_SP_COLOR_NOTEBOOK_H
+#define SEEN_SP_COLOR_NOTEBOOK_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/ptr_container/ptr_vector.hpp>
+#if WITH_GTKMM_3_0
+#include <gtkmm/grid.h>
+#else
+#include <gtkmm/table.h>
+#endif
+#include <gtk/gtk.h>
+#include <glib.h>
+
+#include "color.h"
+#include "ui/selected-color.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+class ColorNotebook
+#if GTK_CHECK_VERSION(3, 0, 0)
+ : public Gtk::Grid
+#else
+ : public Gtk::Table
+#endif
+{
+public:
+ ColorNotebook(SelectedColor &color);
+ virtual ~ColorNotebook();
+
+protected:
+ struct Page {
+ Page(Inkscape::UI::ColorSelectorFactory *selector_factory, bool enabled_full);
+
+ Inkscape::UI::ColorSelectorFactory *selector_factory;
+ bool enabled_full;
+ };
+
+ virtual void _initUI();
+ void _addPage(Page &page);
+
+ static void _onButtonClicked(GtkWidget *widget, ColorNotebook *colorbook);
+ static void _onPickerClicked(GtkWidget *widget, ColorNotebook *colorbook);
+ static void _onPageSwitched(GtkNotebook *notebook, GtkWidget *page, guint page_num, ColorNotebook *colorbook);
+ virtual void _onSelectedColorChanged();
+
+ void _updateICCButtons();
+ void _setCurrentPage(int i);
+
+ Inkscape::UI::SelectedColor &_selected_color;
+ gulong _entryId;
+ GtkWidget *_book;
+ GtkWidget *_buttonbox;
+ GtkWidget **_buttons;
+ GtkWidget *_rgbal; /* RGBA entry */
+#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ GtkWidget *_box_outofgamut, *_box_colormanaged, *_box_toomuchink;
+#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
+ GtkWidget *_btn_picker;
+ GtkWidget *_p; /* Color preview */
+ boost::ptr_vector<Page> _available_pages;
+
+private:
+ // By default, disallow copy constructor and assignment operator
+ ColorNotebook(const ColorNotebook &obj);
+ ColorNotebook &operator=(const ColorNotebook &obj);
+};
+}
+}
+}
+#endif // SEEN_SP_COLOR_NOTEBOOK_H
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
+
diff --git a/src/ui/widget/color-picker.cpp b/src/ui/widget/color-picker.cpp
index d4c4d394e..a66fbfc9c 100644
--- a/src/ui/widget/color-picker.cpp
+++ b/src/ui/widget/color-picker.cpp
@@ -17,7 +17,7 @@
#include "document-undo.h"
#include "ui/dialog-events.h"
-#include "widgets/sp-color-notebook.h"
+#include "ui/widget/color-notebook.h"
#include "verbs.h"
@@ -27,8 +27,6 @@ namespace Inkscape {
namespace UI {
namespace Widget {
-void sp_color_picker_color_mod(SPColorSelector *csel, GObject *cp);
-
ColorPicker::ColorPicker (const Glib::ustring& title, const Glib::ustring& tip,
guint32 rgba, bool undo)
: _preview(rgba), _title(title), _rgba(rgba), _undo(undo),
@@ -39,12 +37,15 @@ ColorPicker::ColorPicker (const Glib::ustring& title, const Glib::ustring& tip,
_preview.show();
add (_preview);
set_tooltip_text (tip);
+
+ _selected_color.signal_changed.connect(sigc::mem_fun(this, &ColorPicker::_onSelectedColorChanged));
+ _selected_color.signal_dragged.connect(sigc::mem_fun(this, &ColorPicker::_onSelectedColorChanged));
+ _selected_color.signal_released.connect(sigc::mem_fun(this, &ColorPicker::_onSelectedColorChanged));
}
ColorPicker::~ColorPicker()
{
closeWindow();
- _colorSelector = NULL;
}
void ColorPicker::setupDialog(const Glib::ustring &title)
@@ -55,25 +56,17 @@ void ColorPicker::setupDialog(const Glib::ustring &title)
_colorSelectorDialog.hide();
_colorSelectorDialog.set_title (title);
_colorSelectorDialog.set_border_width (4);
- _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK));
+
+ _color_selector = Gtk::manage(new ColorNotebook(_selected_color));
#if WITH_GTKMM_3_0
_colorSelectorDialog.get_content_area()->pack_start (
- *Glib::wrap(&_colorSelector->vbox), true, true, 0);
+ *_color_selector, true, true, 0);
#else
_colorSelectorDialog.get_vbox()->pack_start (
- *Glib::wrap(&_colorSelector->vbox), true, true, 0);
+ *_color_selector, true, true, 0);
#endif
-
- g_signal_connect(G_OBJECT(_colorSelector), "dragged",
- G_CALLBACK(sp_color_picker_color_mod), (void *)this);
- g_signal_connect(G_OBJECT(_colorSelector), "released",
- G_CALLBACK(sp_color_picker_color_mod), (void *)this);
- g_signal_connect(G_OBJECT(_colorSelector), "changed",
- G_CALLBACK(sp_color_picker_color_mod), (void *)this);
-
- gtk_widget_show(GTK_WIDGET(_colorSelector));
-
+ _color_selector->show();
}
void ColorPicker::setRgba32 (guint32 rgba)
@@ -82,11 +75,11 @@ void ColorPicker::setRgba32 (guint32 rgba)
_preview.setRgba32 (rgba);
_rgba = rgba;
- if (_colorSelector)
+ if (_color_selector)
{
- SPColor color;
- color.set( rgba );
- _colorSelector->base->setColorAlpha(color, SP_RGBA32_A_F(rgba));
+ _updating = true;
+ _selected_color.setValue(rgba);
+ _updating = false;
}
}
@@ -97,11 +90,11 @@ void ColorPicker::closeWindow()
void ColorPicker::on_clicked()
{
- if (_colorSelector)
+ if (_color_selector)
{
- SPColor color;
- color.set( _rgba );
- _colorSelector->base->setColorAlpha(color, SP_RGBA32_A_F(_rgba));
+ _updating = true;
+ _selected_color.setValue(_rgba);
+ _updating = false;
}
_colorSelectorDialog.show();
}
@@ -110,34 +103,31 @@ void ColorPicker::on_changed (guint32)
{
}
-void sp_color_picker_color_mod(SPColorSelector *csel, GObject *cp)
-{
+void ColorPicker::_onSelectedColorChanged() {
+ if (_updating) {
+ return;
+ }
+
if (_in_use) {
return;
} else {
_in_use = true;
}
- SPColor color;
- float alpha = 0;
- csel->base->getColorAlpha(color, alpha);
- guint32 rgba = color.toRGBA32( alpha );
-
- ColorPicker *ptr = reinterpret_cast<ColorPicker *>(cp);
-
- (ptr->_preview).setRgba32 (rgba);
+ guint32 rgba = _selected_color.value();
+ _preview.setRgba32(rgba);
- if (ptr->_undo && SP_ACTIVE_DESKTOP)
+ if (_undo && SP_ACTIVE_DESKTOP) {
DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_NONE,
/* TODO: annotate */ "color-picker.cpp:130");
+ }
- ptr->on_changed (rgba);
+ on_changed(rgba);
_in_use = false;
- ptr->_changed_signal.emit (rgba);
- ptr->_rgba = rgba;
+ _changed_signal.emit(rgba);
+ _rgba = rgba;
}
-
}//namespace Widget
}//namespace UI
}//namespace Inkscape
diff --git a/src/ui/widget/color-picker.h b/src/ui/widget/color-picker.h
index 99904b081..e8a738b5b 100644
--- a/src/ui/widget/color-picker.h
+++ b/src/ui/widget/color-picker.h
@@ -18,6 +18,7 @@
#include <gtkmm/dialog.h>
#include <gtkmm/button.h>
#include <sigc++/sigc++.h>
+#include "ui/selected-color.h"
#include "ui/widget/color-preview.h"
struct SPColorSelector;
@@ -49,7 +50,7 @@ public:
protected:
- friend void sp_color_picker_color_mod(SPColorSelector *csel, GObject *cp);
+ void _onSelectedColorChanged();
virtual void on_clicked();
virtual void on_changed (guint32);
@@ -59,13 +60,14 @@ protected:
sigc::signal<void,guint32> _changed_signal;
guint32 _rgba;
bool _undo;
-
+ bool _updating;
//Dialog
void setupDialog(const Glib::ustring &title);
//Inkscape::UI::Dialog::Dialog _colorSelectorDialog;
Gtk::Dialog _colorSelectorDialog;
- SPColorSelector *_colorSelector;
+ SelectedColor _selected_color;
+ Gtk::Widget *_color_selector;
};
}//namespace Widget
diff --git a/src/ui/widget/color-scales.cpp b/src/ui/widget/color-scales.cpp
new file mode 100644
index 000000000..170f83887
--- /dev/null
+++ b/src/ui/widget/color-scales.cpp
@@ -0,0 +1,677 @@
+/*
+ * bulia byak <buliabyak@users.sf.net>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include <gtkmm/adjustment.h>
+#include <glibmm/i18n.h>
+#include <gtk/gtk.h>
+
+#include "svg/svg-icc-color.h"
+#include "ui/dialog-events.h"
+#include "ui/widget/color-scales.h"
+#include "ui/widget/color-slider.h"
+
+#define CSC_CHANNEL_R (1 << 0)
+#define CSC_CHANNEL_G (1 << 1)
+#define CSC_CHANNEL_B (1 << 2)
+#define CSC_CHANNEL_A (1 << 3)
+#define CSC_CHANNEL_H (1 << 0)
+#define CSC_CHANNEL_S (1 << 1)
+#define CSC_CHANNEL_V (1 << 2)
+#define CSC_CHANNEL_C (1 << 0)
+#define CSC_CHANNEL_M (1 << 1)
+#define CSC_CHANNEL_Y (1 << 2)
+#define CSC_CHANNEL_K (1 << 3)
+#define CSC_CHANNEL_CMYKA (1 << 4)
+
+#define CSC_CHANNELS_ALL 0
+
+#define XPAD 4
+#define YPAD 1
+
+#define noDUMP_CHANGE_INFO 1
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+
+static const gchar *sp_color_scales_hue_map();
+
+const gchar *ColorScales::SUBMODE_NAMES[] = { N_("None"), N_("RGB"), N_("HSL"), N_("CMYK") };
+
+ColorScales::ColorScales(SelectedColor &color, SPColorScalesMode mode)
+#if GTK_CHECK_VERSION(3, 0, 0)
+ : Gtk::Grid()
+#else
+ : Gtk::Table(5, 3, false)
+#endif
+ , _color(color)
+ , _rangeLimit(255.0)
+ , _updating(FALSE)
+ , _dragging(FALSE)
+{
+ for (gint i = 0; i < 5; i++) {
+ _l[i] = 0;
+ _a[i] = 0;
+ _s[i] = 0;
+ _b[i] = 0;
+ }
+
+ _initUI(mode);
+
+ _color.signal_changed.connect(sigc::mem_fun(this, &ColorScales::_onColorChanged));
+ _color.signal_dragged.connect(sigc::mem_fun(this, &ColorScales::_onColorChanged));
+}
+
+ColorScales::~ColorScales()
+{
+ for (gint i = 0; i < 5; i++) {
+ _l[i] = 0;
+ _a[i] = 0;
+ _s[i] = 0;
+ _b[i] = 0;
+ }
+}
+
+void ColorScales::_initUI(SPColorScalesMode mode)
+{
+ gint i;
+
+ _updating = FALSE;
+ _dragging = FALSE;
+
+ GtkWidget *t = GTK_WIDGET(gobj());
+
+ /* Create components */
+ for (i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++) {
+ /* Label */
+ _l[i] = gtk_label_new("");
+ gtk_misc_set_alignment(GTK_MISC(_l[i]), 1.0, 0.5);
+ gtk_widget_show(_l[i]);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ #if GTK_CHECK_VERSION(3, 12, 0)
+ gtk_widget_set_margin_start(_l[i], XPAD);
+ gtk_widget_set_margin_end(_l[i], XPAD);
+ #else
+ gtk_widget_set_margin_left(_l[i], XPAD);
+ gtk_widget_set_margin_right(_l[i], XPAD);
+ #endif
+ gtk_widget_set_margin_top(_l[i], YPAD);
+ gtk_widget_set_margin_bottom(_l[i], YPAD);
+ gtk_grid_attach(GTK_GRID(t), _l[i], 0, i, 1, 1);
+#else
+ gtk_table_attach(GTK_TABLE(t), _l[i], 0, 1, i, i + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);
+#endif
+
+ /* Adjustment */
+ _a[i] = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, _rangeLimit, 1.0, 10.0, 10.0));
+ /* Slider */
+ _s[i] = Gtk::manage(new Inkscape::UI::Widget::ColorSlider(Glib::wrap(_a[i], true)));
+ _s[i]->show();
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ #if GTK_CHECK_VERSION(3, 12, 0)
+ _s[i]->set_margin_start(XPAD);
+ _s[i]->set_margin_end(XPAD);
+ #else
+ _s[i]->set_margin_left(XPAD);
+ _s[i]->set_margin_right(XPAD);
+ #endif
+ _s[i]->set_margin_top(YPAD);
+ _s[i]->set_margin_bottom(YPAD);
+ _s[i]->set_hexpand(true);
+ gtk_grid_attach(GTK_GRID(t), _s[i]->gobj(), 1, i, 1, 1);
+#else
+ gtk_table_attach(GTK_TABLE(t), _s[i]->gobj(), 1, 2, i, i + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
+ GTK_FILL, XPAD, YPAD);
+#endif
+
+ /* Spinbutton */
+ _b[i] = gtk_spin_button_new(GTK_ADJUSTMENT(_a[i]), 1.0, 0);
+ sp_dialog_defocus_on_enter(_b[i]);
+ gtk_label_set_mnemonic_widget(GTK_LABEL(_l[i]), _b[i]);
+ gtk_widget_show(_b[i]);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ #if GTK_CHECK_VERSION(3, 12, 0)
+ gtk_widget_set_margin_start(_b[i], XPAD);
+ gtk_widget_set_margin_end(_b[i], XPAD);
+ #else
+ gtk_widget_set_margin_left(_b[i], XPAD);
+ gtk_widget_set_margin_right(_b[i], XPAD);
+ #endif
+ gtk_widget_set_margin_top(_b[i], YPAD);
+ gtk_widget_set_margin_bottom(_b[i], YPAD);
+ gtk_widget_set_halign(_b[i], GTK_ALIGN_CENTER);
+ gtk_widget_set_valign(_b[i], GTK_ALIGN_CENTER);
+ gtk_grid_attach(GTK_GRID(t), _b[i], 2, i, 1, 1);
+#else
+ gtk_table_attach(GTK_TABLE(t), _b[i], 2, 3, i, i + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD);
+#endif
+
+ /* Attach channel value to adjustment */
+ g_object_set_data(G_OBJECT(_a[i]), "channel", GINT_TO_POINTER(i));
+ /* Signals */
+ g_signal_connect(G_OBJECT(_a[i]), "value_changed", G_CALLBACK(_adjustmentAnyChanged), this);
+ _s[i]->signal_grabbed.connect(sigc::mem_fun(this, &ColorScales::_sliderAnyGrabbed));
+ _s[i]->signal_released.connect(sigc::mem_fun(this, &ColorScales::_sliderAnyReleased));
+ _s[i]->signal_value_changed.connect(sigc::mem_fun(this, &ColorScales::_sliderAnyChanged));
+ }
+
+ //Prevent 5th bar from being shown by PanelDialog::show_all_children
+ gtk_widget_set_no_show_all(_l[4], TRUE);
+ _s[4]->set_no_show_all(true);
+ gtk_widget_set_no_show_all(_b[4], TRUE);
+
+ /* Initial mode is none, so it works */
+ setMode(mode);
+}
+
+void ColorScales::_recalcColor()
+{
+ SPColor color;
+ gfloat alpha = 1.0;
+ gfloat c[5];
+
+ switch (_mode) {
+ case SP_COLOR_SCALES_MODE_RGB:
+ case SP_COLOR_SCALES_MODE_HSV:
+ _getRgbaFloatv(c);
+ color.set(c[0], c[1], c[2]);
+ alpha = c[3];
+ break;
+ case SP_COLOR_SCALES_MODE_CMYK: {
+ _getCmykaFloatv(c);
+
+ float rgb[3];
+ sp_color_cmyk_to_rgb_floatv(rgb, c[0], c[1], c[2], c[3]);
+ color.set(rgb[0], rgb[1], rgb[2]);
+ alpha = c[4];
+ break;
+ }
+ default:
+ g_warning("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode);
+ break;
+ }
+
+ _color.preserveICC();
+ _color.setColorAlpha(color, alpha);
+}
+
+void ColorScales::_updateDisplay()
+{
+#ifdef DUMP_CHANGE_INFO
+ g_message("ColorScales::_onColorChanged( this=%p, %f, %f, %f, %f)", this, _color.color().v.c[0],
+ _color.color().v.c[1], _color.color().v.c[2], _color.alpha());
+#endif
+ gfloat tmp[3];
+ gfloat c[5] = { 0.0, 0.0, 0.0, 0.0 };
+
+ SPColor color = _color.color();
+
+ switch (_mode) {
+ case SP_COLOR_SCALES_MODE_RGB:
+ sp_color_get_rgb_floatv(&color, c);
+ c[3] = _color.alpha();
+ c[4] = 0.0;
+ break;
+ case SP_COLOR_SCALES_MODE_HSV:
+ sp_color_get_rgb_floatv(&color, tmp);
+ sp_color_rgb_to_hsl_floatv(c, tmp[0], tmp[1], tmp[2]);
+ c[3] = _color.alpha();
+ c[4] = 0.0;
+ break;
+ case SP_COLOR_SCALES_MODE_CMYK:
+ sp_color_get_cmyk_floatv(&color, c);
+ c[4] = _color.alpha();
+ break;
+ default:
+ g_warning("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode);
+ break;
+ }
+
+ _updating = TRUE;
+ setScaled(_a[0], c[0]);
+ setScaled(_a[1], c[1]);
+ setScaled(_a[2], c[2]);
+ setScaled(_a[3], c[3]);
+ setScaled(_a[4], c[4]);
+ _updateSliders(CSC_CHANNELS_ALL);
+ _updating = FALSE;
+}
+
+/* Helpers for setting color value */
+gfloat ColorScales::getScaled(const GtkAdjustment *a)
+{
+ gfloat val = gtk_adjustment_get_value(const_cast<GtkAdjustment *>(a)) /
+ gtk_adjustment_get_upper(const_cast<GtkAdjustment *>(a));
+ return val;
+}
+
+void ColorScales::setScaled(GtkAdjustment *a, gfloat v)
+{
+ gfloat val = v * gtk_adjustment_get_upper(a);
+ gtk_adjustment_set_value(a, val);
+}
+
+void ColorScales::_setRangeLimit(gdouble upper)
+{
+ _rangeLimit = upper;
+ for (gint i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++) {
+ gtk_adjustment_set_upper(_a[i], upper);
+ gtk_adjustment_changed(_a[i]);
+ }
+}
+
+void ColorScales::_onColorChanged()
+{
+ if (!get_visible()) {
+ return;
+ }
+ _updateDisplay();
+}
+
+void ColorScales::on_show()
+{
+#if GTK_CHECK_VERSION(3, 0, 0)
+ Gtk::Grid::on_show();
+#else
+ Gtk::Table::on_show();
+#endif
+ _updateDisplay();
+}
+
+void ColorScales::_getRgbaFloatv(gfloat *rgba)
+{
+ g_return_if_fail(rgba != NULL);
+
+ switch (_mode) {
+ case SP_COLOR_SCALES_MODE_RGB:
+ rgba[0] = getScaled(_a[0]);
+ rgba[1] = getScaled(_a[1]);
+ rgba[2] = getScaled(_a[2]);
+ rgba[3] = getScaled(_a[3]);
+ break;
+ case SP_COLOR_SCALES_MODE_HSV:
+ sp_color_hsl_to_rgb_floatv(rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
+ rgba[3] = getScaled(_a[3]);
+ break;
+ case SP_COLOR_SCALES_MODE_CMYK:
+ sp_color_cmyk_to_rgb_floatv(rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
+ rgba[3] = getScaled(_a[4]);
+ break;
+ default:
+ g_warning("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
+ break;
+ }
+}
+
+void ColorScales::_getCmykaFloatv(gfloat *cmyka)
+{
+ gfloat rgb[3];
+
+ g_return_if_fail(cmyka != NULL);
+
+ switch (_mode) {
+ case SP_COLOR_SCALES_MODE_RGB:
+ sp_color_rgb_to_cmyk_floatv(cmyka, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
+ cmyka[4] = getScaled(_a[3]);
+ break;
+ case SP_COLOR_SCALES_MODE_HSV:
+ sp_color_hsl_to_rgb_floatv(rgb, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
+ sp_color_rgb_to_cmyk_floatv(cmyka, rgb[0], rgb[1], rgb[2]);
+ cmyka[4] = getScaled(_a[3]);
+ break;
+ case SP_COLOR_SCALES_MODE_CMYK:
+ cmyka[0] = getScaled(_a[0]);
+ cmyka[1] = getScaled(_a[1]);
+ cmyka[2] = getScaled(_a[2]);
+ cmyka[3] = getScaled(_a[3]);
+ cmyka[4] = getScaled(_a[4]);
+ break;
+ default:
+ g_warning("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
+ break;
+ }
+}
+
+guint32 ColorScales::_getRgba32()
+{
+ gfloat c[4];
+ guint32 rgba;
+
+ _getRgbaFloatv(c);
+
+ rgba = SP_RGBA32_F_COMPOSE(c[0], c[1], c[2], c[3]);
+
+ return rgba;
+}
+
+void ColorScales::setMode(SPColorScalesMode mode)
+{
+ gfloat rgba[4];
+ gfloat c[4];
+
+ if (_mode == mode)
+ return;
+
+ if ((_mode == SP_COLOR_SCALES_MODE_RGB) || (_mode == SP_COLOR_SCALES_MODE_HSV) ||
+ (_mode == SP_COLOR_SCALES_MODE_CMYK)) {
+ _getRgbaFloatv(rgba);
+ }
+ else {
+ rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0;
+ }
+
+ _mode = mode;
+
+ switch (mode) {
+ case SP_COLOR_SCALES_MODE_RGB:
+ _setRangeLimit(255.0);
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[0]), _("_R:"));
+ _s[0]->set_tooltip_text(_("Red"));
+ gtk_widget_set_tooltip_text(_b[0], _("Red"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[1]), _("_G:"));
+ _s[1]->set_tooltip_text(_("Green"));
+ gtk_widget_set_tooltip_text(_b[1], _("Green"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[2]), _("_B:"));
+ _s[2]->set_tooltip_text(_("Blue"));
+ gtk_widget_set_tooltip_text(_b[2], _("Blue"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[3]), _("_A:"));
+ _s[3]->set_tooltip_text(_("Alpha (opacity)"));
+ gtk_widget_set_tooltip_text(_b[3], _("Alpha (opacity)"));
+ _s[0]->setMap(NULL);
+ gtk_widget_hide(_l[4]);
+ _s[4]->hide();
+ gtk_widget_hide(_b[4]);
+ _updating = TRUE;
+ setScaled(_a[0], rgba[0]);
+ setScaled(_a[1], rgba[1]);
+ setScaled(_a[2], rgba[2]);
+ setScaled(_a[3], rgba[3]);
+ _updateSliders(CSC_CHANNELS_ALL);
+ _updating = FALSE;
+ break;
+ case SP_COLOR_SCALES_MODE_HSV:
+ _setRangeLimit(255.0);
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[0]), _("_H:"));
+ _s[0]->set_tooltip_text(_("Hue"));
+ gtk_widget_set_tooltip_text(_b[0], _("Hue"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[1]), _("_S:"));
+ _s[1]->set_tooltip_text(_("Saturation"));
+ gtk_widget_set_tooltip_text(_b[1], _("Saturation"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[2]), _("_L:"));
+ _s[2]->set_tooltip_text(_("Lightness"));
+ gtk_widget_set_tooltip_text(_b[2], _("Lightness"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[3]), _("_A:"));
+ _s[3]->set_tooltip_text(_("Alpha (opacity)"));
+ gtk_widget_set_tooltip_text(_b[3], _("Alpha (opacity)"));
+ _s[0]->setMap((guchar *)(sp_color_scales_hue_map()));
+ gtk_widget_hide(_l[4]);
+ _s[4]->hide();
+ gtk_widget_hide(_b[4]);
+ _updating = TRUE;
+ c[0] = 0.0;
+ sp_color_rgb_to_hsl_floatv(c, rgba[0], rgba[1], rgba[2]);
+ setScaled(_a[0], c[0]);
+ setScaled(_a[1], c[1]);
+ setScaled(_a[2], c[2]);
+ setScaled(_a[3], rgba[3]);
+ _updateSliders(CSC_CHANNELS_ALL);
+ _updating = FALSE;
+ break;
+ case SP_COLOR_SCALES_MODE_CMYK:
+ _setRangeLimit(100.0);
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[0]), _("_C:"));
+ _s[0]->set_tooltip_text(_("Cyan"));
+ gtk_widget_set_tooltip_text(_b[0], _("Cyan"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[1]), _("_M:"));
+ _s[1]->set_tooltip_text(_("Magenta"));
+ gtk_widget_set_tooltip_text(_b[1], _("Magenta"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[2]), _("_Y:"));
+ _s[2]->set_tooltip_text(_("Yellow"));
+ gtk_widget_set_tooltip_text(_b[2], _("Yellow"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[3]), _("_K:"));
+ _s[3]->set_tooltip_text(_("Black"));
+ gtk_widget_set_tooltip_text(_b[3], _("Black"));
+ gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[4]), _("_A:"));
+ _s[4]->set_tooltip_text(_("Alpha (opacity)"));
+ gtk_widget_set_tooltip_text(_b[4], _("Alpha (opacity)"));
+ _s[0]->setMap(NULL);
+ gtk_widget_show(_l[4]);
+ _s[4]->show();
+ gtk_widget_show(_b[4]);
+ _updating = TRUE;
+
+ sp_color_rgb_to_cmyk_floatv(c, rgba[0], rgba[1], rgba[2]);
+ setScaled(_a[0], c[0]);
+ setScaled(_a[1], c[1]);
+ setScaled(_a[2], c[2]);
+ setScaled(_a[3], c[3]);
+
+ setScaled(_a[4], rgba[3]);
+ _updateSliders(CSC_CHANNELS_ALL);
+ _updating = FALSE;
+ break;
+ default:
+ g_warning("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
+ break;
+ }
+}
+
+SPColorScalesMode ColorScales::getMode() const { return _mode; }
+
+void ColorScales::_adjustmentAnyChanged(GtkAdjustment *adjustment, ColorScales *cs)
+{
+ gint channel = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(adjustment), "channel"));
+
+ _adjustmentChanged(cs, channel);
+}
+
+void ColorScales::_sliderAnyGrabbed()
+{
+ if (_updating) {
+ return;
+ }
+ if (!_dragging) {
+ _dragging = TRUE;
+ _color.setHeld(true);
+ }
+}
+
+void ColorScales::_sliderAnyReleased()
+{
+ if (_updating) {
+ return;
+ }
+ if (_dragging) {
+ _dragging = FALSE;
+ _color.setHeld(false);
+ }
+}
+
+void ColorScales::_sliderAnyChanged()
+{
+ if (_updating) {
+ return;
+ }
+ _recalcColor();
+}
+
+void ColorScales::_adjustmentChanged(ColorScales *scales, guint channel)
+{
+ if (scales->_updating) {
+ return;
+ }
+
+ scales->_updateSliders((1 << channel));
+ scales->_recalcColor();
+}
+
+void ColorScales::_updateSliders(guint channels)
+{
+ gfloat rgb0[3], rgbm[3], rgb1[3];
+#ifdef SPCS_PREVIEW
+ guint32 rgba;
+#endif
+ switch (_mode) {
+ case SP_COLOR_SCALES_MODE_RGB:
+ if ((channels != CSC_CHANNEL_R) && (channels != CSC_CHANNEL_A)) {
+ /* Update red */
+ _s[0]->setColors(SP_RGBA32_F_COMPOSE(0.0, getScaled(_a[1]), getScaled(_a[2]), 1.0),
+ SP_RGBA32_F_COMPOSE(0.5, getScaled(_a[1]), getScaled(_a[2]), 1.0),
+ SP_RGBA32_F_COMPOSE(1.0, getScaled(_a[1]), getScaled(_a[2]), 1.0));
+ }
+ if ((channels != CSC_CHANNEL_G) && (channels != CSC_CHANNEL_A)) {
+ /* Update green */
+ _s[1]->setColors(SP_RGBA32_F_COMPOSE(getScaled(_a[0]), 0.0, getScaled(_a[2]), 1.0),
+ SP_RGBA32_F_COMPOSE(getScaled(_a[0]), 0.5, getScaled(_a[2]), 1.0),
+ SP_RGBA32_F_COMPOSE(getScaled(_a[0]), 1.0, getScaled(_a[2]), 1.0));
+ }
+ if ((channels != CSC_CHANNEL_B) && (channels != CSC_CHANNEL_A)) {
+ /* Update blue */
+ _s[2]->setColors(SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), 0.0, 1.0),
+ SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), 0.5, 1.0),
+ SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), 1.0, 1.0));
+ }
+ if (channels != CSC_CHANNEL_A) {
+ /* Update alpha */
+ _s[3]->setColors(SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0),
+ SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5),
+ SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0));
+ }
+ break;
+ case SP_COLOR_SCALES_MODE_HSV:
+ /* Hue is never updated */
+ if ((channels != CSC_CHANNEL_S) && (channels != CSC_CHANNEL_A)) {
+ /* Update saturation */
+ sp_color_hsl_to_rgb_floatv(rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]));
+ sp_color_hsl_to_rgb_floatv(rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]));
+ sp_color_hsl_to_rgb_floatv(rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]));
+ _s[1]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if ((channels != CSC_CHANNEL_V) && (channels != CSC_CHANNEL_A)) {
+ /* Update value */
+ sp_color_hsl_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0);
+ sp_color_hsl_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5);
+ sp_color_hsl_to_rgb_floatv(rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0);
+ _s[2]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if (channels != CSC_CHANNEL_A) {
+ /* Update alpha */
+ sp_color_hsl_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
+ _s[3]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.0),
+ SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.5),
+ SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0));
+ }
+ break;
+ case SP_COLOR_SCALES_MODE_CMYK:
+ if ((channels != CSC_CHANNEL_C) && (channels != CSC_CHANNEL_CMYKA)) {
+ /* Update C */
+ sp_color_cmyk_to_rgb_floatv(rgb0, 0.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
+ sp_color_cmyk_to_rgb_floatv(rgbm, 0.5, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
+ sp_color_cmyk_to_rgb_floatv(rgb1, 1.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
+ _s[0]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if ((channels != CSC_CHANNEL_M) && (channels != CSC_CHANNEL_CMYKA)) {
+ /* Update M */
+ sp_color_cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]), getScaled(_a[3]));
+ sp_color_cmyk_to_rgb_floatv(rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]), getScaled(_a[3]));
+ sp_color_cmyk_to_rgb_floatv(rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]), getScaled(_a[3]));
+ _s[1]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if ((channels != CSC_CHANNEL_Y) && (channels != CSC_CHANNEL_CMYKA)) {
+ /* Update Y */
+ sp_color_cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0, getScaled(_a[3]));
+ sp_color_cmyk_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5, getScaled(_a[3]));
+ sp_color_cmyk_to_rgb_floatv(rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0, getScaled(_a[3]));
+ _s[2]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if ((channels != CSC_CHANNEL_K) && (channels != CSC_CHANNEL_CMYKA)) {
+ /* Update K */
+ sp_color_cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0);
+ sp_color_cmyk_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5);
+ sp_color_cmyk_to_rgb_floatv(rgb1, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0);
+ _s[3]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0),
+ SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0));
+ }
+ if (channels != CSC_CHANNEL_CMYKA) {
+ /* Update alpha */
+ sp_color_cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]),
+ getScaled(_a[3]));
+ _s[4]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.0),
+ SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.5),
+ SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0));
+ }
+ break;
+ default:
+ g_warning("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
+ break;
+ }
+
+#ifdef SPCS_PREVIEW
+ rgba = sp_color_scales_get_rgba32(cs);
+ sp_color_preview_set_rgba32(SP_COLOR_PREVIEW(_p), rgba);
+#endif
+}
+
+static const gchar *sp_color_scales_hue_map(void)
+{
+ static gchar *map = NULL;
+
+ if (!map) {
+ gchar *p;
+ gint h;
+ map = g_new(gchar, 4 * 1024);
+ p = map;
+ for (h = 0; h < 1024; h++) {
+ gfloat rgb[3];
+ sp_color_hsl_to_rgb_floatv(rgb, h / 1024.0, 1.0, 0.5);
+ *p++ = SP_COLOR_F_TO_U(rgb[0]);
+ *p++ = SP_COLOR_F_TO_U(rgb[1]);
+ *p++ = SP_COLOR_F_TO_U(rgb[2]);
+ *p++ = 255;
+ }
+ }
+
+ return map;
+}
+
+ColorScalesFactory::ColorScalesFactory(SPColorScalesMode submode)
+ : _submode(submode)
+{
+}
+
+ColorScalesFactory::~ColorScalesFactory() {}
+
+Gtk::Widget *ColorScalesFactory::createWidget(Inkscape::UI::SelectedColor &color) const
+{
+ Gtk::Widget *w = Gtk::manage(new ColorScales(color, _submode));
+ return w;
+}
+
+Glib::ustring ColorScalesFactory::modeName() const {
+ return gettext(ColorScales::SUBMODE_NAMES[_submode]);
+}
+
+}
+}
+}
diff --git a/src/ui/widget/color-scales.h b/src/ui/widget/color-scales.h
new file mode 100644
index 000000000..aeacfbcc1
--- /dev/null
+++ b/src/ui/widget/color-scales.h
@@ -0,0 +1,112 @@
+#ifndef SEEN_SP_COLOR_SCALES_H
+#define SEEN_SP_COLOR_SCALES_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if WITH_GTKMM_3_0
+#include <gtkmm/grid.h>
+#else
+#include <gtkmm/table.h>
+#endif
+
+#include "ui/selected-color.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+class ColorSlider;
+
+typedef enum {
+ SP_COLOR_SCALES_MODE_NONE = 0,
+ SP_COLOR_SCALES_MODE_RGB = 1,
+ SP_COLOR_SCALES_MODE_HSV = 2,
+ SP_COLOR_SCALES_MODE_CMYK = 3
+} SPColorScalesMode;
+
+class ColorScales
+#if GTK_CHECK_VERSION(3, 0, 0)
+ : public Gtk::Grid
+#else
+ : public Gtk::Table
+#endif
+{
+public:
+ static const gchar *SUBMODE_NAMES[];
+
+ static gfloat getScaled(const GtkAdjustment *a);
+ static void setScaled(GtkAdjustment *a, gfloat v);
+
+ ColorScales(SelectedColor &color, SPColorScalesMode mode);
+ virtual ~ColorScales();
+
+ virtual void _initUI(SPColorScalesMode mode);
+
+ void setMode(SPColorScalesMode mode);
+ SPColorScalesMode getMode() const;
+
+protected:
+ void _onColorChanged();
+ void on_show();
+
+ static void _adjustmentAnyChanged(GtkAdjustment *adjustment, ColorScales *cs);
+ void _sliderAnyGrabbed();
+ void _sliderAnyReleased();
+ void _sliderAnyChanged();
+ static void _adjustmentChanged(ColorScales *cs, guint channel);
+
+ void _getRgbaFloatv(gfloat *rgba);
+ void _getCmykaFloatv(gfloat *cmyka);
+ guint32 _getRgba32();
+ void _updateSliders(guint channels);
+ void _recalcColor();
+ void _updateDisplay();
+
+ void _setRangeLimit(gdouble upper);
+
+ SelectedColor &_color;
+ SPColorScalesMode _mode;
+ gdouble _rangeLimit;
+ gboolean _updating : 1;
+ gboolean _dragging : 1;
+ GtkAdjustment *_a[5]; /* Channel adjustments */
+ Inkscape::UI::Widget::ColorSlider *_s[5]; /* Channel sliders */
+ GtkWidget *_b[5]; /* Spinbuttons */
+ GtkWidget *_l[5]; /* Labels */
+
+private:
+ // By default, disallow copy constructor and assignment operator
+ ColorScales(ColorScales const &obj);
+ ColorScales &operator=(ColorScales const &obj);
+};
+
+class ColorScalesFactory : public Inkscape::UI::ColorSelectorFactory
+{
+public:
+ ColorScalesFactory(SPColorScalesMode submode);
+ ~ColorScalesFactory();
+
+ Gtk::Widget *createWidget(Inkscape::UI::SelectedColor &color) const;
+ Glib::ustring modeName() const;
+
+private:
+ SPColorScalesMode _submode;
+};
+
+}
+}
+}
+
+#endif /* !SEEN_SP_COLOR_SCALES_H */
+/*
+ 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 :
diff --git a/src/ui/widget/color-slider.cpp b/src/ui/widget/color-slider.cpp
new file mode 100644
index 000000000..0c9586a67
--- /dev/null
+++ b/src/ui/widget/color-slider.cpp
@@ -0,0 +1,633 @@
+/**
+ * @file
+ * A slider with colored background - implementation.
+ */
+/* Author:
+ * Lauris Kaplinski <lauris@kaplinski.com>
+ * bulia byak <buliabyak@users.sf.net>
+ *
+ * Copyright (C) 2001-2002 Lauris Kaplinski
+ *
+ * This code is in public domain
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gdkmm/cursor.h>
+#include <gdkmm/screen.h>
+#include <gdkmm/general.h>
+#include <gtkmm/adjustment.h>
+#if WITH_GTKMM_3_0
+#include <gtkmm/stylecontext.h>
+#else
+#include <gtkmm/style.h>
+#endif
+#include <gtk/gtk.h>
+
+#include "ui/widget/color-scales.h"
+#include "ui/widget/color-slider.h"
+#include "preferences.h"
+
+static const gint SLIDER_WIDTH = 96;
+static const gint SLIDER_HEIGHT = 8;
+static const gint ARROW_SIZE = 7;
+
+static const guchar *sp_color_slider_render_gradient(gint x0, gint y0, gint width, gint height, gint c[], gint dc[],
+ guint b0, guint b1, guint mask);
+static const guchar *sp_color_slider_render_map(gint x0, gint y0, gint width, gint height, guchar *map, gint start,
+ gint step, guint b0, guint b1, guint mask);
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ColorSlider::ColorSlider(Glib::RefPtr<Gtk::Adjustment> adjustment)
+ : _dragging(false)
+#else
+ColorSlider::ColorSlider(Gtk::Adjustment *adjustment)
+ : _dragging(false)
+ , _adjustment(NULL)
+#endif
+ , _value(0.0)
+ , _oldvalue(0.0)
+ , _mapsize(0)
+ , _map(NULL)
+{
+ _c0[0] = 0x00;
+ _c0[1] = 0x00;
+ _c0[2] = 0x00;
+ _c0[3] = 0xff;
+
+ _cm[0] = 0xff;
+ _cm[1] = 0x00;
+ _cm[2] = 0x00;
+ _cm[3] = 0xff;
+
+ _c0[0] = 0xff;
+ _c0[1] = 0xff;
+ _c0[2] = 0xff;
+ _c0[3] = 0xff;
+
+ _b0 = 0x5f;
+ _b1 = 0xa0;
+ _bmask = 0x08;
+
+ setAdjustment(adjustment);
+}
+
+ColorSlider::~ColorSlider()
+{
+ if (_adjustment) {
+ _adjustment_changed_connection.disconnect();
+ _adjustment_value_changed_connection.disconnect();
+#if GTK_CHECK_VERSION(3, 0, 0)
+ _adjustment.reset();
+#else
+ _adjustment->unreference();
+ _adjustment = NULL;
+#endif
+ }
+}
+
+void ColorSlider::on_realize()
+{
+ set_realized();
+
+ if (!_gdk_window) {
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+ Gtk::Allocation allocation = get_allocation();
+
+ memset(&attributes, 0, sizeof(attributes));
+ attributes.x = allocation.get_x();
+ attributes.y = allocation.get_y();
+ attributes.width = allocation.get_width();
+ attributes.height = allocation.get_height();
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.visual = gdk_screen_get_system_visual(gdk_screen_get_default());
+#if !GTK_CHECK_VERSION(3, 0, 0)
+ attributes.colormap = gdk_screen_get_system_colormap(gdk_screen_get_default());
+#endif
+ attributes.event_mask = get_events();
+ attributes.event_mask |= (Gdk::EXPOSURE_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK |
+ Gdk::POINTER_MOTION_MASK | Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
+#else
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+#endif
+
+ _gdk_window = Gdk::Window::create(get_parent_window(), &attributes, attributes_mask);
+ set_window(_gdk_window);
+ _gdk_window->set_user_data(gobj());
+
+#if !GTK_CHECK_VERSION(3, 0, 0)
+ style_attach();
+#endif
+ }
+}
+
+void ColorSlider::on_unrealize()
+{
+ _gdk_window.reset();
+
+ Gtk::Widget::on_unrealize();
+}
+
+void ColorSlider::on_size_allocate(Gtk::Allocation &allocation)
+{
+ set_allocation(allocation);
+
+ if (get_realized()) {
+ _gdk_window->move_resize(allocation.get_x(), allocation.get_y(), allocation.get_width(),
+ allocation.get_height());
+ }
+}
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+
+void ColorSlider::get_preferred_width_vfunc(int &minimum_width, int &natural_width) const
+{
+ Glib::RefPtr<Gtk::StyleContext> style_context = get_style_context();
+ Gtk::Border padding = style_context->get_padding(get_state_flags());
+ int width = SLIDER_WIDTH + padding.get_left() + padding.get_right();
+ minimum_width = natural_width = width;
+}
+
+void ColorSlider::get_preferred_width_for_height_vfunc(int /*height*/, int &minimum_width, int &natural_width) const
+{
+ get_preferred_width(minimum_width, natural_width);
+}
+
+void ColorSlider::get_preferred_height_vfunc(int &minimum_height, int &natural_height) const
+{
+ Glib::RefPtr<Gtk::StyleContext> style_context = get_style_context();
+ Gtk::Border padding = style_context->get_padding(get_state_flags());
+ int height = SLIDER_HEIGHT + padding.get_top() + padding.get_bottom();
+ minimum_height = natural_height = height;
+}
+
+void ColorSlider::get_preferred_height_for_width_vfunc(int /*width*/, int &minimum_height, int &natural_height) const
+{
+ get_preferred_height(minimum_height, natural_height);
+}
+
+#else
+
+void ColorSlider::on_size_request(Gtk::Requisition *requisition)
+{
+ GtkStyle *style = gtk_widget_get_style(gobj());
+ requisition->width = SLIDER_WIDTH + style->xthickness * 2;
+ requisition->height = SLIDER_HEIGHT + style->ythickness * 2;
+}
+
+bool ColorSlider::on_expose_event(GdkEventExpose *event)
+{
+ bool result = false;
+
+ if (get_is_drawable()) {
+ Cairo::RefPtr<Cairo::Context> cr = _gdk_window->create_cairo_context();
+ result = on_draw(cr);
+ }
+ return result;
+}
+
+#endif
+
+bool ColorSlider::on_button_press_event(GdkEventButton *event)
+{
+ if (event->button == 1) {
+ Gtk::Allocation allocation = get_allocation();
+ gint cx, cw;
+#if GTK_CHECK_VERSION(3, 0, 0)
+ cx = get_style_context()->get_padding(get_state_flags()).get_left();
+#else
+ cx = get_style()->get_xthickness();
+#endif
+ cw = allocation.get_width() - 2 * cx;
+ signal_grabbed.emit();
+ _dragging = true;
+ _oldvalue = _value;
+ ColorScales::setScaled(_adjustment->gobj(), CLAMP((gfloat)(event->x - cx) / cw, 0.0, 1.0));
+ signal_dragged.emit();
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ gdk_device_grab(
+ gdk_event_get_device(reinterpret_cast<GdkEvent *>(event)), _gdk_window->gobj(), GDK_OWNERSHIP_NONE, FALSE,
+ static_cast<GdkEventMask>(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), NULL, event->time);
+#else
+ gdk_pointer_grab(get_window()->gobj(), FALSE,
+ static_cast<GdkEventMask>(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), NULL, NULL,
+ event->time);
+#endif
+ }
+
+ return false;
+}
+
+bool ColorSlider::on_button_release_event(GdkEventButton *event)
+{
+ if (event->button == 1) {
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ gdk_device_ungrab(gdk_event_get_device(reinterpret_cast<GdkEvent *>(event)),
+ gdk_event_get_time(reinterpret_cast<GdkEvent *>(event)));
+#else
+ get_window()->pointer_ungrab(event->time);
+#endif
+
+ _dragging = false;
+ signal_released.emit();
+ if (_value != _oldvalue) {
+ signal_value_changed.emit();
+ }
+ }
+
+ return false;
+}
+
+bool ColorSlider::on_motion_notify_event(GdkEventMotion *event)
+{
+ if (_dragging) {
+ gint cx, cw;
+ Gtk::Allocation allocation = get_allocation();
+#if GTK_CHECK_VERSION(3, 0, 0)
+ cx = get_style_context()->get_padding(get_state_flags()).get_left();
+#else
+ cx = get_style()->get_xthickness();
+#endif
+ cw = allocation.get_width() - 2 * cx;
+ ColorScales::setScaled(_adjustment->gobj(), CLAMP((gfloat)(event->x - cx) / cw, 0.0, 1.0));
+ signal_dragged.emit();
+ }
+
+ return false;
+}
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+void ColorSlider::setAdjustment(Glib::RefPtr<Gtk::Adjustment> adjustment)
+{
+#else
+void ColorSlider::setAdjustment(Gtk::Adjustment *adjustment)
+{
+#endif
+ if (!adjustment) {
+#if GTK_CHECK_VERSION(3, 0, 0)
+ _adjustment = Gtk::Adjustment::create(0.0, 0.0, 1.0, 0.01, 0.0, 0.0);
+#else
+ _adjustment = Gtk::manage(new Gtk::Adjustment(0.0, 0.0, 1.0, 0.01, 0.0, 0.0));
+#endif
+ }
+ else {
+ adjustment->set_page_increment(0.0);
+ adjustment->set_page_size(0.0);
+ }
+
+ if (_adjustment != adjustment) {
+ if (_adjustment) {
+ _adjustment_changed_connection.disconnect();
+ _adjustment_value_changed_connection.disconnect();
+#if !GTK_CHECK_VERSION(3, 0, 0)
+ _adjustment->unreference();
+#endif
+ }
+
+ _adjustment = adjustment;
+ _adjustment_changed_connection =
+ _adjustment->signal_changed().connect(sigc::mem_fun(this, &ColorSlider::_onAdjustmentChanged));
+ _adjustment_value_changed_connection =
+ _adjustment->signal_value_changed().connect(sigc::mem_fun(this, &ColorSlider::_onAdjustmentValueChanged));
+
+ _value = ColorScales::getScaled(_adjustment->gobj());
+
+ _onAdjustmentChanged();
+ }
+}
+
+void ColorSlider::_onAdjustmentChanged() { queue_draw(); }
+
+void ColorSlider::_onAdjustmentValueChanged()
+{
+ if (_value != ColorScales::getScaled(_adjustment->gobj())) {
+ gint cx, cy, cw, ch;
+#if GTK_CHECK_VERSION(3, 0, 0)
+ Glib::RefPtr<Gtk::StyleContext> style_context = get_style_context();
+ Gtk::Allocation allocation = get_allocation();
+ Gtk::Border padding = style_context->get_padding(get_state_flags());
+ cx = padding.get_left();
+ cy = padding.get_top();
+#else
+ Glib::RefPtr<Gtk::Style> style = get_style();
+ Gtk::Allocation allocation = get_allocation();
+ cx = style->get_xthickness();
+ cy = style->get_ythickness();
+#endif
+ cw = allocation.get_width() - 2 * cx;
+ ch = allocation.get_height() - 2 * cy;
+ if ((gint)(ColorScales::getScaled(_adjustment->gobj()) * cw) != (gint)(_value * cw)) {
+ gint ax, ay;
+ gfloat value;
+ value = _value;
+ _value = ColorScales::getScaled(_adjustment->gobj());
+ ax = (int)(cx + value * cw - ARROW_SIZE / 2 - 2);
+ ay = cy;
+ queue_draw_area(ax, ay, ARROW_SIZE + 4, ch);
+ ax = (int)(cx + _value * cw - ARROW_SIZE / 2 - 2);
+ ay = cy;
+ queue_draw_area(ax, ay, ARROW_SIZE + 4, ch);
+ }
+ else {
+ _value = ColorScales::getScaled(_adjustment->gobj());
+ }
+ }
+}
+
+void ColorSlider::setColors(guint32 start, guint32 mid, guint32 end)
+{
+ // Remove any map, if set
+ _map = 0;
+
+ _c0[0] = start >> 24;
+ _c0[1] = (start >> 16) & 0xff;
+ _c0[2] = (start >> 8) & 0xff;
+ _c0[3] = start & 0xff;
+
+ _cm[0] = mid >> 24;
+ _cm[1] = (mid >> 16) & 0xff;
+ _cm[2] = (mid >> 8) & 0xff;
+ _cm[3] = mid & 0xff;
+
+ _c1[0] = end >> 24;
+ _c1[1] = (end >> 16) & 0xff;
+ _c1[2] = (end >> 8) & 0xff;
+ _c1[3] = end & 0xff;
+
+ queue_draw();
+}
+
+void ColorSlider::setMap(const guchar *map)
+{
+ _map = const_cast<guchar *>(map);
+
+ queue_draw();
+}
+
+void ColorSlider::setBackground(guint dark, guint light, guint size)
+{
+ _b0 = dark;
+ _b1 = light;
+ _bmask = size;
+
+ queue_draw();
+}
+
+bool ColorSlider::on_draw(const Cairo::RefPtr<Cairo::Context> &cr)
+{
+ gboolean colorsOnTop = Inkscape::Preferences::get()->getBool("/options/workarounds/colorsontop", false);
+
+ Gtk::Allocation allocation = get_allocation();
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ Glib::RefPtr<Gtk::StyleContext> style_context = get_style_context();
+#else
+ Glib::RefPtr<Gdk::Window> window = get_window();
+ Glib::RefPtr<Gtk::Style> style = get_style();
+#endif
+
+ // Draw shadow
+ if (colorsOnTop) {
+#if GTK_CHECK_VERSION(3, 0, 0)
+ style_context->render_frame(cr, 0, 0, allocation.get_width(), allocation.get_height());
+#else
+ gtk_paint_shadow(style->gobj(), window->gobj(), gtk_widget_get_state(gobj()), GTK_SHADOW_IN, NULL, gobj(),
+ "colorslider", 0, 0, allocation.get_width(), allocation.get_height());
+#endif
+ }
+
+ /* Paintable part of color gradient area */
+ Gdk::Rectangle carea;
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ Gtk::Border padding;
+
+ padding = style_context->get_padding(get_state_flags());
+
+ carea.set_x(padding.get_left());
+ carea.set_y(padding.get_top());
+ ;
+#else
+ carea.set_x(style->get_xthickness());
+ carea.set_y(style->get_ythickness());
+#endif
+
+ carea.set_width(allocation.get_width() - 2 * carea.get_x());
+ carea.set_height(allocation.get_height() - 2 * carea.get_y());
+
+ if (_map) {
+ /* Render map pixelstore */
+ gint d = (1024 << 16) / carea.get_width();
+ gint s = 0;
+
+ const guchar *b =
+ sp_color_slider_render_map(0, 0, carea.get_width(), carea.get_height(), _map, s, d, _b0, _b1, _bmask);
+
+ if (b != NULL && carea.get_width() > 0) {
+ Glib::RefPtr<Gdk::Pixbuf> pb = Gdk::Pixbuf::create_from_data(
+ b, Gdk::COLORSPACE_RGB, false, 8, carea.get_width(), carea.get_height(), carea.get_width() * 3);
+
+ Gdk::Cairo::set_source_pixbuf(cr, pb, carea.get_x(), carea.get_y());
+ cr->paint();
+ }
+ }
+ else {
+ gint c[4], dc[4];
+
+ /* Render gradient */
+
+ // part 1: from c0 to cm
+ if (carea.get_width() > 0) {
+ for (gint i = 0; i < 4; i++) {
+ c[i] = _c0[i] << 16;
+ dc[i] = ((_cm[i] << 16) - c[i]) / (carea.get_width() / 2);
+ }
+ guint wi = carea.get_width() / 2;
+ const guchar *b = sp_color_slider_render_gradient(0, 0, wi, carea.get_height(), c, dc, _b0, _b1, _bmask);
+
+ /* Draw pixelstore 1 */
+ if (b != NULL && wi > 0) {
+ Glib::RefPtr<Gdk::Pixbuf> pb =
+ Gdk::Pixbuf::create_from_data(b, Gdk::COLORSPACE_RGB, false, 8, wi, carea.get_height(), wi * 3);
+
+ Gdk::Cairo::set_source_pixbuf(cr, pb, carea.get_x(), carea.get_y());
+ cr->paint();
+ }
+ }
+
+ // part 2: from cm to c1
+ if (carea.get_width() > 0) {
+ for (gint i = 0; i < 4; i++) {
+ c[i] = _cm[i] << 16;
+ dc[i] = ((_c1[i] << 16) - c[i]) / (carea.get_width() / 2);
+ }
+ guint wi = carea.get_width() / 2;
+ const guchar *b = sp_color_slider_render_gradient(carea.get_width() / 2, 0, wi, carea.get_height(), c, dc,
+ _b0, _b1, _bmask);
+
+ /* Draw pixelstore 2 */
+ if (b != NULL && wi > 0) {
+ Glib::RefPtr<Gdk::Pixbuf> pb =
+ Gdk::Pixbuf::create_from_data(b, Gdk::COLORSPACE_RGB, false, 8, wi, carea.get_height(), wi * 3);
+
+ Gdk::Cairo::set_source_pixbuf(cr, pb, carea.get_width() / 2 + carea.get_x(), carea.get_y());
+ cr->paint();
+ }
+ }
+ }
+
+ /* Draw shadow */
+ if (!colorsOnTop) {
+#if GTK_CHECK_VERSION(3, 0, 0)
+ style_context->render_frame(cr, 0, 0, allocation.get_width(), allocation.get_height());
+#else
+ gtk_paint_shadow(style->gobj(), window->gobj(), gtk_widget_get_state(gobj()), GTK_SHADOW_IN, NULL, gobj(),
+ "colorslider", 0, 0, allocation.get_width(), allocation.get_height());
+#endif
+ }
+
+ /* Draw arrow */
+ gint x = (int)(_value * (carea.get_width() - 1) - ARROW_SIZE / 2 + carea.get_x());
+ gint y1 = carea.get_y();
+ gint y2 = carea.get_y() + carea.get_height() - 1;
+ cr->set_line_width(1.0);
+
+ // Define top arrow
+ cr->move_to(x - 0.5, y1 + 0.5);
+ cr->line_to(x + ARROW_SIZE - 0.5, y1 + 0.5);
+ cr->line_to(x + (ARROW_SIZE - 1) / 2.0, y1 + ARROW_SIZE / 2.0 + 0.5);
+ cr->line_to(x - 0.5, y1 + 0.5);
+
+ // Define bottom arrow
+ cr->move_to(x - 0.5, y2 + 0.5);
+ cr->line_to(x + ARROW_SIZE - 0.5, y2 + 0.5);
+ cr->line_to(x + (ARROW_SIZE - 1) / 2.0, y2 - ARROW_SIZE / 2.0 + 0.5);
+ cr->line_to(x - 0.5, y2 + 0.5);
+
+ // Render both arrows
+ cr->set_source_rgb(1.0, 1.0, 1.0);
+ cr->stroke_preserve();
+ cr->set_source_rgb(0.0, 0.0, 0.0);
+ cr->fill();
+
+ return false;
+}
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+/* Colors are << 16 */
+
+static const guchar *sp_color_slider_render_gradient(gint x0, gint y0, gint width, gint height, gint c[], gint dc[],
+ guint b0, guint b1, guint mask)
+{
+ static guchar *buf = NULL;
+ static gint bs = 0;
+ guchar *dp;
+ gint x, y;
+ guint r, g, b, a;
+
+ if (buf && (bs < width * height)) {
+ g_free(buf);
+ buf = NULL;
+ }
+ if (!buf) {
+ buf = g_new(guchar, width * height * 3);
+ bs = width * height;
+ }
+
+ dp = buf;
+ r = c[0];
+ g = c[1];
+ b = c[2];
+ a = c[3];
+ for (x = x0; x < x0 + width; x++) {
+ gint cr, cg, cb, ca;
+ guchar *d;
+ cr = r >> 16;
+ cg = g >> 16;
+ cb = b >> 16;
+ ca = a >> 16;
+ d = dp;
+ for (y = y0; y < y0 + height; y++) {
+ guint bg, fc;
+ /* Background value */
+ bg = ((x & mask) ^ (y & mask)) ? b0 : b1;
+ fc = (cr - bg) * ca;
+ d[0] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
+ fc = (cg - bg) * ca;
+ d[1] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
+ fc = (cb - bg) * ca;
+ d[2] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
+ d += 3 * width;
+ }
+ r += dc[0];
+ g += dc[1];
+ b += dc[2];
+ a += dc[3];
+ dp += 3;
+ }
+
+ return buf;
+}
+
+/* Positions are << 16 */
+
+static const guchar *sp_color_slider_render_map(gint x0, gint y0, gint width, gint height, guchar *map, gint start,
+ gint step, guint b0, guint b1, guint mask)
+{
+ static guchar *buf = NULL;
+ static gint bs = 0;
+ guchar *dp;
+ gint x, y;
+
+ if (buf && (bs < width * height)) {
+ g_free(buf);
+ buf = NULL;
+ }
+ if (!buf) {
+ buf = g_new(guchar, width * height * 3);
+ bs = width * height;
+ }
+
+ dp = buf;
+ for (x = x0; x < x0 + width; x++) {
+ gint cr, cg, cb, ca;
+ guchar *d = dp;
+ guchar *sp = map + 4 * (start >> 16);
+ cr = *sp++;
+ cg = *sp++;
+ cb = *sp++;
+ ca = *sp++;
+ for (y = y0; y < y0 + height; y++) {
+ guint bg, fc;
+ /* Background value */
+ bg = ((x & mask) ^ (y & mask)) ? b0 : b1;
+ fc = (cr - bg) * ca;
+ d[0] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
+ fc = (cg - bg) * ca;
+ d[1] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
+ fc = (cb - bg) * ca;
+ d[2] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
+ d += 3 * width;
+ }
+ dp += 3;
+ start += step;
+ }
+
+ return buf;
+}
diff --git a/src/ui/widget/color-slider.h b/src/ui/widget/color-slider.h
new file mode 100644
index 000000000..253f3123c
--- /dev/null
+++ b/src/ui/widget/color-slider.h
@@ -0,0 +1,110 @@
+/*
+ * A slider with colored background
+ *
+ * Author:
+ * Lauris Kaplinski <lauris@kaplinski.com>
+ *
+ * Copyright (C) 2001-2002 Lauris Kaplinski
+ *
+ * This code is in public domain
+ */
+
+#ifndef SEEN_COLOR_SLIDER_H
+#define SEEN_COLOR_SLIDER_H
+
+#include <gtkmm/widget.h>
+#include <sigc++/signal.h>
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+/*
+ * A slider with colored background
+ */
+class ColorSlider : public Gtk::Widget {
+public:
+#if GTK_CHECK_VERSION(3, 0, 0)
+ ColorSlider(Glib::RefPtr<Gtk::Adjustment> adjustment);
+#else
+ ColorSlider(Gtk::Adjustment *adjustment);
+#endif
+ ~ColorSlider();
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ void setAdjustment(Glib::RefPtr<Gtk::Adjustment> adjustment);
+#else
+ void setAdjustment(Gtk::Adjustment *adjustment);
+#endif
+
+ void setColors(guint32 start, guint32 mid, guint32 end);
+
+ void setMap(const guchar *map);
+
+ void setBackground(guint dark, guint light, guint size);
+
+ sigc::signal<void> signal_grabbed;
+ sigc::signal<void> signal_dragged;
+ sigc::signal<void> signal_released;
+ sigc::signal<void> signal_value_changed;
+
+protected:
+ void on_size_allocate(Gtk::Allocation &allocation);
+ void on_realize();
+ void on_unrealize();
+ bool on_button_press_event(GdkEventButton *event);
+ bool on_button_release_event(GdkEventButton *event);
+ bool on_motion_notify_event(GdkEventMotion *event);
+ bool on_draw(const Cairo::RefPtr<Cairo::Context> &cr);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ void get_preferred_width_vfunc(int &minimum_width, int &natural_width) const;
+ void get_preferred_width_for_height_vfunc(int height, int &minimum_width, int &natural_width) const;
+ void get_preferred_height_vfunc(int &minimum_height, int &natural_height) const;
+ void get_preferred_height_for_width_vfunc(int width, int &minimum_height, int &natural_height) const;
+#else
+ void on_size_request(Gtk::Requisition *requisition);
+ bool on_expose_event(GdkEventExpose *event);
+#endif
+
+private:
+ void _onAdjustmentChanged();
+ void _onAdjustmentValueChanged();
+
+ bool _dragging;
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ Glib::RefPtr<Gtk::Adjustment> _adjustment;
+#else
+ Gtk::Adjustment *_adjustment;
+#endif
+ sigc::connection _adjustment_changed_connection;
+ sigc::connection _adjustment_value_changed_connection;
+
+ gfloat _value;
+ gfloat _oldvalue;
+ guchar _c0[4], _cm[4], _c1[4];
+ guchar _b0, _b1;
+ guchar _bmask;
+
+ gint _mapsize;
+ guchar *_map;
+
+ Glib::RefPtr<Gdk::Window> _gdk_window;
+};
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+#endif
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/color-wheel-selector.cpp b/src/ui/widget/color-wheel-selector.cpp
new file mode 100644
index 000000000..ed3400bb5
--- /dev/null
+++ b/src/ui/widget/color-wheel-selector.cpp
@@ -0,0 +1,302 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "color-wheel-selector.h"
+
+#include <math.h>
+#include <gtk/gtk.h>
+#include <glibmm/i18n.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/label.h>
+#include <gtkmm/spinbutton.h>
+#include "svg/svg-icc-color.h"
+#include "ui/dialog-events.h"
+#include "ui/selected-color.h"
+#include "ui/widget/color-scales.h"
+#include "ui/widget/color-slider.h"
+#include "ui/widget/gimpcolorwheel.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+
+#define XPAD 4
+#define YPAD 1
+
+
+const gchar *ColorWheelSelector::MODE_NAME = N_("Wheel");
+
+ColorWheelSelector::ColorWheelSelector(SelectedColor &color)
+#if GTK_CHECK_VERSION(3, 0, 0)
+ : Gtk::Grid()
+#else
+ : Gtk::Table(5, 3, false)
+#endif
+ , _color(color)
+ , _updating(false)
+#if !GTK_CHECK_VERSION(3, 0, 0)
+ , _alpha_adjustment(NULL)
+#endif
+ , _wheel(0)
+ , _slider(0)
+{
+ _initUI();
+ _color_changed_connection = color.signal_changed.connect(sigc::mem_fun(this, &ColorWheelSelector::_colorChanged));
+ _color_dragged_connection = color.signal_dragged.connect(sigc::mem_fun(this, &ColorWheelSelector::_colorChanged));
+}
+
+ColorWheelSelector::~ColorWheelSelector()
+{
+ _wheel = 0;
+#if !GTK_CHECK_VERSION(3, 0, 0)
+ delete _alpha_adjustment;
+#endif
+
+ _color_changed_connection.disconnect();
+ _color_dragged_connection.disconnect();
+}
+
+void ColorWheelSelector::_initUI()
+{
+ /* Create components */
+ gint row = 0;
+
+ _wheel = gimp_color_wheel_new();
+ gtk_widget_show(_wheel);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ gtk_widget_set_halign(_wheel, GTK_ALIGN_FILL);
+ gtk_widget_set_valign(_wheel, GTK_ALIGN_FILL);
+ gtk_widget_set_hexpand(_wheel, TRUE);
+ gtk_widget_set_vexpand(_wheel, TRUE);
+ gtk_grid_attach(GTK_GRID(gobj()), _wheel, 0, row, 3, 1);
+#else
+ gtk_table_attach(GTK_TABLE(gobj()), _wheel, 0, 3, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0);
+#endif
+
+ row++;
+
+ /* Label */
+ Gtk::Label *label = Gtk::manage(new Gtk::Label(_("_A:"), true));
+ label->set_alignment(1.0, 0.5);
+ label->show();
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ #if GTK_CHECK_VERSION(3, 12, 0)
+ label->set_margin_start(XPAD);
+ label->set_margin_end(XPAD);
+ #else
+ label->set_margin_left(XPAD);
+ label->set_margin_right(XPAD);
+ #endif
+ label->set_margin_top(YPAD);
+ label->set_margin_bottom(YPAD);
+ label->set_halign(Gtk::ALIGN_FILL);
+ label->set_valign(Gtk::ALIGN_FILL);
+ attach(*label, 0, row, 1, 1);
+#else
+ attach(*label, 0, 1, row, row + 1, Gtk::FILL, Gtk::FILL, XPAD, YPAD);
+#endif
+
+/* Adjustment */
+#if GTK_CHECK_VERSION(3, 0, 0)
+ _alpha_adjustment = Gtk::Adjustment::create(0.0, 0.0, 255.0, 1.0, 10.0, 10.0);
+#else
+ _alpha_adjustment = new Gtk::Adjustment(0.0, 0.0, 255.0, 1.0, 10.0, 10.0);
+#endif
+ /* Slider */
+ _slider = Gtk::manage(new Inkscape::UI::Widget::ColorSlider(_alpha_adjustment));
+ _slider->set_tooltip_text(_("Alpha (opacity)"));
+ _slider->show();
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ #if GTK_CHECK_VERSION(3, 12, 0)
+ _slider->set_margin_start(XPAD);
+ _slider->set_margin_end(XPAD);
+ #else
+ _slider->set_margin_left(XPAD);
+ _slider->set_margin_right(XPAD);
+ #endif
+ _slider->set_margin_top(YPAD);
+ _slider->set_margin_bottom(YPAD);
+ _slider->set_hexpand(true);
+ _slider->set_halign(Gtk::ALIGN_FILL);
+ _slider->set_valign(Gtk::ALIGN_FILL);
+ attach(*_slider, 1, row, 1, 1);
+#else
+ attach(*_slider, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::FILL, XPAD, YPAD);
+#endif
+
+ _slider->setColors(SP_RGBA32_F_COMPOSE(1.0, 1.0, 1.0, 0.0), SP_RGBA32_F_COMPOSE(1.0, 1.0, 1.0, 0.5),
+ SP_RGBA32_F_COMPOSE(1.0, 1.0, 1.0, 1.0));
+
+/* Spinbutton */
+#if GTK_CHECK_VERSION(3, 0, 0)
+ Gtk::SpinButton *spin_button = Gtk::manage(new Gtk::SpinButton(_alpha_adjustment, 1.0, 0));
+#else
+ Gtk::SpinButton *spin_button = Gtk::manage(new Gtk::SpinButton(*_alpha_adjustment, 1.0, 0));
+#endif
+ spin_button->set_tooltip_text(_("Alpha (opacity)"));
+ sp_dialog_defocus_on_enter(GTK_WIDGET(spin_button->gobj()));
+ label->set_mnemonic_widget(*spin_button);
+ spin_button->show();
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+ #if GTK_CHECK_VERSION(3, 12, 0)
+ spin_button->set_margin_start(XPAD);
+ spin_button->set_margin_end(XPAD);
+ #else
+ spin_button->set_margin_left(XPAD);
+ spin_button->set_margin_right(XPAD);
+ #endif
+ spin_button->set_margin_top(YPAD);
+ spin_button->set_margin_bottom(YPAD);
+ spin_button->set_halign(Gtk::ALIGN_CENTER);
+ spin_button->set_valign(Gtk::ALIGN_CENTER);
+ attach(*spin_button, 2, row, 1, 1);
+#else
+ attach(*spin_button, 2, 3, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, XPAD, YPAD);
+#endif
+
+ /* Signals */
+ _alpha_adjustment->signal_value_changed().connect(sigc::mem_fun(this, &ColorWheelSelector::_adjustmentChanged));
+ _slider->signal_grabbed.connect(sigc::mem_fun(*this, &ColorWheelSelector::_sliderGrabbed));
+ _slider->signal_released.connect(sigc::mem_fun(*this, &ColorWheelSelector::_sliderReleased));
+ _slider->signal_value_changed.connect(sigc::mem_fun(*this, &ColorWheelSelector::_sliderChanged));
+
+ g_signal_connect(G_OBJECT(_wheel), "changed", G_CALLBACK(_wheelChanged), this);
+}
+
+void ColorWheelSelector::on_show()
+{
+#if GTK_CHECK_VERSION(3, 0, 0)
+ Gtk::Grid::on_show();
+#else
+ Gtk::Table::on_show();
+#endif
+ _updateDisplay();
+}
+
+void ColorWheelSelector::_colorChanged()
+{
+ _updateDisplay();
+}
+
+void ColorWheelSelector::_adjustmentChanged()
+{
+ if (_updating) {
+ return;
+ }
+
+ // TODO check this. It looks questionable:
+ // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255 or 0..100
+ gdouble value = _alpha_adjustment->get_value();
+ gdouble upper = _alpha_adjustment->get_upper();
+ if (value > 0.0 && value < 1.0) {
+ _alpha_adjustment->set_value(floor(value * upper + 0.5));
+ }
+
+ _color.preserveICC();
+ _color.setAlpha(ColorScales::getScaled(_alpha_adjustment->gobj()));
+}
+
+void ColorWheelSelector::_sliderGrabbed()
+{
+ _color.preserveICC();
+ _color.setHeld(true);
+}
+
+void ColorWheelSelector::_sliderReleased()
+{
+ _color.preserveICC();
+ _color.setHeld(false);
+}
+
+void ColorWheelSelector::_sliderChanged()
+{
+ if (_updating) {
+ return;
+ }
+
+ _color.preserveICC();
+ _color.setAlpha(ColorScales::getScaled(_alpha_adjustment->gobj()));
+}
+
+void ColorWheelSelector::_wheelChanged(GimpColorWheel *wheel, ColorWheelSelector *wheelSelector)
+{
+ if (wheelSelector->_updating) {
+ return;
+ }
+
+ gdouble h = 0;
+ gdouble s = 0;
+ gdouble v = 0;
+ gimp_color_wheel_get_color(wheel, &h, &s, &v);
+
+ float rgb[3] = { 0, 0, 0 };
+ sp_color_hsv_to_rgb_floatv(rgb, h, s, v);
+
+ SPColor color(rgb[0], rgb[1], rgb[2]);
+
+ guint32 start = color.toRGBA32(0x00);
+ guint32 mid = color.toRGBA32(0x7f);
+ guint32 end = color.toRGBA32(0xff);
+
+ wheelSelector->_slider->setColors(start, mid, end);
+
+ wheelSelector->_color.preserveICC();
+
+ wheelSelector->_color.setHeld(gimp_color_wheel_is_adjusting(wheel));
+ wheelSelector->_color.setColor(color);
+}
+
+void ColorWheelSelector::_updateDisplay()
+{
+#ifdef DUMP_CHANGE_INFO
+ g_message("ColorWheelSelector::_colorChanged( this=%p, %f, %f, %f, %f)", this, _color.color().v.c[0],
+ _color.color().v.c[1], _color.color().v.c[2], alpha);
+#endif
+
+ bool oldval = _updating;
+ _updating = true;
+ {
+ float hsv[3] = { 0, 0, 0 };
+ sp_color_rgb_to_hsv_floatv(hsv, _color.color().v.c[0], _color.color().v.c[1], _color.color().v.c[2]);
+ gimp_color_wheel_set_color(GIMP_COLOR_WHEEL(_wheel), hsv[0], hsv[1], hsv[2]);
+ }
+
+ guint32 start = _color.color().toRGBA32(0x00);
+ guint32 mid = _color.color().toRGBA32(0x7f);
+ guint32 end = _color.color().toRGBA32(0xff);
+
+ _slider->setColors(start, mid, end);
+
+ ColorScales::setScaled(_alpha_adjustment->gobj(), _color.alpha());
+
+ _updating = oldval;
+}
+
+
+Gtk::Widget *ColorWheelSelectorFactory::createWidget(Inkscape::UI::SelectedColor &color) const
+{
+ Gtk::Widget *w = Gtk::manage(new ColorWheelSelector(color));
+ return w;
+}
+
+Glib::ustring ColorWheelSelectorFactory::modeName() const { return gettext(ColorWheelSelector::MODE_NAME); }
+}
+}
+}
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/color-wheel-selector.h b/src/ui/widget/color-wheel-selector.h
new file mode 100644
index 000000000..5711d417c
--- /dev/null
+++ b/src/ui/widget/color-wheel-selector.h
@@ -0,0 +1,101 @@
+/**
+ * @file
+ * Color selector widget containing GIMP color wheel and slider
+ */
+/* Authors:
+ * Tomasz Boczkowski <penginsbacon@gmail.com> (c++-sification)
+ *
+ * Copyright (C) 2014 Authors
+ *
+ * This code is in public domain
+ */
+#ifndef SEEN_SP_COLOR_WHEEL_SELECTOR_H
+#define SEEN_SP_COLOR_WHEEL_SELECTOR_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if WITH_GTKMM_3_0
+#include <gtkmm/grid.h>
+#else
+#include <gtkmm/table.h>
+#endif
+
+#include "ui/selected-color.h"
+
+typedef struct _GimpColorWheel GimpColorWheel;
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+class ColorSlider;
+
+class ColorWheelSelector
+#if GTK_CHECK_VERSION(3, 0, 0)
+ : public Gtk::Grid
+#else
+ : public Gtk::Table
+#endif
+{
+public:
+ static const gchar *MODE_NAME;
+
+ ColorWheelSelector(SelectedColor &color);
+ virtual ~ColorWheelSelector();
+
+protected:
+ void _initUI();
+
+ void on_show();
+
+ void _colorChanged();
+ void _adjustmentChanged();
+ void _sliderGrabbed();
+ void _sliderReleased();
+ void _sliderChanged();
+ static void _wheelChanged(GimpColorWheel *wheel, ColorWheelSelector *cs);
+
+ void _updateDisplay();
+
+ SelectedColor &_color;
+ bool _updating;
+#if GTK_CHECK_VERSION(3, 0, 0)
+ Glib::RefPtr<Gtk::Adjustment> _alpha_adjustment;
+#else
+ Gtk::Adjustment *_alpha_adjustment;
+#endif
+ GtkWidget *_wheel;
+ Inkscape::UI::Widget::ColorSlider *_slider;
+
+private:
+ // By default, disallow copy constructor and assignment operator
+ ColorWheelSelector(const ColorWheelSelector &obj);
+ ColorWheelSelector &operator=(const ColorWheelSelector &obj);
+
+ sigc::connection _color_changed_connection;
+ sigc::connection _color_dragged_connection;
+};
+
+class ColorWheelSelectorFactory : public ColorSelectorFactory {
+public:
+ Gtk::Widget *createWidget(SelectedColor &color) const;
+ Glib::ustring modeName() const;
+};
+}
+}
+}
+
+#endif // SEEN_SP_COLOR_WHEEL_SELECTOR_H
+
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/font-variants.cpp b/src/ui/widget/font-variants.cpp
new file mode 100644
index 000000000..637631fda
--- /dev/null
+++ b/src/ui/widget/font-variants.cpp
@@ -0,0 +1,512 @@
+/*
+ * Author:
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2015 Tavmong Bah
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gtkmm.h>
+#include <glibmm/i18n.h>
+
+#include <iostream>
+
+#include "font-variants.h"
+
+// For updating from selection
+#include "desktop.h"
+#include "selection.h"
+#include "style.h"
+#include "sp-text.h"
+#include "sp-tspan.h"
+#include "sp-tref.h"
+#include "sp-textpath.h"
+#include "sp-item-group.h"
+#include "xml/repr.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+ FontVariants::FontVariants () :
+ Gtk::VBox (),
+ _ligatures_frame ( Glib::ustring(_("Ligatures" )) ),
+ _ligatures_common ( Glib::ustring(_("Common" )) ),
+ _ligatures_discretionary ( Glib::ustring(_("Discretionary")) ),
+ _ligatures_historical ( Glib::ustring(_("Historical" )) ),
+ _ligatures_contextual ( Glib::ustring(_("Contextual" )) ),
+
+ _position_frame ( Glib::ustring(_("Position" )) ),
+ _position_normal ( Glib::ustring(_("Normal" )) ),
+ _position_sub ( Glib::ustring(_("Subscript" )) ),
+ _position_super ( Glib::ustring(_("Superscript" )) ),
+
+ _caps_frame ( Glib::ustring(_("Capitals" )) ),
+ _caps_normal ( Glib::ustring(_("Normal" )) ),
+ _caps_small ( Glib::ustring(_("Small" )) ),
+ _caps_all_small ( Glib::ustring(_("All small" )) ),
+ _caps_petite ( Glib::ustring(_("Petite" )) ),
+ _caps_all_petite ( Glib::ustring(_("All petite" )) ),
+ _caps_unicase ( Glib::ustring(_("Unicase" )) ),
+ _caps_titling ( Glib::ustring(_("Titling" )) ),
+
+ _numeric_frame ( Glib::ustring(_("Numeric" )) ),
+ _numeric_lining ( Glib::ustring(_("Lining" )) ),
+ _numeric_old_style ( Glib::ustring(_("Old Style" )) ),
+ _numeric_default_style ( Glib::ustring(_("Default Style")) ),
+ _numeric_proportional ( Glib::ustring(_("Proportional" )) ),
+ _numeric_tabular ( Glib::ustring(_("Tabular" )) ),
+ _numeric_default_width ( Glib::ustring(_("Default Width")) ),
+ _numeric_diagonal ( Glib::ustring(_("Diagonal" )) ),
+ _numeric_stacked ( Glib::ustring(_("Stacked" )) ),
+ _numeric_default_fractions( Glib::ustring(_("Default Fractions")) ),
+ _numeric_ordinal ( Glib::ustring(_("Ordinal" )) ),
+ _numeric_slashed_zero ( Glib::ustring(_("Slashed Zero" )) ),
+
+ _ligatures_changed( false ),
+ _position_changed( false ),
+ _caps_changed( false ),
+ _numeric_changed( false )
+
+ {
+
+ // Ligatures --------------------------
+
+ // Add tooltips
+ _ligatures_common.set_tooltip_text(
+ _("Common ligatures. On by default. OpenType tables: 'liga', 'clig'"));
+ _ligatures_discretionary.set_tooltip_text(
+ _("Discretionary ligatures. Off by default. OpenType table: 'dlig'"));
+ _ligatures_historical.set_tooltip_text(
+ _("Historical ligatures. Off by default. OpenType table: 'hlig'"));
+ _ligatures_contextual.set_tooltip_text(
+ _("Contextual forms. On by default. OpenType table: 'calt'"));
+
+ // Add signals
+ _ligatures_common.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::ligatures_callback) );
+ _ligatures_discretionary.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::ligatures_callback) );
+ _ligatures_historical.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::ligatures_callback) );
+ _ligatures_contextual.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::ligatures_callback) );
+
+ // Add to frame
+ _ligatures_vbox.add( _ligatures_common );
+ _ligatures_vbox.add( _ligatures_discretionary );
+ _ligatures_vbox.add( _ligatures_historical );
+ _ligatures_vbox.add( _ligatures_contextual );
+ _ligatures_frame.add( _ligatures_vbox );
+ add( _ligatures_frame );
+
+ ligatures_init();
+
+ // Position ----------------------------------
+
+ // Add tooltips
+ _position_normal.set_tooltip_text( _("Normal position."));
+ _position_sub.set_tooltip_text( _("Subscript. OpenType table: 'subs'") );
+ _position_super.set_tooltip_text( _("Superscript. OpenType table: 'sups'") );
+
+ // Group buttons
+ Gtk::RadioButton::Group position_group = _position_normal.get_group();
+ _position_sub.set_group(position_group);
+ _position_super.set_group(position_group);
+
+ // Add signals
+ _position_normal.signal_pressed().connect ( sigc::mem_fun(*this, &FontVariants::position_callback) );
+ _position_sub.signal_pressed().connect ( sigc::mem_fun(*this, &FontVariants::position_callback) );
+ _position_super.signal_pressed().connect ( sigc::mem_fun(*this, &FontVariants::position_callback) );
+
+ // Add to frame
+ _position_vbox.add( _position_normal );
+ _position_vbox.add( _position_sub );
+ _position_vbox.add( _position_super );
+ _position_frame.add( _position_vbox );
+ add( _position_frame );
+
+ position_init();
+
+ // Caps ----------------------------------
+
+ // Add tooltips
+ _caps_normal.set_tooltip_text( _("Normal capitalization."));
+ _caps_small.set_tooltip_text( _("Small-caps (lowercase). OpenType table: 'smcp'"));
+ _caps_all_small.set_tooltip_text( _("All small-caps (uppercase and lowercase). OpenType tables: 'c2sc' and 'smcp'"));
+ _caps_petite.set_tooltip_text( _("Petite-caps (lowercase). OpenType table: 'pcap'"));
+ _caps_all_petite.set_tooltip_text( _("All petite-caps (uppercase and lowercase). OpenType tables: 'c2sc' and 'pcap'"));
+ _caps_unicase.set_tooltip_text( _("Unicase (small caps for uppercase, normal for lowercase). OpenType table: 'unic'"));
+ _caps_titling.set_tooltip_text( _("Titling caps (lighter-weight uppercase for use in titles). OpenType table: 'titl'"));
+
+ // Group buttons
+ Gtk::RadioButton::Group caps_group = _caps_normal.get_group();
+ _caps_small.set_group(caps_group);
+ _caps_all_small.set_group(caps_group);
+ _caps_petite.set_group(caps_group);
+ _caps_all_petite.set_group(caps_group);
+ _caps_unicase.set_group(caps_group);
+ _caps_titling.set_group(caps_group);
+
+ // Add signals
+ _caps_normal.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::caps_callback) );
+ _caps_small.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::caps_callback) );
+ _caps_all_small.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::caps_callback) );
+ _caps_petite.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::caps_callback) );
+ _caps_all_petite.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::caps_callback) );
+ _caps_unicase.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::caps_callback) );
+ _caps_titling.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::caps_callback) );
+
+ // Add to frame
+ _caps_vbox.add( _caps_normal );
+ _caps_vbox.add( _caps_small );
+ _caps_vbox.add( _caps_all_small );
+ _caps_vbox.add( _caps_petite );
+ _caps_vbox.add( _caps_all_petite );
+ _caps_vbox.add( _caps_unicase );
+ _caps_vbox.add( _caps_titling );
+ _caps_frame.add( _caps_vbox );
+ add( _caps_frame );
+
+ caps_init();
+
+ // Numeric ------------------------------
+
+ // Add tooltips
+ _numeric_default_style.set_tooltip_text( _("Normal style."));
+ _numeric_lining.set_tooltip_text( _("Lining numerals. OpenType table: 'lnum'"));
+ _numeric_old_style.set_tooltip_text( _("Old style numerals. OpenType table: 'onum'"));
+ _numeric_default_width.set_tooltip_text( _("Normal widths."));
+ _numeric_proportional.set_tooltip_text( _("Proportional width numerals. OpenType table: 'pnum'"));
+ _numeric_tabular.set_tooltip_text( _("Same width numerals. OpenType table: 'tnum'"));
+ _numeric_default_fractions.set_tooltip_text( _("Normal fractions."));
+ _numeric_diagonal.set_tooltip_text( _("Diagonal fractions. OpenType table: 'frac'"));
+ _numeric_stacked.set_tooltip_text( _("Stacked fractions. OpenType table: 'afrc'"));
+ _numeric_ordinal.set_tooltip_text( _("Ordinals (raised 'th', etc.). OpenType table: 'ordn'"));
+ _numeric_slashed_zero.set_tooltip_text( _("Slashed zeros. OpenType table: 'zero'"));
+
+ // Group buttons
+ Gtk::RadioButton::Group style_group = _numeric_default_style.get_group();
+ _numeric_lining.set_group(style_group);
+ _numeric_old_style.set_group(style_group);
+
+ Gtk::RadioButton::Group width_group = _numeric_default_width.get_group();
+ _numeric_proportional.set_group(width_group);
+ _numeric_tabular.set_group(width_group);
+
+ Gtk::RadioButton::Group fraction_group = _numeric_default_fractions.get_group();
+ _numeric_diagonal.set_group(fraction_group);
+ _numeric_stacked.set_group(fraction_group);
+
+ // Add signals
+ _numeric_default_style.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::numeric_callback) );
+ _numeric_lining.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::numeric_callback) );
+ _numeric_old_style.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::numeric_callback) );
+ _numeric_default_width.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::numeric_callback) );
+ _numeric_proportional.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::numeric_callback) );
+ _numeric_tabular.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::numeric_callback) );
+ _numeric_default_fractions.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::numeric_callback) );
+ _numeric_diagonal.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::numeric_callback) );
+ _numeric_stacked.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::numeric_callback) );
+ _numeric_ordinal.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::numeric_callback) );
+ _numeric_slashed_zero.signal_clicked().connect ( sigc::mem_fun(*this, &FontVariants::numeric_callback) );
+
+ // Add to frame
+ _numeric_stylebox.add( _numeric_default_style );
+ _numeric_stylebox.add( _numeric_lining );
+ _numeric_stylebox.add( _numeric_old_style );
+ _numeric_vbox.add( _numeric_stylebox );
+ _numeric_widthbox.add( _numeric_default_width );
+ _numeric_widthbox.add( _numeric_proportional );
+ _numeric_widthbox.add( _numeric_tabular );
+ _numeric_vbox.add( _numeric_widthbox );
+ _numeric_fractionbox.add( _numeric_default_fractions );
+ _numeric_fractionbox.add( _numeric_diagonal );
+ _numeric_fractionbox.add( _numeric_stacked );
+ _numeric_vbox.add( _numeric_fractionbox );
+ _numeric_vbox.add( _numeric_ordinal );
+ _numeric_vbox.add( _numeric_slashed_zero );
+ _numeric_frame.add( _numeric_vbox );
+ add( _numeric_frame );
+
+
+ show_all_children();
+
+ }
+
+ void
+ FontVariants::ligatures_init() {
+ // std::cout << "FontVariants::ligatures_init()" << std::endl;
+ }
+
+ void
+ FontVariants::ligatures_callback() {
+ // std::cout << "FontVariants::ligatures_callback()" << std::endl;
+ _ligatures_changed = true;
+ _changed_signal.emit();
+ }
+
+ void
+ FontVariants::position_init() {
+ // std::cout << "FontVariants::position_init()" << std::endl;
+ }
+
+ void
+ FontVariants::position_callback() {
+ // std::cout << "FontVariants::position_callback()" << std::endl;
+ _position_changed = true;
+ _changed_signal.emit();
+ }
+
+ void
+ FontVariants::caps_init() {
+ // std::cout << "FontVariants::caps_init()" << std::endl;
+ }
+
+ void
+ FontVariants::caps_callback() {
+ // std::cout << "FontVariants::caps_callback()" << std::endl;
+ _caps_changed = true;
+ _changed_signal.emit();
+ }
+
+ void
+ FontVariants::numeric_init() {
+ // std::cout << "FontVariants::numeric_init()" << std::endl;
+ }
+
+ void
+ FontVariants::numeric_callback() {
+ // std::cout << "FontVariants::numeric_callback()" << std::endl;
+ _numeric_changed = true;
+ _changed_signal.emit();
+ }
+
+ // Update GUI based on query.
+ void
+ FontVariants::update( SPStyle const *query ) {
+
+ _ligatures_all = query->font_variant_ligatures.computed;
+ _ligatures_mix = query->font_variant_ligatures.value;
+
+ _ligatures_common.set_active( _ligatures_all & SP_CSS_FONT_VARIANT_LIGATURES_COMMON );
+ _ligatures_discretionary.set_active(_ligatures_all & SP_CSS_FONT_VARIANT_LIGATURES_DISCRETIONARY );
+ _ligatures_historical.set_active( _ligatures_all & SP_CSS_FONT_VARIANT_LIGATURES_HISTORICAL );
+ _ligatures_contextual.set_active( _ligatures_all & SP_CSS_FONT_VARIANT_LIGATURES_CONTEXTUAL );
+
+ _ligatures_common.set_inconsistent( _ligatures_mix & SP_CSS_FONT_VARIANT_LIGATURES_COMMON );
+ _ligatures_discretionary.set_inconsistent( _ligatures_mix & SP_CSS_FONT_VARIANT_LIGATURES_DISCRETIONARY );
+ _ligatures_historical.set_inconsistent( _ligatures_mix & SP_CSS_FONT_VARIANT_LIGATURES_HISTORICAL );
+ _ligatures_contextual.set_inconsistent( _ligatures_mix & SP_CSS_FONT_VARIANT_LIGATURES_CONTEXTUAL );
+
+ _position_all = query->font_variant_position.computed;
+ _position_mix = query->font_variant_position.value;
+
+ _position_normal.set_active( _position_all & SP_CSS_FONT_VARIANT_POSITION_NORMAL );
+ _position_sub.set_active( _position_all & SP_CSS_FONT_VARIANT_POSITION_SUB );
+ _position_super.set_active( _position_all & SP_CSS_FONT_VARIANT_POSITION_SUPER );
+
+ _position_normal.set_inconsistent( _position_mix & SP_CSS_FONT_VARIANT_POSITION_NORMAL );
+ _position_sub.set_inconsistent( _position_mix & SP_CSS_FONT_VARIANT_POSITION_SUB );
+ _position_super.set_inconsistent( _position_mix & SP_CSS_FONT_VARIANT_POSITION_SUPER );
+
+ _caps_all = query->font_variant_caps.computed;
+ _caps_mix = query->font_variant_caps.value;
+
+ _caps_normal.set_active( _caps_all & SP_CSS_FONT_VARIANT_CAPS_NORMAL );
+ _caps_small.set_active( _caps_all & SP_CSS_FONT_VARIANT_CAPS_SMALL );
+ _caps_all_small.set_active( _caps_all & SP_CSS_FONT_VARIANT_CAPS_ALL_SMALL );
+ _caps_petite.set_active( _caps_all & SP_CSS_FONT_VARIANT_CAPS_PETITE );
+ _caps_all_petite.set_active( _caps_all & SP_CSS_FONT_VARIANT_CAPS_ALL_PETITE );
+ _caps_unicase.set_active( _caps_all & SP_CSS_FONT_VARIANT_CAPS_UNICASE );
+ _caps_titling.set_active( _caps_all & SP_CSS_FONT_VARIANT_CAPS_TITLING );
+
+ _caps_normal.set_inconsistent( _caps_mix & SP_CSS_FONT_VARIANT_CAPS_NORMAL );
+ _caps_small.set_inconsistent( _caps_mix & SP_CSS_FONT_VARIANT_CAPS_SMALL );
+ _caps_all_small.set_inconsistent( _caps_mix & SP_CSS_FONT_VARIANT_CAPS_ALL_SMALL );
+ _caps_petite.set_inconsistent( _caps_mix & SP_CSS_FONT_VARIANT_CAPS_PETITE );
+ _caps_all_petite.set_inconsistent( _caps_mix & SP_CSS_FONT_VARIANT_CAPS_ALL_PETITE );
+ _caps_unicase.set_inconsistent( _caps_mix & SP_CSS_FONT_VARIANT_CAPS_UNICASE );
+ _caps_titling.set_inconsistent( _caps_mix & SP_CSS_FONT_VARIANT_CAPS_TITLING );
+
+ _numeric_all = query->font_variant_numeric.computed;
+ _numeric_mix = query->font_variant_numeric.value;
+
+ if (_numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS) {
+ _numeric_lining.set_active();
+ } else if (_numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS) {
+ _numeric_old_style.set_active();
+ } else {
+ _numeric_default_style.set_active();
+ }
+
+ if (_numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS) {
+ _numeric_proportional.set_active();
+ } else if (_numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS) {
+ _numeric_tabular.set_active();
+ } else {
+ _numeric_default_width.set_active();
+ }
+
+ if (_numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS) {
+ _numeric_diagonal.set_active();
+ } else if (_numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS) {
+ _numeric_stacked.set_active();
+ } else {
+ _numeric_default_fractions.set_active();
+ }
+
+ _numeric_ordinal.set_active( _numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL );
+ _numeric_slashed_zero.set_active( _numeric_all & SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO );
+
+
+ _numeric_lining.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_LINING_NUMS );
+ _numeric_old_style.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_OLDSTYLE_NUMS );
+ _numeric_proportional.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_PROPORTIONAL_NUMS );
+ _numeric_tabular.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_TABULAR_NUMS );
+ _numeric_diagonal.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_DIAGONAL_FRACTIONS );
+ _numeric_stacked.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_STACKED_FRACTIONS );
+ _numeric_ordinal.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_ORDINAL );
+ _numeric_slashed_zero.set_inconsistent( _numeric_mix & SP_CSS_FONT_VARIANT_NUMERIC_SLASHED_ZERO );
+
+ _ligatures_changed = false;
+ _position_changed = false;
+ _caps_changed = false;
+ _numeric_changed = false;
+ }
+
+ void
+ FontVariants::fill_css( SPCSSAttr *css ) {
+
+ // Ligatures
+ bool common = _ligatures_common.get_active();
+ bool discretionary = _ligatures_discretionary.get_active();
+ bool historical = _ligatures_historical.get_active();
+ bool contextual = _ligatures_contextual.get_active();
+
+ if( !common && !discretionary && !historical && !contextual ) {
+ sp_repr_css_set_property(css, "font-variant-ligatures", "none" );
+ } else if ( common && !discretionary && !historical && contextual ) {
+ sp_repr_css_set_property(css, "font-variant-ligatures", "normal" );
+ } else {
+ Glib::ustring css_string;
+ if ( !common )
+ css_string += "no-common-ligatures ";
+ if ( discretionary )
+ css_string += "discretionary-ligatures ";
+ if ( historical )
+ css_string += "historical-ligatures ";
+ if ( !contextual )
+ css_string += "no-contextual ";
+ sp_repr_css_set_property(css, "font-variant-ligatures", css_string.c_str() );
+ }
+
+ // Position
+ {
+ unsigned position_new = SP_CSS_FONT_VARIANT_POSITION_NORMAL;
+ Glib::ustring css_string;
+ if( _position_normal.get_active() ) {
+ css_string = "normal";
+ } else if( _position_sub.get_active() ) {
+ css_string = "sub";
+ position_new = SP_CSS_FONT_VARIANT_POSITION_SUB;
+ } else if( _position_super.get_active() ) {
+ css_string = "super";
+ position_new = SP_CSS_FONT_VARIANT_POSITION_SUPER;
+ }
+
+ // 'if' may not be necessary... need to test.
+ if( (_position_all != position_new) || ((_position_mix != 0) && _position_changed) ) {
+ sp_repr_css_set_property(css, "font-variant-position", css_string.c_str() );
+ }
+ }
+
+ // Caps
+ {
+ unsigned caps_new = SP_CSS_FONT_VARIANT_CAPS_NORMAL;
+ Glib::ustring css_string;
+ if( _caps_normal.get_active() ) {
+ css_string = "normal";
+ caps_new = SP_CSS_FONT_VARIANT_CAPS_NORMAL;
+ } else if( _caps_small.get_active() ) {
+ css_string = "small-caps";
+ caps_new = SP_CSS_FONT_VARIANT_CAPS_SMALL;
+ } else if( _caps_all_small.get_active() ) {
+ css_string = "all-small-caps";
+ caps_new = SP_CSS_FONT_VARIANT_CAPS_ALL_SMALL;
+ } else if( _caps_all_petite.get_active() ) {
+ css_string = "petite";
+ caps_new = SP_CSS_FONT_VARIANT_CAPS_PETITE;
+ } else if( _caps_all_petite.get_active() ) {
+ css_string = "all-petite";
+ caps_new = SP_CSS_FONT_VARIANT_CAPS_ALL_PETITE;
+ } else if( _caps_unicase.get_active() ) {
+ css_string = "unicase";
+ caps_new = SP_CSS_FONT_VARIANT_CAPS_UNICASE;
+ } else if( _caps_titling.get_active() ) {
+ css_string = "titling";
+ caps_new = SP_CSS_FONT_VARIANT_CAPS_TITLING;
+ }
+
+ // May not be necessary... need to test.
+ //if( (_caps_all != caps_new) || ((_caps_mix != 0) && _caps_changed) ) {
+ sp_repr_css_set_property(css, "font-variant-caps", css_string.c_str() );
+ //}
+ }
+
+ // Numeric
+ bool default_style = _numeric_default_style.get_active();
+ bool lining = _numeric_lining.get_active();
+ bool old_style = _numeric_old_style.get_active();
+
+ bool default_width = _numeric_default_width.get_active();
+ bool proportional = _numeric_proportional.get_active();
+ bool tabular = _numeric_tabular.get_active();
+
+ bool default_fractions = _numeric_default_fractions.get_active();
+ bool diagonal = _numeric_diagonal.get_active();
+ bool stacked = _numeric_stacked.get_active();
+
+ bool ordinal = _numeric_ordinal.get_active();
+ bool slashed_zero = _numeric_slashed_zero.get_active();
+
+ if (default_style & default_width & default_fractions & !ordinal & !slashed_zero) {
+ sp_repr_css_set_property(css, "font-variant-numeric", "normal");
+ } else {
+ Glib::ustring css_string;
+ if ( lining )
+ css_string += "lining-nums ";
+ if ( old_style )
+ css_string += "oldstyle-nums ";
+ if ( proportional )
+ css_string += "proportional-nums ";
+ if ( tabular )
+ css_string += "tabular-nums ";
+ if ( diagonal )
+ css_string += "diagonal-fractions ";
+ if ( stacked )
+ css_string += "stacked-fractions ";
+ if ( ordinal )
+ css_string += "ordinal ";
+ if ( slashed_zero )
+ css_string += "slashed-zero ";
+ sp_repr_css_set_property(css, "font-variant-numeric", css_string.c_str() );
+ }
+
+ }
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/font-variants.h b/src/ui/widget/font-variants.h
new file mode 100644
index 000000000..e6a9dd68b
--- /dev/null
+++ b/src/ui/widget/font-variants.h
@@ -0,0 +1,152 @@
+/*
+ * Author:
+ * Tavmjong Bah <tavmjong@free.fr>
+ *
+ * Copyright (C) 2015 Tavmong Bah
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#ifndef INKSCAPE_UI_WIDGET_FONT_VARIANT_H
+#define INKSCAPE_UI_WIDGET_FONT_VARIANT_H
+
+#include <gtkmm/expander.h>
+#include <gtkmm/checkbutton.h>
+#include <gtkmm/radiobutton.h>
+
+class SPDesktop;
+class SPObject;
+class SPStyle;
+class SPCSSAttr;
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+/**
+ * A container for selecting font variants (OpenType Features).
+ */
+class FontVariants : public Gtk::VBox
+{
+
+public:
+
+ /**
+ * Constructor
+ */
+ FontVariants();
+
+protected:
+ // To start, use four check buttons.
+ Gtk::Expander _ligatures_frame;
+ Gtk::VBox _ligatures_vbox;
+ Gtk::CheckButton _ligatures_common;
+ Gtk::CheckButton _ligatures_discretionary;
+ Gtk::CheckButton _ligatures_historical;
+ Gtk::CheckButton _ligatures_contextual;
+
+ // Exclusive options
+ Gtk::Expander _position_frame;
+ Gtk::VBox _position_vbox;
+ Gtk::RadioButton _position_normal;
+ Gtk::RadioButton _position_sub;
+ Gtk::RadioButton _position_super;
+
+ // Exclusive options (maybe a dropdown menu to save space?)
+ Gtk::Expander _caps_frame;
+ Gtk::VBox _caps_vbox;
+ Gtk::RadioButton _caps_normal;
+ Gtk::RadioButton _caps_small;
+ Gtk::RadioButton _caps_all_small;
+ Gtk::RadioButton _caps_petite;
+ Gtk::RadioButton _caps_all_petite;
+ Gtk::RadioButton _caps_unicase;
+ Gtk::RadioButton _caps_titling;
+
+ // Complicated!
+ Gtk::Expander _numeric_frame;
+ Gtk::VBox _numeric_vbox;
+ Gtk::HBox _numeric_stylebox;
+ Gtk::RadioButton _numeric_lining;
+ Gtk::RadioButton _numeric_old_style;
+ Gtk::RadioButton _numeric_default_style;
+ Gtk::HBox _numeric_widthbox;
+ Gtk::RadioButton _numeric_proportional;
+ Gtk::RadioButton _numeric_tabular;
+ Gtk::RadioButton _numeric_default_width;
+ Gtk::HBox _numeric_fractionbox;
+ Gtk::RadioButton _numeric_diagonal;
+ Gtk::RadioButton _numeric_stacked;
+ Gtk::RadioButton _numeric_default_fractions;
+ Gtk::CheckButton _numeric_ordinal;
+ Gtk::CheckButton _numeric_slashed_zero;
+
+private:
+ void ligatures_init();
+ void ligatures_callback();
+
+ void position_init();
+ void position_callback();
+
+ void caps_init();
+ void caps_callback();
+
+ void numeric_init();
+ void numeric_callback();
+
+ // To determine if we need to write out property (may not be necessary)
+ unsigned _ligatures_all;
+ unsigned _position_all;
+ unsigned _caps_all;
+ unsigned _numeric_all;
+
+ unsigned _ligatures_mix;
+ unsigned _position_mix;
+ unsigned _caps_mix;
+ unsigned _numeric_mix;
+
+ bool _ligatures_changed;
+ bool _position_changed;
+ bool _caps_changed;
+ bool _numeric_changed;
+
+ sigc::signal<void> _changed_signal;
+
+public:
+
+ /**
+ * Update GUI based on query results.
+ */
+ void update( SPStyle const *query );
+
+ /**
+ * Fill SPCSSAttr based on settings of buttons.
+ */
+ void fill_css( SPCSSAttr* css );
+
+ /**
+ * Let others know that user has changed GUI settings.
+ * (Used to enable 'Apply' and 'Default' buttons.)
+ */
+ sigc::connection connectChanged(sigc::slot<void> slot) {
+ return _changed_signal.connect(slot);
+ }
+};
+
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+#endif // INKSCAPE_UI_WIDGET_FONT_VARIANT_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/verbs.cpp b/src/verbs.cpp
index ea2c06dcf..e0ef27b0d 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -1350,39 +1350,9 @@ void LayerVerb::perform(SPAction *action, void *data)
}
case SP_VERB_LAYER_DUPLICATE: {
if ( dt->currentLayer() != dt->currentRoot() ) {
- // Note with either approach:
- // Any clone masters are duplicated, their clones use the *original*,
- // but the duplicated master is not linked up as master nor clone of the original.
-#if 0
- // Only copies selectable things, honoring locks, visibility, avoids sublayers.
- SPObject *new_layer = Inkscape::create_layer(dt->currentRoot(), dt->currentLayer(), LPOS_BELOW);
- if ( dt->currentLayer()->label() ) {
- gchar* name = g_strdup_printf(_("%s copy"), dt->currentLayer()->label());
- dt->layer_manager->renameLayer( new_layer, name, TRUE );
- g_free(name);
- }
- sp_edit_select_all(dt);
- sp_selection_duplicate(dt, true);
- sp_selection_to_prev_layer(dt, true);
- dt->setCurrentLayer(new_layer);
- sp_edit_select_all(dt);
-#else
- // Copies everything, regardless of locks, visibility, sublayers.
- //XML Tree being directly used here while it shouldn't be.
- Inkscape::XML::Node *selected = dt->currentLayer()->getRepr();
- Inkscape::XML::Node *parent = selected->parent();
- Inkscape::XML::Node *dup = selected->duplicate(parent->document());
- parent->addChild(dup, selected);
- SPObject *new_layer = dt->currentLayer()->next;
- if (new_layer) {
- if (new_layer->label()) {
- gchar* name = g_strdup_printf(_("%s copy"), new_layer->label());
- dt->layer_manager->renameLayer( new_layer, name, TRUE );
- g_free(name);
- }
- dt->setCurrentLayer(new_layer);
- }
-#endif
+
+ sp_selection_duplicate(dt, true, true);
+
DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_DUPLICATE,
_("Duplicate layer"));
diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt
index 072b905a2..a3e9e14d0 100644
--- a/src/widgets/CMakeLists.txt
+++ b/src/widgets/CMakeLists.txt
@@ -41,12 +41,7 @@ set(widgets_SRC
select-toolbar.cpp
shrink-wrap-button.cpp
sp-attribute-widget.cpp
- sp-color-icc-selector.cpp
- sp-color-notebook.cpp
- sp-color-scales.cpp
sp-color-selector.cpp
- sp-color-slider.cpp
- sp-color-wheel-selector.cpp
sp-widget.cpp
sp-xmlview-attr-list.cpp
sp-xmlview-content.cpp
@@ -103,12 +98,7 @@ set(widgets_SRC
select-toolbar.h
shrink-wrap-button.h
sp-attribute-widget.h
- sp-color-icc-selector.h
- sp-color-notebook.h
- sp-color-scales.h
sp-color-selector.h
- sp-color-slider.h
- sp-color-wheel-selector.h
sp-widget.h
sp-xmlview-attr-list.h
sp-xmlview-content.h
diff --git a/src/widgets/Makefile_insert b/src/widgets/Makefile_insert
index dc4c12967..f66be66ed 100644
--- a/src/widgets/Makefile_insert
+++ b/src/widgets/Makefile_insert
@@ -76,18 +76,8 @@ ink_common_sources += \
widgets/spiral-toolbar.h \
widgets/sp-attribute-widget.cpp \
widgets/sp-attribute-widget.h \
- widgets/sp-color-icc-selector.cpp \
- widgets/sp-color-icc-selector.h \
- widgets/sp-color-notebook.cpp \
- widgets/sp-color-notebook.h \
- widgets/sp-color-scales.cpp \
- widgets/sp-color-scales.h \
widgets/sp-color-selector.cpp \
widgets/sp-color-selector.h \
- widgets/sp-color-slider.cpp \
- widgets/sp-color-slider.h \
- widgets/sp-color-wheel-selector.cpp \
- widgets/sp-color-wheel-selector.h \
widgets/spinbutton-events.cpp \
widgets/spinbutton-events.h \
widgets/sp-widget.cpp \
diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp
index b1f812338..fa5eabab4 100644
--- a/src/widgets/fill-style.cpp
+++ b/src/widgets/fill-style.cpp
@@ -300,7 +300,7 @@ void FillNStroke::performUpdate()
psel->setGradientProperties( rg->getUnits(),
rg->getSpread() );
} else if (SP_IS_PATTERN(server)) {
- SPPattern *pat = pattern_getroot(SP_PATTERN(server));
+ SPPattern *pat = SP_PATTERN(server)->rootPattern();
psel->updatePatternList( pat );
}
}
@@ -431,8 +431,7 @@ void FillNStroke::dragFromPaint()
update = true;
switch (psel->mode) {
- case SPPaintSelector::MODE_COLOR_RGB:
- case SPPaintSelector::MODE_COLOR_CMYK:
+ case SPPaintSelector::MODE_SOLID_COLOR:
{
// local change, do not update from selection
dragId = g_timeout_add_full(G_PRIORITY_DEFAULT, 100, dragDelayCB, this, 0);
@@ -505,8 +504,7 @@ void FillNStroke::updateFromPaint()
break;
}
- case SPPaintSelector::MODE_COLOR_RGB:
- case SPPaintSelector::MODE_COLOR_CMYK:
+ case SPPaintSelector::MODE_SOLID_COLOR:
{
if (kind == FILL) {
// FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events
@@ -656,7 +654,7 @@ void FillNStroke::updateFromPaint()
SPPaintServer *server = (kind == FILL) ?
selobj->style->getFillPaintServer() :
selobj->style->getStrokePaintServer();
- if (SP_IS_PATTERN(server) && pattern_getroot(SP_PATTERN(server)) == pattern)
+ if (SP_IS_PATTERN(server) && SP_PATTERN(server)->rootPattern() == pattern)
// only if this object's pattern is not rooted in our selected pattern, apply
continue;
}
diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp
index 42e59cbfe..402f30846 100644
--- a/src/widgets/gradient-selector.cpp
+++ b/src/widgets/gradient-selector.cpp
@@ -17,6 +17,10 @@
# include "config.h"
#endif
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/treeview.h>
#include "gradient-vector.h"
diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp
index 10d1cc107..259d4c9af 100644
--- a/src/widgets/gradient-vector.cpp
+++ b/src/widgets/gradient-vector.cpp
@@ -31,17 +31,16 @@
#include "macros.h"
#include <glibmm/i18n.h>
#include <set>
-#include "widgets/gradient-image.h"
-#include "inkscape.h"
-#include "document-private.h"
-#include "gradient-chemistry.h"
-#include "helper/window.h"
+#include "../widgets/gradient-image.h"
+#include "../inkscape.h"
+#include "../document-private.h"
+#include "../gradient-chemistry.h"
+#include "../helper/window.h"
#include "io/resource.h"
#include "xml/repr.h"
-#include "ui/dialog-events.h"
-#include "preferences.h"
+#include "../preferences.h"
#include "svg/css-ostringstream.h"
#include "sp-stop.h"
#include "selection-chemistry.h"
@@ -51,10 +50,16 @@
#include "desktop.h"
#include "layer-manager.h"
-#include <sigc++/sigc++.h>
+#include <sigc++/functors/ptr_fun.h>
+#include <sigc++/adaptors/bind.h>
#include "document-undo.h"
+#include "ui/dialog-events.h"
+#include "ui/selected-color.h"
+#include "ui/widget/color-notebook.h"
+
using Inkscape::DocumentUndo;
+using Inkscape::UI::SelectedColor;
enum {
VECTOR_SET,
@@ -468,11 +473,10 @@ void SPGradientVectorSelector::setSwatched()
### Vector Editing Widget
##################################################################*/
-#include "widgets/sp-color-notebook.h"
#include "widgets/widget-sizes.h"
#include "xml/node-event-vector.h"
#include "svg/svg-color.h"
-
+#include "ui/widget/color-notebook.h"
#define PAD 4
@@ -491,8 +495,8 @@ static void sp_gradient_vector_widget_destroy(GtkObject *object, gpointer data);
static void sp_gradient_vector_gradient_release(SPObject *obj, GtkWidget *widget);
static void sp_gradient_vector_gradient_modified(SPObject *obj, guint flags, GtkWidget *widget);
-static void sp_gradient_vector_color_dragged(SPColorSelector *csel, GObject *object);
-static void sp_gradient_vector_color_changed(SPColorSelector *csel, GObject *object);
+static void sp_gradient_vector_color_dragged(Inkscape::UI::SelectedColor *selected_color, GObject *object);
+static void sp_gradient_vector_color_changed(Inkscape::UI::SelectedColor *selected_color, GObject *object);
static void update_stop_list( GtkWidget *vb, SPGradient *gradient, SPStop *new_stop);
static gboolean blocked = FALSE;
@@ -649,9 +653,11 @@ static void sp_grad_edit_combo_box_changed (GtkComboBox * /*widget*/, GtkWidget
blocked = TRUE;
- SPColorSelector *csel = static_cast<SPColorSelector*>(g_object_get_data(G_OBJECT(tbl), "cselector"));
+ SelectedColor *csel = static_cast<SelectedColor*>(g_object_get_data(G_OBJECT(tbl), "cselector"));
// set its color, from the stored array
- csel->base->setColorAlpha( stop->getEffectiveColor(), stop->opacity );
+ g_object_set_data(G_OBJECT(tbl), "updating_color", reinterpret_cast<void*>(1));
+ csel->setColorAlpha(stop->getEffectiveColor(), stop->opacity);
+ g_object_set_data(G_OBJECT(tbl), "updating_color", reinterpret_cast<void*>(0));
GtkWidget *offspin = GTK_WIDGET(g_object_get_data(G_OBJECT(tbl), "offspn"));
GtkWidget *offslide =GTK_WIDGET(g_object_get_data(G_OBJECT(tbl), "offslide"));
@@ -832,7 +838,9 @@ static void sp_grd_ed_del_stop(GtkWidget */*widget*/, GtkWidget *vb)
static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *select_stop)
{
- GtkWidget *vb, *w, *f, *csel;
+ using Inkscape::UI::Widget::ColorNotebook;
+
+ GtkWidget *vb, *w, *f;
g_return_val_if_fail(!gradient || SP_IS_GRADIENT(gradient), NULL);
@@ -960,12 +968,23 @@ static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *s
f = gtk_frame_new(_("Stop Color"));
gtk_widget_show(f);
gtk_box_pack_start(GTK_BOX(vb), f, TRUE, TRUE, PAD);
- csel = static_cast<GtkWidget*>(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK));
- g_object_set_data(G_OBJECT(vb), "cselector", csel);
+
+ Inkscape::UI::SelectedColor *selected_color = new Inkscape::UI::SelectedColor;
+ g_object_set_data(G_OBJECT(vb), "cselector", selected_color);
+ g_object_set_data(G_OBJECT(vb), "updating_color", reinterpret_cast<void*>(0));
+ selected_color->signal_dragged.connect(sigc::bind(sigc::ptr_fun(&sp_gradient_vector_color_dragged), selected_color, G_OBJECT(vb)));
+ selected_color->signal_dragged.connect(sigc::bind(sigc::ptr_fun(&sp_gradient_vector_color_changed), selected_color, G_OBJECT(vb)));
+
+ Gtk::Widget *color_selector = Gtk::manage(new ColorNotebook(*selected_color));
+ color_selector->show();
+ gtk_container_add(GTK_CONTAINER(f), color_selector->gobj());
+
+ /*
gtk_widget_show(csel);
gtk_container_add(GTK_CONTAINER(f), csel);
g_signal_connect(G_OBJECT(csel), "dragged", G_CALLBACK(sp_gradient_vector_color_dragged), vb);
g_signal_connect(G_OBJECT(csel), "changed", G_CALLBACK(sp_gradient_vector_color_changed), vb);
+ */
gtk_widget_show(vb);
@@ -1126,9 +1145,11 @@ static void sp_gradient_vector_widget_load_gradient(GtkWidget *widget, SPGradien
}
// get the color selector
- SPColorSelector *csel = SP_COLOR_SELECTOR(g_object_get_data(G_OBJECT(widget), "cselector"));
+ SelectedColor *csel = static_cast<SelectedColor*>(g_object_get_data(G_OBJECT(widget), "cselector"));
- csel->base->setColorAlpha( stop->getEffectiveColor(), stop->opacity );
+ g_object_set_data(G_OBJECT(widget), "updating_color", reinterpret_cast<void*>(1));
+ csel->setColorAlpha(stop->getEffectiveColor(), stop->opacity);
+ g_object_set_data(G_OBJECT(widget), "updating_color", reinterpret_cast<void*>(0));
/* Fill preview */
GtkWidget *w = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(widget), "preview"));
@@ -1228,6 +1249,12 @@ static void sp_gradient_vector_widget_destroy(GtkObject *object, gpointer /*data
sp_repr_remove_listener_by_data(gradient->getRepr(), object);
}
}
+
+ SelectedColor *selected_color = static_cast<SelectedColor *>(g_object_get_data(G_OBJECT(object), "cselector"));
+ if (selected_color) {
+ delete selected_color;
+ g_object_set_data(G_OBJECT(object), "cselector", NULL);
+ }
}
static void sp_gradient_vector_gradient_release(SPObject */*object*/, GtkWidget *widget)
@@ -1245,7 +1272,7 @@ static void sp_gradient_vector_gradient_modified(SPObject *object, guint /*flags
}
}
-static void sp_gradient_vector_color_dragged(SPColorSelector *csel, GObject *object)
+static void sp_gradient_vector_color_dragged(Inkscape::UI::SelectedColor *selected_color, GObject *object)
{
SPGradient *gradient, *ngr;
@@ -1273,14 +1300,21 @@ static void sp_gradient_vector_color_dragged(SPColorSelector *csel, GObject *obj
return;
}
- csel->base->getColorAlpha(stop->specified_color, stop->opacity);
+ selected_color->colorAlpha(stop->specified_color, stop->opacity);
stop->currentColor = false;
blocked = FALSE;
}
-static void sp_gradient_vector_color_changed(SPColorSelector *csel, GObject *object)
+static void sp_gradient_vector_color_changed(Inkscape::UI::SelectedColor *selected_color, GObject *object)
{
+ (void)selected_color;
+
+ void* updating_color = g_object_get_data(G_OBJECT(object), "updating_color");
+ if (updating_color) {
+ return;
+ }
+
if (blocked) {
return;
}
@@ -1309,10 +1343,10 @@ static void sp_gradient_vector_color_changed(SPColorSelector *csel, GObject *obj
return;
}
- csel = static_cast<SPColorSelector*>(g_object_get_data(G_OBJECT(object), "cselector"));
+ SelectedColor *csel = static_cast<SelectedColor *>(g_object_get_data(G_OBJECT(object), "cselector"));
SPColor color;
float alpha = 0;
- csel->base->getColorAlpha( color, alpha );
+ csel->colorAlpha(color, alpha);
sp_repr_set_css_double(stop->getRepr(), "offset", stop->offset);
Inkscape::CSSOStringStream os;
diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp
index 221344296..846ded511 100644
--- a/src/widgets/paint-selector.cpp
+++ b/src/widgets/paint-selector.cpp
@@ -31,7 +31,6 @@
#include "widgets/widget-sizes.h"
#include "xml/repr.h"
-#include "sp-color-notebook.h"
#include "sp-linear-gradient.h"
#include "sp-radial-gradient.h"
#include "sp-mesh.h"
@@ -48,6 +47,7 @@
#include "io/sys.h"
#include "helper/stock-items.h"
#include "ui/icon-names.h"
+#include "ui/widget/color-notebook.h"
#include "paint-selector.h"
@@ -58,6 +58,7 @@
#include <gtk/gtk.h>
using Inkscape::Widgets::SwatchSelector;
+using Inkscape::UI::SelectedColor;
enum {
MODE_CHANGED,
@@ -94,8 +95,7 @@ static gchar const* modeStrings[] = {
"MODE_EMPTY",
"MODE_MULTIPLE",
"MODE_NONE",
- "MODE_COLOR_RGB",
- "MODE_COLOR_CMYK",
+ "MODE_SOLID_COLOR",
"MODE_GRADIENT_LINEAR",
"MODE_GRADIENT_RADIAL",
"MODE_PATTERN",
@@ -218,7 +218,7 @@ sp_paint_selector_init(SPPaintSelector *psel)
psel->none = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-none"),
SPPaintSelector::MODE_NONE, _("No paint"));
psel->solid = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-solid"),
- SPPaintSelector::MODE_COLOR_RGB, _("Flat color"));
+ SPPaintSelector::MODE_SOLID_COLOR, _("Flat color"));
psel->gradient = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-gradient-linear"),
SPPaintSelector::MODE_GRADIENT_LINEAR, _("Linear gradient"));
psel->radial = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-gradient-radial"),
@@ -292,8 +292,13 @@ sp_paint_selector_init(SPPaintSelector *psel)
/* Last used color */
- psel->color.set( 0.0, 0.0, 0.0 );
- psel->alpha = 1.0;
+ psel->selected_color = new SelectedColor;
+ psel->updating_color = false;
+
+ psel->selected_color->signal_grabbed.connect(sigc::mem_fun(psel, &SPPaintSelector::onSelectedColorGrabbed));
+ psel->selected_color->signal_dragged.connect(sigc::mem_fun(psel, &SPPaintSelector::onSelectedColorDragged));
+ psel->selected_color->signal_released.connect(sigc::mem_fun(psel, &SPPaintSelector::onSelectedColorReleased));
+ psel->selected_color->signal_changed.connect(sigc::mem_fun(psel, &SPPaintSelector::onSelectedColorChanged));
}
static void sp_paint_selector_dispose(GObject *object)
@@ -303,6 +308,11 @@ static void sp_paint_selector_dispose(GObject *object)
// clean up our long-living pattern menu
g_object_set_data(G_OBJECT(psel),"patternmenu",NULL);
+ if (psel->selected_color) {
+ delete psel->selected_color;
+ psel->selected_color = NULL;
+ }
+
if ((G_OBJECT_CLASS(sp_paint_selector_parent_class))->dispose)
(G_OBJECT_CLASS(sp_paint_selector_parent_class))->dispose(object);
}
@@ -396,8 +406,7 @@ void SPPaintSelector::setMode(Mode mode)
case MODE_NONE:
sp_paint_selector_set_mode_none(this);
break;
- case MODE_COLOR_RGB:
- case MODE_COLOR_CMYK:
+ case MODE_SOLID_COLOR:
sp_paint_selector_set_mode_color(this, mode);
break;
case MODE_GRADIENT_LINEAR:
@@ -438,7 +447,6 @@ void SPPaintSelector::setFillrule(FillRule fillrule)
void SPPaintSelector::setColorAlpha(SPColor const &color, float alpha)
{
g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) );
- SPColorSelector *csel = 0;
/*
guint32 rgba = 0;
@@ -455,12 +463,13 @@ void SPPaintSelector::setColorAlpha(SPColor const &color, float alpha)
#ifdef SP_PS_VERBOSE
g_print("PaintSelector set RGBA\n");
#endif
- setMode(MODE_COLOR_RGB);
+ setMode(MODE_SOLID_COLOR);
}
- csel = reinterpret_cast<SPColorSelector*>(g_object_get_data(G_OBJECT(selector), "color-selector"));
+ updating_color = true;
+ selected_color->setColorAlpha(color, alpha);
+ updating_color = false;
//rgba = color.toRGBA32( alpha );
- csel->base->setColorAlpha( color, alpha );
}
void SPPaintSelector::setSwatch(SPGradient *vector )
@@ -541,11 +550,7 @@ void SPPaintSelector::getGradientProperties( SPGradientUnits &units, SPGradientS
*/
void SPPaintSelector::getColorAlpha(SPColor &color, gfloat &alpha) const
{
- SPColorSelector *csel;
-
- csel = reinterpret_cast<SPColorSelector*>(g_object_get_data(G_OBJECT(selector), "color-selector"));
-
- csel->base->getColorAlpha( color, alpha );
+ selected_color->colorAlpha(color, alpha);
g_assert( ( 0.0 <= alpha )
&& ( alpha <= 1.0 ) );
@@ -581,6 +586,9 @@ sp_paint_selector_clear_frame(SPPaintSelector *psel)
if (psel->selector) {
+ //This is a hack to work around GtkNotebook bug in ColorSelector. Is sends signal switch-page on destroy
+ //The widget is hidden firts so it can recognize that it should not process signals from notebook child
+ gtk_widget_set_visible(psel->selector, false);
gtk_widget_destroy(psel->selector);
psel->selector = NULL;
}
@@ -633,82 +641,82 @@ sp_paint_selector_set_mode_none(SPPaintSelector *psel)
/* Color paint */
-static void sp_paint_selector_color_grabbed(SPColorSelector * /*csel*/, SPPaintSelector *psel)
-{
- g_signal_emit(G_OBJECT(psel), psel_signals[GRABBED], 0);
+void SPPaintSelector::onSelectedColorGrabbed() {
+ g_signal_emit(G_OBJECT(this), psel_signals[GRABBED], 0);
}
-static void sp_paint_selector_color_dragged(SPColorSelector * /*csel*/, SPPaintSelector *psel)
-{
- g_signal_emit(G_OBJECT(psel), psel_signals[DRAGGED], 0);
+void SPPaintSelector::onSelectedColorDragged() {
+ if (updating_color) {
+ return;
+ }
+ g_signal_emit(G_OBJECT(this), psel_signals[DRAGGED], 0);
}
-static void sp_paint_selector_color_released(SPColorSelector * /*csel*/, SPPaintSelector *psel)
-{
- g_signal_emit(G_OBJECT(psel), psel_signals[RELEASED], 0);
+void SPPaintSelector::onSelectedColorReleased() {
+ g_signal_emit(G_OBJECT(this), psel_signals[RELEASED], 0);
}
-static void
-sp_paint_selector_color_changed(SPColorSelector *csel, SPPaintSelector *psel)
-{
- csel->base->getColorAlpha( psel->color, psel->alpha );
+void SPPaintSelector::onSelectedColorChanged() {
+ if (updating_color) {
+ return;
+ }
- g_signal_emit(G_OBJECT(psel), psel_signals[CHANGED], 0);
+ if (mode == MODE_SOLID_COLOR) {
+ g_signal_emit(G_OBJECT(this), psel_signals[CHANGED], 0);
+ } else {
+ g_warning("SPPaintSelector::onSelectedColorChanged(): selected color changed while not in color selection mode");
+ }
}
static void sp_paint_selector_set_mode_color(SPPaintSelector *psel, SPPaintSelector::Mode /*mode*/)
{
- GtkWidget *csel;
-
- SPColor newcolor = psel->color;
- float newalpha = psel->alpha;
-
+ using Inkscape::UI::Widget::ColorNotebook;
+
if ((psel->mode == SPPaintSelector::MODE_SWATCH)
|| (psel->mode == SPPaintSelector::MODE_GRADIENT_LINEAR)
|| (psel->mode == SPPaintSelector::MODE_GRADIENT_RADIAL) ) {
SPGradientSelector *gsel = getGradientFromData(psel);
if (gsel) {
SPGradient *gradient = gsel->getVector();
- newcolor = gradient->getFirstStop()->specified_color;
- newalpha = gradient->getFirstStop()->opacity;
+
+ // Gradient can be null if object paint is changed externally (ie. with a color picker tool)
+ if (gradient)
+ {
+ SPColor color = gradient->getFirstStop()->specified_color;
+ float alpha = gradient->getFirstStop()->opacity;
+ psel->selected_color->setColorAlpha(color, alpha, false);
+ }
}
}
sp_paint_selector_set_style_buttons(psel, psel->solid);
gtk_widget_set_sensitive(psel->style, TRUE);
- if ((psel->mode == SPPaintSelector::MODE_COLOR_RGB) || (psel->mode == SPPaintSelector::MODE_COLOR_CMYK)) {
+ if ((psel->mode == SPPaintSelector::MODE_SOLID_COLOR)) {
/* Already have color selector */
- csel = GTK_WIDGET(g_object_get_data(G_OBJECT(psel->selector), "color-selector"));
+ // Do nothing
} else {
sp_paint_selector_clear_frame(psel);
/* Create new color selector */
/* Create vbox */
#if GTK_CHECK_VERSION(3,0,0)
- GtkWidget *vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
- gtk_box_set_homogeneous(GTK_BOX(vb), FALSE);
+ GtkWidget *vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
+ gtk_box_set_homogeneous(GTK_BOX(vb), FALSE);
#else
GtkWidget *vb = gtk_vbox_new(FALSE, 4);
#endif
gtk_widget_show(vb);
/* Color selector */
- csel = sp_color_selector_new( SP_TYPE_COLOR_NOTEBOOK );
- gtk_widget_show(csel);
- g_object_set_data(G_OBJECT(vb), "color-selector", csel);
- gtk_box_pack_start(GTK_BOX(vb), csel, TRUE, TRUE, 0);
- g_signal_connect(G_OBJECT(csel), "grabbed", G_CALLBACK(sp_paint_selector_color_grabbed), psel);
- g_signal_connect(G_OBJECT(csel), "dragged", G_CALLBACK(sp_paint_selector_color_dragged), psel);
- g_signal_connect(G_OBJECT(csel), "released", G_CALLBACK(sp_paint_selector_color_released), psel);
- g_signal_connect(G_OBJECT(csel), "changed", G_CALLBACK(sp_paint_selector_color_changed), psel);
+ Gtk::Widget *color_selector = Gtk::manage(new ColorNotebook(*(psel->selected_color)));
+ color_selector->show();
+ gtk_box_pack_start(GTK_BOX(vb), color_selector->gobj(), TRUE, TRUE, 0);
+
/* Pack everything to frame */
gtk_container_add(GTK_CONTAINER(psel->frame), vb);
psel->selector = vb;
-
- /* Set color */
- SP_COLOR_SELECTOR( csel )->base->setColorAlpha( newcolor, newalpha );
}
gtk_label_set_markup(GTK_LABEL(psel->label), _("<b>Flat color</b>"));
@@ -720,22 +728,22 @@ static void sp_paint_selector_set_mode_color(SPPaintSelector *psel, SPPaintSelec
/* Gradient */
-static void sp_paint_selector_gradient_grabbed(SPColorSelector * /*csel*/, SPPaintSelector *psel)
+static void sp_paint_selector_gradient_grabbed(SPGradientSelector * /*csel*/, SPPaintSelector *psel)
{
g_signal_emit(G_OBJECT(psel), psel_signals[GRABBED], 0);
}
-static void sp_paint_selector_gradient_dragged(SPColorSelector * /*csel*/, SPPaintSelector *psel)
+static void sp_paint_selector_gradient_dragged(SPGradientSelector * /*csel*/, SPPaintSelector *psel)
{
g_signal_emit(G_OBJECT(psel), psel_signals[DRAGGED], 0);
}
-static void sp_paint_selector_gradient_released(SPColorSelector * /*csel*/, SPPaintSelector *psel)
+static void sp_paint_selector_gradient_released(SPGradientSelector * /*csel*/, SPPaintSelector *psel)
{
g_signal_emit(G_OBJECT(psel), psel_signals[RELEASED], 0);
}
-static void sp_paint_selector_gradient_changed(SPColorSelector * /*csel*/, SPPaintSelector *psel)
+static void sp_paint_selector_gradient_changed(SPGradientSelector * /*csel*/, SPPaintSelector *psel)
{
g_signal_emit(G_OBJECT(psel), psel_signals[CHANGED], 0);
}
@@ -838,7 +846,7 @@ ink_pattern_list_get (SPDocument *source)
GSList *pl = NULL;
GSList const *patterns = source->getResourceList("pattern");
for (GSList *l = const_cast<GSList *>(patterns); l != NULL; l = l->next) {
- if (SP_PATTERN(l->data) == pattern_getroot(SP_PATTERN(l->data))) { // only if this is a root pattern
+ if (SP_PATTERN(l->data) == SP_PATTERN(l->data)->rootPattern()) { // only if this is a root pattern
pl = g_slist_prepend(pl, l->data);
}
}
@@ -1158,7 +1166,7 @@ SPPattern *SPPaintSelector::getPattern()
}
g_free(paturn);
} else {
- pat = pattern_getroot(SP_PATTERN(patid));
+ pat = SP_PATTERN(patid)->rootPattern();
}
if (pat && !SP_IS_PATTERN(pat)) {
@@ -1265,7 +1273,7 @@ SPPaintSelector::Mode SPPaintSelector::getModeForStyle(SPStyle const & style, Fi
}
} else if ( target.isColor() ) {
// TODO this is no longer a valid assertion:
- mode = MODE_COLOR_RGB; // so far only rgb can be read from svg
+ mode = MODE_SOLID_COLOR; // so far only rgb can be read from svg
} else if ( target.isNone() ) {
mode = MODE_NONE;
} else {
diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h
index 788aa673e..23c2dd456 100644
--- a/src/widgets/paint-selector.h
+++ b/src/widgets/paint-selector.h
@@ -12,12 +12,18 @@
*
*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <glib.h>
#include <gtk/gtk.h>
#include "color.h"
#include "fill-or-stroke.h"
#include "sp-gradient-spread.h"
#include "sp-gradient-units.h"
+#include "ui/selected-color.h"
class SPGradient;
class SPDesktop;
@@ -44,8 +50,7 @@ struct SPPaintSelector {
MODE_EMPTY,
MODE_MULTIPLE,
MODE_NONE,
- MODE_COLOR_RGB,
- MODE_COLOR_CMYK,
+ MODE_SOLID_COLOR,
MODE_GRADIENT_LINEAR,
MODE_GRADIENT_RADIAL,
#ifdef WITH_MESH
@@ -83,9 +88,8 @@ struct SPPaintSelector {
GtkWidget *frame, *selector;
GtkWidget *label;
- SPColor color;
- float alpha;
-
+ Inkscape::UI::SelectedColor *selected_color;
+ bool updating_color;
static Mode getModeForStyle(SPStyle const & style, FillOrStroke kind);
@@ -114,6 +118,11 @@ struct SPPaintSelector {
// TODO move this elsewhere:
void setFlatColor( SPDesktop *desktop, const gchar *color_property, const gchar *opacity_property );
+
+ void onSelectedColorGrabbed();
+ void onSelectedColorDragged();
+ void onSelectedColorReleased();
+ void onSelectedColorChanged();
};
enum {COMBO_COL_LABEL=0, COMBO_COL_STOCK=1, COMBO_COL_PATTERN=2, COMBO_COL_SEP=3, COMBO_N_COLS=4};
diff --git a/src/widgets/sp-color-icc-selector.cpp b/src/widgets/sp-color-icc-selector.cpp
deleted file mode 100644
index 6e910c582..000000000
--- a/src/widgets/sp-color-icc-selector.cpp
+++ /dev/null
@@ -1,1113 +0,0 @@
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "gradient-vector.h"
-#include <math.h>
-#include <gtk/gtk.h>
-#include <glibmm/i18n.h>
-#include <map>
-#include <set>
-#include <vector>
-
-#include "ui/dialog-events.h"
-#include "sp-color-icc-selector.h"
-#include "sp-color-scales.h"
-#include "sp-color-slider.h"
-#include "svg/svg-icc-color.h"
-#include "colorspace.h"
-#include "document.h"
-#include "inkscape.h"
-#include "profile-manager.h"
-
-#define noDEBUG_LCMS
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-#include "color-profile.h"
-#include "cms-system.h"
-#include "color-profile-cms-fns.h"
-
-#ifdef DEBUG_LCMS
-#include "preferences.h"
-#endif // DEBUG_LCMS
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
-
-#ifdef DEBUG_LCMS
-extern guint update_in_progress;
-#define DEBUG_MESSAGE(key, ...) \
-{\
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();\
- bool dump = prefs->getBool("/options/scislac/" #key);\
- bool dumpD = prefs->getBool("/options/scislac/" #key "D");\
- bool dumpD2 = prefs->getBool("/options/scislac/" #key "D2");\
- dumpD &&= ( (update_in_progress == 0) || dumpD2 );\
- if ( dump )\
- {\
- g_message( __VA_ARGS__ );\
-\
- }\
- if ( dumpD )\
- {\
- GtkWidget *dialog = gtk_message_dialog_new(NULL,\
- GTK_DIALOG_DESTROY_WITH_PARENT, \
- GTK_MESSAGE_INFO, \
- GTK_BUTTONS_OK, \
- __VA_ARGS__ \
- );\
- g_signal_connect_swapped(dialog, "response",\
- G_CALLBACK(gtk_widget_destroy), \
- dialog); \
- gtk_widget_show_all( dialog );\
- }\
-}
-#endif // DEBUG_LCMS
-
-
-
-G_BEGIN_DECLS
-
-static void sp_color_icc_selector_dispose(GObject *object);
-static void sp_color_icc_selector_show_all (GtkWidget *widget);
-static void sp_color_icc_selector_hide(GtkWidget *widget);
-
-G_END_DECLS
-
-/**
- * Class containing the parts for a single color component's UI presence.
- */
-class ComponentUI
-{
-public:
- ComponentUI() :
- _component(),
- _adj(0),
- _slider(0),
- _btn(0),
- _label(0),
- _map(0)
- {
- }
-
- ComponentUI(colorspace::Component const &component) :
- _component(component),
- _adj(0),
- _slider(0),
- _btn(0),
- _label(0),
- _map(0)
- {
- }
-
- colorspace::Component _component;
- GtkAdjustment *_adj; // Component adjustment
- GtkWidget *_slider;
- GtkWidget *_btn; // spinbutton
- GtkWidget *_label; // Label
- guchar *_map;
-};
-
-/**
- * Class that implements the internals of the selector.
- */
-class ColorICCSelectorImpl
-{
-public:
-
- ColorICCSelectorImpl( ColorICCSelector *owner);
-
- ~ColorICCSelectorImpl();
-
- static void _adjustmentChanged ( GtkAdjustment *adjustment, SPColorICCSelector *cs );
-
- static void _sliderGrabbed( SPColorSlider *slider, SPColorICCSelector *cs );
- static void _sliderReleased( SPColorSlider *slider, SPColorICCSelector *cs );
- static void _sliderChanged( SPColorSlider *slider, SPColorICCSelector *cs );
-
- static void _profileSelected( GtkWidget* src, gpointer data );
- static void _fixupHit( GtkWidget* src, gpointer data );
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- void _setProfile( SVGICCColor* profile );
- void _switchToProfile( gchar const* name );
-#endif
- void _updateSliders( gint ignore );
- void _profilesChanged( std::string const & name );
-
- ColorICCSelector *_owner;
-
- gboolean _updating : 1;
- gboolean _dragging : 1;
-
- guint32 _fixupNeeded;
- GtkWidget* _fixupBtn;
- GtkWidget* _profileSel;
-
- std::vector<ComponentUI> _compUI;
-
- GtkAdjustment* _adj; // Channel adjustment
- GtkWidget* _slider;
- GtkWidget* _sbtn; // Spinbutton
- GtkWidget* _label; // Label
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- std::string _profileName;
- Inkscape::ColorProfile* _prof;
- guint _profChannelCount;
- gulong _profChangedID;
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-};
-
-#define XPAD 4
-#define YPAD 1
-
-namespace
-{
-
-size_t maxColorspaceComponentCount = 0;
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
-/**
- * Internal variable to track all known colorspaces.
- */
-std::set<cmsUInt32Number> knownColorspaces;
-
-#endif
-
-
-/**
- * Simple helper to allow bitwise or on GtkAttachOptions.
- */
-GtkAttachOptions operator|(GtkAttachOptions lhs, GtkAttachOptions rhs)
-{
- return static_cast<GtkAttachOptions>(static_cast<int>(lhs) | static_cast<int>(rhs));
-}
-
-/**
- * Helper function to handle GTK2/GTK3 attachment #ifdef code.
- */
-void attachToGridOrTable(GtkWidget *parent,
- GtkWidget *child,
- guint left,
- guint top,
- guint width,
- guint height,
- bool hexpand = false,
- bool centered = false,
- guint xpadding = XPAD,
- guint ypadding = YPAD)
-{
-#if GTK_CHECK_VERSION(3,0,0)
- #if GTK_CHECK_VERSION(3,12,0)
- gtk_widget_set_margin_start( child, xpadding );
- gtk_widget_set_margin_end( child, xpadding );
- #else
- gtk_widget_set_margin_left( child, xpadding );
- gtk_widget_set_margin_right( child, xpadding );
- #endif
-
- gtk_widget_set_margin_top( child, ypadding );
- gtk_widget_set_margin_bottom( child, ypadding );
- if (hexpand) {
- gtk_widget_set_hexpand(child, TRUE);
- }
- if (centered) {
- gtk_widget_set_halign( child, GTK_ALIGN_CENTER );
- gtk_widget_set_valign( child, GTK_ALIGN_CENTER );
- }
- gtk_grid_attach( GTK_GRID(parent), child, left, top, width, height );
-#else
- GtkAttachOptions xoptions = centered ? static_cast<GtkAttachOptions>(0) : hexpand ? (GTK_EXPAND | GTK_FILL) : GTK_FILL;
- GtkAttachOptions yoptions = centered ? static_cast<GtkAttachOptions>(0) : GTK_FILL;
-
- gtk_table_attach( GTK_TABLE(parent), child, left, left + width, top, top + height, xoptions, yoptions, xpadding, ypadding );
-#endif
-}
-
-} // namespace
-
-G_DEFINE_TYPE(SPColorICCSelector, sp_color_icc_selector, SP_TYPE_COLOR_SELECTOR);
-
-static void sp_color_icc_selector_class_init(SPColorICCSelectorClass *klass)
-{
- static const gchar* nameset[] = {N_("CMS"), 0};
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass);
-
- selector_class->name = nameset;
- selector_class->submode_count = 1;
-
- object_class->dispose = sp_color_icc_selector_dispose;
-
- widget_class->show_all = sp_color_icc_selector_show_all;
- widget_class->hide = sp_color_icc_selector_hide;
-}
-
-
-ColorICCSelector::ColorICCSelector( SPColorSelector* csel )
- : ColorSelector( csel ),
- _impl(NULL)
-{
-}
-
-ColorICCSelector::~ColorICCSelector()
-{
- if (_impl)
- {
- delete _impl;
- _impl = 0;
- }
-}
-
-void sp_color_icc_selector_init(SPColorICCSelector *cs)
-{
- SP_COLOR_SELECTOR(cs)->base = new ColorICCSelector( SP_COLOR_SELECTOR(cs) );
-
- if ( SP_COLOR_SELECTOR(cs)->base )
- {
- SP_COLOR_SELECTOR(cs)->base->init();
- }
-}
-
-
-/*
-icSigRgbData
-icSigCmykData
-icSigCmyData
-*/
-#define SPACE_ID_RGB 0
-#define SPACE_ID_CMY 1
-#define SPACE_ID_CMYK 2
-
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-static cmsUInt16Number* getScratch() {
- // bytes per pixel * input channels * width
- static cmsUInt16Number* scritch = static_cast<cmsUInt16Number*>(g_new(cmsUInt16Number, 4 * 1024));
-
- return scritch;
-}
-
-colorspace::Component::Component() :
- name(),
- tip(),
- scale(1)
-{
-}
-
-colorspace::Component::Component(std::string const &name, std::string const &tip, guint scale) :
- name(name),
- tip(tip),
- scale(scale)
-{
-}
-
-std::vector<colorspace::Component> colorspace::getColorSpaceInfo( uint32_t space )
-{
- static std::map<cmsUInt32Number, std::vector<Component> > sets;
- if (sets.empty())
- {
- sets[cmsSigXYZData].push_back(Component("_X", "X", 2)); // TYPE_XYZ_16
- sets[cmsSigXYZData].push_back(Component("_Y", "Y", 1));
- sets[cmsSigXYZData].push_back(Component("_Z", "Z", 2));
-
- sets[cmsSigLabData].push_back(Component("_L", "L", 100)); // TYPE_Lab_16
- sets[cmsSigLabData].push_back(Component("_a", "a", 256));
- sets[cmsSigLabData].push_back(Component("_b", "b", 256));
-
- //cmsSigLuvData
-
- sets[cmsSigYCbCrData].push_back(Component("_Y", "Y", 1)); // TYPE_YCbCr_16
- sets[cmsSigYCbCrData].push_back(Component("C_b", "Cb", 1));
- sets[cmsSigYCbCrData].push_back(Component("C_r", "Cr", 1));
-
- sets[cmsSigYxyData].push_back(Component("_Y", "Y", 1)); // TYPE_Yxy_16
- sets[cmsSigYxyData].push_back(Component("_x", "x", 1));
- sets[cmsSigYxyData].push_back(Component("y", "y", 1));
-
- sets[cmsSigRgbData].push_back(Component(_("_R:"), _("Red"), 1)); // TYPE_RGB_16
- sets[cmsSigRgbData].push_back(Component(_("_G:"), _("Green"), 1));
- sets[cmsSigRgbData].push_back(Component(_("_B:"), _("Blue"), 1));
-
- sets[cmsSigGrayData].push_back(Component(_("G:"), _("Gray"), 1)); // TYPE_GRAY_16
-
- sets[cmsSigHsvData].push_back(Component(_("_H:"), _("Hue"), 360)); // TYPE_HSV_16
- sets[cmsSigHsvData].push_back(Component(_("_S:"), _("Saturation"), 1));
- sets[cmsSigHsvData].push_back(Component("_V:", "Value", 1));
-
- sets[cmsSigHlsData].push_back(Component(_("_H:"), _("Hue"), 360)); // TYPE_HLS_16
- sets[cmsSigHlsData].push_back(Component(_("_L:"), _("Lightness"), 1));
- sets[cmsSigHlsData].push_back(Component(_("_S:"), _("Saturation"), 1));
-
- sets[cmsSigCmykData].push_back(Component(_("_C:"), _("Cyan"), 1)); // TYPE_CMYK_16
- sets[cmsSigCmykData].push_back(Component(_("_M:"), _("Magenta"), 1));
- sets[cmsSigCmykData].push_back(Component(_("_Y:"), _("Yellow"), 1));
- sets[cmsSigCmykData].push_back(Component(_("_K:"), _("Black"), 1));
-
- sets[cmsSigCmyData].push_back(Component(_("_C:"), _("Cyan"), 1)); // TYPE_CMY_16
- sets[cmsSigCmyData].push_back(Component(_("_M:"), _("Magenta"), 1));
- sets[cmsSigCmyData].push_back(Component(_("_Y:"), _("Yellow"), 1));
-
- for (std::map<cmsUInt32Number, std::vector<Component> >::iterator it = sets.begin(); it != sets.end(); ++it)
- {
- knownColorspaces.insert(it->first);
- maxColorspaceComponentCount = std::max(maxColorspaceComponentCount, it->second.size());
- }
- }
-
- std::vector<Component> target;
-
- if (sets.find(space) != sets.end())
- {
- target = sets[space];
- }
- return target;
-}
-
-
-std::vector<colorspace::Component> colorspace::getColorSpaceInfo( Inkscape::ColorProfile *prof )
-{
- return getColorSpaceInfo( asICColorSpaceSig(prof->getColorSpace()) );
-}
-
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
-ColorICCSelectorImpl::ColorICCSelectorImpl(ColorICCSelector *owner) :
- _owner(owner),
- _updating( FALSE ),
- _dragging( FALSE ),
- _fixupNeeded(0),
- _fixupBtn(0),
- _profileSel(0),
- _compUI(),
- _adj(0),
- _slider(0),
- _sbtn(0),
- _label(0)
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- ,
- _profileName(),
- _prof(0),
- _profChannelCount(0),
- _profChangedID(0)
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-{
-}
-
-ColorICCSelectorImpl::~ColorICCSelectorImpl()
-{
- _adj = 0;
- _sbtn = 0;
- _label = 0;
-}
-
-void ColorICCSelector::init()
-{
- if (_impl) delete(_impl);
- _impl = new ColorICCSelectorImpl(this);
- gint row = 0;
-
- _impl->_updating = FALSE;
- _impl->_dragging = FALSE;
-
-#if GTK_CHECK_VERSION(3,0,0)
- GtkWidget *t = gtk_grid_new();
-#else
- GtkWidget *t = gtk_table_new(5, 3, FALSE);
-#endif
-
- gtk_widget_show (t);
- gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 4);
-
- _impl->_compUI.clear();
-
- // Create components
- row = 0;
-
-
- _impl->_fixupBtn = gtk_button_new_with_label(_("Fix"));
- g_signal_connect( G_OBJECT(_impl->_fixupBtn), "clicked", G_CALLBACK(ColorICCSelectorImpl::_fixupHit), (gpointer)_impl );
- gtk_widget_set_sensitive( _impl->_fixupBtn, FALSE );
- gtk_widget_set_tooltip_text( _impl->_fixupBtn, _("Fix RGB fallback to match icc-color() value.") );
- //gtk_misc_set_alignment( GTK_MISC (_impl->_fixupBtn), 1.0, 0.5 );
- gtk_widget_show( _impl->_fixupBtn );
-
- attachToGridOrTable(t, _impl->_fixupBtn, 0, row, 1, 1);
-
- // Combobox and store with 2 columns : label (0) and full name (1)
- GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
- _impl->_profileSel = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
-
- GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(_impl->_profileSel), renderer, TRUE);
- gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(_impl->_profileSel), renderer, "text", 0, NULL);
-
- GtkTreeIter iter;
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, _("<none>"), 1, _("<none>"), -1);
-
- gtk_widget_show( _impl->_profileSel );
- gtk_combo_box_set_active( GTK_COMBO_BOX(_impl->_profileSel), 0 );
-
- attachToGridOrTable(t, _impl->_profileSel, 1, row, 1, 1);
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- _impl->_profChangedID = g_signal_connect( G_OBJECT(_impl->_profileSel), "changed", G_CALLBACK(ColorICCSelectorImpl::_profileSelected), (gpointer)_impl );
-#else
- gtk_widget_set_sensitive( _impl->_profileSel, false );
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
-
- row++;
-
- // populate the data for colorspaces and channels:
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- std::vector<colorspace::Component> things = colorspace::getColorSpaceInfo( cmsSigRgbData );
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
- for ( size_t i = 0; i < maxColorspaceComponentCount; i++ ) {
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- if (i < things.size()) {
- _impl->_compUI.push_back(ComponentUI(things[i]));
- } else {
- _impl->_compUI.push_back(ComponentUI());
- }
-
- std::string labelStr = (i < things.size()) ? things[i].name.c_str() : "";
-#else
- _impl->_compUI.push_back(ComponentUI());
-
- std::string labelStr = ".";
-#endif
-
- _impl->_compUI[i]._label = gtk_label_new_with_mnemonic( labelStr.c_str() );
- gtk_misc_set_alignment( GTK_MISC (_impl->_compUI[i]._label), 1.0, 0.5 );
- gtk_widget_show( _impl->_compUI[i]._label );
-
- attachToGridOrTable(t, _impl->_compUI[i]._label, 0, row, 1, 1);
-
- // Adjustment
- guint scaleValue = _impl->_compUI[i]._component.scale;
- gdouble step = static_cast<gdouble>(scaleValue) / 100.0;
- gdouble page = static_cast<gdouble>(scaleValue) / 10.0;
- gint digits = (step > 0.9) ? 0 : 2;
- _impl->_compUI[i]._adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0.0, 0.0, scaleValue, step, page, page ) );
-
- // Slider
- _impl->_compUI[i]._slider = sp_color_slider_new( _impl->_compUI[i]._adj );
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- gtk_widget_set_tooltip_text( _impl->_compUI[i]._slider, (i < things.size()) ? things[i].tip.c_str() : "" );
-#else
- gtk_widget_set_tooltip_text( _impl->_compUI[i]._slider, "." );
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- gtk_widget_show( _impl->_compUI[i]._slider );
-
- attachToGridOrTable(t, _impl->_compUI[i]._slider, 1, row, 1, 1, true);
-
- _impl->_compUI[i]._btn = gtk_spin_button_new( _impl->_compUI[i]._adj, step, digits );
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- gtk_widget_set_tooltip_text( _impl->_compUI[i]._btn, (i < things.size()) ? things[i].tip.c_str() : "" );
-#else
- gtk_widget_set_tooltip_text( _impl->_compUI[i]._btn, "." );
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- sp_dialog_defocus_on_enter( _impl->_compUI[i]._btn );
- gtk_label_set_mnemonic_widget( GTK_LABEL(_impl->_compUI[i]._label), _impl->_compUI[i]._btn );
- gtk_widget_show( _impl->_compUI[i]._btn );
-
- attachToGridOrTable(t, _impl->_compUI[i]._btn, 2, row, 1, 1, false, true);
-
- _impl->_compUI[i]._map = g_new( guchar, 4 * 1024 );
- memset( _impl->_compUI[i]._map, 0x0ff, 1024 * 4 );
-
-
- // Signals
- g_signal_connect( G_OBJECT( _impl->_compUI[i]._adj ), "value_changed", G_CALLBACK( ColorICCSelectorImpl::_adjustmentChanged ), _csel );
-
- g_signal_connect( G_OBJECT( _impl->_compUI[i]._slider ), "grabbed", G_CALLBACK( ColorICCSelectorImpl::_sliderGrabbed ), _csel );
- g_signal_connect( G_OBJECT( _impl->_compUI[i]._slider ), "released", G_CALLBACK( ColorICCSelectorImpl::_sliderReleased ), _csel );
- g_signal_connect( G_OBJECT( _impl->_compUI[i]._slider ), "changed", G_CALLBACK( ColorICCSelectorImpl::_sliderChanged ), _csel );
-
- row++;
- }
-
- // Label
- _impl->_label = gtk_label_new_with_mnemonic(_("_A:"));
- gtk_misc_set_alignment(GTK_MISC(_impl->_label), 1.0, 0.5);
- gtk_widget_show(_impl->_label);
-
- attachToGridOrTable(t, _impl->_label, 0, row, 1, 1);
-
- // Adjustment
- _impl->_adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 255.0, 1.0, 10.0, 10.0));
-
- // Slider
- _impl->_slider = sp_color_slider_new(_impl->_adj);
- gtk_widget_set_tooltip_text(_impl->_slider, _("Alpha (opacity)"));
- gtk_widget_show(_impl->_slider);
-
- attachToGridOrTable(t, _impl->_slider, 1, row, 1, 1, true);
-
- sp_color_slider_set_colors( SP_COLOR_SLIDER( _impl->_slider ),
- SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 0.0 ),
- SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 0.5 ),
- SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 1.0 ) );
-
-
- // Spinbutton
- _impl->_sbtn = gtk_spin_button_new(GTK_ADJUSTMENT(_impl->_adj), 1.0, 0);
- gtk_widget_set_tooltip_text(_impl->_sbtn, _("Alpha (opacity)"));
- sp_dialog_defocus_on_enter(_impl->_sbtn);
- gtk_label_set_mnemonic_widget(GTK_LABEL(_impl->_label), _impl->_sbtn);
- gtk_widget_show(_impl->_sbtn);
-
- attachToGridOrTable(t, _impl->_sbtn, 2, row, 1, 1, false, true);
-
- // Signals
- g_signal_connect(G_OBJECT(_impl->_adj), "value_changed", G_CALLBACK(ColorICCSelectorImpl::_adjustmentChanged), _csel);
-
- g_signal_connect(G_OBJECT(_impl->_slider), "grabbed", G_CALLBACK(ColorICCSelectorImpl::_sliderGrabbed), _csel);
- g_signal_connect(G_OBJECT(_impl->_slider), "released", G_CALLBACK(ColorICCSelectorImpl::_sliderReleased), _csel);
- g_signal_connect(G_OBJECT(_impl->_slider), "changed", G_CALLBACK(ColorICCSelectorImpl::_sliderChanged), _csel);
-}
-
-static void sp_color_icc_selector_dispose(GObject *object)
-{
- if (G_OBJECT_CLASS(sp_color_icc_selector_parent_class)->dispose) {
- G_OBJECT_CLASS(sp_color_icc_selector_parent_class)->dispose(object);
- }
-}
-
-static void
-sp_color_icc_selector_show_all (GtkWidget *widget)
-{
- gtk_widget_show (widget);
-}
-
-static void sp_color_icc_selector_hide(GtkWidget *widget)
-{
- gtk_widget_hide(widget);
-}
-
-GtkWidget *
-sp_color_icc_selector_new (void)
-{
- SPColorICCSelector *csel;
-
- csel = static_cast<SPColorICCSelector*>(g_object_new (SP_TYPE_COLOR_ICC_SELECTOR, NULL));
-
- return GTK_WIDGET (csel);
-}
-
-
-void ColorICCSelectorImpl::_fixupHit( GtkWidget* /*src*/, gpointer data )
-{
- ColorICCSelectorImpl* self = reinterpret_cast<ColorICCSelectorImpl*>(data);
- gtk_widget_set_sensitive( self->_fixupBtn, FALSE );
- self->_adjustmentChanged( self->_compUI[0]._adj, SP_COLOR_ICC_SELECTOR(self->_owner->_csel) );
-}
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-void ColorICCSelectorImpl::_profileSelected( GtkWidget* /*src*/, gpointer data )
-{
- ColorICCSelectorImpl* self = reinterpret_cast<ColorICCSelectorImpl*>(data);
-
- GtkTreeIter iter;
- if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(self->_profileSel), &iter)) {
- GtkTreeModel *store = gtk_combo_box_get_model(GTK_COMBO_BOX(self->_profileSel));
- gchar* name = 0;
-
- gtk_tree_model_get(store, &iter, 1, &name, -1);
- self->_switchToProfile( name );
- gtk_widget_set_tooltip_text(self->_profileSel, name );
-
- if ( name ) {
- g_free( name );
- }
- }
-}
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-void ColorICCSelectorImpl::_switchToProfile( gchar const* name )
-{
- bool dirty = false;
- SPColor tmp( _owner->_color );
-
- if ( name ) {
- if ( tmp.icc && tmp.icc->colorProfile == name ) {
-#ifdef DEBUG_LCMS
- g_message("Already at name [%s]", name );
-#endif // DEBUG_LCMS
- } else {
-#ifdef DEBUG_LCMS
- g_message("Need to switch to profile [%s]", name );
-#endif // DEBUG_LCMS
- if ( tmp.icc ) {
- tmp.icc->colors.clear();
- } else {
- tmp.icc = new SVGICCColor();
- }
- tmp.icc->colorProfile = name;
- Inkscape::ColorProfile* newProf = SP_ACTIVE_DOCUMENT->profileManager->find(name);
- if ( newProf ) {
- cmsHTRANSFORM trans = newProf->getTransfFromSRGB8();
- if ( trans ) {
- guint32 val = _owner->_color.toRGBA32(0);
- guchar pre[4] = {
- static_cast<guchar>(SP_RGBA32_R_U(val)),
- static_cast<guchar>(SP_RGBA32_G_U(val)),
- static_cast<guchar>(SP_RGBA32_B_U(val)),
- 255};
-#ifdef DEBUG_LCMS
- g_message("Shoving in [%02x] [%02x] [%02x]", pre[0], pre[1], pre[2]);
-#endif // DEBUG_LCMS
- cmsUInt16Number post[4] = {0,0,0,0};
- cmsDoTransform( trans, pre, post, 1 );
-#ifdef DEBUG_LCMS
- g_message("got on out [%04x] [%04x] [%04x] [%04x]", post[0], post[1], post[2], post[3]);
-#endif // DEBUG_LCMS
-#if HAVE_LIBLCMS1
- guint count = _cmsChannelsOf( asICColorSpaceSig(newProf->getColorSpace()) );
-#elif HAVE_LIBLCMS2
- guint count = cmsChannelsOf( asICColorSpaceSig(newProf->getColorSpace()) );
-#endif
-
- std::vector<colorspace::Component> things = colorspace::getColorSpaceInfo(asICColorSpaceSig(newProf->getColorSpace()));
-
- for ( guint i = 0; i < count; i++ ) {
- gdouble val = (((gdouble)post[i])/65535.0) * (gdouble)((i < things.size()) ? things[i].scale : 1);
-#ifdef DEBUG_LCMS
- g_message(" scaled %d by %d to be %f", i, ((i < things.size()) ? things[i].scale : 1), val);
-#endif // DEBUG_LCMS
- tmp.icc->colors.push_back(val);
- }
- cmsHTRANSFORM retrans = newProf->getTransfToSRGB8();
- if ( retrans ) {
- cmsDoTransform( retrans, post, pre, 1 );
-#ifdef DEBUG_LCMS
- g_message(" back out [%02x] [%02x] [%02x]", pre[0], pre[1], pre[2]);
-#endif // DEBUG_LCMS
- tmp.set(SP_RGBA32_U_COMPOSE(pre[0], pre[1], pre[2], 0xff));
- }
- }
- }
- dirty = true;
- }
- } else {
-#ifdef DEBUG_LCMS
- g_message("NUKE THE ICC");
-#endif // DEBUG_LCMS
- if ( tmp.icc ) {
- delete tmp.icc;
- tmp.icc = 0;
- dirty = true;
- _fixupHit( 0, this );
- } else {
-#ifdef DEBUG_LCMS
- g_message("No icc to nuke");
-#endif // DEBUG_LCMS
- }
- }
-
- if ( dirty ) {
-#ifdef DEBUG_LCMS
- g_message("+----------------");
- g_message("+ new color is [%s]", tmp.toString().c_str());
-#endif // DEBUG_LCMS
- _setProfile( tmp.icc );
- //_adjustmentChanged( _compUI[0]._adj, SP_COLOR_ICC_SELECTOR(_csel) );
- _owner->setColorAlpha( tmp, _owner->_alpha, true );
-#ifdef DEBUG_LCMS
- g_message("+_________________");
-#endif // DEBUG_LCMS
- }
-}
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-void ColorICCSelectorImpl::_profilesChanged( std::string const & name )
-{
- GtkComboBox* combo = GTK_COMBO_BOX(_profileSel);
-
- g_signal_handler_block( G_OBJECT(_profileSel), _profChangedID );
-
- GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(combo));
- gtk_list_store_clear(store);
-
- GtkTreeIter iter;
- gtk_list_store_append (store, &iter);
- gtk_list_store_set(store, &iter, 0, _("<none>"), 1, _("<none>"), -1);
-
- gtk_combo_box_set_active( combo, 0 );
-
- int index = 1;
- const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "iccprofile" );
- while ( current ) {
- SPObject* obj = SP_OBJECT(current->data);
- Inkscape::ColorProfile* prof = reinterpret_cast<Inkscape::ColorProfile*>(obj);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set(store, &iter, 0, gr_ellipsize_text(prof->name, 25).c_str(), 1, prof->name, -1);
-
- if ( name == prof->name ) {
- gtk_combo_box_set_active( combo, index );
- gtk_widget_set_tooltip_text(_profileSel, prof->name );
- }
-
- index++;
- current = g_slist_next(current);
- }
-
- g_signal_handler_unblock( G_OBJECT(_profileSel), _profChangedID );
-}
-#else
-void ColorICCSelectorImpl::_profilesChanged( std::string const & /*name*/ )
-{
-}
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
-// Helpers for setting color value
-
-void ColorICCSelector::_colorChanged()
-{
- _impl->_updating = TRUE;
- //sp_color_icc_set_color( SP_COLOR_ICC( _icc ), &color );
-
-#ifdef DEBUG_LCMS
- g_message( "/^^^^^^^^^ %p::_colorChanged(%08x:%s)", this,
- _color.toRGBA32(_alpha), ( (_color.icc) ? _color.icc->colorProfile.c_str(): "<null>" )
- );
-#endif // DEBUG_LCMS
-
-#ifdef DEBUG_LCMS
- g_message("FLIPPIES!!!! %p '%s'", _color.icc, (_color.icc ? _color.icc->colorProfile.c_str():"<null>"));
-#endif // DEBUG_LCMS
-
- _impl->_profilesChanged( (_color.icc) ? _color.icc->colorProfile : std::string("") );
- ColorScales::setScaled( _impl->_adj, _alpha );
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- _impl->_setProfile( _color.icc );
- _impl->_fixupNeeded = 0;
- gtk_widget_set_sensitive( _impl->_fixupBtn, FALSE );
-
- if (_impl->_prof) {
- if (_impl->_prof->getTransfToSRGB8() ) {
- cmsUInt16Number tmp[4];
- for ( guint i = 0; i < _impl->_profChannelCount; i++ ) {
- gdouble val = 0.0;
- if ( _color.icc->colors.size() > i ) {
- if ( _impl->_compUI[i]._component.scale == 256 ) {
- val = (_color.icc->colors[i] + 128.0) / static_cast<gdouble>(_impl->_compUI[i]._component.scale);
- } else {
- val = _color.icc->colors[i] / static_cast<gdouble>(_impl->_compUI[i]._component.scale);
- }
- }
- tmp[i] = val * 0x0ffff;
- }
- guchar post[4] = {0,0,0,0};
- cmsHTRANSFORM trans = _impl->_prof->getTransfToSRGB8();
- if ( trans ) {
- cmsDoTransform( trans, tmp, post, 1 );
- guint32 other = SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255 );
- if ( other != _color.toRGBA32(255) ) {
- _impl->_fixupNeeded = other;
- gtk_widget_set_sensitive( _impl->_fixupBtn, TRUE );
-#ifdef DEBUG_LCMS
- g_message("Color needs to change 0x%06x to 0x%06x", _color.toRGBA32(255) >> 8, other >> 8 );
-#endif // DEBUG_LCMS
- }
- }
- }
- }
-#else
- //(void)color;
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- _impl->_updateSliders( -1 );
-
-
- _impl->_updating = FALSE;
-#ifdef DEBUG_LCMS
- g_message( "\\_________ %p::_colorChanged()", this );
-#endif // DEBUG_LCMS
-}
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-void ColorICCSelectorImpl::_setProfile( SVGICCColor* profile )
-{
-#ifdef DEBUG_LCMS
- g_message( "/^^^^^^^^^ %p::_setProfile(%s)", this,
- ( (profile) ? profile->colorProfile.c_str() : "<null>")
- );
-#endif // DEBUG_LCMS
- bool profChanged = false;
- if ( _prof && (!profile || (_profileName != profile->colorProfile) ) ) {
- // Need to clear out the prior one
- profChanged = true;
- _profileName.clear();
- _prof = 0;
- _profChannelCount = 0;
- } else if ( profile && !_prof ) {
- profChanged = true;
- }
-
- for ( size_t i = 0; i < _compUI.size(); i++ ) {
- gtk_widget_hide( _compUI[i]._label );
- gtk_widget_hide( _compUI[i]._slider );
- gtk_widget_hide( _compUI[i]._btn );
- }
-
- if ( profile ) {
- _prof = SP_ACTIVE_DOCUMENT->profileManager->find(profile->colorProfile.c_str());
- if ( _prof && (asICColorProfileClassSig(_prof->getProfileClass()) != cmsSigNamedColorClass) ) {
-#if HAVE_LIBLCMS1
- _profChannelCount = _cmsChannelsOf( asICColorSpaceSig(_prof->getColorSpace()) );
-#elif HAVE_LIBLCMS2
- _profChannelCount = cmsChannelsOf( asICColorSpaceSig(_prof->getColorSpace()) );
-#endif
-
- if ( profChanged ) {
- std::vector<colorspace::Component> things = colorspace::getColorSpaceInfo(asICColorSpaceSig(_prof->getColorSpace()));
- for (size_t i = 0; (i < things.size()) && (i < _profChannelCount); ++i)
- {
- _compUI[i]._component = things[i];
- }
-
- for ( guint i = 0; i < _profChannelCount; i++ ) {
- gtk_label_set_text_with_mnemonic( GTK_LABEL(_compUI[i]._label), (i < things.size()) ? things[i].name.c_str() : "");
-
- gtk_widget_set_tooltip_text( _compUI[i]._slider, (i < things.size()) ? things[i].tip.c_str() : "" );
- gtk_widget_set_tooltip_text( _compUI[i]._btn, (i < things.size()) ? things[i].tip.c_str() : "" );
-
- sp_color_slider_set_colors( SP_COLOR_SLIDER(_compUI[i]._slider),
- SPColor(0.0, 0.0, 0.0).toRGBA32(0xff),
- SPColor(0.5, 0.5, 0.5).toRGBA32(0xff),
- SPColor(1.0, 1.0, 1.0).toRGBA32(0xff) );
-/*
- _compUI[i]._adj = GTK_ADJUSTMENT( gtk_adjustment_new( val, 0.0, _fooScales[i], step, page, page ) );
- g_signal_connect( G_OBJECT( _compUI[i]._adj ), "value_changed", G_CALLBACK( _adjustmentChanged ), _csel );
-
- sp_color_slider_set_adjustment( SP_COLOR_SLIDER(_compUI[i]._slider), _compUI[i]._adj );
- gtk_spin_button_set_adjustment( GTK_SPIN_BUTTON(_compUI[i]._btn), _compUI[i]._adj );
- gtk_spin_button_set_digits( GTK_SPIN_BUTTON(_compUI[i]._btn), digits );
-*/
- gtk_widget_show( _compUI[i]._label );
- gtk_widget_show( _compUI[i]._slider );
- gtk_widget_show( _compUI[i]._btn );
- //gtk_adjustment_set_value( _compUI[i]._adj, 0.0 );
- //gtk_adjustment_set_value( _compUI[i]._adj, val );
- }
- for ( size_t i = _profChannelCount; i < _compUI.size(); i++ ) {
- gtk_widget_hide( _compUI[i]._label );
- gtk_widget_hide( _compUI[i]._slider );
- gtk_widget_hide( _compUI[i]._btn );
- }
- }
- } else {
- // Give up for now on named colors
- _prof = 0;
- }
- }
-
-#ifdef DEBUG_LCMS
- g_message( "\\_________ %p::_setProfile()", this );
-#endif // DEBUG_LCMS
-}
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
-void ColorICCSelectorImpl::_updateSliders( gint ignore )
-{
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- if ( _owner->_color.icc )
- {
- for ( guint i = 0; i < _profChannelCount; i++ ) {
- gdouble val = 0.0;
- if ( _owner->_color.icc->colors.size() > i ) {
- if ( _compUI[i]._component.scale == 256 ) {
- val = (_owner->_color.icc->colors[i] + 128.0) / static_cast<gdouble>(_compUI[i]._component.scale);
- } else {
- val = _owner->_color.icc->colors[i] / static_cast<gdouble>(_compUI[i]._component.scale);
- }
- }
- gtk_adjustment_set_value( _compUI[i]._adj, val );
- }
-
- if ( _prof ) {
- if ( _prof->getTransfToSRGB8() ) {
- for ( guint i = 0; i < _profChannelCount; i++ ) {
- if ( static_cast<gint>(i) != ignore ) {
- cmsUInt16Number* scratch = getScratch();
- cmsUInt16Number filler[4] = {0, 0, 0, 0};
- for ( guint j = 0; j < _profChannelCount; j++ ) {
- filler[j] = 0x0ffff * ColorScales::getScaled( _compUI[j]._adj );
- }
-
- cmsUInt16Number* p = scratch;
- for ( guint x = 0; x < 1024; x++ ) {
- for ( guint j = 0; j < _profChannelCount; j++ ) {
- if ( j == i ) {
- *p++ = x * 0x0ffff / 1024;
- } else {
- *p++ = filler[j];
- }
- }
- }
-
- cmsHTRANSFORM trans = _prof->getTransfToSRGB8();
- if ( trans ) {
- cmsDoTransform( trans, scratch, _compUI[i]._map, 1024 );
- sp_color_slider_set_map( SP_COLOR_SLIDER(_compUI[i]._slider), _compUI[i]._map );
- }
- }
- }
- }
- }
- }
-#else
- (void)ignore;
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
- guint32 start = _owner->_color.toRGBA32( 0x00 );
- guint32 mid = _owner->_color.toRGBA32( 0x7f );
- guint32 end = _owner->_color.toRGBA32( 0xff );
-
- sp_color_slider_set_colors( SP_COLOR_SLIDER(_slider), start, mid, end );
-}
-
-
-void ColorICCSelectorImpl::_adjustmentChanged( GtkAdjustment *adjustment, SPColorICCSelector *cs )
-{
-// // TODO check this. It looks questionable:
-// // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255 or 0..100
-// if (adjustment->value > 0.0 && adjustment->value < 1.0) {
-// gtk_adjustment_set_value( adjustment, floor ((adjustment->value) * adjustment->upper + 0.5) );
-// }
-
-#ifdef DEBUG_LCMS
- g_message( "/^^^^^^^^^ %p::_adjustmentChanged()", cs );
-#endif // DEBUG_LCMS
-
- ColorICCSelector* iccSelector = static_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base);
- if (iccSelector->_impl->_updating) {
- return;
- }
-
- iccSelector->_impl->_updating = TRUE;
-
- gint match = -1;
-
- SPColor newColor( iccSelector->_color );
- gfloat scaled = ColorScales::getScaled( iccSelector->_impl->_adj );
- if ( iccSelector->_impl->_adj == adjustment ) {
-#ifdef DEBUG_LCMS
- g_message("ALPHA");
-#endif // DEBUG_LCMS
- } else {
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- for ( size_t i = 0; i < iccSelector->_impl->_compUI.size(); i++ ) {
- if ( iccSelector->_impl->_compUI[i]._adj == adjustment ) {
- match = i;
- break;
- }
- }
- if ( match >= 0 ) {
-#ifdef DEBUG_LCMS
- g_message(" channel %d", match );
-#endif // DEBUG_LCMS
- }
-
-
- cmsUInt16Number tmp[4];
- for ( guint i = 0; i < 4; i++ ) {
- tmp[i] = ColorScales::getScaled( iccSelector->_impl->_compUI[i]._adj ) * 0x0ffff;
- }
- guchar post[4] = {0,0,0,0};
-
- cmsHTRANSFORM trans = iccSelector->_impl->_prof->getTransfToSRGB8();
- if ( trans ) {
- cmsDoTransform( trans, tmp, post, 1 );
- }
-
- SPColor other( SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255) );
- other.icc = new SVGICCColor();
- if ( iccSelector->_color.icc ) {
- other.icc->colorProfile = iccSelector->_color.icc->colorProfile;
- }
-
- guint32 prior = iccSelector->_color.toRGBA32(255);
- guint32 newer = other.toRGBA32(255);
-
- if ( prior != newer ) {
-#ifdef DEBUG_LCMS
- g_message("Transformed color from 0x%08x to 0x%08x", prior, newer );
- g_message(" ~~~~ FLIP");
-#endif // DEBUG_LCMS
- newColor = other;
- newColor.icc->colors.clear();
- for ( guint i = 0; i < iccSelector->_impl->_profChannelCount; i++ ) {
- gdouble val = ColorScales::getScaled( iccSelector->_impl->_compUI[i]._adj );
- val *= iccSelector->_impl->_compUI[i]._component.scale;
- if ( iccSelector->_impl->_compUI[i]._component.scale == 256 ) {
- val -= 128;
- }
- newColor.icc->colors.push_back( val );
- }
- }
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- }
- iccSelector->_updateInternals( newColor, scaled, iccSelector->_impl->_dragging );
- iccSelector->_impl->_updateSliders( match );
-
- iccSelector->_impl->_updating = FALSE;
-#ifdef DEBUG_LCMS
- g_message( "\\_________ %p::_adjustmentChanged()", cs );
-#endif // DEBUG_LCMS
-}
-
-void ColorICCSelectorImpl::_sliderGrabbed( SPColorSlider * /*slider*/, SPColorICCSelector * /*cs*/ )
-{
-// ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base);
-// if (!iccSelector->_dragging) {
-// iccSelector->_dragging = TRUE;
-// iccSelector->_grabbed();
-// iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_impl->_adj ), iccSelector->_dragging );
-// }
-}
-
-void ColorICCSelectorImpl::_sliderReleased( SPColorSlider * /*slider*/, SPColorICCSelector * /*cs*/ )
-{
-// ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base);
-// if (iccSelector->_dragging) {
-// iccSelector->_dragging = FALSE;
-// iccSelector->_released();
-// iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), iccSelector->_dragging );
-// }
-}
-
-#ifdef DEBUG_LCMS
-void ColorICCSelectorImpl::_sliderChanged( SPColorSlider *slider, SPColorICCSelector *cs )
-#else
-void ColorICCSelectorImpl::_sliderChanged( SPColorSlider * /*slider*/, SPColorICCSelector * /*cs*/ )
-#endif // DEBUG_LCMS
-{
-#ifdef DEBUG_LCMS
- g_message("Changed %p and %p", slider, cs );
-#endif // DEBUG_LCMS
-// ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base);
-
-// iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), iccSelector->_dragging );
-}
-
-
-/*
- 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/widgets/sp-color-icc-selector.h b/src/widgets/sp-color-icc-selector.h
deleted file mode 100644
index 6cdaff639..000000000
--- a/src/widgets/sp-color-icc-selector.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef SEEN_SP_COLOR_ICC_SELECTOR_H
-#define SEEN_SP_COLOR_ICC_SELECTOR_H
-
-#include <glib.h>
-#include "sp-color-selector.h"
-
-namespace Inkscape {
-class ColorProfile;
-}
-
-struct SPColorICCSelector;
-struct SPColorICCSelectorClass;
-
-class ColorICCSelectorImpl;
-
-class ColorICCSelector: public ColorSelector
-{
-public:
- ColorICCSelector( SPColorSelector* csel );
- virtual ~ColorICCSelector();
-
- virtual void init();
-
-protected:
- virtual void _colorChanged();
-
- void _recalcColor( gboolean changing );
-
-private:
- friend class ColorICCSelectorImpl;
-
- // By default, disallow copy constructor and assignment operator
- ColorICCSelector( const ColorICCSelector& obj );
- ColorICCSelector& operator=( const ColorICCSelector& obj );
-
- ColorICCSelectorImpl *_impl;
-};
-
-
-
-#define SP_TYPE_COLOR_ICC_SELECTOR (sp_color_icc_selector_get_type())
-#define SP_COLOR_ICC_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_COLOR_ICC_SELECTOR, SPColorICCSelector))
-#define SP_COLOR_ICC_SELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SP_TYPE_COLOR_ICC_SELECTOR, SPColorICCSelectorClass))
-#define SP_IS_COLOR_ICC_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_COLOR_ICC_SELECTOR))
-#define SP_IS_COLOR_ICC_SELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_COLOR_ICC_SELECTOR))
-
-struct SPColorICCSelector {
- SPColorSelector parent;
-};
-
-struct SPColorICCSelectorClass {
- SPColorSelectorClass parent_class;
-};
-
-GType sp_color_icc_selector_get_type(void);
-
-GtkWidget *sp_color_icc_selector_new(void);
-
-
-
-#endif // SEEN_SP_COLOR_ICC_SELECTOR_H
-
-/*
- 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp
deleted file mode 100644
index c7fa96efd..000000000
--- a/src/widgets/sp-color-notebook.cpp
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
- * A notebook with RGB, CMYK, CMS, HSL, and Wheel pages
- *
- * Author:
- * Lauris Kaplinski <lauris@kaplinski.com>
- * bulia byak <buliabyak@users.sf.net>
- *
- * Copyright (C) 2001-2002 Lauris Kaplinski
- *
- * This code is in public domain
- */
-
-#undef SPCS_PREVIEW
-#define noDUMP_CHANGE_INFO
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "widgets/icon.h"
-#include <cstring>
-#include <string>
-#include <cstdlib>
-#include <cstddef>
-#include <gtk/gtk.h>
-#include <glibmm/i18n.h>
-
-#include "ui/dialog-events.h"
-#include "../preferences.h"
-#include "sp-color-notebook.h"
-#include "spw-utilities.h"
-#include "sp-color-scales.h"
-#include "sp-color-icc-selector.h"
-#include "sp-color-wheel-selector.h"
-#include "svg/svg-icc-color.h"
-#include "../inkscape.h"
-#include "../document.h"
-#include "../profile-manager.h"
-#include "color-profile.h"
-#include "cms-system.h"
-#include "ui/tools-switch.h"
-#include "ui/tools/tool-base.h"
-
-using Inkscape::CMSSystem;
-
-struct SPColorNotebookTracker {
- const gchar* name;
- const gchar* className;
- GType type;
- guint submode;
- gboolean enabledFull;
- gboolean enabledBrief;
- SPColorNotebook *backPointer;
-};
-
-static void sp_color_notebook_dispose(GObject *object);
-
-static void sp_color_notebook_show_all (GtkWidget *widget);
-static void sp_color_notebook_hide(GtkWidget *widget);
-
-#define XPAD 4
-#define YPAD 1
-
-G_DEFINE_TYPE(SPColorNotebook, sp_color_notebook, SP_TYPE_COLOR_SELECTOR);
-
-static void sp_color_notebook_class_init(SPColorNotebookClass *klass)
-{
- GObjectClass *object_class = reinterpret_cast<GObjectClass *>(klass);
- GtkWidgetClass *widget_class = reinterpret_cast<GtkWidgetClass *>(klass);
-
- object_class->dispose = sp_color_notebook_dispose;
-
- widget_class->show_all = sp_color_notebook_show_all;
- widget_class->hide = sp_color_notebook_hide;
-}
-
-static void
-sp_color_notebook_switch_page(GtkNotebook *notebook,
- GtkWidget *page,
- guint page_num,
- SPColorNotebook *colorbook)
-{
- if ( colorbook )
- {
- ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base);
- nb->switchPage( notebook, page, page_num );
-
- // remember the page we switched to
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setInt("/colorselector/page", page_num);
- }
-}
-
-void ColorNotebook::switchPage(GtkNotebook*,
- GtkWidget*,
- guint page_num)
-{
- SPColorSelector* csel;
- GtkWidget* widget;
-
- if ( gtk_notebook_get_current_page (GTK_NOTEBOOK (_book)) >= 0 )
- {
- csel = getCurrentSelector();
- csel->base->getColorAlpha(_color, _alpha);
- }
- widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (_book), page_num);
- if ( widget && SP_IS_COLOR_SELECTOR(widget) )
- {
- csel = SP_COLOR_SELECTOR (widget);
- csel->base->setColorAlpha( _color, _alpha );
-
- // Temporary workaround to undo a spurious GRABBED
- _released();
- }
-}
-
-static gint sp_color_notebook_menu_handler( GtkWidget *widget, GdkEvent *event )
-{
- if (event->type == GDK_BUTTON_PRESS)
- {
- SPColorSelector* csel = SP_COLOR_SELECTOR(widget);
- (dynamic_cast<ColorNotebook*>(csel->base))->menuHandler( event );
-
- /* Tell calling code that we have handled this event; the buck
- * stops here. */
- return TRUE;
- }
-
- /* Tell calling code that we have not handled this event; pass it on. */
- return FALSE;
-}
-
-gint ColorNotebook::menuHandler( GdkEvent* event )
-{
- GdkEventButton *bevent = (GdkEventButton *) event;
- gtk_menu_popup (GTK_MENU( _popup ), NULL, NULL, NULL, NULL,
- bevent->button, bevent->time);
- return TRUE;
-}
-
-static void sp_color_notebook_menuitem_response (GtkMenuItem *menuitem, gpointer user_data)
-{
- gboolean active = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem));
- SPColorNotebookTracker *entry = reinterpret_cast< SPColorNotebookTracker* > (user_data);
- if ( entry )
- {
- if ( active )
- {
- (dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(entry->backPointer)->base))->addPage(entry->type, entry->submode);
- }
- else
- {
- (dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(entry->backPointer)->base))->removePage(entry->type, entry->submode);
- }
- }
-}
-
-static void
-sp_color_notebook_init (SPColorNotebook *colorbook)
-{
- SP_COLOR_SELECTOR(colorbook)->base = new ColorNotebook( SP_COLOR_SELECTOR(colorbook) );
-
- if ( SP_COLOR_SELECTOR(colorbook)->base )
- {
- SP_COLOR_SELECTOR(colorbook)->base->init();
- }
-}
-
-void ColorNotebook::init()
-{
- guint row = 0;
- guint i = 0;
- guint j = 0;
- GType *selector_types = 0;
- guint selector_type_count = 0;
-
- /* tempory hardcoding to get types loaded */
- SP_TYPE_COLOR_SCALES;
- SP_TYPE_COLOR_WHEEL_SELECTOR;
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- SP_TYPE_COLOR_ICC_SELECTOR;
-#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
- /* REJON: Comment out the next line to not use the normal GTK Color
- wheel. */
-
-// SP_TYPE_COLOR_GTKSELECTOR;
-
- _updating = FALSE;
- _updatingrgba = FALSE;
- _btn = 0;
- _popup = 0;
- _trackerList = g_ptr_array_new ();
-
- _book = gtk_notebook_new ();
- gtk_widget_show (_book);
-
- // Dont show the notebook tabs, use radiobuttons instead
- gtk_notebook_set_show_border (GTK_NOTEBOOK (_book), false);
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (_book), false);
-
- selector_types = g_type_children (SP_TYPE_COLOR_SELECTOR, &selector_type_count);
-
- for ( i = 0; i < selector_type_count; i++ )
- {
- if (!g_type_is_a (selector_types[i], SP_TYPE_COLOR_NOTEBOOK))
- {
- guint howmany = 1;
- gpointer klass = g_type_class_ref (selector_types[i]);
- if ( klass && SP_IS_COLOR_SELECTOR_CLASS(klass) )
- {
- SPColorSelectorClass *ck = SP_COLOR_SELECTOR_CLASS (klass);
- howmany = MAX (1, ck->submode_count);
- for ( j = 0; j < howmany; j++ )
- {
- SPColorNotebookTracker *entry = reinterpret_cast< SPColorNotebookTracker* > (malloc(sizeof(SPColorNotebookTracker)));
- if ( entry )
- {
- memset( entry, 0, sizeof(SPColorNotebookTracker) );
- entry->name = ck->name[j];
- entry->type = selector_types[i];
- entry->submode = j;
- entry->enabledFull = TRUE;
- entry->enabledBrief = TRUE;
- entry->backPointer = SP_COLOR_NOTEBOOK(_csel);
-
- g_ptr_array_add (_trackerList, entry);
- }
- }
- }
- }
- }
-
-#if GTK_CHECK_VERSION(3,0,0)
- _buttonbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
- gtk_box_set_homogeneous(GTK_BOX(_buttonbox), TRUE);
-#else
- _buttonbox = gtk_hbox_new (TRUE, 2);
-#endif
-
- gtk_widget_show (_buttonbox);
- _buttons = new GtkWidget *[_trackerList->len];
-
- for ( i = 0; i < _trackerList->len; i++ )
- {
- SPColorNotebookTracker *entry =
- reinterpret_cast< SPColorNotebookTracker* > (g_ptr_array_index (_trackerList, i));
- if ( entry )
- {
- addPage(entry->type, entry->submode);
- }
- }
-
-#if GTK_CHECK_VERSION(3,0,0)
- GtkWidget* table = gtk_grid_new();
-#else
- GtkWidget* table = gtk_table_new(2, 3, FALSE);
-#endif
-
- gtk_widget_show (table);
-
- gtk_box_pack_start (GTK_BOX (_csel), table, TRUE, TRUE, 0);
-
- sp_set_font_size_smaller (_buttonbox);
-
-#if GTK_CHECK_VERSION(3,0,0)
- #if GTK_CHECK_VERSION(3,12,0)
- gtk_widget_set_margin_start(_buttonbox, XPAD);
- gtk_widget_set_margin_end(_buttonbox, XPAD);
- #else
- gtk_widget_set_margin_left(_buttonbox, XPAD);
- gtk_widget_set_margin_right(_buttonbox, XPAD);
- #endif
- gtk_widget_set_margin_top(_buttonbox, YPAD);
- gtk_widget_set_margin_bottom(_buttonbox, YPAD);
- gtk_widget_set_hexpand(_buttonbox, TRUE);
- gtk_widget_set_valign(_buttonbox, GTK_ALIGN_CENTER);
- gtk_grid_attach(GTK_GRID(table), _buttonbox, 0, row, 2, 1);
-#else
- gtk_table_attach (GTK_TABLE (table), _buttonbox, 0, 2, row, row + 1,
- static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL),
- static_cast<GtkAttachOptions>(0),
- XPAD, YPAD);
-#endif
-
- row++;
-
-#if GTK_CHECK_VERSION(3,0,0)
- #if GTK_CHECK_VERSION(3,12,0)
- gtk_widget_set_margin_start(_book, XPAD*2);
- gtk_widget_set_margin_end(_book, XPAD*2);
- #else
- gtk_widget_set_margin_left(_book, XPAD*2);
- gtk_widget_set_margin_right(_book, XPAD*2);
- #endif
- gtk_widget_set_margin_top(_book, YPAD);
- gtk_widget_set_margin_bottom(_book, YPAD);
- gtk_widget_set_hexpand(_book, TRUE);
- gtk_widget_set_vexpand(_book, TRUE);
- gtk_grid_attach(GTK_GRID(table), _book, 0, row, 2, 1);
-#else
- gtk_table_attach (GTK_TABLE (table), _book, 0, 2, row, row + 1,
- static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL),
- static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL),
- XPAD*2, YPAD);
-#endif
-
- // restore the last active page
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- _setCurrentPage(prefs->getInt("/colorselector/page", 0));
-
- {
- gboolean found = FALSE;
-
- _popup = gtk_menu_new();
- GtkMenu *menu = GTK_MENU (_popup);
-
- for ( i = 0; i < _trackerList->len; i++ )
- {
- SPColorNotebookTracker *entry = reinterpret_cast< SPColorNotebookTracker* > (g_ptr_array_index (_trackerList, i));
- if ( entry )
- {
- GtkWidget *item = gtk_check_menu_item_new_with_label (_(entry->name));
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), entry->enabledFull);
- gtk_widget_show (item);
- gtk_menu_shell_append (GTK_MENU_SHELL(menu), item);
-
- g_signal_connect (G_OBJECT (item), "activate",
- G_CALLBACK (sp_color_notebook_menuitem_response),
- reinterpret_cast< gpointer > (entry) );
- found = TRUE;
- }
- }
-
- GtkWidget *arrow = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
- gtk_widget_show (arrow);
-
- _btn = gtk_button_new ();
- gtk_widget_show (_btn);
- gtk_container_add (GTK_CONTAINER (_btn), arrow);
-
- GtkWidget *align = gtk_alignment_new (1.0, 0.0, 0.0, 0.0);
- gtk_widget_show (align);
- gtk_container_add (GTK_CONTAINER (align), _btn);
-
- // uncomment to reenable the "show/hide modes" menu,
- // but first fix it so it remembers its settings in prefs and does not take that much space (entire vertical column!)
- //gtk_table_attach (GTK_TABLE (table), align, 2, 3, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);
-
- g_signal_connect_swapped(G_OBJECT(_btn), "event", G_CALLBACK (sp_color_notebook_menu_handler), G_OBJECT(_csel));
- if ( !found )
- {
- gtk_widget_set_sensitive (_btn, FALSE);
- }
- }
-
- row++;
-
-#if GTK_CHECK_VERSION(3,0,0)
- GtkWidget *rgbabox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
-#else
- GtkWidget *rgbabox = gtk_hbox_new (FALSE, 0);
-#endif
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- /* Create color management icons */
- _box_colormanaged = gtk_event_box_new ();
- GtkWidget *colormanaged = gtk_image_new_from_icon_name ("color-management-icon", GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_container_add (GTK_CONTAINER (_box_colormanaged), colormanaged);
- gtk_widget_set_tooltip_text (_box_colormanaged, _("Color Managed"));
- gtk_widget_set_sensitive (_box_colormanaged, false);
- gtk_box_pack_start(GTK_BOX(rgbabox), _box_colormanaged, FALSE, FALSE, 2);
-
- _box_outofgamut = gtk_event_box_new ();
- GtkWidget *outofgamut = gtk_image_new_from_icon_name ("out-of-gamut-icon", GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_container_add (GTK_CONTAINER (_box_outofgamut), outofgamut);
- gtk_widget_set_tooltip_text (_box_outofgamut, _("Out of gamut!"));
- gtk_widget_set_sensitive (_box_outofgamut, false);
- gtk_box_pack_start(GTK_BOX(rgbabox), _box_outofgamut, FALSE, FALSE, 2);
-
- _box_toomuchink = gtk_event_box_new ();
- GtkWidget *toomuchink = gtk_image_new_from_icon_name ("too-much-ink-icon", GTK_ICON_SIZE_SMALL_TOOLBAR);
- gtk_container_add (GTK_CONTAINER (_box_toomuchink), toomuchink);
- gtk_widget_set_tooltip_text (_box_toomuchink, _("Too much ink!"));
- gtk_widget_set_sensitive (_box_toomuchink, false);
- gtk_box_pack_start(GTK_BOX(rgbabox), _box_toomuchink, FALSE, FALSE, 2);
-#endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
-
- /* Color picker */
- GtkWidget *picker = gtk_image_new_from_icon_name ("color-picker", GTK_ICON_SIZE_SMALL_TOOLBAR);
- _btn_picker = gtk_button_new ();
- gtk_button_set_relief(GTK_BUTTON(_btn_picker), GTK_RELIEF_NONE);
- gtk_widget_show (_btn);
- gtk_container_add (GTK_CONTAINER (_btn_picker), picker);
- gtk_widget_set_tooltip_text (_btn_picker, _("Pick colors from image"));
- gtk_box_pack_start(GTK_BOX(rgbabox), _btn_picker, FALSE, FALSE, 2);
- g_signal_connect(G_OBJECT(_btn_picker), "clicked", G_CALLBACK(ColorNotebook::_picker_clicked), _csel);
-
- /* Create RGBA entry and color preview */
- _rgbal = gtk_label_new_with_mnemonic (_("RGBA_:"));
- gtk_misc_set_alignment (GTK_MISC (_rgbal), 1.0, 0.5);
- gtk_box_pack_start(GTK_BOX(rgbabox), _rgbal, TRUE, TRUE, 2);
-
- _rgbae = gtk_entry_new ();
- sp_dialog_defocus_on_enter (_rgbae);
- gtk_entry_set_max_length (GTK_ENTRY (_rgbae), 8);
- gtk_entry_set_width_chars (GTK_ENTRY (_rgbae), 8);
- gtk_widget_set_tooltip_text (_rgbae, _("Hexadecimal RGBA value of the color"));
- gtk_box_pack_start(GTK_BOX(rgbabox), _rgbae, FALSE, FALSE, 0);
- gtk_label_set_mnemonic_widget (GTK_LABEL(_rgbal), _rgbae);
-
- sp_set_font_size_smaller (rgbabox);
- gtk_widget_show_all (rgbabox);
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- //the "too much ink" icon is initially hidden
- gtk_widget_hide(GTK_WIDGET(_box_toomuchink));
-#endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
-#if GTK_CHECK_VERSION(3,0,0)
- #if GTK_CHECK_VERSION(3,12,0)
- gtk_widget_set_margin_start(rgbabox, XPAD);
- gtk_widget_set_margin_end(rgbabox, XPAD);
- #else
- gtk_widget_set_margin_left(rgbabox, XPAD);
- gtk_widget_set_margin_right(rgbabox, XPAD);
- #endif
- gtk_widget_set_margin_top(rgbabox, YPAD);
- gtk_widget_set_margin_bottom(rgbabox, YPAD);
- gtk_grid_attach(GTK_GRID(table), rgbabox, 0, row, 2, 1);
-#else
- gtk_table_attach (GTK_TABLE (table), rgbabox, 0, 2, row, row + 1, GTK_FILL, GTK_SHRINK, XPAD, YPAD);
-#endif
-
-#ifdef SPCS_PREVIEW
- _p = sp_color_preview_new (0xffffffff);
- gtk_widget_show (_p);
- gtk_table_attach (GTK_TABLE (table), _p, 2, 3, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);
-#endif
-
- _switchId = g_signal_connect(G_OBJECT (_book), "switch-page",
- G_CALLBACK (sp_color_notebook_switch_page), SP_COLOR_NOTEBOOK(_csel));
-
- _entryId = g_signal_connect (G_OBJECT (_rgbae), "changed", G_CALLBACK (ColorNotebook::_rgbaEntryChangedHook), _csel);
-}
-
-static void sp_color_notebook_dispose(GObject *object)
-{
- if (G_OBJECT_CLASS(sp_color_notebook_parent_class)->dispose)
- G_OBJECT_CLASS(sp_color_notebook_parent_class)->dispose(object);
-}
-
-ColorNotebook::~ColorNotebook()
-{
- if ( _trackerList )
- {
- g_ptr_array_free (_trackerList, TRUE);
- _trackerList = 0;
- }
-
- if ( _switchId )
- {
- if ( _book )
- {
- g_signal_handler_disconnect (_book, _switchId);
- _switchId = 0;
- }
- }
-
- if ( _buttons )
- {
- delete [] _buttons;
- _buttons = 0;
- }
-
-}
-
-static void
-sp_color_notebook_show_all (GtkWidget *widget)
-{
- gtk_widget_show (widget);
-}
-
-static void sp_color_notebook_hide(GtkWidget *widget)
-{
- gtk_widget_hide(widget);
-}
-
-GtkWidget *sp_color_notebook_new()
-{
- SPColorNotebook *colorbook = SP_COLOR_NOTEBOOK(g_object_new (SP_TYPE_COLOR_NOTEBOOK, NULL));
-
- return GTK_WIDGET(colorbook);
-}
-
-ColorNotebook::ColorNotebook( SPColorSelector* csel )
- : ColorSelector( csel )
-{
-}
-
-SPColorSelector* ColorNotebook::getCurrentSelector()
-{
- SPColorSelector* csel = NULL;
- gint current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (_book));
-
- if ( current_page >= 0 )
- {
- GtkWidget* widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (_book), current_page);
- if ( SP_IS_COLOR_SELECTOR (widget) )
- {
- csel = SP_COLOR_SELECTOR (widget);
- }
- }
-
- return csel;
-}
-
-void ColorNotebook::_colorChanged()
-{
- SPColorSelector* cselPage = getCurrentSelector();
- if ( cselPage )
- {
- cselPage->base->setColorAlpha( _color, _alpha );
- }
-
- _updateRgbaEntry( _color, _alpha );
-}
-
-void ColorNotebook::_picker_clicked(GtkWidget * /*widget*/, SPColorNotebook * /*colorbook*/)
-{
- // Set the dropper into a "one click" mode, so it reverts to the previous tool after a click
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setBool("/tools/dropper/onetimepick", true);
- Inkscape::UI::Tools::sp_toggle_dropper(SP_ACTIVE_DESKTOP);
-}
-
-void ColorNotebook::_rgbaEntryChangedHook(GtkEntry *entry, SPColorNotebook *colorbook)
-{
- (dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base))->_rgbaEntryChanged( entry );
-}
-
-void ColorNotebook::_rgbaEntryChanged(GtkEntry* entry)
-{
- if (_updating) return;
- if (_updatingrgba) return;
-
- const gchar *t = gtk_entry_get_text( entry );
-
- if (t) {
- Glib::ustring text = t;
- bool changed = false;
- if (!text.empty() && text[0] == '#') {
- changed = true;
- text.erase(0,1);
- if (text.size() == 6) {
- // it was a standard RGB hex
- unsigned int alph = SP_COLOR_F_TO_U(_alpha);
- gchar* tmp = g_strdup_printf("%02x", alph);
- text += tmp;
- g_free(tmp);
- }
- }
- gchar* str = g_strdup(text.c_str());
- gchar* end = 0;
- guint64 rgba = g_ascii_strtoull( str, &end, 16 );
- if ( end != str ) {
- ptrdiff_t len = end - str;
- if ( len < 8 ) {
- rgba = rgba << ( 4 * ( 8 - len ) );
- }
- _updatingrgba = TRUE;
- if ( changed ) {
- gtk_entry_set_text( entry, str );
- }
- SPColor color( rgba );
- setColorAlpha( color, SP_RGBA32_A_F(rgba), true );
- _updatingrgba = FALSE;
- }
- g_free(str);
- }
-}
-
-// TODO pass in param so as to avoid the need for SP_ACTIVE_DOCUMENT
-void ColorNotebook::_updateRgbaEntry( const SPColor& color, gfloat alpha )
-{
- g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) );
-
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- /* update color management icon*/
- gtk_widget_set_sensitive (_box_colormanaged, color.icc != NULL);
-
- /* update out-of-gamut icon */
- gtk_widget_set_sensitive (_box_outofgamut, false);
- if (color.icc){
- Inkscape::ColorProfile* target_profile = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str());
- if ( target_profile )
- gtk_widget_set_sensitive(_box_outofgamut, target_profile->GamutCheck(color));
- }
-
- /* update too-much-ink icon */
- gtk_widget_set_sensitive (_box_toomuchink, false);
- if (color.icc){
- Inkscape::ColorProfile* prof = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str());
- if ( prof && CMSSystem::isPrintColorSpace(prof) ) {
- gtk_widget_show(GTK_WIDGET(_box_toomuchink));
- double ink_sum = 0;
- for (unsigned int i=0; i<color.icc->colors.size(); i++){
- ink_sum += color.icc->colors[i];
- }
-
- /* Some literature states that when the sum of paint values exceed 320%, it is considered to be a satured color,
- which means the paper can get too wet due to an excessive ammount of ink. This may lead to several issues
- such as misalignment and poor quality of printing in general.*/
- if ( ink_sum > 3.2 )
- gtk_widget_set_sensitive (_box_toomuchink, true);
- } else {
- gtk_widget_hide(GTK_WIDGET(_box_toomuchink));
- }
- }
-#endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
-
- if ( !_updatingrgba )
- {
- gchar s[32];
- guint32 rgba;
-
- /* Update RGBA entry */
- rgba = color.toRGBA32( alpha );
-
- g_snprintf (s, 32, "%08x", rgba);
- const gchar* oldText = gtk_entry_get_text( GTK_ENTRY( _rgbae ) );
- if ( strcmp( oldText, s ) != 0 )
- {
- g_signal_handler_block( _rgbae, _entryId );
- gtk_entry_set_text( GTK_ENTRY(_rgbae), s );
- g_signal_handler_unblock( _rgbae, _entryId );
- }
- }
-}
-
-void ColorNotebook::_setCurrentPage(int i)
-{
- gtk_notebook_set_current_page(GTK_NOTEBOOK(_book), i);
-
- if (_buttons && _trackerList && (static_cast<size_t>(i) < _trackerList->len) ) {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_buttons[i]), TRUE);
- }
-}
-
-void ColorNotebook::_buttonClicked(GtkWidget *widget, SPColorNotebook *colorbook)
-{
- ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base);
-
- if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget))) {
- return;
- }
-
- for(gint i = 0; i < gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb->_book)); i++) {
- if (nb->_buttons[i] == widget) {
- gtk_notebook_set_current_page (GTK_NOTEBOOK (nb->_book), i);
- }
- }
-}
-
-void ColorNotebook::_entryGrabbed (SPColorSelector *, SPColorNotebook *colorbook)
-{
- ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base);
- nb->_grabbed();
-}
-
-void ColorNotebook::_entryDragged (SPColorSelector *csel, SPColorNotebook *colorbook)
-{
- gboolean oldState;
- ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base);
-
- oldState = nb->_dragging;
-
- nb->_dragging = TRUE;
- nb->_entryModified( csel, colorbook );
-
- nb->_dragging = oldState;
-}
-
-void ColorNotebook::_entryReleased (SPColorSelector *, SPColorNotebook *colorbook)
-{
- ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base);
- nb->_released();
-}
-
-void ColorNotebook::_entryChanged (SPColorSelector *csel, SPColorNotebook *colorbook)
-{
- gboolean oldState;
- ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base);
-
- oldState = nb->_dragging;
-
- nb->_dragging = FALSE;
- nb->_entryModified( csel, colorbook );
-
- nb->_dragging = oldState;
-}
-
-void ColorNotebook::_entryModified (SPColorSelector *csel, SPColorNotebook *colorbook)
-{
- g_return_if_fail (colorbook != NULL);
- g_return_if_fail (SP_IS_COLOR_NOTEBOOK (colorbook));
- g_return_if_fail (csel != NULL);
- g_return_if_fail (SP_IS_COLOR_SELECTOR (csel));
-
- ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base);
- SPColor color;
- gfloat alpha = 1.0;
-
- csel->base->getColorAlpha( color, alpha );
- nb->_updateRgbaEntry( color, alpha );
- nb->_updateInternals( color, alpha, nb->_dragging );
-}
-
-GtkWidget* ColorNotebook::addPage(GType page_type, guint submode)
-{
- GtkWidget *page;
-
- page = sp_color_selector_new( page_type );
- if ( page )
- {
- GtkWidget* tab_label = 0;
- SPColorSelector* csel;
-
- csel = SP_COLOR_SELECTOR (page);
- if ( submode > 0 )
- {
- csel->base->setSubmode( submode );
- }
- gtk_widget_show (page);
- int index = csel->base ? csel->base->getSubmode() : 0;
- const gchar* str = _(SP_COLOR_SELECTOR_GET_CLASS (csel)->name[index]);
-// g_message( "Hitting up for tab for '%s'", str );
- tab_label = gtk_label_new(_(str));
- gint pageNum = gtk_notebook_append_page( GTK_NOTEBOOK (_book), page, tab_label );
-
- // Add a button for each page
- _buttons[pageNum] = gtk_radio_button_new_with_label(NULL, _(str));
- gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(_buttons[pageNum]), FALSE);
- if (pageNum > 0) {
- GSList *group = gtk_radio_button_get_group (GTK_RADIO_BUTTON(_buttons[0]));
- gtk_radio_button_set_group (GTK_RADIO_BUTTON(_buttons[pageNum]), group);
- }
- gtk_widget_show (_buttons[pageNum]);
- gtk_box_pack_start (GTK_BOX (_buttonbox), _buttons[pageNum], TRUE, TRUE, 0);
-
- g_signal_connect (G_OBJECT (_buttons[pageNum]), "clicked", G_CALLBACK (_buttonClicked), _csel);
- g_signal_connect (G_OBJECT (page), "grabbed", G_CALLBACK (_entryGrabbed), _csel);
- g_signal_connect (G_OBJECT (page), "dragged", G_CALLBACK (_entryDragged), _csel);
- g_signal_connect (G_OBJECT (page), "released", G_CALLBACK (_entryReleased), _csel);
- g_signal_connect (G_OBJECT (page), "changed", G_CALLBACK (_entryChanged), _csel);
- }
-
- return page;
-}
-
-GtkWidget* ColorNotebook::getPage(GType page_type, guint submode)
-{
- gint count = 0;
- gint i = 0;
- GtkWidget* page = 0;
-
-// count = gtk_notebook_get_n_pages (_book);
- count = 200;
- for ( i = 0; i < count && !page; i++ )
- {
- page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (_book), i);
- if ( page )
- {
- SPColorSelector* csel;
- guint pagemode;
- csel = SP_COLOR_SELECTOR (page);
- pagemode = csel->base->getSubmode();
- if ( G_TYPE_FROM_INSTANCE (page) == page_type
- && pagemode == submode )
- {
- // found it.
- break;
- }
- else
- {
- page = 0;
- }
- }
- else
- {
- break;
- }
- }
- return page;
-}
-
-void ColorNotebook::removePage( GType page_type, guint submode )
-{
- GtkWidget *page = 0;
-
- page = getPage(page_type, submode);
- if ( page )
- {
- gint where = gtk_notebook_page_num (GTK_NOTEBOOK (_book), page);
- if ( where >= 0 )
- {
- if ( gtk_notebook_get_current_page (GTK_NOTEBOOK (_book)) == where )
- {
-// getColorAlpha(_color, &_alpha);
- }
- gtk_notebook_remove_page (GTK_NOTEBOOK (_book), where);
- }
- }
-}
-
-/*
- 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/widgets/sp-color-notebook.h b/src/widgets/sp-color-notebook.h
deleted file mode 100644
index 469bb56e8..000000000
--- a/src/widgets/sp-color-notebook.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifndef SEEN_SP_COLOR_NOTEBOOK_H
-#define SEEN_SP_COLOR_NOTEBOOK_H
-
-/*
- * A notebook with RGB, CMYK, CMS, HSL, and Wheel pages
- *
- * Author:
- * Lauris Kaplinski <lauris@kaplinski.com>
- *
- * Copyright (C) 2001-2002 Lauris Kaplinski
- *
- * This code is in public domain
- */
-
-#include "sp-color-selector.h"
-
-#include <glib.h>
-
-struct SPColorNotebook;
-
-class ColorNotebook: public ColorSelector
-{
-public:
- ColorNotebook( SPColorSelector* csel );
- virtual ~ColorNotebook();
-
- virtual void init();
-
- SPColorSelector* getCurrentSelector();
- void switchPage( GtkNotebook *notebook, GtkWidget *page, guint page_num );
-
- GtkWidget* addPage( GType page_type, guint submode );
- void removePage( GType page_type, guint submode );
- GtkWidget* getPage( GType page_type, guint submode );
-
- gint menuHandler( GdkEvent* event );
-
-protected:
- static void _rgbaEntryChangedHook( GtkEntry* entry, SPColorNotebook *colorbook );
- static void _entryGrabbed( SPColorSelector *csel, SPColorNotebook *colorbook );
- static void _entryDragged( SPColorSelector *csel, SPColorNotebook *colorbook );
- static void _entryReleased( SPColorSelector *csel, SPColorNotebook *colorbook );
- static void _entryChanged( SPColorSelector *csel, SPColorNotebook *colorbook );
- static void _entryModified( SPColorSelector *csel, SPColorNotebook *colorbook );
- static void _buttonClicked(GtkWidget *widget, SPColorNotebook *colorbook);
- static void _picker_clicked(GtkWidget *widget, SPColorNotebook *colorbook);
-
- virtual void _colorChanged();
-
- void _rgbaEntryChanged( GtkEntry* entry );
- void _updateRgbaEntry( const SPColor& color, gfloat alpha );
- void _setCurrentPage(int i);
-
- gboolean _updating : 1;
- gboolean _updatingrgba : 1;
- gboolean _dragging : 1;
- gulong _switchId;
- gulong _entryId;
- GtkWidget *_book;
- GtkWidget *_buttonbox;
- GtkWidget **_buttons;
- GtkWidget *_rgbal, *_rgbae; /* RGBA entry */
-#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- GtkWidget *_box_outofgamut, *_box_colormanaged, *_box_toomuchink;
-#endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- GtkWidget *_btn_picker;
- GtkWidget *_p; /* Color preview */
- GtkWidget *_btn;
- GtkWidget *_popup;
- GPtrArray *_trackerList;
-
-private:
- // By default, disallow copy constructor and assignment operator
- ColorNotebook( const ColorNotebook& obj );
- ColorNotebook& operator=( const ColorNotebook& obj );
-};
-
-
-
-#define SP_TYPE_COLOR_NOTEBOOK (sp_color_notebook_get_type ())
-#define SP_COLOR_NOTEBOOK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_COLOR_NOTEBOOK, SPColorNotebook))
-#define SP_COLOR_NOTEBOOK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_COLOR_NOTEBOOK, SPColorNotebookClass))
-#define SP_IS_COLOR_NOTEBOOK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_COLOR_NOTEBOOK))
-#define SP_IS_COLOR_NOTEBOOK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SP_TYPE_COLOR_NOTEBOOK))
-
-struct SPColorNotebook {
- SPColorSelector parent; /* Parent */
-};
-
-struct SPColorNotebookClass {
- SPColorSelectorClass parent_class;
-
- void (* grabbed) (SPColorNotebook *rgbsel);
- void (* dragged) (SPColorNotebook *rgbsel);
- void (* released) (SPColorNotebook *rgbsel);
- void (* changed) (SPColorNotebook *rgbsel);
-};
-
-GType sp_color_notebook_get_type(void);
-
-GtkWidget *sp_color_notebook_new (void);
-
-/* void sp_color_notebook_set_mode (SPColorNotebook *csel, SPColorNotebookMode mode); */
-/* SPColorNotebookMode sp_color_notebook_get_mode (SPColorNotebook *csel); */
-
-
-
-#endif // SEEN_SP_COLOR_NOTEBOOK_H
-
-/*
- 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:fileencoding=utf-8:textwidth=99 :
-
diff --git a/src/widgets/sp-color-scales.cpp b/src/widgets/sp-color-scales.cpp
deleted file mode 100644
index 60ba62ec5..000000000
--- a/src/widgets/sp-color-scales.cpp
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- * bulia byak <buliabyak@users.sf.net>
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include <math.h>
-#include <gtk/gtk.h>
-#include <glibmm/i18n.h>
-#include "ui/dialog-events.h"
-#include "sp-color-scales.h"
-#include "sp-color-slider.h"
-#include "svg/svg-icc-color.h"
-
-#define CSC_CHANNEL_R (1 << 0)
-#define CSC_CHANNEL_G (1 << 1)
-#define CSC_CHANNEL_B (1 << 2)
-#define CSC_CHANNEL_A (1 << 3)
-#define CSC_CHANNEL_H (1 << 0)
-#define CSC_CHANNEL_S (1 << 1)
-#define CSC_CHANNEL_V (1 << 2)
-#define CSC_CHANNEL_C (1 << 0)
-#define CSC_CHANNEL_M (1 << 1)
-#define CSC_CHANNEL_Y (1 << 2)
-#define CSC_CHANNEL_K (1 << 3)
-#define CSC_CHANNEL_CMYKA (1 << 4)
-
-#define CSC_CHANNELS_ALL 0
-
-
-G_BEGIN_DECLS
-
-static void sp_color_scales_dispose(GObject *object);
-
-static void sp_color_scales_show_all (GtkWidget *widget);
-static void sp_color_scales_hide(GtkWidget *widget);
-
-static const gchar *sp_color_scales_hue_map (void);
-
-G_END_DECLS
-
-#define XPAD 4
-#define YPAD 1
-
-#define noDUMP_CHANGE_INFO 1
-
-G_DEFINE_TYPE(SPColorScales, sp_color_scales, SP_TYPE_COLOR_SELECTOR);
-
-static void
-sp_color_scales_class_init (SPColorScalesClass *klass)
-{
- static const gchar* nameset[] = {N_("RGB"), N_("HSL"), N_("CMYK"), 0};
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass);
-
- selector_class->name = nameset;
- selector_class->submode_count = 3;
-
- object_class->dispose = sp_color_scales_dispose;
-
- widget_class->show_all = sp_color_scales_show_all;
- widget_class->hide = sp_color_scales_hide;
-}
-
-ColorScales::ColorScales( SPColorSelector* csel )
- : ColorSelector( csel ),
- _mode( SP_COLOR_SCALES_MODE_NONE ),
- _rangeLimit( 255.0 ),
- _updating( FALSE ),
- _dragging( FALSE )
-{
- for (gint i = 0; i < 5; i++) {
- _l[i] = 0;
- _a[i] = 0;
- _s[i] = 0;
- _b[i] = 0;
- }
-}
-
-ColorScales::~ColorScales()
-{
- for (gint i = 0; i < 5; i++) {
- _l[i] = 0;
- _a[i] = 0;
- _s[i] = 0;
- _b[i] = 0;
- }
-}
-
-void sp_color_scales_init (SPColorScales *cs)
-{
- SP_COLOR_SELECTOR(cs)->base = new ColorScales( SP_COLOR_SELECTOR(cs) );
-
- if ( SP_COLOR_SELECTOR(cs)->base )
- {
- SP_COLOR_SELECTOR(cs)->base->init();
- }
-}
-
-void ColorScales::init()
-{
- gint i;
-
- _updating = FALSE;
- _dragging = FALSE;
-
-#if GTK_CHECK_VERSION(3,0,0)
- GtkWidget *t = gtk_grid_new();
-#else
- GtkWidget *t = gtk_table_new (5, 3, FALSE);
-#endif
- gtk_widget_show (t);
- gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 4);
-
- /* Create components */
- for (i = 0; i < static_cast< gint > (G_N_ELEMENTS(_a)) ; i++) {
- /* Label */
- _l[i] = gtk_label_new("");
- gtk_misc_set_alignment (GTK_MISC (_l[i]), 1.0, 0.5);
- gtk_widget_show (_l[i]);
-
-#if GTK_CHECK_VERSION(3,0,0)
- #if GTK_CHECK_VERSION(3,12,0)
- gtk_widget_set_margin_start(_l[i], XPAD);
- gtk_widget_set_margin_end(_l[i], XPAD);
- #else
- gtk_widget_set_margin_left(_l[i], XPAD);
- gtk_widget_set_margin_right(_l[i], XPAD);
- #endif
- gtk_widget_set_margin_top(_l[i], YPAD);
- gtk_widget_set_margin_bottom(_l[i], YPAD);
- gtk_grid_attach(GTK_GRID(t), _l[i], 0, i, 1, 1);
-#else
- gtk_table_attach (GTK_TABLE (t), _l[i], 0, 1, i, i + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);
-#endif
-
- /* Adjustment */
- _a[i] = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, _rangeLimit, 1.0, 10.0, 10.0));
- /* Slider */
- _s[i] = sp_color_slider_new (_a[i]);
- gtk_widget_show (_s[i]);
-
-#if GTK_CHECK_VERSION(3,0,0)
- #if GTK_CHECK_VERSION(3,12,0)
- gtk_widget_set_margin_start(_s[i], XPAD);
- gtk_widget_set_margin_end(_s[i], XPAD);
- #else
- gtk_widget_set_margin_left(_s[i], XPAD);
- gtk_widget_set_margin_right(_s[i], XPAD);
- #endif
- gtk_widget_set_margin_top(_s[i], YPAD);
- gtk_widget_set_margin_bottom(_s[i], YPAD);
- gtk_widget_set_hexpand(_s[i], TRUE);
- gtk_grid_attach(GTK_GRID(t), _s[i], 1, i, 1, 1);
-#else
- gtk_table_attach (GTK_TABLE (t), _s[i], 1, 2, i, i + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, XPAD, YPAD);
-#endif
-
- /* Spinbutton */
- _b[i] = gtk_spin_button_new (GTK_ADJUSTMENT (_a[i]), 1.0, 0);
- sp_dialog_defocus_on_enter (_b[i]);
- gtk_label_set_mnemonic_widget (GTK_LABEL(_l[i]), _b[i]);
- gtk_widget_show (_b[i]);
-
-#if GTK_CHECK_VERSION(3,0,0)
- #if GTK_CHECK_VERSION(3,12,0)
- gtk_widget_set_margin_start(_b[i], XPAD);
- gtk_widget_set_margin_end(_b[i], XPAD);
- #else
- gtk_widget_set_margin_left(_b[i], XPAD);
- gtk_widget_set_margin_right(_b[i], XPAD);
- #endif
- gtk_widget_set_margin_top(_b[i], YPAD);
- gtk_widget_set_margin_bottom(_b[i], YPAD);
- gtk_widget_set_halign(_b[i], GTK_ALIGN_CENTER);
- gtk_widget_set_valign(_b[i], GTK_ALIGN_CENTER);
- gtk_grid_attach(GTK_GRID(t), _b[i], 2, i, 1, 1);
-#else
- gtk_table_attach (GTK_TABLE (t), _b[i], 2, 3, i, i + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD);
-#endif
-
- /* Attach channel value to adjustment */
- g_object_set_data (G_OBJECT (_a[i]), "channel", GINT_TO_POINTER (i));
- /* Signals */
- g_signal_connect (G_OBJECT (_a[i]), "value_changed",
- G_CALLBACK (_adjustmentAnyChanged), _csel);
- g_signal_connect (G_OBJECT (_s[i]), "grabbed",
- G_CALLBACK (_sliderAnyGrabbed), _csel);
- g_signal_connect (G_OBJECT (_s[i]), "released",
- G_CALLBACK (_sliderAnyReleased), _csel);
- g_signal_connect (G_OBJECT (_s[i]), "changed",
- G_CALLBACK (_sliderAnyChanged), _csel);
- }
-
- /* Initial mode is none, so it works */
- setMode(SP_COLOR_SCALES_MODE_RGB);
-}
-
-static void sp_color_scales_dispose(GObject *object)
-{
- if (G_OBJECT_CLASS(sp_color_scales_parent_class)->dispose)
- G_OBJECT_CLASS(sp_color_scales_parent_class)->dispose(object);
-}
-
-static void
-sp_color_scales_show_all (GtkWidget *widget)
-{
- gtk_widget_show (widget);
-}
-
-static void sp_color_scales_hide(GtkWidget *widget)
-{
- gtk_widget_hide(widget);
-}
-
-GtkWidget *sp_color_scales_new()
-{
- SPColorScales *csel = SP_COLOR_SCALES(g_object_new (SP_TYPE_COLOR_SCALES, NULL));
-
- return GTK_WIDGET (csel);
-}
-
-void ColorScales::_recalcColor( gboolean changing )
-{
- if ( changing )
- {
- SPColor color;
- gfloat alpha = 1.0;
- gfloat c[5];
-
- switch (_mode) {
- case SP_COLOR_SCALES_MODE_RGB:
- case SP_COLOR_SCALES_MODE_HSV:
- _getRgbaFloatv(c);
- color.set( c[0], c[1], c[2] );
- alpha = c[3];
- break;
- case SP_COLOR_SCALES_MODE_CMYK:
- {
- _getCmykaFloatv( c );
-
- float rgb[3];
- sp_color_cmyk_to_rgb_floatv( rgb, c[0], c[1], c[2], c[3] );
- color.set( rgb[0], rgb[1], rgb[2] );
- alpha = c[4];
- break;
- }
- default:
- g_warning ("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode);
- break;
- }
-
- /* Preserve ICC */
- color.icc = _color.icc ? new SVGICCColor(*_color.icc) : 0;
-
- _updateInternals( color, alpha, _dragging );
- }
- else
- {
- _updateInternals( _color, _alpha, _dragging );
- }
-}
-
-/* Helpers for setting color value */
-gfloat ColorScales::getScaled( const GtkAdjustment *a )
-{
- gfloat val = gtk_adjustment_get_value (const_cast<GtkAdjustment*>(a))
- / gtk_adjustment_get_upper (const_cast<GtkAdjustment*>(a));
- return val;
-}
-
-void ColorScales::setScaled( GtkAdjustment *a, gfloat v )
-{
- gfloat val = v * gtk_adjustment_get_upper (a);
- gtk_adjustment_set_value( a, val );
-}
-
-void ColorScales::_setRangeLimit( gdouble upper )
-{
- _rangeLimit = upper;
- for ( gint i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++ ) {
- gtk_adjustment_set_upper (_a[i], upper);
- gtk_adjustment_changed( _a[i] );
- }
-}
-
-void ColorScales::_colorChanged()
-{
-#ifdef DUMP_CHANGE_INFO
- g_message("ColorScales::_colorChanged( this=%p, %f, %f, %f, %f)", this, _color.v.c[0], _color.v.c[1], _color.v.c[2], _alpha );
-#endif
- gfloat tmp[3];
- gfloat c[5] = {0.0, 0.0, 0.0, 0.0};
-
- switch (_mode) {
- case SP_COLOR_SCALES_MODE_RGB:
- sp_color_get_rgb_floatv( &_color, c );
- c[3] = _alpha;
- c[4] = 0.0;
- break;
- case SP_COLOR_SCALES_MODE_HSV:
- sp_color_get_rgb_floatv( &_color, tmp );
- sp_color_rgb_to_hsl_floatv (c, tmp[0], tmp[1], tmp[2]);
- c[3] = _alpha;
- c[4] = 0.0;
- break;
- case SP_COLOR_SCALES_MODE_CMYK:
- sp_color_get_cmyk_floatv( &_color, c );
- c[4] = _alpha;
- break;
- default:
- g_warning ("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode);
- break;
- }
-
- _updating = TRUE;
- setScaled( _a[0], c[0] );
- setScaled( _a[1], c[1] );
- setScaled( _a[2], c[2] );
- setScaled( _a[3], c[3] );
- setScaled( _a[4], c[4] );
- _updateSliders( CSC_CHANNELS_ALL );
- _updating = FALSE;
-}
-
-void ColorScales::_getRgbaFloatv( gfloat *rgba )
-{
- g_return_if_fail (rgba != NULL);
-
- switch (_mode) {
- case SP_COLOR_SCALES_MODE_RGB:
- rgba[0] = getScaled(_a[0]);
- rgba[1] = getScaled(_a[1]);
- rgba[2] = getScaled(_a[2]);
- rgba[3] = getScaled(_a[3]);
- break;
- case SP_COLOR_SCALES_MODE_HSV:
- sp_color_hsl_to_rgb_floatv (rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
- rgba[3] = getScaled(_a[3]);
- break;
- case SP_COLOR_SCALES_MODE_CMYK:
- sp_color_cmyk_to_rgb_floatv (rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
- rgba[3] = getScaled(_a[4]);
- break;
- default:
- g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
- break;
- }
-}
-
-void ColorScales::_getCmykaFloatv( gfloat *cmyka )
-{
- gfloat rgb[3];
-
- g_return_if_fail (cmyka != NULL);
-
- switch (_mode) {
- case SP_COLOR_SCALES_MODE_RGB:
- sp_color_rgb_to_cmyk_floatv (cmyka, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
- cmyka[4] = getScaled(_a[3]);
- break;
- case SP_COLOR_SCALES_MODE_HSV:
- sp_color_hsl_to_rgb_floatv (rgb, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
- sp_color_rgb_to_cmyk_floatv (cmyka, rgb[0], rgb[1], rgb[2]);
- cmyka[4] = getScaled(_a[3]);
- break;
- case SP_COLOR_SCALES_MODE_CMYK:
- cmyka[0] = getScaled(_a[0]);
- cmyka[1] = getScaled(_a[1]);
- cmyka[2] = getScaled(_a[2]);
- cmyka[3] = getScaled(_a[3]);
- cmyka[4] = getScaled(_a[4]);
- break;
- default:
- g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
- break;
- }
-}
-
-guint32 ColorScales::_getRgba32()
-{
- gfloat c[4];
- guint32 rgba;
-
- _getRgbaFloatv(c);
-
- rgba = SP_RGBA32_F_COMPOSE (c[0], c[1], c[2], c[3]);
-
- return rgba;
-}
-
-void ColorScales::setMode(SPColorScalesMode mode)
-{
- gfloat rgba[4];
- gfloat c[4];
-
- if (_mode == mode) return;
-
- if ((_mode == SP_COLOR_SCALES_MODE_RGB) ||
- (_mode == SP_COLOR_SCALES_MODE_HSV) ||
- (_mode == SP_COLOR_SCALES_MODE_CMYK)) {
- _getRgbaFloatv(rgba);
- } else {
- rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0;
- }
-
- _mode = mode;
-
- switch (mode) {
- case SP_COLOR_SCALES_MODE_RGB:
- _setRangeLimit(255.0);
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_R:"));
- gtk_widget_set_tooltip_text (_s[0], _("Red"));
- gtk_widget_set_tooltip_text (_b[0], _("Red"));
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_G:"));
- gtk_widget_set_tooltip_text (_s[1], _("Green"));
- gtk_widget_set_tooltip_text (_b[1], _("Green"));
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_B:"));
- gtk_widget_set_tooltip_text (_s[2], _("Blue"));
- gtk_widget_set_tooltip_text (_b[2], _("Blue"));
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_A:"));
- gtk_widget_set_tooltip_text (_s[3], _("Alpha (opacity)"));
- gtk_widget_set_tooltip_text (_b[3], _("Alpha (opacity)"));
- sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), NULL);
- gtk_widget_hide (_l[4]);
- gtk_widget_hide (_s[4]);
- gtk_widget_hide (_b[4]);
- _updating = TRUE;
- setScaled( _a[0], rgba[0] );
- setScaled( _a[1], rgba[1] );
- setScaled( _a[2], rgba[2] );
- setScaled( _a[3], rgba[3] );
- _updating = FALSE;
- _updateSliders( CSC_CHANNELS_ALL );
- break;
- case SP_COLOR_SCALES_MODE_HSV:
- _setRangeLimit(255.0);
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_H:"));
- gtk_widget_set_tooltip_text (_s[0], _("Hue"));
- gtk_widget_set_tooltip_text (_b[0], _("Hue"));
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_S:"));
- gtk_widget_set_tooltip_text (_s[1], _("Saturation"));
- gtk_widget_set_tooltip_text (_b[1], _("Saturation"));
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_L:"));
- gtk_widget_set_tooltip_text (_s[2], _("Lightness"));
- gtk_widget_set_tooltip_text (_b[2], _("Lightness"));
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_A:"));
- gtk_widget_set_tooltip_text (_s[3], _("Alpha (opacity)"));
- gtk_widget_set_tooltip_text (_b[3], _("Alpha (opacity)"));
- sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), (guchar *)(sp_color_scales_hue_map()));
- gtk_widget_hide (_l[4]);
- gtk_widget_hide (_s[4]);
- gtk_widget_hide (_b[4]);
- _updating = TRUE;
- c[0] = 0.0;
- sp_color_rgb_to_hsl_floatv (c, rgba[0], rgba[1], rgba[2]);
- setScaled( _a[0], c[0] );
- setScaled( _a[1], c[1] );
- setScaled( _a[2], c[2] );
- setScaled( _a[3], rgba[3] );
- _updating = FALSE;
- _updateSliders( CSC_CHANNELS_ALL );
- break;
- case SP_COLOR_SCALES_MODE_CMYK:
- _setRangeLimit(100.0);
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_C:"));
- gtk_widget_set_tooltip_text (_s[0], _("Cyan"));
- gtk_widget_set_tooltip_text (_b[0], _("Cyan"));
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_M:"));
- gtk_widget_set_tooltip_text (_s[1], _("Magenta"));
- gtk_widget_set_tooltip_text (_b[1], _("Magenta"));
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_Y:"));
- gtk_widget_set_tooltip_text (_s[2], _("Yellow"));
- gtk_widget_set_tooltip_text (_b[2], _("Yellow"));
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_K:"));
- gtk_widget_set_tooltip_text (_s[3], _("Black"));
- gtk_widget_set_tooltip_text (_b[3], _("Black"));
- gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[4]), _("_A:"));
- gtk_widget_set_tooltip_text (_s[4], _("Alpha (opacity)"));
- gtk_widget_set_tooltip_text (_b[4], _("Alpha (opacity)"));
- sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), NULL);
- gtk_widget_show (_l[4]);
- gtk_widget_show (_s[4]);
- gtk_widget_show (_b[4]);
- _updating = TRUE;
-
- sp_color_rgb_to_cmyk_floatv (c, rgba[0], rgba[1], rgba[2]);
- setScaled( _a[0], c[0] );
- setScaled( _a[1], c[1] );
- setScaled( _a[2], c[2] );
- setScaled( _a[3], c[3] );
-
- setScaled( _a[4], rgba[3] );
- _updating = FALSE;
- _updateSliders( CSC_CHANNELS_ALL );
- break;
- default:
- g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
- break;
- }
-}
-
-SPColorScalesMode ColorScales::getMode() const
-{
- return _mode;
-}
-
-void ColorScales::setSubmode( guint submode )
-{
- g_return_if_fail (_csel != NULL);
- g_return_if_fail (SP_IS_COLOR_SCALES (_csel));
- g_return_if_fail (submode < 3);
-
- switch ( submode )
- {
- default:
- case 0:
- setMode(SP_COLOR_SCALES_MODE_RGB);
- break;
- case 1:
- setMode(SP_COLOR_SCALES_MODE_HSV);
- break;
- case 2:
- setMode(SP_COLOR_SCALES_MODE_CMYK);
- break;
- }
-}
-
-guint ColorScales::getSubmode() const
-{
- guint submode = 0;
-
- switch ( _mode )
- {
- case SP_COLOR_SCALES_MODE_HSV:
- submode = 1;
- break;
- case SP_COLOR_SCALES_MODE_CMYK:
- submode = 2;
- break;
- case SP_COLOR_SCALES_MODE_RGB:
- default:
- submode = 0;
- }
-
- return submode;
-}
-
-void ColorScales::_adjustmentAnyChanged( GtkAdjustment *adjustment, SPColorScales *cs )
-{
- gint channel = GPOINTER_TO_INT (g_object_get_data(G_OBJECT (adjustment), "channel"));
-
- _adjustmentChanged(cs, channel);
-}
-
-void ColorScales::_sliderAnyGrabbed( SPColorSlider *slider, SPColorScales *cs )
-{
- (void)slider;
- ColorScales* scales = static_cast<ColorScales*>(SP_COLOR_SELECTOR(cs)->base);
- if (!scales->_dragging) {
- scales->_dragging = TRUE;
- scales->_grabbed();
- scales->_recalcColor( FALSE );
- }
-}
-
-void ColorScales::_sliderAnyReleased( SPColorSlider *slider, SPColorScales *cs )
-{
- (void)slider;
- ColorScales* scales = static_cast<ColorScales*>(SP_COLOR_SELECTOR(cs)->base);
- if (scales->_dragging) {
- scales->_dragging = FALSE;
- scales->_released();
- scales->_recalcColor( FALSE );
- }
-}
-
-void ColorScales::_sliderAnyChanged( SPColorSlider *slider, SPColorScales *cs )
-{
- (void)slider;
- ColorScales* scales = static_cast<ColorScales*>(SP_COLOR_SELECTOR(cs)->base);
-
- scales->_recalcColor( TRUE );
-}
-
-void ColorScales::_adjustmentChanged( SPColorScales *cs, guint channel )
-{
- ColorScales* scales = static_cast<ColorScales*>(SP_COLOR_SELECTOR(cs)->base);
- if (scales->_updating) return;
-
- scales->_updating = TRUE;
-
- scales->_updateSliders( (1 << channel) );
-
- scales->_recalcColor (TRUE);
-
- scales->_updating = FALSE;
-}
-
-void ColorScales::_updateSliders( guint channels )
-{
- gfloat rgb0[3], rgbm[3], rgb1[3];
-#ifdef SPCS_PREVIEW
- guint32 rgba;
-#endif
- switch (_mode) {
- case SP_COLOR_SCALES_MODE_RGB:
- if ((channels != CSC_CHANNEL_R) && (channels != CSC_CHANNEL_A)) {
- /* Update red */
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[0]),
- SP_RGBA32_F_COMPOSE (0.0, getScaled(_a[1]), getScaled(_a[2]), 1.0),
- SP_RGBA32_F_COMPOSE (0.5, getScaled(_a[1]), getScaled(_a[2]), 1.0),
- SP_RGBA32_F_COMPOSE (1.0, getScaled(_a[1]), getScaled(_a[2]), 1.0));
- }
- if ((channels != CSC_CHANNEL_G) && (channels != CSC_CHANNEL_A)) {
- /* Update green */
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]),
- SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 0.0, getScaled(_a[2]), 1.0),
- SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 0.5, getScaled(_a[2]), 1.0),
- SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 1.0, getScaled(_a[2]), 1.0));
- }
- if ((channels != CSC_CHANNEL_B) && (channels != CSC_CHANNEL_A)) {
- /* Update blue */
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]),
- SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 0.0, 1.0),
- SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 0.5, 1.0),
- SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 1.0, 1.0));
- }
- if (channels != CSC_CHANNEL_A) {
- /* Update alpha */
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]),
- SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0),
- SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5),
- SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0));
- }
- break;
- case SP_COLOR_SCALES_MODE_HSV:
- /* Hue is never updated */
- if ((channels != CSC_CHANNEL_S) && (channels != CSC_CHANNEL_A)) {
- /* Update saturation */
- sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]));
- sp_color_hsl_to_rgb_floatv (rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]));
- sp_color_hsl_to_rgb_floatv (rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]));
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]),
- SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
- SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
- SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
- }
- if ((channels != CSC_CHANNEL_V) && (channels != CSC_CHANNEL_A)) {
- /* Update value */
- sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0);
- sp_color_hsl_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5);
- sp_color_hsl_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0);
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]),
- SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
- SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
- SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
- }
- if (channels != CSC_CHANNEL_A) {
- /* Update alpha */
- sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]));
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]),
- SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.0),
- SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.5),
- SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0));
- }
- break;
- case SP_COLOR_SCALES_MODE_CMYK:
- if ((channels != CSC_CHANNEL_C) && (channels != CSC_CHANNEL_CMYKA)) {
- /* Update C */
- sp_color_cmyk_to_rgb_floatv (rgb0, 0.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
- sp_color_cmyk_to_rgb_floatv (rgbm, 0.5, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
- sp_color_cmyk_to_rgb_floatv (rgb1, 1.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[0]),
- SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
- SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
- SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
- }
- if ((channels != CSC_CHANNEL_M) && (channels != CSC_CHANNEL_CMYKA)) {
- /* Update M */
- sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]), getScaled(_a[3]));
- sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]), getScaled(_a[3]));
- sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]), getScaled(_a[3]));
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]),
- SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
- SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
- SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
- }
- if ((channels != CSC_CHANNEL_Y) && (channels != CSC_CHANNEL_CMYKA)) {
- /* Update Y */
- sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0, getScaled(_a[3]));
- sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5, getScaled(_a[3]));
- sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0, getScaled(_a[3]));
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]),
- SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
- SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
- SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
- }
- if ((channels != CSC_CHANNEL_K) && (channels != CSC_CHANNEL_CMYKA)) {
- /* Update K */
- sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0);
- sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5);
- sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0);
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]),
- SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0),
- SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0),
- SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0));
- }
- if (channels != CSC_CHANNEL_CMYKA) {
- /* Update alpha */
- sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3]));
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[4]),
- SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.0),
- SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.5),
- SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0));
- }
- break;
- default:
- g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__);
- break;
- }
-
- // Force the internal color to be updated
- if ( !_updating )
- {
- _recalcColor( TRUE );
- }
-
-#ifdef SPCS_PREVIEW
- rgba = sp_color_scales_get_rgba32 (cs);
- sp_color_preview_set_rgba32 (SP_COLOR_PREVIEW (_p), rgba);
-#endif
-}
-
-static const gchar *
-sp_color_scales_hue_map (void)
-{
- static gchar *map = NULL;
-
- if (!map) {
- gchar *p;
- gint h;
- map = g_new (gchar, 4 * 1024);
- p = map;
- for (h = 0; h < 1024; h++) {
- gfloat rgb[3];
- sp_color_hsl_to_rgb_floatv (rgb, h / 1024.0, 1.0, 0.5);
- *p++ = SP_COLOR_F_TO_U (rgb[0]);
- *p++ = SP_COLOR_F_TO_U (rgb[1]);
- *p++ = SP_COLOR_F_TO_U (rgb[2]);
- *p++ = 255;
- }
- }
-
- return map;
-}
-
-
diff --git a/src/widgets/sp-color-scales.h b/src/widgets/sp-color-scales.h
deleted file mode 100644
index 72cbafa2f..000000000
--- a/src/widgets/sp-color-scales.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef SEEN_SP_COLOR_SCALES_H
-#define SEEN_SP_COLOR_SCALES_H
-
-#include <glib.h>
-
-#include <widgets/sp-color-selector.h>
-
-struct SPColorScales;
-struct SPColorScalesClass;
-struct SPColorSlider;
-
-typedef enum {
- SP_COLOR_SCALES_MODE_NONE = 0,
- SP_COLOR_SCALES_MODE_RGB = 1,
- SP_COLOR_SCALES_MODE_HSV = 2,
- SP_COLOR_SCALES_MODE_CMYK = 3
-} SPColorScalesMode;
-
-
-
-class ColorScales: public ColorSelector
-{
-public:
- static gfloat getScaled( const GtkAdjustment *a );
- static void setScaled( GtkAdjustment *a, gfloat v);
-
- ColorScales(SPColorSelector *csel);
- virtual ~ColorScales();
-
- virtual void init();
-
- virtual void setSubmode(guint submode);
- virtual guint getSubmode() const;
-
- void setMode(SPColorScalesMode mode);
- SPColorScalesMode getMode() const;
-
-
-protected:
- virtual void _colorChanged();
-
- static void _adjustmentAnyChanged(GtkAdjustment *adjustment, SPColorScales *cs);
- static void _sliderAnyGrabbed(SPColorSlider *slider, SPColorScales *cs);
- static void _sliderAnyReleased(SPColorSlider *slider, SPColorScales *cs);
- static void _sliderAnyChanged(SPColorSlider *slider, SPColorScales *cs);
- static void _adjustmentChanged(SPColorScales *cs, guint channel);
-
- void _getRgbaFloatv(gfloat *rgba);
- void _getCmykaFloatv(gfloat *cmyka);
- guint32 _getRgba32();
- void _updateSliders(guint channels);
- void _recalcColor(gboolean changing);
-
- void _setRangeLimit( gdouble upper );
-
- SPColorScalesMode _mode;
- gdouble _rangeLimit;
- gboolean _updating : 1;
- gboolean _dragging : 1;
- GtkAdjustment *_a[5]; /* Channel adjustments */
- GtkWidget *_s[5]; /* Channel sliders */
- GtkWidget *_b[5]; /* Spinbuttons */
- GtkWidget *_l[5]; /* Labels */
-
-private:
- // By default, disallow copy constructor and assignment operator
- ColorScales(ColorScales const &obj);
- ColorScales &operator=(ColorScales const &obj );
-};
-
-
-
-#define SP_TYPE_COLOR_SCALES (sp_color_scales_get_type())
-#define SP_COLOR_SCALES(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_COLOR_SCALES, SPColorScales))
-#define SP_COLOR_SCALES_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SP_TYPE_COLOR_SCALES, SPColorScalesClass))
-#define SP_IS_COLOR_SCALES(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_COLOR_SCALES))
-#define SP_IS_COLOR_SCALES_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_COLOR_SCALES))
-
-struct SPColorScales {
- SPColorSelector parent;
-};
-
-struct SPColorScalesClass {
- SPColorSelectorClass parent_class;
-};
-
-GType sp_color_scales_get_type();
-
-GtkWidget *sp_color_scales_new();
-
-#endif /* !SEEN_SP_COLOR_SCALES_H */
-
-/*
- 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 :
diff --git a/src/widgets/sp-color-selector.cpp b/src/widgets/sp-color-selector.cpp
index e97c36431..dad0a18b0 100644
--- a/src/widgets/sp-color-selector.cpp
+++ b/src/widgets/sp-color-selector.cpp
@@ -6,6 +6,11 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <math.h>
#include <gtk/gtk.h>
#include <glibmm/i18n.h>
@@ -289,7 +294,7 @@ void ColorSelector::_updateInternals( const SPColor& color, gfloat alpha, gboole
(_held ? "CHANGED" : "DRAGGED" ),
color.toRGBA32( alpha ), (color.icc?color.icc->colorProfile.c_str():"<null>"), FOO_NAME(_csel));
#endif
- g_signal_emit(G_OBJECT(_csel), csel_signals[_held ? CHANGED : DRAGGED], 0);
+ g_signal_emit(G_OBJECT(_csel), csel_signals[_held ? DRAGGED : CHANGED], 0);
}
}
diff --git a/src/widgets/sp-color-selector.h b/src/widgets/sp-color-selector.h
index 30061774a..308a5519c 100644
--- a/src/widgets/sp-color-selector.h
+++ b/src/widgets/sp-color-selector.h
@@ -1,6 +1,14 @@
#ifndef SEEN_SP_COLOR_SELECTOR_H
#define SEEN_SP_COLOR_SELECTOR_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtk/gtk.h>
#include "color.h"
diff --git a/src/widgets/sp-color-slider.cpp b/src/widgets/sp-color-slider.cpp
deleted file mode 100644
index ab7e2cd84..000000000
--- a/src/widgets/sp-color-slider.cpp
+++ /dev/null
@@ -1,749 +0,0 @@
-/*
- * A slider with colored background
- *
- * Author:
- * Lauris Kaplinski <lauris@kaplinski.com>
- * bulia byak <buliabyak@users.sf.net>
- *
- * Copyright (C) 2001-2002 Lauris Kaplinski
- *
- * This code is in public domain
- */
-
-#include <gtk/gtk.h>
-#include "sp-color-scales.h"
-#include "sp-color-slider.h"
-#include "preferences.h"
-
-#define SLIDER_WIDTH 96
-#define SLIDER_HEIGHT 8
-#define ARROW_SIZE 7
-
-enum {
- GRABBED,
- DRAGGED,
- RELEASED,
- CHANGED,
- LAST_SIGNAL
-};
-
-static void sp_color_slider_dispose(GObject *object);
-
-static void sp_color_slider_realize (GtkWidget *widget);
-static void sp_color_slider_size_request (GtkWidget *widget, GtkRequisition *requisition);
-
-#if GTK_CHECK_VERSION(3,0,0)
-static void sp_color_slider_get_preferred_width(GtkWidget *widget,
- gint *minimal_width,
- gint *natural_width);
-
-static void sp_color_slider_get_preferred_height(GtkWidget *widget,
- gint *minimal_height,
- gint *natural_height);
-#else
-static gboolean sp_color_slider_expose(GtkWidget *widget, GdkEventExpose *event);
-#endif
-
-static void sp_color_slider_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
-
-static gboolean sp_color_slider_draw(GtkWidget *widget, cairo_t *cr);
-
-static gint sp_color_slider_button_press (GtkWidget *widget, GdkEventButton *event);
-static gint sp_color_slider_button_release (GtkWidget *widget, GdkEventButton *event);
-static gint sp_color_slider_motion_notify (GtkWidget *widget, GdkEventMotion *event);
-
-static void sp_color_slider_adjustment_changed (GtkAdjustment *adjustment, SPColorSlider *slider);
-static void sp_color_slider_adjustment_value_changed (GtkAdjustment *adjustment, SPColorSlider *slider);
-
-static const guchar *sp_color_slider_render_gradient (gint x0, gint y0, gint width, gint height,
- gint c[], gint dc[], guint b0, guint b1, guint mask);
-static const guchar *sp_color_slider_render_map (gint x0, gint y0, gint width, gint height,
- guchar *map, gint start, gint step, guint b0, guint b1, guint mask);
-
-static guint slider_signals[LAST_SIGNAL] = {0};
-
-G_DEFINE_TYPE(SPColorSlider, sp_color_slider, GTK_TYPE_WIDGET);
-
-static void sp_color_slider_class_init(SPColorSliderClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
-
- slider_signals[GRABBED] = g_signal_new ("grabbed",
- G_TYPE_FROM_CLASS(object_class),
- (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE),
- G_STRUCT_OFFSET (SPColorSliderClass, grabbed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- slider_signals[DRAGGED] = g_signal_new ("dragged",
- G_TYPE_FROM_CLASS(object_class),
- (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE),
- G_STRUCT_OFFSET (SPColorSliderClass, dragged),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- slider_signals[RELEASED] = g_signal_new ("released",
- G_TYPE_FROM_CLASS(object_class),
- (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE),
- G_STRUCT_OFFSET (SPColorSliderClass, released),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- slider_signals[CHANGED] = g_signal_new ("changed",
- G_TYPE_FROM_CLASS(object_class),
- (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE),
- G_STRUCT_OFFSET (SPColorSliderClass, changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- object_class->dispose = sp_color_slider_dispose;
-
- widget_class->realize = sp_color_slider_realize;
-#if GTK_CHECK_VERSION(3,0,0)
- widget_class->get_preferred_width = sp_color_slider_get_preferred_width;
- widget_class->get_preferred_height = sp_color_slider_get_preferred_height;
- widget_class->draw = sp_color_slider_draw;
-#else
- widget_class->size_request = sp_color_slider_size_request;
- widget_class->expose_event = sp_color_slider_expose;
-#endif
- widget_class->size_allocate = sp_color_slider_size_allocate;
-/* widget_class->draw_focus = sp_color_slider_draw_focus; */
-/* widget_class->draw_default = sp_color_slider_draw_default; */
-
- widget_class->button_press_event = sp_color_slider_button_press;
- widget_class->button_release_event = sp_color_slider_button_release;
- widget_class->motion_notify_event = sp_color_slider_motion_notify;
-}
-
-static void
-sp_color_slider_init (SPColorSlider *slider)
-{
- /* We are widget with window */
- gtk_widget_set_has_window (GTK_WIDGET(slider), TRUE);
-
- slider->dragging = FALSE;
-
- slider->adjustment = NULL;
- slider->value = 0.0;
-
- slider->c0[0] = 0x00;
- slider->c0[1] = 0x00;
- slider->c0[2] = 0x00;
- slider->c0[3] = 0xff;
-
- slider->cm[0] = 0xff;
- slider->cm[1] = 0x00;
- slider->cm[2] = 0x00;
- slider->cm[3] = 0xff;
-
- slider->c1[0] = 0xff;
- slider->c1[1] = 0xff;
- slider->c1[2] = 0xff;
- slider->c1[3] = 0xff;
-
- slider->b0 = 0x5f;
- slider->b1 = 0xa0;
- slider->bmask = 0x08;
-
- slider->map = NULL;
-}
-
-static void sp_color_slider_dispose(GObject *object)
-{
- SPColorSlider *slider = SP_COLOR_SLIDER (object);
-
- if (slider->adjustment) {
- g_signal_handlers_disconnect_matched (G_OBJECT (slider->adjustment), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, slider);
- g_object_unref (slider->adjustment);
- slider->adjustment = NULL;
- }
-
- if (G_OBJECT_CLASS(sp_color_slider_parent_class)->dispose)
- G_OBJECT_CLASS(sp_color_slider_parent_class)->dispose (object);
-}
-
-static void
-sp_color_slider_realize (GtkWidget *widget)
-{
- GdkWindowAttr attributes;
- gint attributes_mask;
- GtkAllocation allocation;
-
- gtk_widget_get_allocation(widget, &allocation);
- gtk_widget_set_realized (widget, TRUE);
-
- attributes.window_type = GDK_WINDOW_CHILD;
- attributes.x = allocation.x;
- attributes.y = allocation.y;
- attributes.width = allocation.width;
- attributes.height = allocation.height;
- attributes.wclass = GDK_INPUT_OUTPUT;
- attributes.visual = gdk_screen_get_system_visual(gdk_screen_get_default());
-
-#if !GTK_CHECK_VERSION(3,0,0)
- attributes.colormap = gdk_screen_get_system_colormap(gdk_screen_get_default());
-#endif
-
- attributes.event_mask = gtk_widget_get_events (widget);
- attributes.event_mask |= (GDK_EXPOSURE_MASK |
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_POINTER_MOTION_MASK |
- GDK_ENTER_NOTIFY_MASK |
- GDK_LEAVE_NOTIFY_MASK);
-#if GTK_CHECK_VERSION(3,0,0)
- attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
-#else
- attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-#endif
-
- gtk_widget_set_window(widget,
- gdk_window_new(gtk_widget_get_parent_window(widget),
- &attributes, attributes_mask));
-
- gdk_window_set_user_data(gtk_widget_get_window(widget), widget);
-
-#if !GTK_CHECK_VERSION(3,0,0)
- // This doesn't do anything in GTK+ 3
- gtk_widget_set_style(widget,
- gtk_style_attach(gtk_widget_get_style(widget),
- gtk_widget_get_window(widget)));
-#endif
-}
-
-static void
-sp_color_slider_size_request (GtkWidget *widget, GtkRequisition *requisition)
-{
- GtkStyle *style = gtk_widget_get_style(widget);
- requisition->width = SLIDER_WIDTH + style->xthickness * 2;
- requisition->height = SLIDER_HEIGHT + style->ythickness * 2;
-}
-
-#if GTK_CHECK_VERSION(3,0,0)
-static void sp_color_slider_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width)
-{
- GtkRequisition requisition;
- sp_color_slider_size_request(widget, &requisition);
- *minimal_width = *natural_width = requisition.width;
-}
-
-static void sp_color_slider_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height)
-{
- GtkRequisition requisition;
- sp_color_slider_size_request(widget, &requisition);
- *minimal_height = *natural_height = requisition.height;
-}
-#endif
-
-static void
-sp_color_slider_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
-{
- gtk_widget_set_allocation(widget, allocation);
-
- if (gtk_widget_get_realized (widget)) {
- /* Resize GdkWindow */
- gdk_window_move_resize(gtk_widget_get_window(widget),
- allocation->x, allocation->y,
- allocation->width, allocation->height);
- }
-}
-
-#if !GTK_CHECK_VERSION(3,0,0)
-static gboolean sp_color_slider_expose(GtkWidget *widget, GdkEventExpose * /*event*/)
-{
- gboolean result = FALSE;
-
- if (gtk_widget_is_drawable(widget)) {
- GdkWindow *window = gtk_widget_get_window(widget);
- cairo_t *cr = gdk_cairo_create(window);
- result = sp_color_slider_draw(widget, cr);
- cairo_destroy(cr);
- }
-
- return result;
-}
-#endif
-
-static gint
-sp_color_slider_button_press (GtkWidget *widget, GdkEventButton *event)
-{
- SPColorSlider *slider;
-
- slider = SP_COLOR_SLIDER (widget);
-
- if (event->button == 1) {
- GtkAllocation allocation;
- gtk_widget_get_allocation(widget, &allocation);
- gint cx, cw;
- cx = gtk_widget_get_style(widget)->xthickness;
- cw = allocation.width - 2 * cx;
- g_signal_emit (G_OBJECT (slider), slider_signals[GRABBED], 0);
- slider->dragging = TRUE;
- slider->oldvalue = slider->value;
- ColorScales::setScaled( slider->adjustment, CLAMP ((gfloat) (event->x - cx) / cw, 0.0, 1.0) );
- g_signal_emit (G_OBJECT (slider), slider_signals[DRAGGED], 0);
-
-#if GTK_CHECK_VERSION(3,0,0)
- gdk_device_grab(gdk_event_get_device(reinterpret_cast<GdkEvent *>(event)),
- gtk_widget_get_window(widget),
- GDK_OWNERSHIP_NONE,
- FALSE,
- static_cast<GdkEventMask>(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK),
- NULL,
- event->time);
-#else
- gdk_pointer_grab(gtk_widget_get_window(widget), FALSE,
- static_cast<GdkEventMask>(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK),
- NULL, NULL, event->time);
-#endif
- }
-
- return FALSE;
-}
-
-static gint
-sp_color_slider_button_release (GtkWidget *widget, GdkEventButton *event)
-{
- SPColorSlider *slider;
-
- slider = SP_COLOR_SLIDER (widget);
-
- if (event->button == 1) {
-
-#if GTK_CHECK_VERSION(3,0,0)
- gdk_device_ungrab(gdk_event_get_device(reinterpret_cast<GdkEvent *>(event)),
- gdk_event_get_time(reinterpret_cast<GdkEvent *>(event)));
-#else
- gdk_pointer_ungrab (event->time);
-#endif
-
- slider->dragging = FALSE;
- g_signal_emit (G_OBJECT (slider), slider_signals[RELEASED], 0);
- if (slider->value != slider->oldvalue) g_signal_emit (G_OBJECT (slider), slider_signals[CHANGED], 0);
- }
-
- return FALSE;
-}
-
-static gint
-sp_color_slider_motion_notify (GtkWidget *widget, GdkEventMotion *event)
-{
- SPColorSlider *slider;
-
- slider = SP_COLOR_SLIDER (widget);
-
- if (slider->dragging) {
- gint cx, cw;
- GtkAllocation allocation;
- gtk_widget_get_allocation(widget, &allocation);
- cx = gtk_widget_get_style(widget)->xthickness;
- cw = allocation.width - 2 * cx;
- ColorScales::setScaled( slider->adjustment, CLAMP ((gfloat) (event->x - cx) / cw, 0.0, 1.0) );
- g_signal_emit (G_OBJECT (slider), slider_signals[DRAGGED], 0);
- }
-
- return FALSE;
-}
-
-GtkWidget *sp_color_slider_new(GtkAdjustment *adjustment)
-{
- SPColorSlider *slider = SP_COLOR_SLIDER(g_object_new(SP_TYPE_COLOR_SLIDER, NULL));
-
- sp_color_slider_set_adjustment (slider, adjustment);
-
- return GTK_WIDGET (slider);
-}
-
-void sp_color_slider_set_adjustment(SPColorSlider *slider, GtkAdjustment *adjustment)
-{
- g_return_if_fail (slider != NULL);
- g_return_if_fail (SP_IS_COLOR_SLIDER (slider));
-
- if (!adjustment) {
- adjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 1.0, 0.01, 0.0, 0.0));
- } else {
- gtk_adjustment_set_page_increment(adjustment, 0.0);
- gtk_adjustment_set_page_size(adjustment, 0.0);
- }
-
- if (slider->adjustment != adjustment) {
- if (slider->adjustment) {
- g_signal_handlers_disconnect_matched (G_OBJECT (slider->adjustment), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, slider);
- g_object_unref (slider->adjustment);
- }
-
- slider->adjustment = adjustment;
- g_object_ref (adjustment);
- g_object_ref_sink (adjustment);
-
- g_signal_connect (G_OBJECT (adjustment), "changed",
- G_CALLBACK (sp_color_slider_adjustment_changed), slider);
- g_signal_connect (G_OBJECT (adjustment), "value_changed",
- G_CALLBACK (sp_color_slider_adjustment_value_changed), slider);
-
- slider->value = ColorScales::getScaled( adjustment );
-
- sp_color_slider_adjustment_changed (adjustment, slider);
- }
-}
-
-void
-sp_color_slider_set_colors (SPColorSlider *slider, guint32 start, guint32 mid, guint32 end)
-{
- g_return_if_fail (slider != NULL);
- g_return_if_fail (SP_IS_COLOR_SLIDER (slider));
-
- // Remove any map, if set
- slider->map = 0;
-
- slider->c0[0] = start >> 24;
- slider->c0[1] = (start >> 16) & 0xff;
- slider->c0[2] = (start >> 8) & 0xff;
- slider->c0[3] = start & 0xff;
-
- slider->cm[0] = mid >> 24;
- slider->cm[1] = (mid >> 16) & 0xff;
- slider->cm[2] = (mid >> 8) & 0xff;
- slider->cm[3] = mid & 0xff;
-
- slider->c1[0] = end >> 24;
- slider->c1[1] = (end >> 16) & 0xff;
- slider->c1[2] = (end >> 8) & 0xff;
- slider->c1[3] = end & 0xff;
-
- gtk_widget_queue_draw (GTK_WIDGET (slider));
-}
-
-void
-sp_color_slider_set_map (SPColorSlider *slider, const guchar *map)
-{
- g_return_if_fail (slider != NULL);
- g_return_if_fail (SP_IS_COLOR_SLIDER (slider));
-
- slider->map = const_cast<guchar *>(map);
-
- gtk_widget_queue_draw (GTK_WIDGET (slider));
-}
-
-void
-sp_color_slider_set_background (SPColorSlider *slider, guint dark, guint light, guint size)
-{
- g_return_if_fail (slider != NULL);
- g_return_if_fail (SP_IS_COLOR_SLIDER (slider));
-
- slider->b0 = dark;
- slider->b1 = light;
- slider->bmask = size;
-
- gtk_widget_queue_draw (GTK_WIDGET (slider));
-}
-
-static void
-sp_color_slider_adjustment_changed (GtkAdjustment */*adjustment*/, SPColorSlider *slider)
-{
- gtk_widget_queue_draw (GTK_WIDGET (slider));
-}
-
-static void
-sp_color_slider_adjustment_value_changed (GtkAdjustment *adjustment, SPColorSlider *slider)
-{
- GtkWidget *widget;
-
- widget = GTK_WIDGET (slider);
-
- if (slider->value != ColorScales::getScaled( adjustment )) {
- gint cx, cy, cw, ch;
- GtkStyle *style = gtk_widget_get_style(widget);
- GtkAllocation allocation;
- gtk_widget_get_allocation(widget, &allocation);
- cx = style->xthickness;
- cy = style->ythickness;
- cw = allocation.width - 2 * cx;
- ch = allocation.height - 2 * cy;
- if ((gint) (ColorScales::getScaled( adjustment ) * cw) != (gint) (slider->value * cw)) {
- gint ax, ay;
- gfloat value;
- value = slider->value;
- slider->value = ColorScales::getScaled( adjustment );
- ax = (int)(cx + value * cw - ARROW_SIZE / 2 - 2);
- ay = cy;
- gtk_widget_queue_draw_area (widget, ax, ay, ARROW_SIZE + 4, ch);
- ax = (int)(cx + slider->value * cw - ARROW_SIZE / 2 - 2);
- ay = cy;
- gtk_widget_queue_draw_area (widget, ax, ay, ARROW_SIZE + 4, ch);
- } else {
- slider->value = ColorScales::getScaled( adjustment );
- }
- }
-}
-
-static gboolean sp_color_slider_draw(GtkWidget *widget, cairo_t *cr)
-{
- SPColorSlider *slider = SP_COLOR_SLIDER(widget);
-
- gboolean colorsOnTop = Inkscape::Preferences::get()->getBool("/options/workarounds/colorsontop", false);
-
- GtkAllocation allocation;
- gtk_widget_get_allocation(widget, &allocation);
-
-#if GTK_CHECK_VERSION(3,0,0)
- GtkStyleContext *context = gtk_widget_get_style_context(widget);
-#else
- GdkWindow *window = gtk_widget_get_window(widget);
- GtkStyle *style = gtk_widget_get_style(widget);
-#endif
-
- // Draw shadow
- if (colorsOnTop) {
-#if GTK_CHECK_VERSION(3,0,0)
- gtk_render_frame(context,
- cr,
- 0, 0,
- allocation.width, allocation.height);
-#else
- gtk_paint_shadow( style, window,
- gtk_widget_get_state(widget), GTK_SHADOW_IN,
- NULL, widget, "colorslider",
- 0, 0,
- allocation.width, allocation.height);
-#endif
- }
-
- /* Paintable part of color gradient area */
- GdkRectangle carea;
-
-#if GTK_CHECK_VERSION(3,0,0)
- GtkBorder padding;
-
- gtk_style_context_get_padding(context,
- gtk_widget_get_state_flags(widget),
- &padding);
-
- carea.x = padding.left;
- carea.y = padding.top;
-#else
- carea.x = style->xthickness;
- carea.y = style->ythickness;
-#endif
-
- carea.width = allocation.width - 2 * carea.x;
- carea.height = allocation.height - 2 * carea.y;
-
- if (slider->map) {
- /* Render map pixelstore */
- gint d = (1024 << 16) / carea.width;
- gint s = 0;
-
- const guchar *b = sp_color_slider_render_map(0, 0, carea.width, carea.height,
- slider->map, s, d,
- slider->b0, slider->b1, slider->bmask);
-
- if (b != NULL && carea.width > 0) {
- GdkPixbuf *pb = gdk_pixbuf_new_from_data (b, GDK_COLORSPACE_RGB,
- 0, 8, carea.width, carea.height, carea.width * 3, NULL, NULL);
-
- gdk_cairo_set_source_pixbuf(cr, pb, carea.x, carea.y);
- cairo_paint(cr);
- g_object_unref(pb);
- }
-
- } else {
- gint c[4], dc[4];
-
- /* Render gradient */
-
- // part 1: from c0 to cm
- if (carea.width > 0) {
- for (gint i = 0; i < 4; i++) {
- c[i] = slider->c0[i] << 16;
- dc[i] = ((slider->cm[i] << 16) - c[i]) / (carea.width/2);
- }
- guint wi = carea.width/2;
- const guchar *b = sp_color_slider_render_gradient(0, 0, wi, carea.height,
- c, dc, slider->b0, slider->b1, slider->bmask);
-
- /* Draw pixelstore 1 */
- if (b != NULL && wi > 0) {
- GdkPixbuf *pb = gdk_pixbuf_new_from_data (b, GDK_COLORSPACE_RGB,
- 0, 8, wi, carea.height, wi * 3, NULL, NULL);
-
- gdk_cairo_set_source_pixbuf(cr, pb, carea.x, carea.y);
- cairo_paint(cr);
- g_object_unref(pb);
- }
- }
-
- // part 2: from cm to c1
- if (carea.width > 0) {
- for (gint i = 0; i < 4; i++) {
- c[i] = slider->cm[i] << 16;
- dc[i] = ((slider->c1[i] << 16) - c[i]) / (carea.width/2);
- }
- guint wi = carea.width/2;
- const guchar *b = sp_color_slider_render_gradient(carea.width/2, 0, wi, carea.height,
- c, dc,
- slider->b0, slider->b1, slider->bmask);
-
- /* Draw pixelstore 2 */
- if (b != NULL && wi > 0) {
- GdkPixbuf *pb = gdk_pixbuf_new_from_data (b, GDK_COLORSPACE_RGB,
- 0, 8, wi, carea.height, wi * 3, NULL, NULL);
-
- gdk_cairo_set_source_pixbuf(cr, pb, carea.width/2 + carea.x, carea.y);
- cairo_paint(cr);
-
- g_object_unref(pb);
- }
- }
- }
-
- /* Draw shadow */
- if (!colorsOnTop) {
-#if GTK_CHECK_VERSION(3,0,0)
- gtk_render_frame(context,
- cr,
- 0, 0,
- allocation.width, allocation.height);
-#else
- gtk_paint_shadow( style, window,
- gtk_widget_get_state(widget), GTK_SHADOW_IN,
- NULL, widget, "colorslider",
- 0, 0,
- allocation.width, allocation.height);
-#endif
- }
-
- /* Draw arrow */
- gint x = (int)(slider->value * (carea.width - 1) - ARROW_SIZE / 2 + carea.x);
- gint y1 = carea.y;
- gint y2 = carea.y + carea.height - 1;
- cairo_set_line_width(cr, 1.0);
-
- // Define top arrow
- cairo_move_to(cr, x - 0.5, y1 + 0.5);
- cairo_line_to(cr, x + ARROW_SIZE - 0.5, y1 + 0.5);
- cairo_line_to(cr, x + (ARROW_SIZE-1)/2.0, y1 + ARROW_SIZE/2.0 + 0.5);
- cairo_line_to(cr, x - 0.5, y1 + 0.5);
-
- // Define bottom arrow
- cairo_move_to(cr, x - 0.5, y2 + 0.5);
- cairo_line_to(cr, x + ARROW_SIZE - 0.5, y2 + 0.5);
- cairo_line_to(cr, x + (ARROW_SIZE-1)/2.0, y2 - ARROW_SIZE/2.0 + 0.5);
- cairo_line_to(cr, x - 0.5, y2 + 0.5);
-
- // Render both arrows
- cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
- cairo_stroke_preserve(cr);
- cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
- cairo_fill(cr);
-
- return FALSE;
-}
-
-/* Colors are << 16 */
-
-static const guchar *
-sp_color_slider_render_gradient (gint x0, gint y0, gint width, gint height,
- gint c[], gint dc[], guint b0, guint b1, guint mask)
-{
- static guchar *buf = NULL;
- static gint bs = 0;
- guchar *dp;
- gint x, y;
- guint r, g, b, a;
-
- if (buf && (bs < width * height)) {
- g_free (buf);
- buf = NULL;
- }
- if (!buf) {
- buf = g_new (guchar, width * height * 3);
- bs = width * height;
- }
-
- dp = buf;
- r = c[0];
- g = c[1];
- b = c[2];
- a = c[3];
- for (x = x0; x < x0 + width; x++) {
- gint cr, cg, cb, ca;
- guchar *d;
- cr = r >> 16;
- cg = g >> 16;
- cb = b >> 16;
- ca = a >> 16;
- d = dp;
- for (y = y0; y < y0 + height; y++) {
- guint bg, fc;
- /* Background value */
- bg = ((x & mask) ^ (y & mask)) ? b0 : b1;
- fc = (cr - bg) * ca;
- d[0] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
- fc = (cg - bg) * ca;
- d[1] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
- fc = (cb - bg) * ca;
- d[2] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
- d += 3 * width;
- }
- r += dc[0];
- g += dc[1];
- b += dc[2];
- a += dc[3];
- dp += 3;
- }
-
- return buf;
-}
-
-/* Positions are << 16 */
-
-static const guchar *
-sp_color_slider_render_map (gint x0, gint y0, gint width, gint height,
- guchar *map, gint start, gint step, guint b0, guint b1, guint mask)
-{
- static guchar *buf = NULL;
- static gint bs = 0;
- guchar *dp;
- gint x, y;
-
- if (buf && (bs < width * height)) {
- g_free (buf);
- buf = NULL;
- }
- if (!buf) {
- buf = g_new (guchar, width * height * 3);
- bs = width * height;
- }
-
- dp = buf;
- for (x = x0; x < x0 + width; x++) {
- gint cr, cg, cb, ca;
- guchar *d = dp;
- guchar *sp = map + 4 * (start >> 16);
- cr = *sp++;
- cg = *sp++;
- cb = *sp++;
- ca = *sp++;
- for (y = y0; y < y0 + height; y++) {
- guint bg, fc;
- /* Background value */
- bg = ((x & mask) ^ (y & mask)) ? b0 : b1;
- fc = (cr - bg) * ca;
- d[0] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
- fc = (cg - bg) * ca;
- d[1] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
- fc = (cb - bg) * ca;
- d[2] = bg + ((fc + (fc >> 8) + 0x80) >> 8);
- d += 3 * width;
- }
- dp += 3;
- start += step;
- }
-
- return buf;
-}
-
diff --git a/src/widgets/sp-color-slider.h b/src/widgets/sp-color-slider.h
deleted file mode 100644
index b81d62e41..000000000
--- a/src/widgets/sp-color-slider.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef __SP_COLOR_SLIDER_H__
-#define __SP_COLOR_SLIDER_H__
-
-/*
- * A slider with colored background
- *
- * Author:
- * Lauris Kaplinski <lauris@kaplinski.com>
- *
- * Copyright (C) 2001-2002 Lauris Kaplinski
- *
- * This code is in public domain
- */
-
-#include <gtk/gtk.h>
-
-#define SP_TYPE_COLOR_SLIDER (sp_color_slider_get_type ())
-#define SP_COLOR_SLIDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_COLOR_SLIDER, SPColorSlider))
-#define SP_COLOR_SLIDER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_COLOR_SLIDER, SPColorSliderClass))
-#define SP_IS_COLOR_SLIDER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_COLOR_SLIDER))
-#define SP_IS_COLOR_SLIDER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SP_TYPE_COLOR_SLIDER))
-
-struct SPColorSlider {
- GtkWidget widget;
-
- guint dragging : 1;
-
- GtkAdjustment *adjustment;
-
- gfloat value;
- gfloat oldvalue;
- guchar c0[4], cm[4], c1[4];
- guchar b0, b1;
- guchar bmask;
-
- gint mapsize;
- guchar *map;
-};
-
-struct SPColorSliderClass {
- GtkWidgetClass parent_class;
-
- void (* grabbed) (SPColorSlider *slider);
- void (* dragged) (SPColorSlider *slider);
- void (* released) (SPColorSlider *slider);
- void (* changed) (SPColorSlider *slider);
-};
-
-GType sp_color_slider_get_type (void);
-
-GtkWidget *sp_color_slider_new (GtkAdjustment *adjustment);
-
-void sp_color_slider_set_adjustment (SPColorSlider *slider, GtkAdjustment *adjustment);
-void sp_color_slider_set_colors (SPColorSlider *slider, guint32 start, guint32 mid, guint32 end);
-void sp_color_slider_set_map (SPColorSlider *slider, const guchar *map);
-void sp_color_slider_set_background (SPColorSlider *slider, guint dark, guint light, guint size);
-
-
-
-#endif
diff --git a/src/widgets/sp-color-wheel-selector.cpp b/src/widgets/sp-color-wheel-selector.cpp
deleted file mode 100644
index 6cfa7c14d..000000000
--- a/src/widgets/sp-color-wheel-selector.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include <math.h>
-#include <gtk/gtk.h>
-#include <glibmm/i18n.h>
-#include "ui/dialog-events.h"
-#include "sp-color-wheel-selector.h"
-#include "sp-color-scales.h"
-#include "sp-color-slider.h"
-#include "sp-color-icc-selector.h"
-#include "../svg/svg-icc-color.h"
-#include "ui/widget/gimpcolorwheel.h"
-
-G_BEGIN_DECLS
-
-static void sp_color_wheel_selector_dispose(GObject *object);
-
-static void sp_color_wheel_selector_show_all (GtkWidget *widget);
-static void sp_color_wheel_selector_hide(GtkWidget *widget);
-
-
-G_END_DECLS
-
-#define XPAD 4
-#define YPAD 1
-
-G_DEFINE_TYPE(SPColorWheelSelector, sp_color_wheel_selector, SP_TYPE_COLOR_SELECTOR);
-
-static void sp_color_wheel_selector_class_init(SPColorWheelSelectorClass *klass)
-{
- static const gchar* nameset[] = {N_("Wheel"), 0};
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass);
-
- selector_class->name = nameset;
- selector_class->submode_count = 1;
-
- object_class->dispose = sp_color_wheel_selector_dispose;
-
- widget_class->show_all = sp_color_wheel_selector_show_all;
- widget_class->hide = sp_color_wheel_selector_hide;
-}
-
-ColorWheelSelector::ColorWheelSelector( SPColorSelector* csel )
- : ColorSelector( csel ),
- _updating( FALSE ),
- _dragging( FALSE ),
- _adj(0),
- _wheel(0),
- _slider(0),
- _sbtn(0),
- _label(0)
-{
-}
-
-ColorWheelSelector::~ColorWheelSelector()
-{
- _adj = 0;
- _wheel = 0;
- _sbtn = 0;
- _label = 0;
-}
-
-void sp_color_wheel_selector_init (SPColorWheelSelector *cs)
-{
- SP_COLOR_SELECTOR(cs)->base = new ColorWheelSelector( SP_COLOR_SELECTOR(cs) );
-
- if ( SP_COLOR_SELECTOR(cs)->base )
- {
- SP_COLOR_SELECTOR(cs)->base->init();
- }
-}
-
-void ColorWheelSelector::init()
-{
- gint row = 0;
-
- _updating = FALSE;
- _dragging = FALSE;
-
-#if GTK_CHECK_VERSION(3,0,0)
- GtkWidget *t = gtk_grid_new();
-#else
- GtkWidget *t = gtk_table_new (5, 3, FALSE);
-#endif
-
- gtk_widget_show (t);
- gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 0);
-
- /* Create components */
- row = 0;
-
- _wheel = gimp_color_wheel_new();
- gtk_widget_show( _wheel );
-
-#if GTK_CHECK_VERSION(3,0,0)
- gtk_widget_set_halign(_wheel, GTK_ALIGN_FILL);
- gtk_widget_set_valign(_wheel, GTK_ALIGN_FILL);
- gtk_widget_set_hexpand(_wheel, TRUE);
- gtk_widget_set_vexpand(_wheel, TRUE);
- gtk_grid_attach(GTK_GRID(t), _wheel, 0, row, 3, 1);
-#else
- gtk_table_attach(GTK_TABLE(t), _wheel, 0, 3, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0);
-#endif
-
- row++;
-
- /* Label */
- _label = gtk_label_new_with_mnemonic (_("_A:"));
- gtk_misc_set_alignment (GTK_MISC (_label), 1.0, 0.5);
- gtk_widget_show (_label);
-
-#if GTK_CHECK_VERSION(3,0,0)
- #if GTK_CHECK_VERSION(3,12,0)
- gtk_widget_set_margin_start(_label, XPAD);
- gtk_widget_set_margin_end(_label, XPAD);
- #else
- gtk_widget_set_margin_left(_label, XPAD);
- gtk_widget_set_margin_right(_label, XPAD);
- #endif
- gtk_widget_set_margin_top(_label, YPAD);
- gtk_widget_set_margin_bottom(_label, YPAD);
- gtk_widget_set_halign(_label, GTK_ALIGN_FILL);
- gtk_widget_set_valign(_label, GTK_ALIGN_FILL);
- gtk_grid_attach(GTK_GRID(t), _label, 0, row, 1, 1);
-#else
- gtk_table_attach (GTK_TABLE (t), _label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD);
-#endif
-
- /* Adjustment */
- _adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 255.0, 1.0, 10.0, 10.0));
-
- /* Slider */
- _slider = sp_color_slider_new (_adj);
- gtk_widget_set_tooltip_text (_slider, _("Alpha (opacity)"));
- gtk_widget_show (_slider);
-
-#if GTK_CHECK_VERSION(3,0,0)
- #if GTK_CHECK_VERSION(3,12,0)
- gtk_widget_set_margin_start(_slider, XPAD);
- gtk_widget_set_margin_end(_slider, XPAD);
- #else
- gtk_widget_set_margin_left(_slider, XPAD);
- gtk_widget_set_margin_right(_slider, XPAD);
- #endif
- gtk_widget_set_margin_top(_slider, YPAD);
- gtk_widget_set_margin_bottom(_slider, YPAD);
- gtk_widget_set_hexpand(_slider, TRUE);
- gtk_widget_set_halign(_slider, GTK_ALIGN_FILL);
- gtk_widget_set_valign(_slider, GTK_ALIGN_FILL);
- gtk_grid_attach(GTK_GRID(t), _slider, 1, row, 1, 1);
-#else
- gtk_table_attach(GTK_TABLE (t), _slider, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, XPAD, YPAD);
-#endif
-
- sp_color_slider_set_colors (SP_COLOR_SLIDER (_slider),
- SP_RGBA32_F_COMPOSE (1.0, 1.0, 1.0, 0.0),
- SP_RGBA32_F_COMPOSE (1.0, 1.0, 1.0, 0.5),
- SP_RGBA32_F_COMPOSE (1.0, 1.0, 1.0, 1.0));
-
-
- /* Spinbutton */
- _sbtn = gtk_spin_button_new (GTK_ADJUSTMENT (_adj), 1.0, 0);
- gtk_widget_set_tooltip_text (_sbtn, _("Alpha (opacity)"));
- sp_dialog_defocus_on_enter (_sbtn);
- gtk_label_set_mnemonic_widget (GTK_LABEL(_label), _sbtn);
- gtk_widget_show (_sbtn);
-
-#if GTK_CHECK_VERSION(3,0,0)
- #if GTK_CHECK_VERSION(3,12,0)
- gtk_widget_set_margin_start(_sbtn, XPAD);
- gtk_widget_set_margin_end(_sbtn, XPAD);
- #else
- gtk_widget_set_margin_left(_sbtn, XPAD);
- gtk_widget_set_margin_right(_sbtn, XPAD);
- #endif
- gtk_widget_set_margin_top(_sbtn, YPAD);
- gtk_widget_set_margin_bottom(_sbtn, YPAD);
- gtk_widget_set_halign(_sbtn, GTK_ALIGN_CENTER);
- gtk_widget_set_valign(_sbtn, GTK_ALIGN_CENTER);
- gtk_grid_attach(GTK_GRID(t), _sbtn, 2, row, 1, 1);
-#else
- gtk_table_attach (GTK_TABLE (t), _sbtn, 2, 3, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD);
-#endif
-
- /* Signals */
- g_signal_connect (G_OBJECT (_adj), "value_changed",
- G_CALLBACK (_adjustmentChanged), _csel);
-
- g_signal_connect (G_OBJECT (_slider), "grabbed",
- G_CALLBACK (_sliderGrabbed), _csel);
- g_signal_connect (G_OBJECT (_slider), "released",
- G_CALLBACK (_sliderReleased), _csel);
- g_signal_connect (G_OBJECT (_slider), "changed",
- G_CALLBACK (_sliderChanged), _csel);
-
- g_signal_connect( G_OBJECT(_wheel), "changed",
- G_CALLBACK (_wheelChanged), _csel );
-}
-
-static void sp_color_wheel_selector_dispose(GObject *object)
-{
- if (G_OBJECT_CLASS(sp_color_wheel_selector_parent_class)->dispose)
- G_OBJECT_CLASS(sp_color_wheel_selector_parent_class)->dispose(object);
-}
-
-static void
-sp_color_wheel_selector_show_all (GtkWidget *widget)
-{
- gtk_widget_show (widget);
-}
-
-static void sp_color_wheel_selector_hide(GtkWidget *widget)
-{
- gtk_widget_hide(widget);
-}
-
-GtkWidget *sp_color_wheel_selector_new()
-{
- SPColorWheelSelector *csel = SP_COLOR_WHEEL_SELECTOR(g_object_new (SP_TYPE_COLOR_WHEEL_SELECTOR, NULL));
-
- return GTK_WIDGET (csel);
-}
-
-/* Helpers for setting color value */
-
-static void preserve_icc(SPColor *color, SPColorWheelSelector *cs){
- ColorSelector* selector = static_cast<ColorSelector*>(SP_COLOR_SELECTOR(cs)->base);
- color->icc = selector->getColor().icc ? new SVGICCColor(*selector->getColor().icc) : 0;
-}
-
-void ColorWheelSelector::_colorChanged()
-{
-#ifdef DUMP_CHANGE_INFO
- g_message("ColorWheelSelector::_colorChanged( this=%p, %f, %f, %f, %f)", this, color.v.c[0], color.v.c[1], color.v.c[2], alpha );
-#endif
- _updating = TRUE;
- {
- float hsv[3] = {0,0,0};
- sp_color_rgb_to_hsv_floatv(hsv, _color.v.c[0], _color.v.c[1], _color.v.c[2]);
- gimp_color_wheel_set_color( GIMP_COLOR_WHEEL(_wheel), hsv[0], hsv[1], hsv[2] );
- }
-
- guint32 start = _color.toRGBA32( 0x00 );
- guint32 mid = _color.toRGBA32( 0x7f );
- guint32 end = _color.toRGBA32( 0xff );
-
- sp_color_slider_set_colors(SP_COLOR_SLIDER(_slider), start, mid, end);
-
- ColorScales::setScaled(_adj, _alpha);
-
- _updating = FALSE;
-}
-
-void ColorWheelSelector::_adjustmentChanged( GtkAdjustment *adjustment, SPColorWheelSelector *cs )
-{
-// TODO check this. It looks questionable:
- // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255 or 0..100
- gdouble value = gtk_adjustment_get_value (adjustment);
- gdouble upper = gtk_adjustment_get_upper (adjustment);
-
- if (value > 0.0 && value < 1.0) {
- gtk_adjustment_set_value( adjustment, floor (value * upper + 0.5) );
- }
-
- ColorWheelSelector* wheelSelector = static_cast<ColorWheelSelector*>(SP_COLOR_SELECTOR(cs)->base);
- if (wheelSelector->_updating) return;
-
- wheelSelector->_updating = TRUE;
-
- preserve_icc(&wheelSelector->_color, cs);
- wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging );
-
- wheelSelector->_updating = FALSE;
-}
-
-void ColorWheelSelector::_sliderGrabbed( SPColorSlider *slider, SPColorWheelSelector *cs )
-{
- (void)slider;
- ColorWheelSelector* wheelSelector = static_cast<ColorWheelSelector*>(SP_COLOR_SELECTOR(cs)->base);
- if (!wheelSelector->_dragging) {
- wheelSelector->_dragging = TRUE;
- wheelSelector->_grabbed();
-
- preserve_icc(&wheelSelector->_color, cs);
- wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging );
- }
-}
-
-void ColorWheelSelector::_sliderReleased( SPColorSlider *slider, SPColorWheelSelector *cs )
-{
- (void)slider;
- ColorWheelSelector* wheelSelector = static_cast<ColorWheelSelector*>(SP_COLOR_SELECTOR(cs)->base);
- if (wheelSelector->_dragging) {
- wheelSelector->_dragging = FALSE;
- wheelSelector->_released();
-
- preserve_icc(&wheelSelector->_color, cs);
- wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging );
- }
-}
-
-void ColorWheelSelector::_sliderChanged( SPColorSlider *slider, SPColorWheelSelector *cs )
-{
- (void)slider;
- ColorWheelSelector* wheelSelector = static_cast<ColorWheelSelector*>(SP_COLOR_SELECTOR(cs)->base);
-
- preserve_icc(&wheelSelector->_color, cs);
- wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging );
-}
-
-void ColorWheelSelector::_wheelChanged( GimpColorWheel *wheel, SPColorWheelSelector *cs )
-{
- ColorWheelSelector* wheelSelector = static_cast<ColorWheelSelector*>(SP_COLOR_SELECTOR(cs)->base);
-
- gdouble h = 0;
- gdouble s = 0;
- gdouble v = 0;
- gimp_color_wheel_get_color( wheel, &h, &s, &v );
-
- float rgb[3] = {0,0,0};
- sp_color_hsv_to_rgb_floatv (rgb, h, s, v);
-
- SPColor color(rgb[0], rgb[1], rgb[2]);
-
- guint32 start = color.toRGBA32( 0x00 );
- guint32 mid = color.toRGBA32( 0x7f );
- guint32 end = color.toRGBA32( 0xff );
-
- sp_color_slider_set_colors (SP_COLOR_SLIDER(wheelSelector->_slider), start, mid, end);
-
- preserve_icc(&color, cs);
- wheelSelector->_updateInternals( color, wheelSelector->_alpha, gimp_color_wheel_is_adjusting(wheel) );
-}
-
-
-/*
- 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/widgets/sp-color-wheel-selector.h b/src/widgets/sp-color-wheel-selector.h
deleted file mode 100644
index 12b060dbe..000000000
--- a/src/widgets/sp-color-wheel-selector.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef SEEN_SP_COLOR_WHEEL_SELECTOR_H
-#define SEEN_SP_COLOR_WHEEL_SELECTOR_H
-
-#include <gtk/gtk.h>
-
-#include "sp-color-selector.h"
-
-typedef struct _GimpColorWheel GimpColorWheel;
-struct SPColorSlider;
-struct SPColorWheelSelector;
-struct SPColorWheelSelectorClass;
-
-class ColorWheelSelector: public ColorSelector
-{
-public:
- ColorWheelSelector( SPColorSelector* csel );
- virtual ~ColorWheelSelector();
-
- virtual void init();
-
-protected:
- virtual void _colorChanged();
-
- static void _adjustmentChanged ( GtkAdjustment *adjustment, SPColorWheelSelector *cs );
-
- static void _sliderGrabbed( SPColorSlider *slider, SPColorWheelSelector *cs );
- static void _sliderReleased( SPColorSlider *slider, SPColorWheelSelector *cs );
- static void _sliderChanged( SPColorSlider *slider, SPColorWheelSelector *cs );
- static void _wheelChanged( GimpColorWheel *wheel, SPColorWheelSelector *cs );
-
- static void _fooChanged( GtkWidget foo, SPColorWheelSelector *cs );
-
- void _recalcColor( gboolean changing );
-
- gboolean _updating : 1;
- gboolean _dragging : 1;
- GtkAdjustment* _adj; // Channel adjustment
- GtkWidget* _wheel;
- GtkWidget* _slider;
- GtkWidget* _sbtn; // Spinbutton
- GtkWidget* _label; // Label
-
-private:
- // By default, disallow copy constructor and assignment operator
- ColorWheelSelector( const ColorWheelSelector& obj );
- ColorWheelSelector& operator=( const ColorWheelSelector& obj );
-};
-
-
-
-#define SP_TYPE_COLOR_WHEEL_SELECTOR (sp_color_wheel_selector_get_type ())
-#define SP_COLOR_WHEEL_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_COLOR_WHEEL_SELECTOR, SPColorWheelSelector))
-#define SP_COLOR_WHEEL_SELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_COLOR_WHEEL_SELECTOR, SPColorWheelSelectorClass))
-#define SP_IS_COLOR_WHEEL_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_COLOR_WHEEL_SELECTOR))
-#define SP_IS_COLOR_WHEEL_SELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SP_TYPE_COLOR_WHEEL_SELECTOR))
-
-struct SPColorWheelSelector {
- SPColorSelector parent;
-};
-
-struct SPColorWheelSelectorClass {
- SPColorSelectorClass parent_class;
-};
-
-GType sp_color_wheel_selector_get_type (void);
-
-GtkWidget *sp_color_wheel_selector_new (void);
-
-
-
-#endif // SEEN_SP_COLOR_WHEEL_SELECTOR_H
-
-/*
- 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/widgets/swatch-selector.cpp b/src/widgets/swatch-selector.cpp
index 7178ad072..6f2807255 100644
--- a/src/widgets/swatch-selector.cpp
+++ b/src/widgets/swatch-selector.cpp
@@ -5,11 +5,11 @@
#include "document-undo.h"
#include "gradient-chemistry.h"
#include "gradient-selector.h"
-#include "sp-color-notebook.h"
#include "sp-stop.h"
#include "svg/css-ostringstream.h"
#include "svg/svg-color.h"
#include "verbs.h"
+#include "ui/widget/color-notebook.h"
#include "xml/node.h"
namespace Inkscape
@@ -20,8 +20,10 @@ namespace Widgets
SwatchSelector::SwatchSelector() :
Gtk::VBox(),
_gsel(0),
- _csel(0)
+ _updating_color(false)
{
+ using Inkscape::UI::Widget::ColorNotebook;
+
GtkWidget *gsel = sp_gradient_selector_new();
_gsel = SP_GRADIENT_SELECTOR(gsel);
g_object_set_data( G_OBJECT(gobj()), "base", this );
@@ -31,27 +33,18 @@ SwatchSelector::SwatchSelector() :
pack_start(*Gtk::manage(Glib::wrap(gsel)));
+ Gtk::Widget *color_selector = Gtk::manage(new ColorNotebook(_selected_color));
+ color_selector->show();
+ pack_start(*color_selector);
- GtkWidget *csel = sp_color_selector_new( SP_TYPE_COLOR_NOTEBOOK );
- _csel = SP_COLOR_SELECTOR(csel);
- Gtk::Widget *wrappedCSel = Glib::wrap(csel);
- wrappedCSel->show();
- //gtk_widget_show(csel);
-
-
- GObject *obj = G_OBJECT(csel);
-
- g_signal_connect(obj, "grabbed", G_CALLBACK(_grabbedCb), this);
- g_signal_connect(obj, "dragged", G_CALLBACK(_draggedCb), this);
- g_signal_connect(obj, "released", G_CALLBACK(_releasedCb), this);
- g_signal_connect(obj, "changed", G_CALLBACK(_changedCb), this);
-
- pack_start(*Gtk::manage(wrappedCSel));
+ _selected_color.signal_grabbed.connect(sigc::mem_fun(this, &SwatchSelector::_grabbedCb));
+ _selected_color.signal_dragged.connect(sigc::mem_fun(this, &SwatchSelector::_draggedCb));
+ _selected_color.signal_released.connect(sigc::mem_fun(this, &SwatchSelector::_releasedCb));
+ _selected_color.signal_changed.connect(sigc::mem_fun(this, &SwatchSelector::_changedCb));
}
SwatchSelector::~SwatchSelector()
{
- _csel = 0; // dtor should be handled by Gtk::manage()
_gsel = 0;
}
@@ -60,13 +53,13 @@ SPGradientSelector *SwatchSelector::getGradientSelector()
return _gsel;
}
-void SwatchSelector::_grabbedCb(SPColorSelector * /*csel*/, void * /*data*/)
+void SwatchSelector::_grabbedCb()
{
}
-void SwatchSelector::_draggedCb(SPColorSelector * /*csel*/, void *data)
+void SwatchSelector::_draggedCb()
{
- if (data) {
+ // if (data) {
//SwatchSelector *swsel = reinterpret_cast<SwatchSelector*>(data);
// TODO might have to block cycles
@@ -92,50 +85,46 @@ void SwatchSelector::_draggedCb(SPColorSelector * /*csel*/, void *data)
}
}
*/
- }
+ // }
}
-void SwatchSelector::_releasedCb(SPColorSelector * /*csel*/, void * /*data*/)
+void SwatchSelector::_releasedCb()
{
}
-void SwatchSelector::_changedCb(SPColorSelector */*csel*/, void *data)
+void SwatchSelector::_changedCb()
{
- if (data) {
- SwatchSelector *swsel = reinterpret_cast<SwatchSelector*>(data);
+ if (_updating_color) {
+ return;
+ }
+ // TODO might have to block cycles
+
+ if (_gsel && _gsel->getVector()) {
+ SPGradient *gradient = _gsel->getVector();
+ SPGradient *ngr = sp_gradient_ensure_vector_normalized(gradient);
+ if (ngr != gradient) {
+ /* Our master gradient has changed */
+ // TODO replace with proper - sp_gradient_vector_widget_load_gradient(GTK_WIDGET(swsel->_gsel), ngr);
+ }
- // TODO might have to block cycles
+ ngr->ensureVector();
- if (swsel->_gsel && swsel->_gsel->getVector()) {
- SPGradient *gradient = swsel->_gsel->getVector();
- SPGradient *ngr = sp_gradient_ensure_vector_normalized(gradient);
- if (ngr != gradient) {
- /* Our master gradient has changed */
- // TODO replace with proper - sp_gradient_vector_widget_load_gradient(GTK_WIDGET(swsel->_gsel), ngr);
- }
- ngr->ensureVector();
+ SPStop* stop = ngr->getFirstStop();
+ if (stop) {
+ SPColor color = _selected_color.color();
+ gfloat alpha = _selected_color.alpha();
+ guint32 rgb = color.toRGBA32( 0x00 );
+ // TODO replace with generic shared code that also handles icc-color
+ Inkscape::CSSOStringStream os;
+ gchar c[64];
+ sp_svg_write_color(c, sizeof(c), rgb);
+ os << "stop-color:" << c << ";stop-opacity:" << static_cast<gdouble>(alpha) <<";";
+ stop->getRepr()->setAttribute("style", os.str().c_str());
- SPStop* stop = ngr->getFirstStop();
- if (stop) {
- SPColor color;
- float alpha = 0;
- guint32 rgb = 0;
-
- swsel->_csel->base->getColorAlpha( color, alpha );
- rgb = color.toRGBA32( 0x00 );
-
- // TODO replace with generic shared code that also handles icc-color
- Inkscape::CSSOStringStream os;
- gchar c[64];
- sp_svg_write_color(c, sizeof(c), rgb);
- os << "stop-color:" << c << ";stop-opacity:" << static_cast<gdouble>(alpha) <<";";
- stop->getRepr()->setAttribute("style", os.str().c_str());
-
- DocumentUndo::done(ngr->document, SP_VERB_CONTEXT_GRADIENT,
- _("Change swatch color"));
- }
+ DocumentUndo::done(ngr->document, SP_VERB_CONTEXT_GRADIENT,
+ _("Change swatch color"));
}
}
}
@@ -173,11 +162,10 @@ void SwatchSelector::setVector(SPDocument */*doc*/, SPGradient *vector)
SPStop* stop = vector->getFirstStop();
guint32 const colorVal = stop->get_rgba32();
- _csel->base->setAlpha(SP_RGBA32_A_F(colorVal));
- SPColor color( SP_RGBA32_R_F(colorVal), SP_RGBA32_G_F(colorVal), SP_RGBA32_B_F(colorVal) );
- // set its color, from the stored array
- _csel->base->setColor( color );
- gtk_widget_show_all( GTK_WIDGET(_csel) );
+ _updating_color = true;
+ _selected_color.setValue(colorVal);
+ _updating_color = false;
+ // gtk_widget_show_all( GTK_WIDGET(_csel) );
} else {
//gtk_widget_hide( GTK_WIDGET(_csel) );
}
diff --git a/src/widgets/swatch-selector.h b/src/widgets/swatch-selector.h
index 4b7aa483f..16a8cfac8 100644
--- a/src/widgets/swatch-selector.h
+++ b/src/widgets/swatch-selector.h
@@ -2,6 +2,7 @@
#define SEEN_SP_SWATCH_SELECTOR_H
#include <gtkmm/box.h>
+#include "ui/selected-color.h"
class SPDocument;
class SPGradient;
@@ -29,13 +30,14 @@ public:
SPGradientSelector *getGradientSelector();
private:
- static void _grabbedCb(SPColorSelector *csel, void *data);
- static void _draggedCb(SPColorSelector *csel, void *data);
- static void _releasedCb(SPColorSelector *csel, void *data);
- static void _changedCb(SPColorSelector *csel, void *data);
+ void _grabbedCb();
+ void _draggedCb();
+ void _releasedCb();
+ void _changedCb();
SPGradientSelector *_gsel;
- SPColorSelector *_csel;
+ Inkscape::UI::SelectedColor _selected_color;
+ bool _updating_color;
};