From: joncruz Date: Thu, 6 Apr 2006 07:20:13 +0000 (+0000) Subject: Adding rendering-intent to X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=30c6998f17591646332badc392826e7b6f75b645;p=inkscape.git Adding rendering-intent to --- diff --git a/ChangeLog b/ChangeLog index f57923f4f..07fdbfb22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-04-06 Jon A. Cruz + + * src/Makefile_insert, src/Makefile.am, src/color-profile.cpp + src/color-profile.h, src/color-profile-fns.h, + src/color-profile-test.h, src/sp-image.cpp: + + Adding rendering-intent to . + 2006-04-05 MenTaLguY * configure.ac, share/keyboards/.cvsignore, share/keyboards/Makefile.am, diff --git a/src/Makefile.am b/src/Makefile.am index cf1033881..23aa417af 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -235,19 +235,20 @@ test-all.cpp: \ $(libnr_test_nr_includes) \ $(svg_test_svg_includes) \ $(xml_test_xml_includes) \ - attributes-test.h + $(test_all_includes) $(top_srcdir)/cxxtest/cxxtestgen.pl --error-printer -root -o test-all.cpp \ $(libnr_test_nr_includes) \ $(svg_test_svg_includes) \ $(xml_test_xml_includes) \ - attributes-test.h + $(test_all_includes) test_all_SOURCES = \ test-all.cpp test_all_LDADD = \ - libinkpre.a \ + $(all_libs) \ + io/libio.a \ $(libnr_test_nr_LDADD) \ $(svg_test_svg_LDADD) \ $(xml_test_xml_LDADD) diff --git a/src/Makefile_insert b/src/Makefile_insert index e09b69ffc..43d85e62e 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -339,3 +339,7 @@ style_test_LDADD = $(all_libs) inkscape_version.h: ../configure.ac echo '#define INKSCAPE_VERSION "$(VERSION)"' > inkscape_version.h + +test_all_includes = \ + attributes-test.h \ + color-profile-test.h diff --git a/src/color-profile-fns.h b/src/color-profile-fns.h index 96a7410a9..d7342b09d 100644 --- a/src/color-profile-fns.h +++ b/src/color-profile-fns.h @@ -25,7 +25,7 @@ GType colorprofile_get_type(); #if ENABLE_LCMS -cmsHPROFILE colorprofile_get_handle( SPDocument* document, gchar* const name ); +cmsHPROFILE colorprofile_get_handle( SPDocument* document, guint* intent, gchar* const name ); #endif diff --git a/src/color-profile-test.h b/src/color-profile-test.h new file mode 100644 index 000000000..56134ef4a --- /dev/null +++ b/src/color-profile-test.h @@ -0,0 +1,159 @@ + + +#include +#include + +#include "inkscape-private.h" +#include "sp-object.h" +#include "document.h" + +#include "color-profile.h" +#include "color-profile-fns.h" + +using Inkscape::ColorProfile; + +/// Dummy functions to keep linker happy +#if !defined(DUMMY_MAIN_TEST_CALLS_SEEN) +#define DUMMY_MAIN_TEST_CALLS_SEEN +int sp_main_gui (int, char const**) { return 0; } +int sp_main_console (int, char const**) { return 0; } +#endif // DUMMY_MAIN_TEST_CALLS_SEEN + +class ColorProfileTest : public CxxTest::TestSuite +{ +public: + + ColorProfileTest() : + TestSuite(), + _doc(0) + { + } + virtual ~ColorProfileTest() {} + +// createSuite and destroySuite get us per-suite setup and teardown +// without us having to worry about static initialization order, etc. + static ColorProfileTest *createSuite() + { + ColorProfileTest* suite = 0; + bool canRun = false; + + g_type_init(); + Inkscape::GC::init(); + + ColorProfile *prof = static_cast(g_object_new(COLORPROFILE_TYPE, NULL)); + canRun = prof; + canRun &= prof->rendering_intent == (guint)Inkscape::RENDERING_INTENT_UNKNOWN; + TS_ASSERT_EQUALS( prof->rendering_intent, (guint)Inkscape::RENDERING_INTENT_UNKNOWN ); + g_object_unref(prof); + + if ( canRun ) { + // Create the global inkscape object. + static_cast(g_object_new(inkscape_get_type(), NULL)); + SPDocument* tmp = sp_document_new_dummy(); + if ( tmp ) { + suite = new ColorProfileTest(); + suite->_doc = tmp; + } + } + + return suite; + } + + static void destroySuite( ColorProfileTest *suite ) + { + delete suite; + } + + + SPDocument* _doc; + + // --------------------------------------------------------------- + + void testSetRenderingIntent() + { + struct { + gchar const *attr; + guint intVal; + } + const cases[] = { + {"auto", (guint)Inkscape::RENDERING_INTENT_AUTO}, + {"perceptual", (guint)Inkscape::RENDERING_INTENT_PERCEPTUAL}, + {"relative-colorimetric", (guint)Inkscape::RENDERING_INTENT_RELATIVE_COLORIMETRIC}, + {"saturation", (guint)Inkscape::RENDERING_INTENT_SATURATION}, + {"absolute-colorimetric", (guint)Inkscape::RENDERING_INTENT_ABSOLUTE_COLORIMETRIC}, + {"something-else", (guint)Inkscape::RENDERING_INTENT_UNKNOWN}, + {"auto2", (guint)Inkscape::RENDERING_INTENT_UNKNOWN}, + }; + + ColorProfile *prof = static_cast(g_object_new(COLORPROFILE_TYPE, NULL)); + TS_ASSERT( prof ); + SP_OBJECT(prof)->document = _doc; + + for ( size_t i = 0; i < G_N_ELEMENTS( cases ); i++ ) { + std::string descr(cases[i].attr); + sp_object_set(SP_OBJECT(prof), SP_ATTR_RENDERING_INTENT, cases[i].attr); + TSM_ASSERT_EQUALS( descr, prof->rendering_intent, (guint)cases[i].intVal ); + } + + g_object_unref(prof); + } + + void testSetLocal() + { + gchar const* cases[] = { + "local", + "something", + }; + + ColorProfile *prof = static_cast(g_object_new(COLORPROFILE_TYPE, NULL)); + TS_ASSERT( prof ); + SP_OBJECT(prof)->document = _doc; + + for ( size_t i = 0; i < G_N_ELEMENTS( cases ); i++ ) { + sp_object_set(SP_OBJECT(prof), SP_ATTR_LOCAL, cases[i]); + TS_ASSERT( prof->local ); + if ( prof->local ) { + TS_ASSERT_EQUALS( std::string(prof->local), std::string(cases[i]) ); + } + } + sp_object_set(SP_OBJECT(prof), SP_ATTR_LOCAL, NULL); + TS_ASSERT_EQUALS( prof->local, (gchar*)0 ); + + g_object_unref(prof); + } + + void testSetName() + { + gchar const* cases[] = { + "name", + "something", + }; + + ColorProfile *prof = static_cast(g_object_new(COLORPROFILE_TYPE, NULL)); + TS_ASSERT( prof ); + SP_OBJECT(prof)->document = _doc; + + for ( size_t i = 0; i < G_N_ELEMENTS( cases ); i++ ) { + sp_object_set(SP_OBJECT(prof), SP_ATTR_NAME, cases[i]); + TS_ASSERT( prof->name ); + if ( prof->name ) { + TS_ASSERT_EQUALS( std::string(prof->name), std::string(cases[i]) ); + } + } + sp_object_set(SP_OBJECT(prof), SP_ATTR_NAME, NULL); + TS_ASSERT_EQUALS( prof->name, (gchar*)0 ); + + g_object_unref(prof); + } +}; + +/* + 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:encoding=utf-8:textwidth=99 : diff --git a/src/color-profile.cpp b/src/color-profile.cpp index b9e42ccbd..7b03c7773 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -9,6 +9,8 @@ using Inkscape::ColorProfile; using Inkscape::ColorProfileClass; +namespace Inkscape +{ static void colorprofile_class_init( ColorProfileClass *klass ); static void colorprofile_init( ColorProfile *cprof ); @@ -16,6 +18,7 @@ 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 SPObject *cprof_parent_class; @@ -44,7 +47,7 @@ GType Inkscape::colorprofile_get_type() /** * ColorProfile vtable initialization. */ -static void colorprofile_class_init( ColorProfileClass *klass ) +static void Inkscape::colorprofile_class_init( ColorProfileClass *klass ) { SPObjectClass *sp_object_class = reinterpret_cast(klass); @@ -59,12 +62,13 @@ static void colorprofile_class_init( ColorProfileClass *klass ) /** * Callback for ColorProfile object initialization. */ -static void colorprofile_init( ColorProfile *cprof ) +static void Inkscape::colorprofile_init( ColorProfile *cprof ) { cprof->href = 0; cprof->local = 0; cprof->name = 0; - cprof->rendering_intent = 0; + cprof->intentStr = 0; + cprof->rendering_intent = Inkscape::RENDERING_INTENT_UNKNOWN; #if ENABLE_LCMS cprof->profHandle = 0; #endif // ENABLE_LCMS @@ -73,7 +77,7 @@ static void colorprofile_init( ColorProfile *cprof ) /** * Callback: free object */ -static void colorprofile_release( SPObject *object ) +static void Inkscape::colorprofile_release( SPObject *object ) { ColorProfile *cprof = COLORPROFILE(object); if ( cprof->href ) { @@ -91,6 +95,11 @@ static void colorprofile_release( SPObject *object ) cprof->name = 0; } + if ( cprof->intentStr ) { + g_free( cprof->intentStr ); + cprof->intentStr = 0; + } + #if ENABLE_LCMS if ( cprof->profHandle ) { cmsCloseProfile( cprof->profHandle ); @@ -102,12 +111,13 @@ static void colorprofile_release( SPObject *object ) /** * Callback: set attributes from associated repr. */ -static void colorprofile_build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr ) +static void Inkscape::colorprofile_build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr ) { ColorProfile *cprof = COLORPROFILE(object); g_assert(cprof->href == 0); g_assert(cprof->local == 0); g_assert(cprof->name == 0); + g_assert(cprof->intentStr == 0); if (((SPObjectClass *) cprof_parent_class)->build) { (* ((SPObjectClass *) cprof_parent_class)->build)(object, document, repr); @@ -121,15 +131,18 @@ static void colorprofile_build( SPObject *object, SPDocument *document, Inkscape /** * Callback: set attribute. */ -static void colorprofile_set( SPObject *object, unsigned key, gchar const *value ) +static void Inkscape::colorprofile_set( SPObject *object, unsigned key, gchar const *value ) { ColorProfile *cprof = COLORPROFILE(object); switch (key) { case SP_ATTR_XLINK_HREF: + if ( cprof->href ) { + g_free( cprof->href ); + cprof->href = 0; + } if ( value ) { cprof->href = g_strdup( value ); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); if ( *cprof->href ) { #if ENABLE_LCMS cmsErrorAction( LCMS_ERROR_SHOW ); @@ -153,28 +166,53 @@ static void colorprofile_set( SPObject *object, unsigned key, gchar const *value #endif // ENABLE_LCMS } } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_LOCAL: - if ( value ) { - cprof->local = g_strdup( value ); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + if ( cprof->local ) { + g_free( cprof->local ); + cprof->local = 0; } + cprof->local = g_strdup( value ); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_NAME: - if ( value ) { - cprof->name = g_strdup( value ); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + if ( cprof->name ) { + g_free( cprof->name ); + cprof->name = 0; } + cprof->name = g_strdup( value ); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_RENDERING_INTENT: + if ( cprof->intentStr ) { + g_free( cprof->intentStr ); + cprof->intentStr = 0; + } + cprof->intentStr = g_strdup( value ); + if ( value ) { -// auto | perceptual | relative-colorimetric | saturation | absolute-colorimetric - //cprof->name = g_strdup( value ); - //object->requestModified(SP_OBJECT_MODIFIED_FLAG); + if ( strcmp( value, "auto" ) == 0 ) { + cprof->rendering_intent = RENDERING_INTENT_AUTO; + } else if ( strcmp( value, "perceptual" ) == 0 ) { + cprof->rendering_intent = RENDERING_INTENT_PERCEPTUAL; + } else if ( strcmp( value, "relative-colorimetric" ) == 0 ) { + cprof->rendering_intent = RENDERING_INTENT_RELATIVE_COLORIMETRIC; + } else if ( strcmp( value, "saturation" ) == 0 ) { + cprof->rendering_intent = RENDERING_INTENT_SATURATION; + } else if ( strcmp( value, "absolute-colorimetric" ) == 0 ) { + cprof->rendering_intent = RENDERING_INTENT_ABSOLUTE_COLORIMETRIC; + } else { + cprof->rendering_intent = RENDERING_INTENT_UNKNOWN; + } + } else { + cprof->rendering_intent = RENDERING_INTENT_UNKNOWN; } + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); break; default: @@ -183,12 +221,13 @@ static void colorprofile_set( SPObject *object, unsigned key, gchar const *value } break; } + } /** * Callback: write attributes to associated repr. */ -static Inkscape::XML::Node* colorprofile_write( SPObject *object, Inkscape::XML::Node *repr, guint flags ) +static Inkscape::XML::Node* Inkscape::colorprofile_write( SPObject *object, Inkscape::XML::Node *repr, guint flags ) { ColorProfile *cprof = COLORPROFILE(object); @@ -197,19 +236,19 @@ static Inkscape::XML::Node* colorprofile_write( SPObject *object, Inkscape::XML: } if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->href ) { - repr->setAttribute( "xlink:href", cprof->name ); + repr->setAttribute( "xlink:href", cprof->href ); } - if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->href ) { - repr->setAttribute( "local", cprof->name ); + if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->local ) { + repr->setAttribute( "local", cprof->local ); } - if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->href ) { + if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->name ) { repr->setAttribute( "name", cprof->name ); } - if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->href ) { -// repr->setAttribute( "rendering-intent", cprof->name ); + if ( (flags & SP_OBJECT_WRITE_ALL) || cprof->intentStr ) { + repr->setAttribute( "rendering-intent", cprof->intentStr ); } if (((SPObjectClass *) cprof_parent_class)->write) { @@ -251,7 +290,7 @@ static SPObject* bruteFind( SPObject* curr, gchar* const name ) return result; } -cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, gchar* const name ) +cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, guint* intent, gchar* const name ) { cmsHPROFILE prof = 0; @@ -261,6 +300,10 @@ cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, gchar* cons prof = COLORPROFILE(thing)->profHandle; } + if ( intent ) { + *intent = thing ? COLORPROFILE(thing)->rendering_intent : (guint)RENDERING_INTENT_UNKNOWN; + } + return prof; } #endif // ENABLE_LCMS diff --git a/src/color-profile.h b/src/color-profile.h index a6a83ccb5..76e25d065 100644 --- a/src/color-profile.h +++ b/src/color-profile.h @@ -13,11 +13,21 @@ namespace Inkscape { +enum { + RENDERING_INTENT_UNKNOWN = 0, + RENDERING_INTENT_AUTO = 1, + RENDERING_INTENT_PERCEPTUAL = 2, + RENDERING_INTENT_RELATIVE_COLORIMETRIC = 3, + RENDERING_INTENT_SATURATION = 4, + RENDERING_INTENT_ABSOLUTE_COLORIMETRIC = 5 +}; + /** Color Profile. */ struct ColorProfile : public SPObject { gchar* href; gchar* local; gchar* name; + gchar* intentStr; guint rendering_intent; #if ENABLE_LCMS cmsHPROFILE profHandle; diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 6a848c1bc..83b623dbc 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -38,6 +38,7 @@ #include #if ENABLE_LCMS #include "color-profile-fns.h" +#include "color-profile.h" #endif // ENABLE_LCMS /* * SPImage @@ -665,16 +666,36 @@ sp_image_update (SPObject *object, SPCtx *ctx, unsigned int flags) guchar* px = gdk_pixbuf_get_pixels( pixbuf ); if ( px ) { - cmsHPROFILE prof = Inkscape::colorprofile_get_handle( SP_OBJECT_DOCUMENT( object ), image->color_profile ); + guint profIntent = Inkscape::RENDERING_INTENT_UNKNOWN; + cmsHPROFILE prof = Inkscape::colorprofile_get_handle( SP_OBJECT_DOCUMENT( object ), + &profIntent, + image->color_profile ); if ( prof ) { icProfileClassSignature profileClass = cmsGetDeviceClass( prof ); if ( profileClass != icSigNamedColorClass ) { + int intent = INTENT_PERCEPTUAL; + switch ( profIntent ) { + case Inkscape::RENDERING_INTENT_RELATIVE_COLORIMETRIC: + intent = INTENT_RELATIVE_COLORIMETRIC; + break; + case Inkscape::RENDERING_INTENT_SATURATION: + intent = INTENT_SATURATION; + break; + case Inkscape::RENDERING_INTENT_ABSOLUTE_COLORIMETRIC: + intent = INTENT_ABSOLUTE_COLORIMETRIC; + break; + case Inkscape::RENDERING_INTENT_PERCEPTUAL: + case Inkscape::RENDERING_INTENT_UNKNOWN: + case Inkscape::RENDERING_INTENT_AUTO: + default: + intent = INTENT_PERCEPTUAL; + } cmsHPROFILE destProf = cmsCreate_sRGBProfile(); cmsHTRANSFORM transf = cmsCreateTransform( prof, TYPE_RGBA_8, destProf, TYPE_RGBA_8, - INTENT_PERCEPTUAL, 0 ); + intent, 0 ); if ( transf ) { guchar* currLine = px; for ( int y = 0; y < imageheight; y++ ) {