summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorsu_v <suv-sf@users.sourceforge.net>2012-10-08 18:55:32 +0000
committer~suv <suv-sf@users.sourceforge.net>2012-10-08 18:55:32 +0000
commit823318895dfecc05e8376e557543ea9e89c362b2 (patch)
treed8a7b66f0ede52e0bc5415eb103e7e89ea436953 /src
parentchanges_2012_10_04b.patch: fixes one small memory issue (bytes allocated and ... (diff)
parentGerman translation update 93% (diff)
downloadinkscape-823318895dfecc05e8376e557543ea9e89c362b2.tar.gz
inkscape-823318895dfecc05e8376e557543ea9e89c362b2.zip
merge from trunk (r11760)
(bzr r11668.1.25)
Diffstat (limited to 'src')
-rw-r--r--src/extension/internal/filter/color.h2
-rw-r--r--src/inkscape.cpp20
-rw-r--r--src/live_effects/lpe-powerstroke.cpp164
-rw-r--r--src/main.cpp2
-rw-r--r--src/select-context.cpp5
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp12
-rw-r--r--src/ui/dialog/swatches.cpp47
-rw-r--r--src/ui/widget/panel.cpp1
-rw-r--r--src/widgets/gradient-image.cpp2
-rw-r--r--src/widgets/gradient-selector.cpp4
10 files changed, 230 insertions, 29 deletions
diff --git a/src/extension/internal/filter/color.h b/src/extension/internal/filter/color.h
index 22b77a8cc..785059cca 100644
--- a/src/extension/internal/filter/color.h
+++ b/src/extension/internal/filter/color.h
@@ -637,7 +637,7 @@ public:
"<_item value=\"g\">" N_("Green") "</_item>\n"
"<_item value=\"b\">" N_("Blue") "</_item>\n"
"<_item value=\"c\">" N_("Cyan") "</_item>\n"
- "<_item value=\"m\">" N_("Majenta") "</_item>\n"
+ "<_item value=\"m\">" N_("Magenta") "</_item>\n"
"<_item value=\"y\">" N_("Yellow") "</_item>\n"
"</param>\n"
"<param name=\"blend\" gui-text=\"" N_("Background blend mode:") "\" type=\"enum\">\n"
diff --git a/src/inkscape.cpp b/src/inkscape.cpp
index b1cc53b4e..0a94d0742 100644
--- a/src/inkscape.cpp
+++ b/src/inkscape.cpp
@@ -309,8 +309,24 @@ static gint inkscape_autosave(gpointer)
GDir *autosave_dir_ptr = g_dir_open(autosave_dir.c_str(), 0, NULL);
if( !autosave_dir_ptr ){
- g_warning("Cannot open autosave directory!");
- return TRUE;
+ // Try to create the autosave directory if it doesn't exist
+ if (g_mkdir(autosave_dir.c_str(), 0755)) {
+ // the creation failed
+ Glib::ustring msg = Glib::ustring::format(
+ _("Autosave failed! Cannot create directory "), Glib::filename_to_utf8(autosave_dir));
+ g_warning("%s", msg.c_str());
+ SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, msg.c_str());
+ return TRUE;
+ }
+ // Try to read dir again
+ autosave_dir_ptr = g_dir_open(autosave_dir.c_str(), 0, NULL);
+ if( !autosave_dir_ptr ){
+ Glib::ustring msg = Glib::ustring::format(
+ _("Autosave failed! Cannot open directory "), Glib::filename_to_utf8(autosave_dir));
+ g_warning("%s", msg.c_str());
+ SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, msg.c_str());
+ return TRUE;
+ }
}
time_t sptime = time(NULL);
diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp
index 69d0808e4..df94a761e 100644
--- a/src/live_effects/lpe-powerstroke.cpp
+++ b/src/live_effects/lpe-powerstroke.cpp
@@ -28,6 +28,8 @@
#include <2geom/path-intersection.h>
#include <2geom/crossing.h>
#include <2geom/ellipse.h>
+#include <2geom/math-utils.h>
+#include <math.h>
#include "spiro.h"
@@ -86,6 +88,70 @@ static Ellipse find_ellipse(Point P, Point Q, Point O)
return Ellipse(A, B, C, D, E, F);
}
+/**
+ * Refer to: Weisstein, Eric W. "Circle-Circle Intersection."
+ From MathWorld--A Wolfram Web Resource.
+ http://mathworld.wolfram.com/Circle-CircleIntersection.html
+ *
+ * @return 0 if no intersection
+ * @return 1 if one circle is contained in the other
+ * @return 2 if intersections are found (they are written to p0 and p1)
+ */
+static int circle_circle_intersection(Circle const &circle0, Circle const &circle1,
+ Point & p0, Point & p1)
+{
+ Point X0 = circle0.center();
+ double r0 = circle0.ray();
+ Point X1 = circle1.center();
+ double r1 = circle1.ray();
+
+ /* dx and dy are the vertical and horizontal distances between
+ * the circle centers.
+ */
+ Point D = X1 - X0;
+
+ /* Determine the straight-line distance between the centers. */
+ double d = L2(D);
+
+ /* Check for solvability. */
+ if (d > (r0 + r1))
+ {
+ /* no solution. circles do not intersect. */
+ return 0;
+ }
+ if (d <= fabs(r0 - r1))
+ {
+ /* no solution. one circle is contained in the other */
+ return 1;
+ }
+
+ /* 'point 2' is the point where the line through the circle
+ * intersection points crosses the line between the circle
+ * centers.
+ */
+
+ /* Determine the distance from point 0 to point 2. */
+ double a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ;
+
+ /* Determine the coordinates of point 2. */
+ Point p2 = X0 + D * (a/d);
+
+ /* Determine the distance from point 2 to either of the
+ * intersection points.
+ */
+ double h = std::sqrt((r0*r0) - (a*a));
+
+ /* Now determine the offsets of the intersection points from
+ * point 2.
+ */
+ Point r = (h/d)*rot90(D);
+
+ /* Determine the absolute intersection points. */
+ p0 = p2 + r;
+ p1 = p2 - r;
+
+ return 2;
+}
} // namespace Geom
@@ -121,7 +187,8 @@ enum LineJoinType {
LINEJOIN_ROUND,
LINEJOIN_EXTRP_MITER,
LINEJOIN_MITER,
- LINEJOIN_SPIRO
+ LINEJOIN_SPIRO,
+ LINEJOIN_EXTRP_MITER_ARC
};
static const Util::EnumData<unsigned> LineJoinTypeData[] = {
{LINEJOIN_BEVEL, N_("Beveled"), "bevel"},
@@ -129,6 +196,9 @@ static const Util::EnumData<unsigned> LineJoinTypeData[] = {
{LINEJOIN_EXTRP_MITER, N_("Extrapolated"), "extrapolated"},
{LINEJOIN_MITER, N_("Miter"), "miter"},
{LINEJOIN_SPIRO, N_("Spiro"), "spiro"},
+#ifdef LPE_ENABLE_TEST_EFFECTS
+ {LINEJOIN_EXTRP_MITER_ARC, N_("Extrapolated arc"), "extrp_arc"},
+#endif
};
static const Util::EnumDataConverter<unsigned> LineJoinTypeConverter(LineJoinTypeData, sizeof(LineJoinTypeData)/sizeof(*LineJoinTypeData));
@@ -310,6 +380,98 @@ static Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise<Geom::D2<Geom::
}
break;
}
+ case LINEJOIN_EXTRP_MITER_ARC: {
+ Geom::Circle circle0;
+ Geom::Circle circle1;
+ Geom::Point tang0(0.,0.);
+ {
+ Geom::Point norm0(0.,0.);
+ Geom::Coord curv0 = 0;
+ std::vector<Geom::Point> derivs = reverse(B[prev_i]).valueAndDerivatives(0.,5);
+ for (unsigned deriv_n = 1, count = 0; deriv_n < derivs.size(); deriv_n++) {
+ Geom::Coord length = derivs[deriv_n].length();
+ if ( ! Geom::are_near(length, 0) ) {
+ if (count == 0) {
+ tang0 = derivs[deriv_n] / length;
+ curv0 = length; // save the length of the tangent
+ count++;
+ } else {
+ // curv0 = need good way to calculate curvature
+ // calculate direction of normal
+ double angle = angle_between(tang0, derivs[deriv_n]);
+ if (angle >= 0 ) {
+ norm0 = tang0.ccw();
+ } else {
+ norm0 = tang0.cw();
+ }
+ break; // break out of for-loop
+ }
+ }
+ }
+ double r0 = curv0;
+ Geom::Point center0 = B[prev_i].at1() - r0*norm0;
+ circle0 = Geom::Circle(center0, r0);
+ }
+ Geom::Point tang1(0.,0.);
+ {
+ Geom::Point norm1(0.,0.);
+ Geom::Coord curv1 = 0;
+ std::vector<Geom::Point> derivs = B[i].valueAndDerivatives(0.,5);
+ for (unsigned deriv_n = 1, count = 0; deriv_n < derivs.size(); deriv_n++) {
+ Geom::Coord length = derivs[deriv_n].length();
+ if ( ! Geom::are_near(length, 0) ) {
+ if (count == 0) {
+ tang1 = derivs[deriv_n] / length;
+ curv1 = length; // save the length of the tangent
+ count++;
+ } else {
+ //curv1 = length / curv1; // curvature = tangent' / tangent
+ // calculate direction of normal
+ double angle = angle_between(tang1, derivs[deriv_n]);
+ if (angle >= 0 ) {
+ norm1 = tang1.ccw();
+ } else {
+ norm1 = tang1.cw();
+ }
+ break; // break out of for-loop
+ }
+ }
+ }
+ double r1 = curv1;
+ Geom::Point center1 = B[i].at0() - r1*norm1;
+ circle1 = Geom::Circle(center1, r1);
+ }
+
+ Geom::Point points[2];
+ int solutions = circle_circle_intersection(circle0, circle1, points[0], points[1]);
+ if (solutions == 2) {
+ Geom::Point sol = points[0];
+ if ( dot(tang0,sol-B[prev_i].at1()) > 0 ) {
+ sol = points[1];
+ }
+ Geom::EllipticalArc *arc0 = circle0.arc(B[prev_i].at1(), 0.5*(B[prev_i].at1()+sol), sol, true);
+ Geom::EllipticalArc *arc1 = circle1.arc(sol, 0.5*(sol+B[i].at0()), B[i].at0(), true);
+
+ if (arc0) {
+ build_from_sbasis(pb,arc0->toSBasis(), tol, false);
+ delete arc0;
+ arc0 = NULL;
+ }
+ if (arc1) {
+ build_from_sbasis(pb,arc1->toSBasis(), tol, false);
+ delete arc1;
+ arc1 = NULL;
+ }
+ } else if (solutions == 1) { // one circle is inside the other
+ // don't know what to do: default to bevel
+ pb.lineTo(B[i].at0());
+ } else { // no intersections
+ // don't know what to do: default to bevel
+ pb.lineTo(B[i].at0());
+ }
+
+ break;
+ }
case LINEJOIN_MITER: {
boost::optional<Geom::Point> p = intersection_point( B[prev_i].at1(), tang1,
B[i].at0(), tang2 );
diff --git a/src/main.cpp b/src/main.cpp
index d1e087cac..578279929 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -625,6 +625,8 @@ main(int argc, char **argv)
bindtextdomain(GETTEXT_PACKAGE, BR_LOCALEDIR(""));
# else
bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
+ // needed by Python/Gettext
+ g_setenv("PACKAGE_LOCALE_DIR", PACKAGE_LOCALE_DIR, TRUE);
# endif
#endif
diff --git a/src/select-context.cpp b/src/select-context.cpp
index 7fecc7167..bc096d528 100644
--- a/src/select-context.cpp
+++ b/src/select-context.cpp
@@ -1140,8 +1140,9 @@ sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event)
}
// set cursor to default.
if (!desktop->isWaitingCursor()) {
- GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop)));
- gdk_window_set_cursor(window, event_context->cursor);
+ // Do we need to reset the cursor here on key release ?
+ //GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (sp_desktop_canvas(desktop)));
+ //gdk_window_set_cursor(window, event_context->cursor);
}
break;
default:
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index fbaebfbec..2731b6174 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -480,7 +480,7 @@ void InkscapePreferences::initPageTools()
_misc_gradientangle.init("/dialogs/gradienteditor/angle", -359, 359, 1, 90, 0, false, false);
_page_gradient.add_line( false, _("Linear gradient _angle:"), _misc_gradientangle, "",
- _("Default angle of new linear gradients in degrees (clockwise from horizontal"), false);
+ _("Default angle of new linear gradients in degrees (clockwise from horizontal)"), false);
//Dropper
@@ -811,7 +811,7 @@ void InkscapePreferences::initPageIO()
_("Maximum mouse drag (in screen pixels) which is considered a click, not a drag"), false);
_mouse_grabsize.init("/options/grabsize/value", 1, 7, 1, 2, 3, 0);
- _page_mouse.add_line(false, _("_Handle size"), _mouse_grabsize, "",
+ _page_mouse.add_line(false, _("_Handle size:"), _mouse_grabsize, "",
_("Set the relative size of node handles"), true);
_mouse_use_ext_input.init( _("Use pressure-sensitive tablet (requires restart)"), "/options/useextinput/value", true);
@@ -1041,10 +1041,14 @@ void InkscapePreferences::initPageIO()
// Autosave options
_save_autosave_enable.init( _("Enable autosave (requires restart)"), "/options/autosave/enable", false);
_page_autosave.add_line(false, "", _save_autosave_enable, "", _("Automatically save the current document(s) at a given interval, thus minimizing loss in case of a crash"), false);
+ _save_autosave_path.init("/options/autosave/path", true);
+ if (prefs->getString("/options/autosave/path").empty()) {
+ // Show the default fallback "tmp dir" if autosave path is not set.
+ _save_autosave_path.set_text(Glib::get_tmp_dir());
+ }
+ _page_autosave.add_line(false, C_("Filesystem", "Autosave _directory:"), _save_autosave_path, "", _("The directory where autosaves will be written. This should be an absolute path (starts with / on UNIX or a drive letter such as C: on Windows). "), false);
_save_autosave_interval.init("/options/autosave/interval", 1.0, 10800.0, 1.0, 10.0, 10.0, true, false);
_page_autosave.add_line(false, _("_Interval (in minutes):"), _save_autosave_interval, "", _("Interval (in minutes) at which document will be autosaved"), false);
- _save_autosave_path.init("/options/autosave/path", true);
- _page_autosave.add_line(false, C_("Filesystem", "_Path:"), _save_autosave_path, "", _("The directory where autosaves will be written"), false);
_save_autosave_max.init("/options/autosave/max", 1.0, 100.0, 1.0, 10.0, 10.0, true, false);
_page_autosave.add_line(false, _("_Maximum number of autosaves:"), _save_autosave_max, "", _("Maximum number of autosaved files; use this to limit the storage space used"), false);
diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp
index 3baba3460..9d5a2ac28 100644
--- a/src/ui/dialog/swatches.cpp
+++ b/src/ui/dialog/swatches.cpp
@@ -62,10 +62,10 @@ namespace Dialogs {
#define VBLOCK 16
#define PREVIEW_PIXBUF_WIDTH 128
-void _loadPaletteFile( gchar const *filename );
+void _loadPaletteFile( gchar const *filename, gboolean user=FALSE );
-
-std::vector<SwatchPage*> possible;
+std::list<SwatchPage*> userSwatchPages;
+std::list<SwatchPage*> systemSwatchPages;
static std::map<SPDocument*, SwatchPage*> docPalettes;
static std::vector<DocTrack*> docTrackings;
static std::map<SwatchesPanel*, SPDocument*> docPerPanel;
@@ -391,7 +391,7 @@ static bool parseNum( char*& str, int& val ) {
}
-void _loadPaletteFile( gchar const *filename )
+void _loadPaletteFile( gchar const *filename, gboolean user/*=FALSE*/ )
{
char block[1024];
FILE *f = Inkscape::IO::fopen_utf8name( filename, "r" );
@@ -493,7 +493,10 @@ void _loadPaletteFile( gchar const *filename )
}
} while ( result && !hasErr );
if ( !hasErr ) {
- possible.push_back(onceMore);
+ if (user)
+ userSwatchPages.push_back(onceMore);
+ else
+ systemSwatchPages.push_back(onceMore);
#if ENABLE_MAGIC_COLORS
ColorItem::_wireMagicColors( onceMore );
#endif // ENABLE_MAGIC_COLORS
@@ -507,9 +510,16 @@ void _loadPaletteFile( gchar const *filename )
}
}
+static bool
+compare_swatch_names(SwatchPage const *a, SwatchPage const *b) {
+
+ return g_utf8_collate(a->_name.c_str(), b->_name.c_str()) < 0;
+}
+
static void loadEmUp()
{
static bool beenHere = false;
+ gboolean userPalete = true;
if ( !beenHere ) {
beenHere = true;
@@ -521,7 +531,6 @@ static void loadEmUp()
// Use this loop to iterate through a list of possible document locations.
while (!sources.empty()) {
gchar *dirname = sources.front();
-
if ( Inkscape::IO::file_test( dirname, G_FILE_TEST_EXISTS )
&& Inkscape::IO::file_test( dirname, G_FILE_TEST_IS_DIR )) {
GError *err = 0;
@@ -535,11 +544,13 @@ static void loadEmUp()
while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) {
gchar* lower = g_ascii_strdown( filename, -1 );
// if ( g_str_has_suffix(lower, ".gpl") ) {
+ if ( !g_str_has_suffix(lower, "~") ) {
gchar* full = g_build_filename(dirname, filename, NULL);
if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) {
- _loadPaletteFile(full);
+ _loadPaletteFile(full, userPalete);
}
g_free(full);
+ }
// }
g_free(lower);
}
@@ -550,15 +561,15 @@ static void loadEmUp()
// toss the dirname
g_free(dirname);
sources.pop_front();
+ userPalete = false;
}
}
-}
-
-
-
-
+ // Sort the list of swatches by name, grouped by user/system
+ userSwatchPages.sort(compare_swatch_names);
+ systemSwatchPages.sort(compare_swatch_names);
+}
@@ -592,7 +603,7 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath) :
}
loadEmUp();
- if ( !possible.empty() ) {
+ if ( !systemSwatchPages.empty() ) {
SwatchPage* first = 0;
int index = 0;
Glib::ustring targetName;
@@ -603,8 +614,9 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath) :
if (targetName == "Auto") {
first = docPalettes[0];
} else {
- index++;
- for ( std::vector<SwatchPage*>::iterator iter = possible.begin(); iter != possible.end(); ++iter ) {
+ //index++;
+ std::vector<SwatchPage*> pages = _getSwatchSets();
+ for ( std::vector<SwatchPage*>::iterator iter = pages.begin(); iter != pages.end(); ++iter ) {
if ( (*iter)->_name == targetName ) {
first = *iter;
break;
@@ -635,6 +647,7 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath) :
hotItem = single;
}
_regItem( single, 3, i );
+
i++;
}
}
@@ -1027,6 +1040,7 @@ void SwatchesPanel::handleDefsModified(SPDocument *document)
}
}
+
std::vector<SwatchPage*> SwatchesPanel::_getSwatchSets() const
{
std::vector<SwatchPage*> tmp;
@@ -1034,7 +1048,8 @@ std::vector<SwatchPage*> SwatchesPanel::_getSwatchSets() const
tmp.push_back(docPalettes[_currentDocument]);
}
- tmp.insert(tmp.end(), possible.begin(), possible.end());
+ tmp.insert(tmp.end(), userSwatchPages.begin(), userSwatchPages.end());
+ tmp.insert(tmp.end(), systemSwatchPages.begin(), systemSwatchPages.end());
return tmp;
}
diff --git a/src/ui/widget/panel.cpp b/src/ui/widget/panel.cpp
index 42435f298..dcf5956bf 100644
--- a/src/ui/widget/panel.cpp
+++ b/src/ui/widget/panel.cpp
@@ -560,6 +560,7 @@ void Panel::_regItem(Gtk::MenuItem* item, int group, int id)
_menu->append(*item);
item->signal_activate().connect(sigc::bind<int, int>(sigc::mem_fun(*this, &Panel::_bounceCall), group + PANEL_SETTING_NEXTFREE, id));
item->show();
+
}
void Panel::_handleAction(int /*set_id*/, int /*item_id*/)
diff --git a/src/widgets/gradient-image.cpp b/src/widgets/gradient-image.cpp
index 3c84e606b..94918c614 100644
--- a/src/widgets/gradient-image.cpp
+++ b/src/widgets/gradient-image.cpp
@@ -127,7 +127,7 @@ static void sp_gradient_image_destroy(GtkObject *object)
static void sp_gradient_image_size_request(GtkWidget * /*widget*/, GtkRequisition *requisition)
{
- requisition->width = 64;
+ requisition->width = 54;
requisition->height = 12;
}
diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp
index 082f04a77..dffda69e3 100644
--- a/src/widgets/gradient-selector.cpp
+++ b/src/widgets/gradient-selector.cpp
@@ -143,13 +143,13 @@ static void sp_gradient_selector_init(SPGradientSelector *sel)
sel->icon_renderer = Gtk::manage(new Gtk::CellRendererPixbuf());
sel->text_renderer = Gtk::manage(new Gtk::CellRendererText());
- sel->treeview->append_column("Gradient", *sel->icon_renderer);
+ sel->treeview->append_column(_("Gradient"), *sel->icon_renderer);
Gtk::TreeView::Column* icon_column = sel->treeview->get_column(0);
icon_column->add_attribute(sel->icon_renderer->property_pixbuf(), sel->columns->pixbuf);
icon_column->set_sort_column(sel->columns->color);
icon_column->set_clickable(true);
- sel->treeview->append_column("Name", *sel->text_renderer);
+ sel->treeview->append_column(_("Name"), *sel->text_renderer);
Gtk::TreeView::Column* name_column = sel->treeview->get_column(1);
sel->text_renderer->property_editable() = true;
name_column->add_attribute(sel->text_renderer->property_text(), sel->columns->name);