diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-04-08 02:42:29 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2011-04-08 02:42:29 +0000 |
| commit | 88b520a809dea1e5a6ca21bcbad962bc58deb0c3 (patch) | |
| tree | 205342b685bdf533d8f05851dcfc98ee64f37acc | |
| parent | Merge from trunk (diff) | |
| download | inkscape-88b520a809dea1e5a6ca21bcbad962bc58deb0c3.tar.gz inkscape-88b520a809dea1e5a6ca21bcbad962bc58deb0c3.zip | |
Fix color-managed view
(bzr r9508.1.74)
| -rw-r--r-- | src/color-profile-fns.h | 1 | ||||
| -rw-r--r-- | src/color-profile.cpp | 73 | ||||
| -rw-r--r-- | src/display/sp-canvas.cpp | 107 |
3 files changed, 60 insertions, 121 deletions
diff --git a/src/color-profile-fns.h b/src/color-profile-fns.h index 3d22417f6..defc58f2c 100644 --- a/src/color-profile-fns.h +++ b/src/color-profile-fns.h @@ -38,6 +38,7 @@ std::vector<Glib::ustring> colorprofile_get_display_names(); std::vector<Glib::ustring> colorprofile_get_softproof_names(); Glib::ustring get_path_for_profile(Glib::ustring const& name); +void colorprofile_load_profiles(bool force_refresh = false); #endif diff --git a/src/color-profile.cpp b/src/color-profile.cpp index f06ebab88..d1897ab19 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -86,6 +86,9 @@ extern guint update_in_progress; g_message( __VA_ARGS__ );\ } +#else +#define DEBUG_MESSAGE_SCISLAC(key, ...) +#define DEBUG_MESSAGE(key, ...) #endif // DEBUG_LCMS static SPObjectClass *cprof_parent_class; @@ -312,9 +315,7 @@ void ColorProfile::set( SPObject *object, unsigned key, gchar const *value ) cprof->_profileSpace = cmsGetColorSpace( cprof->profHandle ); cprof->_profileClass = cmsGetDeviceClass( cprof->profHandle ); } -#ifdef DEBUG_LCMS DEBUG_MESSAGE( lcmsOne, "cmsOpenProfileFromFile( '%s'...) = %p", fullname, (void*)cprof->profHandle ); -#endif // DEBUG_LCMS g_free(escaped); escaped = 0; g_free(fullname); @@ -339,9 +340,7 @@ void ColorProfile::set( SPObject *object, unsigned key, gchar const *value ) cprof->name = 0; } cprof->name = g_strdup( value ); -#ifdef DEBUG_LCMS DEBUG_MESSAGE( lcmsTwo, "<color-profile> name set to '%s'", cprof->name ); -#endif // DEBUG_LCMS object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; @@ -506,9 +505,7 @@ cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, guint* inte *intent = thing ? COLORPROFILE(thing)->rendering_intent : (guint)RENDERING_INTENT_UNKNOWN; } -#ifdef DEBUG_LCMS DEBUG_MESSAGE( lcmsThree, "<color-profile> queried for profile of '%s'. Returning %p with intent of %d", name, prof, (intent? *intent:0) ); -#endif // DEBUG_LCMS return prof; } @@ -517,7 +514,7 @@ cmsHTRANSFORM ColorProfile::getTransfToSRGB8() { if ( !_transf && profHandle ) { int intent = getLcmsIntent(rendering_intent); - _transf = cmsCreateTransform( profHandle, _getInputFormat(_profileSpace), getSRGBProfile(), TYPE_RGBA_8, intent, 0 ); + _transf = cmsCreateTransform( profHandle, _getInputFormat(_profileSpace), getSRGBProfile(), TYPE_BGRA_8, intent, 0 ); } return _transf; } @@ -526,7 +523,7 @@ cmsHTRANSFORM ColorProfile::getTransfFromSRGB8() { if ( !_revTransf && profHandle ) { int intent = getLcmsIntent(rendering_intent); - _revTransf = cmsCreateTransform( getSRGBProfile(), TYPE_RGBA_8, profHandle, _getInputFormat(_profileSpace), intent, 0 ); + _revTransf = cmsCreateTransform( getSRGBProfile(), TYPE_BGRA_8, profHandle, _getInputFormat(_profileSpace), intent, 0 ); } return _revTransf; } @@ -534,7 +531,7 @@ cmsHTRANSFORM ColorProfile::getTransfFromSRGB8() cmsHTRANSFORM ColorProfile::getTransfGamutCheck() { if ( !_gamutTransf ) { - _gamutTransf = cmsCreateProofingTransform(getSRGBProfile(), TYPE_RGBA_8, getNULLProfile(), TYPE_GRAY_8, profHandle, INTENT_RELATIVE_COLORIMETRIC, INTENT_RELATIVE_COLORIMETRIC, (cmsFLAGS_GAMUTCHECK|cmsFLAGS_SOFTPROOFING)); + _gamutTransf = cmsCreateProofingTransform(getSRGBProfile(), TYPE_BGRA_8, getNULLProfile(), TYPE_GRAY_8, profHandle, INTENT_RELATIVE_COLORIMETRIC, INTENT_RELATIVE_COLORIMETRIC, (cmsFLAGS_GAMUTCHECK|cmsFLAGS_SOFTPROOFING)); } return _gamutTransf; } @@ -589,6 +586,7 @@ static std::vector<ProfileInfo> knownProfiles; std::vector<Glib::ustring> Inkscape::colorprofile_get_display_names() { + colorprofile_load_profiles(); std::vector<Glib::ustring> result; for ( std::vector<ProfileInfo>::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { @@ -602,6 +600,7 @@ std::vector<Glib::ustring> Inkscape::colorprofile_get_display_names() std::vector<Glib::ustring> Inkscape::colorprofile_get_softproof_names() { + colorprofile_load_profiles(); std::vector<Glib::ustring> result; for ( std::vector<ProfileInfo>::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { @@ -615,6 +614,7 @@ std::vector<Glib::ustring> Inkscape::colorprofile_get_softproof_names() Glib::ustring Inkscape::get_path_for_profile(Glib::ustring const& name) { + colorprofile_load_profiles(); Glib::ustring result; for ( std::vector<ProfileInfo>::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { @@ -775,7 +775,28 @@ std::list<Glib::ustring> ColorProfile::getProfileFiles() } #if ENABLE_LCMS -static void findThings() { + +int errorHandlerCB(int ErrorCode, const char *ErrorText) +{ + g_message("lcms: Error %d; %s", ErrorCode, ErrorText); + + return 1; +} + +/* This function loads or refreshes data in knownProfiles. + * Call it at the start of every call that requires this data. */ +void Inkscape::colorprofile_load_profiles(bool force_refresh) +{ + static bool error_handler_set = false; + if (!error_handler_set) { + cmsSetErrorHandler(errorHandlerCB); + error_handler_set = true; + } + + static bool profiles_searched = false; + if (profiles_searched && !force_refresh) return; + + knownProfiles.clear(); std::list<Glib::ustring> files = ColorProfile::getProfileFiles(); for ( std::list<Glib::ustring>::const_iterator it = files.begin(); it != files.end(); ++it ) { @@ -797,13 +818,7 @@ static void findThings() { } } } -} - -int errorHandlerCB(int ErrorCode, const char *ErrorText) -{ - g_message("lcms: Error %d; %s", ErrorCode, ErrorText); - - return 1; + profiles_searched = true; } static bool gamutWarn = false; @@ -821,13 +836,7 @@ cmsHPROFILE Inkscape::colorprofile_get_system_profile_handle() static cmsHPROFILE theOne = 0; static Glib::ustring lastURI; - static bool init = false; - if ( !init ) { - cmsSetErrorHandler(errorHandlerCB); - - findThings(); - init = true; - } + colorprofile_load_profiles(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring uri = prefs->getString("/options/displayprofile/uri"); @@ -880,13 +889,7 @@ cmsHPROFILE Inkscape::colorprofile_get_proof_profile_handle() static cmsHPROFILE theOne = 0; static Glib::ustring lastURI; - static bool init = false; - if ( !init ) { - cmsSetErrorHandler(errorHandlerCB); - - findThings(); - init = true; - } + colorprofile_load_profiles(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool which = prefs->getBool( "/options/softproof/enable"); @@ -1003,9 +1006,9 @@ cmsHTRANSFORM Inkscape::colorprofile_get_display_transform() dwFlags |= cmsFLAGS_PRESERVEBLACK; } #endif // defined(cmsFLAGS_PRESERVEBLACK) - transf = cmsCreateProofingTransform( ColorProfile::getSRGBProfile(), TYPE_RGBA_8, hprof, TYPE_RGBA_8, proofProf, intent, proofIntent, dwFlags ); + transf = cmsCreateProofingTransform( ColorProfile::getSRGBProfile(), TYPE_BGRA_8, hprof, TYPE_BGRA_8, proofProf, intent, proofIntent, dwFlags ); } else if ( hprof ) { - transf = cmsCreateTransform( ColorProfile::getSRGBProfile(), TYPE_RGBA_8, hprof, TYPE_RGBA_8, intent, 0 ); + transf = cmsCreateTransform( ColorProfile::getSRGBProfile(), TYPE_BGRA_8, hprof, TYPE_BGRA_8, intent, 0 ); } } @@ -1163,9 +1166,9 @@ cmsHTRANSFORM Inkscape::colorprofile_get_display_per( Glib::ustring const& id ) dwFlags |= cmsFLAGS_PRESERVEBLACK; } #endif // defined(cmsFLAGS_PRESERVEBLACK) - item.transf = cmsCreateProofingTransform( ColorProfile::getSRGBProfile(), TYPE_RGBA_8, item.hprof, TYPE_RGBA_8, proofProf, intent, proofIntent, dwFlags ); + item.transf = cmsCreateProofingTransform( ColorProfile::getSRGBProfile(), TYPE_BGRA_8, item.hprof, TYPE_BGRA_8, proofProf, intent, proofIntent, dwFlags ); } else if ( item.hprof ) { - item.transf = cmsCreateTransform( ColorProfile::getSRGBProfile(), TYPE_RGBA_8, item.hprof, TYPE_RGBA_8, intent, 0 ); + item.transf = cmsCreateTransform( ColorProfile::getSRGBProfile(), TYPE_BGRA_8, item.hprof, TYPE_BGRA_8, intent, 0 ); } } diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 43f33b74e..a67a0fed8 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -15,7 +15,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +# include <config.h> #endif #include <gtk/gtkmain.h> @@ -1651,6 +1651,8 @@ sp_canvas_paint_single_buffer (SPCanvas *canvas, int x0, int y0, int x1, int y1, //buf.ct = gdk_cairo_create(widget->window); // create temporary surface + int w = x1 - x0; + int h = y1 - y0; cairo_surface_t *imgs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, x1 - x0, y1 - y0); buf.ct = cairo_create(imgs); //cairo_translate(buf.ct, -x0, -y0); @@ -1673,97 +1675,30 @@ sp_canvas_paint_single_buffer (SPCanvas *canvas, int x0, int y0, int x1, int y1, SP_CANVAS_ITEM_GET_CLASS (canvas->root)->render (canvas->root, &buf); } -#if 0 -#if ENABLE_LCMS - cmsHTRANSFORM transf = 0; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool fromDisplay = prefs->getBool( "/options/displayprofile/from_display"); - if ( fromDisplay ) { - transf = Inkscape::colorprofile_get_display_per( canvas->cms_key ? *(canvas->cms_key) : "" ); - } else { - transf = Inkscape::colorprofile_get_display_transform(); - } -#endif // ENABLE_LCMS + // output to X + cairo_destroy(buf.ct); - if (buf.is_empty) { #if ENABLE_LCMS - if ( transf && canvas->enable_cms_display_adj ) { - cmsDoTransform( transf, &buf.bg_color, &buf.bg_color, 1 ); + if (canvas->enable_cms_display_adj) { + cmsHTRANSFORM transf = 0; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool fromDisplay = prefs->getBool( "/options/displayprofile/from_display"); + if ( fromDisplay ) { + transf = Inkscape::colorprofile_get_display_per( canvas->cms_key ? *(canvas->cms_key) : "" ); + } else { + transf = Inkscape::colorprofile_get_display_transform(); } -#endif // ENABLE_LCMS - gdk_rgb_gc_set_foreground (canvas->pixmap_gc, buf.bg_color); - gdk_draw_rectangle (SP_CANVAS_WINDOW (canvas), - canvas->pixmap_gc, - TRUE, - x0 - canvas->x0, y0 - canvas->y0, - x1 - x0, y1 - y0); - } else { - -#if ENABLE_LCMS - if ( transf && canvas->enable_cms_display_adj ) { - for ( gint yy = 0; yy < (y1 - y0); yy++ ) { - guchar* p = buf.buf + (buf.buf_rowstride * yy); - cmsDoTransform( transf, p, p, (x1 - x0) ); + + if (transf) { + unsigned char *px = cairo_image_surface_get_data(imgs); + int stride = cairo_image_surface_get_stride(imgs); + for (int i=0; i<h; ++i) { + unsigned char *row = px + i*stride; + cmsDoTransform(transf, row, row, w); } } -#endif // ENABLE_LCMS - -// Now we only need to output the prepared pixmap to the actual screen, and this define chooses one -// of the two ways to do it. The cairo way is direct and straightforward, but unfortunately -// noticeably slower. I asked Carl Worth but he was unable so far to suggest any specific reason -// for this slowness. So, for now we use the oldish method: squeeze out 32bpp buffer to 24bpp and -// use gdk_draw_rgb_image_dithalign, for unfortunately gdk can only handle 24 bpp, which cairo -// cannot handle at all. Still, this way is currently faster even despite the blit with squeeze. - -//#define CANVAS_OUTPUT_VIA_CAIRO - -#ifdef CANVAS_OUTPUT_VIA_CAIRO - - cairo_surface_t *cst = cairo_image_surface_create_for_data ( - buf.buf, - CAIRO_FORMAT_ARGB32, // unpacked, i.e. 32 bits! one byte is unused - x1 - x0, y1 - y0, - buf.buf_rowstride - ); - cairo_t *window_ct = gdk_cairo_create(SP_CANVAS_WINDOW (canvas)); - cairo_set_source_surface (window_ct, cst, x0 - canvas->x0, y0 - canvas->y0); - cairo_paint (window_ct); - cairo_destroy (window_ct); - cairo_surface_finish (cst); - cairo_surface_destroy (cst); - -#else - - NRPixBlock b3; - nr_pixblock_setup_fast (&b3, NR_PIXBLOCK_MODE_R8G8B8, x0, y0, x1, y1, TRUE); - - NRPixBlock b4; - nr_pixblock_setup_extern (&b4, NR_PIXBLOCK_MODE_R8G8B8A8P, x0, y0, x1, y1, - buf.buf, - buf.buf_rowstride, - FALSE, FALSE); - - // this does the 32->24 squishing, using an assembler routine: - nr_blit_pixblock_pixblock (&b3, &b4); - - gdk_draw_rgb_image_dithalign (SP_CANVAS_WINDOW (canvas), - canvas->pixmap_gc, - x0 - canvas->x0, y0 - canvas->y0, - x1 - x0, y1 - y0, - GDK_RGB_DITHER_MAX, - NR_PIXBLOCK_PX(&b3), - sw * 3, - x0 - canvas->x0, y0 - canvas->y0); - - nr_pixblock_release (&b3); - nr_pixblock_release (&b4); -#endif } -#endif - - - // output to X - cairo_destroy(buf.ct); +#endif // ENABLE_LCMS cairo_t *xct = gdk_cairo_create(widget->window); cairo_translate(xct, x0 - canvas->x0, y0 - canvas->y0); |
