Merge lp:~inkscape.dev/inkscape/knot_improvements into lp:~inkscape.dev/inkscape/trunk

Proposed by Jabiertxof
Status: Merged
Merge reported by: Jabiertxof
Merged at revision: not available
Proposed branch: lp:~inkscape.dev/inkscape/knot_improvements
Merge into: lp:~inkscape.dev/inkscape/trunk
Diff against target: 247 lines (+88/-7)
5 files modified
src/display/sodipodi-ctrl.cpp (+72/-3)
src/display/sodipodi-ctrl.h (+3/-1)
src/knot-enums.h (+2/-1)
src/knot.cpp (+9/-2)
src/knot.h (+2/-0)
To merge this branch: bzr merge lp:~inkscape.dev/inkscape/knot_improvements
Reviewer Review Type Date Requested Status
Jabiertxof Approve
Review via email: mp+272515@code.launchpad.net

Description of the change

This branch improve the Knot and the Mesh gradient code:
Knot:
Add a new knot type "TRIANGLE".
Add a new knot property called Angle to turn triangle knots.
Mesh:
Improve the size of corners (DIAMOND) knots.
Update to angled triangle knots the handles of selected corners.

To post a comment you must log in.
14388. By jabiertxof<email address hidden>

Update knot angle while dragging

14389. By jabiertxof<email address hidden>

fix bug on extra highlight of knot in radial mesh gradient

14390. By jabiertxof<email address hidden>

highligt draggers of corner on hover

14391. By jabiertxof<email address hidden>

Remove the memory problem on hover knots.
Added highlight active hover/drag line on draggers
todo: add highlight on node tool hover a knot

14392. By jabiertxof<email address hidden>

update to trunk

14393. By Jabiertxof

update to trunk

14394. By Jabiertxof

Update to trunk

14395. By Jabiertxof

Fixes to new trunk

14396. By Jabiertxof

Allow update knots on mousedown

14397. By Jabiertxof

Siplify the code

14398. By Jabiertxof <jtx@jtx>

Update to trunk

14399. By Jabiertxof

Update to trunk

14400. By Jabiertxof

Update knot colors

14401. By Jabiertxof

Update to trunk

14402. By Jabiertxof

Update knot colors

14403. By Jabiertxof <jtx@jtx>

fix knot colors

14404. By Jabiertxof

Update to trunk

14405. By Jabiertxof

Improve knots triangle

14406. By Jabiertxof

Update to trunk

14407. By Jabiertxof

Some imrovements to render triangles and fix angle knots pointed in IRC

14408. By Jabiertxof

Some imrovements to render triangle knots

14409. By Jabiertxof

NOT WORKING -Some imrovements to render triangle knots

14410. By Jabiertxof <jtx@jtx>

Polish triangle knot

14411. By Jabiertxof

Update to trunk

Revision history for this message
Tavmjong Bah (tavmjong-free) wrote :

Code could use some formatting attention: see https://inkscape.org/en/develop/coding-style/ :
  For example: in sodipodi-ctrl.cpp the opening bracket of the 'for' should be on the same line.

Also, avoid adding or removing blank lines unless it is a real improvement in readability.

I am wondering about the hard-coding of the sizes[] array. Wouldn't it be better to allow the user to set the size directly? This should somehow be coordinated with the node tool knot sizes. And the hard coded array should not appear three different places in the code. (Can GrDragger::updateControlSizes() be called instead?)

Why the special knot-size factor for the SP_KNOT_SHAPE_DIAMOND knot?

GR_KNOT_COLOR_HIGHLIGTH should be GR_KNOT_COLOR_HIGHLIGHT (spelling error).

In GrDragger::highlightNode

  Why the test for node->draggable < G_MAXUINT ?

What does the highlight flag do in "addCurve"?

Does enum GrDraggerPositions need to be in the header?

Not your problem... but why do we have SPKnotShapeType and SPCtrlShapeType?

This code seems to be doing two separate things:
  1. Implement the triangle knot.
  2. Implement variable size knots.

It might be better if the two were separated into different patches.

14412. By Jabiertxof

Some Tavmjong fixes

Revision history for this message
Jabiertxof (jabiertxof) wrote :

I just commit a new version with your improvements:
but:

*Why the test for node->draggable < G_MAXUINT ?
When coding sometimes this value give a > G_MAXUINT and break, maybe a
comment to check or remove on trunk and retain in 0.92 to be sure.

