Modernise Calligraphy tool base
Open, WishlistPublic

Description

There's several problems here that are just abut modernising the calligraphic tool base and barely touch making it more usable.

Outline, code:

  • KoParametricShape is a KoPathShape that has a list of handles and parameters that can be modified.
    • KarbonCalligraphicShape is a KoParametricShape.
      • Which has KarbonCalligraphicPoints. - These only contain a point, a width and an angle.
  • The KarbonCalligraphicTool generates a KarbonCalligraphicShape.

Problems:

  • KoParamtericShape is intended to have some handles that generate a path, but mostly like circles, rectangles, stars, etc. (This could be a good candidate for a python plugin btw). It is not really intended for something that can generate a similar path, like the KarbonCalligraphicShape.
    • This means no add/remove/insert nodes.
    • No different node types either.
    • This is what causes the 'move node and have the path run off bug', it's a problem in KoCalligraphicShape::normalize().
  • There's no saving of the spine-path.
  • This path shape currently only saves the width and angle of a given path, while it might be better if we could store the KisPaintInformation instead.

Solutions:

Either we...

Keep KarbonCalligraphicShape a KoParametricShape.

And then extend the calligraphic tool to handle add/remove of points.

Cons:

  • This doesn't make much sense from the user point of view. Why would the node editing tool only be able to edit the points, but not adding removing points.
  • On the other hand, this does simplify the question of where a hypothetical kispaintinformation-editor would go.
  • You'd still need to fix the normalize bug.
  • Isn't flexible in the long term.
    • for example, if we have a situation where the intersection of two calligraphic path spines would need to be calculated, KoParametricShape just isn't capable of that.

Make KarbonCalligraphicShape a KoPathShape

We make this a KoPathShape with a KoPathShape inside, the latter will contain the 'rendered stroke', we override the paint() and paint that 'rendered stroke' instead. We also keep a list of KisPaintInformations.

Cons:

  • Needs a whole lot of rewriting:
    • We need to be mindful of subpaths.
    • We need to override add/remove/combine/seperate.
    • The path rendering needs to be done as such that we can handle different path types
    • We need to find a solution for convert-to-path.
    • Will need a whole lot of testing for edgecases.

