diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-07-13 22:21:37 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2011-07-13 22:21:37 +0000 |
| commit | 0d6be77f2af241e47d0df3f19619db85ca8127e7 (patch) | |
| tree | 510d535eb41530772c79218ece39023d85d42c93 /src | |
| parent | Fix crashes during offscreen rendering, part 1 (diff) | |
| parent | Fix crashes in print preview (diff) | |
| download | inkscape-0d6be77f2af241e47d0df3f19619db85ca8127e7.tar.gz inkscape-0d6be77f2af241e47d0df3f19619db85ca8127e7.zip | |
Merge from trunk to pull in fix for LP #806105
(bzr r10347.1.13)
Diffstat (limited to 'src')
74 files changed, 2153 insertions, 1635 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 580d65b0c..038e7bb73 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -306,7 +306,9 @@ set(inkscape_SRC box3d-context.h box3d-side.h box3d.h - color-profile-fns.h + cms-color-types.h + cms-system.h + color-profile-cms-fns.h color-profile-test.h color-profile.h color-rgba.h diff --git a/src/Makefile.am b/src/Makefile.am index 7925dcd7e..5a50eb36f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -208,11 +208,7 @@ libinkscape_a_SOURCES = $(ink_common_sources) inkscape_SOURCES += main.cpp $(win32_sources) inkscape_LDADD = $(all_libs) -if EXPORT_DYNAMIC_DIRECT -inkscape_LDFLAGS = --export-dynamic $(kdeldflags) $(mwindows) -else -inkscape_LDFLAGS = -Wl,--export-dynamic $(kdeldflags) $(mwindows) -endif +inkscape_LDFLAGS = $(kdeldflags) $(mwindows) inkview_SOURCES += inkview.cpp $(win32_sources) inkview_LDADD = $(all_libs) diff --git a/src/Makefile_insert b/src/Makefile_insert index 7d48dba93..2cb689740 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -12,9 +12,11 @@ ink_common_sources += \ box3d.cpp box3d.h \ box3d-side.cpp box3d-side.h \ brokenimage.xpm \ + cms-color-types.h \ + cms-system.h \ color.cpp color.h \ color-profile.cpp color-profile.h \ - color-profile-fns.h \ + color-profile-cms-fns.h \ color-rgba.h \ common-context.cpp common-context.h \ composite-undo-stack-observer.cpp \ diff --git a/src/cms-color-types.h b/src/cms-color-types.h new file mode 100644 index 000000000..74fdac12c --- /dev/null +++ b/src/cms-color-types.h @@ -0,0 +1,58 @@ +#ifndef SEEN_CMS_COLOR_TYPES_H +#define SEEN_CMS_COLOR_TYPES_H + +/** \file + * A simple abstraction to provide opaque compatibility with either lcms or lcms2. + */ + +#include <glib/gtypes.h> + + +typedef void * cmsHPROFILE; +typedef void * cmsHTRANSFORM; + +namespace Inkscape { + +/** + * Opaque holder of a 32-bit signature type. + */ +class FourCCSig { +public: + FourCCSig( FourCCSig const &other ) : value(other.value) {}; + +protected: + FourCCSig( guint32 value ) : value(value) {}; + + guint32 value; +}; + +class ColorSpaceSig : public FourCCSig { +public: + ColorSpaceSig( ColorSpaceSig const &other ) : FourCCSig(other) {}; + +protected: + ColorSpaceSig( guint32 value ) : FourCCSig(value) {}; +}; + +class ColorProfileClassSig : public FourCCSig { +public: + ColorProfileClassSig( ColorProfileClassSig const &other ) : FourCCSig(other) {}; + +protected: + ColorProfileClassSig( guint32 value ) : FourCCSig(value) {}; +}; + +} // namespace Inkscape + +#endif // SEEN_CMS_COLOR_TYPES_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/cms-system.h b/src/cms-system.h new file mode 100644 index 000000000..1f75f8619 --- /dev/null +++ b/src/cms-system.h @@ -0,0 +1,60 @@ +#ifndef SEEN_COLOR_PROFILE_FNS_H +#define SEEN_COLOR_PROFILE_FNS_H + +/** \file + * Macros and fn declarations related to linear gradients. + */ + +#include <glib-object.h> +#include <glib/gtypes.h> +#include <vector> +#include <glibmm/ustring.h> +#include "cms-color-types.h" + +class SPDocument; + +namespace Inkscape { + +class ColorProfile; + +class CMSSystem { +public: + static cmsHPROFILE getHandle( SPDocument* document, guint* intent, gchar const* name ); + + static cmsHTRANSFORM getDisplayTransform(); + + static Glib::ustring getDisplayId( int screen, int monitor ); + + static Glib::ustring setDisplayPer( gpointer buf, guint bufLen, int screen, int monitor ); + + static cmsHTRANSFORM getDisplayPer( Glib::ustring const& id ); + + static std::vector<Glib::ustring> getDisplayNames(); + + static std::vector<Glib::ustring> getSoftproofNames(); + + static Glib::ustring getPathForProfile(Glib::ustring const& name); + + static void doTransform(cmsHTRANSFORM transform, void *inBuf, void *outBuf, unsigned int size); + + static bool isPrintColorSpace(ColorProfile const *profile); + + static gint getChannelCount(ColorProfile const *profile); +}; + + +} // namespace Inkscape + + +#endif // !SEEN_COLOR_PROFILE_FNS_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/color-profile-cms-fns.h b/src/color-profile-cms-fns.h new file mode 100644 index 000000000..fe0eed392 --- /dev/null +++ b/src/color-profile-cms-fns.h @@ -0,0 +1,51 @@ +#ifndef SEEN_COLOR_PROFILE_CMS_FNS_H +#define SEEN_COLOR_PROFILE_CMS_FNS_H + +#if ENABLE_LCMS +#include <lcms.h> +#endif // ENABLE_LCMS + +#include "cms-color-types.h" + +namespace Inkscape { + +#if ENABLE_LCMS + +// Note: these can later be adjusted to adapt for lcms2: + +class ColorSpaceSigWrapper : public ColorSpaceSig { +public : + ColorSpaceSigWrapper( icColorSpaceSignature sig ) : ColorSpaceSig( static_cast<guint32>(sig) ) {} + ColorSpaceSigWrapper( ColorSpaceSig const &other ) : ColorSpaceSig( other ) {} + + operator icColorSpaceSignature() const { return static_cast<icColorSpaceSignature>(value); } +}; + +class ColorProfileClassSigWrapper : public ColorProfileClassSig { +public : + ColorProfileClassSigWrapper( icProfileClassSignature sig ) : ColorProfileClassSig( static_cast<guint32>(sig) ) {} + ColorProfileClassSigWrapper( ColorProfileClassSig const &other ) : ColorProfileClassSig( other ) {} + + operator icProfileClassSignature() const { return static_cast<icProfileClassSignature>(value); } +}; + +icColorSpaceSignature asICColorSpaceSig(ColorSpaceSig const & sig); +icProfileClassSignature asICColorProfileClassSig(ColorProfileClassSig const & sig); + +#endif // ENABLE_LCMS + +} // namespace Inkscape + + +#endif // !SEEN_COLOR_PROFILE_CMS_FNS_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/color-profile-fns.h b/src/color-profile-fns.h deleted file mode 100644 index defc58f2c..000000000 --- a/src/color-profile-fns.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef SEEN_COLOR_PROFILE_FNS_H -#define SEEN_COLOR_PROFILE_FNS_H - -/** \file - * Macros and fn declarations related to linear gradients. - */ - -#include <glib-object.h> -#include <glib/gtypes.h> -#if ENABLE_LCMS -#include <vector> -#include <glibmm/ustring.h> -#include <lcms.h> -#endif // ENABLE_LCMS - -class SPDocument; - -namespace Inkscape { - -namespace XML { -class Node; -} // namespace XML - -class ColorProfile; - -GType colorprofile_get_type(); - -#if ENABLE_LCMS - -cmsHPROFILE colorprofile_get_handle( SPDocument* document, guint* intent, gchar const* name ); -cmsHTRANSFORM colorprofile_get_display_transform(); - -Glib::ustring colorprofile_get_display_id( int screen, int monitor ); -Glib::ustring colorprofile_set_display_per( gpointer buf, guint bufLen, int screen, int monitor ); -cmsHTRANSFORM colorprofile_get_display_per( Glib::ustring const& id ); - -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 - -} // namespace Inkscape - -#define COLORPROFILE_TYPE (Inkscape::colorprofile_get_type()) -#define COLORPROFILE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), COLORPROFILE_TYPE, Inkscape::ColorProfile)) -#define COLORPROFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), COLORPROFILE_TYPE, Inkscape::ColorProfileClass)) -#define IS_COLORPROFILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), COLORPROFILE_TYPE)) -#define IS_COLORPROFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), COLORPROFILE_TYPE)) - - -#endif // !SEEN_COLOR_PROFILE_FNS_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/color-profile-test.h b/src/color-profile-test.h index 4b679e5b7..b3ead5d55 100644 --- a/src/color-profile-test.h +++ b/src/color-profile-test.h @@ -9,7 +9,7 @@ #include "color-profile.h" -#include "color-profile-fns.h" +#include "cms-system.h" class ColorProfileTest : public CxxTest::TestSuite { diff --git a/src/color-profile.cpp b/src/color-profile.cpp index 4dc4d5bd8..41c9d4c63 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -24,10 +24,15 @@ #include <windows.h> #endif +#if ENABLE_LCMS +#include <lcms.h> +#endif // ENABLE_LCMS + #include "xml/repr.h" #include "color.h" #include "color-profile.h" -#include "color-profile-fns.h" +#include "cms-system.h" +#include "color-profile-cms-fns.h" #include "attributes.h" #include "inkscape.h" #include "document.h" @@ -42,12 +47,15 @@ using Inkscape::ColorProfile; using Inkscape::ColorProfileClass; +using Inkscape::ColorProfileImpl; -namespace Inkscape +namespace { #if ENABLE_LCMS -static cmsHPROFILE colorprofile_get_system_profile_handle(); -static cmsHPROFILE colorprofile_get_proof_profile_handle(); +cmsHPROFILE getSystemProfileHandle(); +cmsHPROFILE getProofProfileHandle(); +void loadProfiles(); +Glib::ustring getNameFromProfile(cmsHPROFILE profile); #endif // ENABLE_LCMS } @@ -93,20 +101,77 @@ extern guint update_in_progress; static SPObjectClass *cprof_parent_class; +class ColorProfileImpl { +public: #if ENABLE_LCMS + static cmsHPROFILE _sRGBProf; + static cmsHPROFILE _NullProf; +#endif // ENABLE_LCMS + + ColorProfileImpl(); + +#if ENABLE_LCMS + static DWORD _getInputFormat( icColorSpaceSignature space ); + + static cmsHPROFILE getNULLProfile(); + static cmsHPROFILE getSRGBProfile(); + + void _clearProfile(); + + cmsHPROFILE _profHandle; + icProfileClassSignature _profileClass; + icColorSpaceSignature _profileSpace; + cmsHTRANSFORM _transf; + cmsHTRANSFORM _revTransf; + cmsHTRANSFORM _gamutTransf; +#endif // ENABLE_LCMS +}; + + -cmsHPROFILE ColorProfile::_sRGBProf = 0; +namespace Inkscape { -cmsHPROFILE ColorProfile::getSRGBProfile() { +#ifdef ENABLE_LCMS +icColorSpaceSignature asICColorSpaceSig(ColorSpaceSig const & sig) +{ + return ColorSpaceSigWrapper(sig); +} + +icProfileClassSignature asICColorProfileClassSig(ColorProfileClassSig const & sig) +{ + return ColorProfileClassSigWrapper(sig); +} +#endif // ENABLE_LCMS + +} // namespace Inkscape + +ColorProfileImpl::ColorProfileImpl() +#if ENABLE_LCMS + : + _profHandle(0), + _profileClass(icSigInputClass), + _profileSpace(icSigRgbData), + _transf(0), + _revTransf(0), + _gamutTransf(0) +#endif // ENABLE_LCMS +{ +} + +#if ENABLE_LCMS + +cmsHPROFILE ColorProfileImpl::_sRGBProf = 0; + +cmsHPROFILE ColorProfileImpl::getSRGBProfile() { if ( !_sRGBProf ) { _sRGBProf = cmsCreate_sRGBProfile(); } - return _sRGBProf; + return ColorProfileImpl::_sRGBProf; } -cmsHPROFILE ColorProfile::_NullProf = 0; +cmsHPROFILE ColorProfileImpl::_NullProf = 0; -cmsHPROFILE ColorProfile::getNULLProfile() { +cmsHPROFILE ColorProfileImpl::getNULLProfile() { if ( !_NullProf ) { _NullProf = cmsCreateNULLProfile(); } @@ -162,19 +227,13 @@ void ColorProfile::classInit( ColorProfileClass *klass ) */ void ColorProfile::init( ColorProfile *cprof ) { + cprof->impl = new ColorProfileImpl(); + cprof->href = 0; cprof->local = 0; cprof->name = 0; cprof->intentStr = 0; cprof->rendering_intent = Inkscape::RENDERING_INTENT_UNKNOWN; -#if ENABLE_LCMS - cprof->profHandle = 0; - cprof->_profileClass = icSigInputClass; - cprof->_profileSpace = icSigRgbData; - cprof->_transf = 0; - cprof->_revTransf = 0; - cprof->_gamutTransf = 0; -#endif // ENABLE_LCMS } /** @@ -209,12 +268,15 @@ void ColorProfile::release( SPObject *object ) } #if ENABLE_LCMS - cprof->_clearProfile(); + cprof->impl->_clearProfile(); #endif // ENABLE_LCMS + + delete cprof->impl; + cprof->impl = 0; } #if ENABLE_LCMS -void ColorProfile::_clearProfile() +void ColorProfileImpl::_clearProfile() { _profileSpace = icSigRgbData; @@ -230,9 +292,9 @@ void ColorProfile::_clearProfile() cmsDeleteTransform( _gamutTransf ); _gamutTransf = 0; } - if ( profHandle ) { - cmsCloseProfile( profHandle ); - profHandle = 0; + if ( _profHandle ) { + cmsCloseProfile( _profHandle ); + _profHandle = 0; } } #endif // ENABLE_LCMS @@ -309,13 +371,13 @@ void ColorProfile::set( SPObject *object, unsigned key, gchar const *value ) // the w3c specs. All absolute and relative issues are considered org::w3c::dom::URI cprofUri = docUri.resolve(hrefUri); gchar* fullname = g_uri_unescape_string(cprofUri.getNativePath().c_str(), ""); - cprof->_clearProfile(); - cprof->profHandle = cmsOpenProfileFromFile( fullname, "r" ); - if ( cprof->profHandle ) { - cprof->_profileSpace = cmsGetColorSpace( cprof->profHandle ); - cprof->_profileClass = cmsGetDeviceClass( cprof->profHandle ); + cprof->impl->_clearProfile(); + cprof->impl->_profHandle = cmsOpenProfileFromFile( fullname, "r" ); + if ( cprof->impl->_profHandle ) { + cprof->impl->_profileSpace = cmsGetColorSpace( cprof->impl->_profHandle ); + cprof->impl->_profileClass = cmsGetDeviceClass( cprof->impl->_profHandle ); } - DEBUG_MESSAGE( lcmsOne, "cmsOpenProfileFromFile( '%s'...) = %p", fullname, (void*)cprof->profHandle ); + DEBUG_MESSAGE( lcmsOne, "cmsOpenProfileFromFile( '%s'...) = %p", fullname, (void*)cprof->impl->_profHandle ); g_free(escaped); escaped = 0; g_free(fullname); @@ -423,7 +485,7 @@ struct MapMap { DWORD inForm; }; -DWORD ColorProfile::_getInputFormat( icColorSpaceSignature space ) +DWORD ColorProfileImpl::_getInputFormat( icColorSpaceSignature space ) { MapMap possible[] = { {icSigXYZData, TYPE_XYZ_16}, @@ -492,13 +554,13 @@ static SPObject* bruteFind( SPDocument* document, gchar const* name ) return result; } -cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, guint* intent, gchar const* name ) +cmsHPROFILE Inkscape::CMSSystem::getHandle( SPDocument* document, guint* intent, gchar const* name ) { cmsHPROFILE prof = 0; SPObject* thing = bruteFind( document, name ); if ( thing ) { - prof = COLORPROFILE(thing)->profHandle; + prof = COLORPROFILE(thing)->impl->_profHandle; } if ( intent ) { @@ -510,35 +572,43 @@ cmsHPROFILE Inkscape::colorprofile_get_handle( SPDocument* document, guint* inte return prof; } +Inkscape::ColorSpaceSig ColorProfile::getColorSpace() const { + return ColorSpaceSigWrapper(impl->_profileSpace); +} + +Inkscape::ColorProfileClassSig ColorProfile::getProfileClass() const { + return ColorProfileClassSigWrapper(impl->_profileClass); +} + cmsHTRANSFORM ColorProfile::getTransfToSRGB8() { - if ( !_transf && profHandle ) { + if ( !impl->_transf && impl->_profHandle ) { int intent = getLcmsIntent(rendering_intent); - _transf = cmsCreateTransform( profHandle, _getInputFormat(_profileSpace), getSRGBProfile(), TYPE_BGRA_8, intent, 0 ); + impl->_transf = cmsCreateTransform( impl->_profHandle, ColorProfileImpl::_getInputFormat(impl->_profileSpace), ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, intent, 0 ); } - return _transf; + return impl->_transf; } cmsHTRANSFORM ColorProfile::getTransfFromSRGB8() { - if ( !_revTransf && profHandle ) { + if ( !impl->_revTransf && impl->_profHandle ) { int intent = getLcmsIntent(rendering_intent); - _revTransf = cmsCreateTransform( getSRGBProfile(), TYPE_BGRA_8, profHandle, _getInputFormat(_profileSpace), intent, 0 ); + impl->_revTransf = cmsCreateTransform( ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, impl->_profHandle, ColorProfileImpl::_getInputFormat(impl->_profileSpace), intent, 0 ); } - return _revTransf; + return impl->_revTransf; } cmsHTRANSFORM ColorProfile::getTransfGamutCheck() { - if ( !_gamutTransf ) { - _gamutTransf = cmsCreateProofingTransform(getSRGBProfile(), TYPE_BGRA_8, getNULLProfile(), TYPE_GRAY_8, profHandle, INTENT_RELATIVE_COLORIMETRIC, INTENT_RELATIVE_COLORIMETRIC, (cmsFLAGS_GAMUTCHECK|cmsFLAGS_SOFTPROOFING)); + if ( !impl->_gamutTransf ) { + impl->_gamutTransf = cmsCreateProofingTransform(ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, ColorProfileImpl::getNULLProfile(), TYPE_GRAY_8, impl->_profHandle, INTENT_RELATIVE_COLORIMETRIC, INTENT_RELATIVE_COLORIMETRIC, (cmsFLAGS_GAMUTCHECK|cmsFLAGS_SOFTPROOFING)); } - return _gamutTransf; + return impl->_gamutTransf; } bool ColorProfile::GamutCheck(SPColor color){ BYTE outofgamut = 0; - + guint32 val = color.toRGBA32(0); guchar check_color[4] = { SP_RGBA32_R_U(val), @@ -584,9 +654,9 @@ ProfileInfo::ProfileInfo( cmsHPROFILE prof, Glib::ustring const & path ) static std::vector<ProfileInfo> knownProfiles; -std::vector<Glib::ustring> Inkscape::colorprofile_get_display_names() +std::vector<Glib::ustring> Inkscape::CMSSystem::getDisplayNames() { - colorprofile_load_profiles(); + loadProfiles(); std::vector<Glib::ustring> result; for ( std::vector<ProfileInfo>::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { @@ -598,9 +668,9 @@ std::vector<Glib::ustring> Inkscape::colorprofile_get_display_names() return result; } -std::vector<Glib::ustring> Inkscape::colorprofile_get_softproof_names() +std::vector<Glib::ustring> Inkscape::CMSSystem::getSoftproofNames() { - colorprofile_load_profiles(); + loadProfiles(); std::vector<Glib::ustring> result; for ( std::vector<ProfileInfo>::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { @@ -612,9 +682,9 @@ std::vector<Glib::ustring> Inkscape::colorprofile_get_softproof_names() return result; } -Glib::ustring Inkscape::get_path_for_profile(Glib::ustring const& name) +Glib::ustring Inkscape::CMSSystem::getPathForProfile(Glib::ustring const& name) { - colorprofile_load_profiles(); + loadProfiles(); Glib::ustring result; for ( std::vector<ProfileInfo>::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { @@ -626,9 +696,34 @@ Glib::ustring Inkscape::get_path_for_profile(Glib::ustring const& name) return result; } + +void Inkscape::CMSSystem::doTransform(cmsHTRANSFORM transform, void *inBuf, void *outBuf, unsigned int size) +{ + cmsDoTransform(transform, inBuf, outBuf, size); +} + +bool Inkscape::CMSSystem::isPrintColorSpace(ColorProfile const *profile) +{ + bool isPrint = false; + if ( profile ) { + ColorSpaceSigWrapper colorspace = profile->getColorSpace(); + isPrint = (colorspace == icSigCmykData) || (colorspace == icSigCmyData); + } + return isPrint; +} + +gint Inkscape::CMSSystem::getChannelCount(ColorProfile const *profile) +{ + gint count = 0; + if ( profile ) { + count = _cmsChannelsOf( asICColorSpaceSig(profile->getColorSpace()) ); + } + return count; +} + #endif // ENABLE_LCMS -std::list<Glib::ustring> ColorProfile::getBaseProfileDirs() { +std::vector<Glib::ustring> ColorProfile::getBaseProfileDirs() { #if ENABLE_LCMS static bool warnSet = false; if (!warnSet) { @@ -636,7 +731,7 @@ std::list<Glib::ustring> ColorProfile::getBaseProfileDirs() { warnSet = true; } #endif // ENABLE_LCMS - std::list<Glib::ustring> sources; + std::vector<Glib::ustring> sources; gchar* base = profile_path("XXX"); { @@ -662,10 +757,10 @@ std::list<Glib::ustring> ColorProfile::getBaseProfileDirs() { // On OS X: { bool onOSX = false; - std::list<Glib::ustring> possible; + std::vector<Glib::ustring> possible; possible.push_back("/System/Library/ColorSync/Profiles"); possible.push_back("/Library/ColorSync/Profiles"); - for ( std::list<Glib::ustring>::const_iterator it = possible.begin(); it != possible.end(); ++it ) { + for ( std::vector<Glib::ustring>::const_iterator it = possible.begin(); it != possible.end(); ++it ) { if ( g_file_test(it->c_str(), G_FILE_TEST_EXISTS) && g_file_test(it->c_str(), G_FILE_TEST_IS_DIR) ) { sources.push_back(it->c_str()); onOSX = true; @@ -738,11 +833,15 @@ static bool isIccFile( gchar const *filepath ) return isIccFile; } -std::list<Glib::ustring> ColorProfile::getProfileFiles() +std::vector<Glib::ustring> ColorProfile::getProfileFiles() { - std::list<Glib::ustring> files; + std::vector<Glib::ustring> files; - std::list<Glib::ustring> sources = ColorProfile::getBaseProfileDirs(); + std::list<Glib::ustring> sources; + { + std::vector<Glib::ustring> tmp = ColorProfile::getBaseProfileDirs(); + sources.insert(sources.begin(), tmp.begin(), tmp.end()); + } for ( std::list<Glib::ustring>::const_iterator it = sources.begin(); it != sources.end(); ++it ) { if ( g_file_test( it->c_str(), G_FILE_TEST_EXISTS ) && g_file_test( it->c_str(), G_FILE_TEST_IS_DIR ) ) { GError *err = 0; @@ -775,7 +874,28 @@ std::list<Glib::ustring> ColorProfile::getProfileFiles() } #if ENABLE_LCMS +#endif // ENABLE_LCMS + +std::vector<std::pair<Glib::ustring, Glib::ustring> > ColorProfile::getProfileFilesWithNames() +{ + std::vector<std::pair<Glib::ustring, Glib::ustring> > result; + +#if ENABLE_LCMS + std::vector<Glib::ustring> files = getProfileFiles(); + for ( std::vector<Glib::ustring>::const_iterator it = files.begin(); it != files.end(); ++it ) { + cmsHPROFILE hProfile = cmsOpenProfileFromFile(it->c_str(), "r"); + if ( hProfile ) { + Glib::ustring name = getNameFromProfile(hProfile); + result.push_back( std::make_pair(*it, name) ); + cmsCloseProfile(hProfile); + } + } +#endif // ENABLE_LCMS + + return result; +} +#if ENABLE_LCMS int errorHandlerCB(int ErrorCode, const char *ErrorText) { g_message("lcms: Error %d; %s", ErrorCode, ErrorText); @@ -783,9 +903,28 @@ int errorHandlerCB(int ErrorCode, const char *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) +namespace +{ +Glib::ustring getNameFromProfile(cmsHPROFILE profile) +{ + gchar const *name = 0; + if ( profile ) { + name = cmsTakeProductDesc(profile); + if ( !name ) { + name = cmsTakeProductName(profile); + } + if ( name && !g_utf8_validate(name, -1, NULL) ) { + name = _("(invalid UTF-8 string)"); + } + } + return (name) ? name : _("None"); +} + +/** + * This function loads or refreshes data in knownProfiles. + * Call it at the start of every call that requires this data. + */ +void loadProfiles() { static bool error_handler_set = false; if (!error_handler_set) { @@ -794,32 +933,34 @@ void Inkscape::colorprofile_load_profiles(bool force_refresh) } 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 ) { - cmsHPROFILE prof = cmsOpenProfileFromFile( it->c_str(), "r" ); - if ( prof ) { - ProfileInfo info( prof, Glib::filename_to_utf8( it->c_str() ) ); - cmsCloseProfile( prof ); + if ( !profiles_searched ) { + knownProfiles.clear(); + std::vector<Glib::ustring> files = ColorProfile::getProfileFiles(); - bool sameName = false; - for ( std::vector<ProfileInfo>::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { - if ( it->getName() == info.getName() ) { - sameName = true; - break; + for ( std::vector<Glib::ustring>::const_iterator it = files.begin(); it != files.end(); ++it ) { + cmsHPROFILE prof = cmsOpenProfileFromFile( it->c_str(), "r" ); + if ( prof ) { + ProfileInfo info( prof, Glib::filename_to_utf8( it->c_str() ) ); + cmsCloseProfile( prof ); + prof = 0; + + bool sameName = false; + for ( std::vector<ProfileInfo>::iterator it = knownProfiles.begin(); it != knownProfiles.end(); ++it ) { + if ( it->getName() == info.getName() ) { + sameName = true; + break; + } } - } - if ( !sameName ) { - knownProfiles.push_back(info); + if ( !sameName ) { + knownProfiles.push_back(info); + } } } + profiles_searched = true; } - profiles_searched = true; } +} // namespace static bool gamutWarn = false; static Gdk::Color lastGamutColor("#808080"); @@ -831,12 +972,13 @@ static int lastIntent = INTENT_PERCEPTUAL; static int lastProofIntent = INTENT_PERCEPTUAL; static cmsHTRANSFORM transf = 0; -cmsHPROFILE Inkscape::colorprofile_get_system_profile_handle() +namespace { +cmsHPROFILE getSystemProfileHandle() { static cmsHPROFILE theOne = 0; static Glib::ustring lastURI; - colorprofile_load_profiles(); + loadProfiles(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Glib::ustring uri = prefs->getString("/options/displayprofile/uri"); @@ -884,12 +1026,12 @@ cmsHPROFILE Inkscape::colorprofile_get_system_profile_handle() } -cmsHPROFILE Inkscape::colorprofile_get_proof_profile_handle() +cmsHPROFILE getProofProfileHandle() { static cmsHPROFILE theOne = 0; static Glib::ustring lastURI; - colorprofile_load_profiles(); + loadProfiles(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool which = prefs->getBool( "/options/softproof/enable"); @@ -942,10 +1084,11 @@ cmsHPROFILE Inkscape::colorprofile_get_proof_profile_handle() return theOne; } +} // namespace static void free_transforms(); -cmsHTRANSFORM Inkscape::colorprofile_get_display_transform() +cmsHTRANSFORM Inkscape::CMSSystem::getDisplayTransform() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool fromDisplay = prefs->getBool( "/options/displayprofile/from_display"); @@ -988,8 +1131,8 @@ cmsHTRANSFORM Inkscape::colorprofile_get_display_transform() } // Fetch 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; + cmsHPROFILE hprof = getSystemProfileHandle(); + cmsHPROFILE proofProf = hprof ? getProofProfileHandle() : 0; if ( !transf ) { if ( hprof && proofProf ) { @@ -1006,9 +1149,9 @@ cmsHTRANSFORM Inkscape::colorprofile_get_display_transform() dwFlags |= cmsFLAGS_PRESERVEBLACK; } #endif // defined(cmsFLAGS_PRESERVEBLACK) - transf = cmsCreateProofingTransform( ColorProfile::getSRGBProfile(), TYPE_BGRA_8, hprof, TYPE_BGRA_8, proofProf, intent, proofIntent, dwFlags ); + transf = cmsCreateProofingTransform( ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, hprof, TYPE_BGRA_8, proofProf, intent, proofIntent, dwFlags ); } else if ( hprof ) { - transf = cmsCreateTransform( ColorProfile::getSRGBProfile(), TYPE_BGRA_8, hprof, TYPE_BGRA_8, intent, 0 ); + transf = cmsCreateTransform( ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, hprof, TYPE_BGRA_8, intent, 0 ); } } @@ -1056,7 +1199,7 @@ void free_transforms() } } -Glib::ustring Inkscape::colorprofile_get_display_id( int screen, int monitor ) +Glib::ustring Inkscape::CMSSystem::getDisplayId( int screen, int monitor ) { Glib::ustring id; @@ -1071,7 +1214,7 @@ Glib::ustring Inkscape::colorprofile_get_display_id( int screen, int monitor ) return id; } -Glib::ustring Inkscape::colorprofile_set_display_per( gpointer buf, guint bufLen, int screen, int monitor ) +Glib::ustring Inkscape::CMSSystem::setDisplayPer( gpointer buf, guint bufLen, int screen, int monitor ) { Glib::ustring id; @@ -1104,7 +1247,7 @@ Glib::ustring Inkscape::colorprofile_set_display_per( gpointer buf, guint bufLen return id; } -cmsHTRANSFORM Inkscape::colorprofile_get_display_per( Glib::ustring const& id ) +cmsHTRANSFORM Inkscape::CMSSystem::getDisplayPer( Glib::ustring const& id ) { cmsHTRANSFORM result = 0; if ( id.empty() ) { @@ -1149,7 +1292,7 @@ cmsHTRANSFORM Inkscape::colorprofile_get_display_per( Glib::ustring const& id ) } // Fetch these now, as they might clear the transform as a side effect. - cmsHPROFILE proofProf = item.hprof ? Inkscape::colorprofile_get_proof_profile_handle() : 0; + cmsHPROFILE proofProf = item.hprof ? getProofProfileHandle() : 0; if ( !item.transf ) { if ( item.hprof && proofProf ) { @@ -1166,9 +1309,9 @@ cmsHTRANSFORM Inkscape::colorprofile_get_display_per( Glib::ustring const& id ) dwFlags |= cmsFLAGS_PRESERVEBLACK; } #endif // defined(cmsFLAGS_PRESERVEBLACK) - item.transf = cmsCreateProofingTransform( ColorProfile::getSRGBProfile(), TYPE_BGRA_8, item.hprof, TYPE_BGRA_8, proofProf, intent, proofIntent, dwFlags ); + item.transf = cmsCreateProofingTransform( ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, item.hprof, TYPE_BGRA_8, proofProf, intent, proofIntent, dwFlags ); } else if ( item.hprof ) { - item.transf = cmsCreateTransform( ColorProfile::getSRGBProfile(), TYPE_BGRA_8, item.hprof, TYPE_BGRA_8, intent, 0 ); + item.transf = cmsCreateTransform( ColorProfileImpl::getSRGBProfile(), TYPE_BGRA_8, item.hprof, TYPE_BGRA_8, intent, 0 ); } } diff --git a/src/color-profile.h b/src/color-profile.h index e1dd298bd..a9724defc 100644 --- a/src/color-profile.h +++ b/src/color-profile.h @@ -5,12 +5,11 @@ * SPColorProfile: SVG <color-profile> implementation */ +#include <vector> #include <glib/gtypes.h> #include <sp-object.h> #include <glibmm/ustring.h> -#if ENABLE_LCMS -#include <lcms.h> -#endif // ENABLE_LCMS +#include "cms-color-types.h" namespace Inkscape { @@ -23,6 +22,9 @@ enum { RENDERING_INTENT_ABSOLUTE_COLORIMETRIC = 5 }; +class ColorProfileImpl; + + /// The SPColorProfile vtable. struct ColorProfileClass { SPObjectClass parent_class; @@ -30,17 +32,20 @@ struct ColorProfileClass { /** Color Profile. */ struct ColorProfile : public SPObject { + friend cmsHPROFILE colorprofile_get_handle( SPDocument*, guint*, gchar const* ); + friend class CMSSystem; + static GType getType(); static void classInit( ColorProfileClass *klass ); - static std::list<Glib::ustring> getBaseProfileDirs(); - static std::list<Glib::ustring> getProfileFiles(); + static std::vector<Glib::ustring> getBaseProfileDirs(); + static std::vector<Glib::ustring> getProfileFiles(); + static std::vector<std::pair<Glib::ustring, Glib::ustring> > getProfileFilesWithNames(); #if ENABLE_LCMS - static cmsHPROFILE getSRGBProfile(); - static cmsHPROFILE getNULLProfile(); - - icColorSpaceSignature getColorSpace() const {return _profileSpace;} - icProfileClassSignature getProfileClass() const {return _profileClass;} + //icColorSpaceSignature getColorSpace() const; + ColorSpaceSig getColorSpace() const; + //icProfileClassSignature getProfileClass() const; + ColorProfileClassSig getProfileClass() const; cmsHTRANSFORM getTransfToSRGB8(); cmsHTRANSFORM getTransfFromSRGB8(); cmsHTRANSFORM getTransfGamutCheck(); @@ -53,9 +58,6 @@ struct ColorProfile : public SPObject { gchar* name; gchar* intentStr; guint rendering_intent; -#if ENABLE_LCMS - cmsHPROFILE profHandle; -#endif // ENABLE_LCMS private: static void init( ColorProfile *cprof ); @@ -64,23 +66,20 @@ private: static void build( SPObject *object, SPDocument *document, Inkscape::XML::Node *repr ); static void set( SPObject *object, unsigned key, gchar const *value ); static Inkscape::XML::Node *write( SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags ); -#if ENABLE_LCMS - static DWORD _getInputFormat( icColorSpaceSignature space ); - void _clearProfile(); - - static cmsHPROFILE _sRGBProf; - static cmsHPROFILE _NullProf; - icProfileClassSignature _profileClass; - icColorSpaceSignature _profileSpace; - cmsHTRANSFORM _transf; - cmsHTRANSFORM _revTransf; - cmsHTRANSFORM _gamutTransf; -#endif // ENABLE_LCMS + ColorProfileImpl *impl; }; +GType colorprofile_get_type(); + } // namespace Inkscape +#define COLORPROFILE_TYPE (Inkscape::colorprofile_get_type()) +#define COLORPROFILE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), COLORPROFILE_TYPE, Inkscape::ColorProfile)) +#define COLORPROFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), COLORPROFILE_TYPE, Inkscape::ColorProfileClass)) +#define IS_COLORPROFILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), COLORPROFILE_TYPE)) +#define IS_COLORPROFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), COLORPROFILE_TYPE)) + #endif // !SEEN_COLOR_PROFILE_H /* diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 90f65c33e..8b75f09a6 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -345,6 +345,18 @@ ink_cairo_surface_create_for_argb32_pixbuf(GdkPixbuf *pb) return pbs; } +/** @brief Cleanup function for GdkPixbuf. + * This function should be passed as the GdkPixbufDestroyNotify parameter + * to gdk_pixbuf_new_from_data when creating a GdkPixbuf backed by + * a Cairo surface. + */ +void +ink_cairo_pixbuf_cleanup(guchar *pixels, void *data) +{ + cairo_surface_t *surface = reinterpret_cast<cairo_surface_t*>(data); + cairo_surface_destroy(surface); +} + /** @brief Create an exact copy of a surface. * Creates a surface that has the same type, content type, dimensions and contents * as the specified surface. */ diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h index 0c2ac2dd6..1de88785d 100644 --- a/src/display/cairo-utils.h +++ b/src/display/cairo-utils.h @@ -106,6 +106,7 @@ void convert_pixels_argb32_to_pixbuf(guchar *data, int w, int h, int rs); void convert_pixbuf_normal_to_argb32(GdkPixbuf *); void convert_pixbuf_argb32_to_normal(GdkPixbuf *); cairo_surface_t *ink_cairo_surface_create_for_argb32_pixbuf(GdkPixbuf *pb); +void ink_cairo_pixbuf_cleanup(guchar *pixels, void *surface); G_GNUC_CONST guint32 argb32_from_pixbuf(guint32 in); G_GNUC_CONST guint32 pixbuf_from_argb32(guint32 in); diff --git a/src/display/nr-arena-glyphs.cpp b/src/display/nr-arena-glyphs.cpp index b76e87a78..d09f66a2f 100644 --- a/src/display/nr-arena-glyphs.cpp +++ b/src/display/nr-arena-glyphs.cpp @@ -295,28 +295,26 @@ nr_arena_glyphs_group_render(cairo_t *ct, NRArenaItem *item, NRRectL *area, NRPi } if (item->arena->rendermode == Inkscape::RENDERMODE_OUTLINE) { - + cairo_save(ct); guint32 rgba = item->arena->outlinecolor; ink_cairo_set_source_rgba32(ct, rgba); cairo_set_tolerance(ct, 1.25); // low quality, but good enough for outline mode - - NRRect temp(area->x0, area->y0, area->x1, area->y1); - Geom::OptRect area_2geom = temp.upgrade_2geom(); + cairo_new_path(ct); + ink_cairo_transform(ct, ggroup->ctm); for (child = group->children; child != NULL; child = child->next) { NRArenaGlyphs *g = NR_ARENA_GLYPHS(child); Geom::PathVector const * pathv = g->font->PathVector(g->glyph); - Geom::Affine transform = g->g_transform * group->ctm; + Geom::Affine transform = g->g_transform; - cairo_new_path(ct); cairo_save(ct); ink_cairo_transform(ct, transform); feed_pathvector_to_cairo (ct, *pathv); cairo_fill(ct); cairo_restore(ct); } - + cairo_restore(ct); return item->state; } diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 29729ef6c..f6446bdd7 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -30,9 +30,7 @@ #include "preferences.h" #include "inkscape.h" #include "sodipodi-ctrlrect.h" -#if ENABLE_LCMS -#include "color-profile-fns.h" -#endif // ENABLE_LCMS +#include "cms-system.h" #include "display/rendermode.h" #include "display/cairo-utils.h" #include "debug/gdk-event-latency-tracker.h" @@ -1696,9 +1694,9 @@ static void sp_canvas_paint_single_buffer(SPCanvas *canvas, int x0, int y0, int 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) : "" ); + transf = Inkscape::CMSSystem::getDisplayPer( canvas->cms_key ? *(canvas->cms_key) : "" ); } else { - transf = Inkscape::colorprofile_get_display_transform(); + transf = Inkscape::CMSSystem::getDisplayTransform(); } if (transf) { @@ -1707,7 +1705,7 @@ static void sp_canvas_paint_single_buffer(SPCanvas *canvas, int x0, int y0, int 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); + Inkscape::CMSSystem::doTransform(transf, row, row, w); } cairo_surface_mark_dirty(imgs); } diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 2f3e2cd65..e7599d996 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -855,6 +855,7 @@ void Script::checkStderr (const Glib::ustring &data, vbox->pack_start(*scrollwindow, true, true, 5 /* fix these */); + warning.maximize(); warning.run(); return; diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 1c1dac028..22b68b0ca 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -1419,7 +1419,7 @@ CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle con return true; } -bool CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, unsigned int rs, +bool CairoRenderContext::renderImage(GdkPixbuf *pb, Geom::Affine const *image_transform, SPStyle const * /*style*/) { g_assert( _is_valid ); @@ -1428,63 +1428,18 @@ bool CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, return true; } - guchar* px_rgba = NULL; - guint64 size = 4L * (guint64)w * (guint64)h; + int w = gdk_pixbuf_get_width (pb); + int h = gdk_pixbuf_get_height (pb); - if(size < (guint64)G_MAXSIZE) { - px_rgba = (guchar*)g_try_malloc(4 * w * h); - if (!px_rgba) { - g_warning ("Could not allocate %lu bytes for pixel buffer!", (long unsigned) size); - return false; - } - } else { - g_warning ("the requested memory exceeds the system limit"); - return false; - } - - - float opacity; - if (_state->merge_opacity) - opacity = _state->opacity; - else - opacity = 1.0; - - // make a copy of the original pixbuf with premultiplied alpha - // if we pass the original pixbuf it will get messed up - /// @todo optimize this code, it costs a lot of time - for (unsigned i = 0; i < h; i++) { - guchar const *src = px + i * rs; - guint32 *dst = (guint32 *)(px_rgba + i * rs); - for (unsigned j = 0; j < w; j++) { - guchar r, g, b, alpha_dst; - - // calculate opacity-modified alpha - alpha_dst = src[3]; - if ((opacity != 1.0) && _vector_based_target) - alpha_dst = (guchar)ceil((float)alpha_dst * opacity); - - // premul alpha (needed because this will be undone by cairo-pdf) - r = src[0]*alpha_dst/255; - g = src[1]*alpha_dst/255; - b = src[2]*alpha_dst/255; - - *dst = (((alpha_dst) << 24) | (((r)) << 16) | (((g)) << 8) | (b)); - - dst++; // pointer to 4byte variables - src += 4; // pointer to 1byte variables - } - } + // TODO: reenable merge_opacity if useful + float opacity = _state->opacity; - cairo_surface_t *image_surface = cairo_image_surface_create_for_data(px_rgba, CAIRO_FORMAT_ARGB32, w, h, w * 4); + cairo_surface_t *image_surface = ink_cairo_surface_create_for_argb32_pixbuf(pb); if (cairo_surface_status(image_surface)) { TRACE(("Image surface creation failed:\n%s\n", cairo_status_to_string(cairo_surface_status(image_surface)))); return false; } - // setup automatic freeing of the image data when destroying the surface - static cairo_user_data_key_t key; - cairo_surface_set_user_data(image_surface, &key, px_rgba, (cairo_destroy_func_t)g_free); - cairo_save(_cr); // scaling by width & height is not needed because it will be done by Cairo @@ -1499,16 +1454,10 @@ bool CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, cairo_rectangle(_cr, 0, 0, w, h); cairo_clip(_cr); } - - if (_vector_based_target) - cairo_paint(_cr); - else - cairo_paint_with_alpha(_cr, opacity); + cairo_paint_with_alpha(_cr, opacity); cairo_restore(_cr); - cairo_surface_destroy(image_surface); - return true; } diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index 68a3c6537..d4117ff7e 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -139,7 +139,7 @@ public: /* Rendering methods */ bool renderPathVector(Geom::PathVector const & pathv, SPStyle const *style, NRRect const *pbox); - bool renderImage(unsigned char *px, unsigned int w, unsigned int h, unsigned int rs, + bool renderImage(GdkPixbuf *pb, Geom::Affine const *image_transform, SPStyle const *style); bool renderGlyphtext(PangoFont *font, Geom::Affine const *font_matrix, std::vector<CairoGlyphInfo> const &glyphtext, SPStyle const *style); diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index bbafd7e94..1e550f7d1 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -41,6 +41,7 @@ #include "display/nr-arena-group.h" #include "display/curve.h" #include "display/canvas-bpath.h" +#include "display/cairo-utils.h" #include "sp-item.h" #include "sp-item-group.h" #include "style.h" @@ -345,18 +346,15 @@ static void sp_flowtext_render(SPItem *item, CairoRenderContext *ctx) static void sp_image_render(SPItem *item, CairoRenderContext *ctx) { SPImage *image; - guchar *px; - int w, h, rs; + int w, h; image = SP_IMAGE (item); if (!image->pixbuf) return; if ((image->width.computed <= 0.0) || (image->height.computed <= 0.0)) return; - px = gdk_pixbuf_get_pixels (image->pixbuf); w = gdk_pixbuf_get_width (image->pixbuf); h = gdk_pixbuf_get_height (image->pixbuf); - rs = gdk_pixbuf_get_rowstride (image->pixbuf); double x = image->x.computed; double y = image->y.computed; @@ -376,7 +374,7 @@ static void sp_image_render(SPItem *item, CairoRenderContext *ctx) Geom::Scale s(width / (double)w, height / (double)h); Geom::Affine t(s * tp); - ctx->renderImage (px, w, h, rs, &t, item->style); + ctx->renderImage (image->pixbuf, &t, item->style); } static void sp_symbol_render(SPItem *item, CairoRenderContext *ctx) @@ -477,9 +475,11 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx) } // The width and height of the bitmap in pixels - unsigned width = (unsigned) floor ((bbox->max()[Geom::X] - bbox->min()[Geom::X]) * (res / PX_PER_IN)); - unsigned height =(unsigned) floor ((bbox->max()[Geom::Y] - bbox->min()[Geom::Y]) * (res / PX_PER_IN)); - + unsigned width = ceil((bbox->max()[Geom::X] - bbox->min()[Geom::X]) * (res / PX_PER_IN)); + unsigned height = ceil((bbox->max()[Geom::Y] - bbox->min()[Geom::Y]) * (res / PX_PER_IN)); + + if (width == 0 || height == 0) return; + // Scale to exactly fit integer bitmap inside bounding box double scale_x = (bbox->max()[Geom::X] - bbox->min()[Geom::X]) / width; double scale_y = (bbox->max()[Geom::Y] - bbox->min()[Geom::Y]) / height; @@ -516,11 +516,9 @@ static void sp_asbitmap_render(SPItem *item, CairoRenderContext *ctx) if (pb) { TEST(gdk_pixbuf_save( pb, "bitmap.png", "png", NULL, NULL )); - unsigned char *px = gdk_pixbuf_get_pixels (pb); - unsigned int w = gdk_pixbuf_get_width(pb); - unsigned int h = gdk_pixbuf_get_height(pb); - unsigned int rs = gdk_pixbuf_get_rowstride(pb); - ctx->renderImage(px, w, h, rs, &t, item->style); + // TODO this is stupid - we just converted to pixbuf format when generating the bitmap! + convert_pixbuf_normal_to_argb32(pb); + ctx->renderImage(pb, &t, item->style); gdk_pixbuf_unref(pb); pb = 0; } diff --git a/src/extension/internal/filter/abc.h b/src/extension/internal/filter/abc.h index 8368d3f3b..cf2bc8927 100755 --- a/src/extension/internal/filter/abc.h +++ b/src/extension/internal/filter/abc.h @@ -218,7 +218,7 @@ ColorShift::get_filter_text (Inkscape::Extension::Extension * ext) * Smoothness (0.->10., default 6.) -> blur (stdDeviation) * Elevation (0->360, default 25) -> feDistantLight (elevation) * Azimuth (0->360, default 235) -> feDistantLight (azimuth) - * Lightning color (guint, default -1 [white]) -> diffuse (lighting-color) + * Lighting color (guint, default -1 [white]) -> diffuse (lighting-color) */ class DiffuseLight : public Inkscape::Extension::Internal::Filter::Filter { @@ -237,7 +237,7 @@ public: "<param name=\"smooth\" gui-text=\"" N_("Smoothness:") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"10\">6</param>\n" "<param name=\"elevation\" gui-text=\"" N_("Elevation (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">25</param>\n" "<param name=\"azimuth\" gui-text=\"" N_("Azimuth (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">235</param>\n" - "<param name=\"color\" gui-text=\"" N_("Lightning color") "\" type=\"color\">-1</param>\n" + "<param name=\"color\" gui-text=\"" N_("Lighting color") "\" type=\"color\">-1</param>\n" "<effect>\n" "<object-type>all</object-type>\n" "<effects-menu>\n" @@ -355,7 +355,7 @@ Feather::get_filter_text (Inkscape::Extension::Extension * ext) * Brightness (0.0->5., default .9) -> specular (specularConstant) * Elevation (0->360, default 60) -> feDistantLight (elevation) * Azimuth (0->360, default 225) -> feDistantLight (azimuth) - * Lightning color (guint, default -1 [white]) -> specular (lighting-color) + * Lighting color (guint, default -1 [white]) -> specular (lighting-color) */ class MatteJelly : public Inkscape::Extension::Internal::Filter::Filter { @@ -375,7 +375,7 @@ public: "<param name=\"bright\" gui-text=\"" N_("Brightness:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.00\" max=\"5.00\">0.9</param>\n" "<param name=\"elevation\" gui-text=\"" N_("Elevation (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">60</param>\n" "<param name=\"azimuth\" gui-text=\"" N_("Azimuth (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">225</param>\n" - "<param name=\"color\" gui-text=\"" N_("Lightning color") "\" type=\"color\">-1</param>\n" + "<param name=\"color\" gui-text=\"" N_("Lighting color") "\" type=\"color\">-1</param>\n" "<effect>\n" "<object-type>all</object-type>\n" "<effects-menu>\n" @@ -795,7 +795,7 @@ Silhouette::get_filter_text (Inkscape::Extension::Extension * ext) * Brightness (0.0->5., default 1.) -> specular (specularConstant) * Elevation (0->360, default 45) -> feDistantLight (elevation) * Azimuth (0->360, default 235) -> feDistantLight (azimuth) - * Lightning color (guint, default -1 [white]) -> specular (lighting-color) + * Lighting color (guint, default -1 [white]) -> specular (lighting-color) */ class SpecularLight : public Inkscape::Extension::Internal::Filter::Filter { @@ -815,7 +815,7 @@ public: "<param name=\"bright\" gui-text=\"" N_("Brightness:") "\" type=\"float\" appearance=\"full\" min=\"0.0\" max=\"5\">1</param>\n" "<param name=\"elevation\" gui-text=\"" N_("Elevation (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">45</param>\n" "<param name=\"azimuth\" gui-text=\"" N_("Azimuth (°):") "\" type=\"int\" appearance=\"full\" min=\"0\" max=\"360\">235</param>\n" - "<param name=\"color\" gui-text=\"" N_("Lightning color") "\" type=\"color\">-1</param>\n" + "<param name=\"color\" gui-text=\"" N_("Lighting color") "\" type=\"color\">-1</param>\n" "<effect>\n" "<object-type>all</object-type>\n" "<effects-menu>\n" diff --git a/src/helper/pixbuf-ops.cpp b/src/helper/pixbuf-ops.cpp index 226042337..e1ced31b4 100644 --- a/src/helper/pixbuf-ops.cpp +++ b/src/helper/pixbuf-ops.cpp @@ -108,6 +108,7 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/, GSList *items_only) { + if (width == 0 || height == 0) return NULL; GdkPixbuf* pixbuf = NULL; /* Create new arena for offscreen rendering*/ @@ -168,8 +169,8 @@ sp_generate_internal_bitmap(SPDocument *doc, gchar const */*filename*/, pixbuf = gdk_pixbuf_new_from_data(cairo_image_surface_get_data(surface), GDK_COLORSPACE_RGB, TRUE, 8, width, height, cairo_image_surface_get_stride(surface), - (GdkPixbufDestroyNotify) cairo_surface_destroy, - NULL); + ink_cairo_pixbuf_cleanup, + surface); convert_pixbuf_argb32_to_normal(pixbuf); } else diff --git a/src/interface.cpp b/src/interface.cpp index c7946cf18..9aa5cad31 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -56,10 +56,6 @@ #include "message-context.h" #include "ui/uxmanager.h" -// Added for color drag-n-drop -#if ENABLE_LCMS -#include "lcms.h" -#endif // ENABLE_LCMS #include "display/sp-canvas.h" #include "color.h" #include "svg/svg-color.h" diff --git a/src/libgdl/CMakeLists.txt b/src/libgdl/CMakeLists.txt index befb6edb7..3457337e9 100644 --- a/src/libgdl/CMakeLists.txt +++ b/src/libgdl/CMakeLists.txt @@ -1,17 +1,17 @@ set(libgdl_SRC - gdl-dock.c gdl-dock-bar.c - gdl-dock-item.c + gdl-dock-item-button-image.c gdl-dock-item-grip.c + gdl-dock-item.c gdl-dock-master.c gdl-dock-notebook.c gdl-dock-object.c gdl-dock-paned.c gdl-dock-placeholder.c gdl-dock-tablabel.c + gdl-dock.c gdl-i18n.c - gdl-stock.c gdl-switcher.c gdl-tools.h libgdlmarshal.c @@ -21,6 +21,7 @@ set(libgdl_SRC # ------- # Headers gdl-dock-bar.h + gdl-dock-item-button-image.h gdl-dock-item-grip.h gdl-dock-item.h gdl-dock-master.h @@ -32,9 +33,8 @@ set(libgdl_SRC gdl-dock.h gdl-i18n.h gdl-stock-icons.h - gdl-stock.h gdl-switcher.h - libgdl.h + gdl.h libgdlmarshal.h libgdltypebuiltins.h ) diff --git a/src/libgdl/Makefile_insert b/src/libgdl/Makefile_insert index 5869633ea..e151fd5d6 100644 --- a/src/libgdl/Makefile_insert +++ b/src/libgdl/Makefile_insert @@ -16,7 +16,6 @@ libgdl_libgdl_a_SOURCES = \ libgdl/gdl-dock-tablabel.h \ libgdl/gdl-dock-placeholder.h \ libgdl/gdl-dock-bar.h \ - libgdl/gdl-stock.h \ libgdl/gdl-stock-icons.h \ libgdl/gdl-i18n.h \ libgdl/gdl-i18n.c \ @@ -24,6 +23,8 @@ libgdl_libgdl_a_SOURCES = \ libgdl/gdl-dock-master.c \ libgdl/gdl-dock.c \ libgdl/gdl-dock-item.c \ + libgdl/gdl-dock-item-button-image.c \ + libgdl/gdl-dock-item-button-image.h \ libgdl/gdl-dock-item-grip.h \ libgdl/gdl-dock-item-grip.c \ libgdl/gdl-dock-notebook.c \ @@ -31,7 +32,6 @@ libgdl_libgdl_a_SOURCES = \ libgdl/gdl-dock-tablabel.c \ libgdl/gdl-dock-placeholder.c \ libgdl/gdl-dock-bar.c \ - libgdl/gdl-stock.c \ libgdl/gdl-switcher.h \ libgdl/gdl-switcher.c \ libgdl/gdl-win32.h \ @@ -40,4 +40,4 @@ libgdl_libgdl_a_SOURCES = \ libgdl/libgdltypebuiltins.c \ libgdl/libgdlmarshal.h \ libgdl/libgdlmarshal.c \ - libgdl/libgdl.h + libgdl/gdl.h diff --git a/src/libgdl/gdl-dock-bar.h b/src/libgdl/gdl-dock-bar.h index 798dded20..ca6da1d26 100644 --- a/src/libgdl/gdl-dock-bar.h +++ b/src/libgdl/gdl-dock-bar.h @@ -23,7 +23,6 @@ #define __GDL_DOCK_BAR_H__ #include <gtk/gtk.h> -#include "libgdl/gdl-dock.h" G_BEGIN_DECLS diff --git a/src/libgdl/gdl-dock-item-button-image.c b/src/libgdl/gdl-dock-item-button-image.c new file mode 100644 index 000000000..f115c652c --- /dev/null +++ b/src/libgdl/gdl-dock-item-button-image.c @@ -0,0 +1,169 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * gdl-dock-item-button-image.c + * + * Author: Joel Holdsworth <joel@airwebreathe.org.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gdl-dock-item-button-image.h" + +#include <math.h> +#include "gdl-tools.h" + +#define ICON_SIZE 12 + +GDL_CLASS_BOILERPLATE (GdlDockItemButtonImage, + gdl_dock_item_button_image, + GtkWidget, GTK_TYPE_WIDGET); + +static gint +gdl_dock_item_button_image_expose (GtkWidget *widget, + GdkEventExpose *event) +{ + GdlDockItemButtonImage *button_image; + GtkStyle *style; + GdkColor *color; + + g_return_val_if_fail (widget != NULL, 0); + button_image = GDL_DOCK_ITEM_BUTTON_IMAGE (widget); + + cairo_t *cr = gdk_cairo_create (event->window); + cairo_translate (cr, event->area.x, event->area.y); + + /* Set up the pen */ + cairo_set_line_width(cr, 1.0); + + style = gtk_widget_get_style (widget); + g_return_if_fail (style != NULL); + color = &style->fg[GTK_STATE_NORMAL]; + cairo_set_source_rgba(cr, color->red / 65535.0, + color->green / 65535.0, color->blue / 65535.0, 0.55); + + /* Draw the icon border */ + cairo_move_to (cr, 10.5, 2.5); + cairo_arc (cr, 10.5, 4.5, 2, -0.5 * M_PI, 0); + cairo_line_to (cr, 12.5, 10.5); + cairo_arc (cr, 10.5, 10.5, 2, 0, 0.5 * M_PI); + cairo_line_to (cr, 4.5, 12.5); + cairo_arc (cr, 4.5, 10.5, 2, 0.5 * M_PI, M_PI); + cairo_line_to (cr, 2.5, 4.5); + cairo_arc (cr, 4.5, 4.5, 2, M_PI, 1.5 * M_PI); + cairo_close_path (cr); + + cairo_stroke (cr); + + /* Draw the icon */ + cairo_new_path (cr); + + switch(button_image->image_type) { + case GDL_DOCK_ITEM_BUTTON_IMAGE_CLOSE: + cairo_move_to (cr, 4.0, 5.5); + cairo_line_to (cr, 4.0, 5.5); + cairo_line_to (cr, 6.0, 7.5); + cairo_line_to (cr, 4.0, 9.5); + cairo_line_to (cr, 5.5, 11.0); + cairo_line_to (cr, 7.5, 9.0); + cairo_line_to (cr, 9.5, 11.0); + cairo_line_to (cr, 11.0, 9.5); + cairo_line_to (cr, 9.0, 7.5); + cairo_line_to (cr, 11.0, 5.5); + cairo_line_to (cr, 9.5, 4.0); + cairo_line_to (cr, 7.5, 6.0); + cairo_line_to (cr, 5.5, 4.0); + cairo_close_path (cr); + break; + + case GDL_DOCK_ITEM_BUTTON_IMAGE_ICONIFY: + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) { + cairo_move_to (cr, 4.5, 7.5); + cairo_line_to (cr, 10.0, 4.75); + cairo_line_to (cr, 10.0, 10.25); + cairo_close_path (cr); + } else { + cairo_move_to (cr, 10.5, 7.5); + cairo_line_to (cr, 5, 4.75); + cairo_line_to (cr, 5, 10.25); + cairo_close_path (cr); + } + break; + + default: + break; + } + + cairo_fill (cr); + + /* Finish up */ + cairo_destroy (cr); + + return 0; +} + +static void +gdl_dock_item_button_image_instance_init ( + GdlDockItemButtonImage *button_image) +{ + GTK_WIDGET_SET_FLAGS (button_image, GTK_NO_WINDOW); +} + +static void +gdl_dock_item_button_image_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + g_return_if_fail (GDL_IS_DOCK_ITEM_BUTTON_IMAGE (widget)); + g_return_if_fail (requisition != NULL); + + requisition->width = ICON_SIZE; + requisition->height = ICON_SIZE; +} + +static void +gdl_dock_item_button_image_class_init ( + GdlDockItemButtonImageClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + widget_class->expose_event = + gdl_dock_item_button_image_expose; + widget_class->size_request = + gdl_dock_item_button_image_size_request; +} + +/* ----- Public interface ----- */ + +/** + * gdl_dock_item_button_image_new: + * @param image_type: Specifies what type of image the widget should + * display + * + * Creates a new GDL dock button image object. + * Returns: The newly created dock item button image widget. + **/ +GtkWidget* +gdl_dock_item_button_image_new (GdlDockItemButtonImageType image_type) +{ + GdlDockItemButtonImage *button_image = g_object_new ( + GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE, NULL); + button_image->image_type = image_type; + + return GTK_WIDGET (button_image); +} diff --git a/src/libgdl/gdl-dock-item-button-image.h b/src/libgdl/gdl-dock-item-button-image.h new file mode 100644 index 000000000..ce0c6faaf --- /dev/null +++ b/src/libgdl/gdl-dock-item-button-image.h @@ -0,0 +1,70 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * gdl-dock-item-button-image.h + * + * Author: Joel Holdsworth <joel@airwebreathe.org.uk> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _GDL_DOCK_ITEM_BUTTON_IMAGE_H_ +#define _GDL_DOCK_ITEM_BUTTON_IMAGE_H_ + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +/* Standard Macros */ +#define GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE \ + (gdl_dock_item_button_image_get_type()) +#define GDL_DOCK_ITEM_BUTTON_IMAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE, GdlDockItemButtonImage)) +#define GDL_DOCK_ITEM_BUTTON_IMAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE, GdlDockItemButtonImageClass)) +#define GDL_IS_DOCK_ITEM_BUTTON_IMAGE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE)) +#define GDL_IS_DOCK_ITEM_BUTTON_IMAGE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE)) +#define GDL_DOCK_ITEM_BUTTON_IMAGE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), GDL_TYPE_DOCK_ITEM_BUTTON_IMAGE, GdlDockItemButtonImageClass)) + +/* Data Types & Structures */ +typedef enum { + GDL_DOCK_ITEM_BUTTON_IMAGE_CLOSE, + GDL_DOCK_ITEM_BUTTON_IMAGE_ICONIFY +} GdlDockItemButtonImageType; + +typedef struct _GdlDockItemButtonImage GdlDockItemButtonImage; +typedef struct _GdlDockItemButtonImageClass GdlDockItemButtonImageClass; + +struct _GdlDockItemButtonImage { + GtkWidget parent; + + GdlDockItemButtonImageType image_type; +}; + +struct _GdlDockItemButtonImageClass { + GtkWidgetClass parent_class; +}; + +/* Data Public Functions */ +GType gdl_dock_item_button_image_get_type (void); +GtkWidget *gdl_dock_item_button_image_new ( + GdlDockItemButtonImageType image_type); + +G_END_DECLS + +#endif /* _GDL_DOCK_ITEM_BUTTON_IMAGE_H_ */ diff --git a/src/libgdl/gdl-dock-item-grip.c b/src/libgdl/gdl-dock-item-grip.c index 2513313ef..c5eb6f370 100644 --- a/src/libgdl/gdl-dock-item-grip.c +++ b/src/libgdl/gdl-dock-item-grip.c @@ -1,13 +1,30 @@ /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/** +/* * gdl-dock-item-grip.c * - * Based on bonobo-dock-item-grip. Original copyright notice follows. + * Author: Michael Meeks Copyright (C) 2002 Sun Microsystems, Inc. + * + * Based on BonoboDockItemGrip. Original copyright notice follows. + * + * Copyright (C) 1998 Ettore Perazzoli + * Copyright (C) 1998 Elliot Lee + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * All rights reserved. * - * Author: - * Michael Meeks + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * Copyright (C) 2002 Sun Microsystems, Inc. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H @@ -20,10 +37,12 @@ #include <gtk/gtk.h> #include "gdl-dock-item.h" #include "gdl-dock-item-grip.h" -#include "gdl-stock.h" +#include "gdl-dock-item-button-image.h" +#include "gdl-switcher.h" #include "gdl-tools.h" #define ALIGN_BORDER 5 +#define DRAG_HANDLE_SIZE 10 enum { PROP_0, @@ -31,100 +50,79 @@ enum { }; struct _GdlDockItemGripPrivate { + GtkWidget *label; + GtkWidget *close_button; GtkWidget *iconify_button; - - gboolean icon_pixbuf_valid; - GdkPixbuf *icon_pixbuf; - - gchar *title; - PangoLayout *title_layout; + + gboolean handle_shown; }; GDL_CLASS_BOILERPLATE (GdlDockItemGrip, gdl_dock_item_grip, - GtkContainer, GTK_TYPE_CONTAINER); - -/* must be called after size_allocate */ -static void -gdl_dock_item_grip_get_title_area (GdlDockItemGrip *grip, - GdkRectangle *area) + GtkContainer, GTK_TYPE_CONTAINER); + +GtkWidget* +gdl_dock_item_create_label_widget(GdlDockItemGrip *grip) { - GtkWidget *widget = GTK_WIDGET (grip); - gint border = GTK_CONTAINER (grip)->border_width; - gint alloc_height; - - area->width = (widget->allocation.width - 2 * border - ALIGN_BORDER); - - pango_layout_get_pixel_size (grip->_priv->title_layout, NULL, &alloc_height); - - alloc_height = MAX (grip->_priv->close_button->allocation.height, alloc_height); - alloc_height = MAX (grip->_priv->iconify_button->allocation.height, alloc_height); - if (gtk_widget_get_visible (grip->_priv->close_button)) { - area->width -= grip->_priv->close_button->allocation.width; - } - if (gtk_widget_get_visible (grip->_priv->iconify_button)) { - area->width -= grip->_priv->iconify_button->allocation.width; - } - - area->x = widget->allocation.x + border + ALIGN_BORDER; - area->y = widget->allocation.y + border; - area->height = alloc_height; - - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - area->x += (widget->allocation.width - 2 * border) - area->width; -} - -static void -ensure_title_and_icon_pixbuf (GdlDockItemGrip *grip) -{ - gchar *stock_id; + GtkHBox *label_box; + GtkImage *image; + GtkLabel *label; + gchar *stock_id = NULL; + gchar *title = NULL; GdkPixbuf *pixbuf; + + label_box = (GtkHBox*)gtk_hbox_new (FALSE, 0); - g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (grip)); - - /* get long name property from the dock object */ - if (!grip->_priv->title) { - g_object_get (G_OBJECT (grip->item), "long-name", &grip->_priv->title, NULL); - if (!grip->_priv->title) - grip->_priv->title = g_strdup (""); - } - - /* retrieve stock pixbuf, if any */ - if (!grip->_priv->icon_pixbuf_valid) { - g_object_get (G_OBJECT (grip->item), "stock-id", &stock_id, NULL); + g_object_get (G_OBJECT (grip->item), "stock-id", &stock_id, NULL); + g_object_get (G_OBJECT (grip->item), "pixbuf-icon", &pixbuf, NULL); + if(stock_id) { + image = GTK_IMAGE(gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU)); - if (stock_id) { - grip->_priv->icon_pixbuf = gtk_widget_render_icon (GTK_WIDGET (grip), - stock_id, - GTK_ICON_SIZE_MENU, ""); - g_free (stock_id); - grip->_priv->icon_pixbuf_valid = TRUE; - } + gtk_widget_show (GTK_WIDGET(image)); + gtk_box_pack_start(GTK_BOX(label_box), GTK_WIDGET(image), FALSE, TRUE, 0); + + g_free (stock_id); } - - /* retrieve pixbuf icon, if any */ - if (!grip->_priv->icon_pixbuf_valid) { - g_object_get (G_OBJECT (grip->item), "pixbuf-icon", &pixbuf, NULL); + else if (pixbuf) { + image = GTK_IMAGE(gtk_image_new_from_pixbuf (pixbuf)); + + gtk_widget_show (GTK_WIDGET(image)); + gtk_box_pack_start(GTK_BOX(label_box), GTK_WIDGET(image), FALSE, TRUE, 0); + } + + g_object_get (G_OBJECT (grip->item), "long-name", &title, NULL); + if (title) { + label = GTK_LABEL(gtk_label_new(title)); + gtk_label_set_ellipsize(label, PANGO_ELLIPSIZE_END); + gtk_label_set_justify(label, GTK_JUSTIFY_LEFT); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_widget_show (GTK_WIDGET(label)); - if (pixbuf) { - grip->_priv->icon_pixbuf = pixbuf; - grip->_priv->icon_pixbuf_valid = TRUE; + if (gtk_widget_get_direction (GTK_WIDGET(grip)) == GTK_TEXT_DIR_RTL) { + gtk_box_pack_end(GTK_BOX(label_box), GTK_WIDGET(label), TRUE, TRUE, 1); + } else { + gtk_box_pack_start(GTK_BOX(label_box), GTK_WIDGET(label), TRUE, TRUE, 1); } + + g_free(title); } - - /* create layout: the actual text is reset at size_allocate */ - if (!grip->_priv->title_layout) { - grip->_priv->title_layout = gtk_widget_create_pango_layout (GTK_WIDGET (grip), - grip->_priv->title); - pango_layout_set_single_paragraph_mode (grip->_priv->title_layout, TRUE); - } + + return GTK_WIDGET(label_box); } static gint gdl_dock_item_grip_expose (GtkWidget *widget, - GdkEventExpose *event) + GdkEventExpose *event) { GdlDockItemGrip *grip; +/*<<<<<<< HEAD */ + GdkRectangle handle_area; + GdkRectangle expose_area; + + grip = GDL_DOCK_ITEM_GRIP (widget); + + if(grip->_priv->handle_shown) { +/*======= GdkRectangle title_area; GdkRectangle expose_area; GdkGC *bg_style; @@ -134,11 +132,11 @@ gdl_dock_item_grip_expose (GtkWidget *widget, gint text_y; grip = GDL_DOCK_ITEM_GRIP (widget); - gdl_dock_item_grip_get_title_area (grip, &title_area); + gdl_dock_item_grip_get_title_area (grip, &title_area); */ /* draw background, highlight it if the dock item or any of its * descendants have focus */ - bg_style = (gdl_dock_item_or_child_has_focus (grip->item) ? +/* bg_style = (gdl_dock_item_or_child_has_focus (grip->item) ? gtk_widget_get_style (widget)->dark_gc[widget->state] : gtk_widget_get_style (widget)->mid_gc[widget->state]); @@ -148,51 +146,35 @@ gdl_dock_item_grip_expose (GtkWidget *widget, if (grip->_priv->icon_pixbuf) { GdkRectangle pixbuf_rect; +>>>>>>> gdl-2.26.0-with-inkscape */ - pixbuf_rect.width = gdk_pixbuf_get_width (grip->_priv->icon_pixbuf); - pixbuf_rect.height = gdk_pixbuf_get_height (grip->_priv->icon_pixbuf); - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) { - pixbuf_rect.x = title_area.x + title_area.width - pixbuf_rect.width; + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) { + handle_area.x = widget->allocation.x; + handle_area.y = widget->allocation.y; + handle_area.width = DRAG_HANDLE_SIZE; + handle_area.height = widget->allocation.height; } else { - pixbuf_rect.x = title_area.x; - title_area.x += pixbuf_rect.width + 1; + handle_area.x = widget->allocation.x + widget->allocation.width + - DRAG_HANDLE_SIZE; + handle_area.y = widget->allocation.y; + handle_area.width = DRAG_HANDLE_SIZE; + handle_area.height = widget->allocation.height; } - /* shrink title area by the pixbuf width plus a 1px spacing */ - title_area.width -= pixbuf_rect.width + 1; - pixbuf_rect.y = title_area.y + (title_area.height - pixbuf_rect.height) / 2; - - if (gdk_rectangle_intersect (&event->area, &pixbuf_rect, &expose_area)) { - GdkGC *gc; - GtkStyle *style; - - style = gtk_widget_get_style (widget); - gc = style->bg_gc[widget->state]; - gdk_draw_pixbuf (GDK_DRAWABLE (widget->window), gc, - grip->_priv->icon_pixbuf, - 0, 0, pixbuf_rect.x, pixbuf_rect.y, - pixbuf_rect.width, pixbuf_rect.height, - GDK_RGB_DITHER_NONE, 0, 0); - } - } - - if (gdk_rectangle_intersect (&title_area, &event->area, &expose_area)) { - pango_layout_get_pixel_size (grip->_priv->title_layout, &layout_width, - &layout_height); - - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - text_x = title_area.x + title_area.width - layout_width; - else - text_x = title_area.x; - text_y = title_area.y + (title_area.height - layout_height) / 2; + if (gdk_rectangle_intersect (&handle_area, &event->area, &expose_area)) { - gtk_paint_layout (widget->style, widget->window, widget->state, TRUE, - &expose_area, widget, NULL, text_x, text_y, - grip->_priv->title_layout); + gtk_paint_handle (widget->style, widget->window, widget->state, + GTK_SHADOW_NONE, &expose_area, widget, + "handlebox", handle_area.x, handle_area.y, + handle_area.width, handle_area.height, + GTK_ORIENTATION_VERTICAL); + + } + } return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); -} +} static void gdl_dock_item_grip_item_notify (GObject *master, @@ -205,29 +187,20 @@ gdl_dock_item_grip_item_notify (GObject *master, grip = GDL_DOCK_ITEM_GRIP (data); - if (strcmp (pspec->name, "stock-id") == 0) { - if (grip->_priv->icon_pixbuf) { - g_object_unref (grip->_priv->icon_pixbuf); - grip->_priv->icon_pixbuf = NULL; - } - grip->_priv->icon_pixbuf_valid = FALSE; - ensure_title_and_icon_pixbuf (grip); - - } else if (strcmp (pspec->name, "long-name") == 0) { - g_free (grip->_priv->title); - g_object_unref (grip->_priv->title_layout); - grip->_priv->title_layout = NULL; - grip->_priv->title = NULL; - ensure_title_and_icon_pixbuf (grip); - gtk_widget_queue_draw (GTK_WIDGET (grip)); + if ((strcmp (pspec->name, "stock-id") == 0) || + (strcmp (pspec->name, "long-name") == 0)) { + + gdl_dock_item_grip_set_label (grip, + gdl_dock_item_create_label_widget(grip)); + } else if (strcmp (pspec->name, "behavior") == 0) { - cursor = FALSE; + cursor = FALSE; if (grip->_priv->close_button) { if (GDL_DOCK_ITEM_CANT_CLOSE (grip->item)) { gtk_widget_hide (GTK_WIDGET (grip->_priv->close_button)); } else { gtk_widget_show (GTK_WIDGET (grip->_priv->close_button)); - cursor = TRUE; + cursor = TRUE; } } if (grip->_priv->iconify_button) { @@ -235,10 +208,10 @@ gdl_dock_item_grip_item_notify (GObject *master, gtk_widget_hide (GTK_WIDGET (grip->_priv->iconify_button)); } else { gtk_widget_show (GTK_WIDGET (grip->_priv->iconify_button)); - cursor = TRUE; + cursor = TRUE; } } - if (grip->title_window && !cursor) + if (grip->title_window && !cursor) gdk_window_set_cursor (grip->title_window, NULL); } @@ -248,20 +221,13 @@ static void gdl_dock_item_grip_destroy (GtkObject *object) { GdlDockItemGrip *grip = GDL_DOCK_ITEM_GRIP (object); - + if (grip->_priv) { GdlDockItemGripPrivate *priv = grip->_priv; - if (priv->title_layout) { - g_object_unref (priv->title_layout); - priv->title_layout = NULL; - } - g_free (priv->title); - priv->title = NULL; - - if (priv->icon_pixbuf) { - g_object_unref (priv->icon_pixbuf); - priv->icon_pixbuf = NULL; + if (priv->label) { + gtk_widget_unparent(grip->_priv->label); + priv->label = NULL; } if (grip->item) @@ -273,7 +239,7 @@ gdl_dock_item_grip_destroy (GtkObject *object) grip->_priv = NULL; g_free (priv); } - + GDL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); } @@ -293,15 +259,15 @@ gdl_dock_item_grip_set_property (GObject *object, case PROP_ITEM: grip->item = g_value_get_object (value); if (grip->item) { - g_signal_connect (grip->item, "notify::long_name", + g_signal_connect (grip->item, "notify::long-name", G_CALLBACK (gdl_dock_item_grip_item_notify), grip); - g_signal_connect (grip->item, "notify::stock_id", + g_signal_connect (grip->item, "notify::stock-id", + G_CALLBACK (gdl_dock_item_grip_item_notify), + grip); + g_signal_connect (grip->item, "notify::behavior", G_CALLBACK (gdl_dock_item_grip_item_notify), grip); - g_signal_connect (grip->item, "notify::behavior", - G_CALLBACK (gdl_dock_item_grip_item_notify), - grip); if (!GDL_DOCK_ITEM_CANT_CLOSE (grip->item) && grip->_priv->close_button) gtk_widget_show (grip->_priv->close_button); @@ -329,10 +295,34 @@ static void gdl_dock_item_grip_iconify_clicked (GtkWidget *widget, GdlDockItemGrip *grip) { + GtkWidget *parent; + (void)widget; g_return_if_fail (grip->item != NULL); - gdl_dock_item_iconify_item (grip->item); + parent = gtk_widget_get_parent (GTK_WIDGET (grip->item)); + if (GDL_IS_SWITCHER (parent)) + { + /* Note: We can not use gtk_container_foreach (parent) here because + * during iconificatoin, the internal children changes in parent. + * Instead we keep a list of items to iconify and iconify them + * one by one. + */ + GList *node; + GList *items = + gtk_container_get_children (GTK_CONTAINER (parent)); + for (node = items; node != NULL; node = node->next) + { + GdlDockItem *item = GDL_DOCK_ITEM (node->data); + if (!GDL_DOCK_ITEM_CANT_ICONIFY (item)) + gdl_dock_item_iconify_item (item); + } + g_list_free (items); + } + else + { + gdl_dock_item_iconify_item (grip->item); + } /* Workaround to unhighlight the iconify button. */ GTK_BUTTON (grip->_priv->iconify_button)->in_button = FALSE; @@ -347,10 +337,10 @@ gdl_dock_item_grip_instance_init (GdlDockItemGrip *grip) gtk_widget_set_has_window (GTK_WIDGET (grip), FALSE); grip->_priv = g_new0 (GdlDockItemGripPrivate, 1); - grip->_priv->icon_pixbuf_valid = FALSE; - grip->_priv->icon_pixbuf = NULL; - grip->_priv->title_layout = NULL; - + grip->_priv->label = NULL; + grip->_priv->handle_shown = FALSE; + + /* create the close button */ gtk_widget_push_composite_child (); grip->_priv->close_button = gtk_button_new (); gtk_widget_pop_composite_child (); @@ -360,13 +350,14 @@ gdl_dock_item_grip_instance_init (GdlDockItemGrip *grip) gtk_button_set_relief (GTK_BUTTON (grip->_priv->close_button), GTK_RELIEF_NONE); gtk_widget_show (grip->_priv->close_button); - image = gtk_image_new_from_stock (GDL_STOCK_CLOSE, GTK_ICON_SIZE_MENU); + image = gdl_dock_item_button_image_new(GDL_DOCK_ITEM_BUTTON_IMAGE_CLOSE); gtk_container_add (GTK_CONTAINER (grip->_priv->close_button), image); gtk_widget_show (image); g_signal_connect (G_OBJECT (grip->_priv->close_button), "clicked", G_CALLBACK (gdl_dock_item_grip_close_clicked), grip); + /* create the iconify button */ gtk_widget_push_composite_child (); grip->_priv->iconify_button = gtk_button_new (); gtk_widget_pop_composite_child (); @@ -376,17 +367,18 @@ gdl_dock_item_grip_instance_init (GdlDockItemGrip *grip) gtk_button_set_relief (GTK_BUTTON (grip->_priv->iconify_button), GTK_RELIEF_NONE); gtk_widget_show (grip->_priv->iconify_button); - image = gtk_image_new_from_stock (GDL_STOCK_MENU_RIGHT, GTK_ICON_SIZE_MENU); + image = gdl_dock_item_button_image_new(GDL_DOCK_ITEM_BUTTON_IMAGE_ICONIFY); gtk_container_add (GTK_CONTAINER (grip->_priv->iconify_button), image); gtk_widget_show (image); g_signal_connect (G_OBJECT (grip->_priv->iconify_button), "clicked", G_CALLBACK (gdl_dock_item_grip_iconify_clicked), grip); + /* set tooltips on the buttons */ gtk_widget_set_tooltip_text (grip->_priv->iconify_button, - _("Iconify")); + _("Iconify this dock")); gtk_widget_set_tooltip_text (grip->_priv->close_button, - _("Close")); + _("Close this dock")); } static void @@ -396,43 +388,45 @@ gdl_dock_item_grip_realize (GtkWidget *widget) GTK_WIDGET_CLASS (parent_class)->realize (widget); + g_return_if_fail (grip->_priv != NULL); + if (!grip->title_window) { GdkWindowAttr attributes; - GdkRectangle area; GdkCursor *cursor; - ensure_title_and_icon_pixbuf (grip); - gdl_dock_item_grip_get_title_area (grip, &area); - - attributes.x = area.x; - attributes.y = area.y; - attributes.width = area.width; - attributes.height = area.height; - attributes.window_type = GDK_WINDOW_TEMP; - attributes.wclass = GDK_INPUT_ONLY; - attributes.override_redirect = TRUE; - attributes.event_mask = (GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_BUTTON_MOTION_MASK | - gtk_widget_get_events (widget)); + g_return_if_fail (grip->_priv->label != NULL); + + attributes.x = grip->_priv->label->allocation.x; + attributes.y = grip->_priv->label->allocation.y; + attributes.width = grip->_priv->label->allocation.width; + attributes.height = grip->_priv->label->allocation.height; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.event_mask = GDK_ALL_EVENTS_MASK; grip->title_window = gdk_window_new (gtk_widget_get_parent_window (widget), - &attributes, - (GDK_WA_X | - GDK_WA_Y | - GDK_WA_NOREDIR)); + &attributes, (GDK_WA_X | GDK_WA_Y)); + + gdk_window_set_user_data (grip->title_window, grip); + + /* Unref the ref from parent realize for NO_WINDOW */ + g_object_unref (widget->window); + + /* Need to ref widget->window, because parent unrealize unrefs it */ + widget->window = g_object_ref (grip->title_window); + GTK_WIDGET_UNSET_FLAGS(widget, GTK_NO_WINDOW); - gdk_window_set_user_data (grip->title_window, widget); + /* Unset the background so as to make the colour match the parent window */ + gtk_widget_modify_bg(widget, GTK_STATE_NORMAL, NULL); - if (GDL_DOCK_ITEM_CANT_CLOSE (grip->item)) - cursor = NULL; - else if (GDL_DOCK_ITEM_CANT_ICONIFY (grip->item)) - cursor = NULL; - else - cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), + if (GDL_DOCK_ITEM_CANT_CLOSE (grip->item) && + GDL_DOCK_ITEM_CANT_ICONIFY (grip->item)) + cursor = NULL; + else + cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), GDK_HAND2); gdk_window_set_cursor (grip->title_window, cursor); - if (cursor) + if (cursor) gdk_cursor_unref (cursor); } } @@ -443,6 +437,7 @@ gdl_dock_item_grip_unrealize (GtkWidget *widget) GdlDockItemGrip *grip = GDL_DOCK_ITEM_GRIP (widget); if (grip->title_window) { + GTK_WIDGET_SET_FLAGS(widget, GTK_NO_WINDOW); gdk_window_set_user_data (grip->title_window, NULL); gdk_window_destroy (grip->title_window); grip->title_window = NULL; @@ -480,7 +475,7 @@ gdl_dock_item_grip_size_request (GtkWidget *widget, GtkRequisition child_requisition; GtkContainer *container; GdlDockItemGrip *grip; - gint layout_height; + gint layout_height = 0; g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (widget)); g_return_if_fail (requisition != NULL); @@ -488,69 +483,29 @@ gdl_dock_item_grip_size_request (GtkWidget *widget, container = GTK_CONTAINER (widget); grip = GDL_DOCK_ITEM_GRIP (widget); - requisition->width = container->border_width * 2 + ALIGN_BORDER; + requisition->width = container->border_width * 2/* + ALIGN_BORDER*/; requisition->height = container->border_width * 2; - ensure_title_and_icon_pixbuf (grip); - pango_layout_get_pixel_size (grip->_priv->title_layout, NULL, &layout_height); + if(grip->_priv->handle_shown) + requisition->width += DRAG_HANDLE_SIZE; gtk_widget_size_request (grip->_priv->close_button, &child_requisition); - - requisition->width += child_requisition.width; layout_height = MAX (layout_height, child_requisition.height); + if (GTK_WIDGET_VISIBLE (grip->_priv->close_button)) { + requisition->width += child_requisition.width; + } gtk_widget_size_request (grip->_priv->iconify_button, &child_requisition); - + layout_height = MAX (layout_height, child_requisition.height); + if (GTK_WIDGET_VISIBLE (grip->_priv->iconify_button)) { + requisition->width += child_requisition.width; + } + + gtk_widget_size_request (grip->_priv->label, &child_requisition); requisition->width += child_requisition.width; layout_height = MAX (layout_height, child_requisition.height); requisition->height += layout_height; - - if (grip->_priv->icon_pixbuf) { - requisition->width += gdk_pixbuf_get_width (grip->_priv->icon_pixbuf) + 1; - } -} - -#define ELLIPSIS "..." - -static void -ellipsize_layout (PangoLayout *layout, gint width) -{ - PangoLayoutLine *line; - PangoLayout *ell; - gint h, w, ell_w, x; - GString *text; - - if (width <= 0) { - pango_layout_set_text (layout, "", -1); - return; - } - - pango_layout_get_pixel_size (layout, &w, &h); - if (w <= width) return; - - /* calculate ellipsis width */ - ell = pango_layout_copy (layout); - pango_layout_set_text (ell, ELLIPSIS, -1); - pango_layout_get_pixel_size (ell, &ell_w, NULL); - g_object_unref (ell); - - if (width < ell_w) { - /* not even ellipsis fits, so hide the text */ - pango_layout_set_text (layout, "", -1); - return; - } - - /* shrink total available width by the width of the ellipsis */ - width -= ell_w; - line = pango_layout_get_line (layout, 0); - text = g_string_new (pango_layout_get_text (layout)); - if (pango_layout_line_x_to_index (line, width * PANGO_SCALE, &x, NULL)) { - g_string_set_size (text, x); - g_string_append (text, ELLIPSIS); - pango_layout_set_text (layout, text->str, -1); - } - g_string_free (text, TRUE); } static void @@ -559,9 +514,10 @@ gdl_dock_item_grip_size_allocate (GtkWidget *widget, { GdlDockItemGrip *grip; GtkContainer *container; - GtkRequisition button_requisition; + GtkRequisition close_requisition = { 0, }; + GtkRequisition iconify_requisition = { 0, }; GtkAllocation child_allocation; - memset(&button_requisition, 0, sizeof(button_requisition)); + GdkRectangle label_area; g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (widget)); g_return_if_fail (allocation != NULL); @@ -571,57 +527,96 @@ gdl_dock_item_grip_size_allocate (GtkWidget *widget, GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation); + gtk_widget_size_request (grip->_priv->close_button, + &close_requisition); + gtk_widget_size_request (grip->_priv->iconify_button, + &iconify_requisition); + + /* Calculate the Minimum Width where buttons will fit */ + int min_width = close_requisition.width + iconify_requisition.width + + container->border_width * 2; + if(grip->_priv->handle_shown) + min_width += DRAG_HANDLE_SIZE; + const gboolean space_for_buttons = (allocation->width >= min_width); + + /* Set up the rolling child_allocation rectangle */ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - child_allocation.x = allocation->x + container->border_width + ALIGN_BORDER; + child_allocation.x = container->border_width/* + ALIGN_BORDER*/; else - child_allocation.x = allocation->x + allocation->width - container->border_width; - child_allocation.y = allocation->y + container->border_width; - - gtk_widget_size_request (grip->_priv->close_button, &button_requisition); - - if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) - child_allocation.x -= button_requisition.width; + child_allocation.x = allocation->width - container->border_width; + child_allocation.y = container->border_width; - child_allocation.width = button_requisition.width; - child_allocation.height = button_requisition.height; + /* Layout Close Button */ + if (GTK_WIDGET_VISIBLE (grip->_priv->close_button)) { - gtk_widget_size_allocate (grip->_priv->close_button, &child_allocation); - - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - child_allocation.x += button_requisition.width; - + if(space_for_buttons) { + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) + child_allocation.x -= close_requisition.width; + + child_allocation.width = close_requisition.width; + child_allocation.height = close_requisition.height; + } else { + child_allocation.width = 0; + } + + gtk_widget_size_allocate (grip->_priv->close_button, &child_allocation); - gtk_widget_size_request (grip->_priv->iconify_button, &button_requisition); + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + child_allocation.x += close_requisition.width; + } - if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) - child_allocation.x -= button_requisition.width; + /* Layout Iconify Button */ + if (GTK_WIDGET_VISIBLE (grip->_priv->iconify_button)) { - child_allocation.width = button_requisition.width; - child_allocation.height = button_requisition.height; + if(space_for_buttons) { + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) + child_allocation.x -= iconify_requisition.width; - gtk_widget_size_allocate (grip->_priv->iconify_button, &child_allocation); + child_allocation.width = iconify_requisition.width; + child_allocation.height = iconify_requisition.height; + } else { + child_allocation.width = 0; + } - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - child_allocation.x += button_requisition.width; + gtk_widget_size_allocate (grip->_priv->iconify_button, &child_allocation); + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + child_allocation.x += iconify_requisition.width; + } - if (grip->title_window) { - GdkRectangle area; + /* Layout the Grip Handle*/ + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL) { + child_allocation.width = child_allocation.x; + child_allocation.x = container->border_width/* + ALIGN_BORDER*/; - /* set layout text */ - ensure_title_and_icon_pixbuf (grip); - pango_layout_set_text (grip->_priv->title_layout, grip->_priv->title, -1); - - gdl_dock_item_grip_get_title_area (grip, &area); - - gdk_window_move_resize (grip->title_window, - area.x, area.y, area.width, area.height); - - if (grip->_priv->icon_pixbuf) - area.width -= gdk_pixbuf_get_width (grip->_priv->icon_pixbuf) + 1; + if(grip->_priv->handle_shown) { + child_allocation.x += DRAG_HANDLE_SIZE; + child_allocation.width -= DRAG_HANDLE_SIZE; + } + + } else { + child_allocation.width = allocation->width - + (child_allocation.x - allocation->x)/* - ALIGN_BORDER*/; - /* ellipsize title if it doesn't fit the title area */ - ellipsize_layout (grip->_priv->title_layout, area.width); + if(grip->_priv->handle_shown) + child_allocation.width -= DRAG_HANDLE_SIZE; + } + + if(child_allocation.width < 0) + child_allocation.width = 0; + + child_allocation.y = container->border_width; + child_allocation.height = allocation->height - container->border_width * 2; + if(grip->_priv->label) { + gtk_widget_size_allocate (grip->_priv->label, &child_allocation); + } + + if (grip->title_window) { + gdk_window_move_resize (grip->title_window, + allocation->x, + allocation->y, + allocation->width, + allocation->height); } } @@ -638,9 +633,8 @@ static void gdl_dock_item_grip_remove (GtkContainer *container, GtkWidget *widget) { - (void)container; (void)widget; - g_warning ("gtk_container_remove not implemented for GdlDockItemGrip"); + gdl_dock_item_grip_set_label (GDL_DOCK_ITEM_GRIP (container), NULL); } static void @@ -652,12 +646,17 @@ gdl_dock_item_grip_forall (GtkContainer *container, GdlDockItemGrip *grip; g_return_if_fail (GDL_IS_DOCK_ITEM_GRIP (container)); - grip = GDL_DOCK_ITEM_GRIP (container); + + if (grip->_priv) { + if(grip->_priv->label) { + (* callback) (grip->_priv->label, callback_data); + } - if (include_internals) { - (* callback) (grip->_priv->close_button, callback_data); - (* callback) (grip->_priv->iconify_button, callback_data); + if (include_internals) { + (* callback) (grip->_priv->close_button, callback_data); + (* callback) (grip->_priv->iconify_button, callback_data); + } } } @@ -705,11 +704,23 @@ gdl_dock_item_grip_class_init (GdlDockItemGripClass *klass) _("Dockitem which 'owns' this grip"), GDL_TYPE_DOCK_ITEM, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); +} - /* initialize stock images */ - gdl_stock_init (); +static void +gdl_dock_item_grip_showhide_handle (GdlDockItemGrip *grip) +{ + gtk_widget_queue_resize (GTK_WIDGET (grip)); } +/* ----- Public interface ----- */ + +/** + * gdl_dock_item_grip_new: + * @item: The dock item that will "own" this grip widget. + * + * Creates a new GDL dock item grip object. + * Returns: The newly created dock item grip widget. + **/ GtkWidget * gdl_dock_item_grip_new (GdlDockItem *item) { @@ -718,3 +729,61 @@ gdl_dock_item_grip_new (GdlDockItem *item) return GTK_WIDGET (grip); } + +/** + * gdl_dock_item_grip_set_label: + * @grip: The grip that will get it's label widget set. + * @label: The widget that will become the label. + * + * Replaces the current label widget with another widget. + **/ +void +gdl_dock_item_grip_set_label (GdlDockItemGrip *grip, + GtkWidget *label) +{ + g_return_if_fail (grip != NULL); + + if (grip->_priv->label) { + gtk_widget_unparent(grip->_priv->label); + g_object_unref (grip->_priv->label); + grip->_priv->label = NULL; + } + + if (label) { + g_object_ref (label); + gtk_widget_set_parent (label, GTK_WIDGET (grip)); + gtk_widget_show (label); + grip->_priv->label = label; + } +} +/** + * gdl_dock_item_grip_hide_handle: + * @item: The dock item grip to hide the handle of. + * + * This function hides the dock item's grip widget handle hatching. + **/ +void +gdl_dock_item_grip_hide_handle (GdlDockItemGrip *grip) +{ + g_return_if_fail (grip != NULL); + if (grip->_priv->handle_shown) { + grip->_priv->handle_shown = FALSE; + gdl_dock_item_grip_showhide_handle (grip); + }; +} + +/** + * gdl_dock_item_grip_show_handle: + * @grip: The dock item grip to show the handle of. + * + * This function shows the dock item's grip widget handle hatching. + **/ +void +gdl_dock_item_grip_show_handle (GdlDockItemGrip *grip) +{ + g_return_if_fail (grip != NULL); + if (!grip->_priv->handle_shown) { + grip->_priv->handle_shown = TRUE; + gdl_dock_item_grip_showhide_handle (grip); + }; +} diff --git a/src/libgdl/gdl-dock-item-grip.h b/src/libgdl/gdl-dock-item-grip.h index 4dfdd7ab3..a44ef91fb 100644 --- a/src/libgdl/gdl-dock-item-grip.h +++ b/src/libgdl/gdl-dock-item-grip.h @@ -1,13 +1,30 @@ /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */ -/** +/* * gdl-dock-item-grip.h - * - * Based on bonobo-dock-item-grip. Original copyright notice follows. * - * Author: - * Michael Meeks + * Author: Michael Meeks Copyright (C) 2002 Sun Microsystems, Inc. * - * Copyright (C) 2002 Sun Microsystems, Inc. + * Based on BonoboDockItemGrip. Original copyright notice follows. + * + * Copyright (C) 1998 Ettore Perazzoli + * Copyright (C) 1998 Elliot Lee + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. */ #ifndef _GDL_DOCK_ITEM_GRIP_H_ @@ -50,6 +67,10 @@ struct _GdlDockItemGripClass { GType gdl_dock_item_grip_get_type (void); GtkWidget *gdl_dock_item_grip_new (GdlDockItem *item); +void gdl_dock_item_grip_set_label (GdlDockItemGrip *grip, + GtkWidget *label); +void gdl_dock_item_grip_hide_handle (GdlDockItemGrip *grip); +void gdl_dock_item_grip_show_handle (GdlDockItemGrip *grip); G_END_DECLS diff --git a/src/libgdl/gdl-dock-item.c b/src/libgdl/gdl-dock-item.c index c01737636..0c0d765df 100644 --- a/src/libgdl/gdl-dock-item.c +++ b/src/libgdl/gdl-dock-item.c @@ -163,6 +163,7 @@ enum { DOCK_DRAG_BEGIN, DOCK_DRAG_MOTION, DOCK_DRAG_END, + SELECTED, MOVE_FOCUS_CHILD, LAST_SIGNAL }; @@ -281,6 +282,16 @@ gdl_dock_item_class_init (GdlDockItemClass *klass) /* properties */ + /** + * GdlDockItem:orientation: + * + * The orientation of the docking item. If the orientation is set to + * #GTK_ORIENTATION_VERTICAL, the grip widget will be shown along + * the top of the edge of item (if it is not hidden). If the + * orientation is set to #GTK_ORIENTATION_HORIZONTAL, the grip + * widget will be shown down the left edge of the item (even if the + * widget text direction is set to RTL). + */ g_object_class_install_property ( g_object_class, PROP_ORIENTATION, g_param_spec_enum ("orientation", _("Orientation"), @@ -301,7 +312,7 @@ gdl_dock_item_class_init (GdlDockItemClass *klass) g_object_class, PROP_RESIZE, g_param_spec_boolean ("resize", _("Resizable"), _("If set, the dock item can be resized when " - "docked in a panel"), + "docked in a GtkPanel widget"), TRUE, G_PARAM_READWRITE)); @@ -339,6 +350,12 @@ gdl_dock_item_class_init (GdlDockItemClass *klass) /* signals */ + /** + * GdlDockItem::dock-drag-begin: + * @item: The dock item which is being dragged. + * + * Signals that the dock item has begun to be dragged. + **/ gdl_dock_item_signals [DOCK_DRAG_BEGIN] = g_signal_new ("dock-drag-begin", G_TYPE_FROM_CLASS (klass), @@ -349,7 +366,15 @@ gdl_dock_item_class_init (GdlDockItemClass *klass) gdl_marshal_VOID__VOID, G_TYPE_NONE, 0); - + + /** + * GdlDockItem::dock-drag-motion: + * @item: The dock item which is being dragged. + * @x: The x-position that the dock item has been dragged to. + * @y: The y-position that the dock item has been dragged to. + * + * Signals that a dock item dragging motion event has occured. + **/ gdl_dock_item_signals [DOCK_DRAG_MOTION] = g_signal_new ("dock-drag-motion", G_TYPE_FROM_CLASS (klass), @@ -363,6 +388,14 @@ gdl_dock_item_class_init (GdlDockItemClass *klass) G_TYPE_INT, G_TYPE_INT); + /** + * GdlDockItem::dock-drag-end: + * @item: The dock item which is no longer being dragged. + * @cancel: This value is set to TRUE if the drag was cancelled by + * the user. #cancel is set to FALSE if the drag was accepted. + * + * Signals that the dock item dragging has ended. + **/ gdl_dock_item_signals [DOCK_DRAG_END] = g_signal_new ("dock_drag_end", G_TYPE_FROM_CLASS (klass), @@ -375,6 +408,22 @@ gdl_dock_item_class_init (GdlDockItemClass *klass) 1, G_TYPE_BOOLEAN); + /** + * GdlDockItem::selected: + * + * Signals that this dock has been selected from a switcher. + */ + gdl_dock_item_signals [SELECTED] = + g_signal_new ("selected", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + gdl_dock_item_signals [MOVE_FOCUS_CHILD] = g_signal_new ("move_focus_child", G_TYPE_FROM_CLASS (klass), @@ -1257,8 +1306,9 @@ gdl_dock_item_dock (GdlDockObject *object, GdlDockPlacement position, GValue *other_data) { - GdlDockObject *new_parent, *parent; - gboolean add_ourselves_first; + GdlDockObject *new_parent = NULL; + GdlDockObject *parent, *requestor_parent; + gboolean add_ourselves_first = FALSE; guint available_space=0; gint pref_size=-1; @@ -1372,11 +1422,16 @@ gdl_dock_item_dock (GdlDockObject *object, pref_size = req.width; break; case GDL_DOCK_CENTER: - new_parent = g_object_new (gdl_dock_object_type_from_nick ("notebook"), - "preferred-width", object_req.width, - "preferred-height", object_req.height, - NULL); - add_ourselves_first = TRUE; + /* If the parent is already a DockNotebook, we don't need + to create a new one. */ + if (!GDL_IS_DOCK_NOTEBOOK (parent)) + { + new_parent = g_object_new (gdl_dock_object_type_from_nick ("notebook"), + "preferred-width", object_req.width, + "preferred-height", object_req.height, + NULL); + add_ourselves_first = TRUE; + } break; default: { @@ -1395,52 +1450,73 @@ gdl_dock_item_dock (GdlDockObject *object, if (parent) gdl_dock_object_freeze (parent); - /* ref ourselves since we could be destroyed when detached */ - g_object_ref (object); - GDL_DOCK_OBJECT_SET_FLAGS (object, GDL_DOCK_IN_REFLOW); - gdl_dock_object_detach (object, FALSE); - - /* freeze the new parent, so reduce won't get called before it's - actually added to our parent */ - gdl_dock_object_freeze (new_parent); - /* bind the new parent to our master, so the following adds work */ - gdl_dock_object_bind (new_parent, G_OBJECT (GDL_DOCK_OBJECT_GET_MASTER (object))); + if (new_parent) + { + /* ref ourselves since we could be destroyed when detached */ + g_object_ref (object); + GDL_DOCK_OBJECT_SET_FLAGS (object, GDL_DOCK_IN_REFLOW); + gdl_dock_object_detach (object, FALSE); + + /* freeze the new parent, so reduce won't get called before it's + actually added to our parent */ + gdl_dock_object_freeze (new_parent); + + /* bind the new parent to our master, so the following adds work */ + gdl_dock_object_bind (new_parent, G_OBJECT (GDL_DOCK_OBJECT_GET_MASTER (object))); - /* add the objects */ - if (add_ourselves_first) { - gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (object)); - gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (requestor)); - splitpos = available_space - pref_size; - } else { - gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (requestor)); - gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (object)); - splitpos = pref_size; - } + /* add the objects */ + if (add_ourselves_first) { + gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (object)); + gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (requestor)); + splitpos = available_space - pref_size; + } else { + gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (requestor)); + gtk_container_add (GTK_CONTAINER (new_parent), GTK_WIDGET (object)); + splitpos = pref_size; + } - /* add the new parent to the parent */ - if (parent) - gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (new_parent)); + /* add the new parent to the parent */ + if (parent) + gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (new_parent)); - /* show automatic object */ - if (gtk_widget_get_visible (GTK_WIDGET (object))) - gtk_widget_show (GTK_WIDGET (new_parent)); - - /* use extra docking parameter */ - if (position != GDL_DOCK_CENTER && other_data && - G_VALUE_HOLDS (other_data, G_TYPE_UINT)) { + /* show automatic object */ + if (gtk_widget_get_visible (GTK_WIDGET (object))) + { + gtk_widget_show (GTK_WIDGET (new_parent)); + GDL_DOCK_OBJECT_UNSET_FLAGS (object, GDL_DOCK_IN_REFLOW); + } + gdl_dock_object_thaw (new_parent); + + /* use extra docking parameter */ + if (position != GDL_DOCK_CENTER && other_data && + G_VALUE_HOLDS (other_data, G_TYPE_UINT)) { - g_object_set (G_OBJECT (new_parent), - "position", g_value_get_uint (other_data), - NULL); - } else if (splitpos > 0 && splitpos < available_space) { - g_object_set (G_OBJECT (new_parent), "position", splitpos, NULL); + g_object_set (G_OBJECT (new_parent), + "position", g_value_get_uint (other_data), + NULL); + } else if (splitpos > 0 && splitpos < available_space) { + g_object_set (G_OBJECT (new_parent), "position", splitpos, NULL); + } + + g_object_unref (object); + } + else + { + /* If the parent is already a DockNotebook, we don't need + to create a new one. */ + gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (requestor)); } - GDL_DOCK_OBJECT_UNSET_FLAGS (object, GDL_DOCK_IN_REFLOW); - g_object_unref (object); - - gdl_dock_object_thaw (new_parent); + requestor_parent = gdl_dock_object_get_parent_object (requestor); + if (GDL_IS_DOCK_NOTEBOOK (requestor_parent)) + { + /* Activate the page we just added */ + GdlDockItem* notebook = GDL_DOCK_ITEM (gdl_dock_object_get_parent_object (requestor)); + gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook->child), + gtk_notebook_page_num (GTK_NOTEBOOK (notebook->child), GTK_WIDGET (requestor))); + } + if (parent) gdl_dock_object_thaw (parent); @@ -1642,6 +1718,17 @@ gdl_dock_item_real_set_orientation (GdlDockItem *item, /* ----- Public interface ----- */ +/** + * gdl_dock_item_new: + * @name: Unique name for identifying the dock object. + * @long_name: Human readable name for the dock object. + * @behavior: General behavior for the dock item (i.e. whether it can + * float, if it's locked, etc.), as specified by + * #GdlDockItemBehavior flags. + * + * Creates a new dock item widget. + * Returns: The newly created dock item grip widget. + **/ GtkWidget * gdl_dock_item_new (const gchar *name, const gchar *long_name, @@ -1659,6 +1746,18 @@ gdl_dock_item_new (const gchar *name, return GTK_WIDGET (item); } +/** + * gdl_dock_item_new_with_stock: + * @name: Unique name for identifying the dock object. + * @long_name: Human readable name for the dock object. + * @stock_id: Stock icon for the dock object. + * @behavior: General behavior for the dock item (i.e. whether it can + * float, if it's locked, etc.), as specified by + * #GdlDockItemBehavior flags. + * + * Creates a new dock item grip widget with a given stock id. + * Returns: The newly created dock item grip widget. + **/ GtkWidget * gdl_dock_item_new_with_stock (const gchar *name, const gchar *long_name, @@ -1701,6 +1800,15 @@ gdl_dock_item_new_with_pixbuf_icon (const gchar *name, } /* convenient function (and to preserve source compat) */ +/** + * gdl_dock_item_dock_to: + * @item: The dock item that will be relocated to the dock position. + * @target: The dock item that will be used as the point of reference. + * @position: The position to dock #item, relative to #target. + * @docking_param: This value is unused, and will be ignored. + * + * Relocates a dock item to a new location relative to another dock item. + **/ void gdl_dock_item_dock_to (GdlDockItem *item, GdlDockItem *target, @@ -1738,6 +1846,18 @@ gdl_dock_item_dock_to (GdlDockItem *item, position, NULL); } +/** + * gdl_dock_item_set_orientation: + * @item: The dock item which will get it's orientation set. + * @orientation: The orientation to set the item to. If the orientation + * is set to #GTK_ORIENTATION_VERTICAL, the grip widget will be shown + * along the top of the edge of item (if it is not hidden). If the + * orientation is set to #GTK_ORIENTATION_HORIZONTAL, the grip widget + * will be shown down the left edge of the item (even if the widget + * text direction is set to RTL). + * + * This function sets the layout of the dock item. + **/ void gdl_dock_item_set_orientation (GdlDockItem *item, GtkOrientation orientation) @@ -1762,6 +1882,16 @@ gdl_dock_item_set_orientation (GdlDockItem *item, } } +/** + * gdl_dock_item_get_tablabel: + * @item: The dock item from which to get the tab label widget. + * + * Gets the current tab label widget. Note that this label widget is + * only visible when the "switcher-style" property of the #GdlDockMaster + * is set to #GDL_SWITCHER_STYLE_TABS + * + * Returns: Returns the tab label widget. + **/ GtkWidget * gdl_dock_item_get_tablabel (GdlDockItem *item) { @@ -1771,6 +1901,15 @@ gdl_dock_item_get_tablabel (GdlDockItem *item) return item->_priv->tab_label; } +/** + * gdl_dock_item_set_tablabel: + * @item: The dock item which will get it's tab label widget set. + * @tablabel: The widget that will become the tab label. + * + * Replaces the current tab label widget with another widget. Note that + * this label widget is only visible when the "switcher-style" property + * of the #GdlDockMaster is set to #GDL_SWITCHER_STYLE_TABS + **/ void gdl_dock_item_set_tablabel (GdlDockItem *item, GtkWidget *tablabel) @@ -1802,6 +1941,29 @@ gdl_dock_item_set_tablabel (GdlDockItem *item, } } +/** + * gdl_dock_item_get_grip: + * @item: The dock item from which to to get the grip of. + * + * This function returns the dock item's grip label widget. + * + * Returns: Returns the current label widget. + **/ +GtkWidget * +gdl_dock_item_get_grip(GdlDockItem *item) +{ + g_return_if_fail (item != NULL); + g_return_val_if_fail (GDL_IS_DOCK_ITEM (item), NULL); + + return item->_priv->grip; +} + +/** + * gdl_dock_item_hide_grip: + * @item: The dock item to hide the grip of. + * + * This function hides the dock item's grip widget. + **/ void gdl_dock_item_hide_grip (GdlDockItem *item) { @@ -1813,6 +1975,12 @@ gdl_dock_item_hide_grip (GdlDockItem *item) g_warning ("Grips always show unless GDL_DOCK_ITEM_BEH_NO_GRIP is set\n" ); } +/** + * gdl_dock_item_show_grip: + * @item: The dock item to show the grip of. + * + * This function shows the dock item's grip widget. + **/ void gdl_dock_item_show_grip (GdlDockItem *item) { @@ -1823,7 +1991,28 @@ gdl_dock_item_show_grip (GdlDockItem *item) }; } +/** + * gdl_dock_item_notify_selected: + * @item: the dock item to emit a selected signal on. + * + * This function emits the selected signal. It is to be used by #GdlSwitcher + * to let clients know that this item has been switched to. + **/ +void +gdl_dock_item_notify_selected (GdlDockItem *item) +{ + g_signal_emit (item, gdl_dock_item_signals [SELECTED], 0); +} + /* convenient function (and to preserve source compat) */ +/** + * gdl_dock_item_bind: + * @item: The item to bind. + * @dock: The #GdlDock widget to bind it to. Note that this widget must + * be a type of #GdlDock. + * + * Binds this dock item to a new dock master. + **/ void gdl_dock_item_bind (GdlDockItem *item, GtkWidget *dock) @@ -1836,6 +2025,12 @@ gdl_dock_item_bind (GdlDockItem *item, } /* convenient function (and to preserve source compat) */ +/** + * gdl_dock_item_unbind: + * @item: The item to unbind. + * + * Unbinds this dock item from it's dock master. + **/ void gdl_dock_item_unbind (GdlDockItem *item) { @@ -1844,6 +2039,15 @@ gdl_dock_item_unbind (GdlDockItem *item) gdl_dock_object_unbind (GDL_DOCK_OBJECT (item)); } +/** + * gdl_dock_item_hide_item: + * @item: The dock item to hide. + * + * This function hides the dock item. When dock items are hidden they + * are completely removed from the layout. + * + * The dock item close button causes the panel to be hidden. + **/ void gdl_dock_item_hide_item (GdlDockItem *item) { @@ -1905,6 +2109,15 @@ gdl_dock_item_hide_item (GdlDockItem *item) gdl_dock_object_thaw (GDL_DOCK_OBJECT (item)); } +/** + * gdl_dock_item_iconify_item: + * @item: The dock item to iconify. + * + * This function iconifies the dock item. When dock items are iconified + * they are hidden, and appear only as icons in dock bars. + * + * The dock item iconify button causes the panel to be iconified. + **/ void gdl_dock_item_iconify_item (GdlDockItem *item) { @@ -1914,6 +2127,13 @@ gdl_dock_item_iconify_item (GdlDockItem *item) gdl_dock_item_hide_item (item); } +/** + * gdl_dock_item_show_item: + * @item: The dock item to show. + * + * This function shows the dock item. When dock items are shown, they + * are displayed in their normal layout position. + **/ void gdl_dock_item_show_item (GdlDockItem *item) { @@ -1965,18 +2185,41 @@ gdl_dock_item_show_item (GdlDockItem *item) gtk_widget_show (GTK_WIDGET (item)); } +/** + * gdl_dock_item_lock: + * @item: The dock item to lock. + * + * This function locks the dock item. When locked the dock item cannot + * be dragged around and it doesn't show a grip. + **/ void gdl_dock_item_lock (GdlDockItem *item) { g_object_set (item, "locked", TRUE, NULL); } +/** + * gdl_dock_item_unlock: + * @item: The dock item to unlock. + * + * This function unlocks the dock item. When unlocked the dock item can + * be dragged around and can show a grip. + **/ void gdl_dock_item_unlock (GdlDockItem *item) { g_object_set (item, "locked", FALSE, NULL); } +/** + * gdl_dock_item_set_default_position: + * @item: The dock item + * @reference: The GdlDockObject which is the default dock for @item + * + * This method has only an effect when you add you dock_item with + * GDL_DOCK_ITEM_BEH_NEVER_FLOATING. In this case you have to assign + * it a default position. + **/ void gdl_dock_item_set_default_position (GdlDockItem *item, GdlDockObject *reference) @@ -2003,6 +2246,14 @@ gdl_dock_item_set_default_position (GdlDockItem *item, } } +/** + * gdl_dock_item_preferred_size: + * @item: The dock item to get the preferred size of. + * @req: A pointer to a #GtkRequisition into which the preferred size + * will be written. + * + * Gets the preferred size of the dock item in pixels. + **/ void gdl_dock_item_preferred_size (GdlDockItem *item, GtkRequisition *req) diff --git a/src/libgdl/gdl-dock-item.h b/src/libgdl/gdl-dock-item.h index 6c0029d13..d97fdf6fd 100644 --- a/src/libgdl/gdl-dock-item.h +++ b/src/libgdl/gdl-dock-item.h @@ -93,17 +93,16 @@ struct _GdlDockItemClass { gboolean has_grip; /* virtuals */ - void (* dock_drag_begin) (GdlDockItem *item); - void (* dock_drag_motion) (GdlDockItem *item, - gint x, - gint y); - void (* dock_drag_end) (GdlDockItem *item, - gboolean cancelled); + void (* dock_drag_begin) (GdlDockItem *item); + void (* dock_drag_motion) (GdlDockItem *item, + gint x, + gint y); + void (* dock_drag_end) (GdlDockItem *item, + gboolean cancelled); void (* move_focus_child) (GdlDockItem *item, GtkDirectionType direction); - - void (* set_orientation) (GdlDockItem *item, - GtkOrientation orientation); + void (* set_orientation) (GdlDockItem *item, + GtkOrientation orientation); }; /* additional macros */ @@ -163,8 +162,10 @@ void gdl_dock_item_set_orientation (GdlDockItem *item, GtkWidget *gdl_dock_item_get_tablabel (GdlDockItem *item); void gdl_dock_item_set_tablabel (GdlDockItem *item, GtkWidget *tablabel); +GtkWidget *gdl_dock_item_get_grip (GdlDockItem *item); void gdl_dock_item_hide_grip (GdlDockItem *item); void gdl_dock_item_show_grip (GdlDockItem *item); +void gdl_dock_item_notify_selected (GdlDockItem *item); /* bind and unbind items to a dock */ void gdl_dock_item_bind (GdlDockItem *item, diff --git a/src/libgdl/gdl-dock-master.c b/src/libgdl/gdl-dock-master.c index 78cbf69ec..57d0618ec 100644 --- a/src/libgdl/gdl-dock-master.c +++ b/src/libgdl/gdl-dock-master.c @@ -31,6 +31,8 @@ #include "gdl-dock-master.h" #include "gdl-dock.h" #include "gdl-dock-item.h" +#include "gdl-dock-notebook.h" +#include "gdl-switcher.h" #include "libgdlmarshal.h" #include "libgdltypebuiltins.h" #ifdef WIN32 diff --git a/src/libgdl/gdl-dock-master.h b/src/libgdl/gdl-dock-master.h index 3268e68b5..266ca7ee4 100644 --- a/src/libgdl/gdl-dock-master.h +++ b/src/libgdl/gdl-dock-master.h @@ -44,6 +44,15 @@ typedef struct _GdlDockMaster GdlDockMaster; typedef struct _GdlDockMasterClass GdlDockMasterClass; typedef struct _GdlDockMasterPrivate GdlDockMasterPrivate; +typedef enum { + GDL_SWITCHER_STYLE_TEXT, + GDL_SWITCHER_STYLE_ICON, + GDL_SWITCHER_STYLE_BOTH, + GDL_SWITCHER_STYLE_TOOLBAR, + GDL_SWITCHER_STYLE_TABS, + GDL_SWITCHER_STYLE_NONE +} GdlSwitcherStyle; + struct _GdlDockMaster { GObject object; diff --git a/src/libgdl/gdl-dock-notebook.c b/src/libgdl/gdl-dock-notebook.c index f6e0aeeef..3db3fab3f 100644 --- a/src/libgdl/gdl-dock-notebook.c +++ b/src/libgdl/gdl-dock-notebook.c @@ -270,7 +270,7 @@ gdl_dock_notebook_switch_page_cb (GtkNotebook *nb, { GdlDockNotebook *notebook; GtkWidget *tablabel; - (void)page_num; + GdlDockItem *item; notebook = GDL_DOCK_NOTEBOOK (data); @@ -293,6 +293,10 @@ gdl_dock_notebook_switch_page_cb (GtkNotebook *nb, GDL_DOCK_OBJECT (notebook)->master) g_signal_emit_by_name (GDL_DOCK_OBJECT (notebook)->master, "layout-changed"); + + /* Signal that a new dock item has been selected */ + item = GDL_DOCK_ITEM (gtk_notebook_get_nth_page (nb, page_num)); + gdl_dock_item_notify_selected (item); } static void diff --git a/src/libgdl/gdl-dock-object.c b/src/libgdl/gdl-dock-object.c index 9bdcd18ed..129cc28d9 100644 --- a/src/libgdl/gdl-dock-object.c +++ b/src/libgdl/gdl-dock-object.c @@ -396,6 +396,7 @@ gdl_dock_object_real_reduce (GdlDockObject *object) children = gtk_container_get_children (GTK_CONTAINER (object)); if (g_list_length (children) <= 1) { GList *l; + GList *dchildren = NULL; /* detach ourselves and then re-attach our children to our current parent. if we are not currently attached, the @@ -403,18 +404,41 @@ gdl_dock_object_real_reduce (GdlDockObject *object) if (parent) gdl_dock_object_freeze (parent); gdl_dock_object_freeze (object); - gdl_dock_object_detach (object, FALSE); + /* Detach the children before detaching this object, since in this + * way the children can have access to the whole object hierarchy. + * Set the InDetach flag now, so the children know that this object + * is going to be detached. */ + + + GDL_DOCK_OBJECT_SET_FLAGS (object, GDL_DOCK_IN_DETACH); + for (l = children; l; l = l->next) { - GdlDockObject *child = GDL_DOCK_OBJECT (l->data); + GdlDockObject *child; + + if (!GDL_IS_DOCK_OBJECT (l->data)) + continue; + + child = GDL_DOCK_OBJECT (l->data); g_object_ref (child); - GDL_DOCK_OBJECT_SET_FLAGS (child, GDL_DOCK_IN_REFLOW); gdl_dock_object_detach (child, FALSE); + GDL_DOCK_OBJECT_SET_FLAGS (child, GDL_DOCK_IN_REFLOW); if (parent) - gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (child)); + dchildren = g_list_append (dchildren, child); GDL_DOCK_OBJECT_UNSET_FLAGS (child, GDL_DOCK_IN_REFLOW); - g_object_unref (child); } + /* Now it can be detached */ + gdl_dock_object_detach (object, FALSE); + + /* After detaching the reduced object, we can add the + children (the only child in fact) to the new parent */ + for (l = dchildren; l; l = l->next) { + gtk_container_add (GTK_CONTAINER (parent), l->data); + g_object_unref (l->data); + } + g_list_free (dchildren); + + /* sink the widget, so any automatic floating widget is destroyed */ g_object_ref_sink (object); /* don't reenter */ @@ -469,6 +493,9 @@ gdl_dock_object_detach (GdlDockObject *object, { g_return_if_fail (object != NULL); + if (!GDL_IS_DOCK_OBJECT (object)) + return; + if (!GDL_DOCK_OBJECT_ATTACHED (object)) return; diff --git a/src/libgdl/gdl-dock-object.h b/src/libgdl/gdl-dock-object.h index 6ac36a44c..d1c27ffbd 100644 --- a/src/libgdl/gdl-dock-object.h +++ b/src/libgdl/gdl-dock-object.h @@ -221,7 +221,7 @@ GType gdl_dock_object_set_type_for_nick (const gchar *nick, __PRETTY_FUNCTION__, \ G_OBJECT_TYPE_NAME (object), object, \ G_OBJECT (object)->ref_count, \ - (GTK_IS_OBJECT (object) && GTK_OBJECT_FLOATING (object)) ? "(float)" : "", \ + (GTK_IS_OBJECT (object) && g_object_is_floating (object)) ? "(float)" : "", \ GDL_IS_DOCK_OBJECT (object) ? GDL_DOCK_OBJECT (object)->freeze_count : -1, \ ##args); } G_STMT_END diff --git a/src/libgdl/gdl-dock-paned.c b/src/libgdl/gdl-dock-paned.c index 5d0ac17ed..141770aa2 100644 --- a/src/libgdl/gdl-dock-paned.c +++ b/src/libgdl/gdl-dock-paned.c @@ -710,6 +710,7 @@ gdl_dock_paned_dock (GdlDockObject *object, } else { gdl_dock_item_show_grip (GDL_DOCK_ITEM (requestor)); + gtk_widget_show (GTK_WIDGET (requestor)); GDL_DOCK_OBJECT_SET_FLAGS (requestor, GDL_DOCK_ATTACHED); } } diff --git a/src/libgdl/gdl-dock-placeholder.c b/src/libgdl/gdl-dock-placeholder.c index ca7763a55..7a86ebe81 100644 --- a/src/libgdl/gdl-dock-placeholder.c +++ b/src/libgdl/gdl-dock-placeholder.c @@ -30,6 +30,7 @@ #include "gdl-tools.h" #include "gdl-dock-placeholder.h" #include "gdl-dock-item.h" +#include "gdl-dock-paned.h" #include "gdl-dock-master.h" #include "libgdltypebuiltins.h" @@ -189,14 +190,14 @@ gdl_dock_placeholder_class_init (GdlDockPlaceholderClass *klass) g_object_class_install_property ( g_object_class, PROP_FLOAT_X, g_param_spec_int ("floatx", _("X-Coordinate"), - _("X coordinate for dock when floating"), + _("X-Coordinate for dock when floating"), -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | GDL_DOCK_PARAM_EXPORT)); g_object_class_install_property ( g_object_class, PROP_FLOAT_Y, g_param_spec_int ("floaty", _("Y-Coordinate"), - _("Y coordinate for dock when floating"), + _("Y-Coordinate for dock when floating"), -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | GDL_DOCK_PARAM_EXPORT)); @@ -494,7 +495,7 @@ gdl_dock_placeholder_dock (GdlDockObject *object, GdlDockObject *toplevel; if (!gdl_dock_object_is_bound (GDL_DOCK_OBJECT (ph))) { - g_warning ("%s",_("Attempt to dock a dock object to an unbound placeholder")); + g_warning ("%s", _("Attempt to dock a dock object to an unbound placeholder")); return; } @@ -543,7 +544,7 @@ gdl_dock_placeholder_present (GdlDockObject *object, /* ----- Public interface ----- */ GtkWidget * -gdl_dock_placeholder_new (gchar *name, +gdl_dock_placeholder_new (const gchar *name, GdlDockObject *object, GdlDockPlacement position, gboolean sticky) diff --git a/src/libgdl/gdl-dock-placeholder.h b/src/libgdl/gdl-dock-placeholder.h index aeb55da67..c7e57e204 100644 --- a/src/libgdl/gdl-dock-placeholder.h +++ b/src/libgdl/gdl-dock-placeholder.h @@ -55,7 +55,7 @@ struct _GdlDockPlaceholderClass { GType gdl_dock_placeholder_get_type (void); -GtkWidget *gdl_dock_placeholder_new (gchar *name, +GtkWidget *gdl_dock_placeholder_new (const gchar *name, GdlDockObject *object, GdlDockPlacement position, gboolean sticky); diff --git a/src/libgdl/gdl-dock.c b/src/libgdl/gdl-dock.c index d80a47a1f..47a4f5b3d 100644 --- a/src/libgdl/gdl-dock.c +++ b/src/libgdl/gdl-dock.c @@ -349,21 +349,6 @@ gdl_dock_constructor (GType type, g_signal_connect (dock, "notify::long-name", (GCallback) gdl_dock_notify_cb, NULL); - /* set transient for the first dock if that is a non-floating dock */ - controller = gdl_dock_master_get_controller (master); - if (controller && GDL_IS_DOCK (controller)) { - gboolean first_is_floating; - g_object_get (controller, "floating", &first_is_floating, NULL); - if (!first_is_floating) { - GtkWidget *toplevel = - gtk_widget_get_toplevel (GTK_WIDGET (controller)); - - if (GTK_IS_WINDOW (toplevel)) - gtk_window_set_transient_for (GTK_WINDOW (dock->_priv->window), - GTK_WINDOW (toplevel)); - } - } - gtk_container_add (GTK_CONTAINER (dock->_priv->window), GTK_WIDGET (dock)); g_signal_connect (dock->_priv->window, "delete_event", @@ -1139,6 +1124,8 @@ gdl_dock_select_larger_item (GdlDockItem *dock_item_1, return ((size_1.width * size_1.height) >= (size_2.width * size_2.height)? dock_item_1 : dock_item_2); + } else if (placement == GDL_DOCK_NONE) { + return dock_item_1; } else { g_warning ("Should not reach here: %s:%d", __FUNCTION__, __LINE__); } diff --git a/src/libgdl/gdl-stock.c b/src/libgdl/gdl-stock.c deleted file mode 100644 index dc86e523b..000000000 --- a/src/libgdl/gdl-stock.c +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * gdl-stock.c - * - * Copyright (C) 2003 Jeroen Zwartepoorte - * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include "gdl-stock.h" -#include "gdl-stock-icons.h" - -static GtkIconFactory *gdl_stock_factory = NULL; - -static struct { - const gchar *stock_id; - const guint8 *icon_data; - const guint data_size; -} -gdl_icons[] = -{ - { GDL_STOCK_CLOSE, stock_close_icon, sizeof (stock_close_icon) }, - { GDL_STOCK_MENU_LEFT, stock_menu_left_icon, sizeof (stock_menu_left_icon) }, - { GDL_STOCK_MENU_RIGHT, stock_menu_right_icon, sizeof (stock_menu_right_icon) } -}; - -static void -icon_set_from_data (GtkIconSet *set, - const guint8 *icon_data, - const guint data_size, - GtkIconSize size, - gboolean fallback) -{ - GtkIconSource *source; - GdkPixbuf *pixbuf; - GError *err = NULL; - - source = gtk_icon_source_new (); - - gtk_icon_source_set_size (source, size); - gtk_icon_source_set_size_wildcarded (source, FALSE); - - pixbuf = gdk_pixbuf_new_from_inline (data_size, icon_data, FALSE, &err); - if (err) { - g_warning ("%s",err->message); - g_error_free (err); - err = NULL; - g_object_unref (source); - return; - } - - gtk_icon_source_set_pixbuf (source, pixbuf); - - g_object_unref (pixbuf); - - gtk_icon_set_add_source (set, source); - - if (fallback) { - gtk_icon_source_set_size_wildcarded (source, TRUE); - gtk_icon_set_add_source (set, source); - } - - gtk_icon_source_free (source); -} - -static void -add_icon (GtkIconFactory *factory, - const gchar *stock_id, - const guint8 *icon_data, - const guint data_size) -{ - GtkIconSet *set; - gboolean fallback = FALSE; - - set = gtk_icon_factory_lookup (factory, stock_id); - - if (!set) { - set = gtk_icon_set_new (); - gtk_icon_factory_add (factory, stock_id, set); - gtk_icon_set_unref (set); - - fallback = TRUE; - } - - icon_set_from_data (set, icon_data, data_size, GTK_ICON_SIZE_MENU, fallback); -} - -void -gdl_stock_init (void) -{ - static gboolean initialized = FALSE; - gint i; - - if (initialized) - return; - - gdl_stock_factory = gtk_icon_factory_new (); - - for (i = 0; i < G_N_ELEMENTS (gdl_icons); i++) { - add_icon (gdl_stock_factory, - gdl_icons[i].stock_id, - gdl_icons[i].icon_data, - gdl_icons[i].data_size); - } - - gtk_icon_factory_add_default (gdl_stock_factory); - - initialized = TRUE; -} diff --git a/src/libgdl/gdl-switcher.c b/src/libgdl/gdl-switcher.c index eccd66ce2..65013e390 100644 --- a/src/libgdl/gdl-switcher.c +++ b/src/libgdl/gdl-switcher.c @@ -4,20 +4,22 @@ * Copyright (C) 2003 Ettore Perazzoli, * 2007 Naba Kumar * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * Library General Public License for more details. * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * + * * Copied and adapted from ESidebar.[ch] from evolution * * Authors: Ettore Perazzoli <ettore@ximian.com> @@ -36,10 +38,6 @@ #include <gtk/gtk.h> -#if HAVE_GNOME -#include <gconf/gconf-client.h> -#endif - static void gdl_switcher_set_property (GObject *object, guint prop_id, const GValue *value, @@ -55,7 +53,7 @@ static void gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *stock_id, const GdkPixbuf *pixbuf_icon, gint switcher_id); -static void gdl_switcher_remove_button (GdlSwitcher *switcher, gint switcher_id); +/* static void gdl_switcher_remove_button (GdlSwitcher *switcher, gint switcher_id); */ static void gdl_switcher_select_page (GdlSwitcher *switcher, gint switcher_id); static void gdl_switcher_select_button (GdlSwitcher *switcher, gint switcher_id); static void gdl_switcher_set_show_buttons (GdlSwitcher *switcher, gboolean show); @@ -216,7 +214,7 @@ button_toggled_callback (GtkToggleButton *toggle_button, static int layout_buttons (GdlSwitcher *switcher) { - GtkRequisition client_requisition; + GtkRequisition client_requisition = {0,}; GtkAllocation *allocation = & GTK_WIDGET (switcher)->allocation; GdlSwitcherStyle switcher_style; gboolean icons_only; @@ -514,7 +512,7 @@ gdl_switcher_expose (GtkWidget *widget, GdkEventExpose *event) } } return GDL_CALL_PARENT_WITH_DEFAULT (GTK_WIDGET_CLASS, expose_event, - (widget, event), FALSE); + (widget, event), FALSE); } static void @@ -608,12 +606,6 @@ static void gdl_switcher_notify_cb (GObject *g_object, GParamSpec *pspec, GdlSwitcher *switcher) { - gboolean show_tabs; - (void)g_object; - (void)pspec; - g_return_if_fail (switcher != NULL && GDL_IS_SWITCHER (switcher)); - show_tabs = gtk_notebook_get_show_tabs (GTK_NOTEBOOK (switcher)); - gdl_switcher_set_show_buttons (switcher, !show_tabs); } static void @@ -678,11 +670,9 @@ gdl_switcher_select_page (GdlSwitcher *switcher, gint id) static void gdl_switcher_class_init (GdlSwitcherClass *klass) { - GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass); GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass); - (void)notebook_class; container_class->forall = gdl_switcher_forall; container_class->remove = gdl_switcher_remove; @@ -704,6 +694,15 @@ gdl_switcher_class_init (GdlSwitcherClass *klass) GDL_TYPE_SWITCHER_STYLE, GDL_SWITCHER_STYLE_BOTH, G_PARAM_READWRITE)); + + gtk_rc_parse_string ("style \"gdl-button-style\"\n" + "{\n" + "GtkWidget::focus-padding = 1\n" + "GtkWidget::focus-line-width = 1\n" + "xthickness = 0\n" + "ythickness = 0\n" + "}\n" + "widget \"*.gdl-button\" style \"gdl-button-style\""); } static void @@ -745,6 +744,7 @@ gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *label, const gchar *tooltips, const gchar *stock_id, const GdkPixbuf *pixbuf_icon, gint switcher_id) { + GtkWidget *event_box; GtkWidget *button_widget; GtkWidget *hbox; GtkWidget *icon_widget; @@ -752,6 +752,8 @@ gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *label, GtkWidget *arrow; button_widget = gtk_toggle_button_new (); + gtk_widget_set_name (button_widget, "gdl-button"); + gtk_button_set_relief (GTK_BUTTON(button_widget), GTK_RELIEF_HALF); if (switcher->priv->show) gtk_widget_show (button_widget); g_signal_connect (button_widget, "toggled", @@ -763,11 +765,11 @@ gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *label, gtk_widget_show (hbox); if (stock_id) { - icon_widget = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON); + icon_widget = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU); } else if (pixbuf_icon) { icon_widget = gtk_image_new_from_pixbuf (pixbuf_icon); } else { - icon_widget = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_BUTTON); + icon_widget = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_MENU); } gtk_widget_show (icon_widget); @@ -781,8 +783,11 @@ gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *label, } gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5); gtk_widget_show (label_widget); - gtk_widget_set_tooltip_text (button_widget, tooltips); - + + + gtk_widget_set_tooltip_text (button_widget, + tooltips); + switch (INTERNAL_MODE (switcher)) { case GDL_SWITCHER_STYLE_TEXT: gtk_box_pack_start (GTK_BOX (hbox), label_widget, TRUE, TRUE, 0); @@ -803,13 +808,14 @@ gdl_switcher_add_button (GdlSwitcher *switcher, const gchar *label, switcher->priv->buttons = g_slist_append (switcher->priv->buttons, button_new (button_widget, label_widget, - icon_widget, + icon_widget, arrow, hbox, switcher_id)); + gtk_widget_set_parent (button_widget, GTK_WIDGET (switcher)); - gtk_widget_queue_resize (GTK_WIDGET (switcher)); } +#if 0 static void gdl_switcher_remove_button (GdlSwitcher *switcher, gint switcher_id) { @@ -827,6 +833,7 @@ gdl_switcher_remove_button (GdlSwitcher *switcher, gint switcher_id) } gtk_widget_queue_resize (GTK_WIDGET (switcher)); } +#endif static void gdl_switcher_select_button (GdlSwitcher *switcher, gint switcher_id) @@ -864,179 +871,87 @@ gdl_switcher_insert_page (GdlSwitcher *switcher, GtkWidget *page, } static void -set_switcher_style_internal (GdlSwitcher *switcher, - GdlSwitcherStyle switcher_style ) +set_switcher_style_toolbar (GdlSwitcher *switcher, + GdlSwitcherStyle switcher_style) { GSList *p; - if (switcher_style == GDL_SWITCHER_STYLE_TABS && - switcher->priv->show == FALSE) + if (switcher_style == GDL_SWITCHER_STYLE_NONE + || switcher_style == GDL_SWITCHER_STYLE_TABS) return; - if (switcher_style == GDL_SWITCHER_STYLE_TABS) - { - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (switcher), TRUE); - return; - } - - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (switcher), FALSE); - + if (switcher_style == GDL_SWITCHER_STYLE_TOOLBAR) + switcher_style = GDL_SWITCHER_STYLE_BOTH; + if (switcher_style == INTERNAL_MODE (switcher)) return; - + + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (switcher), FALSE); + for (p = switcher->priv->buttons; p != NULL; p = p->next) { Button *button = p->data; gtk_container_remove (GTK_CONTAINER (button->hbox), button->arrow); + + if (gtk_widget_get_parent (button->icon)) + gtk_container_remove (GTK_CONTAINER (button->hbox), button->icon); + if (gtk_widget_get_parent (button->label)) + gtk_container_remove (GTK_CONTAINER (button->hbox), button->label); + switch (switcher_style) { case GDL_SWITCHER_STYLE_TEXT: - gtk_container_remove (GTK_CONTAINER (button->hbox), button->icon); - if (INTERNAL_MODE (switcher) - == GDL_SWITCHER_STYLE_ICON) { - gtk_box_pack_start (GTK_BOX (button->hbox), button->label, - TRUE, TRUE, 0); - gtk_widget_show (button->label); - } + gtk_box_pack_start (GTK_BOX (button->hbox), button->label, + TRUE, TRUE, 0); + gtk_widget_show (button->label); break; + case GDL_SWITCHER_STYLE_ICON: - gtk_container_remove(GTK_CONTAINER (button->hbox), button->label); - if (INTERNAL_MODE (switcher) - == GDL_SWITCHER_STYLE_TEXT) { - gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, - TRUE, TRUE, 0); - gtk_widget_show (button->icon); - } else - gtk_container_child_set (GTK_CONTAINER (button->hbox), - button->icon, "expand", TRUE, NULL); + gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, + TRUE, TRUE, 0); + gtk_widget_show (button->icon); break; - case GDL_SWITCHER_STYLE_BOTH: - if (INTERNAL_MODE (switcher) - == GDL_SWITCHER_STYLE_TEXT) { - gtk_container_remove (GTK_CONTAINER (button->hbox), - button->label); - gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, - FALSE, TRUE, 0); - gtk_widget_show (button->icon); - } else { - gtk_container_child_set (GTK_CONTAINER (button->hbox), - button->icon, "expand", FALSE, NULL); - } - gtk_box_pack_start (GTK_BOX (button->hbox), button->label, TRUE, - TRUE, 0); + case GDL_SWITCHER_STYLE_BOTH: + gtk_box_pack_start (GTK_BOX (button->hbox), button->icon, + FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (button->hbox), button->label, + TRUE, TRUE, 0); + gtk_widget_show (button->icon); gtk_widget_show (button->label); break; + default: break; } - gtk_box_pack_start (GTK_BOX (button->hbox), button->arrow, FALSE, - FALSE, 0); - } -} - -#if HAVE_GNOME -static GConfEnumStringPair toolbar_styles[] = { - { GDL_SWITCHER_STYLE_TEXT, "text" }, - { GDL_SWITCHER_STYLE_ICON, "icons" }, - { GDL_SWITCHER_STYLE_BOTH, "both" }, - { GDL_SWITCHER_STYLE_BOTH, "both-horiz" }, - { GDL_SWITCHER_STYLE_BOTH, "both_horiz" }, - { -1, NULL } -}; - -static void -style_changed_notify (GConfClient *gconf, guint id, GConfEntry *entry, - void *data) -{ - GdlSwitcher *switcher = data; - char *val; - int switcher_style; - - val = gconf_client_get_string (gconf, - "/desktop/gnome/interface/toolbar_style", - NULL); - if (val == NULL || !gconf_string_to_enum (toolbar_styles, val, - &switcher_style)) - switcher_style = GDL_SWITCHER_STYLE_BOTH; - g_free(val); - set_switcher_style_internal (GDL_SWITCHER (switcher), switcher_style); - switcher->priv->toolbar_style = switcher_style; + gtk_box_pack_start (GTK_BOX (button->hbox), button->arrow, + FALSE, FALSE, 0); + } - gtk_widget_queue_resize (GTK_WIDGET (switcher)); + gdl_switcher_set_show_buttons (switcher, TRUE); } static void gdl_switcher_set_style (GdlSwitcher *switcher, GdlSwitcherStyle switcher_style) { - GConfClient *gconf_client = gconf_client_get_default (); - - if (switcher_style == GDL_SWITCHER_STYLE_TABS && - switcher->priv->show == FALSE) - return; - - if (switcher->priv->switcher_style == switcher_style && - switcher->priv->show == TRUE) + if (switcher->priv->switcher_style == switcher_style) return; - if (switcher->priv->switcher_style == GDL_SWITCHER_STYLE_TOOLBAR) { - if (switcher->priv->style_changed_id) { - gconf_client_notify_remove (gconf_client, - switcher->priv->style_changed_id); - switcher->priv->style_changed_id = 0; - } + if (switcher_style == GDL_SWITCHER_STYLE_NONE) { + gdl_switcher_set_show_buttons (switcher, FALSE); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (switcher), FALSE); } - - if (switcher_style != GDL_SWITCHER_STYLE_TOOLBAR) { - set_switcher_style_internal (switcher, switcher_style); - - gtk_widget_queue_resize (GTK_WIDGET (switcher)); - } else { - /* This is a little bit tricky, toolbar style is more - * of a meta-style where the actual style is dictated by - * the gnome toolbar setting, so that is why we have - * the is_toolbar_style bool - it tracks the toolbar - * style while the switcher_style member is the actual look and - * feel */ - switcher->priv->style_changed_id = - gconf_client_notify_add (gconf_client, - "/desktop/gnome/interface/toolbar_style", - style_changed_notify, switcher, - NULL, NULL); - style_changed_notify (gconf_client, 0, NULL, switcher); + else if (switcher_style == GDL_SWITCHER_STYLE_TABS) { + gdl_switcher_set_show_buttons (switcher, FALSE); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (switcher), TRUE); } - - g_object_unref (gconf_client); - - if (switcher_style != GDL_SWITCHER_STYLE_TABS) - switcher->priv->switcher_style = switcher_style; -} - -#else /* HAVE_GNOME */ - -static void -gdl_switcher_set_style (GdlSwitcher *switcher, GdlSwitcherStyle switcher_style) -{ - if (switcher_style == GDL_SWITCHER_STYLE_TABS && - switcher->priv->show == FALSE) - return; - - if (switcher->priv->switcher_style == switcher_style && - switcher->priv->show == TRUE) - return; + else + set_switcher_style_toolbar (switcher, switcher_style); - set_switcher_style_internal (switcher, - ((switcher_style == - GDL_SWITCHER_STYLE_TOOLBAR)? - GDL_SWITCHER_STYLE_BOTH : switcher_style)); gtk_widget_queue_resize (GTK_WIDGET (switcher)); - - if (switcher_style != GDL_SWITCHER_STYLE_TABS) - switcher->priv->switcher_style = switcher_style; + switcher->priv->switcher_style = switcher_style; } -#endif /* HAVE_GNOME */ - static void gdl_switcher_set_show_buttons (GdlSwitcher *switcher, gboolean show) { diff --git a/src/libgdl/gdl-switcher.h b/src/libgdl/gdl-switcher.h index 9c33f8bbf..991f2da20 100644 --- a/src/libgdl/gdl-switcher.h +++ b/src/libgdl/gdl-switcher.h @@ -4,20 +4,22 @@ * Copyright (C) 2003 Ettore Perazzoli * 2007 Naba Kumar * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. +* This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * Library General Public License for more details. * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * + * * Authors: Ettore Perazzoli <ettore@ximian.com> * Naba Kumar <naba@gnome.org> */ @@ -39,14 +41,6 @@ typedef struct _GdlSwitcher GdlSwitcher; typedef struct _GdlSwitcherPrivate GdlSwitcherPrivate; typedef struct _GdlSwitcherClass GdlSwitcherClass; -typedef enum { - GDL_SWITCHER_STYLE_TEXT, - GDL_SWITCHER_STYLE_ICON, - GDL_SWITCHER_STYLE_BOTH, - GDL_SWITCHER_STYLE_TOOLBAR, - GDL_SWITCHER_STYLE_TABS -} GdlSwitcherStyle; - struct _GdlSwitcher { GtkNotebook parent; diff --git a/src/libgdl/gdl-tools.h b/src/libgdl/gdl-tools.h index 2cc68c035..4e515b23b 100644 --- a/src/libgdl/gdl-tools.h +++ b/src/libgdl/gdl-tools.h @@ -79,9 +79,10 @@ G_BEGIN_DECLS #endif /* DO_GDL_TRACE */ -/** +/* * Class boilerplate and base class call macros copied from * bonobo/bonobo-macros.h. Original copyright follows. + * * * Author: * Darin Adler <darin@bentspoon.com> diff --git a/src/libgdl/gdl-stock.h b/src/libgdl/gdl.h index cb6f7abb9..d136b9295 100644 --- a/src/libgdl/gdl-stock.h +++ b/src/libgdl/gdl.h @@ -1,8 +1,8 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * gdl-stock.h - * - * Copyright (C) 2003 Jeroen Zwartepoorte +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * + * This file is part of the GNOME Devtools Libraries. + * + * Copyright (C) 1999-2000 Dave Camp <dave@helixcode.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,19 +19,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef __GDL_STOCK_H__ -#define __GDL_STOCK_H__ - -#include <glib/gmacros.h> // G_BEGIN_DECLS - -G_BEGIN_DECLS - -#define GDL_STOCK_CLOSE "gdl-close" -#define GDL_STOCK_MENU_LEFT "gdl-menu-left" -#define GDL_STOCK_MENU_RIGHT "gdl-menu-right" - -void gdl_stock_init (void); +#ifndef __GDL_H__ +#define __GDL_H__ -G_END_DECLS +#include "libgdl/gdl-tools.h" +#include "libgdl/gdl-dock-object.h" +#include "libgdl/gdl-dock-master.h" +#include "libgdl/gdl-dock.h" +#include "libgdl/gdl-dock-item.h" +#include "libgdl/gdl-dock-item-grip.h" +#include "libgdl/gdl-dock-bar.h" -#endif /* __GDL_STOCK_H__ */ +#endif diff --git a/src/libgdl/libgdl.h b/src/libgdl/libgdl.h deleted file mode 100644 index 5ee84e1ae..000000000 --- a/src/libgdl/libgdl.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * This file is part of the GNOME Devtools Libraries. - * - * Copyright (C) 1999-2000 Dave Camp <dave@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GDL_H__ -#define __GDL_H__ - -#include "libgdl/gdl-tools.h" -#include "libgdl/gdl-dock-object.h" -#include "libgdl/gdl-dock-master.h" -#include "libgdl/gdl-dock.h" -#include "libgdl/gdl-dock-item.h" -#include "libgdl/gdl-dock-paned.h" -#include "libgdl/gdl-dock-notebook.h" -#include "libgdl/gdl-dock-tablabel.h" -#include "libgdl/gdl-dock-bar.h" -#include "libgdl/gdl-switcher.h" - -#endif diff --git a/src/libgdl/libgdltypebuiltins.h b/src/libgdl/libgdltypebuiltins.h index 8be5decb1..f5e6ea17b 100644 --- a/src/libgdl/libgdltypebuiltins.h +++ b/src/libgdl/libgdltypebuiltins.h @@ -4,7 +4,7 @@ #ifndef __LIBGDLTYPEBUILTINS_H__ #define __LIBGDLTYPEBUILTINS_H__ 1 -#include "libgdl/libgdl.h" +#include "libgdl/gdl.h" G_BEGIN_DECLS diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index 45bc0c89b..c5ea3969d 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -135,7 +135,7 @@ float Layout::InputStreamTextSource::styleComputeFontSize() const if (this_style->font_size.set && !this_style->font_size.inherit) { switch (this_style->font_size.type) { case SP_FONT_SIZE_LITERAL: { - switch(this_style->font_size.value) { // these multipliers are straight out of the CSS spec + switch(this_style->font_size.literal) { // these multipliers are straight out of the CSS spec case SP_CSS_FONT_SIZE_XX_SMALL: return medium_font_size * inherit_multiplier * (3.0/5.0); case SP_CSS_FONT_SIZE_X_SMALL: return medium_font_size * inherit_multiplier * (3.0/4.0); case SP_CSS_FONT_SIZE_SMALL: return medium_font_size * inherit_multiplier * (8.0/9.0); diff --git a/src/seltrans.cpp b/src/seltrans.cpp index f95a204a9..f6a702ed9 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -1566,7 +1566,7 @@ Geom::Point Inkscape::SelTrans::_getGeomHandlePos(Geom::Point const &visual_hand // Calculate the absolute affine while taking into account the scaling of the stroke width Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool transform_stroke = prefs->getBool("/options/transform/stroke", true); - Geom::Affine abs_affine = get_scale_transform_with_stroke (*_bbox, _strokewidth, transform_stroke, + Geom::Affine abs_affine = get_scale_transform_with_uniform_stroke (*_bbox, _strokewidth, transform_stroke, new_bbox.min()[Geom::X], new_bbox.min()[Geom::Y], new_bbox.max()[Geom::X], new_bbox.max()[Geom::Y]); // Calculate the scaled geometrical bbox @@ -1613,7 +1613,7 @@ Geom::Point Inkscape::SelTrans::_calcAbsAffineDefault(Geom::Scale const default_ strokewidth = _strokewidth; } - _absolute_affine = get_scale_transform_with_stroke (*_approximate_bbox, strokewidth, transform_stroke, + _absolute_affine = get_scale_transform_with_uniform_stroke (*_approximate_bbox, strokewidth, transform_stroke, new_bbox_min[Geom::X], new_bbox_min[Geom::Y], new_bbox_max[Geom::X], new_bbox_max[Geom::Y]); // return the new handle position diff --git a/src/snap-preferences.cpp b/src/snap-preferences.cpp index 4859b111e..b98726a86 100644 --- a/src/snap-preferences.cpp +++ b/src/snap-preferences.cpp @@ -5,7 +5,7 @@ * Authors: * Diederik van Lierop <mail@diedenrezi.nl> * - * Copyright (C) 2008 Authors + * Copyright (C) 2008 - 2011 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ diff --git a/src/snap-preferences.h b/src/snap-preferences.h index 8e8ebc9cf..35d05c40e 100644 --- a/src/snap-preferences.h +++ b/src/snap-preferences.h @@ -8,7 +8,7 @@ * Authors: * Diederik van Lierop <mail@diedenrezi.nl> * - * Copyright (C) 2008 - 2010 Authors + * Copyright (C) 2008 - 2011 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ diff --git a/src/sp-image.cpp b/src/sp-image.cpp index 3f1c19295..791e88b39 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -45,8 +45,9 @@ #include "io/sys.h" #if ENABLE_LCMS -#include "color-profile-fns.h" +#include "cms-system.h" #include "color-profile.h" +#include <lcms.h> //#define DEBUG_LCMS #ifdef DEBUG_LCMS @@ -849,9 +850,9 @@ static void sp_image_update( SPObject *object, SPCtx *ctx, unsigned int flags ) DEBUG_MESSAGE( lcmsFive, "in <image>'s sp_image_update. About to call colorprofile_get_handle()" ); #endif // DEBUG_LCMS guint profIntent = Inkscape::RENDERING_INTENT_UNKNOWN; - cmsHPROFILE prof = Inkscape::colorprofile_get_handle( object->document, - &profIntent, - image->color_profile ); + cmsHPROFILE prof = Inkscape::CMSSystem::getHandle( object->document, + &profIntent, + image->color_profile ); if ( prof ) { icProfileClassSignature profileClass = cmsGetDeviceClass( prof ); if ( profileClass != icSigNamedColorClass ) { diff --git a/src/sp-item-transform.cpp b/src/sp-item-transform.cpp index ae55a5c50..eb4b81a61 100644 --- a/src/sp-item-transform.cpp +++ b/src/sp-item-transform.cpp @@ -7,8 +7,9 @@ * bulia byak <buliabyak@gmail.com> * Johan Engelen <goejendaagh@zonnet.nl> * Abhishek Sharma + * Diederik van Lierop <mail@diedenrezi.nl> * - * Copyright (C) 1999-2008 authors + * Copyright (C) 1999-2011 authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -67,46 +68,76 @@ sp_item_skew_rel (SPItem *item, double skewX, double skewY) void sp_item_move_rel(SPItem *item, Geom::Translate const &tr) { - item->set_i2d_affine(item->i2d_affine() * tr); + item->set_i2d_affine(item->i2d_affine() * tr); - item->doWriteTransform(item->getRepr(), item->transform); + item->doWriteTransform(item->getRepr(), item->transform); } -/* -** Returns the matrix you need to apply to an object with given visual bbox and strokewidth to -scale/move it to the new visual bbox x0/y0/x1/y1. Takes into account the "scale stroke" -preference value passed to it. Has to solve a quadratic equation to make sure -the goal is met exactly and the stroke scaling is obeyed. +/** + * \brief Calculate the affine transformation required to transform one visual bounding box into another, accounting for a uniform strokewidth + * + * PS: This function will only return accurate results for the visual bounding box of a selection of one of more objects, all having + * the same strokewidth. If the stroke width varies from object to object in this selection, then the function + * get_scale_transform_with_unequal_stroke() should be called instead + * + * When scaling or stretching an object using the selector, e.g. by dragging the handles or by entering a value, we will + * need to calculate the affine transformation for the old dimensions to the new dimensions. When using a geometric bounding + * box this is very straightforward, but when using a visual bounding box this become more tricky as we need to account for + * the strokewidth, which is either constant or scales width the area of the object. This function takes care of the calculation + * of the affine transformation: + * \param bbox_visual Current visual bounding box + * \param strokewidth Strokewidth + * \param transform_stroke If true then the stroke will be scaled proportional to the square root of the area of the geometric bounding box + * \param x0 Coordinate of the target visual bounding box + * \param y0 Coordinate of the target visual bounding box + * \param x1 Coordinate of the target visual bounding box + * \param y1 Coordinate of the target visual bounding box + * PS: we have to pass each coordinate individually, to find out if we are mirroring the object; Using a Geom::Rect() instead is + not possible here because it will only allow for a positive width and height, and therefore cannot mirror + * \return */ Geom::Affine -get_scale_transform_with_stroke (Geom::Rect const &bbox_param, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1) +get_scale_transform_with_uniform_stroke (Geom::Rect const &bbox_visual, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1) { - Geom::Rect bbox (bbox_param); - - Geom::Affine p2o = Geom::Translate (-bbox.min()); + Geom::Affine p2o = Geom::Translate (-bbox_visual.min()); Geom::Affine o2n = Geom::Translate (x0, y0); - Geom::Affine scale = Geom::Scale (1, 1); // scale component - Geom::Affine unbudge = Geom::Translate (0, 0); // move component to compensate for the drift caused by stroke width change + Geom::Affine scale = Geom::Scale (1, 1); + Geom::Affine unbudge = Geom::Translate (0, 0); // moves the object(s) to compensate for the drift caused by stroke width change + + // 1) We start with a visual bounding box (w0, h0) which we want to transfer into another visual bounding box (w1, h1) + // 2) The stroke is r0, equal for all edges + // 3) Given this visual bounding box we can calculate the geometric bounding box by subtracting half the stroke from each side; + // -> The width and height of the geometric bounding box will therefore be (w0 - 2*0.5*r0) and (h0 - 2*0.5*r0) - gdouble w0 = bbox[Geom::X].extent(); // will return a value >= 0, as required further down the road - gdouble h0 = bbox[Geom::Y].extent(); + gdouble w0 = bbox_visual.width(); // will return a value >= 0, as required further down the road + gdouble h0 = bbox_visual.height(); + gdouble r0 = fabs(strokewidth); + + // We also know the width and height of the new visual bounding box gdouble w1 = x1 - x0; // can have any sign gdouble h1 = y1 - y0; - gdouble r0 = strokewidth; + // The new visual bounding box will have a stroke r1 + + // We will now try to calculate the affine transformation required to transform the first visual bounding box into + // the second one, while accounting for strokewidth - if (bbox.hasZeroArea()) { - Geom::Affine move = Geom::Translate(x0 - bbox.min()[Geom::X], y0 - bbox.min()[Geom::Y]); - return (move); // cannot scale from empty boxes at all, so only translate + if (bbox_visual.hasZeroArea()) { // Obviously we cannot scale from empty visual bounding boxes at all, so we will only translate in such a case + Geom::Affine move = Geom::Translate(x0 - bbox_visual.min()[Geom::X], y0 - bbox_visual.min()[Geom::Y]); + return (move); } - Geom::Affine direct = Geom::Scale(w1 / w0, h1 / h0); + Geom::Affine direct = Geom::Scale(w1 / w0, h1 / h0); // Scaling of the visual bounding box + // Although the area of the visual bounding box is not zero, we can still have a geometric + // bounding box with one or both sides having zero length. We can't handle this and will therefore + // simply return the scaling of the visual bounding box, without accounting for any stroke scaling if (fabs(w0 - r0) < 1e-6 || fabs(h0 - r0) < 1e-6 || (!transform_stroke && (fabs(w1 - r0) < 1e-6 || fabs(h1 - r0) < 1e-6))) { - return (p2o * direct * o2n); // can't solve the equation: one of the dimensions is equal to stroke width, so return the straightforward scaler + return (p2o * direct * o2n); } + // Here starts the calculation you've been waiting for; first do some preparation int flip_x = (w1 > 0) ? 1 : -1; int flip_y = (h1 > 0) ? 1 : -1; @@ -115,41 +146,46 @@ get_scale_transform_with_stroke (Geom::Rect const &bbox_param, gdouble strokewid w1 = fabs(w1); h1 = fabs(h1); r0 = fabs(r0); - // w0 and h0 will always be positive due to the definition extent() + // w0 and h0 will always be positive due to the definition of the width() and height() methods. - gdouble ratio_x = (w1 - r0) / (w0 - r0); + gdouble ratio_x = (w1 - r0) / (w0 - r0); // Only valid when the stroke is kept constant, in which case r1 = r0 gdouble ratio_y = (h1 - r0) / (h0 - r0); - + + // Calculating the scaling of the geometric bounding box if the stroke is kept constant Geom::Affine direct_constant_r = Geom::Scale(flip_x * ratio_x, flip_y * ratio_y); - if (transform_stroke && r0 != 0 && r0 != Geom::infinity()) { // there's stroke, and we need to scale it - // These coefficients are obtained from the assumption that scaling applies to the - // non-stroked "shape proper" and that stroke scale is scaled by the expansion of that - // matrix. We're trying to solve this equation: - // r1 = r0 * sqrt (((w1-r0)/(w0-r0))*((h1-r0)/(h0-r0))) - // The operant of the sqrt() must be positive, which is ensured by the fabs() a few lines above + // If the stroke is not kept constant however, the scaling of the geometric bbox is more difficult to find + if (transform_stroke && r0 != 0 && r0 != Geom::infinity()) { // Check if there's stroke, and we need to scale it + /* Initial area of the geometric bounding box: A0 = (w0-r0)*(h0-r0) + * Desired area of the geometric bounding box: A1 = (w1-r1)*(h1-r1) + * This is how the stroke should scale: r1^2 / A1 = r0^2 / A0 + * So therefore we will need to solve this equation: + * + * r1^2 * (w0-r0) * (h1-r1) = r0^2 * (w1-r1) * (h0-r0) + * + * This is a quadratic equation in r1, of which the roots can be found using the ABC formula + * */ gdouble A = -w0*h0 + r0*(w0 + h0); gdouble B = -(w1 + h1) * r0*r0; gdouble C = w1 * h1 * r0*r0; if (B*B - 4*A*C > 0) { + // Of the two roots, I verified experimentally that this is the one we need gdouble r1 = fabs((-B - sqrt(B*B - 4*A*C))/(2*A)); - //gdouble r2 = (-B + sqrt (B*B - 4*A*C))/(2*A); - //std::cout << "r0" << r0 << " r1" << r1 << " r2" << r2 << "\n"; - // - // If w1 < 0 then the scale will be wrong if we just do - // gdouble scale_x = (w1 - r1)/(w0 - r0); - // Here we also need the absolute values of w0, w1, h0, h1, and r1 + // If w1 < 0 then the scale will be wrong if we just assume that scale_x = (w1 - r1)/(w0 - r0); + // Therefore we here need the absolute values of w0, w1, h0, h1, and r0, as taken care of earlier gdouble scale_x = (w1 - r1)/(w0 - r0); gdouble scale_y = (h1 - r1)/(h0 - r0); + // Now we account for mirroring by flipping if needed scale *= Geom::Scale(flip_x * scale_x, flip_y * scale_y); + // Make sure that the lower-left corner of the visual bounding box stays where it is, even though the stroke width has changed unbudge *= Geom::Translate (-flip_x * 0.5 * (r0 * scale_x - r1), -flip_y * 0.5 * (r0 * scale_y - r1)); - } else { + } else { // Can't find the roots of the quadratic equation. Likely the input parameters are invalid? scale *= direct; } - } else { - if (r0 == 0 || r0 == Geom::infinity()) { // no stroke to scale + } else { // The stroke should not be scaled, or is zero + if (r0 == 0 || r0 == Geom::infinity() ) { // Strokewidth is zero or infinite scale *= direct; - } else {// nonscaling strokewidth + } else { // Nonscaling strokewidth scale *= direct_constant_r; unbudge *= Geom::Translate (flip_x * 0.5 * r0 * (1 - ratio_x), flip_y * 0.5 * r0 * (1 - ratio_y)); } @@ -158,10 +194,162 @@ get_scale_transform_with_stroke (Geom::Rect const &bbox_param, gdouble strokewid return (p2o * scale * unbudge * o2n); } +/** + * \brief Calculate the affine transformation required to transform one visual bounding box into another, accounting for a VARIABLE strokewidth + * + * Note: Please try to understand get_scale_transform_with_uniform_stroke() first, and read all it's comments carefully. This function + * (get_scale_transform_with_unequal_stroke) is a bit different because it will allow for a strokewidth that's different for each + * side of the visual bounding box. Such a situation will arise when transforming the visual bounding box of a selection of objects, + * each having a different stroke width. In fact this function is a generalized version of get_scale_transform_with_uniform_stroke(), but + * will not (yet) replace it because it has not been tested as carefully, and because the old function is can serve as an introduction to + * understand the new one. + * + * When scaling or stretching an object using the selector, e.g. by dragging the handles or by entering a value, we will + * need to calculate the affine transformation for the old dimensions to the new dimensions. When using a geometric bounding + * box this is very straightforward, but when using a visual bounding box this become more tricky as we need to account for + * the strokewidth, which is either constant or scales width the area of the object. This function takes care of the calculation + * of the affine transformation: + * + * \param bbox_visual Current visual bounding box + * \param bbox_geometric Current geometric bounding box (allows for calculating the strokewidth of each edge) + * \param transform_stroke If true then the stroke will be scaled proportional to the square root of the area of the geometric bounding box + * \param x0 Coordinate of the target visual bounding box + * \param y0 Coordinate of the target visual bounding box + * \param x1 Coordinate of the target visual bounding box + * \param y1 Coordinate of the target visual bounding box + PS: we have to pass each coordinate individually, to find out if we are mirroring the object; Using a Geom::Rect() instead is + not possible here because it will only allow for a positive width and height, and therefore cannot mirror + * \return +*/ + +Geom::Affine +get_scale_transform_with_unequal_stroke (Geom::Rect const &bbox_visual, Geom::Rect const &bbox_geom, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1) +{ + Geom::Affine p2o = Geom::Translate (-bbox_visual.min()); + Geom::Affine o2n = Geom::Translate (x0, y0); + + Geom::Affine scale = Geom::Scale (1, 1); + Geom::Affine unbudge = Geom::Translate (0, 0); // moves the object(s) to compensate for the drift caused by stroke width change + + // 1) We start with a visual bounding box (w0, h0) which we want to transfer into another visual bounding box (w1, h1) + // 2) We will also know the geometric bounding box, which can be used to calculate the strokewidth. The strokewidth will however + // be different for each of the four sides (left/right/top/bottom: r0l, r0r, r0t, r0b) + + gdouble w0 = bbox_visual.width(); // will return a value >= 0, as required further down the road + gdouble h0 = bbox_visual.height(); + + // We also know the width and height of the new visual bounding box + gdouble w1 = x1 - x0; // can have any sign + gdouble h1 = y1 - y0; + // The new visual bounding box will have strokes r1l, r1r, r1t, and r1b + + // We will now try to calculate the affine transformation required to transform the first visual bounding box into + // the second one, while accounting for strokewidth + gdouble r0w = w0 - bbox_geom.width(); // r0w is the average strokewidth of the left and right edges, i.e. 0.5*(r0l + r0r) + gdouble r0h = h0 - bbox_geom.height(); // r0h is the average strokewidth of the top and bottom edges, i.e. 0.5*(r0t + r0b) + + // Check whether the stroke is not negative; should not be possible, but just in case: + g_assert(r0w >= 0); + g_assert(r0h >= 0); + + if (bbox_visual.hasZeroArea()) { // Obviously we cannot scale from empty visual bounding boxes at all, so we will only translate in such a case + Geom::Affine move = Geom::Translate(x0 - bbox_visual.min()[Geom::X], y0 - bbox_visual.min()[Geom::Y]); + return (move); + } + + Geom::Affine direct = Geom::Scale(w1 / w0, h1 / h0); + + // Although the area of the visual bounding box is not zero, we can still have a geometric + // bounding box with one or both sides having zero length. We can't handle this and will therefore + // simply return the scaling of the visual bounding box, without accounting for any stroke scaling + if (fabs(w0 - r0w) < 1e-6 || fabs(h0 - r0h) < 1e-6 || (!transform_stroke && (fabs(w1 - r0w) < 1e-6 || fabs(h1 - r0h) < 1e-6))) { + return (p2o * direct * o2n); + } + + // Here starts the calculation you've been waiting for; first do some preparation + int flip_x = (w1 > 0) ? 1 : -1; + int flip_y = (h1 > 0) ? 1 : -1; + + // w1 and h1 will be negative when mirroring, but if so then e.g. w1-r0 won't make sense + // Therefore we will use the absolute values from this point on + w1 = fabs(w1); + h1 = fabs(h1); + // w0 and h0 will always be positive due to the definition of the width() and height() methods. + + gdouble ratio_x = (w1 - r0w) / (w0 - r0w); // Only valid when the stroke is kept constant, in which case r1 = r0 + gdouble ratio_y = (h1 - r0h) / (h0 - r0h); + + // Calculating the scaling of the geometric bounding box if the stroke is kept constant + Geom::Affine direct_constant_r = Geom::Scale(flip_x * ratio_x, flip_y * ratio_y); + + // The calculation of the new strokewidth will only use the average stroke for each of the dimensions; To find the new stroke for each + // of the edges individually though, we will use the boundary condition that the ratio of the left/right strokewidth will not change due to the + // scaling. The same holds for the ratio of the top/bottom strokewidth. + gdouble stroke_ratio_w = fabs(r0w) < 1e-6 ? 1 : (bbox_geom[Geom::X].min() - bbox_visual[Geom::X].min())/r0w; + gdouble stroke_ratio_h = fabs(r0h) < 1e-6 ? 1 : (bbox_geom[Geom::Y].min() - bbox_visual[Geom::Y].min())/r0h; + + // If the stroke is not kept constant however, the scaling of the geometric bbox is more difficult to find + if (transform_stroke && r0w != 0 && r0w != Geom::infinity() && r0h != 0 && r0h != Geom::infinity()) { // Check if there's stroke, and we need to scale it + /* Initial area of the geometric bounding box: A0 = (w0-r0w)*(h0-r0h) + * Desired area of the geometric bounding box: A1 = (w1-r1w)*(h1-r1h) + * This is how the stroke should scale: r1w^2 = A1/A0 * r0w^2, AND + * r1h^2 = A1/A0 * r0h^2 + * Now we have to solve this set of two equations and find r1w and r1h; this too complicated to do by hand, + * so I used wxMaxima for that (http://wxmaxima.sourceforge.net/). These lines can be copied into Maxima + * + * A1: (w1-r1w)*(h1-r1h); + * s: A1/A0; + * expr1a: r1w^2 = s*r0w^2; + * expr1b: r1h^2 = s*r0h^2; + * sol: solve([expr1a, expr1b], [r1h, r1w]); + * sol[1][1]; sol[2][1]; sol[3][1]; sol[4][1]; + * sol[1][2]; sol[2][2]; sol[3][2]; sol[4][2]; + * + * PS1: The last two lines are only needed for readability of the output, and can be omitted if desired + * PS2: A0 is known beforehand and assumed to be constant, instead of using A0 = (w0-r0w)*(h0-r0h). This reduces the + * length of the results significantly + * PS3: You'll get 8 solutions, 4 for each of the strokewidths r1w and r1h. Some experiments quickly showed which of the solutions + * lead to meaningful strokewidths + * */ + gdouble r0h2 = r0h*r0h; + gdouble r0h3 = r0h2*r0h; + gdouble r0w2 = r0w*r0w; + gdouble w12 = w1*w1; + gdouble h12 = h1*h1; + gdouble A0 = bbox_geom.area(); + gdouble A02 = A0*A0; + + gdouble operant = 4*h1*w1*A0+r0h2*w12-2*h1*r0h*r0w*w1+h12*r0w2; + if (operant >= 0) { + // Of the eight roots, I verified experimentally that these are the two we need + gdouble r1h= fabs((r0h*sqrt(operant)-r0h2*w1-h1*r0h*r0w)/(2*A0-2*r0h*r0w)); + gdouble r1w= fabs(-((h1*r0w*A0+r0h2*r0w*w1)*sqrt(operant)+(-3*h1*r0h*r0w*w1-h12*r0w2)*A0-r0h3*r0w*w12+h1*r0h2*r0w2*w1)/((r0h*A0-r0h2*r0w)*sqrt(operant)-2*h1*A02+(3*h1*r0h*r0w-r0h2*w1)*A0+r0h3*r0w*w1-h1*r0h2*r0w2)); + // If w1 < 0 then the scale will be wrong if we just assume that scale_x = (w1 - r1)/(w0 - r0); + // Therefore we here need the absolute values of w0, w1, h0, h1, and r0, as taken care of earlier + gdouble scale_x = (w1 - r1w)/(w0 - r0w); + gdouble scale_y = (h1 - r1h)/(h0 - r0h); + // Now we account for mirroring by flipping if needed + scale *= Geom::Scale(flip_x * scale_x, flip_y * scale_y); + // Make sure that the lower-left corner of the visual bounding box stays where it is, even though the stroke width has changed + unbudge *= Geom::Translate (-flip_x * stroke_ratio_w * (r0w * scale_x - r1w), -flip_y * stroke_ratio_h * (r0h * scale_y - r1h)); + } else { // Can't find the roots of the quadratic equation. Likely the input parameters are invalid? + scale *= direct; + } + } else { // The stroke should not be scaled, or is zero (or infinite) + if (r0w == 0 || r0w == Geom::infinity() || r0h == 0 || r0h == Geom::infinity()) { // can't calculate, because apparently strokewidth is zero or infinite + scale *= direct; + } else { + scale *= direct_constant_r; + unbudge *= Geom::Translate (flip_x * stroke_ratio_w * r0w * (1 - ratio_x), flip_y * stroke_ratio_h * r0h * (1 - ratio_y)); + } + } + + return (p2o * scale * unbudge * o2n); +} + Geom::Rect get_visual_bbox (Geom::OptRect const &initial_geom_bbox, Geom::Affine const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke) { - g_assert(initial_geom_bbox); // Find the new geometric bounding box; Do this by transforming each corner of diff --git a/src/sp-item-transform.h b/src/sp-item-transform.h index 552b23e2f..47e0ec0ec 100644 --- a/src/sp-item-transform.h +++ b/src/sp-item-transform.h @@ -9,7 +9,8 @@ void sp_item_scale_rel (SPItem *item, Geom::Scale const &scale); void sp_item_skew_rel (SPItem *item, double skewX, double skewY); void sp_item_move_rel(SPItem *item, Geom::Translate const &tr); -Geom::Affine get_scale_transform_with_stroke (Geom::Rect const &bbox, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1); +Geom::Affine get_scale_transform_with_uniform_stroke (Geom::Rect const &bbox_visual, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1); +Geom::Affine get_scale_transform_with_unequal_stroke (Geom::Rect const &bbox_visual, Geom::Rect const &bbox_geom, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1); Geom::Rect get_visual_bbox (Geom::OptRect const &initial_geom_bbox, Geom::Affine const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke); diff --git a/src/sp-object-repr.cpp b/src/sp-object-repr.cpp index c6d6729cc..b40017e65 100644 --- a/src/sp-object-repr.cpp +++ b/src/sp-object-repr.cpp @@ -55,7 +55,7 @@ #include "sp-style-elem.h" #include "sp-switch.h" -#include "color-profile-fns.h" +#include "color-profile.h" #include "xml/repr.h" #include "sp-filter.h" #include "filters/blend.h" diff --git a/src/sp-object.cpp b/src/sp-object.cpp index e0b3e3201..c12b9344b 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -39,7 +39,7 @@ #include "helper/sp-marshal.h" #include "xml/node-event-vector.h" #include "attributes.h" -#include "color-profile-fns.h" +#include "color-profile.h" #include "document.h" #include "style.h" #include "sp-object-repr.h" diff --git a/src/style.cpp b/src/style.cpp index e66c15494..44d2b0761 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -6,6 +6,7 @@ * Peter Moulder <pmoulder@mail.csse.monash.edu.au> * bulia byak <buliabyak@users.sf.net> * Abhishek Sharma + * Tavmjong Bah <tavmjong@free.fr> * * Copyright (C) 2001-2002 Lauris Kaplinski * Copyright (C) 2001 Ximian, Inc. @@ -919,8 +920,137 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val) style->text->font.value = g_strdup(val); style->text->font.set = TRUE; style->text->font.inherit = (val && !strcmp(val, "inherit")); + + // Break string into white space separated tokens + std::stringstream os( val ); + Glib::ustring param; + + while (os >> param) { + + // CSS is case insensitive but we're comparing against lowercase strings + Glib::ustring lparam = param.lowercase(); + + if (lparam == "/") { + + os >> param; + // Eat the line-height for the moment as it is not an SVG property. + // lparam = param.lowercase(); + // sp_style_read_ilengthornormal(&style->line_height, lparam); + + } else { + + // Skip if "normal" as that is the default (and we don't know which attribute it applies to). + if (lparam == "normal") continue; + + // Check each property in turn + + // font-style + SPIEnum test_style; + test_style.set = FALSE; + + // Read once to see if param is valid style. If valid, .set will be TRUE. + sp_style_read_ienum(&test_style, lparam.c_str(), enum_font_style, true); + + // If valid style parameter + if (test_style.set) { + + // If not previously set + if (!style->font_style.set) { + style->font_style.set = TRUE; + style->font_style.inherit = test_style.inherit; + style->font_style.value = test_style.value; + style->font_style.computed = test_style.computed; + } + continue; // Next parameter. + } + + // font-variant (small-caps) + SPIEnum test_variant; + test_variant.set = FALSE; + sp_style_read_ienum(&test_variant, lparam.c_str(), enum_font_variant, true); + + // If valid variant parameter + if (test_variant.set) { + + // If not previously set + if (!style->font_variant.set) { + style->font_variant.set = TRUE; + style->font_variant.inherit = test_variant.inherit; + style->font_variant.value = test_variant.value; + style->font_variant.computed = test_variant.computed; + } + continue; // Next parameter. + } + + // font-weight + SPIEnum test_weight; + test_weight.set = FALSE; + sp_style_read_ienum(&test_weight, lparam.c_str(), enum_font_weight, true); + + // If valid weight parameter + if (test_weight.set) { + + // If not previously set + if (!style->font_weight.set) { + style->font_weight.set = TRUE; + style->font_weight.inherit = test_weight.inherit; + style->font_weight.value = test_weight.value; + style->font_weight.computed = test_weight.computed; + } + continue; // Next parameter + } + + // Font-size + SPIFontSize test_size; + test_size.set = FALSE; + + // Read once to see if param is valid size. + sp_style_read_ifontsize( &test_size, lparam.c_str() ); + + // If valid size parameter + if (test_size.set) { + + // If not previously set + if (!style->font_size.set) { + style->font_size.set = TRUE; + style->font_size.inherit = test_size.inherit; + style->font_size.unit = test_size.unit; + style->font_size.value = test_size.value; + style->font_size.computed = test_size.computed; + style->font_size.type = test_size.type; + style->font_size.literal = test_size.literal; + } + continue; + } + + // No valid property value found. + break; + } + } // params + + // The rest must be font-family... + std::string val_s = val; + std::string family = val_s.substr( val_s.find( param ) ); + + if (!style->text_private) sp_style_privatize_text(style); + if (!style->text->font_family.set) { + gchar *val_unquoted = attribute_unquote( family.c_str() ); + sp_style_read_istring(&style->text->font_family, val_unquoted); + if (val_unquoted) g_free (val_unquoted); + } + + // Set all properties to their default values per CSS 2.1 spec if not already set + SPS_READ_IFONTSIZE_IF_UNSET(&style->font_size, "medium" ); + SPS_READ_IENUM_IF_UNSET(&style->font_style, "normal", enum_font_style, true); + SPS_READ_IENUM_IF_UNSET(&style->font_variant, "normal", enum_font_variant, true); + SPS_READ_IENUM_IF_UNSET(&style->font_weight, "normal", enum_font_weight, true); + // Line height is not an SVG property but Inkscape uses it for multi-line text. + // sp_style_read_ilengthornormal(&style->line_height, "normal"); + } + break; + /* Text */ case SP_PROP_TEXT_INDENT: SPS_READ_ILENGTH_IF_UNSET(&style->text_indent, val); @@ -1353,11 +1483,11 @@ sp_style_merge_font_size_from_parent(SPIFontSize &child, SPIFontSize const &pare * fixme: SVG and CSS do not specify clearly, whether we should use * user or screen coordinates (Lauris) */ - if (child.value < SP_CSS_FONT_SIZE_SMALLER) { - child.computed = font_size_table[child.value]; - } else if (child.value == SP_CSS_FONT_SIZE_SMALLER) { + if (child.literal < SP_CSS_FONT_SIZE_SMALLER) { + child.computed = font_size_table[child.literal]; + } else if (child.literal == SP_CSS_FONT_SIZE_SMALLER) { child.computed = parent.computed / 1.2; - } else if (child.value == SP_CSS_FONT_SIZE_LARGER) { + } else if (child.literal == SP_CSS_FONT_SIZE_LARGER) { child.computed = parent.computed * 1.2; } else { /* Illegal value */ @@ -1365,7 +1495,21 @@ sp_style_merge_font_size_from_parent(SPIFontSize &child, SPIFontSize const &pare } else if (child.type == SP_FONT_SIZE_PERCENTAGE) { /* Unlike most other lengths, percentage for font size is relative to parent computed value * rather than viewport. */ - child.computed = parent.computed * SP_F8_16_TO_FLOAT(child.value); + child.computed = parent.computed * child.value; + } else if (child.type == SP_FONT_SIZE_LENGTH) { + switch (child.unit) { + case SP_CSS_UNIT_EM: + /* Relative to parent font size */ + child.computed = parent.computed * child.value; + break; + case SP_CSS_UNIT_EX: + /* Relative to parent font size */ + child.computed = parent.computed * child.value * 0.5; /* Hack */ + break; + default: + /* No change */ + break; + } } } @@ -1805,7 +1949,7 @@ get_relative_font_size_frac(SPIFontSize const &font_size) { switch (font_size.type) { case SP_FONT_SIZE_LITERAL: { - switch (font_size.value) { + switch (font_size.literal) { case SP_CSS_FONT_SIZE_SMALLER: return 5.0 / 6.0; @@ -1818,10 +1962,20 @@ get_relative_font_size_frac(SPIFontSize const &font_size) } case SP_FONT_SIZE_PERCENTAGE: - return SP_F8_16_TO_FLOAT(font_size.value); + return font_size.value; + + case SP_FONT_SIZE_LENGTH: { + switch (font_size.unit ) { + case SP_CSS_UNIT_EM: + return font_size.value; - case SP_FONT_SIZE_LENGTH: - g_assert_not_reached(); + case SP_CSS_UNIT_EX: + return font_size.value * 0.5; + + default: + g_assert_not_reached(); + } + } } g_assert_not_reached(); } @@ -1868,20 +2022,29 @@ sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const pare { /* font-size. Note that we update the computed font-size of style, to assist in em calculations later in this function. */ + if (parent->font_size.set && !parent->font_size.inherit) { + /* Parent has defined font-size */ + if (!style->font_size.set || style->font_size.inherit) { /* font_size inherits the computed value, so we can use the parent value * verbatim. */ style->font_size = parent->font_size; - } else if ( style->font_size.type == SP_FONT_SIZE_LENGTH ) { + + } else if ( style->font_size.type == SP_FONT_SIZE_LENGTH && + style->font_size.unit != SP_CSS_UNIT_EM && + style->font_size.unit != SP_CSS_UNIT_EX ) { + /* Child already has absolute size (stored in computed value), so do nothing. */ + } else if ( style->font_size.type == SP_FONT_SIZE_LITERAL - && style->font_size.value < SP_CSS_FONT_SIZE_SMALLER ) { + && style->font_size.literal < SP_CSS_FONT_SIZE_SMALLER ) { /* Child already has absolute size, but we ensure that the computed value is up-to-date. */ - unsigned const ix = style->font_size.value; + unsigned const ix = style->font_size.literal; g_assert(ix < G_N_ELEMENTS(font_size_table)); style->font_size.computed = font_size_table[ix]; + } else { /* Child has relative size. */ double const child_frac(get_relative_font_size_frac(style->font_size)); @@ -1890,17 +2053,26 @@ sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const pare style->font_size.computed = parent->font_size.computed * child_frac; if ( ( parent->font_size.type == SP_FONT_SIZE_LITERAL - && parent->font_size.value < SP_CSS_FONT_SIZE_SMALLER ) - || parent->font_size.type == SP_FONT_SIZE_LENGTH ) - { + && parent->font_size.literal < SP_CSS_FONT_SIZE_SMALLER ) || + ( parent->font_size.type == SP_FONT_SIZE_LENGTH && + parent->font_size.unit != SP_CSS_UNIT_EM && + parent->font_size.unit != SP_CSS_UNIT_EX ) ) { + /* Absolute value. */ style->font_size.type = SP_FONT_SIZE_LENGTH; - /* .value is unused for SP_FONT_SIZE_LENGTH. */ + /* .value is unused for non ex/em SP_FONT_SIZE_LENGTH. */ + } else { /* Relative value. */ + double const parent_frac(get_relative_font_size_frac(parent->font_size)); - style->font_size.type = SP_FONT_SIZE_PERCENTAGE; - style->font_size.value = SP_F8_16_FROM_FLOAT(parent_frac * child_frac); + if( style->font_size.type == SP_FONT_SIZE_LENGTH ) { + /* Value in terms of ex/em */ + style->font_size.value *= parent_frac; + } else { + style->font_size.value = parent_frac * child_frac; + style->font_size.type = SP_FONT_SIZE_PERCENTAGE; + } } } } @@ -2697,7 +2869,7 @@ sp_style_clear(SPStyle *style) style->font_size.set = FALSE; style->font_size.type = SP_FONT_SIZE_LITERAL; - style->font_size.value = SP_CSS_FONT_SIZE_MEDIUM; + style->font_size.literal = SP_CSS_FONT_SIZE_MEDIUM; style->font_size.computed = 12.0; style->font_style.set = FALSE; style->font_style.value = style->font_style.computed = SP_CSS_FONT_STYLE_NORMAL; @@ -3030,6 +3202,7 @@ sp_style_read_ienum(SPIEnum *val, gchar const *str, SPStyleEnum const *dict, } } } + return; } @@ -3088,9 +3261,8 @@ sp_style_read_ilength(SPILength *val, gchar const *str) val->unit = SP_CSS_UNIT_PT; val->computed = value * PX_PER_PT; } else if (!strcmp(e, "pc")) { - /* 1 pica = 12pt; FIXME: add it to SPUnit */ val->unit = SP_CSS_UNIT_PC; - val->computed = value * PX_PER_PT * 12; + val->computed = value * PX_PER_PC; } else if (!strcmp(e, "mm")) { val->unit = SP_CSS_UNIT_MM; val->computed = value * PX_PER_MM; @@ -3306,52 +3478,29 @@ sp_style_read_ifontsize(SPIFontSize *val, gchar const *str) val->set = TRUE; val->inherit = FALSE; val->type = SP_FONT_SIZE_LITERAL; - val->value = enum_font_size[i].value; + val->literal = enum_font_size[i].value; return; } } /* Invalid */ return; } else { - gdouble value; - gchar *e; - /* fixme: Move this to standard place (Lauris) */ - value = g_ascii_strtod(str, &e); - if ((gchar const *) e != str) { - if (!*e) { - /* Userspace */ - } else if (!strcmp(e, "px")) { - /* Userspace */ - } else if (!strcmp(e, "pt")) { - /* Userspace * DEVICESCALE */ - value *= PX_PER_PT; - } else if (!strcmp(e, "pc")) { - /* 12pt */ - value *= PX_PER_PT * 12.0; - } else if (!strcmp(e, "mm")) { - value *= PX_PER_MM; - } else if (!strcmp(e, "cm")) { - value *= PX_PER_CM; - } else if (!strcmp(e, "in")) { - value *= PX_PER_IN; - } else if (!strcmp(e, "%")) { - /* Percentage */ - val->set = TRUE; - val->inherit = FALSE; + SPILength length; + length.set = FALSE; + sp_style_read_ilength(&length, str); + if( length.set ) { + val->set = TRUE; + val->inherit = length.inherit; + val->unit = length.unit; + val->value = length.value; + val->computed = length.computed; + if( val->unit == SP_CSS_UNIT_PERCENT ) { val->type = SP_FONT_SIZE_PERCENTAGE; - val->value = SP_F8_16_FROM_FLOAT(value / 100.0); - return; } else { - /* Invalid */ - return; + val->type = SP_FONT_SIZE_LENGTH; } - /* Length */ - val->set = TRUE; - val->inherit = FALSE; - val->type = SP_FONT_SIZE_LENGTH; - val->computed = value; - return; } + return; } } @@ -3957,7 +4106,7 @@ sp_style_write_ifontsize(gchar *p, gint const len, gchar const *key, return g_strlcpy(p, os.str().c_str(), len); } else if (val->type == SP_FONT_SIZE_PERCENTAGE) { Inkscape::CSSOStringStream os; - os << key << ":" << (SP_F8_16_TO_FLOAT(val->value) * 100.0) << "%;"; + os << key << ":" << (val->value * 100.0) << "%;"; return g_strlcpy(p, os.str().c_str(), len); } } diff --git a/src/style.h b/src/style.h index 3ca1d4dbc..b8b3d6c0d 100644 --- a/src/style.h +++ b/src/style.h @@ -206,21 +206,24 @@ enum { SP_BASELINE_SHIFT_PERCENTAGE }; -#define SP_FONT_SIZE ((1 << 24) - 1) - +/* +Not used anymore, originally for SPIFontSize #define SP_F8_16_TO_FLOAT(v) ((gdouble) (v) / (1 << 16)) #define SP_F8_16_FROM_FLOAT(v) ((int) ((v) * ((1 << 16) + 0.9999))) +*/ #define SP_STYLE_FLAG_IFSET (1 << 0) #define SP_STYLE_FLAG_IFDIFF (1 << 1) #define SP_STYLE_FLAG_ALWAYS (1 << 2) -/// Fontsize type internal to SPStyle. +/// Fontsize type internal to SPStyle (also used by libnrtype/Layout-TNG-Input.cpp). struct SPIFontSize { unsigned set : 1; unsigned inherit : 1; unsigned type : 2; - unsigned value : 24; + unsigned unit : 4; + unsigned literal: 4; + float value; float computed; }; diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index e50cb2928..9293564d5 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -1,5 +1,3 @@ -#define __SP_SVG_COLOR_C__ - /** * \file * Reading \& writing of SVG/CSS colors. @@ -37,15 +35,16 @@ #include "svg-icc-color.h" #if ENABLE_LCMS -#include <lcms.h> #include "color.h" #include "color-profile.h" #include "document.h" #include "inkscape.h" #include "profile-manager.h" #endif // ENABLE_LCMS +#include "cms-system.h" using std::sprintf; +using Inkscape::CMSSystem; struct SPSVGColor { unsigned long rgb; @@ -465,7 +464,7 @@ sp_svg_create_color_hash() #if ENABLE_LCMS //helper function borrowed from src/widgets/sp-color-icc-selector.cpp: -void getThings( DWORD space, gchar const**& namers, gchar const**& tippies, guint const*& scalies ); +void getThings( Inkscape::ColorProfile *prof, gchar const**& namers, gchar const**& tippies, guint const*& scalies ); void icc_color_to_sRGB(SVGICCColor* icc, guchar* r, guchar* g, guchar* b){ guchar color_out[4]; @@ -479,16 +478,18 @@ g_message("profile name: %s", icc->colorProfile.c_str()); gchar const** names = 0; gchar const** tips = 0; guint const* scales = 0; - getThings( prof->getColorSpace(), names, tips, scales ); + getThings( prof, names, tips, scales ); - guint count = _cmsChannelsOf( prof->getColorSpace() ); - if (count>4) count=4; //do we need it? Should we allow an arbitrary number of color values? Or should we limit to a maximum? (max==4?) - for (guint i=0;i<count; i++){ + gint count = CMSSystem::getChannelCount( prof ); + if (count > 4) { + count = 4; //do we need it? Should we allow an arbitrary number of color values? Or should we limit to a maximum? (max==4?) + } + for (gint i = 0; i < count; i++){ color_in[i] = (guchar) ((((gdouble)icc->colors[i])*256.0) * (gdouble)scales[i]); g_message("input[%d]: %d",i, color_in[i]); } - cmsDoTransform( trans, color_in, color_out, 1 ); + CMSSystem::doTransform( trans, color_in, color_out, 1 ); g_message("transform to sRGB done"); } *r = color_out[0]; diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 9bbdd861e..1a662f3be 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -159,7 +159,6 @@ set(ui_SRC dialog/print-colors-preview-dialog.h dialog/print.h dialog/scriptdialog.h - dialog/session-player.h dialog/svg-fonts-dialog.h dialog/swatches.h dialog/tile.h diff --git a/src/ui/cache/svg_preview_cache.cpp b/src/ui/cache/svg_preview_cache.cpp index c631631fb..cd1d65ba7 100644 --- a/src/ui/cache/svg_preview_cache.cpp +++ b/src/ui/cache/svg_preview_cache.cpp @@ -80,8 +80,7 @@ GdkPixbuf* render_pixbuf(NRArenaItem* root, double scale_factor, const Geom::Rec GDK_COLORSPACE_RGB, TRUE, 8, psize, psize, cairo_image_surface_get_stride(s), - (GdkPixbufDestroyNotify)cairo_surface_destroy, - NULL); + ink_cairo_pixbuf_cleanup, s); convert_pixbuf_argb32_to_normal(pixbuf); return pixbuf; diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index 89245575c..598827da9 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -225,7 +225,7 @@ static void colorItemDragBegin( GtkWidget */*widget*/, GdkDragContext* dc, gpoin pixbuf = gdk_pixbuf_new_from_data(cairo_image_surface_get_data(s), GDK_COLORSPACE_RGB, TRUE, 8, width, height, cairo_image_surface_get_stride(s), - (GdkPixbufDestroyNotify) cairo_surface_destroy, NULL); + ink_cairo_pixbuf_cleanup, s); convert_pixbuf_argb32_to_normal(pixbuf); } else { Glib::RefPtr<Gdk::Pixbuf> thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, width, height ); @@ -517,11 +517,13 @@ void ColorItem::_regenPreview(EekPreview * preview) (def.getG() << 8) | def.getG(), (def.getB() << 8) | def.getB() ); } else { - double w; - cairo_pattern_get_linear_points(_pattern, NULL, NULL, &w, NULL); - int width = ceil(w); + // These correspond to PREVIEW_PIXBUF_WIDTH and VBLOCK from swatches.cpp + // TODO: the pattern to draw should be in the widget that draws the preview, + // so the preview can be scalable + int w = 128; + int h = 16; - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, 1); + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); cairo_t *ct = cairo_create(s); cairo_set_source(ct, _pattern); cairo_paint(ct); @@ -530,8 +532,8 @@ void ColorItem::_regenPreview(EekPreview * preview) GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( cairo_image_surface_get_data(s), GDK_COLORSPACE_RGB, TRUE, 8, - width, 1, cairo_image_surface_get_stride(s), - (GdkPixbufDestroyNotify) cairo_surface_destroy, NULL); + w, h, cairo_image_surface_get_stride(s), + ink_cairo_pixbuf_cleanup, s); convert_pixbuf_argb32_to_normal(pixbuf); eek_preview_set_pixbuf( preview, pixbuf ); } diff --git a/src/ui/dialog/dock-behavior.h b/src/ui/dialog/dock-behavior.h index b865af545..98c111719 100644 --- a/src/ui/dialog/dock-behavior.h +++ b/src/ui/dialog/dock-behavior.h @@ -21,7 +21,7 @@ #include "ui/widget/dock-item.h" -#include "libgdl/libgdl.h" +#include "libgdl/gdl.h" #include "behavior.h" diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 569dd2311..5d32839cb 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -43,8 +43,6 @@ #include "xml/repr.h" #if ENABLE_LCMS -#include <lcms.h> -//#include "color-profile-fns.h" #include "color-profile.h" #endif // ENABLE_LCMS @@ -309,53 +307,29 @@ DocumentProperties::build_snap() } #if ENABLE_LCMS -static void -lcms_profile_get_name (cmsHPROFILE profile, const gchar **name) -{ - if (profile) - { - *name = cmsTakeProductDesc (profile); - - if (! *name) - *name = cmsTakeProductName (profile); - - if (*name && ! g_utf8_validate (*name, -1, NULL)) - *name = _("(invalid UTF-8 string)"); - } - else - { - *name = _("None"); - } -} - -void -DocumentProperties::populate_available_profiles(){ +void DocumentProperties::populate_available_profiles(){ Glib::ListHandle<Gtk::Widget*> children = _menu.get_children(); for ( Glib::ListHandle<Gtk::Widget*>::iterator it2 = children.begin(); it2 != children.end(); ++it2 ) { _menu.remove(**it2); delete(*it2); } - std::list<Glib::ustring> files = ColorProfile::getProfileFiles(); - for ( std::list<Glib::ustring>::const_iterator it = files.begin(); it != files.end(); ++it ) { - cmsHPROFILE hProfile = cmsOpenProfileFromFile(it->c_str(), "r"); - if ( hProfile ){ - const gchar* name = 0; - lcms_profile_get_name(hProfile, &name); - Gtk::MenuItem* mi = manage(new Gtk::MenuItem()); - mi->set_data("filepath", g_strdup(it->c_str())); - mi->set_data("name", g_strdup(name)); - Gtk::HBox *hbox = manage(new Gtk::HBox()); - hbox->show(); - Gtk::Label* lbl = manage(new Gtk::Label(name)); - lbl->show(); - hbox->pack_start(*lbl, true, true, 0); - mi->add(*hbox); - mi->show_all(); - _menu.append(*mi); -// g_free((void*)name); - cmsCloseProfile(hProfile); - } + std::vector<std::pair<Glib::ustring, Glib::ustring> > pairs = ColorProfile::getProfileFilesWithNames(); + for ( std::vector<std::pair<Glib::ustring, Glib::ustring> >::const_iterator it = pairs.begin(); it != pairs.end(); ++it ) { + Glib::ustring file = it->first; + Glib::ustring name = it->second; + + Gtk::MenuItem* mi = manage(new Gtk::MenuItem()); + mi->set_data("filepath", g_strdup(file.c_str())); + mi->set_data("name", g_strdup(name.c_str())); + Gtk::HBox *hbox = manage(new Gtk::HBox()); + hbox->show(); + Gtk::Label* lbl = manage(new Gtk::Label(name)); + lbl->show(); + hbox->pack_start(*lbl, true, true, 0); + mi->add(*hbox); + mi->show_all(); + _menu.append(*mi); } _menu.show_all(); diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index c6d81b070..68cf3b505 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -965,10 +965,10 @@ public: _settings.add_spinslider(0, SP_ATTR_ELEVATION, _("Elevation"), 0, 360, 1, 1, 0, _("Direction angle for the light source on the YZ plane, in degrees")); _settings.type(LIGHT_POINT); - _settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_X, SP_ATTR_Y, SP_ATTR_Z, _("Location"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate")); + _settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_X, SP_ATTR_Y, SP_ATTR_Z, _("Location:"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate")); _settings.type(LIGHT_SPOT); - _settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_X, SP_ATTR_Y, SP_ATTR_Z, _("Location"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate")); + _settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_X, SP_ATTR_Y, SP_ATTR_Z, _("Location:"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate")); _settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_POINTSATX, SP_ATTR_POINTSATY, SP_ATTR_POINTSATZ, _("Points At"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate")); diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 3c272e691..d11ffd565 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -41,7 +41,7 @@ #include "ui/widget/spinbutton.h" #include "display/nr-filter-gaussian.h" #include "display/nr-filter-types.h" -#include "color-profile-fns.h" +#include "cms-system.h" #include "color-profile.h" #include "display/canvas-grid.h" #include "path-prefix.h" @@ -62,6 +62,7 @@ using Inkscape::UI::Widget::PrefCheckButton; using Inkscape::UI::Widget::PrefRadioButton; using Inkscape::UI::Widget::PrefSpinButton; using Inkscape::UI::Widget::StyleSwatch; +using Inkscape::CMSSystem; InkscapePreferences::InkscapePreferences() @@ -858,7 +859,7 @@ static void profileComboChanged( Gtk::ComboBoxText* combo ) } else { Glib::ustring active = combo->get_active_text(); - Glib::ustring path = get_path_for_profile(active); + Glib::ustring path = CMSSystem::getPathForProfile(active); if ( !path.empty() ) { prefs->setString("/options/displayprofile/uri", path); } @@ -868,7 +869,7 @@ static void profileComboChanged( Gtk::ComboBoxText* combo ) static void proofComboChanged( Gtk::ComboBoxText* combo ) { Glib::ustring active = combo->get_active_text(); - Glib::ustring path = get_path_for_profile(active); + Glib::ustring path = CMSSystem::getPathForProfile(active); if ( !path.empty() ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -906,8 +907,8 @@ void InkscapePreferences::initPageCMS() _page_cms.add_group_header( _("Display adjustment")); Glib::ustring tmpStr; - std::list<Glib::ustring> sources = ColorProfile::getBaseProfileDirs(); - for ( std::list<Glib::ustring>::const_iterator it = sources.begin(); it != sources.end(); ++it ) { + std::vector<Glib::ustring> sources = ColorProfile::getBaseProfileDirs(); + for ( std::vector<Glib::ustring>::const_iterator it = sources.begin(); it != sources.end(); ++it ) { gchar* part = g_strdup_printf( "\n%s", it->c_str() ); tmpStr += part; g_free(part); @@ -975,7 +976,7 @@ void InkscapePreferences::initPageCMS() #if ENABLE_LCMS { - std::vector<Glib::ustring> names = ::Inkscape::colorprofile_get_display_names(); + std::vector<Glib::ustring> names = ::Inkscape::CMSSystem::getDisplayNames(); Glib::ustring current = prefs->getString( "/options/displayprofile/uri" ); gint index = 0; @@ -983,7 +984,7 @@ void InkscapePreferences::initPageCMS() index++; for ( std::vector<Glib::ustring>::iterator it = names.begin(); it != names.end(); ++it ) { _cms_display_profile.append_text( *it ); - Glib::ustring path = get_path_for_profile(*it); + Glib::ustring path = CMSSystem::getPathForProfile(*it); if ( !path.empty() && path == current ) { _cms_display_profile.set_active(index); } @@ -993,12 +994,12 @@ void InkscapePreferences::initPageCMS() _cms_display_profile.set_active(0); } - names = ::Inkscape::colorprofile_get_softproof_names(); + names = ::Inkscape::CMSSystem::getSoftproofNames(); current = prefs->getString("/options/softproof/uri"); index = 0; for ( std::vector<Glib::ustring>::iterator it = names.begin(); it != names.end(); ++it ) { _cms_proof_profile.append_text( *it ); - Glib::ustring path = get_path_for_profile(*it); + Glib::ustring path = CMSSystem::getPathForProfile(*it); if ( !path.empty() && path == current ) { _cms_proof_profile.set_active(index); } diff --git a/src/ui/dialog/session-player.cpp b/src/ui/dialog/session-player.cpp deleted file mode 100644 index 040c1419b..000000000 --- a/src/ui/dialog/session-player.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/** @file - * @brief Whiteboard session playback control dialog - implementation - */ -/* Authors: - * David Yip <yipdw@rose-hulman.edu> - * Abhishek Sharma - * - * Copyright (c) 2005 Authors - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <glibmm.h> -#include <glibmm/i18n.h> -#include <gtk/gtk.h> -#include <gtkmm.h> - -#include "inkscape.h" -#include "path-prefix.h" - -#include "desktop.h" -#include "desktop-handles.h" -#include "document.h" - -#include "jabber_whiteboard/node-tracker.h" -#include "jabber_whiteboard/session-manager.h" -#include "jabber_whiteboard/session-file-player.h" - -#include "ui/dialog/session-player.h" - -#include "util/ucompose.hpp" - -namespace Inkscape { - -namespace UI { - -namespace Dialog { - -SessionPlaybackDialog* -SessionPlaybackDialog::create() -{ - return new SessionPlaybackDialogImpl(); -} - -SessionPlaybackDialogImpl::SessionPlaybackDialogImpl() - : _delay(100, 1, 5000, 10, 100), _delayentry(_delay) -{ - this->_desktop = this->getDesktop(); - this->_sm = this->_desktop->whiteboard_session_manager(); - this->_sfp = this->_sm->session_player(); - this->_openfile.set_text(this->_sfp->filename()); - - this->_construct(); - this->get_vbox()->show_all_children(); -} - -SessionPlaybackDialogImpl::~SessionPlaybackDialogImpl() -{ - -} - -void -SessionPlaybackDialogImpl::_construct() -{ - Gtk::VBox* main = this->get_vbox(); - - // Dialog organization - this->_filemanager.set_label(_("Session file")); - this->_playback.set_label(_("Playback controls")); - this->_currentmsgbox.set_label(_("Message information")); - - this->_filemanager.set_border_width(4); - this->_playback.set_border_width(4); - this->_fm.set_border_width(4); - this->_toolbarbox.set_border_width(4); - - // Active session file display - // fixme: Does this mean the active file for the session, or the file for the active session? - // Please indicate which with a TRANSLATORS comment. - this->_labels[0].set_text(_("Active session file:")); - this->_labels[1].set_text(_("Delay (milliseconds):")); - - this->_openfile.set_editable(false); - - this->_filebox.pack_start(this->_labels[0], true, false, 8); - this->_filebox.pack_end(this->_openfile, true, true, 0); - - // Unload/load buttons - this->_close.set_label(_("Close file")); - this->_open.set_label(_("Open new file")); - this->_setdelay.set_label(_("Set delay")); - - // Attach callbacks - this->_close.signal_clicked().connect(sigc::bind< 0 >(sigc::mem_fun(*this, &SessionPlaybackDialogImpl::_respCallback), CLOSE_FILE)); - this->_open.signal_clicked().connect(sigc::bind< 0 >(sigc::mem_fun(*this, &SessionPlaybackDialogImpl::_respCallback), OPEN_FILE)); - this->_setdelay.signal_clicked().connect(sigc::bind< 0 >(sigc::mem_fun(*this, &SessionPlaybackDialogImpl::_respCallback), RESET_DELAY)); - - // Button box - this->_filebuttons.pack_start(this->_close, true, false, 0); - this->_filebuttons.pack_start(this->_open, true, false, 0); - - // Message information box - this->_currentmsgbuffer = Gtk::TextBuffer::create(); - this->_currentmsgview.set_buffer(this->_currentmsgbuffer); - this->_currentmsgview.set_editable(false); - this->_currentmsgview.set_cursor_visible(false); - this->_currentmsgview.set_wrap_mode(Gtk::WRAP_WORD); - this->_currentmsgscroller.add(this->_currentmsgview); - this->_currentmsgbox.add(this->_currentmsgscroller); - this->_sfp->setMessageOutputWidget(this->_currentmsgbuffer); - - // Delay setting - // parameters: initial lower upper single-incr page-incr - this->_delayentry.set_numeric(true); - - // Playback controls - this->_playbackcontrols.set_show_arrow(false); - - this->_controls[0].set_label("Rewind"); - this->_controls[1].set_label("Go back one"); - this->_controls[2].set_label("Pause"); - this->_controls[3].set_label("Go forward one"); - this->_controls[4].set_label("Play"); - - this->_controls[0].set_tooltip(this->_tooltips, _("Rewind")); - this->_controls[1].set_tooltip(this->_tooltips, _("Go back one change")); - this->_controls[2].set_tooltip(this->_tooltips, _("Pause")); - this->_controls[3].set_tooltip(this->_tooltips, _("Go forward one change")); - this->_controls[4].set_tooltip(this->_tooltips, _("Play")); - - for(int i = 0; i < 5; i++) { - this->_playbackcontrols.append(this->_controls[i], sigc::bind< 0 >(sigc::mem_fun(*this, &SessionPlaybackDialogImpl::_respCallback), TOOLBAR_BASE + i)); - } - - this->_delaybox.pack_start(this->_labels[1]); - this->_delaybox.pack_start(this->_delayentry); - this->_delaybox.pack_end(this->_setdelay); - - this->_toolbarbox.pack_start(this->_delaybox); - this->_toolbarbox.pack_end(this->_playbackcontrols); - - // Pack widgets into frames - this->_fm.pack_start(this->_filebox); - this->_fm.pack_end(this->_filebuttons); - - this->_filemanager.add(this->_fm); - this->_playback.add(this->_toolbarbox); - - // Pack widgets into main vbox - main->pack_start(this->_filemanager); - main->pack_start(this->_playback); - main->pack_end(this->_currentmsgbox); -} - -void -SessionPlaybackDialogImpl::_respCallback(int resp) -{ - g_log(NULL, G_LOG_LEVEL_DEBUG, "_respCallback: %u", resp); - switch(resp) { - case CLOSE_FILE: - this->_sfp->unload(); - break; - case OPEN_FILE: { - Gtk::FileChooserDialog sessionfiledlg(_("Open session file"), Gtk::FILE_CHOOSER_ACTION_OPEN); - sessionfiledlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - sessionfiledlg.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); - - int result = sessionfiledlg.run(); - switch (result) { - case Gtk::RESPONSE_OK: - this->_sm->clearDocument(); - SPDocumentUndo::done(sp_desktop_document(this->_desktop), SP_VERB_NONE, - /* TODO: annotate */ "session-player.cpp:186"); - this->_sm->loadSessionFile(sessionfiledlg.get_filename()); - this->_openfile.set_text(this->_sfp->filename()); - break; - default: - break; - } - break; - } - case RESET_DELAY: - this->_sfp->setDelay(this->_delayentry.get_value_as_int()); - break; - case REWIND: - if (this->_sfp->_playing) { - this->_sfp->stop(); - } - this->_sfp->_curdir = Whiteboard::SessionFilePlayer::BACKWARD; - this->_sfp->start(); - break; - case STEP_REWIND: - this->_sfp->step(Whiteboard::SessionFilePlayer::BACKWARD); - break; - case PAUSE: - this->_sfp->stop(); - break; - case STEP_PLAY: - this->_sfp->step(Whiteboard::SessionFilePlayer::FORWARD); - break; - case PLAY: - if (this->_sfp->_playing) { - this->_sfp->stop(); - } - this->_sfp->_curdir = Whiteboard::SessionFilePlayer::FORWARD; - this->_sfp->start(); - break; - default: - break; - } -} - -} - -} - -} - -/* - 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/ui/dialog/session-player.h b/src/ui/dialog/session-player.h deleted file mode 100644 index 2d235cd25..000000000 --- a/src/ui/dialog/session-player.h +++ /dev/null @@ -1,134 +0,0 @@ -/** @file - * @brief Whiteboard session playback control dialog - */ -/* Authors: - * David Yip <yipdw@rose-hulman.edu> - * - * Copyright (c) 2005 Authors - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef __SESSION_PLAYBACK_DIALOG_H__ -#define __SESSION_PLAYBACK_DIALOG_H__ - -#include "verbs.h" -#include "dialog.h" - -#include "gtkmm/toolbutton.h" -#include "gtkmm/toolbar.h" -#include "gtkmm/expander.h" - -#include "ui/widget/icon-widget.h" - -struct SPDesktop; - -namespace Inkscape { - -namespace Whiteboard { - -class SessionManager; -class SessionFilePlayer; - -} - -namespace UI { - -namespace Dialog { - -class SessionPlaybackDialog : public Dialog { -public: - SessionPlaybackDialog() : Dialog("/dialogs/session_playback", SP_VERB_DIALOG_WHITEBOARD_SESSIONPLAYBACK) - { - - } - - static SessionPlaybackDialog* create(); - - virtual ~SessionPlaybackDialog() - { - - } -private: - SessionPlaybackDialog(SessionPlaybackDialog const& dlg); // no copy - void operator=(SessionPlaybackDialog const& dlg); // no assign -}; - -class SessionPlaybackDialogImpl : public SessionPlaybackDialog { -public: - SessionPlaybackDialogImpl(); - ~SessionPlaybackDialogImpl(); - -private: - // GTK+ widgets - Gtk::HBox _filebox; - Gtk::HBox _filebuttons; - Gtk::HBox _toolbarbox; - Gtk::HBox _delaybox; - - Gtk::Entry _openfile; - - Gtk::Label _labels[2]; - Gtk::ToolButton _controls[5]; - - Gtk::Button _close, _open, _setdelay; - - Gtk::Tooltips _tooltips; - Gtk::Toolbar _playbackcontrols; - Gtk::Adjustment _delay; - Widget::SpinButton _delayentry; - - Gtk::Frame _filemanager; - Gtk::VBox _fm; - - Gtk::Frame _playback; - - Gtk::Expander _currentmsgbox; - Glib::RefPtr<Gtk::TextBuffer> _currentmsgbuffer; - Gtk::TextView _currentmsgview; - Gtk::ScrolledWindow _currentmsgscroller; - - // Construction and callback - void _construct(); - void _respCallback(int resp); - - // SessionManager and SPDesktop pointers - ::SPDesktop* _desktop; - Whiteboard::SessionManager* _sm; - Whiteboard::SessionFilePlayer* _sfp; - - // button values - static unsigned short const CLOSE_FILE = 0; - static unsigned short const OPEN_FILE = 1; - static unsigned short const RESET_DELAY = 2; - - static unsigned short const TOOLBAR_BASE = 10; - static unsigned short const REWIND = TOOLBAR_BASE + 0; - static unsigned short const STEP_REWIND = TOOLBAR_BASE + 1; - static unsigned short const PAUSE = TOOLBAR_BASE + 2; - static unsigned short const STEP_PLAY = TOOLBAR_BASE + 3; - static unsigned short const PLAY = TOOLBAR_BASE + 4; - - - // noncopyable - SessionPlaybackDialogImpl(SessionPlaybackDialogImpl const& dlg); // no copy - void operator=(SessionPlaybackDialogImpl const& dlg); // no assign -}; - -} - -} - -} - -#endif - -/* - 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/ui/widget/dock-item.h b/src/ui/widget/dock-item.h index 79d69d862..1780b7525 100644 --- a/src/ui/widget/dock-item.h +++ b/src/ui/widget/dock-item.h @@ -19,7 +19,7 @@ #include <gtkmm/paned.h> #include <gtkmm/window.h> -#include "libgdl/libgdl.h" +#include "libgdl/gdl.h" namespace Inkscape { namespace UI { diff --git a/src/ui/widget/dock.h b/src/ui/widget/dock.h index 5836cf83f..bd5685348 100644 --- a/src/ui/widget/dock.h +++ b/src/ui/widget/dock.h @@ -20,7 +20,7 @@ #include "ui/widget/dock-item.h" -#include "libgdl/libgdl.h" +#include "libgdl/gdl.h" namespace Inkscape { namespace UI { diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 1af678dc6..075a24f82 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -29,7 +29,7 @@ #include <2geom/rect.h> #include "box3d-context.h" -#include "color-profile-fns.h" +#include "cms-system.h" #include "conn-avoid-ref.h" #include "desktop-events.h" #include "desktop-handles.h" @@ -194,7 +194,7 @@ void CMSPrefWatcher::hook(EgeColorProfTracker */*tracker*/, gint screen, gint mo guint len = 0; ege_color_prof_tracker_get_profile_for( screen, monitor, reinterpret_cast<gpointer*>(&buf), &len ); - Glib::ustring id = Inkscape::colorprofile_set_display_per( buf, len, screen, monitor ); + Glib::ustring id = Inkscape::CMSSystem::setDisplayPer( buf, len, screen, monitor ); #endif // ENABLE_LCMS } @@ -541,7 +541,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) #if ENABLE_LCMS bool fromDisplay = prefs->getBool( "/options/displayprofile/from_display"); if ( fromDisplay ) { - Glib::ustring id = Inkscape::colorprofile_get_display_id( 0, 0 ); + Glib::ustring id = Inkscape::CMSSystem::getDisplayId( 0, 0 ); bool enabled = false; if ( dtw->canvas->cms_key ) { @@ -806,7 +806,7 @@ void sp_dtw_color_profile_event(EgeColorProfTracker */*tracker*/, SPDesktopWidge GdkScreen* screen = gtk_widget_get_screen(GTK_WIDGET(dtw)); gint screenNum = gdk_screen_get_number(screen); gint monitor = gdk_screen_get_monitor_at_window(screen, gtk_widget_get_toplevel(GTK_WIDGET(dtw))->window); - Glib::ustring id = Inkscape::colorprofile_get_display_id( screenNum, monitor ); + Glib::ustring id = Inkscape::CMSSystem::getDisplayId( screenNum, monitor ); bool enabled = false; if ( dtw->canvas->cms_key ) { *(dtw->canvas->cms_key) = id; diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index eb9b2805d..ba32dc321 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -159,12 +159,16 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) document->ensureUpToDate (); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + Geom::OptRect bbox_vis = selection->bounds(SPItem::APPROXIMATE_BBOX); + Geom::OptRect bbox_geom = selection->bounds(SPItem::GEOMETRIC_BBOX); + int prefs_bbox = prefs->getInt("/tools/bounding_box"); - SPItem::BBoxType bbox_type = (prefs_bbox ==0)? + SPItem::BBoxType bbox_type = (prefs_bbox == 0)? SPItem::APPROXIMATE_BBOX : SPItem::GEOMETRIC_BBOX; - Geom::OptRect bbox = selection->bounds(bbox_type); + Geom::OptRect bbox_user = selection->bounds(bbox_type); - if ( !bbox ) { + if ( !bbox_user ) { g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); return; } @@ -186,35 +190,35 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) x0 = sp_units_get_pixels (a_x->value, unit); y0 = sp_units_get_pixels (a_y->value, unit); x1 = x0 + sp_units_get_pixels (a_w->value, unit); - xrel = sp_units_get_pixels (a_w->value, unit) / bbox->dimensions()[Geom::X]; + xrel = sp_units_get_pixels (a_w->value, unit) / bbox_user->dimensions()[Geom::X]; y1 = y0 + sp_units_get_pixels (a_h->value, unit); - yrel = sp_units_get_pixels (a_h->value, unit) / bbox->dimensions()[Geom::Y]; + yrel = sp_units_get_pixels (a_h->value, unit) / bbox_user->dimensions()[Geom::Y]; } else { double const x0_propn = a_x->value * unit.unittobase; - x0 = bbox->min()[Geom::X] * x0_propn; + x0 = bbox_user->min()[Geom::X] * x0_propn; double const y0_propn = a_y->value * unit.unittobase; - y0 = y0_propn * bbox->min()[Geom::Y]; + y0 = y0_propn * bbox_user->min()[Geom::Y]; xrel = a_w->value * unit.unittobase; - x1 = x0 + xrel * bbox->dimensions()[Geom::X]; + x1 = x0 + xrel * bbox_user->dimensions()[Geom::X]; yrel = a_h->value * unit.unittobase; - y1 = y0 + yrel * bbox->dimensions()[Geom::Y]; + y1 = y0 + yrel * bbox_user->dimensions()[Geom::Y]; } // Keep proportions if lock is on GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(G_OBJECT(spw), "lock") ); if ( gtk_toggle_action_get_active(lock) ) { if (adj == a_h) { - x1 = x0 + yrel * bbox->dimensions()[Geom::X]; + x1 = x0 + yrel * bbox_user->dimensions()[Geom::X]; } else if (adj == a_w) { - y1 = y0 + xrel * bbox->dimensions()[Geom::Y]; + y1 = y0 + xrel * bbox_user->dimensions()[Geom::Y]; } } // scales and moves, in px - double mh = fabs(x0 - bbox->min()[Geom::X]); - double sh = fabs(x1 - bbox->max()[Geom::X]); - double mv = fabs(y0 - bbox->min()[Geom::Y]); - double sv = fabs(y1 - bbox->max()[Geom::Y]); + double mh = fabs(x0 - bbox_user->min()[Geom::X]); + double sh = fabs(x1 - bbox_user->max()[Geom::X]); + double mv = fabs(y0 - bbox_user->min()[Geom::Y]); + double sv = fabs(y1 - bbox_user->max()[Geom::Y]); // unless the unit is %, convert the scales and moves to the unit if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) { @@ -244,11 +248,11 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) Geom::Affine scaler; if (bbox_type == SPItem::APPROXIMATE_BBOX) { - // get_scale_transform_with_stroke() is intended for VISUAL (or APPROXIMATE) bounding boxes, not geometrical ones! - scaler = get_scale_transform_with_stroke (*bbox, strokewidth, transform_stroke, x0, y0, x1, y1); + scaler = get_scale_transform_with_unequal_stroke (*bbox_vis, *bbox_geom, transform_stroke, x0, y0, x1, y1); } else { - // we'll trick it into using a geometrical bounding box though, by setting the stroke width to zero - scaler = get_scale_transform_with_stroke (*bbox, 0, false, x0, y0, x1, y1); + // get_scale_transform_with_stroke() is intended for VISUAL (or APPROXIMATE) bounding boxes, not geometrical ones! + // we'll trick it into using a geometric bounding box though, by setting the stroke width to zero + scaler = get_scale_transform_with_uniform_stroke (*bbox_user, 0, false, x0, y0, x1, y1); } sp_selection_apply_affine(selection, scaler); diff --git a/src/widgets/sp-color-icc-selector.cpp b/src/widgets/sp-color-icc-selector.cpp index 94f450e50..888cc2629 100644 --- a/src/widgets/sp-color-icc-selector.cpp +++ b/src/widgets/sp-color-icc-selector.cpp @@ -15,8 +15,9 @@ #define noDEBUG_LCMS #if ENABLE_LCMS -#include "color-profile-fns.h" #include "color-profile.h" +#include "cms-system.h" +#include "color-profile-cms-fns.h" #ifdef DEBUG_LCMS #include "preferences.h" @@ -258,6 +259,12 @@ void getThings( DWORD space, gchar const**& namers, gchar const**& tippies, guin tippies = tips[index]; scalies = scales[index]; } + + +void getThings( Inkscape::ColorProfile *prof, gchar const**& namers, gchar const**& tippies, guint const*& scalies ) { + getThings( asICColorSpaceSig(prof->getColorSpace()), namers, tippies, scalies ); +} + #endif // ENABLE_LCMS @@ -497,12 +504,12 @@ void ColorICCSelector::_switchToProfile( gchar const* name ) #ifdef DEBUG_LCMS g_message("got on out [%04x] [%04x] [%04x] [%04x]", post[0], post[1], post[2], post[3]); #endif // DEBUG_LCMS - guint count = _cmsChannelsOf( newProf->getColorSpace() ); + guint count = _cmsChannelsOf( asICColorSpaceSig(newProf->getColorSpace()) ); gchar const** names = 0; gchar const** tips = 0; guint const* scales = 0; - getThings( newProf->getColorSpace(), names, tips, scales ); + getThings( asICColorSpaceSig(newProf->getColorSpace()), names, tips, scales ); for ( guint i = 0; i < count; i++ ) { gdouble val = (((gdouble)post[i])/65535.0) * (gdouble)scales[i]; @@ -680,12 +687,12 @@ void ColorICCSelector::_setProfile( SVGICCColor* profile ) if ( profile ) { _prof = SP_ACTIVE_DOCUMENT->profileManager->find(profile->colorProfile.c_str()); - if ( _prof && _prof->getProfileClass() != icSigNamedColorClass ) { - _profChannelCount = _cmsChannelsOf( _prof->getColorSpace() ); + if ( _prof && (asICColorProfileClassSig(_prof->getProfileClass()) != icSigNamedColorClass) ) { + _profChannelCount = _cmsChannelsOf( asICColorSpaceSig(_prof->getColorSpace()) ); gchar const** names = 0; gchar const** tips = 0; - getThings( _prof->getColorSpace(), names, tips, _fooScales ); + getThings( asICColorSpaceSig(_prof->getColorSpace()), names, tips, _fooScales ); if ( profChanged ) { for ( guint i = 0; i < _profChannelCount; i++ ) { diff --git a/src/widgets/sp-color-icc-selector.h b/src/widgets/sp-color-icc-selector.h index 9238e3f68..a3915cd48 100644 --- a/src/widgets/sp-color-icc-selector.h +++ b/src/widgets/sp-color-icc-selector.h @@ -8,11 +8,9 @@ #include "sp-color-slider.h" #include "sp-color-selector.h" -#if ENABLE_LCMS -#include "color-profile.h" -#endif // ENABLE_LCMS - - +namespace Inkscape { +struct ColorProfile; +} struct SPColorICCSelector; struct SPColorICCSelectorClass; diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp index 377abf219..1324e0b16 100644 --- a/src/widgets/sp-color-notebook.cpp +++ b/src/widgets/sp-color-notebook.cpp @@ -1,5 +1,3 @@ -#define __SP_COLOR_NOTEBOOK_C__ - /* * A notebook with RGB, CMYK, CMS, HSL, and Wheel pages * @@ -37,6 +35,10 @@ #include "../inkscape.h" #include "../document.h" #include "../profile-manager.h" +#include "color-profile.h" +#include "cms-system.h" + +using Inkscape::CMSSystem; struct SPColorNotebookTracker { const gchar* name; @@ -529,14 +531,14 @@ void ColorNotebook::_updateRgbaEntry( const SPColor& color, gfloat alpha ) if (color.icc){ Inkscape::ColorProfile* target_profile = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str()); if ( target_profile ) - gtk_widget_set_sensitive (_box_outofgamut, target_profile->GamutCheck(color)); + gtk_widget_set_sensitive(_box_outofgamut, target_profile->GamutCheck(color)); } /* update too-much-ink icon */ gtk_widget_set_sensitive (_box_toomuchink, false); if (color.icc){ Inkscape::ColorProfile* prof = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str()); - if ( prof && ( (prof->getColorSpace() == icSigCmykData) || (prof->getColorSpace() == icSigCmyData) ) ) { + if ( prof && CMSSystem::isPrintColorSpace(prof) ) { gtk_widget_show(GTK_WIDGET(_box_toomuchink)); double ink_sum = 0; for (unsigned int i=0; i<color.icc->colors.size(); i++){ |