*What does the highlight flag do in "addCurve"?
Update the helperline active color on hover a knot.

*Does enum GrDraggerPositions need to be in the header?
Im returning this object by a typedef in a header class so I think I
need here, maybe I could put inside the class.

*This code seems to be doing two separate things:
1 create triangle knot
2 apply it to mesh tool
Create 2 branches?

Thanks for the review.

Revision history for this message
Tavmjong Bah (tavmjong-free) wrote :

Looks good!

I am still worried about the need for G_MAXUINT. It sounds like it's hiding a bug.

I missed the line high-lighting. Nice!

Two branches would be better... but I'm not going to insist.

14413. By Jabiertxof <jtx@jtx>

split on two branches

Revision history for this message
Jabiertxof (jabiertxof) wrote :

Splited into 2 branches. Removed G_MAXUINT. this branch be first. mesh_improvements after

14414. By Jabiertxof <jtx@jtx>

Update to trunk

Revision history for this message
Tavmjong Bah (tavmjong-free) wrote :

Merged triangle knot code into trunk after making a few changes:

* Reordered enum values.
* Used M_PI rather than custom PI constant.
* Moved "NULL" to end of arg list of sp_canvas_item_new (where it must be).

Revision history for this message
Jabiertxof (jabiertxof) wrote :