Battle plan:

  • Convert KarbonCalligraphicPoint to a KoPathPoint with a KisPaintInformation.
  • OR Convert KarbonCalligraphicPath to a KoPath instead of KoParametricPath. [Turned out too difficult]
    • This would need to become a KoPathShape with a KoPathShape inside, the later containing the rendered stroke.
    • Store the KisPaintInformations in a list.
    • No idea how to implement convert to path here...
  • Make KarbonCalligraphicShape render with these new KarbonCalligraphicPoints (and use the relevant similar bits from )
  • Make the Calligraphy tool generate these simply for now.
  • Verify that the Alternate pointtypes render sensibly. (big, mostly cusp is a problem)
  • Allow *stroke selected shapes* to stroke calligraphic strokes with the relevant bits. We can try to check the shapeID to see if it's possible.
  • Make a KarbonCalligraphicShape config object. This is like a preset, it will allow people to modify the shape based on the paintinfo instead of making the Calligraphy tool do that. (also big) [Using a KisPropertiesConfig now]
    • Keep usePath - useAssistants was added too!
    • Replace strokewidth, pressure and thinning by size sensor curve-widget in calligraphy tool.
    • Move calc width to the stroke.
    • Replace angle, fixation and custom angle with angle sensor curve-widget
    • Move calc angle to the stroke.
    • Keep caps.
    • Keep mass and drag until better smoothing is implemented. (new smoothing was implemented.
  • Make this path type save and load proper. This seems to be unimplemented. (needs input on how it should look)

Save something like this?

<path
     style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
     d="m 114.28571,640.93363 c 1.96528,-0.89379 -1.33194,-14.65239 -3.87853,-31.5105 -2.68746,-17.7907 -4.48873,-37.56486 -3.1739,-58.03937 1.88174,-29.30254 9.80413,-54.02772 23.6747,-73.89615 13.58786,-19.46347 32.54488,-33.80754 56.07886,-44.15814 16.03322,-6.95659 29.86336,-8.18164 41.25597,-7.37414 11.5853,0.82115 22.63348,3.9201 32.786,7.88512 14.41689,5.63044 28.5889,13.65292 41.28598,21.51544 12.31181,7.62394 25.80375,16.74753 37.1699,24.26992 14.03531,9.28891 28.15513,18.39231 42.89161,26.49148 14.33815,7.88026 31.27473,15.9259 49.49391,21.06265 14.04122,3.9588 31.12793,6.84894 49.5381,5.00865 9.34159,-0.9338 19.15403,-3.09936 29.1008,-7.06683 9.97504,-3.97874 19.87612,-9.68506 29.51115,-17.54687 9.25068,-7.54818 17.38413,-16.37014 24.1574,-26.20236 -6.1289,-5.98368 -12.02883,-12.19748 -17.68708,-18.62804 -22.80886,-25.92207 -41.4997,-55.14845 -53.82832,-88.30825 C 480.15548,340.79727 474.9125,305.02 476.82408,267.38582 c 2.21568,-43.62102 19.13011,-99.7235 17.46163,-100.7379 -2.5573,-1.55478 -12.71633,10.82215 -22.31047,28.51715 -9.94042,18.33367 -19.20149,41.68451 -25.2567,67.87052 -9.37262,40.53231 -10.03521,82.9255 -0.83713,124.84737 5.58682,25.46297 14.53134,49.559 26.12819,72.1967 -5.00436,-1.23024 -10.32199,-3.11487 -15.85032,-5.48309 -10.56704,-4.5267 -22.06844,-10.8863 -34.3231,-18.08986 -8.26071,-4.85583 -29.54787,-17.77758 -40.48489,-24.17314 -12.26359,-7.17129 -27.30249,-15.64661 -43.22492,-23.25834 -15.75337,-7.53091 -35.87451,-15.93519 -57.8892,-20.96925 -15.70667,-3.59161 -34.09651,-5.88388 -53.96971,-4.05519 -20.07279,1.84706 -42.02784,7.91841 -64.68282,21.62982 -29.53292,17.97724 -52.4959,41.82714 -66.457196,71.64804 -13.948286,29.79311 -17.438963,62.44561 -13.542334,94.90605 4.93611,41.11973 26.57007,91.48704 32.7006,88.69893 z"
     id="path4136"
     krita:original-d="m 114.28571,640.93363 c 0,0 -73.004042,-160.52221 60,-231.42857 133.00404,-70.90636 247.51153,143.98617 347.51153,72.5576 C 398.41014,324.34377 494.28571,166.64792 494.28571,166.64792"
     calligra:nodetypes="czcc">
     		<paintInfo pointX pointY pressure Xtilt yTilt rotation tangentialPressure perspective time speed />
     		<paintInfo pointX pointY pressure Xtilt yTilt rotation tangentialPressure perspective time speed />
     		<paintInfo pointX pointY pressure Xtilt yTilt rotation tangentialPressure perspective time speed />
     		<paintInfo pointX pointY pressure Xtilt yTilt rotation tangentialPressure perspective time speed />
     		<paintInfo pointX pointY pressure Xtilt yTilt rotation tangentialPressure perspective time speed />
 </path>

See this for saving and loading

woltherav updated the task description. (Show Details)Feb 19 2017, 11:10 AM
woltherav updated the task description. (Show Details)Mar 12 2017, 6:45 PM
woltherav added a comment.EditedMar 13 2017, 4:48 PM

Okay, here's an example svg saved with the calligraphic information inside:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- Created using Krita: http://krita.org -->
<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:krita="http://krita.org/kritasvg"
    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
    width="48pt"
    height="48pt"
    viewBox="0 0 48 48">
<defs/>
<path id="shape0" krita:type="calligraphic-stroke" transform="translate(8.4262316695, 9.5529534338)" d="M14.407 30.3895C14.5723 29.8705 15.1114 29.4924 15.5191 29.1603L14.8642 28.7977C14.8575 26.3455 16.993 23.611 18.2532 21.6685C20.6583 17.9614 22.7518 14.9474 22.9816 10.3011C23.081 8.29097 22.2981 4.65018 20.2843 3.6567C20.1398 3.58539 20.1573 4.13595 20.1428 4.16194C19.9478 4.51273 19.7061 4.8355 19.4934 5.17588C18.9115 6.10724 18.6353 6.56409 18.1215 7.55206C17.4674 8.80954 18.1373 10.7078 17.4455 11.7929C17.3655 11.9184 15.562 12.2143 15.3979 12.2427C14.9282 12.3243 14.428 12.3418 13.9595 12.2404C12.4821 11.9205 12.9341 9.87252 12.4068 8.73618C10.9394 5.5742 8.04757 3.29667 4.58953 5.27203C2.98364 6.18937 5.52491 9.47327 6.12882 10.3532C9.58961 15.3958 13.7951 19.7248 17.3606 24.6889C18.1604 25.8026 19.3738 27.4752 19.392 28.9191C19.4041 29.8874 18.7631 31.3434 17.5186 30.5953C16.769 30.1459 16.0858 31.2876 15.4603 30.745C14.7873 30.1611 14.4516 29.0962 13.9972 28.3518C13.2204 27.0791 12.2658 25.9072 11.3636 24.7229C7.88214 20.1531 3.71503 15.8982 1.29093 10.623C0.392594 8.6681 -0.457327 6.5 0.290617 4.35038C1.71262 0.2635 7.97953 -0.209143 11.2583 1.37478C12.8242 2.13123 14.2389 3.67379 15.1445 5.13117C15.297 5.37665 15.4408 5.62783 15.5741 5.8843C16.1582 7.00859 16.3606 7.88765 16.8463 8.9693C16.951 9.20249 17.3825 9.69136 17.2093 9.98265C16.8109 10.6526 14.9492 10.5374 14.3608 10.5694C14.2808 10.5738 13.4169 10.6076 13.3785 10.699C13.227 11.0586 13.5119 9.92992 13.5666 9.54356C13.7046 8.56768 13.7652 7.51535 14.1197 6.58668C15.1677 3.84125 17.8529 -0.6394 21.3387 0.0845487C24.3963 0.719551 26.2629 4.40869 26.8604 7.17311C28.3231 13.9403 25.1982 19.6466 21.1774 24.7027C19.973 26.2174 17.8651 29.1898 15.8029 29.4374L14.9011 29.4373C14.8366 29.6039 14.4498 30.5029 14.407 30.3895Z" fill="#000000">
  <point xTilt="-26" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.2100935135469" yTilt="4" time="21" speed="0" pointY="29.2987752448177" pressure="0.0908203125"/>

  <point xTilt="-25" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.3335723968683" yTilt="4" time="31" speed="0" pointY="29.1175834051613" pressure="0.15234375"/>

  <point xTilt="-25" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.5026847805476" yTilt="4" time="41" speed="0" pointY="28.8961267122479" pressure="0.2119140625"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.706693370383" yTilt="4" time="51" speed="0" pointY="28.6243389527633" pressure="0.2587890625"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.9670727547781" yTilt="4" time="61" speed="0" pointY="28.2901406707304" pressure="0.3125"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="16.2811386101826" yTilt="3" time="71" speed="0" pointY="27.8854788954977" pressure="0.3603515625"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="16.6435222894954" yTilt="3" time="81" speed="0" pointY="27.4083403844025" pressure="0.404296875"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="17.5025058256443" yTilt="3" time="101" speed="0" pointY="26.2607920665786" pressure="0.4404296875"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="17.9883683882785" yTilt="3" time="111" speed="0" pointY="25.6004484731642" pressure="0.4931640625"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="19.0620978084646" yTilt="3" time="131" speed="0.0236909318895769" pointY="24.1287680866216" pressure="0.5390625"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="20.8283827046708" yTilt="5" time="161" speed="0.0538420865943792" pointY="21.6424133980031" pressure="0.57421875"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="22.0443812730315" yTilt="6" time="181" speed="0.0706747466976856" pointY="19.8767995826846" pressure="0.5791015625"/>

  <point xTilt="-25" perspective="1" rotation="0" tangentialPressure="0.5" pointX="23.2281679587867" yTilt="7" time="201" speed="0.0847585098803996" pointY="18.0145501195493" pressure="0.587890625"/>

  <point xTilt="-26" perspective="1" rotation="0" tangentialPressure="0.5" pointX="24.4656411155512" yTilt="9" time="231" speed="0.100508183262328" pointY="15.0027390959272" pressure="0.5771484375"/>

  <point xTilt="-26" perspective="1" rotation="0" tangentialPressure="0.5" pointX="25.0803512086078" yTilt="12" time="271" speed="0.112779115645527" pointY="10.593737664288" pressure="0.568359375"/>

  <point xTilt="-26" perspective="1" rotation="0" tangentialPressure="0.5" pointX="24.943450707534" yTilt="13" time="291" speed="0.116269521683248" pointY="8.42346207373681" pressure="0.56640625"/>

  <point xTilt="-26" perspective="1" rotation="0" tangentialPressure="0.5" pointX="24.5246962336615" yTilt="15" time="311" speed="0.117598654226805" pointY="6.52900072799594" pressure="0.5625"/>

  <point xTilt="-26" perspective="1" rotation="0" tangentialPressure="0.5" pointX="23.899248846403" yTilt="17" time="331" speed="0.116831373354285" pointY="4.98484360559079" pressure="0.5556640625"/>

  <point xTilt="-26" perspective="1" rotation="0" tangentialPressure="0.5" pointX="22.7772016023079" yTilt="19" time="363" speed="0.109583282947662" pointY="3.24942843021499" pressure="0.5283203125"/>

  <point xTilt="-26" perspective="1" rotation="0" tangentialPressure="0.5" pointX="21.5612030339478" yTilt="19" time="393" speed="0.0975202536703222" pointY="2.19046278955643" pressure="0.521484375"/>

  <point xTilt="-25" perspective="1" rotation="0" tangentialPressure="0.5" pointX="20.7532216452577" yTilt="19" time="413" speed="0.0876311515978862" pointY="1.93478097137461" pressure="0.5205078125"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="19.9613461978705" yTilt="19" time="433" speed="0.0778814532027946" pointY="2.02135040587665" pressure="0.521484375"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="19.1802080446844" yTilt="19" time="453" speed="0.073526539387542" pointY="2.46426379170389" pressure="0.5234375"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="17.9749467705262" yTilt="19" time="483" speed="0.073526539387542" pointY="3.90977202362944" pressure="0.5302734375"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="17.1320691756801" yTilt="18" time="503" speed="0.068744331700357" pointY="5.24253866643546" pressure="0.53125"/>

  <point xTilt="-24" perspective="1" rotation="0" tangentialPressure="0.5" pointX="16.3804585815498" yTilt="17" time="523" speed="0.0685502402839409" pointY="6.55517288261298" pressure="0.5380859375"/>

  <point xTilt="-23" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.8811744011632" yTilt="16" time="543" speed="0.0705075793577963" pointY="7.74701253901956" pressure="0.546875"/>

  <point xTilt="-20" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.4973161334461" yTilt="11" time="603" speed="0.0708863593466234" pointY="10.6984262827561" pressure="0.5576171875"/>

  <point xTilt="-20" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.4275237211346" yTilt="10" time="623" speed="0.0683513020690757" pointY="11.1212072419544" pressure="0.55859375"/>

  <point xTilt="-20" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.3872588678776" yTilt="9" time="643" speed="0.0683513020690757" pointY="11.2581077430281" pressure="0.5556640625"/>

  <point xTilt="-20" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.2933075436107" yTilt="8" time="663" speed="0.0683513020690757" pointY="11.0889953593488" pressure="0.5546875"/>

  <point xTilt="-20" perspective="1" rotation="0" tangentialPressure="0.5" pointX="14.7913390396743" yTilt="9" time="703" speed="0.0683513020690757" pointY="9.37773909592722" pressure="0.5556640625"/>

  <point xTilt="-20" perspective="1" rotation="0" tangentialPressure="0.5" pointX="14.3833218600036" yTilt="11" time="723" speed="0.0683513020690757" pointY="8.10335649034383" pressure="0.556640625"/>

  <point xTilt="-21" perspective="1" rotation="0" tangentialPressure="0.5" pointX="12.8586260833393" yTilt="14" time="763" speed="0.0676851373498864" pointY="5.38749213816058" pressure="0.548828125"/>

  <point xTilt="-22" perspective="1" rotation="0" tangentialPressure="0.5" pointX="11.0654979516285" yTilt="17" time="793" speed="0.0741818538196536" pointY="3.63194453615628" pressure="0.5400390625"/>

  <point xTilt="-21" perspective="1" rotation="0" tangentialPressure="0.5" pointX="9.82534047131357" yTilt="18" time="813" speed="0.0783905077277158" pointY="2.94945527345049" pressure="0.541015625"/>

  <point xTilt="-20" perspective="1" rotation="0" tangentialPressure="0.5" pointX="7.68325027804227" yTilt="19" time="843" speed="0.0822081177412638" pointY="2.62532320473181" pressure="0.546875"/>

  <point xTilt="-19" perspective="1" rotation="0" tangentialPressure="0.5" pointX="6.14244856007519" yTilt="19" time="863" speed="0.0834240594387112" pointY="2.7239720952114" pressure="0.5498046875"/>

  <point xTilt="-18" perspective="1" rotation="0" tangentialPressure="0.5" pointX="4.77075922578743" yTilt="19" time="883" speed="0.0830533530104348" pointY="2.99777309735886" pressure="0.5537109375"/>

  <point xTilt="-18" perspective="1" rotation="0" tangentialPressure="0.5" pointX="3.62186874618829" yTilt="19" time="903" speed="0.0815606781388215" pointY="3.46685863780267" pressure="0.556640625"/>

  <point xTilt="-17" perspective="1" rotation="0" tangentialPressure="0.5" pointX="2.70651441547964" yTilt="19" time="923" speed="0.0798369907953755" pointY="4.21779815104533" pressure="0.55859375"/>

  <point xTilt="-17" perspective="1" rotation="0" tangentialPressure="0.5" pointX="2.15085944053332" yTilt="19" time="943" speed="0.0776559664165598" pointY="5.30293594632092" pressure="0.560546875"/>

  <point xTilt="-17" perspective="1" rotation="0" tangentialPressure="0.5" pointX="2.1132789108268" yTilt="18" time="963" speed="0.0754281891051743" pointY="6.62966286113839" pressure="0.564453125"/>

  <point xTilt="-17" perspective="1" rotation="0" tangentialPressure="0.5" pointX="2.53203338469938" yTilt="17" time="983" speed="0.0742145104899105" pointY="8.12147567430947" pressure="0.568359375"/>

  <point xTilt="-17" perspective="1" rotation="0" tangentialPressure="0.5" pointX="3.25948506687548" yTilt="15" time="1003" speed="0.0751888129429815" pointY="9.73609628991434" pressure="0.5791015625"/>

  <point xTilt="-17" perspective="1" rotation="0" tangentialPressure="0.5" pointX="4.185576691786" yTilt="13" time="1023" speed="0.0787694987165481" pointY="11.4211803987189" pressure="0.5947265625"/>

  <point xTilt="-17" perspective="1" rotation="0" tangentialPressure="0.5" pointX="8.17985013487834" yTilt="10" time="1083" speed="0.100756071588524" pointY="17.1307365905586" pressure="0.6171875"/>

  <point xTilt="-18" perspective="1" rotation="0" tangentialPressure="0.5" pointX="10.947387715408" yTilt="8" time="1113" speed="0.115227777836688" pointY="20.2814613579172" pressure="0.6435546875"/>

  <point xTilt="-19" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.4436296624374" yTilt="2" time="1174" speed="0.135775247332938" pointY="26.1561034481105" pressure="0.6474609375"/>

  <point xTilt="-20" perspective="1" rotation="0" tangentialPressure="0.5" pointX="16.4744099058161" yTilt="1" time="1193" speed="0.136617226037859" pointY="27.8895053808234" pressure="0.6376953125"/>

  <point xTilt="-21" perspective="1" rotation="0" tangentialPressure="0.5" pointX="17.2287048234968" yTilt="0" time="1213" speed="0.132803399677045" pointY="29.3370268554118" pressure="0.6220703125"/>

  <point xTilt="-21" perspective="1" rotation="0" tangentialPressure="0.5" pointX="17.599141473461" yTilt="0" time="1234" speed="0.123936712974534" pointY="30.281237664288" pressure="0.5107421875"/>

  <point xTilt="-21" perspective="1" rotation="0" tangentialPressure="0.5" pointX="17.639406326718" yTilt="-1" time="1243" speed="0.11778968348695" pointY="30.520813541167" pressure="0.40234375"/>

  <point xTilt="-21" perspective="1" rotation="0" tangentialPressure="0.5" pointX="17.6045101205619" yTilt="-1" time="1253" speed="0.110455755412217" pointY="30.6214756743095" pressure="0.1142578125"/>

  <point xTilt="-21" perspective="1" rotation="0" tangentialPressure="0.5" pointX="17.5186117669471" yTilt="-2" time="1264" speed="0.102283870264839" pointY="30.5953035196924" pressure="0"/>

  <point xTilt="-21" perspective="1" rotation="0" tangentialPressure="0.5" pointX="17.5186117669471" yTilt="-2" time="1264" speed="0.0943550006212422" pointY="30.5953035196924" pressure="0"/>

  <config>
 <param type="internal" name="capSize">2</param>
 <param type="internal" name="strokeWidth">7.456799999999999</param>
</config>

 </path>
</svg>
woltherav updated the task description. (Show Details)Mar 13 2017, 6:36 PM

Hi, @woltherav!

There is a problem in such format, which should be discussed.

The main problem is that this approach is "imperative", while the rest of SVG, including Inkscape's extensions of it are "declarative". I mean that the format tries to save the state of the stylus during the stroke and the "brush" preset for redrawing later, instead of saving the exact shape of the curve. Inkscape just saves the points and their corresonding normals.

The main difference between the approaches is that in "imperative" (current) solution the user cannot edit the shape. That is, he cannot manually drag the handles and change the width fo the stroke. Instead, the user should edit the preset and rerun the whole stroke to get the updted result. While such feture might be nice to have, I have a feeling that it is not the topmost priority for the users.

Actually, the only reason for having such imperative data format would be that "rerunning" of the stroke. The user has nothing to edit on canvas, which is a desirable feature, which has been asked for multiple times already. I think we should somehow combine he two approaches.

There is a possible solution for that. We can implement both usecases (on-canvas editing and stroke rerunning) if we store the shape in three different forms:

  1. <path>...</path>: a fallback for rendering the shape in simple editors
  2. Inkscape's power stroke (or the like) "declarative" format, which stores all the baseline points and normals info. This is the main data model for the shape. Krita loads this data by default and uses it for on-canvas editing.
  3. Our own "imperative" form for rerunning of the stroke on canvas. This data is not used for loading the shape. It i sused only when the user presses "Rerun" button in the preset editor. We might also want to drop this data on the first on-canvas editing acion, because they might diverge and become inconsistent.

What do you think about all that?

woltherav added a comment.EditedMar 15 2017, 6:21 PM

Uhm, dmitry, the user can change the handles of the stroke. This was already there. You just select a calligraphic stroke and move the nodes. It's a bit wonky because of the bounding box, but I managed to fix that bit.

(here, I've made a screencast, and set the time to the moment it's being modified: https://youtu.be/PNeoNqUhZ_U?t=3m )

The data inside the paintinfos that isn't the position needs a redraw function or a special tool though, because that data is too complex to edit. But either how, it's not an imperative format.

Inkscape's powerstroke really is written SUPER-differently, and it is going to take a small forever until I can figure out a method that satisfyingly converts one to the other.

Edit: Inkscape's calligraphy tool IS NOT generating powerstrokes btw, it just generates paths. The powerstroke is a live-path effect, and has 20+ interpolation modes and the like.

I am fine with some option to strip this data from the svg if we're not saving to kra, but this is the only method to save to kra.

Hi, @woltherav!

Uhm, dmitry, the user can change the handles of the stroke. This was already there. You just select a calligraphic stroke and move the nodes. It's a bit wonky because of the bounding box, but I managed to fix that bit.
(here, I've made a screencast, and set the time to the moment it's being modified: https://youtu.be/PNeoNqUhZ_U?t=3m )

I know about the ability to change the handles of the baseline. I speak about a different thing: handles for changing the width of the stoke in specific points. With the current data model it is not possible, even in theory. There is just no reverse transformation for "pressure->sensors->width" chain.

Inkscape's powerstroke really is written SUPER-differently, and it is going to take a small forever until I can figure out a method that satisfyingly converts one to the other.
Edit: Inkscape's calligraphy tool IS NOT generating powerstrokes btw, it just generates paths. The powerstroke is a live-path effect, and has 20+ interpolation modes and the like.

You mean we will need a separate tool for making the stroke width editable?

I am fine with some option to strip this data from the svg if we're not saving to kra, but this is the only method to save to kra.

Ok, then we should wrap this data into a special element with 'krita' namespace, like that:

<path id="shape0" krita:type="calligraphic-stroke" d="..." fill="#000000">
  
  <!-- --
          1) Define a custom element, which is not visible to anyone not knowing about krita namespace
          2) Use xmlns attribute to make krita namespace the default inside this element (to avoid constant repetition of 'krita:' prefix)
  <!-- -->
  <krita:calligraphic-stroke-data xmlns="http://krita.org/kritasvg">

    <!-- inside this block we can omit 'krita:' prefix now -->

    <point xTilt="-26" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.2100935135469" yTilt="4" time="21" speed="0" pointY="29.2987752448177" pressure="0.0908203125"/>
    ...
    <point xTilt="-25" perspective="1" rotation="0" tangentialPressure="0.5" pointX="15.3335723968683" yTilt="4" time="31" speed="0" pointY="29.1175834051613" pressure="0.15234375"/>

    <config>
      <param type="internal" name="capSize">2</param>
      <param type="internal" name="strokeWidth">7.456799999999999</param>
    </config>
  <krita:calligraphic-stroke-data>
</path>

This was we abstract out our very non-standard data from other editors and in the future we can still add some editing capabilities.

Yes, the sensor width stuff is indeed a problem, but at the same time that's also an argument for keeping the stroke data, because you would have the same problem if you ever wanted to have the sensor data. My instinct is to indeed write a seperate tool where the user selects a stroke, makes a new stroke and the closest points for the paintinformation will have their relevant data copied into it. Several programs have implemented something similar.

However, I do not wish to do this straight away yet. We first need to have something that saves and loads, is relatively usable and looks decent(I need to iron bugs out of the old path generation code). For end-users, the ability to just move the path nodes should already prove super-useful. (after all, it solves the issue of having a stroke that has a wobble in there).

I am fine with adding code to save and load an element with a krita namespace thing. What will it do?

Hi, @woltherav!

However, I do not wish to do this straight away yet. We first need to have something that saves and loads,

Well, the problem of file formats is that once a format gets wild we cannot change it, because if we do, users' files will become invalid. So the format should be at least extensible from the very beginning :)

I am fine with adding code to save and load an element with a krita namespace thing. What will it do?

Such wrapping into a custom element will solve the following problems:

  1. Moving this element into a separate namespace will make Inkscape and other editors ignore it. Such behavior will be regulated by the standard, but not by a good will of developers to ignore unknown tags, which is not guaranteed :)
  2. Having one single node for points data will help us:
    1. Add version attribute when you change the format next time :)
    2. Add a separate element with Inkscape-like powerstroke data, if we ever implement width editing in the future. Then the format for both "tools" will be the same and we will be able to convert usual calligraphy tool stroke into powerstroke.

