Krita: SVG Pipe/Animated Brush
Open, NormalPublic

Description

The full project can be found at: https://docs.google.com/document/d/1SwIBNFthJ5Qg3N7DBgzMKMrW-rn5hB_NPxuf8EuMr2w/edit?usp=sharing

Introduction

Krita can handle SVG 1.1 right now, however there is not much that can be done with this format.

This project aims to implement an animated brush for Krita that will be saved as an SVG symbol library. Allowing an easier distribution of animated brushes, higher resolutions and ease to keep them under source control.

Project Goals

Technical goals

  1. Write the proper documentation for end users as per the Krita Contribution Guide.
  1. Write unit tests, comments, and documentation for better maintainability.
  1. Define the tags and structure of an SVG library containing the source tips for a Pipe/Animated brush for Krita.
  1. Write the code for a Pipe/Animated Brush uses that uses an SVG library a source.
  1. Create the User Interface for loading and configuring the Pipe/Animated Brush, which should be done in accordance with the KDE Human Interface Guidelines.

Soft goals

  1. Bond, learn, and become an important member of the Krita and KDE communities.
  1. Get user and artist feedback for the implementation of the project.
  1. Learn about the KDE Human Interface Guidelines (HIG), Community Identity Guidelines (CIG) and Accessibility Guidelines (AG.)
  1. Learn about the testing libraries and guidelines used by Krita and KDE.
  1. Have fun!! 😄

Timeline

Community Bonding Period

0. Learn about the similar implementations that already exists
0.1 Understand Alchemy Pull Shapes.
0.2 Understand GIH brushes.
0.3 Understand Krita SVG libraries.
0.4 Understand Krita Unit Testing framework.
0.5 Add my personal blog to Planet KDE.
0.6 Get feedback from digital artists and the community on how would they use this tool. This will include asking about the options they would like to see in the user interface, how do they use similar tool on other programs, and what other features would they like to see. For the users to feel very comfortable using this tool.
0.6.1 Write a blog post about ideas for the implementation, to get more feedback and discussion.
0.6.2 Posting on reddit to invite the community to join with ideas and discussion.
0.6.3 Choose the best options to include in the user interface.
0.7 Testing and playing with related code, to choose the best way to implement the brush.
0.8 Talk with the mentors about the results and choose the best solutions.
0.9 Being on Krita IRC channel to help users and bond with the community. (Already started)
0.10 Help with bugs that, preferently if they are relevant to the project, to increase my knowledge and create the best implementation possible. (Already started to work on: bug 406124)

Google Summer of Code

1. Write end user documentation.
May 27 - June 01
At the end of this period the documentation for the end user will be mostly done, (there might be some minor changes in the future). The documentation will be about the SVG Pipe/Animated Brush, according to the Krita Contribution Guide. This task should give me a very specific idea of how the end result will be for the user.
Deliverables:
1.1 Write the end user documentation about the use of the Pipe/Animated brush.

2. Loading and parsing an SVG library.
June 02 - June 15
At the end of this point it should be possible to load and parse an SVG library file. This should return a collection with all the “symbol” tags and all the metadata of the SVG library. This should be done using the class KoSvgSymbolCollectionResource from the Flake library. This includes comments, documentation and unit testing.
Deliverables:
2.1 Implement a series of tests to load different SVG libraries, this tests should be part of the class KoSvgSymbolCollectionResource,since it does not have any at the moment:

With no shapes: Should give an error because file is blank.
With one shape: Should parse the shape and return a collection of one element, with “symbol” tag and metadata.
With multiple shapes: Should parse all the shapes and return a collection of as many elements as shapes each with the correspondent “symbol” tag and correct metadata.
    10 shapes SVG library.
    100 shapes SVG library.
    1000 shapes SVG library.
With some not-vector shapes: Should ignore not-vectors and return a collection of as many vector shapes, each with the correspondent “symbol” tag and correct metadata.
    10 shapes SVG library.
    100 shapes SVG library.
    1000 shapes SVG library.
With only not-vector shapes: Should give an error because there are no vectors.
File is not an SVG: should give an error.

If Using Flake Vector objects:
2.2 Write a new class with the functions required to load a trivial SVG library, according to the tests already written. This class should use the class KoSvgSymbolCollectionResource and load the SVG library as its own vector layer.
If Using KisImagePipeBrush:
2.3 Write the required functions inside KisImagePipeBrush to implement the functionality required to load a trivial SVG library, according to the tests already written. This should be using th e class KoSvgSymbolCollectionResource to load the SVG library.
2.4 Write a blog post on planet.kde.org about the work done so far.

