diff options
| author | Johan B. C. Engelen <jbc.engelen@swissonline.ch> | 2011-02-21 22:28:50 +0000 |
|---|---|---|
| committer | Johan Engelen <goejendaagh@zonnet.nl> | 2011-02-21 22:28:50 +0000 |
| commit | 4a4047fdd90aede6d16c020ddcd70c57ea4aa218 (patch) | |
| tree | e43b214f3025b953644385c301a03a4d2f3b1dbf /src/display | |
| parent | Finished cleanup of outdated SP_OBJECT_PARENT C macro. (diff) | |
| download | inkscape-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_insert | 2 | ||||
| -rw-r--r-- | src/display/grayscale.cpp | 91 | ||||
| -rw-r--r-- | src/display/grayscale.h | 40 | ||||
| -rw-r--r-- | src/display/nr-arena-glyphs.cpp | 14 | ||||
| -rw-r--r-- | src/display/nr-arena-item.cpp | 2 | ||||
| -rw-r--r-- | src/display/nr-arena-shape.cpp | 14 | ||||
| -rw-r--r-- | src/display/nr-arena.cpp | 3 | ||||
| -rw-r--r-- | src/display/nr-arena.h | 1 | ||||
| -rw-r--r-- | src/display/rendermode.h | 9 | ||||
| -rw-r--r-- | src/display/sp-canvas.h | 1 |
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; |
