From: joncruz Date: Wed, 3 Oct 2007 01:47:41 +0000 (+0000) Subject: Initial cut of softproofing X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=a17d45e59cc6ab4e74980c584b707537c89efa06;p=inkscape.git Initial cut of softproofing --- diff --git a/src/color-profile-fns.h b/src/color-profile-fns.h index 93d327f42..24044ddce 100644 --- a/src/color-profile-fns.h +++ b/src/color-profile-fns.h @@ -28,10 +28,10 @@ GType colorprofile_get_type(); #if ENABLE_LCMS cmsHPROFILE colorprofile_get_handle( SPDocument* document, guint* intent, gchar const* name ); - -cmsHPROFILE colorprofile_get_system_profile_handle(); +cmsHTRANSFORM colorprofile_get_display_transform(); std::vector colorprofile_get_display_names(); +std::vector colorprofile_get_softproof_names(); Glib::ustring get_path_for_profile(Glib::ustring const& name); diff --git a/src/color-profile.cpp b/src/color-profile.cpp index bdfa694f0..7cd4df598 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -31,6 +31,9 @@ static void colorprofile_release( SPObject *object ); static void colorprofile_build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr ); static void colorprofile_set( SPObject *object, unsigned key, gchar const *value ); static Inkscape::XML::Node *colorprofile_write( SPObject *object, Inkscape::XML::Node *repr, guint flags ); + +static cmsHPROFILE colorprofile_get_system_profile_handle(); +static cmsHPROFILE colorprofile_get_proof_profile_handle(); } #ifdef DEBUG_LCMS @@ -417,6 +420,19 @@ std::vector Inkscape::colorprofile_get_display_names() return result; } +std::vector Inkscape::colorprofile_get_softproof_names() +{ + std::vector result; + + for ( std::vector::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { + if ( it->getClass() == icSigOutputClass ) { + result.push_back( it->getName() ); + } + } + + return result; +} + Glib::ustring Inkscape::get_path_for_profile(Glib::ustring const& name) { Glib::ustring result; @@ -529,6 +545,9 @@ int errorHandlerCB(int ErrorCode, const char *ErrorText) return 1; } +static bool gamutWarn = false; +static cmsHTRANSFORM transf = 0; +static cmsHPROFILE srcprof = 0; cmsHPROFILE Inkscape::colorprofile_get_system_profile_handle() { @@ -552,12 +571,76 @@ cmsHPROFILE Inkscape::colorprofile_get_system_profile_handle() if ( theOne ) { cmsCloseProfile( theOne ); } + if ( transf ) { + cmsDeleteTransform( transf ); + transf = 0; + } + theOne = cmsOpenProfileFromFile( uri, "r" ); + if ( theOne ) { + // a display profile must have the proper stuff + icColorSpaceSignature space = cmsGetColorSpace(theOne); + icProfileClassSignature profClass = cmsGetDeviceClass(theOne); + + if ( profClass != icSigDisplayClass ) { + g_warning("Not a display profile"); + cmsCloseProfile( theOne ); + theOne = 0; + } else if ( space != icSigRgbData ) { + g_warning("Not an RGB profile"); + cmsCloseProfile( theOne ); + theOne = 0; + } else { + lastURI = uri; + } + } + } + } else if ( theOne ) { + cmsCloseProfile( theOne ); + theOne = 0; + lastURI.clear(); + if ( transf ) { + cmsDeleteTransform( transf ); + transf = 0; + } + } + + return theOne; +} + + +cmsHPROFILE Inkscape::colorprofile_get_proof_profile_handle() +{ + static cmsHPROFILE theOne = 0; + static std::string lastURI; + + static bool init = false; + if ( !init ) { + cmsSetErrorHandler(errorHandlerCB); + + findThings(); + init = true; + } + + long long int which = prefs_get_int_attribute_limited( "options.softproof", "enable", 0, 0, 1 ); + gchar const * uri = prefs_get_string_attribute("options.softproof", "uri"); + + if ( which && uri && *uri ) { + if ( lastURI != std::string(uri) ) { + lastURI.clear(); + if ( theOne ) { + cmsCloseProfile( theOne ); + } + if ( transf ) { + cmsDeleteTransform( transf ); + transf = 0; + } theOne = cmsOpenProfileFromFile( uri, "r" ); if ( theOne ) { // a display profile must have the proper stuff icColorSpaceSignature space = cmsGetColorSpace(theOne); icProfileClassSignature profClass = cmsGetDeviceClass(theOne); +/* if ( profClass != icSigDisplayClass ) { g_warning("Not a display profile"); cmsCloseProfile( theOne ); @@ -567,19 +650,60 @@ cmsHPROFILE Inkscape::colorprofile_get_system_profile_handle() cmsCloseProfile( theOne ); theOne = 0; } else { +*/ lastURI = uri; +/* } +*/ } } } else if ( theOne ) { cmsCloseProfile( theOne ); theOne = 0; lastURI.clear(); + if ( transf ) { + cmsDeleteTransform( transf ); + transf = 0; + } } return theOne; } +cmsHTRANSFORM Inkscape::colorprofile_get_display_transform() +{ + bool warn = prefs_get_int_attribute_limited( "options.softproof", "gamutwarn", 0, 0, 1 ); + if ( (warn != gamutWarn) ) { + gamutWarn = warn; + if ( transf ) { + cmsDeleteTransform(transf); + transf = 0; + } + } + + // Fecth these now, as they might clear the transform as a side effect. + cmsHPROFILE hprof = Inkscape::colorprofile_get_system_profile_handle(); + cmsHPROFILE proofProf = hprof ? Inkscape::colorprofile_get_proof_profile_handle() : 0; + + if ( !transf ) { + if ( !srcprof ) { + srcprof = cmsCreate_sRGBProfile(); + } + if ( hprof && proofProf ) { + DWORD dwFlags = cmsFLAGS_SOFTPROOFING; + if ( gamutWarn ) { + dwFlags |= cmsFLAGS_GAMUTCHECK; + } + cmsSetAlarmCodes(0, 255, 0); + transf = cmsCreateProofingTransform( srcprof, TYPE_RGB_8, hprof, TYPE_RGB_8, proofProf, INTENT_PERCEPTUAL, INTENT_PERCEPTUAL, dwFlags ); + } else if ( hprof ) { + transf = cmsCreateTransform( srcprof, TYPE_RGB_8, hprof, TYPE_RGB_8, INTENT_PERCEPTUAL, 0 ); + } + } + + return transf; +} + #endif // ENABLE_LCMS /* diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 3c647aa1c..efd262890 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1588,9 +1588,7 @@ sp_canvas_paint_single_buffer (SPCanvas *canvas, int x0, int y0, int x1, int y1, } #if ENABLE_LCMS - cmsHPROFILE hprof = Inkscape::colorprofile_get_system_profile_handle(); - cmsHPROFILE srcprof = hprof ? cmsCreate_sRGBProfile() : 0; - cmsHTRANSFORM transf = hprof ? cmsCreateTransform( srcprof, TYPE_RGB_8, hprof, TYPE_RGB_8, INTENT_PERCEPTUAL, 0 ) : 0; + cmsHTRANSFORM transf = Inkscape::colorprofile_get_display_transform(); #endif // ENABLE_LCMS if (buf.is_empty) { @@ -1647,14 +1645,6 @@ sp_canvas_paint_single_buffer (SPCanvas *canvas, int x0, int y0, int x1, int y1, x0 - canvas->x0, y0 - canvas->y0); } -#if ENABLE_LCMS - if ( transf ) { - cmsDeleteTransform( transf ); - transf = 0; - } -#endif // ENABLE_LCMS - - if (canvas->rendermode != RENDERMODE_OUTLINE) { nr_pixelstore_256K_free (buf.buf); } else { diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index 16e1bc76e..373323097 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -185,6 +185,11 @@ static char const preferences_skeleton[] = " id=\"displayprofile\"" " enable=\"0\"\n" " uri=\"\" />\n" +" \n" " \n" " \n" " \n" diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 59132349f..0e83addec 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -644,6 +644,17 @@ static void profileComboChanged( Gtk::ComboBoxText* combo ) forceUpdates(); } } + +static void proofComboChanged( Gtk::ComboBoxText* combo ) +{ + Glib::ustring active = combo->get_active_text(); + + Glib::ustring path = get_path_for_profile(active); + if ( !path.empty() ) { + prefs_set_string_attribute( "options.softproof", "uri", path.c_str() ); + forceUpdates(); + } +} #endif // ENABLE_LCMS @@ -663,6 +674,19 @@ void InkscapePreferences::initPageMisc() _page_misc.add_line( false, _("Display profile:"), _misc_cms_display_profile, "", _("The ICC profile to use to calibrate display output."), true); + + + _misc_cms_softproof.init( _("Simulate output on screen."), "options.softproof", "enable", false); + _page_misc.add_line( false, "", _misc_cms_softproof, "", + _("Simulates output of target device."), true); + + _misc_cms_gamutwarn.init( _("Mark out of gamut colors."), "options.softproof", "gamutwarn", false); + _page_misc.add_line( false, "", _misc_cms_gamutwarn, "", + _("Highlights colors that are out of gamut for the target device."), true); + + _page_misc.add_line( false, _("Device profile:"), _misc_cms_proof_profile, "", + _("The ICC profile to use to simulate device output."), true); + #if ENABLE_LCMS { std::vector names = ::Inkscape::colorprofile_get_display_names(); @@ -677,15 +701,34 @@ void InkscapePreferences::initPageMisc() } index++; } + + names = ::Inkscape::colorprofile_get_softproof_names(); + const gchar * tmp = prefs_get_string_attribute( "options.softproof", "uri" ); + current = tmp ? tmp : ""; + index = 0; + for ( std::vector::iterator it = names.begin(); it != names.end(); ++it ) { + _misc_cms_proof_profile.append_text( *it ); + Glib::ustring path = get_path_for_profile(*it); + if ( !path.empty() && path == current ) { + _misc_cms_proof_profile.set_active(index); + } + index++; + } } _misc_cms_display.signal_toggled().connect( sigc::ptr_fun(forceUpdates) ); + _misc_cms_softproof.signal_toggled().connect( sigc::ptr_fun(forceUpdates) ); + _misc_cms_gamutwarn.signal_toggled().connect( sigc::ptr_fun(forceUpdates) ); _misc_cms_display_profile.signal_changed().connect( sigc::bind( sigc::ptr_fun(profileComboChanged), &_misc_cms_display_profile) ); + _misc_cms_proof_profile.signal_changed().connect( sigc::bind( sigc::ptr_fun(proofComboChanged), &_misc_cms_proof_profile) ); #else // disable it, but leave it visible _misc_cms_display.set_sensitive( false ); _misc_cms_display_profile.set_sensitive( false ); + _misc_cms_softproof.set_sensitive( false ); + _misc_cms_gamutwarn.set_sensitive( false ); + _misc_cms_proof_profile.set_sensitive( false ); #endif // ENABLE_LCMS _misc_recent.init("options.maxrecentdocuments", "value", 0.0, 1000.0, 1.0, 1.0, 1.0, true, false); diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 5dafd4051..58c908a9a 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -165,6 +165,10 @@ protected: PrefCheckButton _misc_cms_display; Gtk::ComboBoxText _misc_cms_display_profile; + PrefCheckButton _misc_cms_softproof; + PrefCheckButton _misc_cms_gamutwarn; + Gtk::ComboBoxText _misc_cms_proof_profile; + PrefEntryButtonHBox _importexport_ocal_url; PrefEntry _importexport_ocal_username; PrefEntry _importexport_ocal_password;