summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2011-07-13 22:21:37 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2011-07-13 22:21:37 +0000
commit0d6be77f2af241e47d0df3f19619db85ca8127e7 (patch)
tree510d535eb41530772c79218ece39023d85d42c93 /src
parentFix crashes during offscreen rendering, part 1 (diff)
parentFix crashes in print preview (diff)
downloadinkscape-0d6be77f2af241e47d0df3f19619db85ca8127e7.tar.gz
inkscape-0d6be77f2af241e47d0df3f19619db85ca8127e7.zip
Merge from trunk to pull in fix for LP #806105
(bzr r10347.1.13)
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/Makefile.am6
-rw-r--r--src/Makefile_insert4
-rw-r--r--src/cms-color-types.h58
-rw-r--r--src/cms-system.h60
-rw-r--r--src/color-profile-cms-fns.h51
-rw-r--r--src/color-profile-fns.h65
-rw-r--r--src/color-profile-test.h2
-rw-r--r--src/color-profile.cpp325
-rw-r--r--src/color-profile.h49
-rw-r--r--src/display/cairo-utils.cpp12
-rw-r--r--src/display/cairo-utils.h1
-rw-r--r--src/display/nr-arena-glyphs.cpp12
-rw-r--r--src/display/sp-canvas.cpp10
-rw-r--r--src/extension/implementation/script.cpp1
-rw-r--r--src/extension/internal/cairo-render-context.cpp65
-rw-r--r--src/extension/internal/cairo-render-context.h2
-rw-r--r--src/extension/internal/cairo-renderer.cpp24
-rwxr-xr-xsrc/extension/internal/filter/abc.h12
-rw-r--r--src/helper/pixbuf-ops.cpp5
-rw-r--r--src/interface.cpp4
-rw-r--r--src/libgdl/CMakeLists.txt10
-rw-r--r--src/libgdl/Makefile_insert6
-rw-r--r--src/libgdl/gdl-dock-bar.h1
-rw-r--r--src/libgdl/gdl-dock-item-button-image.c169
-rw-r--r--src/libgdl/gdl-dock-item-button-image.h70
-rw-r--r--src/libgdl/gdl-dock-item-grip.c655
-rw-r--r--src/libgdl/gdl-dock-item-grip.h33
-rw-r--r--src/libgdl/gdl-dock-item.c347
-rw-r--r--src/libgdl/gdl-dock-item.h19
-rw-r--r--src/libgdl/gdl-dock-master.c2
-rw-r--r--src/libgdl/gdl-dock-master.h9
-rw-r--r--src/libgdl/gdl-dock-notebook.c6
-rw-r--r--src/libgdl/gdl-dock-object.c37
-rw-r--r--src/libgdl/gdl-dock-object.h2
-rw-r--r--src/libgdl/gdl-dock-paned.c1
-rw-r--r--src/libgdl/gdl-dock-placeholder.c9
-rw-r--r--src/libgdl/gdl-dock-placeholder.h2
-rw-r--r--src/libgdl/gdl-dock.c17
-rw-r--r--src/libgdl/gdl-stock.c126
-rw-r--r--src/libgdl/gdl-switcher.c243
-rw-r--r--src/libgdl/gdl-switcher.h24
-rw-r--r--src/libgdl/gdl-tools.h3
-rw-r--r--src/libgdl/gdl.h (renamed from src/libgdl/gdl-stock.h)32
-rw-r--r--src/libgdl/libgdl.h37
-rw-r--r--src/libgdl/libgdltypebuiltins.h2
-rw-r--r--src/libnrtype/Layout-TNG-Input.cpp2
-rw-r--r--src/seltrans.cpp4
-rw-r--r--src/snap-preferences.cpp2
-rw-r--r--src/snap-preferences.h2
-rw-r--r--src/sp-image.cpp9
-rw-r--r--src/sp-item-transform.cpp272
-rw-r--r--src/sp-item-transform.h3
-rw-r--r--src/sp-object-repr.cpp2
-rw-r--r--src/sp-object.cpp2
-rw-r--r--src/style.cpp265
-rw-r--r--src/style.h11
-rw-r--r--src/svg/svg-color.cpp19
-rw-r--r--src/ui/CMakeLists.txt1
-rw-r--r--src/ui/cache/svg_preview_cache.cpp3
-rw-r--r--src/ui/dialog/color-item.cpp16
-rw-r--r--src/ui/dialog/dock-behavior.h2
-rw-r--r--src/ui/dialog/document-properties.cpp60
-rw-r--r--src/ui/dialog/filter-effects-dialog.cpp4
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp19
-rw-r--r--src/ui/dialog/session-player.cpp231
-rw-r--r--src/ui/dialog/session-player.h134
-rw-r--r--src/ui/widget/dock-item.h2
-rw-r--r--src/ui/widget/dock.h2
-rw-r--r--src/widgets/desktop-widget.cpp8
-rw-r--r--src/widgets/select-toolbar.cpp42
-rw-r--r--src/widgets/sp-color-icc-selector.cpp19
-rw-r--r--src/widgets/sp-color-icc-selector.h8
-rw-r--r--src/widgets/sp-color-notebook.cpp10
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++){