3. Rendering SVG shapes
June 16 - June 30
At the end of this period it should be possible to paint in Krita’s canvas using the brush. Following the previous discussions in sections 1.3.4 and 3.5, the method that will be used to render the vectors as raster images haven’t been selected yet. This will be decided according to the “testing” point of section 1.3.4.
Deliverables:
3.1 Implement a series of tests to render different SVG libraries:

Small size: brush at a size of 3x3 px.
Medium size: brush at a size of 500x500 px.
Big size: brush at a size of 1000x1000 px.
Each one of the previous will also  test for SVG libraries of different sizes:
10 shapes SVG symbol library.
100 shapes SVG symbol library.
1000 shapes SVG symbol library.

If Using Flake Vector objects:
3.2 Create a KisBrush subclass that encapsulates a KisShapeLayer; and then renders the individual shapes at the desired size. Write the required functions to cache those images and use them as brush tips. This will also require tests for the cache functions.
If Using KisImagePipeBrush:
3.3 Write the functions necessary to transform the shapes into raster images. This should be done using with SvgParser from the Flake library and the images will go through KisImagePipeBrush, rasterized into a normal KisBrushesPipe object, which will render the brushes out-of-box.
3.4 The parsed shapes should be visualized inside an Objects docker.
3.5 Write a blog post on planet.kde.org about the work done so far.

4. User Interface
June 23 - July 15
At the end of this period there should be a user interface to provide the user with tools for using this type of brushes.
The tools and options included in the user interface will be decided after getting feedback from the community during the Community Bonding Period, but tentatively the following options should be included:

Import and delete SVG symbol library.
Options for brush 
    Brush selector
    Size
    Spacing
    Rotation
Save Brush

Deliverables:
4.1 Create the user interface with all the options necessary to load, save and edit this type of brushes. The user interface should follow the KDE Human Interface Guidelines.
4.2 Write a blog post on planet.kde.org about the work done so far.

5. Saving as SVG symbol library
July 15 - August 01
At the end of this period it should be possible to save an SVG symbol library, using the class KoSvgSymbolCollectionResource from the Flake library, with the appropriate “<symbol>” tags and all the metadata set through the User Interface.
Deliverables:
5.1 Write the functions necessary to save as SVG library with the <symbol> tags for correspondant shapes.

6. Fixing bugs
August 01 - August 05
This small period will be focused on finding and fixing the bugs.
During this period I will travel to Netherlands for the Krita Sprint.
Deliverables:
6.1 Find and fix bugs.
6.2 Travel to Krita Sprint.

7.Krita Sprint
August 03 - August 19
This period will be focused on working with the Krita team during the Krita Sprint to polish and finish the brush.
Deliverables:
7.1 Finish the brush with all the requirements.
7.2 Write a blog post on planet.kde.org about the results of Google Summer of Code.
7.3 Thank the community and my mentors.
7.4 Celebrate 😄

albertoefg triaged this task as Normal priority.
albertoefg added a comment.EditedMay 15 2019, 11:48 PM

Brush format

Introduction

This type of brush will require an special format, using XML and SVG. So it will need it's own extension and name.

Name

The selected extension will be AVB which will stand for Animated Vector Brush as suggested by boud.

Note: It could also mean *Alberto's Vector Brush* which I think has a better sound.

SVG Symbol library

Symbols

In order to create an SVG symbols library, it is necessary that all the
<symbols> should be inside a <defs> element. This <symbols>
should be later used with a <use> element.

However, it is not necessary for Krita to understand an SVG as a symbol
library to have <use> elements in the document, only <symbols>
are necessary. This means a full brush can be created

Example made with Inkscape:

.. code:: svg

<defs id="defs132527">
  <symbol id="symbol227795">
    <path
       style="opacity:1;fill:#0b0c10;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       d="m -240.99763,-8.1023808 a 92.98214,92.98214 0 0 1 -92.98214,92.9821388 92.98214,92.98214 0 0 1 -92.98214,-92.9821388 92.98214,92.98214 0 0 1 92.98214,-92.9821392 92.98214,92.98214 0 0 1 92.98214,92.9821392 z"
       id="full-circle"
       inkscape:connector-curvature="0">
      <title id="title132653">full-circle</title>
    </path>
  </symbol>
