Ellipses, Circles, and Arcs, oh my!
Hi,
I see some action on rewriting Inkscape's General Ellipse code. It would be very nice if Inkscape could directly create the SVG circle and ellipse elements rather than use the SVG path element. I realize that this may be outside the scope of the current work but there is one thing that I should bring attention to: The SVG Working Group decided to allow markers on SVG shape elements.[1] Inkscape will actually already draw markers on shapes if there already are markers placed on the shapes in the SVG file (but doesn't draw them "correctly"), however Inkscape does not allow one to add markers to shapes through the GUI. (I'm sure that the drawing of the markers is accidental and not intentional.)
It was fairly clear to the SVG WG that for rectangles, there are four markers (one for each corner) and for rounded rectangles, there are eight markers (one at each start and end of a corner arc). See attachment.[2] It wasn't as clear what to do for circles and ellipses. The group decided that there should be four markers on circles and ellipses, located at the 0, 90, 180, and 270 degree points. Inkscape currently represents circles and arcs as two path elliptical arc segments. In order to have four markers, it should be using four elliptical arc segments.
I also noticed that the Object->Path command converts a circle/ellipse to a path using eight Bezier curves (and would thus have eight markers). It seems to me that it should be converting to four elliptical arc segments. (After all, converting a rectangle to a path doesn't produce four straight Bezier curves!)
Tav
[1] http://www.w3.org/2013/06/03-svg-minutes.html#item03 [2] Top row: expected behavior, bottom row: test. Green: Start marker, Yellow: Mid marker, Red: End marker.
Hi,
I also noticed that the Object->Path command converts a circle/ellipse to a path using eight Bezier curves (and would thus have eight markers). It seems to me that it should be converting to four elliptical arc segments.
The code's there, see "svg/svg-path.cpp", l. 92. It would output elliptical arcs, if Circle::getPath (2geom/circle.cpp, l. 102) created elliptical arcs in the first place. With this I could need a bit of help ;) . Btw, the number of Bezier curves depends on the size of the objects it seems.
Inkscape currently represents circles and arcs as two path elliptical arc segments. In order to have four markers, it should be using four elliptical arc segments.
I don't know. Let's say I create a pizza slice. I'd expect to get exactly one elliptical arc and two straight lines if I convert it to a path, even if there were a marker point on the way. Then the user should rather divide the elliptical arc into two parts manually in order to get a marker there. Usually, you first create your shape and then add your markers afterwards, don't you?
It would be very nice if Inkscape could directly create the SVG circle and ellipse elements rather than use the SVG path element.
The problem here is that then it must be possible to convert between circles and ellipses and paths in both directions. This probably adds lots of buttons and menu entries to the UI.
Regards, Markus
2013/9/30 Markus Engel <p637777@...1081...>:
It would be very nice if Inkscape could directly create the SVG circle and ellipse elements rather than use the SVG path element.
The problem here is that then it must be possible to convert between circles and ellipses and paths in both directions. This probably adds lots of buttons and menu entries to the UI.
Not really. The UI can work like it does at present, but the same SPObject subclass must handle more than one type of XML node, and it should change the XML element name as appropriate in response to tweaking the controls.
Currently there is no such code in Inkscape, but allowing this would not be too intrusive. In fact, I think it can already be done by using Inkscape::XML::Node::setCodeUnsafe().
Regards, Krzysztof
On Tue, 2013-10-01 at 02:16 +0200, Krzysztof Kosiński wrote:
2013/9/30 Markus Engel <p637777@...1081...>:
It would be very nice if Inkscape could directly create the SVG circle and ellipse elements rather than use the SVG path element.
The problem here is that then it must be possible to convert between circles and ellipses and paths in both directions. This probably adds lots of buttons and menu entries to the UI.
Not really. The UI can work like it does at present, but the same SPObject subclass must handle more than one type of XML node, and it should change the XML element name as appropriate in response to tweaking the controls.
Right now there are three classes: SPCircle, SPEllipse, and SPArc, each derived from SPGenericEllipse. To get the GUI to work with each of the derived classes is simple (almost everything needed is already in the SPGenericEllipse class). I have a private build that implements this.
The problem is to be able to change on the fly the SVG element type. One approach I am thinking about is to get rid of the three derived classes and handle the element type directly in SPGenericEllipse.
An SVG circle would be written out if rx==ry and end==start and there is no LPE. An SVG ellipse would be written out if rx!=ry and end==start and there is no LPE. An SVG path of sodipodi:type arc would be written out if end!=start or if there is an LPE.
A user option could be provided to force a path to always be written out.
Currently there is no such code in Inkscape, but allowing this would not be too intrusive. In fact, I think it can already be done by using Inkscape::XML::Node::setCodeUnsafe().
I don't understand how using Inkscape::XML::NOde::setCodeUnsafe() would help.
Tav
Note to self: see sp_item_list_to_curves in path-chemistry.cpp for changing element type.
2013/10/3 Tavmjong Bah <tavmjong@...8...>:
Currently there is no such code in Inkscape, but allowing this would not be too intrusive. In fact, I think it can already be done by using Inkscape::XML::Node::setCodeUnsafe().
I don't understand how using Inkscape::XML::NOde::setCodeUnsafe() would help.
IIRC, this function allows you to change the element name without removing it from the XML tree.
Regards, Krzysztof
On Thu, 2013-10-03 at 21:09 +0200, Krzysztof Kosiński wrote:
2013/10/3 Tavmjong Bah <tavmjong@...8...>:
Currently there is no such code in Inkscape, but allowing this would not be too intrusive. In fact, I think it can already be done by using Inkscape::XML::Node::setCodeUnsafe().
I don't understand how using Inkscape::XML::NOde::setCodeUnsafe() would help.
IIRC, this function allows you to change the element name without removing it from the XML tree.
I've got the code to auto-convert between SVG circle, ellipse, and path (arc) mostly working using setCodeUnsafe(). I've got two problems left:
1. The XML dialog does not update the element type. The actual XML tree is changed. I don't know how to signal the XML dialog to reload the XML tree (switching between two different desktops does result in an update). It seems I need an _observer.notifyElementChanged signal but how to actually do this is hurting my grey cells. Any hints would be appreciated.
2. There is a bug with adding an LPE to a circle/ellipse. The element is converted to a path and the 'd' data is added but none of the other attributes are saved. This shouldn't be too hard to fix.
Tav
2013/10/6 Tavmjong Bah <tavmjong@...8...>:
- The XML dialog does not update the element type. The actual XML tree
is changed. I don't know how to signal the XML dialog to reload the XML tree (switching between two different desktops does result in an update). It seems I need an _observer.notifyElementChanged signal but how to actually do this is hurting my grey cells. Any hints would be appreciated.
It might be necessary to introduce a new callback to XML observers. To be honest, the XML tree was never designed to handle this case - that's why the method has "unsafe" in its name.
It seems we would need 7 callbacks in total:
- notifyAttributeChanged - notifyChildAdded - notifyChildRemoved - notifyChildOrderChanged - notifyContentChanged - notifyElementNameChanged - notifyElementRemoved
The notifyElementRemoved callback is necessary to fix this bug: https://bugs.launchpad.net/inkscape/+bug/540591
These changes are going to be invasive, and I think it's best to batch them together with the work on a partially typed XML tree and the SAX parser.
Regards, Krzysztof
On Sun, 2013-10-06 at 19:18 +0200, Krzysztof Kosiński wrote:
2013/10/6 Tavmjong Bah <tavmjong@...8...>:
- The XML dialog does not update the element type. The actual XML tree
is changed. I don't know how to signal the XML dialog to reload the XML tree (switching between two different desktops does result in an update). It seems I need an _observer.notifyElementChanged signal but how to actually do this is hurting my grey cells. Any hints would be appreciated.
It might be necessary to introduce a new callback to XML observers. To be honest, the XML tree was never designed to handle this case - that's why the method has "unsafe" in its name.
It seems we would need 7 callbacks in total:
- notifyAttributeChanged
- notifyChildAdded
- notifyChildRemoved
- notifyChildOrderChanged
- notifyContentChanged
- notifyElementNameChanged
- notifyElementRemoved
The notifyElementRemoved callback is necessary to fix this bug: https://bugs.launchpad.net/inkscape/+bug/540591
These changes are going to be invasive, and I think it's best to batch them together with the work on a partially typed XML tree and the SAX parser.
Thanks for the answer
As a temporary work-around I can do what is done when an object is converted to a path... create a new object.
Tav
On Mon, 2013-09-30 at 19:35 +0200, Markus Engel wrote:
Hi,
I also noticed that the Object->Path command converts a circle/ellipse to a path using eight Bezier curves (and would thus have eight markers). It seems to me that it should be converting to four elliptical arc segments.
The code's there, see "svg/svg-path.cpp", l. 92. It would output elliptical arcs, if Circle::getPath (2geom/circle.cpp, l. 102) created elliptical arcs in the first place. With this I could need a bit of help ;) . Btw, the number of Bezier curves depends on the size of the objects it seems.
Inkscape currently represents circles and arcs as two path elliptical arc segments. In order to have four markers, it should be using four elliptical arc segments.
I was a bit mistaken, Inkscape currently represents an opened circle/ellipse with one arc segment regardless of its length.
Inkscape should be using the SVG circle or ellipse element. Converting a circle/ellipse to a path would produce a path of four arc segments (so marker rendering won't change). I might have a go at changing Inkscape to use a circle or ellipse element as suggested by Krzysztof.
I don't know. Let's say I create a pizza slice. I'd expect to get exactly one elliptical arc and two straight lines if I convert it to a path, even if there were a marker point on the way. Then the user should rather divide the elliptical arc into two parts manually in order to get a marker there. Usually, you first create your shape and then add your markers afterwards, don't you?
I agree that the default for a pizza slice is to have one arc segment and two straight lines. Inkscape already does this. One could have an option to break the path into multiple arcs so that changing a circle into an arc doesn't change the marker rendering (except adding markers at the start and end of the arc) but I don't think this in really necessary.
It would be very nice if Inkscape could directly create the SVG circle and ellipse elements rather than use the SVG path element.
The problem here is that then it must be possible to convert between circles and ellipses and paths in both directions. This probably adds lots of buttons and menu entries to the UI.
See Krzysztof's comment. Explicitly converting to a circle or ellipse to a path (via Path->Object to Path) always has been a one way process.
Tav
Hi,
I've finished code that changes arcs on the fly between svg:circle, svg:ellipse, and svg:path as required. Several people have complained to me in the past about not being able to edit SVG circles and ellipses. This should fix that. LPE's should also work. There is one "bug" in that the XML Editor dialog does not update the element type. Fixing this requires adding a new observer to the XML code. I would be interested if people can try it out before I commit the changes. A diff file is attached.
Tav
On Mon, Oct 7, 2013 at 12:18 PM, Tavmjong Bah <tavmjong@...8...> wrote:
LPE's should also work.
I added the Powestroke LPE to a Circle and in the Ellipse Tool it no longer showed the on-canvas control handles to edit it. Other than the other issue you mentioned regarding the XML editor getting updated, in my limited testing it seemed like everything else checks out.
Cheers, Josh
On 2013-10-08 01:28 +0200, Josh Andler wrote:
On Mon, Oct 7, 2013 at 12:18 PM, Tavmjong Bah <tavmjong@...8...> wrote:
LPE's should also work.
I added the Powestroke LPE to a Circle and in the Ellipse Tool it no longer showed the on-canvas control handles to edit it.
Works for me after de- and reselecting the ellipse/circle, likely https://bugs.launchpad.net/inkscape/+bug/1219324 (affects unpatched trunk, too)
Other than the other issue you mentioned regarding the XML editor getting updated, in my limited testing it seemed like everything else checks out.
Patched inkscape crashes when saving a new drawing with a circle as 'Plain SVG':
1) launch patched inkscape (default prefs, default new doc) 2) draw a circle 3) save as 'Plain SVG':
Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000 0x0000000100145483 in SPItem::write () (gdb) bt #0 0x0000000100145483 in SPItem::write () #1 0x000000010015a95b in SPLPEItem::write () #2 0x0000000100180761 in SPShape::write () #3 0x000000010011ff95 in SPGenericEllipse::write () #4 0x000000010014ab1c in SPGroup::write () #5 0x000000010014ab1c in SPGroup::write () #6 0x000000010017f78a in SPRoot::write () #7 0x00000001002554b9 in Inkscape::Extension::Internal::Svg::save () #8 0x0000000100249fb5 in Inkscape::Extension::Output::save () #9 0x0000000100247be0 in Inkscape::Extension::save () #10 0x00000001000640ce in file_save () #11 0x0000000100063de1 in sp_file_save_dialog () #12 0x0000000100064509 in sp_file_save_document () #13 0x00000001000647ba in sp_file_save () #14 0x00000001001ce990 in Inkscape::FileVerb::perform () #15 0x000000010002f712 in sigc::internal::signal_emit0<void, sigc::nil>::emit () #16 0x00000001003047ee in sp_action_perform () #17 0x0000000100108c86 in sp_shortcut_invoke () #18 0x000000010030a0c2 in on_window_key_press () #19 0x000000010030a18d in sigc::internal::slot_call1<sigc::pointer_functor1<_GdkEventKey*, bool>, bool, _GdkEventKey*>::call_it () #20 0x00000001011cd3ba in (anonymous namespace)::Widget_signal_key_press_event_callback () #21 0x0000000101664d6e in _gtk_marshal_BOOLEAN__BOXED () #22 0x0000000102e0a521 in g_closure_invoke () #23 0x0000000102e1d523 in signal_emit_unlocked_R () #24 0x0000000102e1e2e4 in g_signal_emit_valist () #25 0x0000000102e1e5ee in g_signal_emit () #26 0x000000010175a51f in gtk_widget_event_internal () #27 0x00000001016630af in gtk_propagate_event () #28 0x0000000101662d6b in gtk_main_do_event () #29 0x0000000101a2415f in gdk_event_dispatch () #30 0x0000000102e7e4ca in g_main_context_dispatch () #31 0x0000000102e7e7cc in g_main_context_iterate () #32 0x0000000102e7ea51 in g_main_loop_run () #33 0x00000001016626f0 in gtk_main () #34 0x000000010000296b in sp_main_gui () #35 0x0000000100001cc4 in start () (gdb)
On Mon, Oct 7, 2013 at 5:26 PM, su_v <suv-sf@...58...> wrote:
Works for me after de- and reselecting the ellipse/circle, likely https://bugs.launchpad.net/inkscape/+bug/1219324 (affects unpatched trunk, too)
I've tried switching tools, changing the selection to different types of objects, etc... but the Ellipse handles won't come back here.
Patched inkscape crashes when saving a new drawing with a circle as 'Plain SVG':
Reproduced.
Cheers, Josh
On 2013-10-08 02:36 +0200, Josh Andler wrote:
On Mon, Oct 7, 2013 at 5:26 PM, su_v <suv-sf@...58...> wrote:
Works for me after de- and reselecting the ellipse/circle, likely https://bugs.launchpad.net/inkscape/+bug/1219324 (affects unpatched trunk, too)
I've tried switching tools, changing the selection to different types of objects, etc... but the Ellipse handles won't come back here.
You are right, my mistake, sorry (the handles of the ellipse no longer show when a path effect is applied).
On Mon, 2013-10-07 at 17:36 -0700, Josh Andler wrote:
On Mon, Oct 7, 2013 at 5:26 PM, su_v <suv-sf@...58...> wrote:
Works for me after de- and reselecting the ellipse/circle, likely https://bugs.launchpad.net/inkscape/+bug/1219324 (affects unpatched trunk, too)
I've tried switching tools, changing the selection to different types of objects, etc... but the Ellipse handles won't come back here.
Patched inkscape crashes when saving a new drawing with a circle as 'Plain SVG':
To get the handles back, hide the LPE (by clicking on the "eye" icon in the Path Effects dialog), and then switch tools. This occurs in unpatched trunk.
Tav
Thanks Josh and su_v for testing! I've fixed the crash and gone ahead and checked in the code. As I mention in another email, the on-canvas shape handles bug already existed in trunk prior to this check-in.
Tav
On Tue, 2013-10-08 at 02:26 +0200, su_v wrote:
On 2013-10-08 01:28 +0200, Josh Andler wrote:
On Mon, Oct 7, 2013 at 12:18 PM, Tavmjong Bah <tavmjong@...8...> wrote:
LPE's should also work.
I added the Powestroke LPE to a Circle and in the Ellipse Tool it no longer showed the on-canvas control handles to edit it.
Works for me after de- and reselecting the ellipse/circle, likely https://bugs.launchpad.net/inkscape/+bug/1219324 (affects unpatched trunk, too)
Other than the other issue you mentioned regarding the XML editor getting updated, in my limited testing it seemed like everything else checks out.
Patched inkscape crashes when saving a new drawing with a circle as 'Plain SVG':
- launch patched inkscape (default prefs, default new doc)
- draw a circle
- save as 'Plain SVG':
Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000 0x0000000100145483 in SPItem::write () (gdb) bt #0 0x0000000100145483 in SPItem::write () #1 0x000000010015a95b in SPLPEItem::write () #2 0x0000000100180761 in SPShape::write () #3 0x000000010011ff95 in SPGenericEllipse::write () #4 0x000000010014ab1c in SPGroup::write () #5 0x000000010014ab1c in SPGroup::write () #6 0x000000010017f78a in SPRoot::write () #7 0x00000001002554b9 in Inkscape::Extension::Internal::Svg::save () #8 0x0000000100249fb5 in Inkscape::Extension::Output::save () #9 0x0000000100247be0 in Inkscape::Extension::save () #10 0x00000001000640ce in file_save () #11 0x0000000100063de1 in sp_file_save_dialog () #12 0x0000000100064509 in sp_file_save_document () #13 0x00000001000647ba in sp_file_save () #14 0x00000001001ce990 in Inkscape::FileVerb::perform () #15 0x000000010002f712 in sigc::internal::signal_emit0<void, sigc::nil>::emit () #16 0x00000001003047ee in sp_action_perform () #17 0x0000000100108c86 in sp_shortcut_invoke () #18 0x000000010030a0c2 in on_window_key_press () #19 0x000000010030a18d in sigc::internal::slot_call1<sigc::pointer_functor1<_GdkEventKey*, bool>, bool, _GdkEventKey*>::call_it () #20 0x00000001011cd3ba in (anonymous namespace)::Widget_signal_key_press_event_callback () #21 0x0000000101664d6e in _gtk_marshal_BOOLEAN__BOXED () #22 0x0000000102e0a521 in g_closure_invoke () #23 0x0000000102e1d523 in signal_emit_unlocked_R () #24 0x0000000102e1e2e4 in g_signal_emit_valist () #25 0x0000000102e1e5ee in g_signal_emit () #26 0x000000010175a51f in gtk_widget_event_internal () #27 0x00000001016630af in gtk_propagate_event () #28 0x0000000101662d6b in gtk_main_do_event () #29 0x0000000101a2415f in gdk_event_dispatch () #30 0x0000000102e7e4ca in g_main_context_dispatch () #31 0x0000000102e7e7cc in g_main_context_iterate () #32 0x0000000102e7ea51 in g_main_loop_run () #33 0x00000001016626f0 in gtk_main () #34 0x000000010000296b in sp_main_gui () #35 0x0000000100001cc4 in start () (gdb)
participants (6)
-
unknown@example.com
-
Josh Andler
-
Krzysztof Kosiński
-
Markus Engel
-
su_v
-
Tavmjong Bah