Basically, this format is extensible into something like that:

<path id="shape0" krita:type="calligraphic-stroke" d="..." fill="#000000">
  
  <!-- high priority data for on-canvas editing of the stroke -->
  <krita:power-stroke-data  version="13" xmlns="http://krita.org/kritasvg">
    ...
  <krita:power-stroke-data>

  <!-- low priority data for rerunning the stroke with a modified preset -->
  <krita:calligraphic-stroke-data version="42" xmlns="http://krita.org/kritasvg">
    ...
  <krita:calligraphic-stroke-data>

</path>

Okay, made the changes in R37:e715d9c3a765c617b220cc9df4d9c198922afb32

Here's a music note:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- Created using Krita: http://krita.org -->
<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:krita="http://krita.org/kritasvg"
    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
    width="249.6pt"
    height="261.84pt"
    viewBox="0 0 249.6 261.84">
<defs/>
 </path><path krita:type="calligraphic-stroke" id="shape0" transform="translate(78.681341676, 11.946160286)" d="M46.1068 116.528C46.3338 115.779 46.579 115.681 47.2618 116.071L42.164 105.664L37.1711 109.199C38.764 102.341 41.3065 95.0846 46.206 89.8824C50.9185 84.8787 60.168 85.8583 66.0096 87.6C77.6913 91.0829 86.0459 103.98 87.1882 115.664C87.5483 119.348 87.1561 123.002 86.4553 126.631C84.9339 134.507 81.7146 142.311 76.1788 148.235C69.9914 154.857 61.0783 158.405 52.271 159.817C42.6732 161.356 32.6048 160.293 23.2782 157.732C13.2211 154.97 2.33874 147.318 1.03016 136.137C0.633944 132.752 0.854707 129.728 1.6357 126.421C2.29074 123.647 3.76377 119.864 5.15309 117.383C10.6339 107.596 17.1952 97.6203 25.1185 89.5985C36.3519 78.2257 49.178 68.2674 56.5361 53.7672C59.6175 47.695 61.8948 41.3074 63.0324 34.5713C64.3501 26.7689 64.4699 19.7262 59.8372 13.0518C57.7279 10.0129 55.0588 5.89892 51.0075 5.62608C46.8101 5.34341 45.1622 8.1201 43.2323 11.4091C41.9167 13.6511 40.6958 15.9496 39.6305 18.322C33.7516 31.413 34.4367 44.9198 36.4235 58.9281C37.7749 68.4561 39.8729 77.8675 40.9682 87.4339C42.3318 99.3424 42.7695 111.536 42.7335 123.513C42.6955 136.154 42.7743 149.178 41.5686 161.874C40.5771 172.314 39.0618 178.936 37.7704 190.303C37.5052 192.637 37.3536 201.496 36.5152 205.125C35.3834 210.025 32.6252 215.502 27.7485 217.604C24.9639 218.804 21.5675 218.49 18.7283 218.052C10.5744 216.793 1.73322 211.782 0.231418 202.997C-0.751375 197.248 1.4462 191.153 6.18656 187.649C8.08528 186.246 11.3318 184.743 13.8442 185.419C18.6378 186.71 20.0311 193.561 21.0069 197.6C21.0004 197.604 20.994 197.609 20.9875 197.613C19.0716 194.735 14.311 191.46 10.8292 194.144C9.02383 195.536 6.71903 199.789 8.42094 202.233C9.79137 204.201 11.2562 206.182 13.1441 207.661C15.069 209.169 17.3302 210.285 19.6573 211.036C21.3846 211.593 23.6641 211.268 25.0755 210.058C26.7109 208.655 27.2335 205.5 27.5707 203.877C28.2929 200.401 28.5451 191.284 28.7885 189.221C29.7576 181.005 31.7659 170.418 32.6473 161.675C33.4793 153.422 33.6345 146.313 33.7324 137.85C33.8413 128.447 33.6389 119.563 33.3019 110.167C33.0504 103.155 32.7791 94.9332 32.023 87.746C31.2603 80.4963 29.5891 71.2996 28.5851 64.5884C25.912 46.718 24.913 27.3875 36.264 12.1568C38.4287 9.25219 39.7682 7.57812 42.302 4.97665C44.9283 2.2803 47.0979 -0.173381 51.0503 0.013263C56.9809 0.293325 61.1705 4.80485 64.3936 9.31243C72.476 20.6161 71.3605 34.2792 67.4781 47.0528C64.2841 57.5616 58.7984 67.8324 51.8733 76.3381C46.4097 83.0488 40.328 89.0325 34.5046 95.4361C26.0052 104.782 27.5314 103.899 20.2185 111.306C13.7234 117.885 4.69659 125.415 8.8776 135.853C9.53097 137.484 11.0041 139.95 12.2519 141.195C13.8013 142.741 15.3936 144.278 17.2061 145.505C18.9945 146.716 20.9529 147.696 22.9749 148.456C32.4033 151.997 41.8025 153.12 51.7822 151.997C57.5606 151.347 63.5907 148.776 68.055 145.062C77.3835 137.301 83.2181 123.084 79.6278 111.187C77.1206 102.88 71.2273 94.5836 62.4647 92.3085C59.6816 91.5859 56.2568 91.2932 53.524 92.3946C48.2562 94.5177 44.6668 100.87 42.164 105.664L37.1711 109.199L44.9517 116.985C45.7274 117.304 45.8555 117.357 46.1068 116.528Z" fill="#090609">
  <krita:calligraphic-stroke-data xmlns="http://krita.org/kritasvg">
 <point tangentialPressure="0.5" perspective="1" time="22" pressure="0.103515625" pointY="116.528321587809" speed="0" xTilt="-28" yTilt="12" pointX="46.1067685255458" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="92" pressure="0.2548828125" pointY="107.431637332001" speed="0.0957313031845028" xTilt="-26" yTilt="13" pointX="39.6675425916589" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="182" pressure="0.29296875" pointY="90.0176195782549" speed="0.234134894958004" xTilt="-26" yTilt="17" pointX="51.8305249112231" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="272" pressure="0.28515625" pointY="96.099110738037" speed="0.297710847654469" xTilt="-24" yTilt="20" pointX="74.1974657873966" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="362" pressure="0.3095703125" pointY="123.005876247493" speed="0.324970452801458" xTilt="-28" yTilt="18" pointX="83.668919806553" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="452" pressure="0.373046875" pointY="151.726868111338" speed="0.395375242655639" xTilt="-27" yTilt="11" pointX="64.9304316391571" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="542" pressure="0.38671875" pointY="153.093925998093" speed="0.499210148315156" xTilt="-25" yTilt="5" pointX="23.1265680366212" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="632" pressure="0.3876953125" pointY="132.971344954699" speed="0.429477876644889" xTilt="-25" yTilt="7" pointX="4.43918483695456" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="722" pressure="0.4482421875" pointY="102.921623929893" speed="0.388792544771497" xTilt="-25" yTilt="12" pointX="20.9801593919922" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="812" pressure="0.3505859375" pointY="62.599804391506" speed="0.576454938414449" xTilt="-23" yTilt="20" pointX="56.2085171466965" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="902" pressure="0.2880859375" pointY="26.3536060295273" speed="0.565294489281781" xTilt="-20" yTilt="26" pointX="67.2301551869739" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="992" pressure="0.2626953125" pointY="5.61776537337944" speed="0.374264377398412" xTilt="-20" yTilt="27" pointX="57.3157914474972" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="1084" pressure="0.2646484375" pointY="4.83841461550818" speed="0.215609902253203" xTilt="-25" yTilt="30" pointX="45.544613880524" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="1172" pressure="0.3447265625" pointY="35.2586466563511" speed="0.303925477455131" xTilt="-20" yTilt="26" pointX="31.3033628733031" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="1264" pressure="0.3759765625" pointY="95.3708649478951" speed="0.602787645294423" xTilt="-21" yTilt="17" pointX="37.1633991729251" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="1354" pressure="0.37109375" pointY="152.161260337037" speed="0.710424742725369" xTilt="-23" yTilt="8" pointX="37.8107287641624" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="1444" pressure="0.376953125" pointY="189.761740343841" speed="0.584614660668095" xTilt="-21" yTilt="1" pointX="33.2794216255012" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="1534" pressure="0.369140625" pointY="209.23273304869" speed="0.346167245692118" xTilt="-19" yTilt="-2" pointX="30.5538233466072" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="1624" pressure="0.3642578125" pointY="214.713740837653" speed="0.185930857413316" xTilt="-18" yTilt="0" pointX="22.0192937358205" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="1714" pressure="0.3984375" pointY="206.47306479131" speed="0.190020648956217" xTilt="-21" yTilt="-4" pointX="6.21082371823564" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="1804" pressure="0.40625" pointY="194.246201262084" speed="0.192656429614358" xTilt="-21" yTilt="-3" pointX="5.95529887958931" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="1894" pressure="0.408203125" pointY="189.902279005097" speed="0.140099490793653" xTilt="-23" yTilt="0" pointX="15.8185576513368" rotation="0"/>
 <point tangentialPressure="0.5" perspective="1" time="1992" pressure="0.0009765625" pointY="197.606352890283" speed="0.146829480817517" xTilt="-20" yTilt="0" pointX="20.9971943812353" rotation="0"/>
 <config>
  <param type="internal" name="capSize">0</param>
  <param type="internal" name="strokeWidth">24</param>
 </config>
