Merge lp:~inkscape.dev/inkscape/knot_improvements into lp:~inkscape.dev/inkscape/trunk
- knot_improvements
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jabiertxof | Approve | ||
Review via email: mp+272515@code.launchpad.net |
Commit message
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.
- 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
Tavmjong Bah (tavmjong-free) wrote : | # |
- 14412. By Jabiertxof
-
Some Tavmjong fixes
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.
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
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
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).
Preview Diff
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); |
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: :updateControlS izes() 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.