Merge lp:~mw-triad/inkscape/polygonal-grid into lp:~inkscape.dev/inkscape/trunk

Proposed by jazzynico
Status: Needs review
Proposed branch: lp:~mw-triad/inkscape/polygonal-grid
Merge into: lp:~inkscape.dev/inkscape/trunk
Diff against target: 1118 lines (+938/-17) (has conflicts)
8 files modified
src/display/CMakeLists.txt (+1/-0)
src/display/canvas-grid.cpp (+33/-2)
src/display/canvas-grid.h (+3/-2)
src/display/canvas-ngongrid.cpp (+747/-0)
src/display/canvas-ngongrid.h (+94/-0)
src/ui/dialog/document-properties.cpp (+2/-0)
src/ui/dialog/inkscape-preferences.cpp (+46/-13)
src/ui/dialog/inkscape-preferences.h (+12/-0)
Text conflict in src/display/canvas-grid.cpp
Text conflict in src/ui/dialog/inkscape-preferences.cpp
To merge this branch: bzr merge lp:~mw-triad/inkscape/polygonal-grid
Reviewer Review Type Date Requested Status
jazzynico (community) Needs Fixing
Review via email: mp+293349@code.launchpad.net

Description of the change

Generating diff against the current trunk.

To post a comment you must log in.
Revision history for this message
jazzynico (jazzynico) wrote :

@Matthew - I know you submitted your branch a long time ago, and I'm sorry we didn't find time to review it sooner. But I'm sure it's an interesting feature and it would be great if we could port it to the current development code.
Would you be willing to fix the conflicts in canvas-grip.cpp and inkscape-preferences.cpp, or give ownership of the branch to the "Inkscape Developers" group so that we can work on it directly?
Thanks!

review: Needs Fixing

Unmerged revisions

11944. By Matthew Woehlke

fix wrong snap for grid origin != (0, 0)

Fix missing addition of grid offset, causing broken snapping to
polygonal grid when grid origin is not (0, 0).

11943. By Matthew Woehlke

implement polygonal grid snapping

Add necessary code to find the nearest relevant lines to which to snap
for the polygonal grid.

11942. By Matthew Woehlke

auto-extents improvements

Compute minimum X extent so we don't render concentric segments that
aren't needed. Add note that we could do better skipping sections that
won't be visible.

11941. By Matthew Woehlke

fix polygonal grid extents

Hook up polygonal grid extents calculation so that we always draw enough
grid to fill the viewport, rather than truncating the grid at an
arbitrary point.

11940. By Matthew Woehlke

start implementing polygonal grid renderingg

Implement basic rendering for the polygonal grid. For now, this uses an
arbitrary max extent (rather than determining max extents per section
with respect to the viewport), and doesn't attempt to clip grid lines to
the viewport. Also, snapping is not yet implemented (the old code from
the axonometric grid has been commented out for now).

11939. By Matthew Woehlke

implement UI for polygonal grid

Modify the UI for polygonal grid to have the appropriate parameters,
rather than those copied from axonometric grid. Since the grid logic has
not been changed yet, we are using the rotation angle as both angles for
the axonometric logic (which gives a degenerate grid with the default
value 0).

11938. By Matthew Woehlke

add template for polygonal grid

Create new 'polygonal' grid type. Right now this is just a copy of the
axonometric grid type, to get the necessary bits in place before
starting to develop the actual logic.

11937. By Matthew Woehlke