</krita:calligraphic-stroke-data>

 </path>
</svg>
woltherav updated the task description. (Show Details)Mar 18 2017, 5:15 PM
woltherav updated the task description. (Show Details)Mar 23 2017, 4:45 PM

Okay, stuck with a problem, the loading of the pressure curves...

This, is obviously saving data, but for some reason Krita isn't loading it...?

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- Created using Krita: http://krita.org -->
<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:krita="http://krita.org/kritasvg"
    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
    width="48pt"
    height="48pt"
    viewBox="0 0 48 48">
<defs/>
<path krita:type="calligraphic-stroke" id="shape0" transform="translate(9.9637106851, 0.42272122605)" d="M12.5739 25.3799C11.3145 25.4818 10.4717 24.7423 9.51203 23.989C7.44645 22.3674 6.66393 20.3892 8.13596 17.929C9.26967 16.0342 11.3535 15.2109 13.4064 14.7877C18.5866 13.7197 24.5079 16.021 26.1371 21.4392C28.7972 30.2858 19.9347 38.9116 11.1238 37.471C8.71137 37.0766 6.25285 36.3888 4.46271 34.6042C3.23097 33.3763 2.10346 32.0143 1.269 30.4807C-1.97504 24.5185 2.06868 18.1415 5.68299 13.3688C8.01643 10.2875 11.4236 8.72159 13.1198 5.12152C13.525 4.26165 14.6856 2.15628 13.1355 1.77056C11.8671 1.45494 11.5564 3.80242 11.4483 4.49078C10.928 7.80308 10.1818 10.5148 10.4152 13.8753C10.9881 22.1243 13.2763 30.4138 12.7615 38.7208C12.5095 42.7871 8.51064 46.569 4.31582 44.2454C0.925272 42.3674 3.14017 38.7445 5.92555 37.9277L7.74229 38.8783L5.75193 40.1014L6.9076 40.165L6.65741 39.7747C5.89972 39.8879 3.77554 40.6519 4.38773 41.7868C5.64178 44.1115 9.32751 42.7765 10.3848 41.0441C10.8098 40.3477 10.8186 39.5134 10.8712 38.7231C10.9516 37.517 10.8351 35.7101 10.7535 34.584C10.5641 31.969 10.3205 29.3462 10.0324 26.7404C9.81776 24.7991 9.49709 22.863 9.23195 20.9292C9.03623 19.5017 8.83678 18.0696 8.69611 16.6354C8.25188 12.1065 8.74572 8.86502 9.57443 4.52781C9.97943 2.40814 10.8013 -0.195358 13.5149 0.00740316C14.2169 0.0598548 14.808 0.388613 15.3372 0.837633C17.7459 2.88119 16.2774 5.58784 14.9058 7.7889C12.4369 11.7508 8.97143 14.9629 6.42886 18.8906C4.06612 22.5405 3.13589 25.5698 5.81004 29.4545C9.55658 34.897 18.2961 32.3544 20.3562 26.7894C20.7456 25.7377 21.3025 24.5801 20.9721 23.441C19.9268 19.8372 16.3687 20.4527 13.6228 20.9322C12.9384 21.0518 11.9375 20.491 11.3232 20.8133C9.06689 21.9969 11.4969 24.5189 12.4482 25.4418Z" fill="#000000">
  <krita:calligraphic-stroke-data xmlns="http://krita.org/kritasvg">
 <point rotation="0" time="21" pressure="0.0927734375" yTilt="14" speed="0.153221654023736" pointY="25.4108059750974" tangentialPressure="0.5" perspective="1" pointX="12.5110566735495" xTilt="-23"/>
 <point rotation="0" time="81" pressure="0.240234375" yTilt="14" speed="0.191061100910887" pointY="24.9860117732362" tangentialPressure="0.5" perspective="1" pointX="11.5903336957399" xTilt="-22"/>
 <point rotation="0" time="141" pressure="0.337890625" yTilt="13" speed="0.169879374094397" pointY="23.4760797760995" tangentialPressure="0.5" perspective="1" pointX="9.99852983031399" xTilt="-20"/>
 <point rotation="0" time="201" pressure="0.509765625" yTilt="13" speed="0.169879374094397" pointY="21.4547841425991" tangentialPressure="0.5" perspective="1" pointX="9.38918838435837" xTilt="-20"/>
 <point rotation="0" time="261" pressure="0.61328125" yTilt="16" speed="0.169879374094397" pointY="19.7817794897716" tangentialPressure="0.5" perspective="1" pointX="10.1515362726905" xTilt="-20"/>
 <point rotation="0" time="321" pressure="0.6884765625" yTilt="15" speed="0.169879374094397" pointY="18.5335690388053" tangentialPressure="0.5" perspective="1" pointX="11.7513931087678" xTilt="-19"/>
 <point rotation="0" time="381" pressure="0.67578125" yTilt="18" speed="0.169879374094397" pointY="17.6054641712319" tangentialPressure="0.5" perspective="1" pointX="14.3954518059761" xTilt="-21"/>
 <point rotation="0" time="441" pressure="0.6669921875" yTilt="21" speed="0.129100284009454" pointY="17.5148682514037" tangentialPressure="0.5" perspective="1" pointX="17.5334260364701" xTilt="-21"/>
 <point rotation="0" time="501" pressure="0.6689453125" yTilt="19" speed="0.079393881755245" pointY="18.8677673208382" tangentialPressure="0.5" perspective="1" pointX="20.8888304745511" xTilt="-23"/>
 <point rotation="0" time="561" pressure="0.6630859375" yTilt="17" speed="0.0726450314140391" pointY="21.9278961683686" tangentialPressure="0.5" perspective="1" pointX="23.3342492290256" xTilt="-23"/>
 <point rotation="0" time="622" pressure="0.666015625" yTilt="15" speed="0.0724226097697531" pointY="25.8215074783186" tangentialPressure="0.5" perspective="1" pointX="23.573154025017" xTilt="-25"/>
 <point rotation="0" time="681" pressure="0.6708984375" yTilt="13" speed="0.0758202468643878" pointY="29.9788535771016" tangentialPressure="0.5" perspective="1" pointX="22.0242993363985" xTilt="-26"/>
 <point rotation="0" time="742" pressure="0.6708984375" yTilt="9" speed="0.080900109867193" pointY="33.0571016085976" tangentialPressure="0.5" perspective="1" pointX="18.8084797229411" xTilt="-25"/>
 <point rotation="0" time="802" pressure="0.634765625" yTilt="8" speed="0.080012721137666" pointY="34.7965432692992" tangentialPressure="0.5" perspective="1" pointX="15.1658526649597" xTilt="-25"/>
 <point rotation="0" time="861" pressure="0.6015625" yTilt="5" speed="0.0770622150864267" pointY="34.9233775570587" tangentialPressure="0.5" perspective="1" pointX="11.0454160149955" xTilt="-24"/>
 <point rotation="0" time="921" pressure="0.5859375" yTilt="5" speed="0.0762417193849531" pointY="33.7093922313607" tangentialPressure="0.5" perspective="1" pointX="7.18535874942645" xTilt="-22"/>
 <point rotation="0" time="974" pressure="0.55859375" yTilt="4" speed="0.0767033710251506" pointY="31.1183489242741" tangentialPressure="0.5" perspective="1" pointX="4.31044822687812" xTilt="-20"/>
 <point rotation="0" time="1033" pressure="0.5556640625" yTilt="4" speed="0.0830346327780926" pointY="26.9428836415249" tangentialPressure="0.5" perspective="1" pointX="2.2408347694694" xTilt="-19"/>
 <point rotation="0" time="1085" pressure="0.517578125" yTilt="6" speed="0.0837256094386986" pointY="22.9586764117473" tangentialPressure="0.5" perspective="1" pointX="2.34552338793754" xTilt="-19"/>
 <point rotation="0" time="1143" pressure="0.5087890625" yTilt="9" speed="0.0897620846144599" pointY="18.0685099836872" tangentialPressure="0.5" perspective="1" pointX="4.77215187755815" xTilt="-18"/>
 <point rotation="0" time="1203" pressure="0.509765625" yTilt="14" speed="0.102423233527153" pointY="13.2427673208382" tangentialPressure="0.5" perspective="1" pointX="8.22687628700696" xTilt="-18"/>
 <point rotation="0" time="1263" pressure="0.453125" yTilt="19" speed="0.109197339822957" pointY="8.85188507316463" tangentialPressure="0.5" perspective="1" pointX="12.4654231731917" xTilt="-18"/>
 <point rotation="0" time="1323" pressure="0.455078125" yTilt="24" speed="0.105172237261532" pointY="4.85559838740941" tangentialPressure="0.5" perspective="1" pointX="14.82494357405" xTilt="-18"/>
 <point rotation="0" time="1374" pressure="0.4501953125" yTilt="25" speed="0.0860030364592134" pointY="2.54036932513309" tangentialPressure="0.5" perspective="1" pointX="15.2383294008223" xTilt="-18"/>
 <point rotation="0" time="1433" pressure="0.396484375" yTilt="25" speed="0.0764069524614674" pointY="1.07070218125288" tangentialPressure="0.5" perspective="1" pointX="13.909589243342" xTilt="-18"/>
 <point rotation="0" time="1493" pressure="0.3837890625" yTilt="27" speed="0.0764069524614674" pointY="1.11096703451033" tangentialPressure="0.5" perspective="1" pointX="12.3097324072647" xTilt="-20"/>
 <point rotation="0" time="1553" pressure="0.380859375" yTilt="25" speed="0.0764069524614674" pointY="2.42762773601355" tangentialPressure="0.5" perspective="1" pointX="11.0534689856469" xTilt="-17"/>
 <point rotation="0" time="1613" pressure="0.3828125" yTilt="23" speed="0.0764069524614674" pointY="5.70720003379451" tangentialPressure="0.5" perspective="1" pointX="10.3045427150671" xTilt="-15"/>
 <point rotation="0" time="1673" pressure="0.3818359375" yTilt="20" speed="0.0706474976638573" pointY="10.0316452735937" tangentialPressure="0.5" perspective="1" pointX="9.44019053181729" xTilt="-17"/>
 <point rotation="0" time="1733" pressure="0.384765625" yTilt="17" speed="0.0824723068930401" pointY="15.1432683945676" tangentialPressure="0.5" perspective="1" pointX="9.54219482673497" xTilt="-17"/>
 <point rotation="0" time="1793" pressure="0.38671875" yTilt="15" speed="0.0946907192674689" pointY="20.8185994611388" tangentialPressure="0.5" perspective="1" pointX="10.194485449498" xTilt="-17"/>
 <point rotation="0" time="1853" pressure="0.388671875" yTilt="13" speed="0.103059200701111" pointY="26.6006323888411" tangentialPressure="0.5" perspective="1" pointX="11.0158884559404" xTilt="-17"/>
 <point rotation="0" time="1913" pressure="0.3876953125" yTilt="12" speed="0.105492203910117" pointY="32.066586218476" tangentialPressure="0.5" perspective="1" pointX="11.4990666950242" xTilt="-17"/>
 <point rotation="0" time="1973" pressure="0.3818359375" yTilt="11" speed="0.0999477190308593" pointY="36.9567526465362" tangentialPressure="0.5" perspective="1" pointX="11.8292384917314" xTilt="-19"/>
 <point rotation="0" time="2033" pressure="0.3828125" yTilt="9" speed="0.0864616990325456" pointY="40.4678478505447" tangentialPressure="0.5" perspective="1" pointX="11.6037553134923" xTilt="-20"/>
 <point rotation="0" time="2086" pressure="0.3837890625" yTilt="8" speed="0.0710856111612534" pointY="42.036163884904" tangentialPressure="0.5" perspective="1" pointX="10.7716150128481" xTilt="-18"/>
 <point rotation="0" time="2146" pressure="0.3837890625" yTilt="10" speed="0.0710856111612534" pointY="43.1253281655053" tangentialPressure="0.5" perspective="1" pointX="9.44824350246869" xTilt="-18"/>
 <point rotation="0" time="2205" pressure="0.384765625" yTilt="7" speed="0.0710856111612534" pointY="43.8782809214109" tangentialPressure="0.5" perspective="1" pointX="7.79738451893255" xTilt="-19"/>
 <point rotation="0" time="2265" pressure="0.3876953125" yTilt="2" speed="0.0710856111612534" pointY="43.7152082657201" tangentialPressure="0.5" perspective="1" pointX="5.59087056045009" xTilt="-18"/>
 <point rotation="0" time="2325" pressure="0.388671875" yTilt="4" speed="0.0710856111612534" pointY="42.6280572277816" tangentialPressure="0.5" perspective="1" pointX="3.85948187039998" xTilt="-17"/>
 <point rotation="0" time="2385" pressure="0.3896484375" yTilt="6" speed="0.0710856111612534" pointY="40.9993439135368" tangentialPressure="0.5" perspective="1" pointX="3.61252410375717" xTilt="-17"/>
 <point rotation="0" time="2445" pressure="0.392578125" yTilt="6" speed="0.0710856111612534" pointY="39.5276635269942" tangentialPressure="0.5" perspective="1" pointX="4.5842492290256" xTilt="-17"/>
 <point rotation="0" time="2505" pressure="0.3916015625" yTilt="9" speed="0.0710856111612534" pointY="38.851213992277" tangentialPressure="0.5" perspective="1" pointX="6.29147900712152" xTilt="-17"/>
 <point rotation="0" time="2565" pressure="0.3505859375" yTilt="10" speed="0.0710856111612534" pointY="39.5216237990057" tangentialPressure="0.5" perspective="1" pointX="7.32494357405064" xTilt="-19"/>
 <point rotation="0" time="2664" pressure="0" yTilt="6" speed="0.0710856111612534" pointY="40.1014376859062" tangentialPressure="0.5" perspective="1" pointX="5.75192997347799" xTilt="-18"/>
 <config>
  <param name="PressureRotation" type="bool">true</param>
  <param name="PressureSize" type="bool">true</param>
  <param name="RotationSensor" type="string"><![CDATA[<!DOCTYPE params>
<params angleOffset="90" lockedAngleMode="0" id="drawingangle" fanCornersEnabled="0" fanCornersStep="30"/>
]]></param>
  <param name="RotationUseCurve" type="bool">true</param>
  <param name="RotationUseSameCurve" type="bool">true</param>
  <param name="RotationValue" type="double">1</param>
  <param name="SizeSensor" type="string"><![CDATA[<!DOCTYPE params>
<params id="pressure">
 <curve>0,0;0.376569,0.244541;0.635983,0.746725;1,1;</curve>
</params>
]]></param>
  <param name="SizeUseCurve" type="bool">true</param>
  <param name="SizeUseSameCurve" type="bool">true</param>
  <param name="SizeValue" type="double">1</param>
  <param name="capSize" type="double">0</param>
  <param name="strokeWidth" type="double">7.418399999999999</param>
 </config>