</defs>

Right now, it seems like Krita is capable of saving gradients inside the
<defs> element, but not symbols, This will need to be fixed for the
matters of this project.

w3 reference

https://www.w3.org/TR/SVG11/struct.html#SymbolElement The ‘symbol’
element is used to define graphical template objects which can be
instantiated by a ‘use’ element.

The use of ‘symbol’ elements for graphics that are used multiple times
in the same document adds structure and semantics. Documents that are
rich in structure may be rendered graphically, as speech, or as braille,
and thus promote accessibility.

The key distinctions between a ‘symbol’ and a ‘g’ are:

A ‘symbol’ element itself is not rendered. Only instances of a ‘symbol’
element (i.e., a reference to a ‘symbol’ by a ‘use’ element) are
rendered. A ‘symbol’ element has attributes ‘viewBox’ and
‘preserveAspectRatio’ which allow a ‘symbol’ to scale-to-fit within a
rectangular viewport defined by the referencing ‘use’ element.

Use

The <use> elements are necessary for the SVG to create instances of
the <symbol> element. For the purpose of this project they might not
be necessary because the <symbol> elements will be transformed into
raster images right before being used as brush tips.

However, it might be necessary to make sure Krita supports them to
provide the users the capability of editing their brushes inside Krita,
and because they are part of the SVG standard.

w3 reference

https://www.w3.org/TR/SVG11/struct.html#UseElement

Metadata

The SVG should have a metadata element, at least to be recognized by
Inkscape as a Symbol library. It is recommended to at least have a
Format, Title, Creator, Date, and License elements, all this elements
can be inserted using the Dublin Core standard.

As of right now, the SVG Libraries that Krita ships use Dublin Core for
metadata. It is necessary to investigate if this metadata was created
with Krita or with an external program.

Example of metadata created with Inkscape:

.. code:: svg

<metadata id="metadata132530">
  <rdf:RDF>
    <cc:Work rdf:about="">
      <dc:format>image/svg+xml</dc:format>
      <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
      <dc:title>1 Symbol library</dc:title>
      <dc:date>17 May 2019</dc:date>
      <dc:creator>
        <cc:Agent>
          <dc:title>Blackbeard</dc:title>
        </cc:Agent>
      </dc:creator>
      <cc:license rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
    </cc:Work>
    <cc:License rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
      <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" />
      <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" />
      <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
    </cc:License>
  </rdf:RDF>
</metadata>

w3 Reference

https://www.w3.org/TR/SVG11/metadata.html The W3C has a Semantic Web
Activity which has been established to serve a leadership role, in both
the design of enabling specifications and the open, collaborative
development of technologies that support the automation, integration and
reuse of data across various applications. The Semantic Web Activity
builds upon the earlier W3C Metadata Activity, including the definition
of Resource Description Framework (RDF). The RDF Primer is the first in
a set of six documents that define the Resource Description Framework
[RDF-PRIMER].

Another activity relevant to most applications of metadata is the Dublin
Core [DCORE], which is a set of generally applicable core metadata
properties (e.g., Title, Creator/Author, Subject, Description, etc.).

Dublin Core

http://dublincore.org/ http://dublincore.org/schemas/xmls/

IRC relevant messages

<Wolthera_laptop> try to read if the svgwriter has functions for writing dublincore metadata… [13:53]

<ivanyossi> have you checked if the KoXmlWriter can create any tag and attribute? [19:47]
<ivanyossi> svgWriter uses KoXmlWriter to add tags to the QDomElement
<ivanyossi> Blackbeardy: Try to make a simle test and create an svg with
custom tags/symbols

hi @albertoefg

If you get a chance, could you provide a quick update on this ticket with where this is at? Also maybe attach the "AVB" file you are using so people can see what it looks like. I can't tell if it is in the repository, or if you just have it on your computer somewhere.

It sounds like you are making some progress based off our IRC conversation

Yes, as of right now it is possible to paint with the brush.

I adjunct an "example.avb" file that can be used to paint.

Right now performance is my biggest problem, I am working on fixing that, when loading the brush will take a while to be able to be used, please give it a few seconds.

@ramonmiranda asked me to look at this video https://www.youtube.com/watch?v=95zGPHg7eTs seems like a good improvement that can be done after the GSoC is finished