summaryrefslogtreecommitdiffstats
path: root/src/display
diff options
context:
space:
mode:
authorJohan B. C. Engelen <jbc.engelen@swissonline.ch>2011-02-21 22:28:50 +0000
committerJohan Engelen <goejendaagh@zonnet.nl>2011-02-21 22:28:50 +0000
commit4a4047fdd90aede6d16c020ddcd70c57ea4aa218 (patch)
treee43b214f3025b953644385c301a03a4d2f3b1dbf /src/display
parentFinished cleanup of outdated SP_OBJECT_PARENT C macro. (diff)
downloadinkscape-4a4047fdd90aede6d16c020ddcd70c57ea4aa218.tar.gz
inkscape-4a4047fdd90aede6d16c020ddcd70c57ea4aa218.zip
NEW: Grayscale color display mode. (toggle assigned keybinding: Shift+keypad5)
(bzr r10065)
Diffstat (limited to 'src/display')
-rw-r--r--src/display/Makefile_insert2
-rw-r--r--src/display/grayscale.cpp91
-rw-r--r--src/display/grayscale.h40
-rw-r--r--src/display/nr-arena-glyphs.cpp14
-rw-r--r--src/display/nr-arena-item.cpp2
-rw-r--r--src/display/nr-arena-shape.cpp14
-rw-r--r--src/display/nr-arena.cpp3
-rw-r--r--src/display/nr-arena.h1
-rw-r--r--src/display/rendermode.h9
-rw-r--r--src/display/sp-canvas.h1
10 files changed, 168 insertions, 9 deletions
diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert
index b50a71033..370e28d6d 100644
--- a/src/display/Makefile_insert
+++ b/src/display/Makefile_insert
@@ -37,6 +37,8 @@ ink_common_sources += \
display/curve.h \
display/gnome-canvas-acetate.cpp \
display/gnome-canvas-acetate.h \
+ display/grayscale.cpp \
+ display/grayscale.h \
display/guideline.cpp \
display/guideline.h \
display/nr-plain-stuff-gdk.cpp \
diff --git a/src/display/grayscale.cpp b/src/display/grayscale.cpp
new file mode 100644
index 000000000..af3a781b0
--- /dev/null
+++ b/src/display/grayscale.cpp
@@ -0,0 +1,91 @@
+/** \file
+ * Provide methods to calculate grayscale values (e.g. convert rgba value to grayscale rgba value)
+ */
+
+/*
+ * Author:
+ * Johan Engelen <goejendaagh@zonnet.nl>
+ *
+ * Copyright (C) 2011 Author
+ *
+ * Released under GNU GPL
+ */
+
+#include "display/grayscale.h"
+#include "color.h"
+
+// for activeDesktopIsGrayscale:
+#include "display/rendermode.h"
+#include "inkscape.h"
+#include "desktop.h"
+
+namespace Grayscale {
+
+guint32 process(guint32 rgba) {
+ return process(SP_RGBA32_R_U(rgba), SP_RGBA32_G_U(rgba), SP_RGBA32_B_U(rgba), SP_RGBA32_A_U(rgba));
+}
+
+guint32 process(guchar r, guchar g, guchar b, guchar a) {
+ float red_factor = 0.3;
+ float green_factor = 0.59;
+ float blue_factor = 0.11;
+
+ /** To reduce banding in gradients, this calculation is tweaked a bit
+ * by outputing blue+1 or red+1 or both. The luminance is calculated
+ * times 4. Then last two bits are used to determine if red and/or blue
+ * can be increased by one. Then these two bits are discarded.
+ * So the output color it still looks gray, but has more than 256 steps.
+ * The assumption is that the eye is most sensitive to green, then red, then blue.
+ * (hope this trick works :-) Johan)
+ */
+
+ guint32 luminance = ( red_factor * (r << 3)
+ + green_factor * (g << 3)
+ + blue_factor * (b << 3) );
+ unsigned blue_plus_one = (luminance & 0x01) ? 1 : 0;
+ unsigned red_plus_one = (luminance & 0x02) ? 1 : 0;
+ unsigned green_plus_one = (luminance & 0x04) ? 1 : 0;
+ luminance = luminance >> 3;
+
+ if (luminance >= 0xff) {
+ return SP_RGBA32_U_COMPOSE(0xff, 0xff, 0xff, a);
+ } else {
+ return SP_RGBA32_U_COMPOSE(luminance + red_plus_one, luminance + green_plus_one, luminance + blue_plus_one, a);
+ }
+}
+
+guchar luminance(guchar r, guchar g, guchar b) {
+ guint32 luminance = ( red_factor * r
+ + green_factor * g
+ + blue_factor * b );
+ if (luminance > 0xff) {
+ luminance = 0xff;
+ }
+
+ return luminance & 0xff;
+}
+
+/** @brief Use this method if there is no other way to find out if grayscale view or not
+ *
+ * In some cases, the choice between normal or grayscale is so deep in the code hierarchy,
+ * that it is not possible to determine whether grayscale is desired or not, without using
+ * the global SP_ACTIVE_DESKTOP macro. Then use this method, so we know where the abuse is
+ * happening...
+ */
+bool activeDesktopIsGrayscale() {
+ return (SP_ACTIVE_DESKTOP->getColorMode() == Inkscape::COLORRENDERMODE_GRAYSCALE);
+}
+
+
+};
+
+/*
+ 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/display/grayscale.h b/src/display/grayscale.h
new file mode 100644
index 000000000..855c9e465
--- /dev/null
+++ b/src/display/grayscale.h
@@ -0,0 +1,40 @@
+#ifndef SEEN_DISPLAY_GRAYSCALE_H
+#define SEEN_DISPLAY_GRAYSCALE_H
+
+/** \file
+ * Provide methods to calculate grayscale values (e.g. convert rgba value to grayscale rgba value)
+ *
+ * Author:
+ * Johan Engelen <goejendaagh@zonnet.nl>
+ *
+ * Copyright (C) 2011 Author
+ *
+ * Released under GNU GPL
+ */
+
+#include <gdk/gdktypes.h>
+
+namespace Grayscale {
+ guint32 process(guint32 rgba);
+ guint32 process(guchar r, guchar g, guchar b, guchar a);
+ guchar luminance(guchar r, guchar g, guchar b);
+
+ const float red_factor = 0.3;
+ const float green_factor = 0.59;
+ const float blue_factor = 0.11;
+
+ bool activeDesktopIsGrayscale();
+};
+
+#endif /* !SEEN_DISPLAY_GRAYSCALE_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/display/nr-arena-glyphs.cpp b/src/display/nr-arena-glyphs.cpp
index 440a87012..42bca7d94 100644
--- a/src/display/nr-arena-glyphs.cpp
+++ b/src/display/nr-arena-glyphs.cpp
@@ -24,6 +24,7 @@
#include "nr-arena-glyphs.h"
#include <cairo.h>
#include "inkscape-cairo.h"
+#include "display/grayscale.h"
#ifdef test_glyph_liv
#include "../display/canvas-bpath.h"
@@ -444,7 +445,8 @@ nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPi
SPStyle const *style = ggroup->style;
guint ret = item->state;
- bool print_colors_preview = (item->arena->rendermode == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW);
+ bool print_colors_preview = (item->arena->colorrendermode == Inkscape::COLORRENDERMODE_PRINT_COLORS_PREVIEW);
+ bool grayscale = (item->arena->colorrendermode == Inkscape::COLORRENDERMODE_GRAYSCALE);
if (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE) {
@@ -513,8 +515,11 @@ nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPi
rgba = style->fill.value.color.toRGBA32( SP_SCALE24_TO_FLOAT(style->fill_opacity.value) );
}
- if (print_colors_preview)
+ if (print_colors_preview) {
nr_arena_separate_color_plates(&rgba);
+ } else if (grayscale) {
+ rgba = Grayscale::process(rgba);
+ }
nr_blit_pixblock_mask_rgba32(pb, &m, rgba);
pb->empty = FALSE;
@@ -557,8 +562,11 @@ nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPi
rgba = style->stroke.value.color.toRGBA32( SP_SCALE24_TO_FLOAT(style->stroke_opacity.value) );
}
- if (print_colors_preview)
+ if (print_colors_preview) {
nr_arena_separate_color_plates(&rgba);
+ } else if (grayscale) {
+ rgba = Grayscale::process(rgba);
+ }
nr_blit_pixblock_mask_rgba32(pb, &m, rgba);
pb->empty = FALSE;
diff --git a/src/display/nr-arena-item.cpp b/src/display/nr-arena-item.cpp
index c74e2baa0..6a5b7b5ba 100644
--- a/src/display/nr-arena-item.cpp
+++ b/src/display/nr-arena-item.cpp
@@ -314,7 +314,7 @@ nr_arena_item_invoke_render (cairo_t *ct, NRArenaItem *item, NRRectL const *area
bool outline = (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE);
bool filter = (item->arena->rendermode != Inkscape::RENDERMODE_OUTLINE &&
item->arena->rendermode != Inkscape::RENDERMODE_NO_FILTERS);
- bool print_colors = (item->arena->rendermode == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW);
+ bool print_colors = (item->arena->colorrendermode == Inkscape::COLORRENDERMODE_PRINT_COLORS_PREVIEW);
nr_return_val_if_fail (item != NULL, NR_ARENA_ITEM_STATE_INVALID);
nr_return_val_if_fail (NR_IS_ARENA_ITEM (item),
diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp
index 1f516c066..33a218e99 100644
--- a/src/display/nr-arena-shape.cpp
+++ b/src/display/nr-arena-shape.cpp
@@ -24,6 +24,7 @@
#include "display/nr-arena.h"
#include "display/nr-arena-shape.h"
#include "display/curve.h"
+#include "display/grayscale.h"
#include "libnr/nr-pixops.h"
#include "libnr/nr-blit.h"
#include "libnr/nr-convert2geom.h"
@@ -843,7 +844,8 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock
if (!shape->style) return item->state;
bool outline = (NR_ARENA_ITEM(shape)->arena->rendermode == Inkscape::RENDERMODE_OUTLINE);
- bool print_colors_preview = (NR_ARENA_ITEM(shape)->arena->rendermode == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW);
+ bool print_colors_preview = (NR_ARENA_ITEM(shape)->arena->colorrendermode == Inkscape::COLORRENDERMODE_PRINT_COLORS_PREVIEW);
+ bool grayscale = (NR_ARENA_ITEM(shape)->arena->colorrendermode == Inkscape::COLORRENDERMODE_GRAYSCALE);
if (outline) { // cairo outline rendering
@@ -903,8 +905,11 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock
rgba = fill_color->toRGBA32( shape->_fill.opacity );
}
- if (print_colors_preview)
+ if (print_colors_preview) {
nr_arena_separate_color_plates(&rgba);
+ } else if (grayscale) {
+ rgba = Grayscale::process(rgba);
+ }
nr_blit_pixblock_mask_rgba32(pb, &m, rgba);
pb->empty = FALSE;
@@ -944,8 +949,11 @@ nr_arena_shape_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPixBlock
rgba = stroke_color->toRGBA32( shape->_stroke.opacity );
}
- if (print_colors_preview)
+ if (print_colors_preview) {
nr_arena_separate_color_plates(&rgba);
+ } else if (grayscale) {
+ rgba = Grayscale::process(rgba);
+ }
nr_blit_pixblock_mask_rgba32(pb, &m, rgba);
pb->empty = FALSE;
diff --git a/src/display/nr-arena.cpp b/src/display/nr-arena.cpp
index 85de5c119..837bc0d86 100644
--- a/src/display/nr-arena.cpp
+++ b/src/display/nr-arena.cpp
@@ -58,6 +58,7 @@ nr_arena_init (NRArena *arena)
arena->delta = 0; // to be set by desktop from prefs
arena->renderoffscreen = false; // use render values from preferences otherwise render exact
arena->rendermode = Inkscape::RENDERMODE_NORMAL; // default is normal render
+ arena->colorrendermode = Inkscape::COLORRENDERMODE_NORMAL; // default is normal color
arena->blurquality = BLUR_QUALITY_NORMAL;
arena->filterquality = Inkscape::Filters::FILTER_QUALITY_NORMAL;
arena->outlinecolor = 0xff; // black; to be set by desktop from bg color
@@ -88,6 +89,7 @@ nr_arena_request_update (NRArena *arena, NRArenaItem *item)
arena->blurquality = BLUR_QUALITY_BEST;
arena->filterquality = Inkscape::Filters::FILTER_QUALITY_BEST;
arena->rendermode = Inkscape::RENDERMODE_NORMAL;
+ arena->colorrendermode = Inkscape::COLORRENDERMODE_NORMAL;
}
if (aobject->callbacks) {
@@ -119,6 +121,7 @@ nr_arena_request_render_rect (NRArena *arena, NRRectL *area)
arena->blurquality = BLUR_QUALITY_BEST;
arena->filterquality = Inkscape::Filters::FILTER_QUALITY_BEST;
arena->rendermode = Inkscape::RENDERMODE_NORMAL;
+ arena->colorrendermode = Inkscape::COLORRENDERMODE_NORMAL;
}
if (aobject->callbacks && area && !nr_rect_l_test_empty_ptr(area)) {
for (unsigned int i = 0; i < aobject->callbacks->length; i++) {
diff --git a/src/display/nr-arena.h b/src/display/nr-arena.h
index d2f9dc246..bd6c3029d 100644
--- a/src/display/nr-arena.h
+++ b/src/display/nr-arena.h
@@ -48,6 +48,7 @@ struct NRArena : public NRActiveObject {
double delta;
bool renderoffscreen; // if true then rendering must be exact
Inkscape::RenderMode rendermode;
+ Inkscape::ColorRenderMode colorrendermode;
int blurquality; // will be updated during update from preferences
int filterquality; // will be updated during update from preferences
diff --git a/src/display/rendermode.h b/src/display/rendermode.h
index abcdb3db4..8fc022bfb 100644
--- a/src/display/rendermode.h
+++ b/src/display/rendermode.h
@@ -12,8 +12,13 @@ namespace Inkscape {
enum RenderMode {
RENDERMODE_NORMAL,
RENDERMODE_NO_FILTERS,
- RENDERMODE_OUTLINE,
- RENDERMODE_PRINT_COLORS_PREVIEW
+ RENDERMODE_OUTLINE
+};
+
+enum ColorRenderMode {
+ COLORRENDERMODE_NORMAL,
+ COLORRENDERMODE_GRAYSCALE,
+ COLORRENDERMODE_PRINT_COLORS_PREVIEW
};
}
diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h
index 7ecbe0451..3a0b56585 100644
--- a/src/display/sp-canvas.h
+++ b/src/display/sp-canvas.h
@@ -143,6 +143,7 @@ struct SPCanvas {
bool drawing_disabled;
int rendermode;
+ int colorrendermode;
#if ENABLE_LCMS
bool enable_cms_display_adj;