</krita:calligraphic-stroke-data>

 </path>
</svg>
woltherav updated the task description. (Show Details)Mar 25 2017, 3:14 PM

Open bugs:

  • There's an issue where moving a handle changes the stroke config to use the latest strokeconfig used... but I have NO idea what is calling this change O_O, like, the change already seems to have happened BEFORE the handle is moved!
  • Cusp rendering issues... these will take a while to fix.

Other than that, it can be tested properly.

Two more bugs:

  1. Sometimes one can get an infinite recursion, when painting random strokes with mouse:
#1030 0x00007f5ddc16b47d in KarbonSimplifyPath::subdivideAux (p1=p1@entry=0x16ce3fe0, p2=<optimized out>)
    at /home/devel5/kde-src/krita/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonSimplifyPath.cpp:209
#1031 0x00007f5ddc16b47d in KarbonSimplifyPath::subdivideAux (p1=p1@entry=0x16ce3fe0, p2=<optimized out>)
    at /home/devel5/kde-src/krita/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonSimplifyPath.cpp:209
#1032 0x00007f5ddc16b47d in KarbonSimplifyPath::subdivideAux (p1=p1@entry=0x16ce3fe0, p2=<optimized out>)
    at /home/devel5/kde-src/krita/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonSimplifyPath.cpp:209