merged

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/display/sodipodi-ctrl.cpp'
2--- src/display/sodipodi-ctrl.cpp 2014-08-24 15:20:54 +0000
3+++ src/display/sodipodi-ctrl.cpp 2016-12-03 02:40:30 +0000
4@@ -22,7 +22,8 @@
5 ARG_FILL_COLOR,
6 ARG_STROKED,
7 ARG_STROKE_COLOR,
8- ARG_PIXBUF
9+ ARG_PIXBUF,
10+ ARG_ANGLE
11 };
12
13 static void sp_ctrl_destroy(SPCanvasItem *object);
14@@ -55,6 +56,8 @@
15 g_object_class_install_property (g_object_class,
16 ARG_PIXBUF, g_param_spec_pointer ("pixbuf", "pixbuf", "Pixbuf", (GParamFlags) G_PARAM_READWRITE));
17 g_object_class_install_property (g_object_class,
18+ ARG_ANGLE, g_param_spec_double ("angle", "angle", "Angle", -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, (GParamFlags) G_PARAM_READWRITE));
19+ g_object_class_install_property (g_object_class,
20 ARG_FILLED, g_param_spec_boolean ("filled", "filled", "Filled", TRUE, (GParamFlags) G_PARAM_READWRITE));
21 g_object_class_install_property (g_object_class,
22 ARG_FILL_COLOR, g_param_spec_int ("fill_color", "fill_color", "Fill Color", G_MININT, G_MAXINT, 0x000000ff, (GParamFlags) G_PARAM_READWRITE));
23@@ -119,6 +122,9 @@
24 g_object_unref(pixbuf);
25 }
26 break;
27+ case ARG_ANGLE:
28+ ctrl->angle = (double)g_value_get_double(value);
29+ break;
30 default:
31 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
32 return; // Do not do an update
33@@ -171,6 +177,10 @@
34 g_value_set_pointer(value, ctrl->pixbuf);
35 break;
36
37+ case ARG_ANGLE:
38+ g_value_set_double(value, ctrl->angle);
39+ break;
40+
41 default:
42 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
43 break;
44@@ -192,6 +202,7 @@
45 ctrl->stroked = 0;
46 ctrl->fill_color = 0x000000ff;
47 ctrl->stroke_color = 0x000000ff;
48+ ctrl->angle = 0.0;
49
50 new (&ctrl->box) Geom::IntRect(0,0,0,0);
51 ctrl->cache = NULL;
52@@ -291,6 +302,23 @@
53 return 1e18;
54 }
55
56+bool
57+sp_point_inside_line(Geom::Point a, Geom::Point b, Geom::Point c, double tolerance = 0.1){
58+ //http://stackoverflow.com/questions/328107/how-can-you-determine-a-point-is-between-two-other-points-on-a-line-segment
59+ return Geom::are_near(Geom::distance(a,c) + Geom::distance(c,b) , Geom::distance(a,b), tolerance);
60+}
61+
62+bool
63+sp_point_inside_triangle(Geom::Point p1,Geom::Point p2,Geom::Point p3, Geom::Point point){
64+ using Geom::X;
65+ using Geom::Y;
66+ double denominator = (p1[X]*(p2[Y] - p3[Y]) + p1[Y]*(p3[X] - p2[X]) + p2[X]*p3[Y] - p2[Y]*p3[X]);
67+ double t1 = (point[X]*(p3[Y] - p1[Y]) + point[Y]*(p1[X] - p3[X]) - p1[X]*p3[Y] + p1[Y]*p3[X]) / denominator;
68+ double t2 = (point[X]*(p2[Y] - p1[Y]) + point[Y]*(p1[X] - p2[X]) - p1[X]*p2[Y] + p1[Y]*p2[X]) / -denominator;
69+ double see = t1 + t2;
70+ return 0 <= t1 && t1 <= 1 && 0 <= t2 && t2 <= 1 && see <= 1;
71+}
72+
73 static void
74 sp_ctrl_build_cache (SPCtrl *ctrl)
75 {
76@@ -316,7 +344,7 @@
77 } else {
78 stroke_color = fill_color;
79 }
80-
81+ gint32 stroke_color_smooth = SP_RGBA32_F_COMPOSE(SP_RGBA32_R_F(stroke_color), SP_RGBA32_G_F(stroke_color), SP_RGBA32_B_F(stroke_color), 0.15);
82 width = (ctrl->width * 2 +1);
83 height = (ctrl->height * 2 +1);
84 c = ctrl->width; // Only used for pre-set square drawing
85@@ -325,7 +353,25 @@
86
87 if (ctrl->cache) delete[] ctrl->cache;
88 ctrl->cache = new guint32[size];
89-
90+ Geom::Point point;
91+ Geom::Point p1;
92+ Geom::Point p2;
93+ Geom::Point p3;
94+ if(ctrl->shape == SP_CTRL_SHAPE_TRIANGLE){
95+ const double PI =3.14159;
96+ Geom::Affine m = Geom::Translate(Geom::Point(-width/2.0,-height/2.0));
97+ m *= Geom::Rotate(-ctrl->angle);
98+ m *= Geom::Translate(Geom::Point(width/2.0, height/2.0));
99+ p1 = Geom::Point(0,height/2);
100+ p2 = Geom::Point(width - (width/PI), height/PI);
101+ p3 = Geom::Point(width - (width/PI), height-(height/PI));
102+ p1 *= m;
103+ p2 *= m;
104+ p3 *= m;
105+ p1 = p1.floor();
106+ p2 = p2.floor();
107+ p3 = p3.floor();
108+ }
109 switch (ctrl->shape) {
110 case SP_CTRL_SHAPE_SQUARE:
111 p = ctrl->cache;
112@@ -407,6 +453,29 @@
113 ctrl->build = TRUE;
114 break;
115
116+ case SP_CTRL_SHAPE_TRIANGLE:
117+ p = ctrl->cache;
118+ for(y = 0; y < height; y++) {
119+ for(x = 0; x < width; x++) {
120+ point = Geom::Point(x,y);
121+ if (sp_point_inside_triangle(p1, p2, p3, point)) {
122+ p[(y*width)+x] = fill_color;
123+ } else if (point == p1 || point == p2 || point == p3 || sp_point_inside_line(p1, p2, point, 0.2) ||
124+ sp_point_inside_line(p3, p1, point, 0.2))
125+ {
126+ p[(y*width)+x] = stroke_color;
127+ } else if (sp_point_inside_line(p1, p2, point, 0.5) ||
128+ sp_point_inside_line(p3, p1, point, 0.5))
129+ {
130+ p[(y*width)+x] = stroke_color_smooth;
131+ } else {
132+ p[(y*width)+x] = 0;
133+ }
134+ }
135+ }
136+ ctrl->build = TRUE;
137+ break;
138+
139 case SP_CTRL_SHAPE_CROSS:
140 p = ctrl->cache;
141 for (y = 0; y < height; y++) {
142
143=== modified file 'src/display/sodipodi-ctrl.h'
144--- src/display/sodipodi-ctrl.h 2014-03-27 01:33:44 +0000
145+++ src/display/sodipodi-ctrl.h 2016-12-03 02:40:30 +0000
146@@ -24,7 +24,8 @@
147 SP_CTRL_SHAPE_CIRCLE,
148 SP_CTRL_SHAPE_CROSS,
149 SP_CTRL_SHAPE_BITMAP,
150- SP_CTRL_SHAPE_IMAGE
151+ SP_CTRL_SHAPE_IMAGE,
152+ SP_CTRL_SHAPE_TRIANGLE
153 } SPCtrlShapeType;
154
155
156@@ -46,6 +47,7 @@
157 guint stroked : 1;
158 guint32 fill_color;
159 guint32 stroke_color;
160+ gdouble angle;
161
162 Geom::IntRect box; /* NB! x1 & y1 are included */
163 guint32 *cache;
164
165=== modified file 'src/knot-enums.h'
166--- src/knot-enums.h 2011-10-25 07:45:35 +0000
167+++ src/knot-enums.h 2016-12-03 02:40:30 +0000
168@@ -21,7 +21,8 @@
169 SP_KNOT_SHAPE_CIRCLE,
170 SP_KNOT_SHAPE_CROSS,
171 SP_KNOT_SHAPE_BITMAP,
172- SP_KNOT_SHAPE_IMAGE
173+ SP_KNOT_SHAPE_IMAGE,
174+ SP_KNOT_SHAPE_TRIANGLE
175 } SPKnotShapeType;
176
177 typedef enum {
178
179=== modified file 'src/knot.cpp'
180--- src/knot.cpp 2016-08-04 11:26:03 +0000
181+++ src/knot.cpp 2016-12-03 02:40:30 +0000
182@@ -76,6 +76,7 @@
183 this->anchor = SP_ANCHOR_CENTER;
184 this->shape = SP_KNOT_SHAPE_SQUARE;
185 this->mode = SP_KNOT_MODE_XOR;
186+ this->angle = 0;
187 this->tip = NULL;
188 this->_event_handler_id = 0;
189 this->pressure = 0;
190@@ -116,7 +117,8 @@
191 "stroked", TRUE,
192 "stroke_color", 0x01000000,
193 "mode", SP_KNOT_MODE_XOR,
194- NULL);
195+ NULL,
196+ "angle",0.0);
197
198 this->_event_handler_id = g_signal_connect(G_OBJECT(this->item), "event",
199 G_CALLBACK(sp_knot_handler), this);
200@@ -214,7 +216,7 @@
201 if ((event->button.button == 1) && knot->desktop && knot->desktop->event_context && !knot->desktop->event_context->space_panning) {
202 Geom::Point const p = knot->desktop->w2d(Geom::Point(event->button.x, event->button.y));
203 knot->startDragging(p, (gint) event->button.x, (gint) event->button.y, event->button.time);
204-
205+ knot->grabbed_signal.emit(knot, event->button.state);
206 consumed = TRUE;
207 }
208 break;
209@@ -450,6 +452,7 @@
210 g_object_set(this->item, "mode", this->mode, NULL);
211 g_object_set(this->item, "size", (gdouble) this->size, NULL);
212 g_object_set(this->item, "anchor", this->anchor, NULL);
213+ g_object_set(this->item, "angle", this->angle, NULL);
214
215 if (this->pixbuf) {
216 g_object_set(this->item, "pixbuf", this->pixbuf, NULL);
217@@ -492,6 +495,10 @@
218 pixbuf = p;
219 }
220
221+void SPKnot::setAngle(double i) {
222+ angle = i;
223+}
224+
225 void SPKnot::setFill(guint32 normal, guint32 mouseover, guint32 dragging) {
226 fill[SP_KNOT_STATE_NORMAL] = normal;
227 fill[SP_KNOT_STATE_MOUSEOVER] = mouseover;
228
229=== modified file 'src/knot.h'
230--- src/knot.h 2014-10-08 02:22:03 +0000
231+++ src/knot.h 2016-12-03 02:40:30 +0000
232@@ -58,6 +58,7 @@
233
234 SPKnotShapeType shape; /**< Shape type. */
235 SPKnotModeType mode;
236+ double angle;
237
238 guint32 fill[SP_KNOT_VISIBLE_STATES];
239 guint32 stroke[SP_KNOT_VISIBLE_STATES];
240@@ -92,6 +93,7 @@
241 void setAnchor(unsigned int i);
242 void setMode(unsigned int i);
243 void setPixbuf(void* p);
244+ void setAngle(double i);
245
246 void setFill(guint32 normal, guint32 mouseover, guint32 dragging);
247 void setStroke(guint32 normal, guint32 mouseover, guint32 dragging);