whitespace fix

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/display/CMakeLists.txt'
2--- src/display/CMakeLists.txt 2015-12-10 05:43:23 +0000
3+++ src/display/CMakeLists.txt 2016-04-29 07:04:20 +0000
4@@ -5,6 +5,7 @@
5 canvas-axonomgrid.cpp
6 canvas-bpath.cpp
7 canvas-grid.cpp
8+ canvas-ngongrid.cpp
9 canvas-temporary-item-list.cpp
10 canvas-temporary-item.cpp
11 canvas-text.cpp
12
13=== modified file 'src/display/canvas-grid.cpp'
14--- src/display/canvas-grid.cpp 2015-05-06 11:55:31 +0000
15+++ src/display/canvas-grid.cpp 2016-04-29 07:04:20 +0000
16@@ -36,6 +36,7 @@
17 #include "display/cairo-utils.h"
18 #include "display/canvas-axonomgrid.h"
19 #include "display/canvas-grid.h"
20+#include "display/canvas-ngongrid.h"
21 #include "display/sp-canvas-group.h"
22 #include "document.h"
23 #include "util/units.h"
24@@ -58,11 +59,13 @@
25
26 static gchar const *const grid_name[] = {
27 N_("Rectangular grid"),
28- N_("Axonometric grid")
29+ N_("Axonometric grid"),
30+ N_("Polygonal grid")
31 };
32 static gchar const *const grid_svgname[] = {
33 "xygrid",
34- "axonomgrid"
35+ "axonomgrid",
36+ "ngongrid"
37 };
38
39
40@@ -72,7 +75,33 @@
41 static void grid_canvasitem_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags);
42 static void grid_canvasitem_render (SPCanvasItem *item, SPCanvasBuf *buf);
43
44+<<<<<<< TREE
45 G_DEFINE_TYPE(GridCanvasItem, grid_canvasitem, SP_TYPE_CANVAS_ITEM);
46+=======
47+static SPCanvasItemClass * parent_class;
48+
49+GType
50+grid_canvasitem_get_type (void)
51+{
52+ static GType grid_canvasitem_type = 0;
53+
54+ if (!grid_canvasitem_type) {
55+ GTypeInfo grid_canvasitem_info = {
56+ sizeof (GridCanvasItemClass),
57+ NULL, NULL,
58+ (GClassInitFunc) grid_canvasitem_class_init,
59+ NULL, NULL,
60+ sizeof (GridCanvasItem),
61+ 0,
62+ (GInstanceInitFunc) grid_canvasitem_init,
63+ NULL
64+ };
65+
66+ grid_canvasitem_type = g_type_register_static(SPCanvasItem::getType(), "GridCanvasItem", &grid_canvasitem_info, GTypeFlags(0));
67+ }
68+ return grid_canvasitem_type;
69+}
70+>>>>>>> MERGE-SOURCE
71
72 static void grid_canvasitem_class_init(GridCanvasItemClass *klass)
73 {
74@@ -263,6 +292,8 @@
75 return dynamic_cast<CanvasGrid*>(new CanvasXYGrid(nv, repr, doc));
76 case GRID_AXONOMETRIC:
77 return dynamic_cast<CanvasGrid*>(new CanvasAxonomGrid(nv, repr, doc));
78+ case GRID_POLYGONAL:
79+ return dynamic_cast<CanvasGrid*>(new CanvasNGonGrid(nv, repr, doc));
80 }
81
82 return NULL;
83
84=== modified file 'src/display/canvas-grid.h'
85--- src/display/canvas-grid.h 2014-10-08 02:22:03 +0000
86+++ src/display/canvas-grid.h 2016-04-29 07:04:20 +0000
87@@ -34,9 +34,10 @@
88
89 enum GridType {
90 GRID_RECTANGULAR = 0,
91- GRID_AXONOMETRIC = 1
92+ GRID_AXONOMETRIC = 1,
93+ GRID_POLYGONAL = 2
94 };
95-#define GRID_MAXTYPENR 1
96+#define GRID_MAXTYPENR 2
97
98 #define INKSCAPE_TYPE_GRID_CANVASITEM (Inkscape::grid_canvasitem_get_type ())
99 #define INKSCAPE_GRID_CANVASITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INKSCAPE_TYPE_GRID_CANVASITEM, GridCanvasItem))
100
101=== added file 'src/display/canvas-ngongrid.cpp'
102--- src/display/canvas-ngongrid.cpp 1970-01-01 00:00:00 +0000
103+++ src/display/canvas-ngongrid.cpp 2016-04-29 07:04:20 +0000
104@@ -0,0 +1,747 @@
105+/*
106+ * Authors:
107+ * Matthew Woehlke <mw_triad@users.sourceforge.net>
108+ * Johan Engelen <j.b.c.engelen@alumnus.utwente.nl>
109+ *
110+ * Copyright (C) 2006-2012 Authors
111+ * Released under GNU GPL, read the file 'COPYING' for more information
112+ */
113+
114+ /*
115+ * Current limits are: one axis (y-axis) is always vertical. The other two
116+ * axes are bound to a certain range of angles. The z-axis always has an angle
117+ * smaller than 90 degrees (measured from horizontal, 0 degrees being a line extending
118+ * to the right). The x-axis will always have an angle between 0 and 90 degrees.
119+ */
120+
121+
122+#include <gtkmm/box.h>
123+#include <gtkmm/label.h>
124+#include <gtkmm/table.h>
125+#include <glibmm/i18n.h>
126+
127+#include "display/canvas-ngongrid.h"
128+
129+#include "ui/widget/registered-widget.h"
130+#include "desktop.h"
131+#include "desktop-handles.h"
132+#include "display/cairo-utils.h"
133+#include "display/canvas-grid.h"
134+#include "display/sp-canvas-util.h"
135+#include "display/sp-canvas.h"
136+#include "document.h"
137+#include "inkscape.h"
138+#include "preferences.h"
139+#include "sp-namedview.h"
140+#include "sp-object.h"
141+#include "svg/svg-color.h"
142+#include "2geom/line.h"
143+#include "2geom/angle.h"
144+#include "util/mathfns.h"
145+#include "round.h"
146+#include "helper/units.h"
147+
148+
149+/**
150+ * This function calls Cairo to render a line on a particular canvas buffer.
151+ * Coordinates are interpreted as SCREENcoordinates
152+ */
153+static void
154+sp_cngongrid_drawline (SPCanvasBuf *buf, gdouble x0, gdouble y0, gdouble x1, gdouble y1, guint32 rgba)
155+{
156+ // Prevent aliasing of horizontal/vertical lines
157+ if (Geom::are_near(x0, x1)) {
158+ x0 = round(x0);
159+ x1 = round(x1);
160+ }
161+ if (Geom::are_near(y0, y1)) {
162+ y0 = round(y0);
163+ y1 = round(y1);
164+ }
165+ //TODO: clip to viewport?
166+ cairo_move_to(buf->ct, 0.5 + x0, 0.5 + y0);
167+ cairo_line_to(buf->ct, 0.5 + x1, 0.5 + y1);
168+ ink_cairo_set_source_rgba32(buf->ct, rgba);
169+ cairo_stroke(buf->ct);
170+}
171+
172+static gdouble
173+distance(gdouble x, gdouble y, double dx, double dy)
174+{
175+ return (dy * x) - (dx * y);
176+}
177+
178+static gdouble
179+find_bound(Geom::Rect const &rect, double dx, double dy, gdouble const & (*bound_func)(gdouble const &, gdouble const &))
180+{
181+ // Note: Y+ is DOWN, not up!
182+ if ( (dx > 0.0) == (dy > 0.0) ) { // Interesting points are bottom-left, top-right
183+ gdouble const a = distance(rect.left(), rect.bottom(), dx, dy);
184+ gdouble const b = distance(rect.right(), rect.top(), dx, dy);
185+ return bound_func(a, b);
186+ } else { // Interesting points are top-left, bottom-right
187+ gdouble const a = distance(rect.left(), rect.top(), dx, dy);
188+ gdouble const b = distance(rect.right(), rect.bottom(), dx, dy);
189+ return bound_func(a, b);
190+ }
191+}
192+
193+namespace Inkscape {
194+
195+
196+/**
197+* A DIRECT COPY-PASTE FROM DOCUMENT-PROPERTIES.CPP TO QUICKLY GET RESULTS
198+*
199+ * Helper function that attachs widgets in a 3xn table. The widgets come in an
200+ * array that has two entries per table row. The two entries code for four
201+ * possible cases: (0,0) means insert space in first column; (0, non-0) means
202+ * widget in columns 2-3; (non-0, 0) means label in columns 1-3; and
203+ * (non-0, non-0) means two widgets in columns 2 and 3.
204+**/
205+#define SPACE_SIZE_X 15
206+#define SPACE_SIZE_Y 10
207+static inline void
208+attach_all(Gtk::Table &table, Gtk::Widget const *const arr[], unsigned size, int start = 0)
209+{
210+ for (unsigned i=0, r=start; i<size/sizeof(Gtk::Widget*); i+=2) {
211+ if (arr[i] && arr[i+1]) {
212+ table.attach (const_cast<Gtk::Widget&>(*arr[i]), 1, 2, r, r+1,
213+ Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
214+ table.attach (const_cast<Gtk::Widget&>(*arr[i+1]), 2, 3, r, r+1,
215+ Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
216+ } else {
217+ if (arr[i+1]) {
218+ table.attach (const_cast<Gtk::Widget&>(*arr[i+1]), 1, 3, r, r+1,
219+ Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
220+ } else if (arr[i]) {
221+ Gtk::Label& label = reinterpret_cast<Gtk::Label&> (const_cast<Gtk::Widget&>(*arr[i]));
222+ label.set_alignment (0.0);
223+ table.attach (label, 0, 3, r, r+1,
224+ Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
225+ } else {
226+ Gtk::HBox *space = manage (new Gtk::HBox);
227+ space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y);
228+ table.attach (*space, 0, 1, r, r+1,
229+ (Gtk::AttachOptions)0, (Gtk::AttachOptions)0,0,0);
230+ }
231+ }
232+ ++r;
233+ }
234+}
235+
236+CanvasNGonGrid::CanvasNGonGrid (SPNamedView * nv, Inkscape::XML::Node * in_repr, SPDocument * in_doc)
237+ : CanvasGrid(nv, in_repr, in_doc, GRID_POLYGONAL)
238+{
239+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
240+ gridunit = sp_unit_get_by_abbreviation( prefs->getString("/options/grids/ngon/units").data() );
241+ if (!gridunit)
242+ gridunit = &sp_unit_get_by_id(SP_UNIT_PX);
243+ origin[Geom::X] = sp_units_get_pixels( prefs->getDouble("/options/grids/ngon/origin_x", 0.0), *gridunit );
244+ origin[Geom::Y] = sp_units_get_pixels( prefs->getDouble("/options/grids/ngon/origin_y", 0.0), *gridunit );
245+ sections = prefs->getInt("/options/grids/ngon/sect_n", 8);
246+ lengthx = sp_units_get_pixels( prefs->getDouble("/options/grids/ngon/spacing_x", 1.0), *gridunit );
247+ lengthy = sp_units_get_pixels( prefs->getDouble("/options/grids/ngon/spacing_y", 1.0), *gridunit );
248+ angle_deg = prefs->getDouble("/options/grids/ngon/rotation", 0.0);
249+ color = prefs->getInt("/options/grids/ngon/color", 0x0000ff20);
250+ empcolor = prefs->getInt("/options/grids/ngon/empcolor", 0x0000ff40);
251+ empspacing = prefs->getInt("/options/grids/ngon/empspacing", 5);
252+
253+ angle_rad = Geom::deg_to_rad(angle_deg);
254+ se_angle_deg = 180.0 / sections;
255+ se_angle_rad = Geom::deg_to_rad(se_angle_deg);
256+ se_tan = tan(se_angle_rad);
257+
258+ snapper = new CanvasNGonGridSnapper(this, &namedview->snap_manager, 0);
259+
260+ if (repr) readRepr();
261+}
262+
263+CanvasNGonGrid::~CanvasNGonGrid ()
264+{
265+ if (snapper) delete snapper;
266+}
267+
268+
269+/* fixme: Collect all these length parsing methods and think common sane API */
270+
271+static gboolean sp_nv_read_length(gchar const *str, guint base, gdouble *val, SPUnit const **unit)
272+{
273+ if (!str) {
274+ return FALSE;
275+ }
276+
277+ gchar *u;
278+ gdouble v = g_ascii_strtod(str, &u);
279+ if (!u) {
280+ return FALSE;
281+ }
282+ while (isspace(*u)) {
283+ u += 1;
284+ }
285+
286+ if (!*u) {
287+ /* No unit specified - keep default */
288+ *val = v;
289+ return TRUE;
290+ }
291+
292+ if (base & SP_UNIT_DEVICE) {
293+ if (u[0] && u[1] && !isalnum(u[2]) && !strncmp(u, "px", 2)) {
294+ *unit = &sp_unit_get_by_id(SP_UNIT_PX);
295+ *val = v;
296+ return TRUE;
297+ }
298+ }
299+
300+ if (base & SP_UNIT_ABSOLUTE) {
301+ if (!strncmp(u, "pt", 2)) {
302+ *unit = &sp_unit_get_by_id(SP_UNIT_PT);
303+ } else if (!strncmp(u, "mm", 2)) {
304+ *unit = &sp_unit_get_by_id(SP_UNIT_MM);
305+ } else if (!strncmp(u, "cm", 2)) {
306+ *unit = &sp_unit_get_by_id(SP_UNIT_CM);
307+ } else if (!strncmp(u, "m", 1)) {
308+ *unit = &sp_unit_get_by_id(SP_UNIT_M);
309+ } else if (!strncmp(u, "in", 2)) {
310+ *unit = &sp_unit_get_by_id(SP_UNIT_IN);
311+ } else if (!strncmp(u, "ft", 2)) {
312+ *unit = &sp_unit_get_by_id(SP_UNIT_FT);
313+ } else if (!strncmp(u, "pc", 2)) {
314+ *unit = &sp_unit_get_by_id(SP_UNIT_PC);
315+ } else {
316+ return FALSE;
317+ }
318+ *val = v;
319+ return TRUE;
320+ }
321+
322+ return FALSE;
323+}
324+
325+static gboolean sp_nv_read_opacity(gchar const *str, guint32 *color)
326+{
327+ if (!str) {
328+ return FALSE;
329+ }
330+
331+ gchar *u;
332+ gdouble v = g_ascii_strtod(str, &u);
333+ if (!u) {
334+ return FALSE;
335+ }
336+ v = CLAMP(v, 0.0, 1.0);
337+
338+ *color = (*color & 0xffffff00) | (guint32) floor(v * 255.9999);
339+
340+ return TRUE;
341+}
342+
343+
344+
345+void
346+CanvasNGonGrid::readRepr()
347+{
348+ gchar const *value;
349+ if ( (value = repr->attribute("originx")) ) {
350+ sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &origin[Geom::X], &gridunit);
351+ origin[Geom::X] = sp_units_get_pixels(origin[Geom::X], *(gridunit));
352+ }
353+ if ( (value = repr->attribute("originy")) ) {
354+ sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &origin[Geom::Y], &gridunit);
355+ origin[Geom::Y] = sp_units_get_pixels(origin[Geom::Y], *(gridunit));
356+ }
357+
358+ if ( (value = repr->attribute("sections")) ) {
359+ sections = atoi(value);
360+ if (sections < 3) sections = 3;
361+ if (sections > 360) sections = 360;
362+ se_angle_deg = 180.0 / sections;
363+ se_angle_rad = Geom::deg_to_rad(se_angle_deg);
364+ se_tan = tan(se_angle_rad);
365+ }
366+
367+ if ( (value = repr->attribute("spacingx")) ) {
368+ sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &lengthx, &gridunit);
369+ lengthx = sp_units_get_pixels(lengthx, *(gridunit));
370+ if (lengthx < 0.0500) lengthx = 0.0500;
371+ }
372+
373+ if ( (value = repr->attribute("spacingy")) ) {
374+ sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &lengthy, &gridunit);
375+ lengthy = sp_units_get_pixels(lengthy, *(gridunit));
376+ if (lengthy < 0.0500) lengthy = 0.0500;
377+ }
378+
379+ if ( (value = repr->attribute("rotation")) ) {
380+ angle_deg = g_ascii_strtod(value, NULL);
381+ double max_angle = 360.0 / sections;
382+ if (fabs(angle_deg) > max_angle) angle_deg = fmod(angle_deg, max_angle);
383+ angle_rad = Geom::deg_to_rad(angle_deg);
384+ }
385+
386+ if ( (value = repr->attribute("color")) ) {
387+ color = (color & 0xff) | sp_svg_read_color(value, color);
388+ }
389+
390+ if ( (value = repr->attribute("empcolor")) ) {
391+ empcolor = (empcolor & 0xff) | sp_svg_read_color(value, empcolor);
392+ }
393+
394+ if ( (value = repr->attribute("opacity")) ) {
395+ sp_nv_read_opacity(value, &color);
396+ }
397+ if ( (value = repr->attribute("empopacity")) ) {
398+ sp_nv_read_opacity(value, &empcolor);
399+ }
400+
401+ if ( (value = repr->attribute("empspacing")) ) {
402+ empspacing = atoi(value);
403+ }
404+
405+ if ( (value = repr->attribute("visible")) ) {
406+ visible = (strcmp(value,"false") != 0 && strcmp(value, "0") != 0);
407+ }
408+
409+ if ( (value = repr->attribute("enabled")) ) {
410+ g_assert(snapper != NULL);
411+ snapper->setEnabled(strcmp(value,"false") != 0 && strcmp(value, "0") != 0);
412+ }
413+
414+ if ( (value = repr->attribute("snapvisiblegridlinesonly")) ) {
415+ g_assert(snapper != NULL);
416+ snapper->setSnapVisibleOnly(strcmp(value,"false") != 0 && strcmp(value, "0") != 0);
417+ }
418+
419+ for (GSList *l = canvasitems; l != NULL; l = l->next) {
420+ sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) );
421+ }
422+ return;
423+}
424+
425+/**
426+ * Called when XML node attribute changed; updates dialog widgets if change was not done by widgets themselves.
427+ */
428+void
429+CanvasNGonGrid::onReprAttrChanged(Inkscape::XML::Node */*repr*/, gchar const */*key*/, gchar const */*oldval*/, gchar const */*newval*/, bool /*is_interactive*/)
430+{
431+ readRepr();
432+
433+ if ( ! (_wr.isUpdating()) )
434+ updateWidgets();
435+}
436+
437+
438+
439+
440+Gtk::Widget *
441+CanvasNGonGrid::newSpecificWidget()
442+{
443+ Gtk::Table * table = Gtk::manage( new Gtk::Table(1,1) );
444+ table->set_spacings(2);
445+
446+_wr.setUpdating (true);
447+
448+ Inkscape::UI::Widget::RegisteredUnitMenu *_rumg = Gtk::manage( new Inkscape::UI::Widget::RegisteredUnitMenu(
449+ _("Grid _units:"), "units", _wr, repr, doc) );
450+ Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_ox = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit(
451+ _("_Origin X:"), _("X coordinate of grid origin"), "originx", *_rumg, _wr, repr, doc) );
452+ Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_oy = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit(
453+ _("O_rigin Y:"), _("Y coordinate of grid origin"), "originy", *_rumg, _wr, repr, doc) );
454+ Inkscape::UI::Widget::RegisteredScalar *_rsu_ns = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar(
455+ _("_Number of sections:"), "", "sections", _wr, repr, doc ) );
456+ Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_sx = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit(
457+ _("Spacing _X:"), _("Distance between concentric grid polygons"), "spacingx", *_rumg, _wr, repr, doc) );
458+ Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_sy = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit(
459+ _("Spacing _Y:"), _("Distance between semi-radial grid lines"), "spacingy", *_rumg, _wr, repr, doc) );
460+ Inkscape::UI::Widget::RegisteredScalar *_rsu_ar = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar(
461+ _("Ro_tation:"), _("Angle of axis rotation"), "rotation", _wr, repr, doc ) );
462+
463+ Inkscape::UI::Widget::RegisteredColorPicker *_rcp_gcol = Gtk::manage(
464+ new Inkscape::UI::Widget::RegisteredColorPicker(
465+ _("Minor grid line _color:"), _("Minor grid line color"), _("Color of the minor grid lines"),
466+ "color", "opacity", _wr, repr, doc));
467+
468+ Inkscape::UI::Widget::RegisteredColorPicker *_rcp_gmcol = Gtk::manage(
469+ new Inkscape::UI::Widget::RegisteredColorPicker(
470+ _("Ma_jor grid line color:"), _("Major grid line color"),
471+ _("Color of the major (highlighted) grid lines"),
472+ "empcolor", "empopacity", _wr, repr, doc));
473+
474+ Inkscape::UI::Widget::RegisteredSuffixedInteger *_rsi = Gtk::manage( new Inkscape::UI::Widget::RegisteredSuffixedInteger(
475+ _("_Major grid line every:"), "", _("lines"), "empspacing", _wr, repr, doc ) );
476+
477+ _rsu_ox->setDigits(5);
478+ _rsu_ox->setIncrements(0.1, 1.0);
479+
480+ _rsu_oy->setDigits(5);
481+ _rsu_oy->setIncrements(0.1, 1.0);
482+
483+ _rsu_ns->setDigits(0);
484+ _rsu_ns->setIncrements(1, 3);
485+
486+ _rsu_sx->setDigits(5);
487+ _rsu_sx->setIncrements(0.1, 1.0);
488+
489+ _rsu_sy->setDigits(5);
490+ _rsu_sy->setIncrements(0.1, 1.0);
491+
492+ _rsu_ar->setDigits(5);
493+ _rsu_ar->setIncrements(0.5, 5.0);
494+
495+_wr.setUpdating (false);
496+
497+ Gtk::Widget const *const widget_array[] = {
498+ 0, _rumg,
499+ 0, _rsu_ox,
500+ 0, _rsu_oy,
501+ 0, _rsu_ns,
502+ 0, _rsu_sx,
503+ 0, _rsu_sy,
504+ 0, _rsu_ar,
505+ _rcp_gcol->_label, _rcp_gcol,
506+ 0, 0,
507+ _rcp_gmcol->_label, _rcp_gmcol,
508+ 0, _rsi,
509+ };
510+
511+ attach_all (*table, widget_array, sizeof(widget_array));
512+
513+ // set widget values
514+ _rumg->setUnit (gridunit);
515+
516+ gdouble val;
517+ val = origin[Geom::X];
518+ val = sp_pixels_get_units (val, *(gridunit));
519+ _rsu_ox->setValue (val);
520+ val = origin[Geom::Y];
521+ val = sp_pixels_get_units (val, *(gridunit));
522+ _rsu_oy->setValue (val);
523+ _rsu_ns->setValue (sections);
524+ val = lengthx;
525+ double gridx = sp_pixels_get_units (val, *(gridunit));
526+ _rsu_sx->setValue (gridx);
527+ val = lengthy;
528+ double gridy = sp_pixels_get_units (val, *(gridunit));
529+ _rsu_sy->setValue (gridy);
530+
531+ _rsu_ar->setValue(angle_deg);
532+
533+ _rcp_gcol->setRgba32 (color);
534+ _rcp_gmcol->setRgba32 (empcolor);
535+ _rsi->setValue (empspacing);
536+
537+ return table;
538+}
539+
540+
541+/**
542+ * Update dialog widgets from object's values.
543+ */
544+void
545+CanvasNGonGrid::updateWidgets()
546+{
547+/* if (_wr.isUpdating()) return;
548+
549+ _wr.setUpdating (true);
550+
551+ _rcb_visible.setActive(visible);
552+ if (snapper != NULL) {
553+ _rcb_enabled.setActive(snapper->getEnabled());
554+ }
555+
556+ _rumg.setUnit (gridunit);
557+
558+ gdouble val;
559+ val = origin[Geom::X];
560+ val = sp_pixels_get_units (val, *(gridunit));
561+ _rsu_ox->setValue (val);
562+ val = origin[Geom::Y];
563+ val = sp_pixels_get_units (val, *(gridunit));
564+ _rsu_oy->setValue (val);
565+ val = lengthx;
566+ double gridx = sp_pixels_get_units (val, *(gridunit));
567+ _rsu_sx->setValue (gridx);
568+ val = lengthy;
569+ double gridy = sp_pixels_get_units (val, *(gridunit));
570+ _rsu_sy->setValue (gridy);
571+
572+ _rsu_ar->setValue(angle_deg);
573+
574+ _rcp_gcol->setRgba32 (color);
575+ _rcp_gmcol->setRgba32 (empcolor);
576+ _rsi->setValue (empspacing);
577+
578+ _wr.setUpdating (false);
579+
580+ return;
581+ */
582+}
583+
584+
585+
586+void
587+CanvasNGonGrid::Update (Geom::Affine const &affine, unsigned int /*flags*/)
588+{
589+ ow = origin * affine;
590+ sw = Geom::Point(fabs(affine[0]),fabs(affine[3]));
591+ sw[Geom::X] *= lengthx;
592+ sw[Geom::Y] *= lengthy;
593+
594+ scaled = false;
595+
596+ for(int dim = 0; dim < 2; dim++) {
597+ gint scaling_factor = empspacing;
598+
599+ if (scaling_factor <= 1)
600+ scaling_factor = 5;
601+
602+ int watchdog = 0;
603+ while ( (sw[dim] < 8.0) & (watchdog < 100) ) {
604+ scaled = true;
605+ sw[dim] *= scaling_factor;
606+ // First pass, go up to the major line spacing, then
607+ // keep increasing by two.
608+ scaling_factor = 2;
609+ watchdog++;
610+ }
611+
612+ }
613+
614+ lxw = sw[Geom::X];
615+ lyw = sw[Geom::Y];
616+
617+ if (empspacing == 0) {
618+ scaled = true;
619+ }
620+}
621+
622+void
623+CanvasNGonGrid::Render (SPCanvasBuf *buf)
624+{
625+ //set correct coloring, depending preference (when zoomed out, always major coloring or minor coloring)
626+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
627+ guint32 _empcolor;
628+ bool preference = prefs->getBool("/options/grids/no_emphasize_when_zoomedout", false);
629+ if( scaled && preference ) {
630+ _empcolor = color;
631+ } else {
632+ _empcolor = empcolor;
633+ }
634+
635+ cairo_save(buf->ct);
636+ cairo_translate(buf->ct, -buf->rect.left(), -buf->rect.top());
637+ cairo_set_line_width(buf->ct, 1.0);
638+ cairo_set_line_cap(buf->ct, CAIRO_LINE_CAP_SQUARE);
639+
640+ double angle_step = 360.0 / sections;
641+ for (int s = 0; s < sections; ++s) {
642+ //TODO: get angles from origin to viewport corners, use to test if section needs to be rendered
643+ renderSection(buf, (s * angle_step) - angle_deg, _empcolor);
644+ }
645+
646+ cairo_restore(buf->ct);
647+}
648+
649+void
650+CanvasNGonGrid::renderSection (SPCanvasBuf *buf, double section_angle_deg, guint32 _empcolor)
651+{
652+ // pc = preimagecoordinates (the coordinates of the section before rotation)
653+ // gc = gridcoordinates (the coordinates calculated from the grids origin 'grid->ow')
654+
655+ Geom::Rect buf_gc(buf->rect);
656+ buf_gc -= ow;
657+
658+ double const section_angle_rad = Geom::deg_to_rad(section_angle_deg);
659+ double const section_sin = sin(section_angle_rad);
660+ double const section_cos = cos(section_angle_rad);
661+
662+ gdouble xmin = find_bound(buf_gc, -section_sin, section_cos, &std::min) / lxw;
663+ gdouble xmax = find_bound(buf_gc, -section_sin, section_cos, &std::max) / lxw;
664+ if (xmax <= 0) return; // Section is entirely out of viewport
665+
666+ gdouble ymin = find_bound(buf_gc, -section_cos, -section_sin, &std::min) / lyw;
667+ gdouble ymax = find_bound(buf_gc, -section_cos, -section_sin, &std::max) / lyw;
668+
669+ gdouble const lxmax = xmax * lxw;
670+ gdouble const xbound = (floor(xmax) + 0.5) * lxw;
671+ gdouble const ybound = (floor(ymax) + 0.5) * lyw;
672+
673+ // Render section edge line
674+ {
675+ gdouble const pc_x = lxmax;
676+ gdouble const pc_y = lxmax * se_tan;
677+ gdouble const gc_x1 = ( (pc_x * section_cos) - (pc_y * section_sin) ) + ow[Geom::X];
678+ gdouble const gc_y1 = ( (pc_x * section_sin) + (pc_y * section_cos) ) + ow[Geom::Y];
679+ sp_cngongrid_drawline (buf, ow[Geom::X], ow[Geom::Y], gc_x1, gc_y1, color);
680+ }
681+
682+ // Render semi-radius lines
683+ ymin = ceil(ymin);
684+ gint xlinenum = ymin;
685+ for (gdouble y = ymin * lyw; y <= ybound; y += lyw, xlinenum++) {
686+ // Compute points in preimage coordinates
687+ gdouble const pc_x0 = fabs(y) / se_tan;
688+ gdouble const pc_x1 = lxmax;
689+ if (pc_x1 <= pc_x0) continue;
690+ // Compute points in grid coordinates (with rotation applied)
691+ gdouble const ys = y * section_sin;
692+ gdouble const yc = y * section_cos;
693+ gdouble const gc_x0 = ( (pc_x0 * section_cos) - ys ) + ow[Geom::X];
694+ gdouble const gc_x1 = ( (pc_x1 * section_cos) - ys ) + ow[Geom::X];
695+ gdouble const gc_y0 = ( (pc_x0 * section_sin) + yc ) + ow[Geom::Y];
696+ gdouble const gc_y1 = ( (pc_x1 * section_sin) + yc ) + ow[Geom::Y];
697+ // Draw segment
698+ guint32 const _color = ( (!scaled && (xlinenum % empspacing) != 0) ? color : _empcolor);
699+ sp_cngongrid_drawline (buf, gc_x0, gc_y0, gc_x1, gc_y1, _color);
700+ }
701+
702+ // Render concentric lines
703+ xmin = std::max(1.0, ceil(xmin));
704+ gint ylinenum = xmin;
705+ for (gdouble x = xmin * lxw; x < xbound; x += lxw, ylinenum++) {
706+ // Compute points in preimage coordinates
707+ gdouble const pc_y = x * se_tan;
708+ // Compute points in grid coordinates (with rotation applied)
709+ gdouble const xs = x * section_sin;
710+ gdouble const xc = x * section_cos;
711+ gdouble const ys = pc_y * section_sin;
712+ gdouble const yc = pc_y * section_cos;
713+ gdouble const gc_x0 = xc + ys + ow[Geom::X];
714+ gdouble const gc_x1 = xc - ys + ow[Geom::X];
715+ gdouble const gc_y0 = xs - yc + ow[Geom::Y];
716+ gdouble const gc_y1 = xs + yc + ow[Geom::Y];
717+ // Draw segment
718+ guint32 const _color = ( (!scaled && (ylinenum % empspacing) != 0) ? color : _empcolor);
719+ sp_cngongrid_drawline (buf, gc_x0, gc_y0, gc_x1, gc_y1, _color);
720+ }
721+}
722+
723+CanvasNGonGridSnapper::CanvasNGonGridSnapper(CanvasNGonGrid *grid, SnapManager *sm, Geom::Coord const d) : LineSnapper(sm, d)
724+{
725+ this->grid = grid;
726+}
727+
728+/**
729+ * \return Snap tolerance (desktop coordinates); depends on current zoom so that it's always the same in screen pixels
730+ */
731+Geom::Coord CanvasNGonGridSnapper::getSnapperTolerance() const
732+{
733+ SPDesktop const *dt = _snapmanager->getDesktop();
734+ double const zoom = dt ? dt->current_zoom() : 1;
735+ return _snapmanager->snapprefs.getGridTolerance() / zoom;
736+}
737+
738+bool CanvasNGonGridSnapper::getSnapperAlwaysSnap() const
739+{
740+ return _snapmanager->snapprefs.getGridTolerance() == 10000; //TODO: Replace this threshold of 10000 by a constant; see also tolerance-slider.cpp
741+}
742+
743+LineSnapper::LineList
744+CanvasNGonGridSnapper::_getSnapLines(Geom::Point const &p) const
745+{
746+ LineList s;
747+
748+ if ( grid == NULL ) {
749+ return s;
750+ }
751+
752+ double spacing_h;
753+ double spacing_v;
754+
755+ if (getSnapVisibleOnly()) {
756+ // Only snapping to visible grid lines
757+ spacing_h = grid->lxw; // horizontal
758+ spacing_v = grid->lyw; // vertical
759+ // convert screen pixels to px
760+ // FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary
761+ SPDesktop const *dt = _snapmanager->getDesktop();
762+ if (dt) {
763+ spacing_h /= dt->current_zoom();
764+ spacing_v /= dt->current_zoom();
765+ }
766+ } else {
767+ // Snapping to any grid line, whether it's visible or not
768+ spacing_h = grid->lengthx;
769+ spacing_v = grid->lengthy;
770+ }
771+
772+ // In a polygonal grid, any point will be surrounded by 6 grid lines:
773+ // - 4 lines of a section grid
774+ // - 2 lines of the section edges
775+ // Of these, we use the closer section edge, and the closer each of the grid X and Y lines
776+
777+ // Calculate what section the point is in
778+ Geom::Point gc_point = p - grid->origin;
779+ double point_angle_rad;
780+ bool const x_is_zero = Geom::are_near(gc_point[Geom::X], 0.);
781+ bool const y_is_zero = Geom::are_near(gc_point[Geom::Y], 0.);
782+ if (Geom::are_near(p, grid->origin))
783+ point_angle_rad = 0;
784+ else
785+ point_angle_rad = Geom::atan2(gc_point);
786+ double const section_ratio = (point_angle_rad - grid->angle_rad - grid->se_angle_rad) / (2.0 * M_PI);
787+ int const section = floor( grid->sections * section_ratio ) + 1;
788+
789+ // Compute spacing-unit vectors for section
790+ double const section_angle_rad = (2.0 * section * grid->se_angle_rad) + grid->angle_rad;
791+ double const section_sin = sin(section_angle_rad);
792+ double const section_cos = cos(section_angle_rad);
793+ Geom::Point const gc_nx(-section_sin, section_cos);
794+ Geom::Point const gc_ny( section_cos, section_sin);
795+ Geom::Point const gc_sx = gc_ny * spacing_h;
796+ Geom::Point const gc_sy = gc_nx * spacing_v;
797+
798+ // Get point in section pre-image space
799+ double const pc_x = ( (gc_point[Geom::Y] * section_sin) + (gc_point[Geom::X] * section_cos) ) / spacing_h;
800+ double const pc_y = ( (gc_point[Geom::Y] * section_cos) - (gc_point[Geom::X] * section_sin) ) / spacing_v;
801+
802+ // Add the nearer section edge line
803+ double const section_edge_angle_rad = section_angle_rad + ( (pc_y > 0.0 ? 1.0 : -1.0) * grid->se_angle_rad);
804+ Geom::Point const section_edge_norm(-sin(section_edge_angle_rad), cos(section_edge_angle_rad));
805+ s.push_back( std::make_pair(section_edge_norm, grid->origin) );
806+
807+ // Add the two nearer lines of the grid square
808+ Geom::Point const gc_corner = (gc_sx * round(pc_x)) + (gc_sy * round(pc_y)) + grid->origin;
809+ s.push_back( std::make_pair(gc_nx, gc_corner) );
810+ s.push_back( std::make_pair(gc_ny, gc_corner) );
811+
812+ return s;
813+}
814+
815+void CanvasNGonGridSnapper::_addSnappedLine(IntermSnapResults &isr, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
816+{
817+ SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, source_num, Inkscape::SNAPTARGET_GRID, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
818+ isr.grid_lines.push_back(dummy);
819+}
820+
821+void CanvasNGonGridSnapper::_addSnappedPoint(IntermSnapResults &isr, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, bool constrained_snap) const
822+{
823+ SnappedPoint dummy = SnappedPoint(snapped_point, source, source_num, Inkscape::SNAPTARGET_GRID, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), constrained_snap, true);
824+ isr.points.push_back(dummy);
825+}
826+
827+void CanvasNGonGridSnapper::_addSnappedLinePerpendicularly(IntermSnapResults &isr, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, bool constrained_snap) const
828+{
829+ SnappedPoint dummy = SnappedPoint(snapped_point, source, source_num, Inkscape::SNAPTARGET_GRID_PERPENDICULAR, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), constrained_snap, true);
830+ isr.points.push_back(dummy);
831+}
832+
833+bool CanvasNGonGridSnapper::ThisSnapperMightSnap() const
834+{
835+ return _snap_enabled && _snapmanager->snapprefs.isTargetSnappable(Inkscape::SNAPTARGET_GRID);
836+}
837+
838+
839+}; // namespace Inkscape
840+
841+
842+/*
843+ Local Variables:
844+ mode:c++
845+ c-file-style:"stroustrup"
846+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
847+ indent-tabs-mode:nil
848+ fill-column:99
849+ End:
850+*/
851+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
852
853=== added file 'src/display/canvas-ngongrid.h'
854--- src/display/canvas-ngongrid.h 1970-01-01 00:00:00 +0000
855+++ src/display/canvas-ngongrid.h 2016-04-29 07:04:20 +0000
856@@ -0,0 +1,94 @@
857+#ifndef CANVAS_NGONGRID_H
858+#define CANVAS_NGONGRID_H
859+
860+/*
861+ * Authors:
862+ * Matthew Woehlke <mw_triad@users.sourceforge.net>
863+ * Johan Engelen <j.b.c.engelen@alumnus.utwente.nl>
864+ *
865+ * Copyright (C) 2006-2012 Authors
866+ * Released under GNU GPL, read the file 'COPYING' for more information
867+ */
868+
869+#include "line-snapper.h"
870+#include "canvas-grid.h"
871+
872+class SPCanvasBuf;
873+class SPDesktop;
874+struct SPNamedView;
875+
876+namespace Inkscape {
877+namespace XML {
878+ class Node;
879+};
880+
881+class CanvasNGonGrid : public CanvasGrid {
882+public:
883+ CanvasNGonGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr, SPDocument * in_doc);
884+ virtual ~CanvasNGonGrid();
885+
886+ void Update (Geom::Affine const &affine, unsigned int flags);
887+ void Render (SPCanvasBuf *buf);
888+
889+ void readRepr();
890+ void onReprAttrChanged (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive);
891+
892+ int sections; /**< Number of grid sections */
893+ double lengthx; /**< Step size along concentric polygons */
894+ double lengthy; /**< Step size along semi-radius lines */
895+ double angle_deg; /**< Angle of rotation (degrees) */
896+ double angle_rad; /**< Angle of rotation (radians) */
897+ double se_angle_deg; /**< Half of section arc (degrees) */
898+ double se_angle_rad; /**< Half of section arc (radians) */
899+ double se_tan; /**< tan(se_angle) */
900+
901+ bool scaled; /**< Whether the grid is in scaled mode */
902+
903+protected:
904+ friend class CanvasNGonGridSnapper;
905+
906+ Geom::Point ow; /**< Transformed origin by the affine for the zoom */
907+ double lxw; /**< Transformed length x by the affine for the zoom */
908+ double lyw; /**< Transformed length y by the affine for the zoom */
909+
910+ Geom::Point sw; /**< the scaling factors of the affine transform */
911+
912+ virtual Gtk::Widget * newSpecificWidget();
913+
914+private:
915+ CanvasNGonGrid(const CanvasNGonGrid&);
916+ CanvasNGonGrid& operator=(const CanvasNGonGrid&);
917+
918+ void updateWidgets();
919+
920+ void renderSection (SPCanvasBuf *buf, double section_angle_deg, guint32 _empcolor);
921+};
922+
923+
924+
925+class CanvasNGonGridSnapper : public LineSnapper
926+{
927+public:
928+ CanvasNGonGridSnapper(CanvasNGonGrid *grid, SnapManager *sm, Geom::Coord const d);
929+ bool ThisSnapperMightSnap() const;
930+
931+ Geom::Coord getSnapperTolerance() const; //returns the tolerance of the snapper in screen pixels (i.e. independent of zoom)
932+ bool getSnapperAlwaysSnap() const; //if true, then the snapper will always snap, regardless of its tolerance
933+
934+private:
935+ LineList _getSnapLines(Geom::Point const &p) const;
936+ void _addSnappedLine(IntermSnapResults &isr, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, Geom::Point const normal_to_line, const Geom::Point point_on_line) const;
937+ void _addSnappedPoint(IntermSnapResults &isr, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, bool constrained_snap) const;
938+ void _addSnappedLinePerpendicularly(IntermSnapResults &isr, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, long source_num, bool constrained_snap) const;
939+
940+ CanvasNGonGrid *grid;
941+};
942+
943+
944+}; //namespace Inkscape
945+
946+
947+
948+#endif
949+
950+
951
952=== modified file 'src/ui/dialog/document-properties.cpp'
953--- src/ui/dialog/document-properties.cpp 2016-02-21 21:44:25 +0000
954+++ src/ui/dialog/document-properties.cpp 2016-04-29 07:04:20 +0000
955@@ -1386,6 +1386,8 @@
956 case GRID_AXONOMETRIC:
957 icon = "grid-axonometric";
958 break;
959+ case GRID_POLYGONAL:
960+ icon = "grid-polygonal";
961 default:
962 break;
963 }
964
965=== modified file 'src/ui/dialog/inkscape-preferences.cpp'
966--- src/ui/dialog/inkscape-preferences.cpp 2016-04-12 10:28:18 +0000
967+++ src/ui/dialog/inkscape-preferences.cpp 2016-04-29 07:04:20 +0000
968@@ -514,7 +514,7 @@
969 this->AddPage(_page_dropper, _("Dropper"), iter_tools, PREFS_PAGE_TOOLS_DROPPER);
970 this->AddSelcueCheckbox(_page_dropper, "/tools/dropper", true);
971 this->AddGradientCheckbox(_page_dropper, "/tools/dropper", true);
972-
973+
974 //Connector
975 this->AddPage(_page_connector, _("Connector"), iter_tools, PREFS_PAGE_TOOLS_CONNECTOR);
976 this->AddSelcueCheckbox(_page_connector, "/tools/connector", true);
977@@ -689,7 +689,7 @@
978
979 _win_native.init ( _("Native open/save dialogs"), "/options/desktopintegration/value", 1, true, 0);
980 _win_gtk.init ( _("GTK open/save dialogs"), "/options/desktopintegration/value", 0, false, &_win_native);
981-
982+
983 _win_hide_task.init ( _("Dialogs are hidden in taskbar"), "/options/dialogsskiptaskbar/value", true);
984 _win_save_viewport.init ( _("Save and restore documents viewport"), "/options/savedocviewport/value", true);
985 _win_zoom_resize.init ( _("Zoom when window is resized"), "/options/stickyzoom/value", false);
986@@ -782,6 +782,7 @@
987 _page_grids.add_line( true, "", _grids_notebook, "", "", false);
988 _grids_notebook.append_page(_grids_xy, CanvasGrid::getName( GRID_RECTANGULAR ));
989 _grids_notebook.append_page(_grids_axonom, CanvasGrid::getName( GRID_AXONOMETRIC ));
990+ _grids_notebook.append_page(_grids_ngon, CanvasGrid::getName( GRID_POLYGONAL ));
991 _grids_xy_units.init("/options/grids/xy/units");
992 _grids_xy.add_line( false, _("Grid units:"), _grids_xy_units, "", "", false);
993 _grids_xy_origin_x.init("/options/grids/xy/origin_x", -10000.0, 10000.0, 0.1, 1.0, 0.0, false, false);
994@@ -829,6 +830,33 @@
995 _grids_axonom_empspacing.init("/options/grids/axonom/empspacing", 1.0, 1000.0, 1.0, 5.0, 5.0, true, false);
996 _grids_axonom.add_line( false, _("Major grid line every:"), _grids_axonom_empspacing, "", "", false);
997
998+ // CanvasNGonGrid properties:
999+ _grids_ngon_units.init("/options/grids/ngon/units");
1000+ _grids_ngon.add_line( false, _("Grid units:"), _grids_ngon_units, "", "", false);
1001+ _grids_ngon_origin_x.init("/options/grids/ngon/origin_x", -10000.0, 10000.0, 0.1, 1.0, 0.0, false, false);
1002+ _grids_ngon_origin_y.init("/options/grids/ngon/origin_y", -10000.0, 10000.0, 0.1, 1.0, 0.0, false, false);
1003+ _grids_ngon_origin_x.set_digits(5);
1004+ _grids_ngon_origin_y.set_digits(5);
1005+ _grids_ngon.add_line( false, _("Origin X:"), _grids_ngon_origin_x, "", _("X coordinate of grid origin"), false);
1006+ _grids_ngon.add_line( false, _("Origin Y:"), _grids_ngon_origin_y, "", _("Y coordinate of grid origin"), false);
1007+ _grids_ngon_sect_n.init("/options/grids/ngon/sect_n", 3.0, 360.0, 1.0, 3.0, 8.0, true, false);
1008+ _grids_ngon.add_line( false, _("Number of sections:"), _grids_ngon_empspacing, "", "", false);
1009+ _grids_ngon_spacing_x.init("/options/grids/ngon/spacing_x", 0.0, 10000.0, 0.1, 1.0, 1.0, false, false);
1010+ _grids_ngon_spacing_y.init("/options/grids/ngon/spacing_y", 0.0, 10000.0, 0.1, 1.0, 1.0, false, false);
1011+ _grids_ngon_spacing_x.set_digits(5);
1012+ _grids_ngon_spacing_y.set_digits(5);
1013+ _grids_ngon.add_line( false, _("Spacing X:"), _grids_ngon_spacing_x, "", _("Distance between concentric grid polygons"), false);
1014+ _grids_ngon.add_line( false, _("Spacing Y:"), _grids_ngon_spacing_y, "", _("Distance between semi-radial grid lines"), false);
1015+ _grids_ngon_rotation.init("/options/grids/ngon/rotation", -360.0, 360.0, 1.0, 0.0, 0.0, false, false);
1016+ _grids_ngon_rotation.set_digits(5);
1017+ _grids_ngon.add_line( false, _("Rotation:"), _grids_ngon_rotation, "", _("Angle of axis rotation"), false);
1018+ _grids_ngon_color.init(_("Minor grid line color:"), "/options/grids/ngon/color", 0x0000ff20);
1019+ _grids_ngon.add_line( false, _("Minor grid line color:"), _grids_ngon_color, "", _("Color used for normal grid lines"), false);
1020+ _grids_ngon_empcolor.init(_("Major grid line color:"), "/options/grids/ngon/empcolor", 0x0000ff40);
1021+ _grids_ngon.add_line( false, _("Major grid line color:"), _grids_ngon_empcolor, "", _("Color used for major (highlighted) grid lines"), false);
1022+ _grids_ngon_empspacing.init("/options/grids/ngon/empspacing", 1.0, 1000.0, 1.0, 5.0, 5.0, true, false);
1023+ _grids_ngon.add_line( false, _("Major grid line every:"), _grids_ngon_empspacing, "", "", false);
1024+
1025 this->AddPage(_page_grids, _("Grids"), iter_ui, PREFS_PAGE_UI_GRIDS);
1026
1027 initKeyboardShortcuts(iter_ui);
1028@@ -1377,28 +1405,28 @@
1029 _mask_mask_remove.init ( _("Remove clippath/mask object after applying"), "/options/maskobject/remove", true);
1030 _page_mask.add_line(false, "", _mask_mask_remove, "",
1031 _("After applying, remove the object used as the clipping path or mask from the drawing"));
1032-
1033+
1034 _page_mask.add_group_header( _("Before applying"));
1035-
1036+
1037 _mask_grouping_none.init( _("Do not group clipped/masked objects"), "/options/maskobject/grouping", PREFS_MASKOBJECT_GROUPING_NONE, true, 0);
1038 _mask_grouping_separate.init( _("Put every clipped/masked object in its own group"), "/options/maskobject/grouping", PREFS_MASKOBJECT_GROUPING_SEPARATE, false, &_mask_grouping_none);
1039 _mask_grouping_all.init( _("Put all clipped/masked objects into one group"), "/options/maskobject/grouping", PREFS_MASKOBJECT_GROUPING_ALL, false, &_mask_grouping_none);
1040-
1041+
1042 _page_mask.add_line(true, "", _mask_grouping_none, "",
1043 _("Apply clippath/mask to every object"));
1044-
1045+
1046 _page_mask.add_line(true, "", _mask_grouping_separate, "",
1047 _("Apply clippath/mask to groups containing single object"));
1048-
1049+
1050 _page_mask.add_line(true, "", _mask_grouping_all, "",
1051 _("Apply clippath/mask to group containing all objects"));
1052-
1053+
1054 _page_mask.add_group_header( _("After releasing"));
1055-
1056+
1057 _mask_ungrouping.init ( _("Ungroup automatically created groups"), "/options/maskobject/ungrouping", true);
1058 _page_mask.add_line(true, "", _mask_ungrouping, "",
1059 _("Ungroup groups created when setting clip/mask"));
1060-
1061+
1062 this->AddPage(_page_mask, _("Clippaths and masks"), iter_behavior, PREFS_PAGE_BEHAVIOR_MASKS);
1063
1064
1065@@ -1896,15 +1924,20 @@
1066
1067 /* the returned pointer should _not_ need to be deleted */
1068 AspellDictInfoList *dlist = get_aspell_dict_info_list(config);
1069-
1070+
1071 /* config is no longer needed */
1072 delete_aspell_config(config);
1073-
1074+
1075 AspellDictInfoEnumeration *dels = aspell_dict_info_list_elements(dlist);
1076+<<<<<<< TREE
1077
1078 languages.push_back(Glib::ustring(C_("Spellchecker language", "None")));
1079+=======
1080+
1081+ languages.push_back(Glib::ustring(_("None")));
1082+>>>>>>> MERGE-SOURCE
1083 langValues.push_back(Glib::ustring(""));
1084-
1085+
1086 const AspellDictInfo *entry;
1087 int en_index = 0;
1088 int i = 0;
1089
1090=== modified file 'src/ui/dialog/inkscape-preferences.h'
1091--- src/ui/dialog/inkscape-preferences.h 2016-03-02 19:44:36 +0000
1092+++ src/ui/dialog/inkscape-preferences.h 2016-04-29 07:04:20 +0000
1093@@ -411,6 +411,7 @@
1094 UI::Widget::PrefRadioButton _grids_emphasize_on_zoom;
1095 UI::Widget::DialogPage _grids_xy;
1096 UI::Widget::DialogPage _grids_axonom;
1097+ UI::Widget::DialogPage _grids_ngon;
1098 // CanvasXYGrid properties:
1099 UI::Widget::PrefUnit _grids_xy_units;
1100 UI::Widget::PrefSpinButton _grids_xy_origin_x;
1101@@ -431,6 +432,17 @@
1102 UI::Widget::PrefColorPicker _grids_axonom_color;
1103 UI::Widget::PrefColorPicker _grids_axonom_empcolor;
1104 UI::Widget::PrefSpinButton _grids_axonom_empspacing;
1105+ // CanvasNGonGrid properties:
1106+ UI::Widget::PrefUnit _grids_ngon_units;
1107+ UI::Widget::PrefSpinButton _grids_ngon_origin_x;
1108+ UI::Widget::PrefSpinButton _grids_ngon_origin_y;
1109+ UI::Widget::PrefSpinButton _grids_ngon_sect_n;
1110+ UI::Widget::PrefSpinButton _grids_ngon_spacing_x;
1111+ UI::Widget::PrefSpinButton _grids_ngon_spacing_y;
1112+ UI::Widget::PrefSpinButton _grids_ngon_rotation;
1113+ UI::Widget::PrefColorPicker _grids_ngon_color;
1114+ UI::Widget::PrefColorPicker _grids_ngon_empcolor;
1115+ UI::Widget::PrefSpinButton _grids_ngon_empspacing;
1116
1117 // SVG Output page:
1118 UI::Widget::PrefCheckButton _svgoutput_usenamedcolors;