#1033 0x00007f5ddc16b47d in KarbonSimplifyPath::subdivideAux (p1=0x16ce3fe0, p2=p2@entry=0x16ce4000)
    at /home/devel5/kde-src/krita/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonSimplifyPath.cpp:209
#1034 0x00007f5ddc16b8a6 in KarbonSimplifyPath::subdivide (subpath=0x16ab2b60)
    at /home/devel5/kde-src/krita/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonSimplifyPath.cpp:157
#1035 0x00007f5ddc16c160 in karbonSimplifyPath (path=path@entry=0x16aeac30, error=error@entry=0.29999999999999999)
    at /home/devel5/kde-src/krita/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonSimplifyPath.cpp:89
#1036 0x00007f5ddc165bb0 in KarbonCalligraphicShape::simplifyPath (this=0x16aeac30)
    at /home/devel5/kde-src/krita/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonCalligraphicShape.cpp:413
#1037 KarbonCalligraphicShape::updatePath (this=0x16aeac30, size=...)
    at /home/devel5/kde-src/krita/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonCalligraphicShape.cpp:391
#1038 0x00007f5ddc1659a6 in KarbonCalligraphicShape::appendPoint (this=0x16aeac30, paintInfo=...)
    at /home/devel5/kde-src/krita/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonCalligraphicShape.cpp:112
#1039 0x00007f5ddc159905 in KarbonCalligraphyTool::addPoint (this=0x12b15aa0, event=<optimized out>, lastPoint=<optimized out>)
    at /home/devel5/kde-src/krita/plugins/tools/karbonplugins/tools/CalligraphyTool/KarbonCalligraphyTool.cpp:226
#1040 0x00007f5e22a62329 in KoToolProxy::mouseMoveEvent (this=this@entry=0x12a7d278, event=event@entry=0x7ffef00faf80)
    at /home/devel5/kde-src/krita/libs/flake/KoToolProxy.cpp:344
#1041 0x00007f5e22a623ef in KoToolProxy::mouseMoveEvent (this=this@entry=0x12a7d278, event=event@entry=0x12f369a0, point=...)
    at /home/devel5/kde-src/krita/libs/flake/KoToolProxy.cpp:328
#1042 0x00007f5e27781fbc in KisToolProxy::forwardEvent (this=0x12a7d278, state=KisToolProxy::CONTINUE, action=KisTool::Primary, 
    event=<optimized out>, originalEvent=0x12f369a0) at /home/devel5/kde-src/krita/libs/ui/canvas/kis_tool_proxy.cpp:148
  1. The brush outline is offset when painting with a mouse. Look at small cyan circle on a screenshot

Tested here and I didn't have the outline offset issue, and I couldn't reproduce the infinite recursion issue (built with Qt 5.8.0).