<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.inkscape.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=S-Rafael</id>
	<title>Inkscape Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.inkscape.org/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=S-Rafael"/>
	<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/Special:Contributions/S-Rafael"/>
	<updated>2026-04-29T01:03:27Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.36.1</generator>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=123226</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=123226"/>
		<updated>2025-05-25T11:20:08Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have '''more of:'''&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality, especially during the release period.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have '''less of:'''&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
*Reliance on time-consuming manual testing;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Code fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Proposed Actions (To Do List)==&lt;br /&gt;
#'''[Done via [https://gitlab.com/inkscape/inkscape/-/merge_requests/6467 MR6467]]''' Set up CMake targets to make it easy to create unit tests.&amp;lt;br /&amp;gt;Currently, all GTest tests link &amp;lt;code&amp;gt;libinkscape_base&amp;lt;/code&amp;gt;, so they are in fact integration tests rather than unit tests. There should be an easy way of explicitly listing one or several cpp files which will be compiled and linked with tests support utilities only (test the functionality '''in isolation'''). Additionally, there needs to be a way to request linking in &amp;lt;code&amp;gt;lib2geom&amp;lt;/code&amp;gt; for functionality that requires it.&lt;br /&gt;
#'''[Done with [https://gitlab.com/inkscape/inkscape/-/merge_requests/7206 MR7206]]''' Ensure all tests run in debug mode so that failed asserts crash them, and that they use the address sanitizer (ASAN).&lt;br /&gt;
#Migrate some of the existing tests to unit test framework.&amp;lt;br/&amp;gt;Do not link all of inkscape just to test a single class or collection of functions.&lt;br /&gt;
#Devise a test strategy for the interactions between &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s and their XML representations.&amp;lt;br/&amp;gt;For each &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; type, it should be possible to easily write tests that create such object (in isolation or in a test fixture simulating a minimalistic document) from an XML string representation and, likewise, write an XML representation of the object. Unit tests of this kind would characterize and document the properties of XML representations and, with sufficient coverage, can prevent data loss bugs and many undo-related issues.&lt;br /&gt;
#Create fixtures for testing &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; behavior.&amp;lt;br/&amp;gt;It should be possible to create an &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;, perhaps embedding it in a minimalistic document provided by a suitable fixture, and perform specific operations on this object in order to create unit tests for all the different &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
#Write integration tests for document-level interactions.&amp;lt;br/&amp;gt;The goal is to test scenarios where several objects depend on each other: clones, groups, gradients, LPE objects, markers which link to each other by href or another type of reference. Integration tests of this kind (linking the entire libinkscape_base into the test executable) will ensure robust handling of situations such as deletion of dependencies, clipboard operations, undo. When run with the sanitizer, they may catch rare memory corruption bugs.&lt;br /&gt;
#Refactor the LPE system.&amp;lt;br/&amp;gt;The LPE system dynamically rewrites the d attribute of an SVG path in order to create an artistic effect. As such, each LPE should be easily testable in principle. Migrate existing end-to-end tests of the LPE system and make them unit tests.  Assumption: making LPEs individually testable will improve the quality of LPE-related code and offer an opportunity to redesign it.&lt;br /&gt;
#Enable test coverage reports in the CI pipeline.&amp;lt;br/&amp;gt;This was already done in lib2geom and the extensions repository, so a similar setup should be easy to reproduce. Consider gamification of test coverage.&lt;br /&gt;
#Create more rendering tests.&amp;lt;br/&amp;gt;The display system should be tested more rigorously in order to prevent rendering regressions.&lt;br /&gt;
#Automated action-based tests.&amp;lt;br/&amp;gt;We could write more tests that execute a sequence of actions, either on a fresh document or on a pre-existing one. Although this could be done with end-to-end CLI-based tests, it is probably easier to have a C++ test fixture with actions called manually or via their string names.&lt;br /&gt;
#Examine the possibility of creating event-injection GUI-tests.&amp;lt;br/&amp;gt;If successful, this could save a lot of time currently spent on manual GUI testing. &lt;br /&gt;
#Enhance contribution and code review guidelines with testing-related information&amp;lt;br /&amp;gt; A careful balance has to be struck beween the imperative of enforcing a sufficient test coverage and allowing for contributions from relatively inexperienced community members who may lack the knowledge of good practices related to testing. Guidelines which help educate contributors, in addition to learning from examples (for instance, tests created as a part of items listed above) will ensure that even new contributors can contribute to the QA goals within Inkscape. We recognize that these goals should not entail more burden on the contributors, and that with a sufficient level of CI automation, the quality will happen &amp;quot;by default&amp;quot; and &amp;quot;by design&amp;quot;.&amp;lt;br /&amp;gt; &lt;br /&gt;
==Automated testing==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]Inkscape's CI pipeline contains a number of integration and end-to-end tests. However, we recognise that the overal test coverage is '''very poor''' as of late 2023. One of the main goals of this initiative is to track the test coverage and work on gradually increasing it.&lt;br /&gt;
&lt;br /&gt;
Although some existing tests can be classified as &amp;quot;unit tests&amp;quot; because they focus on testing a single unit of code at the time, the external dependencies are poorly understood because all tests link all of &amp;lt;code&amp;gt;libinkscape_base&amp;lt;/code&amp;gt;. This should be addressed as a part of point 1 above.&lt;br /&gt;
&lt;br /&gt;
In the context of automated tests, we recall the famous Testing Pyramid (see right). It expresses the principle that tests at unit and component level should be the most prevalent ones, followed by a smaller number of integration tests, and topped off with a relatively minor number of end-to-end tests. Unfortunately, this is not the case today: we have too few unit tests. Manual testing should be limited to UX and usability aspects.&lt;br /&gt;
&lt;br /&gt;
===Why does Inkscape not have enough unit tests===&lt;br /&gt;
&lt;br /&gt;
*Historical reasons: feature development was prioritized and testing was never formally enforced.&lt;br /&gt;
*Work on tests and QA topics may be perceived as less newsworthy because it is less visible to the end user.&lt;br /&gt;
*Many new developments interact with and depend on legacy code which is hard to split off and mock. Thus, new code is hard to test.&lt;br /&gt;
*Insufficient tooling such as automated test coverage reports or custom test fixtures to facilitate test development.&lt;br /&gt;
*Varied knowledge level of contributors, some lacking expertise in testing.&lt;br /&gt;
&lt;br /&gt;
===What can be done about it===&lt;br /&gt;
&lt;br /&gt;
*Code review should emphasize the importance of adding unit tests for new functionality and regression tests for bug fixes.&lt;br /&gt;
*Quality and maintainability should be viewed as core aspects and as an important part of Inkscape's development.&lt;br /&gt;
*Legacy code must be managed carefully, see below.&lt;br /&gt;
*Test coverage reports should be introduced along with facilities that make it easy and pleasant to write tests.&lt;br /&gt;
*By increasing the number of tests, we can increase the knowledge and awareness of testing techniques in the community – learning from examples.&lt;br /&gt;
&lt;br /&gt;
==Dealing with legacy code ==&lt;br /&gt;
According to Michael Feathers, the author of the influential book &amp;quot;Working effectively with legacy code&amp;quot;, ''legacy code'' is not defined as &amp;quot;old code&amp;quot;, &amp;quot;code written in C&amp;quot; or in general &amp;quot;code that nobody maintains&amp;quot;. Instead, legacy code is '''code that is''' '''not testable and not tested.''' We recognise that Inkscape contains a lot of such code.&lt;br /&gt;
&lt;br /&gt;
===The Vicious Cycle of Legacy Code===&lt;br /&gt;
The fundamental problem with legacy code is that it's very risky to change it because a small change in one place can have unpredictable and unintended consequences in other places. This has happened many times in Inkscape's history and has led to severe bugs. In an ideal world, the existing code could be first enriched with &amp;quot;characterization tests&amp;quot; that capture its current behaviour, and tests could also be added for the new behaviour. In this way, we could assure that the development works as intended and doesn't break anything. But, according to our definition, legacy code is '''not testable''' so this cannot be done. We don't live in an ideal world!&lt;br /&gt;
&lt;br /&gt;
Thus, we are stuck in a vicious cycle: to make code testable, we need to refactor it in order to make it testable, but refactoring can break things badly unless we have tests, which unfortunately we don't and which cannot be added because the code is not testable.&lt;br /&gt;
&lt;br /&gt;
To break out of this cycle, we need to start small, adding tests to simple and relatively independent pieces of functionality. It is helpful to identify the &amp;quot;seams&amp;quot;, which usually correspond to interfaces, along which the program or a system can be natuarally divided into functional pieces. If these pieces are simple enough, they can be made testable. However, even with this approach, a fair bit of mocking may be required to simulate external dependencies, which makes it a tedious task.&lt;br /&gt;
&lt;br /&gt;
===Refactoring and development techniques to increase testability===&lt;br /&gt;
A large portion of Inkscape's codebase is made up of code that's very literal, low-level and suffers from a lack of abstraction. Oftentimes, such code was developed as a part of a small contributions without architectural goals, focused only on adding a small missing piece of functionality. As contributors come and go, this leaves behind a patchwork of fairly inconsistent solutions. Nonetheless, many parts of Inkscape have seen some notable refactoring efforts aimed at unifying these patchwork solutions. It is however important that future refactoring efforts take testability considerations into account. &lt;br /&gt;
&lt;br /&gt;
Desigining good interfaces and abstractions is an important goal that should be kept in mind not only during major architectural updates, but also our everyday work. Whenever you work on Inkscape, ask yourself the question: &amp;quot;Does this change make the code I'm working on more or less testable?&amp;quot;. Below are some concrete examples of techniques that can help increase testability.&lt;br /&gt;
&lt;br /&gt;
====Extract and mock/override====&lt;br /&gt;
&lt;br /&gt;
*Identify the piece of code that makes the functionality non-testable.&lt;br /&gt;
*Move this piece of code to a separate function(s) or a class. Moving code is safer than rewriting it, because the functional logic is kept unchanged.&lt;br /&gt;
*In tests, mock the class or function that the problematic code was moved to. This lets you test new functionality independently of the legacy code.&lt;br /&gt;
*If you need to extend the functionality provided by the non-testable code, try doing it without touching the untested function, but rather wrap around it or provide an override.&lt;br /&gt;
&lt;br /&gt;
====Decorator pattern====&lt;br /&gt;
This design pattern helps extend a legacy class with new functionality. Instead of adding the new functionality directly to the non-testable class (which would make the new functionality non-testable as well), write a wrapper around the legacy class. In the decorator pattern, the decorator class holds an instance of the wrapped class and provides an interface that forwards member function calls to the wrapped object. However, some of the member functions of the wrapper can provide additional functionality or further work on the values obtained from the wrapped object, which makes it possible to add new behaviours. This new functionality can now be tested by mocking the wrapped class in tests.&lt;br /&gt;
&lt;br /&gt;
====Façade transformation====&lt;br /&gt;
This technique helps when dealing with huge classes that hold too much data and that have too many member functions, making them complex, difficult to test, and increasing the coupling with other parts of the code. The façade transformation replaces the large class with a façade class which internally holds instances of several smaller classes. These smaller classes need to be designed by identifying the functionally cohesive pieces of the original large class and splitting them up. The member functions of the façade delegate to member function calls on these internal instances, sometimes more than one at a time. This transformation can be repeated if needed, until the classes are small enough that testing them is possible. The advantage of the façade transformation is that the API exposed by the large class is unchanged.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing unit tests==&lt;br /&gt;
&lt;br /&gt;
*Create a separate test executable for each class or functional module.&lt;br /&gt;
*Write a separate test case for each of the tested behaviours.&lt;br /&gt;
*Write a doxygen-style comment above each test case, explaining very briefly what this case is testing.&lt;br /&gt;
*In each test case, follow the Arrange-Act-Assert principle:&lt;br /&gt;
**Arrange: create and prepare the data and objects needed to perform the tested operation; set up expectations for mock calls;&lt;br /&gt;
**Act: run the tested operation;&lt;br /&gt;
**Assert: use &amp;lt;code&amp;gt;EXPECT_*&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ASSERT_*&amp;lt;/code&amp;gt; macros from Google Testing library to check that the behaviour is as expected.&lt;br /&gt;
*Remember to test strange and corner cases, invalid input, fallback behaviours.&lt;br /&gt;
*If your test needs custom set-up and tear-down, use a custom test fixture and &amp;lt;code&amp;gt;TEST_F&amp;lt;/code&amp;gt; macros.&lt;br /&gt;
*If your test needs to run on several cases parametrized by input data, consider using a &amp;lt;code&amp;gt;TEST_P&amp;lt;/code&amp;gt; fixture.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing end-to-end tests==&lt;br /&gt;
If you are about to create an end-to-end test, ask yourself first if perhaps a unit test can be written instead. However, in the case of regression tests, it's often good to have end-to-end tests that clearly demonstrate that a bug has been fixed and ensure it is not accidentaly reintroduced. End-to-end tests are also suitable for complex cases involving import and export operations. In many cases (such as display and rendering, utilities, Live Path Effects, SPObject system, anything in lib2geom), unit tests ought to be preferred.&lt;br /&gt;
&lt;br /&gt;
*If you create test files (SVG documents or files in other formats), ensure that the content of the files can be visually inspected.&lt;br /&gt;
*If your test file contains both test objects and reference objects, ensure that the relationship between them can be directly inspected visually by a human being in order to confirm that the tested behaviour is indeed correct. You may use existing fixtures such as &amp;lt;code&amp;gt;Inkscape::TestWithSvgObjectPairs&amp;lt;/code&amp;gt; for this purpose.&lt;br /&gt;
*If you use separete reference files, ensure they can be visually inspected as well.&lt;br /&gt;
*Try to make your test focused on the tested behaviour by reducing the number of unrelated elements in your test files.&lt;br /&gt;
*Try to make your test robust and independent on implementation details unrelated to the tested behaviour.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Inkscape_Summit_2025_Nuremberg&amp;diff=123224</id>
		<title>Inkscape Summit 2025 Nuremberg</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Inkscape_Summit_2025_Nuremberg&amp;diff=123224"/>
		<updated>2025-05-22T12:44:06Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Inksummit2025.png|left|thumb|150x150px]]&lt;br /&gt;
This page details the planning of Inkscape's 2025 summit in Nuremberg, Germany. The hackfest will take place on '''May 24–28, 2025'''. We are looking to bring together a group of '''17 attendees'''.  We are fully booked and the number of participants is final now.&lt;br /&gt;
&lt;br /&gt;
This summit takes place directly before the 2025 Libre Graphics Meeting.&lt;br /&gt;
&lt;br /&gt;
Previous events: [[Hackfest2023 Bensberg]], [[Hackfest2019 Saarbrücken]], [[Hackfest2019 SCALE]], [[Hackfest2018 Kiel]], [[Hackfest2018 LGM]], [[Hackfest2018]], [[Hackfest2017]], [[Hackfest2016]], [[Hackfest2015]].&lt;br /&gt;
[[Category:Hackfest]]&lt;br /&gt;
&lt;br /&gt;
= Agenda =&lt;br /&gt;
&lt;br /&gt;
=== Add your ideas here! ===&lt;br /&gt;
&lt;br /&gt;
* Bug triaging&lt;br /&gt;
**  Issue filtering (useful application for AI?)&lt;br /&gt;
** Feature requests: how to collect into actionable projects&lt;br /&gt;
**Inbox clening  sprint -  make a 1-2h  grupe effort sprint of going thro issues -  testing, closing, moving to main tracker&lt;br /&gt;
**main tracker  prioritizaiton sprint - make a 1-2h  grupe effort sprint of going thro issues -  testing, closing, setting priorities&lt;br /&gt;
* Development&lt;br /&gt;
** LPE refactoring&lt;br /&gt;
**Work on the [[Quality Assurance Initiative]].&lt;br /&gt;
** 1.5&lt;br /&gt;
*** Selection cues&lt;br /&gt;
*** Status bar&lt;br /&gt;
** 1.4.1 (1.4.2?)&lt;br /&gt;
*** Add Interface test cases (replay certain steps to create an artwork) to check for feature breakage&lt;br /&gt;
*** Canvas performance&lt;br /&gt;
* Documentation&lt;br /&gt;
** Cleaning up documentation (wiki, dev docs, user docs, extension docs)&lt;br /&gt;
* Extensions&lt;br /&gt;
** &amp;quot;Using Inkscape to make physical things&amp;quot;&lt;br /&gt;
*** Have a look at Hatch Embroidery (paid software that has a cool preview feature and thousands of advanced options that are hard to understand)&lt;br /&gt;
** svgpie and inkex&lt;br /&gt;
*** Separation of concerns? (svgpie for SVG wrangling, inkex for an API to the Inkscape interface)&lt;br /&gt;
** async extensions (new extension type in development, enables extensions to receive updated info from the document while running)&lt;br /&gt;
* Organization&lt;br /&gt;
** Foundation/organization setup (what needs actions/help?)&lt;br /&gt;
**Relationship between Inkscape and commercial actors (e.g. advertising companies / developers available for contract work, support contracts)&lt;br /&gt;
**Grants program&lt;br /&gt;
** Long-term goal setting&lt;br /&gt;
* UX&lt;br /&gt;
** Charter &amp;amp; policy&lt;br /&gt;
** Design discussion&lt;br /&gt;
*** Decide which improvements we want to land in 1.5 (high-level)&lt;br /&gt;
*** Object properties (for text, for multi-selection)&lt;br /&gt;
*** new settings (we have tools, but need all other categories)&lt;br /&gt;
*** LPEs and their panels&lt;br /&gt;
*** CMYK export workflow&lt;br /&gt;
*** Swatches dialog&lt;br /&gt;
*** Text tab of Text and Font dialog. What is it's purpose? Can spell-checking be moved completely on-canvas? (There is on-canvas spell checking via the Check Spelling dialog but misspelled words aren't shown unless this dialog is called.)&lt;br /&gt;
* Website&lt;br /&gt;
** Website working group and charter&lt;br /&gt;
** Infrastructure update (less 502s)&lt;br /&gt;
** Library update (django 5)&lt;br /&gt;
** Design/UX overhaul&lt;br /&gt;
** Separate funding page? (Blender, Krita, Thunderbird and KDE have it)&lt;br /&gt;
&lt;br /&gt;
=== Non-Inkscape stuff ===&lt;br /&gt;
&lt;br /&gt;
Ideas for socializing and getting away from screens&lt;br /&gt;
&lt;br /&gt;
* Sunday 25th afternoon - visit a local makerspace, see where Inkscape is used and talk to users (organized by Max)&lt;br /&gt;
*Movies&lt;br /&gt;
* Card games&lt;br /&gt;
* Pub&lt;br /&gt;
* Take a group picture&lt;br /&gt;
* ?&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Summit2024_Rennes_Attendees&amp;diff=122737</id>
		<title>Summit2024 Rennes Attendees</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Summit2024_Rennes_Attendees&amp;diff=122737"/>
		<updated>2024-03-31T11:43:11Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Travel Support ==&lt;br /&gt;
&lt;br /&gt;
The Inkscape Project Leadership Committee has allocated $25,000 to support Inkscape community members travel expenses. This includes transportation, lodging, meals, and miscellaneous expenses.&lt;br /&gt;
&lt;br /&gt;
To ask for travel support, add your name below, and then contact Tavmjong (tavmjong@free.fr or via RocketChat) with a (very) short statement on what you have contributed to Inkscape in the past year and with what you plan to work on during the summit and LGM. It can be anything from promoting Inkscape via social media to software development.&lt;br /&gt;
&lt;br /&gt;
For planning purposes, include an estimate of expenses.&lt;br /&gt;
&lt;br /&gt;
All travel reimbursements &amp;lt;b&amp;gt;MUST&amp;lt;/b&amp;gt; follow the [https://sfconservancy.org/projects/policies/conservancy-travel-policy.html SFC Travel Policy].&lt;br /&gt;
&lt;br /&gt;
== Who is Attending? ==&lt;br /&gt;
&lt;br /&gt;
Please add yourself to the list and then contact Tav about travel support.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|+ List of Attendees&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Who&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Dates&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Arrival&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Departure&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Hotel&lt;br /&gt;
|-&lt;br /&gt;
! Date/Time&lt;br /&gt;
! Detail&lt;br /&gt;
! Date/Time&lt;br /&gt;
! Detail&lt;br /&gt;
|-&lt;br /&gt;
| Tavmjong Bah &lt;br /&gt;
| 6 May - 12 May&lt;br /&gt;
|&lt;br /&gt;
| By car&lt;br /&gt;
|&lt;br /&gt;
| By car&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| Marc Jeanmougin&lt;br /&gt;
| TBD&lt;br /&gt;
| &amp;lt;!-- arrival date + time --&amp;gt;&lt;br /&gt;
| Train&lt;br /&gt;
| &amp;lt;!-- departure date + time --&amp;gt;&lt;br /&gt;
| Train&lt;br /&gt;
| &amp;lt;!-- hotel --&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Rafał Siejakowski&lt;br /&gt;
|6 May – 10 May&lt;br /&gt;
|5 May 16:55&lt;br /&gt;
|By air&lt;br /&gt;
|10 May 16:05&lt;br /&gt;
|By air&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Adam Belis&lt;br /&gt;
|6 May - TBD&lt;br /&gt;
|&lt;br /&gt;
|air + train&lt;br /&gt;
|&lt;br /&gt;
|air + train&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|Mike Kowalski&lt;br /&gt;
|6 May - 10 May&lt;br /&gt;
|&lt;br /&gt;
|air + train&lt;br /&gt;
|&lt;br /&gt;
|train + air&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| Sample Person&lt;br /&gt;
| &amp;lt;!-- dates --&amp;gt;&lt;br /&gt;
| &amp;lt;!-- arrival date + time --&amp;gt;&lt;br /&gt;
| &amp;lt;!-- arrival details, e.g. flight number --&amp;gt;&lt;br /&gt;
| &amp;lt;!-- departure date + time --&amp;gt;&lt;br /&gt;
| &amp;lt;!-- departure details, e.g. flight number --&amp;gt;&lt;br /&gt;
| &amp;lt;!-- hotel --&amp;gt;&lt;br /&gt;
|-! Total&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
TBD: &amp;quot;To Be Determined&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The Inkscape board has approved travel reimbursements of up to $2500 per person (subject to a $25,000 cap). Requests for reimbursements are subject to the SFC travel policy. Pay attention, especially, to the requirements for documenting fare searches and buying tickets in advance.&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
Separate allocations for:&lt;br /&gt;
* Inkscape dinner, participants and guests (500€).&lt;br /&gt;
* Snacks, etc. (200€).&lt;br /&gt;
* Venue: Free.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Summit2024_Rennes_Attendees&amp;diff=122698</id>
		<title>Summit2024 Rennes Attendees</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Summit2024_Rennes_Attendees&amp;diff=122698"/>
		<updated>2024-03-13T17:22:07Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Travel Support ==&lt;br /&gt;
&lt;br /&gt;
The Inkscape Project Leadership Committee has allocated $25,000 to support Inkscape community members travel expenses. This includes transportation, lodging, meals, and miscellaneous expenses.&lt;br /&gt;
&lt;br /&gt;
To ask for travel support, add your name below, and then contact Tavmjong (tavmjong@free.fr or via RocketChat) with a (very) short statement on what you have contributed to Inkscape in the past year and with what you plan to work on during the summit and LGM. It can be anything from promoting Inkscape via social media to software development.&lt;br /&gt;
&lt;br /&gt;
For planning purposes, include an estimate of expenses.&lt;br /&gt;
&lt;br /&gt;
All travel reimbursements &amp;lt;b&amp;gt;MUST&amp;lt;/b&amp;gt; follow the [https://sfconservancy.org/projects/policies/conservancy-travel-policy.html SFC Travel Policy].&lt;br /&gt;
&lt;br /&gt;
== Who is Attending? ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
|+ List of Attendees&lt;br /&gt;
|-&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Who&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Dates&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Maximum Allocation&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Arrival&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Departure&lt;br /&gt;
! rowspan=&amp;quot;2&amp;quot; | Hotel&lt;br /&gt;
|-&lt;br /&gt;
! Date/Time&lt;br /&gt;
! Detail&lt;br /&gt;
! Date/Time&lt;br /&gt;
! Detail&lt;br /&gt;
|-&lt;br /&gt;
| Tavmjong Bah &lt;br /&gt;
| TBD&lt;br /&gt;
| Per SFC Rules&lt;br /&gt;
|&lt;br /&gt;
| By car&lt;br /&gt;
|&lt;br /&gt;
| By car&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| Marc Jeanmougin&lt;br /&gt;
| TBD&lt;br /&gt;
| TBD&lt;br /&gt;
| &amp;lt;!-- arrival date + time --&amp;gt;&lt;br /&gt;
| Train&lt;br /&gt;
| &amp;lt;!-- departure date + time --&amp;gt;&lt;br /&gt;
| Train&lt;br /&gt;
| &amp;lt;!-- hotel --&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Rafał Siejakowski&lt;br /&gt;
|6 May – 9 May&lt;br /&gt;
|TBD&lt;br /&gt;
|&lt;br /&gt;
|By air&lt;br /&gt;
|&lt;br /&gt;
|By air&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| Sample Person&lt;br /&gt;
| &amp;lt;!-- dates --&amp;gt;&lt;br /&gt;
| TBD&lt;br /&gt;
| &amp;lt;!-- arrival date + time --&amp;gt;&lt;br /&gt;
| &amp;lt;!-- arrival details, e.g. flight number --&amp;gt;&lt;br /&gt;
| &amp;lt;!-- departure date + time --&amp;gt;&lt;br /&gt;
| &amp;lt;!-- departure details, e.g. flight number --&amp;gt;&lt;br /&gt;
| &amp;lt;!-- hotel --&amp;gt;&lt;br /&gt;
|-! Total&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
! $ TBD&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
!&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
TBD: &amp;quot;To Be Determined&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- The Inkscape board has approved travel reimbursements of up to $2000 per person. Note: participants require the formality of a board vote. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
Separate allocations for:&lt;br /&gt;
* Inkscape dinner, participants and guests (500€).&lt;br /&gt;
* Snacks, etc. (200€).&lt;br /&gt;
* Venue: Free.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122646</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122646"/>
		<updated>2023-12-23T16:24:12Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have '''more of:'''&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality, especially during the release period.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have '''less of:'''&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
*Reliance on time-consuming manual testing;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Code fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Proposed Actions (To Do List)==&lt;br /&gt;
#Set up CMake targets and macros to make it easy to create unit tests.&amp;lt;br/&amp;gt;Currently, all GTest tests link &amp;lt;code&amp;gt;libinkscape_base&amp;lt;/code&amp;gt;, so they are in fact integration tests rather than unit tests. There should be an easy way of explicitly listing one or several cpp files which will be compiled and linked with tests support utilities only (test the functionality '''in isolation'''). Additionally, there needs to be a way to request linking in &amp;lt;code&amp;gt;lib2geom&amp;lt;/code&amp;gt; for functionality that requires it.&lt;br /&gt;
#Ensure all tests run in debug mode so that failed asserts crash them.&lt;br /&gt;
#Create a flag to easily run tests with the sanitizer.&amp;lt;br/&amp;gt;It should be easy to choose whether a given unit or integration test should run with or without &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt;. The long-term goal is to transition all tests to run in sanitized mode, but many would currently fail due to memory leaks. &lt;br /&gt;
#Create a setup to link inkscape with &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt; in the CI pipeline for use in end-to-end tests.&amp;lt;br/&amp;gt;After building object files, link two inkscape executables: one with and one without &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt;. Create a flag to choose which end-to-end test (e.g., CLI test) should run with the sanitizer (aspirationally, all of them, but not long ago even running &amp;lt;code&amp;gt;inkscape --help&amp;lt;/code&amp;gt; leaked memory).&lt;br /&gt;
#Migrate some of the existing tests to unit test framework.&amp;lt;br/&amp;gt;Do not link all of inkscape just to test a single class or collection of functions.&lt;br /&gt;
#Devise a test strategy for the interactions between &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s and their XML representations.&amp;lt;br/&amp;gt;For each &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; type, it should be possible to easily write tests that create such object (in isolation or in a test fixture simulating a minimalistic document) from an XML string representation and, likewise, write an XML representation of the object. Unit tests of this kind would characterize and document the properties of XML representations and, with sufficient coverage, can prevent data loss bugs and many undo-related issues.&lt;br /&gt;
#Create fixtures for testing &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; behavior.&amp;lt;br/&amp;gt;It should be possible to create an &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;, perhaps embedding it in a minimalistic document provided by a suitable fixture, and perform specific operations on this object in order to create unit tests for all the different &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
#Write integration tests for document-level interactions.&amp;lt;br/&amp;gt;The goal is to test scenarios where several objects depend on each other: clones, groups, gradients, LPE objects, markers which link to each other by href or another type of reference. Integration tests of this kind (linking the entire libinkscape_base into the test executable) will ensure robust handling of situations such as deletion of dependencies, clipboard operations, undo. When run with the sanitizer, they may catch rare memory corruption bugs.&lt;br /&gt;
#Refactor the LPE system.&amp;lt;br/&amp;gt;The LPE system dynamically rewrites the d attribute of an SVG path in order to create an artistic effect. As such, each LPE should be easily testable in principle. Migrate existing end-to-end tests of the LPE system and make them unit tests.  Assumption: making LPEs individually testable will improve the quality of LPE-related code and offer an opportunity to redesign it.&lt;br /&gt;
#Enable test coverage reports in the CI pipeline.&amp;lt;br/&amp;gt;This was already done in lib2geom and the extensions repository, so a similar setup should be easy to reproduce. Consider gamification of test coverage.&lt;br /&gt;
#Create more rendering tests.&amp;lt;br/&amp;gt;The display system should be tested more rigorously in order to prevent rendering regressions.&lt;br /&gt;
#Automated action-based tests.&amp;lt;br/&amp;gt;We could write more tests that execute a sequence of actions, either on a fresh document or on a pre-existing one. Although this could be done with end-to-end CLI-based tests, it is probably easier to have a C++ test fixture with actions called manually or via their string names.&lt;br /&gt;
#Examine the possibility of creating event-injection GUI-tests.&amp;lt;br/&amp;gt;If successful, this could save a lot of time currently spent on manual GUI testing. &lt;br /&gt;
#Enhance contribution and code review guidelines with testing-related information&amp;lt;br /&amp;gt; A careful balance has to be struck beween the imperative of enforcing a sufficient test coverage and allowing for contributions from relatively inexperienced community members who may lack the knowledge of good practices related to testing. Guidelines which help educate contributors, in addition to learning from examples (for instance, tests created as a part of items listed above) will ensure that even new contributors can contribute to the QA goals within Inkscape. We recognize that these goals should not entail more burden on the contributors, and that with a sufficient level of CI automation, the quality will happen &amp;quot;by default&amp;quot; and &amp;quot;by design&amp;quot;.&amp;lt;br /&amp;gt; &lt;br /&gt;
==Automated testing==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]Inkscape's CI pipeline contains a number of integration and end-to-end tests. However, we recognise that the overal test coverage is '''very poor''' as of late 2023. One of the main goals of this initiative is to track the test coverage and work on gradually increasing it.&lt;br /&gt;
&lt;br /&gt;
Although some existing tests can be classified as &amp;quot;unit tests&amp;quot; because they focus on testing a single unit of code at the time, the external dependencies are poorly understood because all tests link all of &amp;lt;code&amp;gt;libinkscape_base&amp;lt;/code&amp;gt;. This should be addressed as a part of point 1 above.&lt;br /&gt;
&lt;br /&gt;
In the context of automated tests, we recall the famous Testing Pyramid (see right). It expresses the principle that tests at unit and component level should be the most prevalent ones, followed by a smaller number of integration tests, and topped off with a relatively minor number of end-to-end tests. Unfortunately, this is not the case today: we have too few unit tests. Manual testing should be limited to UX and usability aspects.&lt;br /&gt;
&lt;br /&gt;
===Why does Inkscape not have enough unit tests===&lt;br /&gt;
&lt;br /&gt;
*Historical reasons: feature development was prioritized and testing was never formally enforced.&lt;br /&gt;
*Work on tests and QA topics may be perceived as less newsworthy because it is less visible to the end user.&lt;br /&gt;
*Many new developments interact with and depend on legacy code which is hard to split off and mock. Thus, new code is hard to test.&lt;br /&gt;
*Insufficient tooling such as automated test coverage reports or custom test fixtures to facilitate test development.&lt;br /&gt;
*Varied knowledge level of contributors, some lacking expertise in testing.&lt;br /&gt;
&lt;br /&gt;
===What can be done about it===&lt;br /&gt;
&lt;br /&gt;
*Code review should emphasize the importance of adding unit tests for new functionality and regression tests for bug fixes.&lt;br /&gt;
*Quality and maintainability should be viewed as core aspects and as an important part of Inkscape's development.&lt;br /&gt;
*Legacy code must be managed carefully, see below.&lt;br /&gt;
*Test coverage reports should be introduced along with facilities that make it easy and pleasant to write tests.&lt;br /&gt;
*By increasing the number of tests, we can increase the knowledge and awareness of testing techniques in the community – learning from examples.&lt;br /&gt;
&lt;br /&gt;
==Dealing with legacy code ==&lt;br /&gt;
According to Michael Feathers, the author of the influential book &amp;quot;Working effectively with legacy code&amp;quot;, ''legacy code'' is not defined as &amp;quot;old code&amp;quot;, &amp;quot;code written in C&amp;quot; or in general &amp;quot;code that nobody maintains&amp;quot;. Instead, legacy code is '''code that is''' '''not testable and not tested.''' We recognise that Inkscape contains a lot of such code.&lt;br /&gt;
&lt;br /&gt;
===The Vicious Cycle of Legacy Code===&lt;br /&gt;
The fundamental problem with legacy code is that it's very risky to change it because a small change in one place can have unpredictable and unintended consequences in other places. This has happened many times in Inkscape's history and has led to severe bugs. In an ideal world, the existing code could be first enriched with &amp;quot;characterization tests&amp;quot; that capture its current behaviour, and tests could also be added for the new behaviour. In this way, we could assure that the development works as intended and doesn't break anything. But, according to our definition, legacy code is '''not testable''' so this cannot be done. We don't live in an ideal world!&lt;br /&gt;
&lt;br /&gt;
Thus, we are stuck in a vicious cycle: to make code testable, we need to refactor it in order to make it testable, but refactoring can break things badly unless we have tests, which unfortunately we don't and which cannot be added because the code is not testable.&lt;br /&gt;
&lt;br /&gt;
To break out of this cycle, we need to start small, adding tests to simple and relatively independent pieces of functionality. It is helpful to identify the &amp;quot;seams&amp;quot;, which usually correspond to interfaces, along which the program or a system can be natuarally divided into functional pieces. If these pieces are simple enough, they can be made testable. However, even with this approach, a fair bit of mocking may be required to simulate external dependencies, which makes it a tedious task.&lt;br /&gt;
&lt;br /&gt;
===Refactoring and development techniques to increase testability===&lt;br /&gt;
A large portion of Inkscape's codebase is made up of code that's very literal, low-level and suffers from a lack of abstraction. Oftentimes, such code was developed as a part of a small contributions without architectural goals, focused only on adding a small missing piece of functionality. As contributors come and go, this leaves behind a patchwork of fairly inconsistent solutions. Nonetheless, many parts of Inkscape have seen some notable refactoring efforts aimed at unifying these patchwork solutions. It is however important that future refactoring efforts take testability considerations into account. &lt;br /&gt;
&lt;br /&gt;
Desigining good interfaces and abstractions is an important goal that should be kept in mind not only during major architectural updates, but also our everyday work. Whenever you work on Inkscape, ask yourself the question: &amp;quot;Does this change make the code I'm working on more or less testable?&amp;quot;. Below are some concrete examples of techniques that can help increase testability.&lt;br /&gt;
&lt;br /&gt;
====Extract and mock/override====&lt;br /&gt;
&lt;br /&gt;
*Identify the piece of code that makes the functionality non-testable.&lt;br /&gt;
*Move this piece of code to a separate function(s) or a class. Moving code is safer than rewriting it, because the functional logic is kept unchanged.&lt;br /&gt;
*In tests, mock the class or function that the problematic code was moved to. This lets you test new functionality independently of the legacy code.&lt;br /&gt;
*If you need to extend the functionality provided by the non-testable code, try doing it without touching the untested function, but rather wrap around it or provide an override.&lt;br /&gt;
&lt;br /&gt;
====Decorator pattern====&lt;br /&gt;
This design pattern helps extend a legacy class with new functionality. Instead of adding the new functionality directly to the non-testable class (which would make the new functionality non-testable as well), write a wrapper around the legacy class. In the decorator pattern, the decorator class holds an instance of the wrapped class and provides an interface that forwards member function calls to the wrapped object. However, some of the member functions of the wrapper can provide additional functionality or further work on the values obtained from the wrapped object, which makes it possible to add new behaviours. This new functionality can now be tested by mocking the wrapped class in tests.&lt;br /&gt;
&lt;br /&gt;
====Façade transformation====&lt;br /&gt;
This technique helps when dealing with huge classes that hold too much data and that have too many member functions, making them complex, difficult to test, and increasing the coupling with other parts of the code. The façade transformation replaces the large class with a façade class which internally holds instances of several smaller classes. These smaller classes need to be designed by identifying the functionally cohesive pieces of the original large class and splitting them up. The member functions of the façade delegate to member function calls on these internal instances, sometimes more than one at a time. This transformation can be repeated if needed, until the classes are small enough that testing them is possible. The advantage of the façade transformation is that the API exposed by the large class is unchanged.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing unit tests==&lt;br /&gt;
&lt;br /&gt;
*Create a separate test executable for each class or functional module.&lt;br /&gt;
*Write a separate test case for each of the tested behaviours.&lt;br /&gt;
*Write a doxygen-style comment above each test case, explaining very briefly what this case is testing.&lt;br /&gt;
*In each test case, follow the Arrange-Act-Assert principle:&lt;br /&gt;
**Arrange: create and prepare the data and objects needed to perform the tested operation; set up expectations for mock calls;&lt;br /&gt;
**Act: run the tested operation;&lt;br /&gt;
**Assert: use &amp;lt;code&amp;gt;EXPECT_*&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ASSERT_*&amp;lt;/code&amp;gt; macros from Google Testing library to check that the behaviour is as expected.&lt;br /&gt;
*Remember to test strange and corner cases, invalid input, fallback behaviours.&lt;br /&gt;
*If your test needs custom set-up and tear-down, use a custom test fixture and &amp;lt;code&amp;gt;TEST_F&amp;lt;/code&amp;gt; macros.&lt;br /&gt;
*If your test needs to run on several cases parametrized by input data, consider using a &amp;lt;code&amp;gt;TEST_P&amp;lt;/code&amp;gt; fixture.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing end-to-end tests==&lt;br /&gt;
If you are about to create an end-to-end test, ask yourself first if perhaps a unit test can be written instead. However, in the case of regression tests, it's often good to have end-to-end tests that clearly demonstrate that a bug has been fixed and ensure it is not accidentaly reintroduced. End-to-end tests are also suitable for complex cases involving import and export operations. In many cases (such as display and rendering, utilities, Live Path Effects, SPObject system, anything in lib2geom), unit tests ought to be preferred.&lt;br /&gt;
&lt;br /&gt;
*If you create test files (SVG documents or files in other formats), ensure that the content of the files can be visually inspected.&lt;br /&gt;
*If your test file contains both test objects and reference objects, ensure that the relationship between them can be directly inspected visually by a human being in order to confirm that the tested behaviour is indeed correct. You may use existing fixtures such as &amp;lt;code&amp;gt;Inkscape::TestWithSvgObjectPairs&amp;lt;/code&amp;gt; for this purpose.&lt;br /&gt;
*If you use separete reference files, ensure they can be visually inspected as well.&lt;br /&gt;
*Try to make your test focused on the tested behaviour by reducing the number of unrelated elements in your test files.&lt;br /&gt;
*Try to make your test robust and independent on implementation details unrelated to the tested behaviour.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122645</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122645"/>
		<updated>2023-12-23T16:21:30Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have '''more of:'''&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality, especially during the release period.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have '''less of:'''&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
*Reliance on time-consuming manual testing;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Code fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Proposed Actions (To Do List)==&lt;br /&gt;
#Set up CMake targets and macros to make it easy to create unit tests.&amp;lt;br/&amp;gt;Currently, all GTest tests link &amp;lt;code&amp;gt;libinkscape_base&amp;lt;/code&amp;gt;, so they are in fact integration tests rather than unit tests. There should be an easy way of explicitly listing one or several cpp files which will be compiled and linked with tests support utilities only (test the functionality '''in isolation'''). Additionally, there needs to be a way to request linking in &amp;lt;code&amp;gt;lib2geom&amp;lt;/code&amp;gt; for functionality that requires it.&lt;br /&gt;
#Ensure all tests run in debug mode so that failed asserts crash them.&lt;br /&gt;
#Create a flag to easily run tests with the sanitizer.&amp;lt;br/&amp;gt;It should be easy to choose whether a given unit or integration test should run with or without &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt;. The long-term goal is to transition all tests to run in sanitized mode, but many would currently fail due to memory leaks. &lt;br /&gt;
#Create a setup to link inkscape with &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt; in the CI pipeline for use in end-to-end tests.&amp;lt;br/&amp;gt;After building object files, link two inkscape executables: one with and one without &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt;. Create a flag to choose which end-to-end test (e.g., CLI test) should run with the sanitizer (aspirationally, all of them, but not long ago even running &amp;lt;code&amp;gt;inkscape --help&amp;lt;/code&amp;gt; leaked memory).&lt;br /&gt;
#Migrate some of the existing tests to unit test framework.&amp;lt;br/&amp;gt;Do not link all of inkscape just to test a single class or collection of functions.&lt;br /&gt;
#Devise a test strategy for the interactions between &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s and their XML representations.&amp;lt;br/&amp;gt;For each &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; type, it should be possible to easily write tests that create such object (in isolation or in a test fixture simulating a minimalistic document) from an XML string representation and, likewise, write an XML representation of the object. Unit tests of this kind would characterize and document the properties of XML representations and, with sufficient coverage, can prevent data loss bugs and many undo-related issues.&lt;br /&gt;
#Create fixtures for testing &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; behavior.&amp;lt;br/&amp;gt;It should be possible to create an &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;, perhaps embedding it in a minimalistic document provided by a suitable fixture, and perform specific operations on this object in order to create unit tests for all the different &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
#Write integration tests for document-level interactions.&amp;lt;br/&amp;gt;The goal is to test scenarios where several objects depend on each other: clones, groups, gradients, LPE objects, markers which link to each other by href or another type of reference. Integration tests of this kind (linking the entire libinkscape_base into the test executable) will ensure robust handling of situations such as deletion of dependencies, clipboard operations, undo. When run with the sanitizer, they may catch rare memory corruption bugs.&lt;br /&gt;
#Refactor the LPE system.&amp;lt;br/&amp;gt;The LPE system dynamically rewrites the d attribute of an SVG path in order to create an artistic effect. As such, each LPE should be easily testable in principle. Migrate existing end-to-end tests of the LPE system and make them unit tests.  Assumption: making LPEs individually testable will improve the quality of LPE-related code and offer an opportunity to redesign it.&lt;br /&gt;
#Enable test coverage reports in the CI pipeline.&amp;lt;br/&amp;gt;This was already done in lib2geom and the extensions repository, so a similar setup should be easy to reproduce. Consider gamification of test coverage.&lt;br /&gt;
#Create more rendering tests.&amp;lt;br/&amp;gt;The display system should be tested more rigorously in order to prevent rendering regressions.&lt;br /&gt;
#Automated action-based tests.&amp;lt;br/&amp;gt;We could write more tests that execute a sequence of actions, either on a fresh document or on a pre-existing one. Although this could be done with end-to-end CLI-based tests, it is probably easier to have a C++ test fixture with actions called manually or via their string names.&lt;br /&gt;
#Examine the possibility of creating event-injection GUI-tests.&amp;lt;br/&amp;gt;If successful, this could save a lot of time currently spent on manual GUI testing. &lt;br /&gt;
#Enhance contribution and code review guidelines with testing-related information&amp;lt;br /&amp;gt; A careful balance has to be struck beween the imperative of enforcing a sufficient test coverage and allowing for contributions from relatively inexperienced community members who may lack the knowledge of good practices related to testing. Guidelines which help educate contributors, in addition to learning from examples (for instance, tests created as a part of items listed above) will ensure that even new contributors can contribute to the QA goals within Inkscape. We recognize that these goals should not entail more burden on the contributors, and that with a sufficient level of CI automation, the quality will happen &amp;quot;by default&amp;quot; and &amp;quot;by design&amp;quot;.&amp;lt;br /&amp;gt; &lt;br /&gt;
==Automated testing==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]Inkscape's CI pipeline contains a number of integration and end-to-end tests. However, we recognise that the overal test coverage is '''very poor''' as of late 2023. One of the main goals of this initiative is to track the test coverage and work on gradually increasing it.&lt;br /&gt;
&lt;br /&gt;
Although some existing tests can be classified as &amp;quot;unit tests&amp;quot; because they focus on testing a single unit of code at the time, the external dependencies are poorly understood because all tests link all of &amp;lt;code&amp;gt;libinkscape_base&amp;lt;/code&amp;gt;. This should be addressed as a part of point 1 above.&lt;br /&gt;
&lt;br /&gt;
In the context of automated tests, we recall the famous Testing Pyramid (see right). It expresses the principle that tests at unit and component level should be the most prevalent ones, followed by a smaller number of integration tests, and topped off with a relatively lower number of end-to-end tests. Unfortunately, this is not the case today: we have too few unit tests. Manual testing should be limited to UX and usability aspects.&lt;br /&gt;
&lt;br /&gt;
===Why does Inkscape not have enough unit tests===&lt;br /&gt;
&lt;br /&gt;
*Historical reasons: feature development was prioritized and testing was never formally enforced.&lt;br /&gt;
*Work on tests and QA topics may be perceived as less newsworthy because it is less visible to the end user.&lt;br /&gt;
*Many new developments interact with and depend on legacy code which is hard to split off and mock. Thus, new code is hard to test.&lt;br /&gt;
*Insufficient tooling such as automated test coverage reports or custom test fixtures to facilitate test development.&lt;br /&gt;
*Varied knowledge level of contributors, some lacking expertise in testing.&lt;br /&gt;
&lt;br /&gt;
===What can be done about it===&lt;br /&gt;
&lt;br /&gt;
*Code review should emphasize the importance of adding unit tests for new functionality and regression tests for bug fixes.&lt;br /&gt;
*Quality and maintainability should be viewed as core aspects and as an important part of Inkscape's development.&lt;br /&gt;
*Legacy code must be managed carefully, see below.&lt;br /&gt;
*Test coverage reports should be introduced along with facilities that make it easy and pleasant to write tests.&lt;br /&gt;
*By increasing the number of tests, we can increase the knowledge and awareness of testing techniques in the community – learning from examples.&lt;br /&gt;
&lt;br /&gt;
==Dealing with legacy code ==&lt;br /&gt;
According to Michael Feathers, the author of the influential book &amp;quot;Working effectively with legacy code&amp;quot;, ''legacy code'' is not defined as &amp;quot;old code&amp;quot;, &amp;quot;code written in C&amp;quot; or in general &amp;quot;code that nobody maintains&amp;quot;. Instead, legacy code is '''code that is''' '''not testable and not tested.''' We recognise that Inkscape contains a lot of such code.&lt;br /&gt;
&lt;br /&gt;
===The Vicious Cycle of Legacy Code===&lt;br /&gt;
The fundamental problem with legacy code is that it's very risky to change it because a small change in one place can have unpredictable and unintended consequences in other places. This has happened many times in Inkscape's history and has led to severe bugs. In an ideal world, the existing code could be first enriched with &amp;quot;characterization tests&amp;quot; that capture its current behaviour, and tests could also be added for the new behaviour. In this way, we could assure that the development works as intended and doesn't break anything. But, according to our definition, legacy code is '''not testable''' so this cannot be done. We don't live in an ideal world!&lt;br /&gt;
&lt;br /&gt;
Thus, we are stuck in a vicious cycle: to make code testable, we need to refactor it in order to make it testable, but refactoring can break things badly unless we have tests, which unfortunately we don't and which cannot be added because the code is not testable.&lt;br /&gt;
&lt;br /&gt;
To break out of this cycle, we need to start small, adding tests to simple and relatively independent pieces of functionality. It is helpful to identify the &amp;quot;seams&amp;quot;, which usually correspond to interfaces, along which the program or a system can be natuarally divided into functional pieces. If these pieces are simple enough, they can be made testable. However, even with this approach, a fair bit of mocking may be required to simulate external dependencies, which makes it a tedious task.&lt;br /&gt;
&lt;br /&gt;
===Refactoring and development techniques to increase testability===&lt;br /&gt;
A large portion of Inkscape's codebase is made up of code that's very literal, low-level and suffers from a lack of abstraction. Oftentimes, such code was developed as a part of a small contributions without architectural goals, focused only on adding a small missing piece of functionality. As contributors come and go, this leaves behind a patchwork of fairly inconsistent solutions. Nonetheless, many parts of Inkscape have seen some notable refactoring efforts aimed at unifying these patchwork solutions. It is however important that future refactoring efforts take testability considerations into account. &lt;br /&gt;
&lt;br /&gt;
Desigining good interfaces and abstractions is an important goal that should be kept in mind not only during major architectural updates, but also our everyday work. Whenever you work on Inkscape, ask yourself the question: &amp;quot;Does this change make the code I'm working on more or less testable?&amp;quot;. Below are some concrete examples of techniques that can help increase testability.&lt;br /&gt;
&lt;br /&gt;
====Extract and mock/override====&lt;br /&gt;
&lt;br /&gt;
*Identify the piece of code that makes the functionality non-testable.&lt;br /&gt;
*Move this piece of code to a separate function(s) or a class. Moving code is safer than rewriting it, because the functional logic is kept unchanged.&lt;br /&gt;
*In tests, mock the class or function that the problematic code was moved to. This lets you test new functionality independently of the legacy code.&lt;br /&gt;
*If you need to extend the functionality provided by the non-testable code, try doing it without touching the untested function, but rather wrap around it or provide an override.&lt;br /&gt;
&lt;br /&gt;
====Decorator pattern====&lt;br /&gt;
This design pattern helps extend a legacy class with new functionality. Instead of adding the new functionality directly to the non-testable class (which would make the new functionality non-testable as well), write a wrapper around the legacy class. In the decorator pattern, the decorator class holds an instance of the wrapped class and provides an interface that forwards member function calls to the wrapped object. However, some of the member functions of the wrapper can provide additional functionality or further work on the values obtained from the wrapped object, which makes it possible to add new behaviours. This new functionality can now be tested by mocking the wrapped class in tests.&lt;br /&gt;
&lt;br /&gt;
====Façade transformation====&lt;br /&gt;
This technique helps when dealing with huge classes that hold too much data and that have too many member functions, making them complex, difficult to test, and increasing the coupling with other parts of the code. The façade transformation replaces the large class with a façade class which internally holds instances of several smaller classes. These smaller classes need to be designed by identifying the functionally cohesive pieces of the original large class and splitting them up. The member functions of the façade delegate to member function calls on these internal instances, sometimes more than one at a time. This transformation can be repeated if needed, until the classes are small enough that testing them is possible. The advantage of the façade transformation is that the API exposed by the large class is unchanged.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing unit tests==&lt;br /&gt;
&lt;br /&gt;
*Create a separate test executable for each class or functional module.&lt;br /&gt;
*Write a separate test case for each of the tested behaviours.&lt;br /&gt;
*Write a doxygen-style comment above each test case, explaining very briefly what this case is testing.&lt;br /&gt;
*In each test case, follow the Arrange-Act-Assert principle:&lt;br /&gt;
**Arrange: create and prepare the data and objects needed to perform the tested operation; set up expectations for mock calls;&lt;br /&gt;
**Act: run the tested operation;&lt;br /&gt;
**Assert: use &amp;lt;code&amp;gt;EXPECT_*&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ASSERT_*&amp;lt;/code&amp;gt; macros from Google Testing library to check that the behaviour is as expected.&lt;br /&gt;
*Remember to test strange and corner cases, invalid input, fallback behaviours.&lt;br /&gt;
*If your test needs custom set-up and tear-down, use a custom test fixture and &amp;lt;code&amp;gt;TEST_F&amp;lt;/code&amp;gt; macros.&lt;br /&gt;
*If your test needs to run on several cases parametrized by input data, consider using a &amp;lt;code&amp;gt;TEST_P&amp;lt;/code&amp;gt; fixture.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing end-to-end tests==&lt;br /&gt;
If you are about to create an end-to-end test, ask yourself first if perhaps a unit test can be written instead. However, in the case of regression tests, it's often good to have end-to-end tests that clearly demonstrate that a bug has been fixed and ensure it is not accidentaly reintroduced. End-to-end tests are also suitable for complex cases involving import and export operations. In many cases (such as display and rendering, utilities, Live Path Effects, SPObject system, anything in lib2geom), unit tests ought to be preferred.&lt;br /&gt;
&lt;br /&gt;
*If you create test files (SVG documents or files in other formats), ensure that the content of the files can be visually inspected.&lt;br /&gt;
*If your test file contains both test objects and reference objects, ensure that the relationship between them can be directly inspected visually by a human being in order to confirm that the tested behaviour is indeed correct. You may use existing fixtures such as &amp;lt;code&amp;gt;Inkscape::TestWithSvgObjectPairs&amp;lt;/code&amp;gt; for this purpose.&lt;br /&gt;
*If you use separete reference files, ensure they can be visually inspected as well.&lt;br /&gt;
*Try to make your test focused on the tested behaviour by reducing the number of unrelated elements in your test files.&lt;br /&gt;
*Try to make your test robust and independent on implementation details unrelated to the tested behaviour.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122644</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122644"/>
		<updated>2023-12-23T15:57:31Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: /* Automated testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have '''more of:'''&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality, especially during the release period.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have '''less of:'''&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
*Reliance on time-consuming manual testing;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Code fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Proposed Actions (To Do List)==&lt;br /&gt;
#Set up CMake targets and macros to make it easy to create unit tests.&amp;lt;br/&amp;gt;Currently, all GTest tests link &amp;lt;code&amp;gt;libinkscape_base&amp;lt;/code&amp;gt;, so they are in fact integration tests rather than unit tests. There should be an easy way of explicitly listing one or several cpp files which will be compiled and linked with tests support utilities only (test the functionality '''in isolation'''). Additionally, there needs to be a way to request linking in &amp;lt;code&amp;gt;lib2geom&amp;lt;/code&amp;gt; for functionality that requires it.&lt;br /&gt;
#Ensure all tests run in debug mode so that failed asserts crash them.&lt;br /&gt;
#Create a flag to easily run tests with the sanitizer.&amp;lt;br/&amp;gt;It should be easy to choose whether a given unit or integration test should run with or without &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt;. The long-term goal is to transition all tests to run in sanitized mode, but many would currently fail due to memory leaks. &lt;br /&gt;
#Create a setup to link inkscape with &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt; in the CI pipeline for use in end-to-end tests.&amp;lt;br/&amp;gt;After building object files, link two inkscape executables: one with and one without &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt;. Create a flag to choose which end-to-end test (e.g., CLI test) should run with the sanitizer (aspirationally, all of them, but not long ago even running &amp;lt;code&amp;gt;inkscape --help&amp;lt;/code&amp;gt; leaked memory).&lt;br /&gt;
#Migrate some of the existing tests to unit test framework.&amp;lt;br/&amp;gt;Do not link all of inkscape just to test a single class or collection of functions.&lt;br /&gt;
#Devise a test strategy for the interactions between &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s and their XML representations.&amp;lt;br/&amp;gt;For each &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; type, it should be possible to easily write tests that create such object (in isolation or in a test fixture simulating a minimalistic document) from an XML string representation and, likewise, write an XML representation of the object. Unit tests of this kind would characterize and document the properties of XML representations and, with sufficient coverage, can prevent data loss bugs and many undo-related issues.&lt;br /&gt;
#Create fixtures for testing &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; behavior.&amp;lt;br/&amp;gt;It should be possible to create an &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;, perhaps embedding it in a minimalistic document provided by a suitable fixture, and perform specific operations on this object in order to create unit tests for all the different &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
#Write integration tests for document-level interactions.&amp;lt;br/&amp;gt;The goal is to test scenarios where several objects depend on each other: clones, groups, gradients, LPE objects, markers which link to each other by href or another type of reference. Integration tests of this kind (linking the entire libinkscape_base into the test executable) will ensure robust handling of situations such as deletion of dependencies, clipboard operations, undo. When run with the sanitizer, they may catch rare memory corruption bugs.&lt;br /&gt;
#Refactor the LPE system.&amp;lt;br/&amp;gt;The LPE system dynamically rewrites the d attribute of an SVG path in order to create an artistic effect. As such, each LPE should be easily testable in principle. Migrate existing end-to-end tests of the LPE system and make them unit tests.  Assumption: making LPEs individually testable will improve the quality of LPE-related code and offer an opportunity to redesign it.&lt;br /&gt;
#Enable test coverage reports in the CI pipeline.&amp;lt;br/&amp;gt;This was already done in lib2geom and the extensions repository, so a similar setup should be easy to reproduce.&lt;br /&gt;
#Create more rendering tests.&amp;lt;br/&amp;gt;The display system should be tested more rigorously in order to prevent rendering regressions.&lt;br /&gt;
#Automated action-based tests.&amp;lt;br/&amp;gt;We could write more tests that execute a sequence of actions, either on a fresh document or on a pre-existing one. Although this could be done with end-to-end CLI-based tests, it is probably easier to have a C++ test fixture with actions called manually or via their string names.&lt;br /&gt;
#Examine the possibility of creating event-injection GUI-tests.&amp;lt;br/&amp;gt;If successful, this could save a lot of time currently spent on manual GUI testing. &lt;br /&gt;
#Enhance contribution and code review guidelines with testing-related information&amp;lt;br /&amp;gt; A careful balance has to be struck beween the imperative of enforcing a sufficient test coverage and allowing for contributions from relatively inexperienced community members who may lack the knowledge of good practices related to testing. Guidelines which help educate contributors, in addition to learning from examples (for instance, tests created as a part of items listed above) will ensure that even new contributors can contribute to the QA goals within Inkscape.&amp;lt;br /&amp;gt; &lt;br /&gt;
==Automated testing==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]Inkscape's CI pipeline contains a number of integration and end-to-end tests. However, we recognise that the overal test coverage is '''very poor''' as of late 2023. One of the main goals of this initiative is to track the test coverage and work on gradually increasing it.&lt;br /&gt;
&lt;br /&gt;
Although some existing tests can be classified as &amp;quot;unit tests&amp;quot; because they focus on testing a single unit of code at the time, the external dependencies are poorly understood because all tests link all of &amp;lt;code&amp;gt;libinkscape_base&amp;lt;/code&amp;gt;. This should be addressed as a part of point 1 above.&lt;br /&gt;
&lt;br /&gt;
In the context of automated tests, we recall the famous Testing Pyramid (see right). It expresses the principle that tests at unit and component level should be the most prevalent ones, followed by a smaller number of integration tests, and topped off with a relatively lower number of end-to-end tests. Unfortunately, this is not the case today: we have too few unit tests. Manual testing should be limited to UX and usability aspects.&lt;br /&gt;
&lt;br /&gt;
===Why does Inkscape not have enough unit tests===&lt;br /&gt;
&lt;br /&gt;
*Historical reasons: feature development was prioritized and testing was never formally enforced.&lt;br /&gt;
*Work on tests and QA topics may be perceived as less newsworthy because it is less visible to the end user.&lt;br /&gt;
*Many new developments interact with and depend on legacy code which is hard to split off and mock. Thus, new code is hard to test.&lt;br /&gt;
*Insufficient tooling such as automated test coverage reports or custom test fixtures to facilitate test development.&lt;br /&gt;
*Varied knowledge level of contributors, some lacking expertise in testing.&lt;br /&gt;
&lt;br /&gt;
===What can be done about it===&lt;br /&gt;
&lt;br /&gt;
*Code review should emphasize the importance of adding unit tests for new functionality and regression tests for bug fixes.&lt;br /&gt;
*Quality and maintainability should be viewed as core aspects and as an important part of Inkscape's development.&lt;br /&gt;
*Legacy code must be managed carefully, see below.&lt;br /&gt;
*Test coverage reports should be introduced along with facilities that make it easy and pleasant to write tests.&lt;br /&gt;
*By increasing the number of tests, we can increase the knowledge and awareness of testing techniques in the community – learning from examples.&lt;br /&gt;
&lt;br /&gt;
==Dealing with legacy code ==&lt;br /&gt;
According to Michael Feathers, the author of the influential book &amp;quot;Working effectively with legacy code&amp;quot;, ''legacy code'' is not defined as &amp;quot;old code&amp;quot;, &amp;quot;code written in C&amp;quot; or in general &amp;quot;code that nobody maintains&amp;quot;. Instead, legacy code is '''code that is''' '''not testable and not tested.''' We recognise that Inkscape contains a lot of such code.&lt;br /&gt;
&lt;br /&gt;
===The Vicious Cycle of Legacy Code===&lt;br /&gt;
The fundamental problem with legacy code is that it's very risky to change it because a small change in one place can have unpredictable and unintended consequences in other places. This has happened many times in Inkscape's history and has led to severe bugs. In an ideal world, the existing code could be first enriched with &amp;quot;characterization tests&amp;quot; that capture its current behaviour, and tests could also be added for the new behaviour. In this way, we could assure that the development works as intended and doesn't break anything. But, according to our definition, legacy code is '''not testable''' so this cannot be done. We don't live in an ideal world!&lt;br /&gt;
&lt;br /&gt;
Thus, we are stuck in a vicious cycle: to make code testable, we need to refactor it in order to make it testable, but refactoring can break things badly unless we have tests, which unfortunately we don't and which cannot be added because the code is not testable.&lt;br /&gt;
&lt;br /&gt;
To break out of this cycle, we need to start small, adding tests to simple and relatively independent pieces of functionality. It is helpful to identify the &amp;quot;seams&amp;quot;, which usually correspond to interfaces, along which the program or a system can be natuarally divided into functional pieces. If these pieces are simple enough, they can be made testable. However, even with this approach, a fair bit of mocking may be required to simulate external dependencies, which makes it a tedious task.&lt;br /&gt;
&lt;br /&gt;
===Refactoring and development techniques to increase testability===&lt;br /&gt;
A large portion of Inkscape's codebase is made up of code that's very literal, low-level and suffers from a lack of abstraction. Oftentimes, such code was developed as a part of a small contributions without architectural goals, focused only on adding a small missing piece of functionality. As contributors come and go, this leaves behind a patchwork of fairly inconsistent solutions. Nonetheless, many parts of Inkscape have seen some notable refactoring efforts aimed at unifying these patchwork solutions. It is however important that future refactoring efforts take testability considerations into account. &lt;br /&gt;
&lt;br /&gt;
Desigining good interfaces and abstractions is an important goal that should be kept in mind not only during major architectural updates, but also our everyday work. Whenever you work on Inkscape, ask yourself the question: &amp;quot;Does this change make the code I'm working on more or less testable?&amp;quot;. Below are some concrete examples of techniques that can help increase testability.&lt;br /&gt;
&lt;br /&gt;
====Extract and mock/override====&lt;br /&gt;
&lt;br /&gt;
*Identify the piece of code that makes the functionality non-testable.&lt;br /&gt;
*Move this piece of code to a separate function(s) or a class. Moving code is safer than rewriting it, because the functional logic is kept unchanged.&lt;br /&gt;
*In tests, mock the class or function that the problematic code was moved to. This lets you test new functionality independently of the legacy code.&lt;br /&gt;
*If you need to extend the functionality provided by the non-testable code, try doing it without touching the untested function, but rather wrap around it or provide an override.&lt;br /&gt;
&lt;br /&gt;
====Decorator pattern====&lt;br /&gt;
This design pattern helps extend a legacy class with new functionality. Instead of adding the new functionality directly to the non-testable class (which would make the new functionality non-testable as well), write a wrapper around the legacy class. In the decorator pattern, the decorator class holds an instance of the wrapped class and provides an interface that forwards member function calls to the wrapped object. However, some of the member functions of the wrapper can provide additional functionality or further work on the values obtained from the wrapped object, which makes it possible to add new behaviours. This new functionality can now be tested by mocking the wrapped class in tests.&lt;br /&gt;
&lt;br /&gt;
====Façade transformation====&lt;br /&gt;
This technique helps when dealing with huge classes that hold too much data and that have too many member functions, making them complex, difficult to test, and increasing the coupling with other parts of the code. The façade transformation replaces the large class with a façade class which internally holds instances of several smaller classes. These smaller classes need to be designed by identifying the functionally cohesive pieces of the original large class and splitting them up. The member functions of the façade delegate to member function calls on these internal instances, sometimes more than one at a time. This transformation can be repeated if needed, until the classes are small enough that testing them is possible. The advantage of the façade transformation is that the API exposed by the large class is unchanged.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing unit tests==&lt;br /&gt;
&lt;br /&gt;
*Create a separate test executable for each class or functional module.&lt;br /&gt;
*Write a separate test case for each of the tested behaviours.&lt;br /&gt;
*Write a doxygen-style comment above each test case, explaining very briefly what this case is testing.&lt;br /&gt;
*In each test case, follow the Arrange-Act-Assert principle:&lt;br /&gt;
**Arrange: create and prepare the data and objects needed to perform the tested operation; set up expectations for mock calls;&lt;br /&gt;
**Act: run the tested operation;&lt;br /&gt;
**Assert: use &amp;lt;code&amp;gt;EXPECT_*&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ASSERT_*&amp;lt;/code&amp;gt; macros from Google Testing library to check that the behaviour is as expected.&lt;br /&gt;
*Remember to test strange and corner cases, invalid input, fallback behaviours.&lt;br /&gt;
*If your test needs custom set-up and tear-down, use a custom test fixture and &amp;lt;code&amp;gt;TEST_F&amp;lt;/code&amp;gt; macros.&lt;br /&gt;
*If your test needs to run on several cases parametrized by input data, consider using a &amp;lt;code&amp;gt;TEST_P&amp;lt;/code&amp;gt; fixture.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing end-to-end tests==&lt;br /&gt;
If you are about to create an end-to-end test, ask yourself first if perhaps a unit test can be written instead. However, in the case of regression tests, it's often good to have end-to-end tests that clearly demonstrate that a bug has been fixed and ensure it is not accidentaly reintroduced. End-to-end tests are also suitable for complex cases involving import and export operations. In many cases (such as display and rendering, utilities, Live Path Effects, SPObject system, anything in lib2geom), unit tests ought to be preferred.&lt;br /&gt;
&lt;br /&gt;
*If you create test files (SVG documents or files in other formats), ensure that the content of the files can be visually inspected.&lt;br /&gt;
*If your test file contains both test objects and reference objects, ensure that the relationship between them can be directly inspected visually by a human being in order to confirm that the tested behaviour is indeed correct. You may use existing fixtures such as &amp;lt;code&amp;gt;Inkscape::TestWithSvgObjectPairs&amp;lt;/code&amp;gt; for this purpose.&lt;br /&gt;
*If you use separete reference files, ensure they can be visually inspected as well.&lt;br /&gt;
*Try to make your test focused on the tested behaviour by reducing the number of unrelated elements in your test files.&lt;br /&gt;
*Try to make your test robust and independent on implementation details unrelated to the tested behaviour.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122643</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122643"/>
		<updated>2023-12-23T15:54:30Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have '''more of:'''&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality, especially during the release period.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have '''less of:'''&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
*Reliance on time-consuming manual testing;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Code fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Proposed Actions (To Do List)==&lt;br /&gt;
#Set up CMake targets and macros to make it easy to create unit tests.&amp;lt;br/&amp;gt;Currently, all GTest tests link &amp;lt;code&amp;gt;libinkscape_base&amp;lt;/code&amp;gt;, so they are in fact integration tests rather than unit tests. There should be an easy way of explicitly listing one or several cpp files which will be compiled and linked with tests support utilities only (test the functionality '''in isolation'''). Additionally, there needs to be a way to request linking in &amp;lt;code&amp;gt;lib2geom&amp;lt;/code&amp;gt; for functionality that requires it.&lt;br /&gt;
#Ensure all tests run in debug mode so that failed asserts crash them.&lt;br /&gt;
#Create a flag to easily run tests with the sanitizer.&amp;lt;br/&amp;gt;It should be easy to choose whether a given unit or integration test should run with or without &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt;. The long-term goal is to transition all tests to run in sanitized mode, but many would currently fail due to memory leaks. &lt;br /&gt;
#Create a setup to link inkscape with &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt; in the CI pipeline for use in end-to-end tests.&amp;lt;br/&amp;gt;After building object files, link two inkscape executables: one with and one without &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt;. Create a flag to choose which end-to-end test (e.g., CLI test) should run with the sanitizer (aspirationally, all of them, but not long ago even running &amp;lt;code&amp;gt;inkscape --help&amp;lt;/code&amp;gt; leaked memory).&lt;br /&gt;
#Migrate some of the existing tests to unit test framework.&amp;lt;br/&amp;gt;Do not link all of inkscape just to test a single class or collection of functions.&lt;br /&gt;
#Devise a test strategy for the interactions between &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s and their XML representations.&amp;lt;br/&amp;gt;For each &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; type, it should be possible to easily write tests that create such object (in isolation or in a test fixture simulating a minimalistic document) from an XML string representation and, likewise, write an XML representation of the object. Unit tests of this kind would characterize and document the properties of XML representations and, with sufficient coverage, can prevent data loss bugs and many undo-related issues.&lt;br /&gt;
#Create fixtures for testing &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; behavior.&amp;lt;br/&amp;gt;It should be possible to create an &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;, perhaps embedding it in a minimalistic document provided by a suitable fixture, and perform specific operations on this object in order to create unit tests for all the different &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
#Write integration tests for document-level interactions.&amp;lt;br/&amp;gt;The goal is to test scenarios where several objects depend on each other: clones, groups, gradients, LPE objects, markers which link to each other by href or another type of reference. Integration tests of this kind (linking the entire libinkscape_base into the test executable) will ensure robust handling of situations such as deletion of dependencies, clipboard operations, undo. When run with the sanitizer, they may catch rare memory corruption bugs.&lt;br /&gt;
#Refactor the LPE system.&amp;lt;br/&amp;gt;The LPE system dynamically rewrites the d attribute of an SVG path in order to create an artistic effect. As such, each LPE should be easily testable in principle. Migrate existing end-to-end tests of the LPE system and make them unit tests.  Assumption: making LPEs individually testable will improve the quality of LPE-related code and offer an opportunity to redesign it.&lt;br /&gt;
#Enable test coverage reports in the CI pipeline.&amp;lt;br/&amp;gt;This was already done in lib2geom and the extensions repository, so a similar setup should be easy to reproduce.&lt;br /&gt;
#Create more rendering tests.&amp;lt;br/&amp;gt;The display system should be tested more rigorously in order to prevent rendering regressions.&lt;br /&gt;
#Automated action-based tests.&amp;lt;br/&amp;gt;We could write more tests that execute a sequence of actions, either on a fresh document or on a pre-existing one. Although this could be done with end-to-end CLI-based tests, it is probably easier to have a C++ test fixture with actions called manually or via their string names.&lt;br /&gt;
#Examine the possibility of creating event-injection GUI-tests.&amp;lt;br/&amp;gt;If successful, this could save a lot of time currently spent on manual GUI testing. &lt;br /&gt;
#Enhance contribution and code review guidelines with testing-related information&amp;lt;br /&amp;gt; A careful balance has to be struck beween the imperative of enforcing a sufficient test coverage and allowing for contributions from relatively inexperienced community members who may lack the knowledge of good practices related to testing. Guidelines which help educate contributors, in addition to learning from examples (for instance, tests created as a part of items listed above) will ensure that even new contributors can contribute to the QA goals within Inkscape.&amp;lt;br /&amp;gt; &lt;br /&gt;
==Automated testing==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]Inkscape's CI pipeline contains a number of unit, integration and end-to-end tests. However, we recognise that the overal test coverage is '''very poor''' as of late 2023. One of the main goals of this initiative is to track the test coverage and work on gradually increasing it.&lt;br /&gt;
&lt;br /&gt;
In the context of automated tests, we recall the famous Testing Pyramid (see right). It expresses the principle that tests at unit and component level should be the most prevalent ones, followed by a smaller number of integration tests, and topped off with a relatively lower number of end-to-end tests. Unfortunately, this is not the case today: we have too few unit tests. Manual testing should be limited to UX and usability aspects.&lt;br /&gt;
&lt;br /&gt;
===Why does Inkscape not have enough unit tests===&lt;br /&gt;
&lt;br /&gt;
*Historical reasons: feature development was prioritized and testing was never formally enforced.&lt;br /&gt;
*Work on tests and QA topics may be perceived as less newsworthy because it is less visible to the end user.&lt;br /&gt;
*Many new developments interact with and depend on legacy code which is hard to split off and mock. Thus, new code is hard to test.&lt;br /&gt;
*Insufficient tooling such as automated test coverage reports or custom test fixtures to facilitate test development.&lt;br /&gt;
*Varied knowledge level of contributors, some lacking expertise in testing.&lt;br /&gt;
&lt;br /&gt;
===What can be done about it===&lt;br /&gt;
&lt;br /&gt;
*Code review should emphasize the importance of adding unit tests for new functionality and regression tests for bug fixes.&lt;br /&gt;
*Quality and maintainability should be viewed as core aspects and as an important part of Inkscape's development.&lt;br /&gt;
*Legacy code must be managed carefully, see below.&lt;br /&gt;
*Test coverage reports should be introduced along with facilities that make it easy and pleasant to write tests.&lt;br /&gt;
*By increasing the number of tests, we can increase the knowledge and awareness of testing techniques in the community – learning from examples.&lt;br /&gt;
&lt;br /&gt;
==Dealing with legacy code ==&lt;br /&gt;
According to Michael Feathers, the author of the influential book &amp;quot;Working effectively with legacy code&amp;quot;, ''legacy code'' is not defined as &amp;quot;old code&amp;quot;, &amp;quot;code written in C&amp;quot; or in general &amp;quot;code that nobody maintains&amp;quot;. Instead, legacy code is '''code that is''' '''not testable and not tested.''' We recognise that Inkscape contains a lot of such code.&lt;br /&gt;
&lt;br /&gt;
===The Vicious Cycle of Legacy Code===&lt;br /&gt;
The fundamental problem with legacy code is that it's very risky to change it because a small change in one place can have unpredictable and unintended consequences in other places. This has happened many times in Inkscape's history and has led to severe bugs. In an ideal world, the existing code could be first enriched with &amp;quot;characterization tests&amp;quot; that capture its current behaviour, and tests could also be added for the new behaviour. In this way, we could assure that the development works as intended and doesn't break anything. But, according to our definition, legacy code is '''not testable''' so this cannot be done. We don't live in an ideal world!&lt;br /&gt;
&lt;br /&gt;
Thus, we are stuck in a vicious cycle: to make code testable, we need to refactor it in order to make it testable, but refactoring can break things badly unless we have tests, which unfortunately we don't and which cannot be added because the code is not testable.&lt;br /&gt;
&lt;br /&gt;
To break out of this cycle, we need to start small, adding tests to simple and relatively independent pieces of functionality. It is helpful to identify the &amp;quot;seams&amp;quot;, which usually correspond to interfaces, along which the program or a system can be natuarally divided into functional pieces. If these pieces are simple enough, they can be made testable. However, even with this approach, a fair bit of mocking may be required to simulate external dependencies, which makes it a tedious task.&lt;br /&gt;
&lt;br /&gt;
===Refactoring and development techniques to increase testability===&lt;br /&gt;
A large portion of Inkscape's codebase is made up of code that's very literal, low-level and suffers from a lack of abstraction. Oftentimes, such code was developed as a part of a small contributions without architectural goals, focused only on adding a small missing piece of functionality. As contributors come and go, this leaves behind a patchwork of fairly inconsistent solutions. Nonetheless, many parts of Inkscape have seen some notable refactoring efforts aimed at unifying these patchwork solutions. It is however important that future refactoring efforts take testability considerations into account. &lt;br /&gt;
&lt;br /&gt;
Desigining good interfaces and abstractions is an important goal that should be kept in mind not only during major architectural updates, but also our everyday work. Whenever you work on Inkscape, ask yourself the question: &amp;quot;Does this change make the code I'm working on more or less testable?&amp;quot;. Below are some concrete examples of techniques that can help increase testability.&lt;br /&gt;
&lt;br /&gt;
====Extract and mock/override====&lt;br /&gt;
&lt;br /&gt;
*Identify the piece of code that makes the functionality non-testable.&lt;br /&gt;
*Move this piece of code to a separate function(s) or a class. Moving code is safer than rewriting it, because the functional logic is kept unchanged.&lt;br /&gt;
*In tests, mock the class or function that the problematic code was moved to. This lets you test new functionality independently of the legacy code.&lt;br /&gt;
*If you need to extend the functionality provided by the non-testable code, try doing it without touching the untested function, but rather wrap around it or provide an override.&lt;br /&gt;
&lt;br /&gt;
====Decorator pattern====&lt;br /&gt;
This design pattern helps extend a legacy class with new functionality. Instead of adding the new functionality directly to the non-testable class (which would make the new functionality non-testable as well), write a wrapper around the legacy class. In the decorator pattern, the decorator class holds an instance of the wrapped class and provides an interface that forwards member function calls to the wrapped object. However, some of the member functions of the wrapper can provide additional functionality or further work on the values obtained from the wrapped object, which makes it possible to add new behaviours. This new functionality can now be tested by mocking the wrapped class in tests.&lt;br /&gt;
&lt;br /&gt;
====Façade transformation====&lt;br /&gt;
This technique helps when dealing with huge classes that hold too much data and that have too many member functions, making them complex, difficult to test, and increasing the coupling with other parts of the code. The façade transformation replaces the large class with a façade class which internally holds instances of several smaller classes. These smaller classes need to be designed by identifying the functionally cohesive pieces of the original large class and splitting them up. The member functions of the façade delegate to member function calls on these internal instances, sometimes more than one at a time. This transformation can be repeated if needed, until the classes are small enough that testing them is possible. The advantage of the façade transformation is that the API exposed by the large class is unchanged.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing unit tests==&lt;br /&gt;
&lt;br /&gt;
*Create a separate test executable for each class or functional module.&lt;br /&gt;
*Write a separate test case for each of the tested behaviours.&lt;br /&gt;
*Write a doxygen-style comment above each test case, explaining very briefly what this case is testing.&lt;br /&gt;
*In each test case, follow the Arrange-Act-Assert principle:&lt;br /&gt;
**Arrange: create and prepare the data and objects needed to perform the tested operation; set up expectations for mock calls;&lt;br /&gt;
**Act: run the tested operation;&lt;br /&gt;
**Assert: use &amp;lt;code&amp;gt;EXPECT_*&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ASSERT_*&amp;lt;/code&amp;gt; macros from Google Testing library to check that the behaviour is as expected.&lt;br /&gt;
*Remember to test strange and corner cases, invalid input, fallback behaviours.&lt;br /&gt;
*If your test needs custom set-up and tear-down, use a custom test fixture and &amp;lt;code&amp;gt;TEST_F&amp;lt;/code&amp;gt; macros.&lt;br /&gt;
*If your test needs to run on several cases parametrized by input data, consider using a &amp;lt;code&amp;gt;TEST_P&amp;lt;/code&amp;gt; fixture.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing end-to-end tests==&lt;br /&gt;
If you are about to create an end-to-end test, ask yourself first if perhaps a unit test can be written instead. However, in the case of regression tests, it's often good to have end-to-end tests that clearly demonstrate that a bug has been fixed and ensure it is not accidentaly reintroduced. End-to-end tests are also suitable for complex cases involving import and export operations. In many cases (such as display and rendering, utilities, Live Path Effects, SPObject system, anything in lib2geom), unit tests ought to be preferred.&lt;br /&gt;
&lt;br /&gt;
*If you create test files (SVG documents or files in other formats), ensure that the content of the files can be visually inspected.&lt;br /&gt;
*If your test file contains both test objects and reference objects, ensure that the relationship between them can be directly inspected visually by a human being in order to confirm that the tested behaviour is indeed correct. You may use existing fixtures such as &amp;lt;code&amp;gt;Inkscape::TestWithSvgObjectPairs&amp;lt;/code&amp;gt; for this purpose.&lt;br /&gt;
*If you use separete reference files, ensure they can be visually inspected as well.&lt;br /&gt;
*Try to make your test focused on the tested behaviour by reducing the number of unrelated elements in your test files.&lt;br /&gt;
*Try to make your test robust and independent on implementation details unrelated to the tested behaviour.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122642</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122642"/>
		<updated>2023-12-23T15:53:19Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have '''more of:'''&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality, especially during the release period.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have '''less of:'''&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
*Reliance on time-consuming manual testing;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Code fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Proposed Actions (To Do List)==&lt;br /&gt;
#Set up CMake targets and macros to make it easy to create unit tests.&amp;lt;br/&amp;gt; Currently, all GTest tests link &amp;lt;code&amp;gt;libinkscape_base&amp;lt;/code&amp;gt;, so they are in fact integration tests rather than unit tests. There should be an easy way of explicitly listing one or several cpp files which will be compiled and linked with tests support utilities only (test the functionality '''in isolation'''). Additionally, there needs to be a way to request linking in &amp;lt;code&amp;gt;lib2geom&amp;lt;/code&amp;gt; for functionality that requires it.&lt;br /&gt;
#Ensure all tests run in debug mode so that failed asserts crash them.&lt;br /&gt;
#Create a flag to easily run tests with the sanitizer.  It should be easy to choose whether a given unit or integration test should run with or without &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt;. The long-term goal is to transition all tests to run in sanitized mode, but many would currently fail due to memory leaks. &lt;br /&gt;
#Create a setup to link inkscape with &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt; in the CI pipeline for use in end-to-end tests.  After building object files, link two inkscape executables: one with and one without &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt;. Create a flag to choose which end-to-end test (e.g., CLI test) should run with the sanitizer (aspirationally, all of them, but not long ago even running &amp;lt;code&amp;gt;inkscape --help&amp;lt;/code&amp;gt; leaked memory).&lt;br /&gt;
#Migrate some of the existing tests to unit test framework.  Do not link all of inkscape just to test a single class or collection of functions.&lt;br /&gt;
#Devise a test strategy for the interactions between &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s and their XML representations. For each &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; type, it should be possible to easily write tests that create such object (in isolation or in a test fixture simulating a minimalistic document) from an XML string representation and, likewise, write an XML representation of the object. Unit tests of this kind would characterize and document the properties of XML representations and, with sufficient coverage, can prevent data loss bugs and many undo-related issues.&lt;br /&gt;
#Create fixtures for testing &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; behavior.  It should be possible to create an &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;, perhaps embedding it in a minimalistic document provided by a suitable fixture, and perform specific operations on this object in order to create unit tests for all the different &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
#Write integration tests for document-level interactions.  The goal is to test scenarios where several objects depend on each other: clones, groups, gradients, LPE objects, markers which link to each other by href or another type of reference. Integration tests of this kind (linking the entire libinkscape_base into the test executable) will ensure robust handling of situations such as deletion of dependencies, clipboard operations, undo. When run with the sanitizer, they may catch rare memory corruption bugs.&lt;br /&gt;
#Refactor the LPE system. The LPE system dynamically rewrites the d attribute of an SVG path in order to create an artistic effect. As such, each LPE should be easily testable in principle. Migrate existing end-to-end tests of the LPE system and make them unit tests.  Assumption: making LPEs individually testable will improve the quality of LPE-related code and offer an opportunity to redesign it.&lt;br /&gt;
#Enable test coverage reports in the CI pipeline. This was already done in lib2geom and the extensions repository, so a similar setup should be easy to reproduce.&lt;br /&gt;
#Create more rendering tests. The display system should be tested more rigorously in order to prevent rendering regressions.&lt;br /&gt;
#Automated action-based tests. We could write more tests that execute a sequence of actions, either on a fresh document or on a pre-existing one. Although this could be done with end-to-end CLI-based tests, it is probably easier to have a C++ test fixture with actions called manually or via their string names.&lt;br /&gt;
#Examine the possibility of creating event-injection GUI-tests. If successful, this could save a lot of time currently spent on manual GUI testing. &lt;br /&gt;
#Enhance contribution and code review guidelines with testing-related information&amp;lt;br /&amp;gt; A careful balance has to be struck beween the imperative of enforcing a sufficient test coverage and allowing for contributions from relatively inexperienced community members who may lack the knowledge of good practices related to testing. Guidelines which help educate contributors, in addition to learning from examples (for instance, tests created as a part of items listed above) will ensure that even new contributors can contribute to the QA goals within Inkscape.&amp;lt;br /&amp;gt; &lt;br /&gt;
==Automated testing==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]Inkscape's CI pipeline contains a number of unit, integration and end-to-end tests. However, we recognise that the overal test coverage is '''very poor''' as of late 2023. One of the main goals of this initiative is to track the test coverage and work on gradually increasing it.&lt;br /&gt;
&lt;br /&gt;
In the context of automated tests, we recall the famous Testing Pyramid (see right). It expresses the principle that tests at unit and component level should be the most prevalent ones, followed by a smaller number of integration tests, and topped off with a relatively lower number of end-to-end tests. Unfortunately, this is not the case today: we have too few unit tests. Manual testing should be limited to UX and usability aspects.&lt;br /&gt;
&lt;br /&gt;
===Why does Inkscape not have enough unit tests===&lt;br /&gt;
&lt;br /&gt;
*Historical reasons: feature development was prioritized and testing was never formally enforced.&lt;br /&gt;
*Work on tests and QA topics may be perceived as less newsworthy because it is less visible to the end user.&lt;br /&gt;
*Many new developments interact with and depend on legacy code which is hard to split off and mock. Thus, new code is hard to test.&lt;br /&gt;
*Insufficient tooling such as automated test coverage reports or custom test fixtures to facilitate test development.&lt;br /&gt;
*Varied knowledge level of contributors, some lacking expertise in testing.&lt;br /&gt;
&lt;br /&gt;
===What can be done about it===&lt;br /&gt;
&lt;br /&gt;
*Code review should emphasize the importance of adding unit tests for new functionality and regression tests for bug fixes.&lt;br /&gt;
*Quality and maintainability should be viewed as core aspects and as an important part of Inkscape's development.&lt;br /&gt;
*Legacy code must be managed carefully, see below.&lt;br /&gt;
*Test coverage reports should be introduced along with facilities that make it easy and pleasant to write tests.&lt;br /&gt;
*By increasing the number of tests, we can increase the knowledge and awareness of testing techniques in the community – learning from examples.&lt;br /&gt;
&lt;br /&gt;
==Dealing with legacy code ==&lt;br /&gt;
According to Michael Feathers, the author of the influential book &amp;quot;Working effectively with legacy code&amp;quot;, ''legacy code'' is not defined as &amp;quot;old code&amp;quot;, &amp;quot;code written in C&amp;quot; or in general &amp;quot;code that nobody maintains&amp;quot;. Instead, legacy code is '''code that is''' '''not testable and not tested.''' We recognise that Inkscape contains a lot of such code.&lt;br /&gt;
&lt;br /&gt;
===The Vicious Cycle of Legacy Code===&lt;br /&gt;
The fundamental problem with legacy code is that it's very risky to change it because a small change in one place can have unpredictable and unintended consequences in other places. This has happened many times in Inkscape's history and has led to severe bugs. In an ideal world, the existing code could be first enriched with &amp;quot;characterization tests&amp;quot; that capture its current behaviour, and tests could also be added for the new behaviour. In this way, we could assure that the development works as intended and doesn't break anything. But, according to our definition, legacy code is '''not testable''' so this cannot be done. We don't live in an ideal world!&lt;br /&gt;
&lt;br /&gt;
Thus, we are stuck in a vicious cycle: to make code testable, we need to refactor it in order to make it testable, but refactoring can break things badly unless we have tests, which unfortunately we don't and which cannot be added because the code is not testable.&lt;br /&gt;
&lt;br /&gt;
To break out of this cycle, we need to start small, adding tests to simple and relatively independent pieces of functionality. It is helpful to identify the &amp;quot;seams&amp;quot;, which usually correspond to interfaces, along which the program or a system can be natuarally divided into functional pieces. If these pieces are simple enough, they can be made testable. However, even with this approach, a fair bit of mocking may be required to simulate external dependencies, which makes it a tedious task.&lt;br /&gt;
&lt;br /&gt;
===Refactoring and development techniques to increase testability===&lt;br /&gt;
A large portion of Inkscape's codebase is made up of code that's very literal, low-level and suffers from a lack of abstraction. Oftentimes, such code was developed as a part of a small contributions without architectural goals, focused only on adding a small missing piece of functionality. As contributors come and go, this leaves behind a patchwork of fairly inconsistent solutions. Nonetheless, many parts of Inkscape have seen some notable refactoring efforts aimed at unifying these patchwork solutions. It is however important that future refactoring efforts take testability considerations into account. &lt;br /&gt;
&lt;br /&gt;
Desigining good interfaces and abstractions is an important goal that should be kept in mind not only during major architectural updates, but also our everyday work. Whenever you work on Inkscape, ask yourself the question: &amp;quot;Does this change make the code I'm working on more or less testable?&amp;quot;. Below are some concrete examples of techniques that can help increase testability.&lt;br /&gt;
&lt;br /&gt;
====Extract and mock/override====&lt;br /&gt;
&lt;br /&gt;
*Identify the piece of code that makes the functionality non-testable.&lt;br /&gt;
*Move this piece of code to a separate function(s) or a class. Moving code is safer than rewriting it, because the functional logic is kept unchanged.&lt;br /&gt;
*In tests, mock the class or function that the problematic code was moved to. This lets you test new functionality independently of the legacy code.&lt;br /&gt;
*If you need to extend the functionality provided by the non-testable code, try doing it without touching the untested function, but rather wrap around it or provide an override.&lt;br /&gt;
&lt;br /&gt;
====Decorator pattern====&lt;br /&gt;
This design pattern helps extend a legacy class with new functionality. Instead of adding the new functionality directly to the non-testable class (which would make the new functionality non-testable as well), write a wrapper around the legacy class. In the decorator pattern, the decorator class holds an instance of the wrapped class and provides an interface that forwards member function calls to the wrapped object. However, some of the member functions of the wrapper can provide additional functionality or further work on the values obtained from the wrapped object, which makes it possible to add new behaviours. This new functionality can now be tested by mocking the wrapped class in tests.&lt;br /&gt;
&lt;br /&gt;
====Façade transformation====&lt;br /&gt;
This technique helps when dealing with huge classes that hold too much data and that have too many member functions, making them complex, difficult to test, and increasing the coupling with other parts of the code. The façade transformation replaces the large class with a façade class which internally holds instances of several smaller classes. These smaller classes need to be designed by identifying the functionally cohesive pieces of the original large class and splitting them up. The member functions of the façade delegate to member function calls on these internal instances, sometimes more than one at a time. This transformation can be repeated if needed, until the classes are small enough that testing them is possible. The advantage of the façade transformation is that the API exposed by the large class is unchanged.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing unit tests==&lt;br /&gt;
&lt;br /&gt;
*Create a separate test executable for each class or functional module.&lt;br /&gt;
*Write a separate test case for each of the tested behaviours.&lt;br /&gt;
*Write a doxygen-style comment above each test case, explaining very briefly what this case is testing.&lt;br /&gt;
*In each test case, follow the Arrange-Act-Assert principle:&lt;br /&gt;
**Arrange: create and prepare the data and objects needed to perform the tested operation; set up expectations for mock calls;&lt;br /&gt;
**Act: run the tested operation;&lt;br /&gt;
**Assert: use &amp;lt;code&amp;gt;EXPECT_*&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ASSERT_*&amp;lt;/code&amp;gt; macros from Google Testing library to check that the behaviour is as expected.&lt;br /&gt;
*Remember to test strange and corner cases, invalid input, fallback behaviours.&lt;br /&gt;
*If your test needs custom set-up and tear-down, use a custom test fixture and &amp;lt;code&amp;gt;TEST_F&amp;lt;/code&amp;gt; macros.&lt;br /&gt;
*If your test needs to run on several cases parametrized by input data, consider using a &amp;lt;code&amp;gt;TEST_P&amp;lt;/code&amp;gt; fixture.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing end-to-end tests==&lt;br /&gt;
If you are about to create an end-to-end test, ask yourself first if perhaps a unit test can be written instead. However, in the case of regression tests, it's often good to have end-to-end tests that clearly demonstrate that a bug has been fixed and ensure it is not accidentaly reintroduced. End-to-end tests are also suitable for complex cases involving import and export operations. In many cases (such as display and rendering, utilities, Live Path Effects, SPObject system, anything in lib2geom), unit tests ought to be preferred.&lt;br /&gt;
&lt;br /&gt;
*If you create test files (SVG documents or files in other formats), ensure that the content of the files can be visually inspected.&lt;br /&gt;
*If your test file contains both test objects and reference objects, ensure that the relationship between them can be directly inspected visually by a human being in order to confirm that the tested behaviour is indeed correct. You may use existing fixtures such as &amp;lt;code&amp;gt;Inkscape::TestWithSvgObjectPairs&amp;lt;/code&amp;gt; for this purpose.&lt;br /&gt;
*If you use separete reference files, ensure they can be visually inspected as well.&lt;br /&gt;
*Try to make your test focused on the tested behaviour by reducing the number of unrelated elements in your test files.&lt;br /&gt;
*Try to make your test robust and independent on implementation details unrelated to the tested behaviour.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122641</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122641"/>
		<updated>2023-12-23T15:52:59Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have '''more of:'''&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality, especially during the release period.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have '''less of:'''&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
*Reliance on time-consuming manual testing;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Code fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Proposed Actions (To Do List)==&lt;br /&gt;
#Set up CMake targets and macros to make it easy to create unit tests. Currently, all GTest tests link &amp;lt;code&amp;gt;libinkscape_base&amp;lt;/code&amp;gt;, so they are in fact integration tests rather than unit tests. There should be an easy way of explicitly listing one or several cpp files which will be compiled and linked with tests support utilities only (test the functionality '''in isolation'''). Additionally, there needs to be a way to request linking in &amp;lt;code&amp;gt;lib2geom&amp;lt;/code&amp;gt; for functionality that requires it.&lt;br /&gt;
#Ensure all tests run in debug mode so that failed asserts crash them.&lt;br /&gt;
#Create a flag to easily run tests with the sanitizer.  It should be easy to choose whether a given unit or integration test should run with or without &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt;. The long-term goal is to transition all tests to run in sanitized mode, but many would currently fail due to memory leaks. &lt;br /&gt;
#Create a setup to link inkscape with &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt; in the CI pipeline for use in end-to-end tests.  After building object files, link two inkscape executables: one with and one without &amp;lt;code&amp;gt;libasan&amp;lt;/code&amp;gt;. Create a flag to choose which end-to-end test (e.g., CLI test) should run with the sanitizer (aspirationally, all of them, but not long ago even running &amp;lt;code&amp;gt;inkscape --help&amp;lt;/code&amp;gt; leaked memory).&lt;br /&gt;
#Migrate some of the existing tests to unit test framework.  Do not link all of inkscape just to test a single class or collection of functions.&lt;br /&gt;
#Devise a test strategy for the interactions between &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s and their XML representations. For each &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; type, it should be possible to easily write tests that create such object (in isolation or in a test fixture simulating a minimalistic document) from an XML string representation and, likewise, write an XML representation of the object. Unit tests of this kind would characterize and document the properties of XML representations and, with sufficient coverage, can prevent data loss bugs and many undo-related issues.&lt;br /&gt;
#Create fixtures for testing &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt; behavior.  It should be possible to create an &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;, perhaps embedding it in a minimalistic document provided by a suitable fixture, and perform specific operations on this object in order to create unit tests for all the different &amp;lt;code&amp;gt;SPObject&amp;lt;/code&amp;gt;s.&lt;br /&gt;
#Write integration tests for document-level interactions.  The goal is to test scenarios where several objects depend on each other: clones, groups, gradients, LPE objects, markers which link to each other by href or another type of reference. Integration tests of this kind (linking the entire libinkscape_base into the test executable) will ensure robust handling of situations such as deletion of dependencies, clipboard operations, undo. When run with the sanitizer, they may catch rare memory corruption bugs.&lt;br /&gt;
#Refactor the LPE system. The LPE system dynamically rewrites the d attribute of an SVG path in order to create an artistic effect. As such, each LPE should be easily testable in principle. Migrate existing end-to-end tests of the LPE system and make them unit tests.  Assumption: making LPEs individually testable will improve the quality of LPE-related code and offer an opportunity to redesign it.&lt;br /&gt;
#Enable test coverage reports in the CI pipeline. This was already done in lib2geom and the extensions repository, so a similar setup should be easy to reproduce.&lt;br /&gt;
#Create more rendering tests. The display system should be tested more rigorously in order to prevent rendering regressions.&lt;br /&gt;
#Automated action-based tests. We could write more tests that execute a sequence of actions, either on a fresh document or on a pre-existing one. Although this could be done with end-to-end CLI-based tests, it is probably easier to have a C++ test fixture with actions called manually or via their string names.&lt;br /&gt;
#Examine the possibility of creating event-injection GUI-tests. If successful, this could save a lot of time currently spent on manual GUI testing. &lt;br /&gt;
#Enhance contribution and code review guidelines with testing-related information&amp;lt;br /&amp;gt; A careful balance has to be struck beween the imperative of enforcing a sufficient test coverage and allowing for contributions from relatively inexperienced community members who may lack the knowledge of good practices related to testing. Guidelines which help educate contributors, in addition to learning from examples (for instance, tests created as a part of items listed above) will ensure that even new contributors can contribute to the QA goals within Inkscape.&amp;lt;br /&amp;gt; &lt;br /&gt;
==Automated testing==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]Inkscape's CI pipeline contains a number of unit, integration and end-to-end tests. However, we recognise that the overal test coverage is '''very poor''' as of late 2023. One of the main goals of this initiative is to track the test coverage and work on gradually increasing it.&lt;br /&gt;
&lt;br /&gt;
In the context of automated tests, we recall the famous Testing Pyramid (see right). It expresses the principle that tests at unit and component level should be the most prevalent ones, followed by a smaller number of integration tests, and topped off with a relatively lower number of end-to-end tests. Unfortunately, this is not the case today: we have too few unit tests. Manual testing should be limited to UX and usability aspects.&lt;br /&gt;
&lt;br /&gt;
===Why does Inkscape not have enough unit tests===&lt;br /&gt;
&lt;br /&gt;
*Historical reasons: feature development was prioritized and testing was never formally enforced.&lt;br /&gt;
*Work on tests and QA topics may be perceived as less newsworthy because it is less visible to the end user.&lt;br /&gt;
*Many new developments interact with and depend on legacy code which is hard to split off and mock. Thus, new code is hard to test.&lt;br /&gt;
*Insufficient tooling such as automated test coverage reports or custom test fixtures to facilitate test development.&lt;br /&gt;
*Varied knowledge level of contributors, some lacking expertise in testing.&lt;br /&gt;
&lt;br /&gt;
===What can be done about it===&lt;br /&gt;
&lt;br /&gt;
*Code review should emphasize the importance of adding unit tests for new functionality and regression tests for bug fixes.&lt;br /&gt;
*Quality and maintainability should be viewed as core aspects and as an important part of Inkscape's development.&lt;br /&gt;
*Legacy code must be managed carefully, see below.&lt;br /&gt;
*Test coverage reports should be introduced along with facilities that make it easy and pleasant to write tests.&lt;br /&gt;
*By increasing the number of tests, we can increase the knowledge and awareness of testing techniques in the community – learning from examples.&lt;br /&gt;
&lt;br /&gt;
==Dealing with legacy code ==&lt;br /&gt;
According to Michael Feathers, the author of the influential book &amp;quot;Working effectively with legacy code&amp;quot;, ''legacy code'' is not defined as &amp;quot;old code&amp;quot;, &amp;quot;code written in C&amp;quot; or in general &amp;quot;code that nobody maintains&amp;quot;. Instead, legacy code is '''code that is''' '''not testable and not tested.''' We recognise that Inkscape contains a lot of such code.&lt;br /&gt;
&lt;br /&gt;
===The Vicious Cycle of Legacy Code===&lt;br /&gt;
The fundamental problem with legacy code is that it's very risky to change it because a small change in one place can have unpredictable and unintended consequences in other places. This has happened many times in Inkscape's history and has led to severe bugs. In an ideal world, the existing code could be first enriched with &amp;quot;characterization tests&amp;quot; that capture its current behaviour, and tests could also be added for the new behaviour. In this way, we could assure that the development works as intended and doesn't break anything. But, according to our definition, legacy code is '''not testable''' so this cannot be done. We don't live in an ideal world!&lt;br /&gt;
&lt;br /&gt;
Thus, we are stuck in a vicious cycle: to make code testable, we need to refactor it in order to make it testable, but refactoring can break things badly unless we have tests, which unfortunately we don't and which cannot be added because the code is not testable.&lt;br /&gt;
&lt;br /&gt;
To break out of this cycle, we need to start small, adding tests to simple and relatively independent pieces of functionality. It is helpful to identify the &amp;quot;seams&amp;quot;, which usually correspond to interfaces, along which the program or a system can be natuarally divided into functional pieces. If these pieces are simple enough, they can be made testable. However, even with this approach, a fair bit of mocking may be required to simulate external dependencies, which makes it a tedious task.&lt;br /&gt;
&lt;br /&gt;
===Refactoring and development techniques to increase testability===&lt;br /&gt;
A large portion of Inkscape's codebase is made up of code that's very literal, low-level and suffers from a lack of abstraction. Oftentimes, such code was developed as a part of a small contributions without architectural goals, focused only on adding a small missing piece of functionality. As contributors come and go, this leaves behind a patchwork of fairly inconsistent solutions. Nonetheless, many parts of Inkscape have seen some notable refactoring efforts aimed at unifying these patchwork solutions. It is however important that future refactoring efforts take testability considerations into account. &lt;br /&gt;
&lt;br /&gt;
Desigining good interfaces and abstractions is an important goal that should be kept in mind not only during major architectural updates, but also our everyday work. Whenever you work on Inkscape, ask yourself the question: &amp;quot;Does this change make the code I'm working on more or less testable?&amp;quot;. Below are some concrete examples of techniques that can help increase testability.&lt;br /&gt;
&lt;br /&gt;
====Extract and mock/override====&lt;br /&gt;
&lt;br /&gt;
*Identify the piece of code that makes the functionality non-testable.&lt;br /&gt;
*Move this piece of code to a separate function(s) or a class. Moving code is safer than rewriting it, because the functional logic is kept unchanged.&lt;br /&gt;
*In tests, mock the class or function that the problematic code was moved to. This lets you test new functionality independently of the legacy code.&lt;br /&gt;
*If you need to extend the functionality provided by the non-testable code, try doing it without touching the untested function, but rather wrap around it or provide an override.&lt;br /&gt;
&lt;br /&gt;
====Decorator pattern====&lt;br /&gt;
This design pattern helps extend a legacy class with new functionality. Instead of adding the new functionality directly to the non-testable class (which would make the new functionality non-testable as well), write a wrapper around the legacy class. In the decorator pattern, the decorator class holds an instance of the wrapped class and provides an interface that forwards member function calls to the wrapped object. However, some of the member functions of the wrapper can provide additional functionality or further work on the values obtained from the wrapped object, which makes it possible to add new behaviours. This new functionality can now be tested by mocking the wrapped class in tests.&lt;br /&gt;
&lt;br /&gt;
====Façade transformation====&lt;br /&gt;
This technique helps when dealing with huge classes that hold too much data and that have too many member functions, making them complex, difficult to test, and increasing the coupling with other parts of the code. The façade transformation replaces the large class with a façade class which internally holds instances of several smaller classes. These smaller classes need to be designed by identifying the functionally cohesive pieces of the original large class and splitting them up. The member functions of the façade delegate to member function calls on these internal instances, sometimes more than one at a time. This transformation can be repeated if needed, until the classes are small enough that testing them is possible. The advantage of the façade transformation is that the API exposed by the large class is unchanged.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing unit tests==&lt;br /&gt;
&lt;br /&gt;
*Create a separate test executable for each class or functional module.&lt;br /&gt;
*Write a separate test case for each of the tested behaviours.&lt;br /&gt;
*Write a doxygen-style comment above each test case, explaining very briefly what this case is testing.&lt;br /&gt;
*In each test case, follow the Arrange-Act-Assert principle:&lt;br /&gt;
**Arrange: create and prepare the data and objects needed to perform the tested operation; set up expectations for mock calls;&lt;br /&gt;
**Act: run the tested operation;&lt;br /&gt;
**Assert: use &amp;lt;code&amp;gt;EXPECT_*&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ASSERT_*&amp;lt;/code&amp;gt; macros from Google Testing library to check that the behaviour is as expected.&lt;br /&gt;
*Remember to test strange and corner cases, invalid input, fallback behaviours.&lt;br /&gt;
*If your test needs custom set-up and tear-down, use a custom test fixture and &amp;lt;code&amp;gt;TEST_F&amp;lt;/code&amp;gt; macros.&lt;br /&gt;
*If your test needs to run on several cases parametrized by input data, consider using a &amp;lt;code&amp;gt;TEST_P&amp;lt;/code&amp;gt; fixture.&lt;br /&gt;
&lt;br /&gt;
==Guidelines on writing end-to-end tests==&lt;br /&gt;
If you are about to create an end-to-end test, ask yourself first if perhaps a unit test can be written instead. However, in the case of regression tests, it's often good to have end-to-end tests that clearly demonstrate that a bug has been fixed and ensure it is not accidentaly reintroduced. End-to-end tests are also suitable for complex cases involving import and export operations. In many cases (such as display and rendering, utilities, Live Path Effects, SPObject system, anything in lib2geom), unit tests ought to be preferred.&lt;br /&gt;
&lt;br /&gt;
*If you create test files (SVG documents or files in other formats), ensure that the content of the files can be visually inspected.&lt;br /&gt;
*If your test file contains both test objects and reference objects, ensure that the relationship between them can be directly inspected visually by a human being in order to confirm that the tested behaviour is indeed correct. You may use existing fixtures such as &amp;lt;code&amp;gt;Inkscape::TestWithSvgObjectPairs&amp;lt;/code&amp;gt; for this purpose.&lt;br /&gt;
*If you use separete reference files, ensure they can be visually inspected as well.&lt;br /&gt;
*Try to make your test focused on the tested behaviour by reducing the number of unrelated elements in your test files.&lt;br /&gt;
*Try to make your test robust and independent on implementation details unrelated to the tested behaviour.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122640</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122640"/>
		<updated>2023-12-17T18:26:14Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have '''more of:'''&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality, especially during the release period.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have '''less of:'''&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
*Reliance on time-consuming manual testing;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Code fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Action plan ==&lt;br /&gt;
TO DO.&lt;br /&gt;
&lt;br /&gt;
== Automated testing ==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]Inkscape's CI pipeline contains a number of unit, integration and end-to-end tests. However, we recognise that the overal test coverage is '''very poor''' as of late 2023. One of the main goals of this initiative is to track the test coverage and work on gradually increasing it.&lt;br /&gt;
&lt;br /&gt;
In the context of automated tests, we recall the famous Testing Pyramid (see right). It expresses the principle that tests at unit and component level should be the most prevalent ones, followed by a smaller number of integration tests, and topped off with a relatively lower number of end-to-end tests. Unfortunately, this is not the case today: we have too few unit tests. Manual testing should be limited to UX and usability aspects.&lt;br /&gt;
&lt;br /&gt;
=== Why does Inkscape not have enough unit tests ===&lt;br /&gt;
&lt;br /&gt;
* Historical reasons: feature development was prioritized and testing was never formally enforced.&lt;br /&gt;
* Work on tests and QA topics may be perceived as less newsworthy because it is less visible to the end user.&lt;br /&gt;
* Many new developments interact with and depend on legacy code which is hard to split off and mock. Thus, new code is hard to test.&lt;br /&gt;
* Insufficient tooling such as automated test coverage reports or custom test fixtures to facilitate test development.&lt;br /&gt;
* Varied knowledge level of contributors, some lacking expertise in testing.&lt;br /&gt;
&lt;br /&gt;
=== What can be done about it ===&lt;br /&gt;
&lt;br /&gt;
* Code review should emphasize the importance of adding unit tests for new functionality and regression tests for bug fixes.&lt;br /&gt;
* Quality and maintainability should be viewed as core aspects and as an important part of Inkscape's development.&lt;br /&gt;
* Legacy code must be managed carefully, see below.&lt;br /&gt;
* Test coverage reports should be introduced along with facilities that make it easy and pleasant to write tests.&lt;br /&gt;
* By increasing the number of tests, we can increase the knowledge and awareness of testing techniques in the community – learning from examples.&lt;br /&gt;
&lt;br /&gt;
== Dealing with legacy code ==&lt;br /&gt;
According to Michael Feathers, the author of the influential book &amp;quot;Working effectively with legacy code&amp;quot;, ''legacy code'' is not defined as &amp;quot;old code&amp;quot;, &amp;quot;code written in C&amp;quot; or in general &amp;quot;code that nobody maintains&amp;quot;. Instead, legacy code is '''code that is''' '''not testable and not tested.''' We recognise that Inkscape contains a lot of such code.&lt;br /&gt;
&lt;br /&gt;
=== The Vicious Cycle of Legacy Code ===&lt;br /&gt;
The fundamental problem with legacy code is that it's very risky to change it because a small change in one place can have unpredictable and unintended consequences in other places. This has happened many times in Inkscape's history and has led to severe bugs. In an ideal world, the existing code could be first enriched with &amp;quot;characterization tests&amp;quot; that capture its current behaviour, and tests could also be added for the new behaviour. In this way, we could assure that the development works as intended and doesn't break anything. But, according to our definition, legacy code is '''not testable''' so this cannot be done. We don't live in an ideal world!&lt;br /&gt;
&lt;br /&gt;
Thus, we are stuck in a vicious cycle: to make code testable, we need to refactor it in order to make it testable, but refactoring can break things badly unless we have tests, which unfortunately we don't and which cannot be added because the code is not testable.&lt;br /&gt;
&lt;br /&gt;
To break out of this cycle, we need to start small, adding tests to simple and relatively independent pieces of functionality. It is helpful to identify the &amp;quot;seams&amp;quot;, which usually correspond to interfaces, along which the program or a system can be natuarally divided into functional pieces. If these pieces are simple enough, they can be made testable. However, even with this approach, a fair bit of mocking may be required to simulate external dependencies, which makes it a tedious task.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring and development techniques to increase testability ===&lt;br /&gt;
A large portion of Inkscape's codebase is made up of code that's very literal, low-level and suffers from a lack of abstraction. Oftentimes, such code was developed as a part of a small contributions without architectural goals, focused only on adding a small missing piece of functionality. As contributors come and go, this leaves behind a patchwork of fairly inconsistent solutions. Nonetheless, many parts of Inkscape have seen some notable refactoring efforts aimed at unifying these patchwork solutions. It is however important that future refactoring efforts take testability considerations into account. &lt;br /&gt;
&lt;br /&gt;
Desigining good interfaces and abstractions is an important goal that should be kept in mind not only during major architectural updates, but also our everyday work. Whenever you work on Inkscape, ask yourself the question: &amp;quot;Does this change make the code I'm working on more or less testable?&amp;quot;. Below are some concrete examples of techniques that can help increase testability.&lt;br /&gt;
&lt;br /&gt;
==== Extract and mock/override ====&lt;br /&gt;
&lt;br /&gt;
* Identify the piece of code that makes the functionality non-testable.&lt;br /&gt;
* Move this piece of code to a separate function(s) or a class. Moving code is safer than rewriting it, because the functional logic is kept unchanged.&lt;br /&gt;
* In tests, mock the class or function that the problematic code was moved to. This lets you test new functionality independently of the legacy code.&lt;br /&gt;
* If you need to extend the functionality provided by the non-testable code, try doing it without touching the untested function, but rather wrap around it or provide an override.&lt;br /&gt;
&lt;br /&gt;
==== Decorator pattern ====&lt;br /&gt;
This design pattern helps extend a legacy class with new functionality. Instead of adding the new functionality directly to the non-testable class (which would make the new functionality non-testable as well), write a wrapper around the legacy class. In the decorator pattern, the decorator class holds an instance of the wrapped class and provides an interface that forwards member function calls to the wrapped object. However, some of the member functions of the wrapper can provide additional functionality or further work on the values obtained from the wrapped object, which makes it possible to add new behaviours. This new functionality can now be tested by mocking the wrapped class in tests.&lt;br /&gt;
&lt;br /&gt;
==== Façade transformation ====&lt;br /&gt;
This technique helps when dealing with huge classes that hold too much data and that have too many member functions, making them complex, difficult to test, and increasing the coupling with other parts of the code. The façade transformation replaces the large class with a façade class which internally holds instances of several smaller classes. These smaller classes need to be designed by identifying the functionally cohesive pieces of the original large class and splitting them up. The member functions of the façade delegate to member function calls on these internal instances, sometimes more than one at a time. This transformation can be repeated if needed, until the classes are small enough that testing them is possible. The advantage of the façade transformation is that the API exposed by the large class is unchanged.&lt;br /&gt;
&lt;br /&gt;
== Guidelines on writing unit tests ==&lt;br /&gt;
&lt;br /&gt;
* Create a separate test executable for each class or functional module.&lt;br /&gt;
* Write a separate test case for each of the tested behaviours.&lt;br /&gt;
* Write a doxygen-style comment above each test case, explaining very briefly what this case is testing.&lt;br /&gt;
* In each test case, follow the Arrange-Act-Assert principle:&lt;br /&gt;
** Arrange: create and prepare the data and objects needed to perform the tested operation; set up expectations for mock calls;&lt;br /&gt;
** Act: run the tested operation;&lt;br /&gt;
** Assert: use &amp;lt;code&amp;gt;EXPECT_*&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ASSERT_*&amp;lt;/code&amp;gt; macros from Google Testing library to check that the behaviour is as expected.&lt;br /&gt;
* Remember to test strange and corner cases, invalid input, fallback behaviours.&lt;br /&gt;
* If your test needs custom set-up and tear-down, use a custom test fixture and &amp;lt;code&amp;gt;TEST_F&amp;lt;/code&amp;gt; macros.&lt;br /&gt;
* If your test needs to run on several cases parametrized by input data, consider using a &amp;lt;code&amp;gt;TEST_P&amp;lt;/code&amp;gt; fixture.&lt;br /&gt;
&lt;br /&gt;
== Guidelines on writing end-to-end tests ==&lt;br /&gt;
If you are about to create an end-to-end test, ask yourself first if perhaps a unit test can be written instead. However, in the case of regression tests, it's often good to have end-to-end tests that clearly demonstrate that a bug has been fixed and ensure it is not accidentaly reintroduced. End-to-end tests are also suitable for complex cases involving import and export operations. In many cases (such as display and rendering, utilities, Live Path Effects, SPObject system, anything in lib2geom), unit tests ought to be preferred.&lt;br /&gt;
&lt;br /&gt;
* If you create test files (SVG documents or files in other formats), ensure that the content of the files can be visually inspected.&lt;br /&gt;
* If your test file contains both test objects and reference objects, ensure that the relationship between them can be directly inspected visually by a human being in order to confirm that the tested behaviour is indeed correct. You may use existing fixtures such as &amp;lt;code&amp;gt;Inkscape::TestWithSvgObjectPairs&amp;lt;/code&amp;gt; for this purpose.&lt;br /&gt;
* If you use separete reference files, ensure they can be visually inspected as well.&lt;br /&gt;
*Try to make your test focused on the tested behaviour by reducing the number of unrelated elements in your test files.&lt;br /&gt;
*Try to make your test robust and independent on implementation details unrelated to the tested behaviour.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122639</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122639"/>
		<updated>2023-12-17T18:25:45Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Stub}}&lt;br /&gt;
&lt;br /&gt;
This page is a work in progress (2023-12-16).&lt;br /&gt;
&lt;br /&gt;
The Quality Assurance Initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have '''more of:'''&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality, especially during the release period.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have '''less of:'''&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
*Reliance on time-consuming manual testing;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Code fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Action plan ==&lt;br /&gt;
TO DO.&lt;br /&gt;
&lt;br /&gt;
== Automated testing ==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]Inkscape's CI pipeline contains a number of unit, integration and end-to-end tests. However, we recognise that the overal test coverage is '''very poor''' as of late 2023. One of the main goals of this initiative is to track the test coverage and work on gradually increasing it.&lt;br /&gt;
&lt;br /&gt;
In the context of automated tests, we recall the famous Testing Pyramid (see right). It expresses the principle that tests at unit and component level should be the most prevalent ones, followed by a smaller number of integration tests, and topped off with a relatively lower number of end-to-end tests. Unfortunately, this is not the case today: we have too few unit tests. Manual testing should be limited to UX and usability aspects.&lt;br /&gt;
&lt;br /&gt;
=== Why does Inkscape not have enough unit tests ===&lt;br /&gt;
&lt;br /&gt;
* Historical reasons: feature development was prioritized and testing was never formally enforced.&lt;br /&gt;
* Work on tests and QA topics may be perceived as less newsworthy because it is less visible to the end user.&lt;br /&gt;
* Many new developments interact with and depend on legacy code which is hard to split off and mock. Thus, new code is hard to test.&lt;br /&gt;
* Insufficient tooling such as automated test coverage reports or custom test fixtures to facilitate test development.&lt;br /&gt;
* Varied knowledge level of contributors, some lacking expertise in testing.&lt;br /&gt;
&lt;br /&gt;
=== What can be done about it ===&lt;br /&gt;
&lt;br /&gt;
* Code review should emphasize the importance of adding unit tests for new functionality and regression tests for bug fixes.&lt;br /&gt;
* Quality and maintainability should be viewed as core aspects and as an important part of Inkscape's development.&lt;br /&gt;
* Legacy code must be managed carefully, see below.&lt;br /&gt;
* Test coverage reports should be introduced along with facilities that make it easy and pleasant to write tests.&lt;br /&gt;
* By increasing the number of tests, we can increase the knowledge and awareness of testing techniques in the community – learning from examples.&lt;br /&gt;
&lt;br /&gt;
== Dealing with legacy code ==&lt;br /&gt;
According to Michael Feathers, the author of the influential book &amp;quot;Working effectively with legacy code&amp;quot;, ''legacy code'' is not defined as &amp;quot;old code&amp;quot;, &amp;quot;code written in C&amp;quot; or in general &amp;quot;code that nobody maintains&amp;quot;. Instead, legacy code is '''code that is''' '''not testable and not tested.''' We recognise that Inkscape contains a lot of such code.&lt;br /&gt;
&lt;br /&gt;
=== The Vicious Cycle of Legacy Code ===&lt;br /&gt;
The fundamental problem with legacy code is that it's very risky to change it because a small change in one place can have unpredictable and unintended consequences in other places. This has happened many times in Inkscape's history and has led to severe bugs. In an ideal world, the existing code could be first enriched with &amp;quot;characterization tests&amp;quot; that capture its current behaviour, and tests could also be added for the new behaviour. In this way, we could assure that the development works as intended and doesn't break anything. But, according to our definition, legacy code is '''not testable''' so this cannot be done. We don't live in an ideal world!&lt;br /&gt;
&lt;br /&gt;
Thus, we are stuck in a vicious cycle: to make code testable, we need to refactor it in order to make it testable, but refactoring can break things badly unless we have tests, which unfortunately we don't and which cannot be added because the code is not testable.&lt;br /&gt;
&lt;br /&gt;
To break out of this cycle, we need to start small, adding tests to simple and relatively independent pieces of functionality. It is helpful to identify the &amp;quot;seams&amp;quot;, which usually correspond to interfaces, along which the program or a system can be natuarally divided into functional pieces. If these pieces are simple enough, they can be made testable. However, even with this approach, a fair bit of mocking may be required to simulate external dependencies, which makes it a tedious task.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring and development techniques to increase testability ===&lt;br /&gt;
A large portion of Inkscape's codebase is made up of code that's very literal, low-level and suffers from a lack of abstraction. Oftentimes, such code was developed as a part of a small contributions without architectural goals, focused only on adding a small missing piece of functionality. As contributors come and go, this leaves behind a patchwork of fairly inconsistent solutions. Nonetheless, many parts of Inkscape have seen some notable refactoring efforts aimed at unifying these patchwork solutions. It is however important that future refactoring efforts take testability considerations into account. &lt;br /&gt;
&lt;br /&gt;
Desigining good interfaces and abstractions is an important goal that should be kept in mind not only during major architectural updates, but also our everyday work. Whenever you work on Inkscape, ask yourself the question: &amp;quot;Does this change make the code I'm working on more or less testable?&amp;quot;. Below are some concrete examples of techniques that can help increase testability.&lt;br /&gt;
&lt;br /&gt;
==== Extract and mock/override ====&lt;br /&gt;
&lt;br /&gt;
* Identify the piece of code that makes the functionality non-testable.&lt;br /&gt;
* Move this piece of code to a separate function(s) or a class. Moving code is safer than rewriting it, because the functional logic is kept unchanged.&lt;br /&gt;
* In tests, mock the class or function that the problematic code was moved to. This lets you test new functionality independently of the legacy code.&lt;br /&gt;
* If you need to extend the functionality provided by the non-testable code, try doing it without touching the untested function, but rather wrap around it or provide an override.&lt;br /&gt;
&lt;br /&gt;
==== Decorator pattern ====&lt;br /&gt;
This design pattern helps extend a legacy class with new functionality. Instead of adding the new functionality directly to the non-testable class (which would make the new functionality non-testable as well), write a wrapper around the legacy class. In the decorator pattern, the decorator class holds an instance of the wrapped class and provides an interface that forwards member function calls to the wrapped object. However, some of the member functions of the wrapper can provide additional functionality or further work on the values obtained from the wrapped object, which makes it possible to add new behaviours. This new functionality can now be tested by mocking the wrapped class in tests.&lt;br /&gt;
&lt;br /&gt;
==== Façade transformation ====&lt;br /&gt;
This technique helps when dealing with huge classes that hold too much data and that have too many member functions, making them complex, difficult to test, and increasing the coupling with other parts of the code. The façade transformation replaces the large class with a façade class which internally holds instances of several smaller classes. These smaller classes need to be designed by identifying the functionally cohesive pieces of the original large class and splitting them up. The member functions of the façade delegate to member function calls on these internal instances, sometimes more than one at a time. This transformation can be repeated if needed, until the classes are small enough that testing them is possible. The advantage of the façade transformation is that the API exposed by the large class is unchanged.&lt;br /&gt;
&lt;br /&gt;
== Guidelines on writing unit tests ==&lt;br /&gt;
&lt;br /&gt;
* Create a separate test executable for each class or functional module.&lt;br /&gt;
* Write a separate test case for each of the tested behaviours.&lt;br /&gt;
* Write a doxygen-style comment above each test case, explaining very briefly what this case is testing.&lt;br /&gt;
* In each test case, follow the Arrange-Act-Assert principle:&lt;br /&gt;
** Arrange: create and prepare the data and objects needed to perform the tested operation; set up expectations for mock calls;&lt;br /&gt;
** Act: run the tested operation;&lt;br /&gt;
** Assert: use &amp;lt;code&amp;gt;EXPECT_*&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ASSERT_*&amp;lt;/code&amp;gt; macros from Google Testing library to check that the behaviour is as expected.&lt;br /&gt;
* Remember to test strange and corner cases, invalid input, fallback behaviours.&lt;br /&gt;
* If your test needs custom set-up and tear-down, use a custom test fixture and &amp;lt;code&amp;gt;TEST_F&amp;lt;/code&amp;gt; macros.&lt;br /&gt;
* If your test needs to run on several cases parametrized by input data, consider using a &amp;lt;code&amp;gt;TEST_P&amp;lt;/code&amp;gt; fixture.&lt;br /&gt;
&lt;br /&gt;
== Guidelines on writing end-to-end tests ==&lt;br /&gt;
If you are about to create an end-to-end test, ask yourself first if perhaps a unit test can be written instead. However, in the case of regression tests, it's often good to have end-to-end tests that clearly demonstrate that a bug has been fixed and ensure it is not accidentaly reintroduced. End-to-end tests are also suitable for complex cases involving import and export operations. In many cases (such as display and rendering, utilities, Live Path Effects, SPObject system, anything in lib2geom), unit tests ought to be preferred.&lt;br /&gt;
&lt;br /&gt;
* If you create test files (SVG documents or files in other formats), ensure that the content of the files can be visually inspected.&lt;br /&gt;
* If your test file contains both test objects and reference objects, ensure that the relationship between them can be directly inspected visually by a human being in order to confirm that the tested behaviour is indeed correct. You may use existing fixtures such as &amp;lt;code&amp;gt;Inkscape::TestWithSvgObjectPairs&amp;lt;/code&amp;gt; for this purpose.&lt;br /&gt;
* If you use separete reference files, ensure they can be visually inspected as well.&lt;br /&gt;
*Try to make your test focused on the tested behaviour by reducing the number of unrelated elements in your test files.&lt;br /&gt;
*Try to make your test robust and independent on implementation details unrelated to the tested behaviour.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122638</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122638"/>
		<updated>2023-12-17T18:20:31Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Stub}}&lt;br /&gt;
&lt;br /&gt;
This page is a work in progress (2023-12-16).&lt;br /&gt;
&lt;br /&gt;
The Quality Assurance Initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have '''more of:'''&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality, especially during the release period.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have '''less of:'''&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
*Reliance on time-consuming manual testing;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Code fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Automated testing ==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]Inkscape's CI pipeline contains a number of unit, integration and end-to-end tests. However, we recognise that the overal test coverage is '''very poor''' as of late 2023. One of the main goals of this initiative is to track the test coverage and work on gradually increasing it.&lt;br /&gt;
&lt;br /&gt;
In the context of automated tests, we recall the famous Testing Pyramid (see right). It expresses the principle that tests at unit and component level should be the most prevalent ones, followed by a smaller number of integration tests, and topped off with a relatively lower number of end-to-end tests. Unfortunately, this is not the case today: we have too few unit tests. Manual testing should be limited to UX and usability aspects.&lt;br /&gt;
&lt;br /&gt;
=== Why does Inkscape not have enough unit tests ===&lt;br /&gt;
&lt;br /&gt;
* Historical reasons: feature development was prioritized and testing was never formally enforced.&lt;br /&gt;
* Work on tests and QA topics may be perceived as less newsworthy because it is less visible to the end user.&lt;br /&gt;
* Many new developments interact with and depend on legacy code which is hard to split off and mock. Thus, new code is hard to test.&lt;br /&gt;
* Insufficient tooling such as automated test coverage reports or custom test fixtures to facilitate test development.&lt;br /&gt;
* Varied knowledge level of contributors, some lacking expertise in testing.&lt;br /&gt;
&lt;br /&gt;
=== What can be done about it ===&lt;br /&gt;
&lt;br /&gt;
* Code review should emphasize the importance of adding unit tests for new functionality and regression tests for bug fixes.&lt;br /&gt;
* Quality and maintainability should be viewed as core aspects and as an important part of Inkscape's development.&lt;br /&gt;
* Legacy code must be managed carefully, see below.&lt;br /&gt;
* Test coverage reports should be introduced along with facilities that make it easy and pleasant to write tests.&lt;br /&gt;
* By increasing the number of tests, we can increase the knowledge and awareness of testing techniques in the community – learning from examples.&lt;br /&gt;
&lt;br /&gt;
== Dealing with legacy code ==&lt;br /&gt;
According to Michael Feathers, the author of the influential book &amp;quot;Working effectively with legacy code&amp;quot;, ''legacy code'' is not defined as &amp;quot;old code&amp;quot;, &amp;quot;code written in C&amp;quot; or in general &amp;quot;code that nobody maintains&amp;quot;. Instead, legacy code is '''code that is''' '''not testable and not tested.''' We recognise that Inkscape contains a lot of such code.&lt;br /&gt;
&lt;br /&gt;
=== The Vicious Cycle of Legacy Code ===&lt;br /&gt;
The fundamental problem with legacy code is that it's very risky to change it because a small change in one place can have unpredictable and unintended consequences in other places. This has happened many times in Inkscape's history and has led to severe bugs. In an ideal world, the existing code could be first enriched with &amp;quot;characterization tests&amp;quot; that capture its current behaviour, and tests could also be added for the new behaviour. In this way, we could assure that the development works as intended and doesn't break anything. But, according to our definition, legacy code is '''not testable''' so this cannot be done. We don't live in an ideal world!&lt;br /&gt;
&lt;br /&gt;
Thus, we are stuck in a vicious cycle: to make code testable, we need to refactor it in order to make it testable, but refactoring can break things badly unless we have tests, which unfortunately we don't and which cannot be added because the code is not testable.&lt;br /&gt;
&lt;br /&gt;
To break out of this cycle, we need to start small, adding tests to simple and relatively independent pieces of functionality. It is helpful to identify the &amp;quot;seams&amp;quot;, which usually correspond to interfaces, along which the program or a system can be natuarally divided into functional pieces. If these pieces are simple enough, they can be made testable. However, even with this approach, a fair bit of mocking may be required to simulate external dependencies, which makes it a tedious task.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring and development techniques to increase testability ===&lt;br /&gt;
A large portion of Inkscape's codebase is made up of code that's very literal, low-level and suffers from a lack of abstraction. Oftentimes, such code was developed as a part of a small contributions without architectural goals, focused only on adding a small missing piece of functionality. As contributors come and go, this leaves behind a patchwork of fairly inconsistent solutions. Nonetheless, many parts of Inkscape have seen some notable refactoring efforts aimed at unifying these patchwork solutions. It is however important that future refactoring efforts take testability considerations into account. &lt;br /&gt;
&lt;br /&gt;
Desigining good interfaces and abstractions is an important goal that should be kept in mind not only during major architectural updates, but also our everyday work. Whenever you work on Inkscape, ask yourself the question: &amp;quot;Does this change make the code I'm working on more or less testable?&amp;quot;. Below are some concrete examples of techniques that can help increase testability.&lt;br /&gt;
&lt;br /&gt;
==== Extract and mock/override ====&lt;br /&gt;
&lt;br /&gt;
* Identify the piece of code that makes the functionality non-testable.&lt;br /&gt;
* Move this piece of code to a separate function(s) or a class. Moving code is safer than rewriting it, because the functional logic is kept unchanged.&lt;br /&gt;
* In tests, mock the class or function that the problematic code was moved to. This lets you test new functionality independently of the legacy code.&lt;br /&gt;
* If you need to extend the functionality provided by the non-testable code, try doing it without touching the untested function, but rather wrap around it or provide an override.&lt;br /&gt;
&lt;br /&gt;
==== Decorator pattern ====&lt;br /&gt;
This design pattern helps extend a legacy class with new functionality. Instead of adding the new functionality directly to the non-testable class (which would make the new functionality non-testable as well), write a wrapper around the legacy class. In the decorator pattern, the decorator class holds an instance of the wrapped class and provides an interface that forwards member function calls to the wrapped object. However, some of the member functions of the wrapper can provide additional functionality or further work on the values obtained from the wrapped object, which makes it possible to add new behaviours. This new functionality can now be tested by mocking the wrapped class in tests.&lt;br /&gt;
&lt;br /&gt;
==== Façade transformation ====&lt;br /&gt;
This technique helps when dealing with huge classes that hold too much data and that have too many member functions, making them complex, difficult to test, and increasing the coupling with other parts of the code. The façade transformation replaces the large class with a façade class which internally holds instances of several smaller classes. These smaller classes need to be designed by identifying the functionally cohesive pieces of the original large class and splitting them up. The member functions of the façade delegate to member function calls on these internal instances, sometimes more than one at a time. This transformation can be repeated if needed, until the classes are small enough that testing them is possible. The advantage of the façade transformation is that the API exposed by the large class is unchanged.&lt;br /&gt;
&lt;br /&gt;
== Guidelines on writing unit tests ==&lt;br /&gt;
&lt;br /&gt;
* Create a separate test executable for each class or functional module.&lt;br /&gt;
* Write a separate test case for each of the tested behaviours.&lt;br /&gt;
* Write a doxygen-style comment above each test case, explaining very briefly what this case is testing.&lt;br /&gt;
* In each test case, follow the Arrange-Act-Assert principle:&lt;br /&gt;
** Arrange: create and prepare the data and objects needed to perform the tested operation; set up expectations for mock calls;&lt;br /&gt;
** Act: run the tested operation;&lt;br /&gt;
** Assert: use &amp;lt;code&amp;gt;EXPECT_*&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ASSERT_*&amp;lt;/code&amp;gt; macros from Google Testing library to check that the behaviour is as expected.&lt;br /&gt;
* Remember to test strange and corner cases, invalid input, fallback behaviours.&lt;br /&gt;
* If your test needs custom set-up and tear-down, use a custom test fixture and &amp;lt;code&amp;gt;TEST_F&amp;lt;/code&amp;gt; macros.&lt;br /&gt;
* If your test needs to run on several cases parametrized by input data, consider using a &amp;lt;code&amp;gt;TEST_P&amp;lt;/code&amp;gt; fixture.&lt;br /&gt;
Guidelines on writing end-to-end tests&lt;br /&gt;
&lt;br /&gt;
If you are about to create an end-to-end test, ask yourself first if perhaps a unit test can be written instead. In case of regression tests, it's often good to have end-to-end tests and they are also suitable for complex cases involving import and export operations. However, in many cases (such as Live Path Effects, SPObject system, anything in lib2geom), unit tests ought to be preferred.&lt;br /&gt;
&lt;br /&gt;
* If you create test files (SVG documents or files in other formats), ensure that the content of the files can be visually inspected.&lt;br /&gt;
* If your test file contains both test objects and reference objects, ensure that the relationship between them can be directly inspected visually by a human being in order to confirm that the tested behaviour is indeed correct.  You may use existing fixtures such as &amp;lt;code&amp;gt;Inkscape::TestWithSvgObjectPairs&amp;lt;/code&amp;gt; for this purpose.&lt;br /&gt;
* If you use separete reference files, ensure they can be visually inspected as well.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122637</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122637"/>
		<updated>2023-12-17T17:55:16Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Stub}}&lt;br /&gt;
&lt;br /&gt;
This page is a work in progress (2023-12-16).&lt;br /&gt;
&lt;br /&gt;
The Quality Assurance Initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have '''more of:'''&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality, especially during the release period.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have '''less of:'''&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Automated testing ==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]Inkscape's CI pipeline involves a number of unit, integration and end-to-end tests. However, we recognise that the overal test coverage is very poor as of late 2023. One of the main goals of this initiative is to track the test coverage and to work on increasing it.&lt;br /&gt;
&lt;br /&gt;
In the context of automated tests, we recall the famous Testing Pyramid (see right). It expresses the principle that tests at unit and component level should be the most prevalent ones, followed by a smaller number of integration tests, and topped off with a relatively lower number of end-to-end tests. Unfortunately, this is not the case today: we have too few unit tests. Manual testing should be limited to UX and usability aspects.&lt;br /&gt;
&lt;br /&gt;
=== Why does Inkscape not have enough unit tests ===&lt;br /&gt;
&lt;br /&gt;
* Historical reasons: feature development was prioritized and testing was never formally enforced.&lt;br /&gt;
* Work on tests and QA topics may be perceived as less &amp;quot;flashy&amp;quot; because it is less visible to the end user.&lt;br /&gt;
* Many new developments interact with and depend on legacy code which is hard to split off and mock. Thus, new code is hard to test.&lt;br /&gt;
* We don't have enough tooling such as automated test coverage reports or custom test fixtures to facilitate test development.&lt;br /&gt;
* Varied knowledge level of contributors, no expertise in testing.&lt;br /&gt;
&lt;br /&gt;
=== What can be done about it ===&lt;br /&gt;
&lt;br /&gt;
* Code review should emphasize the importance of adding unit tests for new functionality and regression tests for bug fixes.&lt;br /&gt;
* Quality and maintainability should be viewed as core aspects and as an important part of Inkscape's development.&lt;br /&gt;
* Legacy code must be managed carefully, see below.&lt;br /&gt;
* Test coverage reports should be introduced along with facilities that make it easy and pleasant to write tests.&lt;br /&gt;
* By increasing the number of tests, we can increase the knowledge and awareness of testing techniques in the community – learning from examples.&lt;br /&gt;
&lt;br /&gt;
== Dealing with legacy code ==&lt;br /&gt;
According to Michael Feathers, the author of the influential book &amp;quot;Working effectively with legacy code&amp;quot;, ''legacy code'' is not defined as &amp;quot;old code&amp;quot;, &amp;quot;code written in C&amp;quot; or in general &amp;quot;code that nobody maintains&amp;quot;. Instead, legacy code is '''code that is''' '''not testable and not tested.''' We recognise that Inkscape contains a lot of such code.&lt;br /&gt;
&lt;br /&gt;
=== The Vicious Cycle of Legacy Code ===&lt;br /&gt;
The fundamental problem with legacy code is that it's risky to change it because a small change in one place can have unpredictable and unintended consequences in other places. This has happened many times before and has led to severe bugs in Inkscape. In an ideal world, the existing code could be first enriched with &amp;quot;characterization tests&amp;quot; that capture its current behaviour, and tests could also be added for the new behaviour. In this way, we could assure that the development works as intended and doesn't break anything. But, according to our definition, legacy code is '''not testable''' so this cannot be done.&lt;br /&gt;
&lt;br /&gt;
In this way, we are stuck in a vicious cycle: to make code testable, we need to refactor it in order to make it testable, but refactoring can break things badly unless we have tests, which unfortunately we don't and which cannot be added because the code is not testable.&lt;br /&gt;
&lt;br /&gt;
To break out of this cycle, we need to start small, adding tests to simple and relatively independent pieces of functionality. It is helpful to identify the &amp;quot;seams&amp;quot;, which usually correspond to interfaces, along which the program or a system can be natuarally divided into pieces. If these pieces are simple enough, they can be made testable. However, even with this approach, a fair bit of mocking may be required to simulate external dependencies, which makes it a tedious task.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring and development techniques to increase testability ===&lt;br /&gt;
A large portion of Inkscape's codebase is made up of code that's very literal, low-level and suffers from a lack of abstraction. Desigining good interfaces and abstraction is an important goal that should be kept in mind not only during major architectural updates, but also our everyday work. Whenever you work on Inkscape, ask yourself the question: &amp;quot;Does this change make the code I'm working on more or less testable?&amp;quot;. Below are some concrete examples of techniques that can help increase testability.&lt;br /&gt;
&lt;br /&gt;
==== Extract and mock/override ====&lt;br /&gt;
&lt;br /&gt;
* Identify the piece of code that makes the functionality non-testable.&lt;br /&gt;
* Move this piece of code to a separate function(s) or a class. Moving code is safer than rewriting it, because the functional logic is kept unchanged.&lt;br /&gt;
* In tests, mock the class or function that the problematic code was moved to. This lets you test new functionality independently of the legacy code.&lt;br /&gt;
* If you need to extend the functionality provided by the non-testable code, try doing it without touching the untested function, but rather wrap around it or provide an override.&lt;br /&gt;
&lt;br /&gt;
==== Decorator pattern ====&lt;br /&gt;
This design pattern helps extend a legacy class with new functionality. Instead of adding the new functionality directly to the non-testable class (which would make the new functionality non-testable as well), write a wrapper around the legacy class. In the decorator pattern, the decorator class holds an instance of the wrapped class and provides an interface that forwards member function calls to the wrapped object. However, some of the member functions of the wrapper can provide additional functionality or further work on the values obtained from the wrapped object, which makes it possible to add new behaviours. This new functionality can now be tested by mocking the wrapped class in tests.&lt;br /&gt;
&lt;br /&gt;
==== Façade transformation ====&lt;br /&gt;
This technique helps when dealing with huge classes that hold too much data and that have too many member functions, making them complex, difficult to test, and increasing the coupling with other parts of the code. The façade transformation replaces the large class with a façade class which internally holds instances of several smaller classes. These smaller classes need to be designed by identifying the functionally cohesive pieces of the original large class and splitting them up. The member functions of the façade delegate to member function calls on these internal instances, sometimes more than one at a time. This transformation can be repeated if needed, until the classes are small enough that testing them is possible. The advantage of the façade transformation is that the API exposed by the large class is unchanged.&lt;br /&gt;
&lt;br /&gt;
== Guidelines on writing unit tests ==&lt;br /&gt;
&lt;br /&gt;
* Create a separate test executable for each class or functional module.&lt;br /&gt;
* Write a separate test case for each of the tested behaviours.&lt;br /&gt;
* Write a doxygen-style comment above each test case, explaining very briefly what this case is testing.&lt;br /&gt;
* In each test case, follow the Arrange-Act-Assert principle:&lt;br /&gt;
** Arrange: create the data and objects needed to perform the tested operation;&lt;br /&gt;
** Act: run the tested operation;&lt;br /&gt;
** Assert: use &amp;lt;code&amp;gt;EXPECT_*&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ASSERT_*&amp;lt;/code&amp;gt; macros from GTest to check that the behaviour is as expected.&lt;br /&gt;
* Remember to test unexpected and corner cases, invalid input, fallback behaviours.&lt;br /&gt;
* If your test needs custom set-up and tear-down, use a custom test fixture and &amp;lt;code&amp;gt;TEST_F&amp;lt;/code&amp;gt; macros.&lt;br /&gt;
* If your test needs to run on several cases parametrized by input data, consider using a &amp;lt;code&amp;gt;TEST_P&amp;lt;/code&amp;gt; fixture.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122636</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122636"/>
		<updated>2023-12-17T17:54:29Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Stub}}&lt;br /&gt;
&lt;br /&gt;
This page is a work in progress (2023-12-16).&lt;br /&gt;
&lt;br /&gt;
The Quality Assurance Initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have '''more of:'''&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality, especially during the release period.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have '''less of:'''&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Automated testing ==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]Inkscape's CI pipeline involves a number of unit, integration and end-to-end tests. However, we recognise that the overal test coverage is very poor as of late 2023. One of the main goals of this initiative is to track the test coverage and to work on increasing it.&lt;br /&gt;
&lt;br /&gt;
In the context of automated tests, we recall the famous Testing Pyramid (see right). It expresses the principle that tests at unit and component level should be the most prevalent ones, followed by a smaller number of integration tests, and topped off with a relatively lower number of end-to-end tests. Unfortunately, this is not the case today: we have too few unit tests. Manual testing should be limited to UX and usability aspects.&lt;br /&gt;
&lt;br /&gt;
=== Why does Inkscape not have enough unit tests ===&lt;br /&gt;
&lt;br /&gt;
* Historical reasons: feature development was prioritized and testing was never formally enforced.&lt;br /&gt;
* Work on tests and QA topics may be perceived as less &amp;quot;flashy&amp;quot; because it is less visible to the end user.&lt;br /&gt;
* Many new developments interact with and depend on legacy code which is hard to split off and mock. Thus, new code is hard to test.&lt;br /&gt;
* We don't have enough tooling such as automated test coverage reports or custom test fixtures to facilitate test development.&lt;br /&gt;
* Varied knowledge level of contributors, no expertise in testing.&lt;br /&gt;
&lt;br /&gt;
=== What can be done about it ===&lt;br /&gt;
&lt;br /&gt;
* Code review should emphasize the importance of adding unit tests for new functionality and regression tests for bug fixes.&lt;br /&gt;
* Quality and maintainability should be viewed as core aspects and as an important part of Inkscape's development.&lt;br /&gt;
* Legacy code must be managed carefully, see below.&lt;br /&gt;
* Test coverage reports should be introduced along with facilities that make it easy and pleasant to write tests.&lt;br /&gt;
* By increasing the number of tests, we can increase the knowledge and awareness of testing techniques in the community – learning from examples.&lt;br /&gt;
&lt;br /&gt;
== Dealing with legacy code ==&lt;br /&gt;
According to Michael Feathers, the author of the influential book &amp;quot;Working effectively with legacy code&amp;quot;, ''legacy code'' is not defined as &amp;quot;old code&amp;quot;, &amp;quot;code written in C&amp;quot; or in general &amp;quot;code that nobody maintains&amp;quot;. Instead, legacy code is '''code that is''' '''not testable and not tested.''' We recognise that Inkscape contains a lot of such code.&lt;br /&gt;
&lt;br /&gt;
=== The Vicious Cycle of Legacy Code ===&lt;br /&gt;
The fundamental problem with legacy code is that it's risky to change it because a small change in one place can have unpredictable and unintended consequences in other places. This has happened many times before and has led to severe bugs in Inkscape. In an ideal world, the existing code could be first enriched with &amp;quot;characterization tests&amp;quot; that capture its current behaviour, and tests could also be added for the new behaviour. In this way, we could assure that the development works as intended and doesn't break anything. But, according to our definition, legacy code is '''not testable''' so this cannot be done.&lt;br /&gt;
&lt;br /&gt;
In this way, we are stuck in a vicious cycle: to make code testable, we need to refactor it in order to make it testable, but refactoring can break things badly unless we have tests, which unfortunately we don't and which cannot be added because the code is not testable.&lt;br /&gt;
&lt;br /&gt;
To break out of this cycle, we need to start small, adding tests to simple and relatively independent pieces of functionality. It is helpful to identify the &amp;quot;seams&amp;quot;, which usually correspond to interfaces, along which the program or a system can be natuarally divided into pieces. If these pieces are simple enough, they can be made testable. However, even with this approach, a fair bit of mocking may be required to simulate external dependencies, which makes it a tedious task.&lt;br /&gt;
&lt;br /&gt;
=== Refactoring and development techniques to increase testability ===&lt;br /&gt;
A large portion of Inkscape's codebase is made up of code that's very literal, low-level and suffers from a lack of abstraction. Desigining good interfaces and abstraction is an important goal that should be kept in mind not only during major architectural updates, but also our everyday work. Whenever you work on Inkscape, ask yourself the question: &amp;quot;Does this change make the code I'm working on more or less testable?&amp;quot;. Below are some concrete examples of techniques that can help increase testability.&lt;br /&gt;
&lt;br /&gt;
==== Extract and mock/override ====&lt;br /&gt;
&lt;br /&gt;
* Identify the piece of code that makes the functionality non-testable.&lt;br /&gt;
* Move this piece of code to a separate function(s) or a class. Moving code is safer than rewriting it, because the functional logic is kept unchanged.&lt;br /&gt;
* In tests, mock the class or function that the problematic code was moved to. This lets you test new functionality independently of the legacy code.&lt;br /&gt;
* If you need to extend the functionality provided by the non-testable code, try doing it without touching the untested function, but rather wrap around it or provide an override.&lt;br /&gt;
&lt;br /&gt;
==== Decorator pattern ====&lt;br /&gt;
This design pattern helps extend a legacy class with new functionality. Instead of adding the new functionality directly to the non-testable class (which would make the new functionality non-testable as well), write a wrapper around the legacy class. In the decorator pattern, the decorator class holds an instance of the wrapped class and provides an interface that forwards member function calls to the wrapped object. However, some of the member functions of the wrapper can provide additional functionality or further work on the values obtained from the wrapped object, which makes it possible to add new behaviours. This new functionality can now be tested by mocking the wrapped class in tests.&lt;br /&gt;
&lt;br /&gt;
==== Façade transformation ====&lt;br /&gt;
This technique helps when dealing with huge classes that hold too much data and that have too many member functions, making them complex, difficult to test, and increasing the coupling with other parts of the code. The façade transformation replaces the large class with a façade class which internally holds instances of several smaller classes. These smaller classes need to be designed by identifying the functionally cohesive pieces of the original large class and splitting them up. The member functions of the façade delegate to member function calls on these internal instances, sometimes more than one at a time. This transformation can be repeated if needed, until the classes are small enough that testing them is possible. The advantage of the façade transformation is that the API exposed by the large class is unchanged.&lt;br /&gt;
&lt;br /&gt;
== Guidelines on writing unit tests ==&lt;br /&gt;
&lt;br /&gt;
* Create a separate test executable for each class or functional module.&lt;br /&gt;
* Write a separate test case for each of the tested behaviours.&lt;br /&gt;
* Write a doxygen-style comment above each test case, explaining very briefly what this case is testing.&lt;br /&gt;
* In each test case, follow the Arrange-Act-Assert principle:&lt;br /&gt;
** Arrange: create the data and objects needed to perform the tested operation;&lt;br /&gt;
** Act: run the tested operation;&lt;br /&gt;
** Assert: use EXPECT_ and ASSERT_ macros from GTest to check that the behaviour is as expected.&lt;br /&gt;
* Remember to test unexpected and corner cases, invalid input, fallback behaviours.&lt;br /&gt;
* If your test needs custom set-up and tear-down, use a custom test fixture and TEST_F macros.&lt;br /&gt;
* If your test needs to run on several cases parametrized by input data, consider using a TEST_P fixture.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=NachrichtenSchreiben&amp;diff=122635</id>
		<title>NachrichtenSchreiben</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=NachrichtenSchreiben&amp;diff=122635"/>
		<updated>2023-12-17T12:36:18Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: Add Outdated template&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Outdated}}&lt;br /&gt;
&lt;br /&gt;
=Nachrichten schreiben und veröffentlichen=&lt;br /&gt;
&lt;br /&gt;
Wir verwenden für den neuen Bereich der Inkscape-Website [http://wordpress.org/][[WordPress]]. Jeder darf mitmachen - einfach registrieren und einen Artikelentwurf schreiben. Nach der Überprüfung durch einen Entwickler wird dieser auf der Website veröffentlicht.&lt;br /&gt;
&lt;br /&gt;
Falls du also irgendwelche Neuigkeiten hast, die alle Inkscape-Nutzer interessieren könnten - hab keine Angst und trau dich, einen kurzen Artikel darüber zu schreiben: &lt;br /&gt;
&lt;br /&gt;
#Leg dir einen Account unter http://inkscape.org/wp/wp-register.php an, merk dir deine Daten (Username[[/Passwort]])&lt;br /&gt;
#Logge dich unter http://inkscape.org/wp/wp-admin/ ein&lt;br /&gt;
#Klick auf den Link &amp;quot;Write&amp;quot; in der Navigation&lt;br /&gt;
#Schreib deinen Artikel und speichere ihn anschließend&lt;br /&gt;
&lt;br /&gt;
Dein Artikel wird von einem Programmierer geprüft, bevor er auf der Hauptseite erscheint.&lt;br /&gt;
&lt;br /&gt;
Bitte lies deinen Bericht vor dem Speichern noch einmal durch und bessere Rechtschreib- und Grammatikfehler aus - du ersparst den Entwicklern so sehr viel Zeit.&lt;br /&gt;
&lt;br /&gt;
=Entwickler=&lt;br /&gt;
&lt;br /&gt;
Du bist ein Entwickler? Turnip (turnip at turnipspatch dot com) kann deinen Userstatus erhöhen, dann kannst du auch Artikel in Eigenverantwortung posten.&lt;br /&gt;
&lt;br /&gt;
[[Category:German]]&lt;br /&gt;
[[Category:Wiki Attic]]&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=NachrichtenSchreiben&amp;diff=122634</id>
		<title>NachrichtenSchreiben</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=NachrichtenSchreiben&amp;diff=122634"/>
		<updated>2023-12-17T12:34:22Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: Move to Wiki Attic category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Nachrichten schreiben und veröffentlichen =&lt;br /&gt;
&lt;br /&gt;
Wir verwenden für den neuen Bereich der Inkscape-Website [http://wordpress.org/ [[WordPress]]]. Jeder darf mitmachen - einfach registrieren und einen Artikelentwurf schreiben. Nach der Überprüfung durch einen Entwickler wird dieser auf der Website veröffentlicht.&lt;br /&gt;
&lt;br /&gt;
Falls du also irgendwelche Neuigkeiten hast, die alle Inkscape-Nutzer interessieren könnten - hab keine Angst und trau dich, einen kurzen Artikel darüber zu schreiben:&lt;br /&gt;
&lt;br /&gt;
# Leg dir einen Account unter http://inkscape.org/wp/wp-register.php an, merk dir deine Daten (Username[[/Passwort]])&lt;br /&gt;
# Logge dich unter http://inkscape.org/wp/wp-admin/ ein&lt;br /&gt;
# Klick auf den Link &amp;quot;Write&amp;quot; in der Navigation&lt;br /&gt;
# Schreib deinen Artikel und speichere ihn anschließend&lt;br /&gt;
&lt;br /&gt;
Dein Artikel wird von einem Programmierer geprüft, bevor er auf der Hauptseite erscheint.&lt;br /&gt;
&lt;br /&gt;
Bitte lies deinen Bericht vor dem Speichern noch einmal durch und bessere Rechtschreib- und Grammatikfehler aus - du ersparst den Entwicklern so sehr viel Zeit.&lt;br /&gt;
&lt;br /&gt;
= Entwickler =&lt;br /&gt;
&lt;br /&gt;
Du bist ein Entwickler? Turnip (turnip at turnipspatch dot com) kann deinen Userstatus erhöhen, dann kannst du auch Artikel in Eigenverantwortung posten.&lt;br /&gt;
&lt;br /&gt;
[[Category:German]]&lt;br /&gt;
[[Category:Wiki Attic]]&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122633</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122633"/>
		<updated>2023-12-16T20:25:00Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Stub}}&lt;br /&gt;
&lt;br /&gt;
This page is a work in progress (2023-12-16).&lt;br /&gt;
&lt;br /&gt;
The Quality Assurance Initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have more of:&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality in all we do.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have less of:&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
== Automated testing ==&lt;br /&gt;
[[File:Test pyramid.png|frame|right|The Test Pyramid illustrates the relative importance and the desired prevalence of tests at different coverage levels.]]&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=File:Test_pyramid.png&amp;diff=122632</id>
		<title>File:Test pyramid.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=File:Test_pyramid.png&amp;diff=122632"/>
		<updated>2023-12-16T20:22:52Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Test pyramid diagram&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122631</id>
		<title>Quality Assurance Initiative</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Quality_Assurance_Initiative&amp;diff=122631"/>
		<updated>2023-12-16T20:21:39Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: Initial page version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Stub}}&lt;br /&gt;
&lt;br /&gt;
This page is a work in progress (2023-12-16).&lt;br /&gt;
&lt;br /&gt;
The Quality Assurance Initiative aims to improve the quality and stability of Inkscape and to reduce the number of bugs and regressions, especially severe ones.&lt;br /&gt;
&lt;br /&gt;
In a nutshell, the goal is to have more of:&lt;br /&gt;
&lt;br /&gt;
* Test coverage of source code (unit tests, component/integration tests, end-to-end tests);&lt;br /&gt;
* Test automation, developer-friendly testing frameworks and tooling;&lt;br /&gt;
* Good practices related to coding and testing;&lt;br /&gt;
* Improvements to the code review process and release management;&lt;br /&gt;
* Focus on quality in all we do.&lt;br /&gt;
&lt;br /&gt;
In this way, we would like to have less of:&lt;br /&gt;
&lt;br /&gt;
* Crashes and data loss bugs;&lt;br /&gt;
* Memory leaks and corruption;&lt;br /&gt;
* Glitches, corner cases and difficult-to-reproduce bugs;&lt;br /&gt;
* Fragility due to hidden assumptions and limitations;&lt;br /&gt;
* Legacy code;&lt;br /&gt;
* Code that nobody understands and maintains.&lt;br /&gt;
&lt;br /&gt;
TODO: Discussion&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Google_Summer_of_Code&amp;diff=122028</id>
		<title>Google Summer of Code</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Google_Summer_of_Code&amp;diff=122028"/>
		<updated>2022-12-16T14:17:22Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: Add P12: Proposal for customizability of canvas control appearance&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;max-width:70em; margin-left: auto; margin-right: auto&amp;quot;&amp;gt;&lt;br /&gt;
= Welcome to Inkscape! =&lt;br /&gt;
&lt;br /&gt;
For quite a few years Inkscape has been successfully participating in [http://code.google.com/soc/ Google Summer of Code].&lt;br /&gt;
&lt;br /&gt;
'''New this year!'''  Google is opening up the program to new-comers to Open Source who are 18 years are older. Projects can be medium size (~175 hours) or large size (~350 hours). Finish times are flexible, 12 to 22 weeks (with agreement of mentor).&lt;br /&gt;
&lt;br /&gt;
GSoC is a program where Google funds the development of specific features in open source software by university students and other new to open source. You don't need to be a Computer Science student to apply. Features to be developed are picked by Inkscape administrators from the pool of proposals submitted by applicants.&lt;br /&gt;
&lt;br /&gt;
We've mentored about half a dozen students a year since GSoC started.  Many students enjoyed their work and continue to be involved; perhaps your mentor will be a past GSoC student!  We have a high rate of acceptance of student code into the core codebase. Indeed, GSoC projects have been a key source of some of Inkscape's best features in the past several releases.&lt;br /&gt;
&lt;br /&gt;
If you are interested in joining us this summer, it is time to get your proposal ready. You can choose a proposal from our list of suggestions or come up with one of your own. In either either case, you '''must''' give us a detailed outline of what you plan to do. It is '''highly''' recommended that you discuss your idea as early as possible with Inkscape developers. They not only can give you guidance as you flesh out your proposal but ultimately you must convince them that you can do the work planned in the time allotted. '''If you have not discussed your proposal with Inkscape developers before you apply, your application will be rejected!'''&lt;br /&gt;
&lt;br /&gt;
= Candidate Applications =&lt;br /&gt;
&lt;br /&gt;
* Google program information:&lt;br /&gt;
** [https://summerofcode.withgoogle.com/ Home page].&lt;br /&gt;
** Summer of Code Application form. Applications open at 18:00 UTC on April 4th 2022.&lt;br /&gt;
&lt;br /&gt;
* Inkscape-specific information:&lt;br /&gt;
** [[SOC Application Template]].&lt;br /&gt;
** [[Roadmap | Inkscape Roadmap]] - to see our overall objectives.&lt;br /&gt;
** [[Projects | Inkscape Development Project Ideas]] - broader list of development ideas.&lt;br /&gt;
** [[SOC Writing Project Proposals]] - some guidelines for proposals.&lt;br /&gt;
** [[SOC Selection Criteria]] - how we rate applications.&lt;br /&gt;
&lt;br /&gt;
'''Candidate Applications for GSoC 2022 must be submitted to the GSoC site by 18:00 UTC on April 19th 2022.'''&lt;br /&gt;
&lt;br /&gt;
= The &amp;quot;two patches&amp;quot; rule =&lt;br /&gt;
&lt;br /&gt;
We require two patches from each potential GSoC student, before accepting the student for GSoC participation (it is the same requirement as for obtaining rights to commit changes to the code repository).&lt;br /&gt;
&lt;br /&gt;
The reason for this requirement is that you can show us that you have succeeded in building Inkscape on your PC, and that you have understood a little piece of Inkscape's code and are able to improve it. &lt;br /&gt;
Inkscape is a large project, and you really should not try to understand all the code. Many (all?) developers know only parts of the program code!&lt;br /&gt;
You can join our [https://inkscape.org/community/discussion/ IRC] channel or [https://chat.inkscape.org/channel/team_devel Rocket Chat] and ask developers for help.&lt;br /&gt;
&lt;br /&gt;
== Suggested &amp;quot;easy&amp;quot; bug fixes or improvements ==&lt;br /&gt;
&lt;br /&gt;
To get you started on Inkscape development, you can find (probably) easy-to-fix bugs or small improvements that require very little knowledge of the whole program by searching our [https://gitlab.com/inkscape/inkscape/issues/ bug-tracker] for bugs tagged with 'easy-fix'.&lt;br /&gt;
&lt;br /&gt;
= Performance Evaluation =&lt;br /&gt;
&lt;br /&gt;
GSoC has two formal evaluation points, at the ''mid-term'' and at the end. These evaluations determine if you receive the stipend from Google. In order to receive a pass for the evaluations you will need to show adequate progress toward your project's goals.&lt;br /&gt;
&lt;br /&gt;
To help you meet your goals and so that your mentor can better evaluate your progress you need to:&lt;br /&gt;
&lt;br /&gt;
* Have frequent, public discussions of your progress. (Don't rely on just your mentor for advice.)&lt;br /&gt;
* Have a public Inkscape branch for your code to which you commit regularly.&lt;br /&gt;
* Give weekly status reports.&lt;br /&gt;
&lt;br /&gt;
For the final pass, you will normally be required to merge your code into Inkscape trunk.&lt;br /&gt;
&lt;br /&gt;
Remember: ''we want you to succeed!''&lt;br /&gt;
&lt;br /&gt;
= Suggested Project Ideas =&lt;br /&gt;
&lt;br /&gt;
The following is a list of formal project suggestions, but do not feel limited to only these - some of our best contributions have been unique ideas that students had in mind from other sources!&lt;br /&gt;
&lt;br /&gt;
See also [[Development Project Ideas]], [[Refactoring projects]], [[Projects]], and https://blueprints.launchpad.net/inkscape/&lt;br /&gt;
&lt;br /&gt;
==P1. Better CSS Style Sheet Support==&lt;br /&gt;
&lt;br /&gt;
Enhance Inkscape's support for CSS style sheets.&lt;br /&gt;
&lt;br /&gt;
* Estimation of difficulty: Moderately hard - Long (350h)&lt;br /&gt;
* Potential mentors: Tavmjong Bah&lt;br /&gt;
* Programming skills needed:  C++&lt;br /&gt;
* Prerequisites: Experience with CSS style sheets.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Detailed Description&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inkscape has basic support for CSS style sheets that can read and parse internal style sheets. A 2016 GSoC project added a simple style dialog that can create and modify the internal style sheet. The dialog is very limited and is not intuitive to use. A 2017 GSoC project added support for CSS 3 selectors. More work has been done recently, creating the ''Selectors and CSS'' dialog... This project will extend the usefulness of that dialog by making it more user friendly and by extending its functionality.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Use Cases&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Support externally created SVGs.&lt;br /&gt;
* Producing better SVGs for the Web.&lt;br /&gt;
* Changing style on multiple objects at once (palettes).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Related Material&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [https://www.w3.org/TR/CSS2/ CSS 2 Specification]&lt;br /&gt;
* [https://www.w3.org/TR/css-2015/ CSS 2015 Snapshot]&lt;br /&gt;
&lt;br /&gt;
==P5. UI-Free Inkscape ==&lt;br /&gt;
&lt;br /&gt;
* Estimation of difficulty: Difficult - Long (350h)&lt;br /&gt;
* Potential mentors: Marc Jeanmougin&lt;br /&gt;
* Programming skills: C++, CMake&lt;br /&gt;
* Prerequisites: Minimal knowledge of build systems. Experience with GtkMM helpful.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Detailed Description&amp;lt;/u&amp;gt;&lt;br /&gt;
Inkscape currently builds with X11 and gtk and a lot of graphical dependencies. But since it is allowed to run in commandline, and there are controlled environments (servers) that use it to convert svg to png and to perform actions, there should be no need to force it to build with those. The main goal of this project is to add a WITH_GUI compilation flag that when OFF, does *not* link Inkscape with any graphical dependency. While much work has been done towards this goal, much remains to be done. DONE &amp;lt;s&amp;gt;As a next step, Inkscape's &amp;quot;verbs&amp;quot; which are mostly GUI dependent (even if there is no reason to be) need to be converted to Gio::Actions.&amp;lt;/s&amp;gt; More work needs to be done to separate out hidden GUI dependencies that remain after the Verb to Action transition.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Use cases&amp;lt;/u&amp;gt;&lt;br /&gt;
* Server installs, scripts&lt;br /&gt;
&lt;br /&gt;
==P6. Refactoring==&lt;br /&gt;
* Estimation of difficulty: Moderate - Short or Long depending on scope (175h or 350h)&lt;br /&gt;
* Potential mentors: Tavmjong Bah&lt;br /&gt;
* Programming skills: C++&lt;br /&gt;
* Prerequisites: proficient C++.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Detailed Description&amp;lt;/u&amp;gt;&lt;br /&gt;
Inkscape began life as the C program Sodipodi. Sodipodi was mostly the work of one person who had a clear vision of how the code should work. A major motivation of the Inkscape fork was to allow others to easily contribute to development. This resulted in rapid development but at a cost: the code has become much messier and now lacks a clear vision. This project is to work on refactoring the code. Refactoring can take many forms. It could be creating a better directory structure with README's that describe the purpose and function of the code in each directory. This would include rewriting code to reduce dependencies across directories (which would help, for example, in achieving a headless version of Inkscape). It could be the continued transition from C to C++ which often results in major reductions in the number of code lines. Or it could be identifying and eliminating redundant code. Refactoring is an important skill of which many books have been written. Here's a chance to gain valuable experience!&lt;br /&gt;
&lt;br /&gt;
See https://wiki.inkscape.org/wiki/index.php/Refactoring_projects for some ideas of projects.&lt;br /&gt;
&lt;br /&gt;
==P7. Tesseract OCR==&lt;br /&gt;
&lt;br /&gt;
* Estimation of difficulty: Easy - Short (175h)&lt;br /&gt;
* Potential mentors: unknown&lt;br /&gt;
* Programming skills: C / C++, AI&lt;br /&gt;
* Prerequisites: unknown&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Detailed Description&amp;lt;/u&amp;gt;&lt;br /&gt;
The Tesseract OCR library available here https://github.com/tesseract-ocr/tesseract gives the ability to detect text, lines, and other shapes within a document. This type of vectorisation is currently missing from Inkscape. Plenty of other open source and proprietary tools have made use of this library.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Use cases&amp;lt;/u&amp;gt;&lt;br /&gt;
* User interface design, converting screenshots&lt;br /&gt;
&lt;br /&gt;
==P8. Add Text and Image Support to Live Path Effect System ==&lt;br /&gt;
* Estimation of difficulty: Hard - Short (175h)&lt;br /&gt;
* Potential mentors: Jabier Arraiza (Spanish, English(not native))&lt;br /&gt;
* Programming skills: C++&lt;br /&gt;
* Prerequisites: Experience managing bitmaps&lt;br /&gt;
&amp;lt;u&amp;gt;Detailed Description&amp;lt;/u&amp;gt;&lt;br /&gt;
Live Path Effects are non destructive effects applied to paths and shapes standalone or inside a group.&amp;lt;br /&amp;gt; &lt;br /&gt;
This is done keepeng a reference to the original data to reaply when needed.&amp;lt;br /&amp;gt;&lt;br /&gt;
But ignore text and image elements.&amp;lt;br /&amp;gt;&lt;br /&gt;
Things to do:&lt;br /&gt;
* Study add image, text, both and maybe others SVG elements to the LPE system.&lt;br /&gt;
* Create/adapt minimun one LPE for each new type of element acepted as reference. Suggestion Perspective-Envelope.&lt;br /&gt;
&amp;lt;u&amp;gt;Use cases&amp;lt;/u&amp;gt;&lt;br /&gt;
* Apply live effects to images and text based in C++ code in a non destructive way even in groups with mixed elements types.&lt;br /&gt;
&lt;br /&gt;
==P9. Path Library Improvements ==&lt;br /&gt;
* Estimation of difficulty: Hard - Long (350h)&lt;br /&gt;
* Potential mentors: Tavmjong Bah, KK&lt;br /&gt;
* Programming skills: C++&lt;br /&gt;
* Prerequisites: Strong math skills, specifically in geometry.&lt;br /&gt;
&amp;lt;u&amp;gt;Detailed Description&amp;lt;/u&amp;gt;&lt;br /&gt;
Inkscape relies on two geometry libraries for path manipulations: lib2geom and livarot. lib2geom is a generic modern library written specifically with Inkscape in mind. lib2geom is missing some functionality that Inkscape requires and that is found in livarot. This project is to move that functionality into lib2geom (or into separate files) using lib2geom path descriptions. A 2020 GSoC student did a significant amount of work understanding and documenting the issues involved. This project would be to build on his work.&lt;br /&gt;
&lt;br /&gt;
Specifically, the functionality needed is&lt;br /&gt;
* Path offset/inset functions.&lt;br /&gt;
* Path simplify.&lt;br /&gt;
* Stroke to path function.&lt;br /&gt;
* Line scanning (used for flowing text into a shape).&lt;br /&gt;
&lt;br /&gt;
==P10. Font Selection Improvements ==&lt;br /&gt;
* Estimation of difficulty: Medium - Short (175h)&lt;br /&gt;
* Potential mentors: Tavmjong Bah, ??&lt;br /&gt;
* Programming skills: C++&lt;br /&gt;
* Prerequisites: Some knowledge of GTK.&lt;br /&gt;
&amp;lt;u&amp;gt;Detailed Description&amp;lt;/u&amp;gt;&lt;br /&gt;
Inkscape's ''Text toolbar'' and ''Text and Font dialog'' present the user with a long list of font family choices. Designers often have hundreds if not thousands of fonts on their system to choose from making the use of these lists difficult and time consuming (and generating font previews slows Inkscape down). This project is to add a ''Font Selection dialog'' where the user can create a list of &amp;quot;Document Fonts&amp;quot; (along with CSS fallbacks). Only these documents fonts will then be shown in the drop-down menus in the Inkscape's Text toolbar and Text and Font dialog. The ''Font Selection'' dialog should show the designer previews of all available fonts, provide &amp;quot;filtering&amp;quot; mechanisms, and allow easily moving fonts to and from the document font list. Interaction with Inkscape's ''UX'' team will be crucial. A bonus feature would be to allow the user to add @font-face rules (Inkscape has some support for these already but has no UX for them).&lt;br /&gt;
&lt;br /&gt;
==P11. Improvements to Paint Server Dialog ==&lt;br /&gt;
&lt;br /&gt;
* Estimation of difficulty: Easy to Medium - Short (175h)&lt;br /&gt;
* Potential mentors: Tavmjong&lt;br /&gt;
* Programming skills: C++&lt;br /&gt;
* Prerequisites: Some knowledge of GTK and CSS.&lt;br /&gt;
&amp;lt;u&amp;gt;Detailed Description&amp;lt;/u&amp;gt;&lt;br /&gt;
The ''Paint Server Dialog'' allows a user to visually select a pattern or hatch to use in painting the ''fill'' or ''stroke'' of an object. This project would be to expand the dialog to cover gradients, meshes, and solid colors as well as make other improvements to the dialog. Interaction with the Inkscape's ''UX'' team will be required.&lt;br /&gt;
&lt;br /&gt;
==P12. Customizable Appearance of Canvas Controls ==&lt;br /&gt;
[[File:Nodes.png|frame|alt=Screenshot of node handles|Node handles (Inkscape 1.2)]]&lt;br /&gt;
* Estimation of difficulty: Medium - Short (175h)&lt;br /&gt;
* Potential mentors: Rafał Siejakowski, ??&lt;br /&gt;
* Programming skills: C, C++&lt;br /&gt;
* Prerequisites: Some knowledge of CSS.&lt;br /&gt;
&amp;lt;u&amp;gt;Detailed Description&amp;lt;/u&amp;gt;&lt;br /&gt;
Interacting with path nodes and tangent handles (e.g., using the ''Node Tool'') is one of the core workflows in Inkscape (see screenshot).&lt;br /&gt;
Unfortunately, the appearance of these on-canvas controls is currently very ugly (gray with black border, no support for outline)&lt;br /&gt;
and  hardcoded (except for size, which can be adjusted in the Preferences).&lt;br /&gt;
The goal of this project is to make Inkscape read the styles of the node handles from an external CSS file shipped with Inkscape installations.&lt;br /&gt;
This feature will enable UI designers to easily tweak the appearance of on-canvas controls using CSS and will in particular implement&lt;br /&gt;
the [https://gitlab.com/inkscape/ux/-/issues/115 existing restyling proposal].&lt;br /&gt;
It will also open up the road to potential future improvements: user-customizability, theming support, styling support for other UI elements.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;u&amp;gt;Technical details&amp;lt;/u&amp;gt;&lt;br /&gt;
Inkscape already uses a library called &amp;lt;code&amp;gt;libcroco&amp;lt;/code&amp;gt; for CSS parsing.&lt;br /&gt;
The proposed mechanism will support only a small subset of CSS, suitable for styling the canvas controls.&lt;br /&gt;
Their shape could be represented by &amp;lt;code&amp;gt;list-style-type&amp;lt;/code&amp;gt; values of &amp;lt;code&amp;gt;disc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;square&amp;lt;/code&amp;gt; and string values &amp;lt;code&amp;gt;&amp;quot;diamond&amp;quot;&amp;lt;/code&amp;gt;, etc.&lt;br /&gt;
The feature should also support &amp;lt;code&amp;gt;background-color&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;border-color&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;border-width&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;outline-color&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;outline-width&amp;lt;/code&amp;gt;, where the widths could be set as absolute dimensions in &amp;lt;code&amp;gt;px&amp;lt;/code&amp;gt; or relative values (percentages).&lt;br /&gt;
Hover, mousedown and selected states should also be specified, using CSS pseudo-classes such as &amp;lt;code&amp;gt;:hover&amp;lt;/code&amp;gt;.&lt;br /&gt;
If time permits, additional CSS properties (such as &amp;lt;code&amp;gt;mix-blend-mode&amp;lt;/code&amp;gt;) and more node shapes could be added.&lt;br /&gt;
A simple renderer for the on-canvas controls must be implemented, which will create cached bitmaps at the requested size, taking the styling information into account.&lt;br /&gt;
&lt;br /&gt;
==Pxx. Your project ==&lt;br /&gt;
* Estimation of difficulty: Variable - Short or Long (175h or 350h)&lt;br /&gt;
* Potential mentors: Marc Jeanmougin&lt;br /&gt;
* Programming skills: usually C++&lt;br /&gt;
* Prerequisites: good ideas&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Detailed Description&amp;lt;/u&amp;gt;&lt;br /&gt;
The most successful GSoC we had in the past were students coming with their own past, use cases and ideas for Inkscape. Many basic tools like 3d cubes or connectors you can see in Inkscape now have been brought by brilliant people (like you) with ideas. If we think that your project fits with Inkscape (ie: has its place with a vector graphic editor), we can help you refining your ideas and help bring shiny new stuff to life!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Use cases&amp;lt;/u&amp;gt;&lt;br /&gt;
* Amaze us!&lt;br /&gt;
&lt;br /&gt;
= Successful SOC Projects from Previous Years =&lt;br /&gt;
* 2005&lt;br /&gt;
** Connectors&lt;br /&gt;
** Inkboard&lt;br /&gt;
** [http://www.openclipart.org/ Open Clip Art Library (OCAL)] Interface&lt;br /&gt;
** DXF Import / Export&lt;br /&gt;
* [[Google Summer of Code 2006|2006]]&lt;br /&gt;
** Support for SVG Filters&lt;br /&gt;
** Filter Effects&lt;br /&gt;
** PDF export&lt;br /&gt;
** Inkboard Protocol Spec / Lib Conversion&lt;br /&gt;
* [[Google Summer of Code 2007|2007]]&lt;br /&gt;
** Text Style Improvements&lt;br /&gt;
** PDF import&lt;br /&gt;
** Live Path Effects&lt;br /&gt;
** 3D Box Tool&lt;br /&gt;
** UI for SVG Filter Effects&lt;br /&gt;
** Raster Functionality&lt;br /&gt;
** Importing from, and Exporting to, a remote ccHost instance&lt;br /&gt;
* [[Google Summer of Code 2008|2008]]&lt;br /&gt;
** SVG Fonts support&lt;br /&gt;
** 2Geom refactoring project - port most geometry code to 2Geom&lt;br /&gt;
** lib2geom: interactive applications showing off the power of lib2geom&lt;br /&gt;
** Tech drawing abilities&lt;br /&gt;
** A test suite&lt;br /&gt;
* 2009&lt;br /&gt;
** [[GSoC2009 Node Tool Rewrite|Node tool rewrite]]&lt;br /&gt;
** D-Bus scripting API&lt;br /&gt;
** Connector tool improvements&lt;br /&gt;
** ICC/CMYK workflow&lt;br /&gt;
* 2010&lt;br /&gt;
** Cairo-based rendering&lt;br /&gt;
** C++ification of SP Layer&lt;br /&gt;
* 2011&lt;br /&gt;
** Rendering caching&lt;br /&gt;
** Javascript support improvements&lt;br /&gt;
** CSS support improvements&lt;br /&gt;
* 2012&lt;br /&gt;
** Usibility Improvements for Guides&lt;br /&gt;
** [[Tiling tool|On-canvas support for Tessellations]]&lt;br /&gt;
** Creating python bindings for lib2geom&lt;br /&gt;
* [[Google Summer of Code 2013|2013]]&lt;br /&gt;
** Recolor Tool&lt;br /&gt;
** Improved Units Support&lt;br /&gt;
** Electronics CAD Support&lt;br /&gt;
** New From Templates Dialog&lt;br /&gt;
** New Raster to Vector Algorithm&lt;br /&gt;
* 2014&lt;br /&gt;
** Better Support for SVG Paints&lt;br /&gt;
** Robust Boolean and Stroking Operations for 2Geom&lt;br /&gt;
* 2016&lt;br /&gt;
** [[GSoC 2016 Better data structure for selections|Better data structure for selections]]&lt;br /&gt;
** [[Style Editor|CSS Style Sheet Editor]]&lt;br /&gt;
* 2017&lt;br /&gt;
** SVG 2 Text Support&lt;br /&gt;
** Better CSS Style Sheet Support&lt;br /&gt;
* 2019&lt;br /&gt;
** Mesh gradient and hatches polyfills. Paint server dialog.&lt;br /&gt;
* 2020&lt;br /&gt;
** [https://gitlab.com/vanntile/inkscape-gsoc-2020 New dialog system.]&lt;br /&gt;
** [https://gitlab.com/rathod-sahaab/gsoc-2020-inkscape Command palette dialog.]&lt;br /&gt;
** Path operations.&lt;br /&gt;
* 2021&lt;br /&gt;
** [https://gitlab.com/inkscape/inkscape/-/merge_requests/3420 On canvas marker editing.]&lt;br /&gt;
** [https://gitlab.com/inkscape/inkscape/-/merge_requests/3328 Verbs to Gio::Actions.]&lt;br /&gt;
** [https://gitlab.com/inkscape/inkscape/-/merge_requests/3294 On canvas alignment snapping.]&lt;br /&gt;
[[Category:Developer Documentation]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=File:Nodes.png&amp;diff=122027</id>
		<title>File:Nodes.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=File:Nodes.png&amp;diff=122027"/>
		<updated>2022-12-16T11:53:07Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Node handles in Inkscape 1.2&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Release_notes/1.3&amp;diff=122026</id>
		<title>Release notes/1.3</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Release_notes/1.3&amp;diff=122026"/>
		<updated>2022-12-14T11:25:25Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: Rename old to old-style (permanent snapping toolbar) and expand.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{Box| '''These Release Notes are in Draft Status.'''&lt;br /&gt;
&lt;br /&gt;
Note: Not all animations work, due to Wiki bugs with resizing images. Release notes will be transferred to website, there animations will be working.&lt;br /&gt;
&lt;br /&gt;
Important Links:&lt;br /&gt;
* [https://gitlab.com/inkscape/inkscape/commits/master Commit History Main Program (starting from: xxx)]&lt;br /&gt;
* [https://gitlab.com/inkscape/extensions/-/commits/master Commit History Extensions (starting from: xxx)]&lt;br /&gt;
* [https://gitlab.com/inkscape/inkscape-docs/documentation/-/tree/master Commit History Documentation (starting from: xxx)]&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Box| Pending questions:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Release highlights ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--'''Released on May xx, 2023 '''--&amp;gt;&lt;br /&gt;
&amp;lt;!--'''Definitely not released yet.'''--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Pattern editor , Pattern canvas controls, and pattern performance&lt;br /&gt;
*Shape builder - New tool for building complex  shapes form simple shapes. = live Boolean tool&lt;br /&gt;
*Live Path effects Dialog - Totally new improved &lt;br /&gt;
*Filter editor - New Redesign &lt;br /&gt;
* '''and so much more!'''&lt;br /&gt;
&lt;br /&gt;
== Performance ==&lt;br /&gt;
There has be lots of effort to improve performance of all aspects in Inkscape. Lots of refactoring of various inefficient code: Display- small hacks, handling of Patterns , Paint server and filters. After that we added Multi treading to Bitmap tracing, ...(more to come)&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests?scope=all&amp;amp;state=merged&amp;amp;label_name&amp;amp;#x5B;&amp;amp;#x5D;=Project%3A%3AMultithreading&lt;br /&gt;
&lt;br /&gt;
== General user interface ==&lt;br /&gt;
[[File:Indicators of used colors.png|thumb|indicators of used colors]]&lt;br /&gt;
Color palettes have indicator color of stroke and fill of selected object. The first 4 colors are pinned and have the ability to become larger than the rest. Other than the special &amp;quot;none&amp;quot; color, the remaining 3 can be customized by editing the file &amp;lt;code&amp;gt;palettes/default-fixed-colors.gpl&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:Inkscape BHd0t2kzml.gif]]&lt;br /&gt;
&lt;br /&gt;
=== New feature paste on page ===&lt;br /&gt;
You can copy and paste object from one page to another. &amp;lt;code&amp;gt;Edit &amp;gt; Specials Paste &amp;gt; Paste on page&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4695&lt;br /&gt;
&lt;br /&gt;
=== Old-style permanent snapping toolbar ===&lt;br /&gt;
An option was added in &amp;lt;code&amp;gt;Settings &amp;gt; Interface &amp;gt; Toolbars&amp;lt;/code&amp;gt; to show the detailed snapping options permanently in a dedicated toolbar, similar to Inkscape version 1.1 and earlier.&lt;br /&gt;
&lt;br /&gt;
=== Keyboard shortcuts ===&lt;br /&gt;
&lt;br /&gt;
The keyboard shortcuts for aligning objects vertically and horizontally have been moved to the numeric keypad, where the other alignment shortcuts are, too:&lt;br /&gt;
&lt;br /&gt;
* Vertical alignment was moved from &amp;lt;kbd&amp;gt;Ctrl+Alt+T&amp;lt;/kbd&amp;gt; to &amp;lt;kbd&amp;gt;'''Ctrl+Alt+Numpad 1'''&amp;lt;/kbd&amp;gt;&lt;br /&gt;
* Horizontal alignment was moved from &amp;lt;kbd&amp;gt;Ctrl+Alt+H&amp;lt;/kbd&amp;gt; to &amp;lt;kbd&amp;gt;'''Ctrl+Alt+Numpad 7'''&amp;lt;/kbd&amp;gt;&lt;br /&gt;
[[File:OKLAB.png|thumb|358x358px]]&lt;br /&gt;
If you find yourself unable to reach the new shortcuts (for example, because your laptop does not have a keypad, or because the shortcuts do not work - may be the case on Linux with Xfce), you can set them to something else by changing '''both''' the alignment shortcut '''and''' the function that now uses that shortcut (if any). Use the search in &amp;lt;code&amp;gt;Edit &amp;gt; Preferences &amp;gt; Interface &amp;gt; Keyboard&amp;lt;/code&amp;gt;. It also allows searching for shortcuts, not only for their name (e.g. search for 'ctrl+alt+t' to find the new default action that is executed when that combo is pressed).&lt;br /&gt;
&lt;br /&gt;
=== Color Picker ===&lt;br /&gt;
Added support for the '''OKLab''' and '''OKLch''' color spaces which have just been adopted into the CSS Color Module Level 4  [https://www.w3.org/TR/css-color-4/#ok-lab draft recommendation]. OKLab is described in detail by its creator in an interesting blog post. The new picker is called &amp;quot;OKHSL&amp;quot; and is available from the dropdown.&lt;br /&gt;
&lt;br /&gt;
=== '''Rulers''' ===&lt;br /&gt;
Improved look. Fixed performance penalty. Added indicator of selection (its possible to trun off in preferences)&lt;br /&gt;
&lt;br /&gt;
== Canvas ==&lt;br /&gt;
&lt;br /&gt;
Pressing '''&amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt;''' temporarily hides on-canvas overlays (transformation handles, grids, guides ...). This allows quick preview of final artwork without any distractions.&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4395&lt;br /&gt;
&lt;br /&gt;
Added display overlay controls in top right corners. You need to have scrollbars enable to see it.&lt;br /&gt;
&lt;br /&gt;
[[File:Canvas overlays.png|399x399px]]&lt;br /&gt;
&lt;br /&gt;
=== OpenGL Canvas rendering  (GPU rendering) ===&lt;br /&gt;
We added OpenGL rendering it is highly experimental and its turned off by default. (known to be broken on Mac ). Its known to be slower than CPU rendering  (gtk3 problems) and it will not be useful unti we migrate to gtk4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Preferences -&amp;gt; rendering -&amp;gt; OpenGL&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4133&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
=== Selection tool ===&lt;br /&gt;
new commands:&lt;br /&gt;
&lt;br /&gt;
* '''Reapply transform''': ''Ctrl+Alt+T''  - This allows a user to perform a transformation multiple times and works from the canvas edits or from transform dialog or the select toolbar. &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Shortcut needs to change, it opens a terminal on Linux.&amp;lt;/span&amp;gt;&lt;br /&gt;
* '''Duplicate and transform''': ''Ctrl+Alt+D'' -This performs a duplication and then reapplies the previous transform to the duplicate. &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Shortcut needs to change, it minimizes the window on Linux.&amp;lt;/span&amp;gt;&lt;br /&gt;
* '''Clone while dragging:''' drag object + C - Drag object  move it and press C to clone in current position   https://gitlab.com/inkscape/inkscape/-/merge_requests/4752&amp;lt;br /&amp;gt; https://gitlab.com/inkscape/inkscape/-/merge_requests/4506&lt;br /&gt;
&lt;br /&gt;
[[File:Inkscape xfsvsc2oY9.gif|thumb|editing pattern on canvas]]&lt;br /&gt;
&lt;br /&gt;
=== Node tool ===&lt;br /&gt;
&lt;br /&gt;
==== Pattern editing ====&lt;br /&gt;
Pattern editing on canvas is now easier you can click on any part of pattern and it will show you controls on that position. We also outline that shows you edges of pattern. First square  controls position circle controls rotation and second square controls size  hold shift to constrain proportions. &lt;br /&gt;
&lt;br /&gt;
We also fixed performance problems with patterns so now you can have smaller patterns in project and also its possible to zoom in on pattern&lt;br /&gt;
&lt;br /&gt;
==== Lasso selection mode ====&lt;br /&gt;
We added new lasso selection mode hold alt and draw around nodes you want to select. Useful fore selecting nodes inside of complicated geometry&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4747&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Shape Builder tool (New tool) ===&lt;br /&gt;
New tool for fast shape building and Boolean operations. Shortcut &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use: Select multiple overlapping shapes and select shipbuilder tool. Selection will be fragmented on overlapping areas everything else is going to be hidden until you confirm operation. Now you '''Click and drag''' to combine segments together or hold '''Shift  + Click and drag''' to substract  and '''Sigle click''' on segment to split. Adding is represented by Blue color removing by pink&lt;br /&gt;
&lt;br /&gt;
[[File:Shape_builder.gif]]&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4709&lt;br /&gt;
[[File:Ezgif.com-gif-maker (12).gif|right|600x600px]]&lt;br /&gt;
&lt;br /&gt;
=== Pages tool ===&lt;br /&gt;
Have controls for margins (guids):&lt;br /&gt;
&lt;br /&gt;
* An attribute on the page element to record the margin&lt;br /&gt;
* A new html/css style box model with tests&lt;br /&gt;
* New UI to set margins in the toolbar&lt;br /&gt;
* New on canvas controls for moving margins (with ctrl/shift)&lt;br /&gt;
* New display of margins in the same canvas group as the page border&lt;br /&gt;
&lt;br /&gt;
* Snapping for page margins&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4523&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Gradient tool ===&lt;br /&gt;
&lt;br /&gt;
* Allowing to change the ''repeat'' setting when multiple gradients are selected.&lt;br /&gt;
* Showing 'Multiple gradients' in the stop list when multiple gradients are selected (instead of a random stop).&lt;br /&gt;
* Allowing the editing of the offset of the start/end stops.&lt;br /&gt;
* Keeping the stop selected after the offset is changed in the toolbar (instead of selecting the 1st stop of the gradient).&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4339&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Path Operations ==&lt;br /&gt;
&lt;br /&gt;
New commands:&lt;br /&gt;
&lt;br /&gt;
'''Fracture''' Path-&amp;gt;fracture - every overlapping path will be silted in to separate object&lt;br /&gt;
&lt;br /&gt;
'''Flatten''' Path-&amp;gt;flatten - overlapping object vi be flatten visually (it  will delete path that are hidden behind a top path). Useful for separating colors for Screen printing and offset printing&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Masking / Clipping ==&lt;br /&gt;
&lt;br /&gt;
* A new option to '''preserve clips / masks when ungrouping''' objects has been added (&amp;lt;code&amp;gt;Edit → Preferences → Behavior → Clippaths and Masks: When ungroup, clip/mask is preserved in childrens&amp;lt;/code&amp;gt;). The option is active by default. This means that when you now ungroup a group that has been clipped, the elements inside it will inherit the clip. Previously, the clip was removed and everything became un-clipped. To go back to previous default behavior, deactivate this new option. ([https://gitlab.com/inkscape/inkscape/-/merge_requests/3564 MR #3564]) --&amp;gt;&lt;br /&gt;
[[File:Pattern editor1.gif|alt=Pattern editor|right|Pattern editor]]&lt;br /&gt;
&lt;br /&gt;
== Dialogs ==&lt;br /&gt;
&lt;br /&gt;
=== Fill and stroke Dialog ===&lt;br /&gt;
&lt;br /&gt;
==== New pattern editor ====&lt;br /&gt;
Added in to UI. You can preview patterns change name,  size, rotation, offset, gaps and colors for some specific patterns. We also added collections of patterns  &amp;lt;code&amp;gt;~paint/pattern.svg&amp;lt;/code&amp;gt;  so its easier to be organized .  Since  this allows  having much more patterns preset we also added search function .&lt;br /&gt;
&lt;br /&gt;
=== Filter editor ===&lt;br /&gt;
[[File:Filter-resize.gif|alt=Filter-resize|Filter-resize|left]]&lt;br /&gt;
&lt;br /&gt;
Redesign of this dialog:&lt;br /&gt;
&lt;br /&gt;
* Filter selection moved to a popover&lt;br /&gt;
* Effects are listed in a popup menu and can be selected by searching (by name)&lt;br /&gt;
* Adjusted connector sizes to make them more compact&lt;br /&gt;
* Fixed an issue where all parameters would initially be visible in a docked filter dialog&lt;br /&gt;
* Fixed min size of parameters panel to make it fit in a narrow docked dialog&lt;br /&gt;
* Reactive layout to accommodate wide dialog&lt;br /&gt;
* Added primitive filter attributes to fe-image and fe-tile (#1417)&lt;br /&gt;
* Replaced GTK color picker with Inkscape color picker&lt;br /&gt;
&lt;br /&gt;
* Sources can now be hidden (for most use cases only the source graphics is useful; other inputs are broken or need ux work) &amp;lt;br /&amp;gt;https://gitlab.com/inkscape/inkscape/-/merge_requests/4720[[File:Inkscape Y7U4yzIFTq.gif|thumb]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Layers and Objects ===&lt;br /&gt;
UX improvements:&lt;br /&gt;
&lt;br /&gt;
* you can click and drag  to change visibility of multiple objects&lt;br /&gt;
* selecting on group does not auto expand .&lt;br /&gt;
* Selecting multiple object and and changing  visibility/locking  applies to all selected&lt;br /&gt;
* We added search feature, Its limited implmentation.it does not auto apply search and you need to search for more 3 characters&lt;br /&gt;
* we added hover  indicator for rows and  layer colors&lt;br /&gt;
* added controls for opacity and blending mode&lt;br /&gt;
&lt;br /&gt;
We added shortcuts for layers navigation and actions:&lt;br /&gt;
&lt;br /&gt;
*   arrows to  navigate&lt;br /&gt;
*   space bur confirms (select, apply, open)&lt;br /&gt;
*  shift -&amp;gt; &amp;lt;- open close group&lt;br /&gt;
* shift up down to move  in Z order&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:VirtualBoxVM I675gipqe1.gif|thumb|1017x1017px|Place holder  demo of new LPE dialog]]&lt;br /&gt;
&lt;br /&gt;
=== Live Path Effects ( LPE ) ===&lt;br /&gt;
New redesigned LPE dialog. &lt;br /&gt;
&lt;br /&gt;
The compacted design merges organization and controls into one unit. You can reorder LPE by drag and drop whole effect. It adds fast search box and fast dropdown for adding effects.&lt;br /&gt;
&lt;br /&gt;
Single LPE has 5 controls:&lt;br /&gt;
&lt;br /&gt;
* Show/Hide Controls&lt;br /&gt;
* Visibility of Effect&lt;br /&gt;
* Delete Effect&lt;br /&gt;
* Context menu &lt;br /&gt;
** Re-order&lt;br /&gt;
** Duplicate&lt;br /&gt;
** Set as default&lt;br /&gt;
** Flatten&lt;br /&gt;
&lt;br /&gt;
[[File:LPE organization.png|right|266x266px]]&lt;br /&gt;
Reorganization of LPEs:&lt;br /&gt;
&lt;br /&gt;
Since we needed more compact way show All LPEs we Decided on a list that is organizes in to 6 Categories :&lt;br /&gt;
&lt;br /&gt;
Tools ,Distort, Generate, Convert, Experimental + Favorite&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Changes:&lt;br /&gt;
&lt;br /&gt;
* Setting presets for LPE was moved in to contextual menu&lt;br /&gt;
* Setting Favorite LPE was moved in to contextual menu&lt;br /&gt;
* Added New feature flatten - This will apply effect to geometry , It will apply all effects in a stuck&lt;br /&gt;
* We removed LPE gallery  (you can sill enable it in Preferences if you wish &amp;lt;code&amp;gt;Preferences -&amp;gt; Behavior -&amp;gt; LPE&amp;lt;/code&amp;gt; &lt;br /&gt;
* To see experimental LPEs you need to enable it in Preferences &amp;lt;code&amp;gt;Preferences -&amp;gt; Behavior -&amp;gt; LPE&amp;lt;/code&amp;gt; &lt;br /&gt;
* Added indicator which object is selected&lt;br /&gt;
* Added conversion commands when you select text objects - Since Text does not support LPEs yet we added workaround that convert text to path or clones the text&lt;br /&gt;
* If you select Object that is assorted with other LPE (Clone, Bool operations, Bend, Fill between many etc...) You will see button in Dialog that will take you to linked geometry/controls&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4677&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== XML Editor ===&lt;br /&gt;
[[File:Syntax highlighting.png|thumb|392x392px]]&lt;br /&gt;
We did small cosmetic changes to this dialog: smaller icons 16x16px , removed text tool tips. Added responsive layout and moved layout controls to top in to dropdown (auto layout is default option). &lt;br /&gt;
&lt;br /&gt;
==== Syntax highlighting: ====&lt;br /&gt;
For improving readability we added syntax color coding and auto line braking. This work for CSS style tag, Inline styling, d &amp;lt;path data&amp;gt; . You change change color coding themes in &amp;lt;code&amp;gt;Preferences -&amp;gt; Interface -&amp;gt; Theming&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4885  &lt;br /&gt;
&lt;br /&gt;
=== Symbols ===&lt;br /&gt;
You can drag and drop symbols on canvas and they are going to be place exactly where you dropped them. New icon &amp;quot;peace&amp;quot;. Improved performance . &lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4666&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4883&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4793&lt;br /&gt;
&lt;br /&gt;
=== Bitmap Tracer ===&lt;br /&gt;
Got significant performance boost. Now it takes advantage of CPU multithreading. &lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4702&lt;br /&gt;
== Filters ==&lt;br /&gt;
&lt;br /&gt;
== Live path effects ==&lt;br /&gt;
All labels are no align to one line. &lt;br /&gt;
&lt;br /&gt;
UI and Lale clean up for: &lt;br /&gt;
&lt;br /&gt;
Roughen LPE &lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4872 &lt;br /&gt;
&lt;br /&gt;
== Import / Export ==&lt;br /&gt;
&lt;br /&gt;
== Templates ==&lt;br /&gt;
&lt;br /&gt;
All template dialogs (Welcome screen, New from Template, Page tool default sizes) now use the same template sizes ([https://gitlab.com/inkscape/extensions/-/merge_requests/479] MR #479)&lt;br /&gt;
&lt;br /&gt;
== Customization / Theming ==&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
== macOS-specific Changes ==&lt;br /&gt;
&lt;br /&gt;
== Windows-specific Changes ==&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
==== General Extension Changes ====&lt;br /&gt;
&lt;br /&gt;
==== New Extensions ====&lt;br /&gt;
&lt;br /&gt;
==== Particular extensions ====&lt;br /&gt;
&lt;br /&gt;
=== Bugs fixed ===&lt;br /&gt;
&lt;br /&gt;
==== All extensions ====&lt;br /&gt;
&lt;br /&gt;
==== Particular extensions ====&lt;br /&gt;
&lt;br /&gt;
=== Extension Development ===&lt;br /&gt;
&lt;br /&gt;
==== API Changes for Third-Party Extension Developers ====&lt;br /&gt;
&lt;br /&gt;
==== Extension Development Documentation ====&lt;br /&gt;
&lt;br /&gt;
==== Under the hood ====&lt;br /&gt;
&lt;br /&gt;
== Command line ==&lt;br /&gt;
&lt;br /&gt;
== Behind the curtains ==&lt;br /&gt;
&lt;br /&gt;
== Notable bugfixes ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Crash fixes ===&lt;br /&gt;
&lt;br /&gt;
Fixed a crash that occurred …&lt;br /&gt;
&lt;br /&gt;
* when …&lt;br /&gt;
&lt;br /&gt;
=== Other bug fixes ===&lt;br /&gt;
&lt;br /&gt;
* LPE related Undo bugs  https://gitlab.com/inkscape/inkscape/-/merge_requests/4520&lt;br /&gt;
&lt;br /&gt;
=== Even more bug fixes ===&lt;br /&gt;
&lt;br /&gt;
There were even more issues fixed than those listed above, but these probably only affect a small portion of users, or are relevant for development and packaging only.&lt;br /&gt;
&lt;br /&gt;
For a complete list, visit [https://gitlab.com/inkscape/inkscape/-/issues?milestone_title=Inkscape+1.3 our GitLab issue tracker] and see the [https://gitlab.com/inkscape/inkscape/-/commits/1.3.x commit history].&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
The following UI translations received updates:&lt;br /&gt;
&lt;br /&gt;
* … &lt;br /&gt;
&lt;br /&gt;
The Windows installer translation was updated for:&lt;br /&gt;
&lt;br /&gt;
* … &lt;br /&gt;
&lt;br /&gt;
The following documentation translations received updates:&lt;br /&gt;
&lt;br /&gt;
* … &lt;br /&gt;
&lt;br /&gt;
=== Contributing to interface translations ===&lt;br /&gt;
&lt;br /&gt;
Want to help with translations? [https://inkscape.org/contribute/translations/ Learn how to help!]&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
=== Contributing to documentation and documentation translation ===&lt;br /&gt;
Contributions to the documentation translations, as well as improvements to its contents, are welcome at [https://gitlab.com/inkscape/inkscape-docs/documentation the inkscape-docs repository].&lt;br /&gt;
&lt;br /&gt;
== Website ==&lt;br /&gt;
&lt;br /&gt;
== Important changes for packagers ==&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&lt;br /&gt;
== Other releases ==&lt;br /&gt;
&lt;br /&gt;
{{:Release notes}}&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Release_notes/1.3&amp;diff=122025</id>
		<title>Release notes/1.3</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Release_notes/1.3&amp;diff=122025"/>
		<updated>2022-12-14T11:21:06Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: Explain how to customize fixed palette colors; add link to CSS4 color spec&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{Box| '''These Release Notes are in Draft Status.'''&lt;br /&gt;
&lt;br /&gt;
Note: Not all animations work, due to Wiki bugs with resizing images. Release notes will be transferred to website, there animations will be working.&lt;br /&gt;
&lt;br /&gt;
Important Links:&lt;br /&gt;
* [https://gitlab.com/inkscape/inkscape/commits/master Commit History Main Program (starting from: xxx)]&lt;br /&gt;
* [https://gitlab.com/inkscape/extensions/-/commits/master Commit History Extensions (starting from: xxx)]&lt;br /&gt;
* [https://gitlab.com/inkscape/inkscape-docs/documentation/-/tree/master Commit History Documentation (starting from: xxx)]&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Box| Pending questions:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Release highlights ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--'''Released on May xx, 2023 '''--&amp;gt;&lt;br /&gt;
&amp;lt;!--'''Definitely not released yet.'''--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Pattern editor , Pattern canvas controls, and pattern performance&lt;br /&gt;
*Shape builder - New tool for building complex  shapes form simple shapes. = live Boolean tool&lt;br /&gt;
*Live Path effects Dialog - Totally new improved &lt;br /&gt;
*Filter editor - New Redesign &lt;br /&gt;
* '''and so much more!'''&lt;br /&gt;
&lt;br /&gt;
== Performance ==&lt;br /&gt;
There has be lots of effort to improve performance of all aspects in Inkscape. Lots of refactoring of various inefficient code: Display- small hacks, handling of Patterns , Paint server and filters. After that we added Multi treading to Bitmap tracing, ...(more to come)&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests?scope=all&amp;amp;state=merged&amp;amp;label_name&amp;amp;#x5B;&amp;amp;#x5D;=Project%3A%3AMultithreading&lt;br /&gt;
&lt;br /&gt;
== General user interface ==&lt;br /&gt;
[[File:Indicators of used colors.png|thumb|indicators of used colors]]&lt;br /&gt;
Color palettes have indicator color of stroke and fill of selected object. The first 4 colors are pinned and have the ability to become larger than the rest. Other than the special &amp;quot;none&amp;quot; color, the remaining 3 can be customized by editing the file &amp;lt;code&amp;gt;palettes/default-fixed-colors.gpl&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[File:Inkscape BHd0t2kzml.gif]]&lt;br /&gt;
&lt;br /&gt;
=== New feature paste on page ===&lt;br /&gt;
You can copy and paste object from one page to another. &amp;lt;code&amp;gt;Edit &amp;gt; Specials Paste &amp;gt; Paste on page&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4695&lt;br /&gt;
&lt;br /&gt;
=== Old permanent snapping toolbar ===&lt;br /&gt;
Was added as an option&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;Settings &amp;gt; Interface &amp;gt; Toolbars&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keyboard shortcuts ===&lt;br /&gt;
&lt;br /&gt;
The keyboard shortcuts for aligning objects vertically and horizontally have been moved to the numeric keypad, where the other alignment shortcuts are, too:&lt;br /&gt;
&lt;br /&gt;
* Vertical alignment was moved from &amp;lt;kbd&amp;gt;Ctrl+Alt+T&amp;lt;/kbd&amp;gt; to &amp;lt;kbd&amp;gt;'''Ctrl+Alt+Numpad 1'''&amp;lt;/kbd&amp;gt;&lt;br /&gt;
* Horizontal alignment was moved from &amp;lt;kbd&amp;gt;Ctrl+Alt+H&amp;lt;/kbd&amp;gt; to &amp;lt;kbd&amp;gt;'''Ctrl+Alt+Numpad 7'''&amp;lt;/kbd&amp;gt;&lt;br /&gt;
[[File:OKLAB.png|thumb|358x358px]]&lt;br /&gt;
If you find yourself unable to reach the new shortcuts (for example, because your laptop does not have a keypad, or because the shortcuts do not work - may be the case on Linux with Xfce), you can set them to something else by changing '''both''' the alignment shortcut '''and''' the function that now uses that shortcut (if any). Use the search in &amp;lt;code&amp;gt;Edit &amp;gt; Preferences &amp;gt; Interface &amp;gt; Keyboard&amp;lt;/code&amp;gt;. It also allows searching for shortcuts, not only for their name (e.g. search for 'ctrl+alt+t' to find the new default action that is executed when that combo is pressed).&lt;br /&gt;
&lt;br /&gt;
=== Color Picker ===&lt;br /&gt;
Added support for the '''OKLab''' and '''OKLch''' color spaces which have just been adopted into the CSS Color Module Level 4  [https://www.w3.org/TR/css-color-4/#ok-lab draft recommendation]. OKLab is described in detail by its creator in an interesting blog post. The new picker is called &amp;quot;OKHSL&amp;quot; and is available from the dropdown.&lt;br /&gt;
&lt;br /&gt;
=== '''Rulers''' ===&lt;br /&gt;
Improved look. Fixed performance penalty. Added indicator of selection (its possible to trun off in preferences)&lt;br /&gt;
&lt;br /&gt;
== Canvas ==&lt;br /&gt;
&lt;br /&gt;
Pressing '''&amp;lt;code&amp;gt;F&amp;lt;/code&amp;gt;''' temporarily hides on-canvas overlays (transformation handles, grids, guides ...). This allows quick preview of final artwork without any distractions.&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4395&lt;br /&gt;
&lt;br /&gt;
Added display overlay controls in top right corners. You need to have scrollbars enable to see it.&lt;br /&gt;
&lt;br /&gt;
[[File:Canvas overlays.png|399x399px]]&lt;br /&gt;
&lt;br /&gt;
=== OpenGL Canvas rendering  (GPU rendering) ===&lt;br /&gt;
We added OpenGL rendering it is highly experimental and its turned off by default. (known to be broken on Mac ). Its known to be slower than CPU rendering  (gtk3 problems) and it will not be useful unti we migrate to gtk4&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Preferences -&amp;gt; rendering -&amp;gt; OpenGL&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4133&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
=== Selection tool ===&lt;br /&gt;
new commands:&lt;br /&gt;
&lt;br /&gt;
* '''Reapply transform''': ''Ctrl+Alt+T''  - This allows a user to perform a transformation multiple times and works from the canvas edits or from transform dialog or the select toolbar. &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Shortcut needs to change, it opens a terminal on Linux.&amp;lt;/span&amp;gt;&lt;br /&gt;
* '''Duplicate and transform''': ''Ctrl+Alt+D'' -This performs a duplication and then reapplies the previous transform to the duplicate. &amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;Shortcut needs to change, it minimizes the window on Linux.&amp;lt;/span&amp;gt;&lt;br /&gt;
* '''Clone while dragging:''' drag object + C - Drag object  move it and press C to clone in current position   https://gitlab.com/inkscape/inkscape/-/merge_requests/4752&amp;lt;br /&amp;gt; https://gitlab.com/inkscape/inkscape/-/merge_requests/4506&lt;br /&gt;
&lt;br /&gt;
[[File:Inkscape xfsvsc2oY9.gif|thumb|editing pattern on canvas]]&lt;br /&gt;
&lt;br /&gt;
=== Node tool ===&lt;br /&gt;
&lt;br /&gt;
==== Pattern editing ====&lt;br /&gt;
Pattern editing on canvas is now easier you can click on any part of pattern and it will show you controls on that position. We also outline that shows you edges of pattern. First square  controls position circle controls rotation and second square controls size  hold shift to constrain proportions. &lt;br /&gt;
&lt;br /&gt;
We also fixed performance problems with patterns so now you can have smaller patterns in project and also its possible to zoom in on pattern&lt;br /&gt;
&lt;br /&gt;
==== Lasso selection mode ====&lt;br /&gt;
We added new lasso selection mode hold alt and draw around nodes you want to select. Useful fore selecting nodes inside of complicated geometry&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4747&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Shape Builder tool (New tool) ===&lt;br /&gt;
New tool for fast shape building and Boolean operations. Shortcut &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Use: Select multiple overlapping shapes and select shipbuilder tool. Selection will be fragmented on overlapping areas everything else is going to be hidden until you confirm operation. Now you '''Click and drag''' to combine segments together or hold '''Shift  + Click and drag''' to substract  and '''Sigle click''' on segment to split. Adding is represented by Blue color removing by pink&lt;br /&gt;
&lt;br /&gt;
[[File:Shape_builder.gif]]&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4709&lt;br /&gt;
[[File:Ezgif.com-gif-maker (12).gif|right|600x600px]]&lt;br /&gt;
&lt;br /&gt;
=== Pages tool ===&lt;br /&gt;
Have controls for margins (guids):&lt;br /&gt;
&lt;br /&gt;
* An attribute on the page element to record the margin&lt;br /&gt;
* A new html/css style box model with tests&lt;br /&gt;
* New UI to set margins in the toolbar&lt;br /&gt;
* New on canvas controls for moving margins (with ctrl/shift)&lt;br /&gt;
* New display of margins in the same canvas group as the page border&lt;br /&gt;
&lt;br /&gt;
* Snapping for page margins&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4523&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Gradient tool ===&lt;br /&gt;
&lt;br /&gt;
* Allowing to change the ''repeat'' setting when multiple gradients are selected.&lt;br /&gt;
* Showing 'Multiple gradients' in the stop list when multiple gradients are selected (instead of a random stop).&lt;br /&gt;
* Allowing the editing of the offset of the start/end stops.&lt;br /&gt;
* Keeping the stop selected after the offset is changed in the toolbar (instead of selecting the 1st stop of the gradient).&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4339&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Path Operations ==&lt;br /&gt;
&lt;br /&gt;
New commands:&lt;br /&gt;
&lt;br /&gt;
'''Fracture''' Path-&amp;gt;fracture - every overlapping path will be silted in to separate object&lt;br /&gt;
&lt;br /&gt;
'''Flatten''' Path-&amp;gt;flatten - overlapping object vi be flatten visually (it  will delete path that are hidden behind a top path). Useful for separating colors for Screen printing and offset printing&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Masking / Clipping ==&lt;br /&gt;
&lt;br /&gt;
* A new option to '''preserve clips / masks when ungrouping''' objects has been added (&amp;lt;code&amp;gt;Edit → Preferences → Behavior → Clippaths and Masks: When ungroup, clip/mask is preserved in childrens&amp;lt;/code&amp;gt;). The option is active by default. This means that when you now ungroup a group that has been clipped, the elements inside it will inherit the clip. Previously, the clip was removed and everything became un-clipped. To go back to previous default behavior, deactivate this new option. ([https://gitlab.com/inkscape/inkscape/-/merge_requests/3564 MR #3564]) --&amp;gt;&lt;br /&gt;
[[File:Pattern editor1.gif|alt=Pattern editor|right|Pattern editor]]&lt;br /&gt;
&lt;br /&gt;
== Dialogs ==&lt;br /&gt;
&lt;br /&gt;
=== Fill and stroke Dialog ===&lt;br /&gt;
&lt;br /&gt;
==== New pattern editor ====&lt;br /&gt;
Added in to UI. You can preview patterns change name,  size, rotation, offset, gaps and colors for some specific patterns. We also added collections of patterns  &amp;lt;code&amp;gt;~paint/pattern.svg&amp;lt;/code&amp;gt;  so its easier to be organized .  Since  this allows  having much more patterns preset we also added search function .&lt;br /&gt;
&lt;br /&gt;
=== Filter editor ===&lt;br /&gt;
[[File:Filter-resize.gif|alt=Filter-resize|Filter-resize|left]]&lt;br /&gt;
&lt;br /&gt;
Redesign of this dialog:&lt;br /&gt;
&lt;br /&gt;
* Filter selection moved to a popover&lt;br /&gt;
* Effects are listed in a popup menu and can be selected by searching (by name)&lt;br /&gt;
* Adjusted connector sizes to make them more compact&lt;br /&gt;
* Fixed an issue where all parameters would initially be visible in a docked filter dialog&lt;br /&gt;
* Fixed min size of parameters panel to make it fit in a narrow docked dialog&lt;br /&gt;
* Reactive layout to accommodate wide dialog&lt;br /&gt;
* Added primitive filter attributes to fe-image and fe-tile (#1417)&lt;br /&gt;
* Replaced GTK color picker with Inkscape color picker&lt;br /&gt;
&lt;br /&gt;
* Sources can now be hidden (for most use cases only the source graphics is useful; other inputs are broken or need ux work) &amp;lt;br /&amp;gt;https://gitlab.com/inkscape/inkscape/-/merge_requests/4720[[File:Inkscape Y7U4yzIFTq.gif|thumb]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Layers and Objects ===&lt;br /&gt;
UX improvements:&lt;br /&gt;
&lt;br /&gt;
* you can click and drag  to change visibility of multiple objects&lt;br /&gt;
* selecting on group does not auto expand .&lt;br /&gt;
* Selecting multiple object and and changing  visibility/locking  applies to all selected&lt;br /&gt;
* We added search feature, Its limited implmentation.it does not auto apply search and you need to search for more 3 characters&lt;br /&gt;
* we added hover  indicator for rows and  layer colors&lt;br /&gt;
* added controls for opacity and blending mode&lt;br /&gt;
&lt;br /&gt;
We added shortcuts for layers navigation and actions:&lt;br /&gt;
&lt;br /&gt;
*   arrows to  navigate&lt;br /&gt;
*   space bur confirms (select, apply, open)&lt;br /&gt;
*  shift -&amp;gt; &amp;lt;- open close group&lt;br /&gt;
* shift up down to move  in Z order&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:VirtualBoxVM I675gipqe1.gif|thumb|1017x1017px|Place holder  demo of new LPE dialog]]&lt;br /&gt;
&lt;br /&gt;
=== Live Path Effects ( LPE ) ===&lt;br /&gt;
New redesigned LPE dialog. &lt;br /&gt;
&lt;br /&gt;
The compacted design merges organization and controls into one unit. You can reorder LPE by drag and drop whole effect. It adds fast search box and fast dropdown for adding effects.&lt;br /&gt;
&lt;br /&gt;
Single LPE has 5 controls:&lt;br /&gt;
&lt;br /&gt;
* Show/Hide Controls&lt;br /&gt;
* Visibility of Effect&lt;br /&gt;
* Delete Effect&lt;br /&gt;
* Context menu &lt;br /&gt;
** Re-order&lt;br /&gt;
** Duplicate&lt;br /&gt;
** Set as default&lt;br /&gt;
** Flatten&lt;br /&gt;
&lt;br /&gt;
[[File:LPE organization.png|right|266x266px]]&lt;br /&gt;
Reorganization of LPEs:&lt;br /&gt;
&lt;br /&gt;
Since we needed more compact way show All LPEs we Decided on a list that is organizes in to 6 Categories :&lt;br /&gt;
&lt;br /&gt;
Tools ,Distort, Generate, Convert, Experimental + Favorite&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Changes:&lt;br /&gt;
&lt;br /&gt;
* Setting presets for LPE was moved in to contextual menu&lt;br /&gt;
* Setting Favorite LPE was moved in to contextual menu&lt;br /&gt;
* Added New feature flatten - This will apply effect to geometry , It will apply all effects in a stuck&lt;br /&gt;
* We removed LPE gallery  (you can sill enable it in Preferences if you wish &amp;lt;code&amp;gt;Preferences -&amp;gt; Behavior -&amp;gt; LPE&amp;lt;/code&amp;gt; &lt;br /&gt;
* To see experimental LPEs you need to enable it in Preferences &amp;lt;code&amp;gt;Preferences -&amp;gt; Behavior -&amp;gt; LPE&amp;lt;/code&amp;gt; &lt;br /&gt;
* Added indicator which object is selected&lt;br /&gt;
* Added conversion commands when you select text objects - Since Text does not support LPEs yet we added workaround that convert text to path or clones the text&lt;br /&gt;
* If you select Object that is assorted with other LPE (Clone, Bool operations, Bend, Fill between many etc...) You will see button in Dialog that will take you to linked geometry/controls&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4677&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== XML Editor ===&lt;br /&gt;
[[File:Syntax highlighting.png|thumb|392x392px]]&lt;br /&gt;
We did small cosmetic changes to this dialog: smaller icons 16x16px , removed text tool tips. Added responsive layout and moved layout controls to top in to dropdown (auto layout is default option). &lt;br /&gt;
&lt;br /&gt;
==== Syntax highlighting: ====&lt;br /&gt;
For improving readability we added syntax color coding and auto line braking. This work for CSS style tag, Inline styling, d &amp;lt;path data&amp;gt; . You change change color coding themes in &amp;lt;code&amp;gt;Preferences -&amp;gt; Interface -&amp;gt; Theming&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4885  &lt;br /&gt;
&lt;br /&gt;
=== Symbols ===&lt;br /&gt;
You can drag and drop symbols on canvas and they are going to be place exactly where you dropped them. New icon &amp;quot;peace&amp;quot;. Improved performance . &lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4666&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4883&lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4793&lt;br /&gt;
&lt;br /&gt;
=== Bitmap Tracer ===&lt;br /&gt;
Got significant performance boost. Now it takes advantage of CPU multithreading. &lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4702&lt;br /&gt;
== Filters ==&lt;br /&gt;
&lt;br /&gt;
== Live path effects ==&lt;br /&gt;
All labels are no align to one line. &lt;br /&gt;
&lt;br /&gt;
UI and Lale clean up for: &lt;br /&gt;
&lt;br /&gt;
Roughen LPE &lt;br /&gt;
&lt;br /&gt;
https://gitlab.com/inkscape/inkscape/-/merge_requests/4872 &lt;br /&gt;
&lt;br /&gt;
== Import / Export ==&lt;br /&gt;
&lt;br /&gt;
== Templates ==&lt;br /&gt;
&lt;br /&gt;
All template dialogs (Welcome screen, New from Template, Page tool default sizes) now use the same template sizes ([https://gitlab.com/inkscape/extensions/-/merge_requests/479] MR #479)&lt;br /&gt;
&lt;br /&gt;
== Customization / Theming ==&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
&lt;br /&gt;
== macOS-specific Changes ==&lt;br /&gt;
&lt;br /&gt;
== Windows-specific Changes ==&lt;br /&gt;
&lt;br /&gt;
== Extensions ==&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
==== General Extension Changes ====&lt;br /&gt;
&lt;br /&gt;
==== New Extensions ====&lt;br /&gt;
&lt;br /&gt;
==== Particular extensions ====&lt;br /&gt;
&lt;br /&gt;
=== Bugs fixed ===&lt;br /&gt;
&lt;br /&gt;
==== All extensions ====&lt;br /&gt;
&lt;br /&gt;
==== Particular extensions ====&lt;br /&gt;
&lt;br /&gt;
=== Extension Development ===&lt;br /&gt;
&lt;br /&gt;
==== API Changes for Third-Party Extension Developers ====&lt;br /&gt;
&lt;br /&gt;
==== Extension Development Documentation ====&lt;br /&gt;
&lt;br /&gt;
==== Under the hood ====&lt;br /&gt;
&lt;br /&gt;
== Command line ==&lt;br /&gt;
&lt;br /&gt;
== Behind the curtains ==&lt;br /&gt;
&lt;br /&gt;
== Notable bugfixes ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Crash fixes ===&lt;br /&gt;
&lt;br /&gt;
Fixed a crash that occurred …&lt;br /&gt;
&lt;br /&gt;
* when …&lt;br /&gt;
&lt;br /&gt;
=== Other bug fixes ===&lt;br /&gt;
&lt;br /&gt;
* LPE related Undo bugs  https://gitlab.com/inkscape/inkscape/-/merge_requests/4520&lt;br /&gt;
&lt;br /&gt;
=== Even more bug fixes ===&lt;br /&gt;
&lt;br /&gt;
There were even more issues fixed than those listed above, but these probably only affect a small portion of users, or are relevant for development and packaging only.&lt;br /&gt;
&lt;br /&gt;
For a complete list, visit [https://gitlab.com/inkscape/inkscape/-/issues?milestone_title=Inkscape+1.3 our GitLab issue tracker] and see the [https://gitlab.com/inkscape/inkscape/-/commits/1.3.x commit history].&lt;br /&gt;
&lt;br /&gt;
== Translations ==&lt;br /&gt;
&lt;br /&gt;
The following UI translations received updates:&lt;br /&gt;
&lt;br /&gt;
* … &lt;br /&gt;
&lt;br /&gt;
The Windows installer translation was updated for:&lt;br /&gt;
&lt;br /&gt;
* … &lt;br /&gt;
&lt;br /&gt;
The following documentation translations received updates:&lt;br /&gt;
&lt;br /&gt;
* … &lt;br /&gt;
&lt;br /&gt;
=== Contributing to interface translations ===&lt;br /&gt;
&lt;br /&gt;
Want to help with translations? [https://inkscape.org/contribute/translations/ Learn how to help!]&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
&lt;br /&gt;
=== Contributing to documentation and documentation translation ===&lt;br /&gt;
Contributions to the documentation translations, as well as improvements to its contents, are welcome at [https://gitlab.com/inkscape/inkscape-docs/documentation the inkscape-docs repository].&lt;br /&gt;
&lt;br /&gt;
== Website ==&lt;br /&gt;
&lt;br /&gt;
== Important changes for packagers ==&lt;br /&gt;
&lt;br /&gt;
== Known issues ==&lt;br /&gt;
&lt;br /&gt;
== Other releases ==&lt;br /&gt;
&lt;br /&gt;
{{:Release notes}}&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Multipage&amp;diff=121890</id>
		<title>Multipage</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Multipage&amp;diff=121890"/>
		<updated>2022-07-30T22:11:35Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: Fix typos, grammar and repair a broken link in the &amp;quot;Pages Tool&amp;quot; section.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Multi-page feature was added in [[Release notes/1.2|Inkscape 1.2]]. Its front end was implemented as a new Pages Tool in the toolbar. Pages are saved to an SVG document in the &amp;lt;code&amp;gt;namedview&amp;lt;/code&amp;gt; tag as custom, Inkscape-specific elements (which do not work on the web and are not part of the SVG standard).&lt;br /&gt;
&lt;br /&gt;
The first page serves as the SVG viewbox.&lt;br /&gt;
&lt;br /&gt;
=== Pages Tool ===&lt;br /&gt;
The new Pages Tool (lowest button in the toolbar) allows you to create multi-page Inkscape documents, and to import as well as export multi-page PDF documents. (MR #3486, MR #3785, MR #3821). It supports overlapping pages and pages of different sizes in a single document.&lt;br /&gt;
&lt;br /&gt;
==== Importing ====&lt;br /&gt;
Multi-page documents can be imported with their pages appended as new pages in the existing document. Select the correct option in the window that pops up to append pages rather than import shapes as usual. This can be used to merge multiple PDF files.&lt;br /&gt;
&lt;br /&gt;
Saving a multi-page document to a format capable of storing multiple pages (e.g., PDF) will automatically save all pages.&lt;br /&gt;
Exporting individual pages can be done in the new export dialog in batch mode. It is also possible to export each individual page in the Single export tab. Use this to split SVG or PDF documents into individual pages. ''Note: it's not yet possible to select a sub-selection of multiple pages to export.''&lt;br /&gt;
&lt;br /&gt;
'''Tool usage:'''&lt;br /&gt;
&lt;br /&gt;
* To '''create a new page''' either:&lt;br /&gt;
** click-and-drag on the canvas, or&lt;br /&gt;
** click on the 'Create a new page' button in the tool controls.&lt;br /&gt;
* To '''delete a page''', click on the page to select it, then click on the button &amp;lt;code&amp;gt;Delete selected page&amp;lt;/code&amp;gt; or use the &amp;lt;code&amp;gt;Delete&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Backspace&amp;lt;/code&amp;gt; keys.&lt;br /&gt;
* To '''move a page''' on the canvas, click-and-drag it to the desired new position. If the option to &amp;lt;code&amp;gt;Move overlapping objects&amp;lt;/code&amp;gt; is active, this will move any objects that touch the page along with it.&lt;br /&gt;
* To '''change a page's size''':&lt;br /&gt;
** click on a page whose size you want to change to select it, then drag a square-shaped handle in one of the corners, or&lt;br /&gt;
** click on a page, then choose one of the predefined sizes in the page size dropdown, or enter your dimensions for the 'Custom' option, by typing them into the field in the format &amp;lt;code&amp;gt;10cm x 15cm&amp;lt;/code&amp;gt;.&lt;br /&gt;
* In order to '''fit a page''' to:&lt;br /&gt;
** the size of '''the drawing''': make sure to have no object selected before you switch to the Pages tool. Then select a page by clicking on it, then click on the button 'Fit page to drawing or selection' in the tool controls;&lt;br /&gt;
** '''a selected object''': first select the object(s) with the selection tool, then switch to the Pages tool, click on a page to select it, then press the the button 'Fit page to drawing or selection' in the tool controls.&lt;br /&gt;
* To '''add a label''' to your page, select the page by clicking on it, then enter a name or label for it into the text field in the page tool's controls. Labels are always visible, no matter which tool is currently selected.&lt;br /&gt;
* To '''export a multi-page PDF''' file, use &amp;lt;code&amp;gt;File → Save a copy … → PDF&amp;lt;/code&amp;gt;. This will automatically include all pages. If you only want to export a certain page, or a selection of pages, the updated [[Release notes/1.2#Export%20Dialog|&amp;lt;code&amp;gt;File → Export&amp;lt;/code&amp;gt; dialog]]'s batch export tab can help you get that done (one file per page).&lt;br /&gt;
* To export pages as separate documents, use the Export dialog.&lt;br /&gt;
* To '''open or import a multi-page PDF or AI (pdf-based)''' file, use &amp;lt;code&amp;gt;File → Open/Import → select file name → choose to import 'All' pages&amp;lt;/code&amp;gt; [Known issue: 'import' moves content of some pages to some far-out place in the drawing]&lt;br /&gt;
* You can navigate pages with page navigator which will show up in right down corner of status bar&lt;br /&gt;
&lt;br /&gt;
''Note: Multi-page SVG files are an Inkscape-specific concept. Web browsers will only display the first page of your document, which corresponds to the 'viewbox' area of the SVG file.''&lt;br /&gt;
[[File:Inkscape o2RwP02rKw.gif|none|thumb|487x487px|multipage ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Multipage in the SVG 1.2 standard (dropped) ==&lt;br /&gt;
*All pages are contained within a single pageSet element. A pageSet may contain any number of page elements. Each page element defines a single container of graphical objects.&lt;br /&gt;
* In a screen-based user agent, only one page element is displayed at any time on the main canvas.&lt;br /&gt;
*The SVG content typically defines a page dimension or aspect ratio in the topmost svg element and its viewBox. The viewBox transformation applies to printed SVG in the same way as screen display.&lt;br /&gt;
*The orientation of each page element can be controlled by the page-orientation property. This enables the content to define whether a portrait or landscape mode is used for display and printing.&lt;br /&gt;
&lt;br /&gt;
==Inkscape-pages extension ==&lt;br /&gt;
&lt;br /&gt;
Developer lixapopescu created a inkscape extension in 2011 which hacked into inkscape some multi page support. https://sourceforge.net/projects/inkscape-pages/&lt;br /&gt;
&lt;br /&gt;
The design is based on using layers as the basis for pages and it's a useful hack if the svg specification will always not include pages.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Multipage&amp;diff=121880</id>
		<title>Multipage</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Multipage&amp;diff=121880"/>
		<updated>2022-07-30T01:18:29Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: Mark as outdated (multipage added in v1.2)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Outdated}}&lt;br /&gt;
&lt;br /&gt;
==Multipage support ==&lt;br /&gt;
&lt;br /&gt;
Currently, Inkscape does '''not''' have multipage support. The main reason is that the current SVG standard does not support multipage documents. This feature was proposed in the SVG revision 1.2, but for now got dropped in the next coming version SVG 2.0.&lt;br /&gt;
&lt;br /&gt;
[[http://wiki.inkscape.org/wiki/index.php/SVG_WorkingGroup#Multipage_document_support SVG 2.0 draft on multiple pages]]&lt;br /&gt;
&lt;br /&gt;
[[http://www.w3.org/TR/2004/WD-SVG12-20041027/multipage.html SVG 1.2 proposal for multiple pages]].&lt;br /&gt;
&lt;br /&gt;
This page discusses how the feature can (or should) be implemented:&lt;br /&gt;
&lt;br /&gt;
*There should be multiple pages within a document.&lt;br /&gt;
*There are two contrary implementations in the real world:&lt;br /&gt;
**distribute pages around the graphics elements - the Adobe way&lt;br /&gt;
**distribute graphics elements around the pages - how Corel does it and how SVG proposes to do it&lt;br /&gt;
*New problems arise when saving to singlepage file formats (jpg, png, etc).&lt;br /&gt;
&lt;br /&gt;
==Multipage in the SVG 1.2 standard (dropped) ==&lt;br /&gt;
*All pages are contained within a single pageSet element. A pageSet may contain any number of page elements. Each page element defines a single container of graphical objects.&lt;br /&gt;
* In a screen-based user agent, only one page element is displayed at any time on the main canvas.&lt;br /&gt;
*The SVG content typically defines a page dimension or aspect ratio in the topmost svg element and its viewBox. The viewBox transformation applies to printed SVG in the same way as screen display.&lt;br /&gt;
*The orientation of each page element can be controlled by the page-orientation property. This enables the content to define whether a portrait or landscape mode is used for display and printing.&lt;br /&gt;
&lt;br /&gt;
==Multipage à la Corel ==&lt;br /&gt;
*There is a list of pages as tabs on the lower side of the drawing window.&lt;br /&gt;
*All pages share the same page properties.&lt;br /&gt;
*A '''master page''' contains elements that are visible on all other pages: drawings, markers&lt;br /&gt;
* In an object browser, pages and layers are integrated.&lt;br /&gt;
&lt;br /&gt;
See [[http://wiki.inkscape.org/wiki/images/Corel_pages.PNG this screeshot]].&lt;br /&gt;
&lt;br /&gt;
==Multicanvas (similar to multi-Artboard on adobe illustrator cs4). ==&lt;br /&gt;
Multicanvas solution is not the same as pages and can't follow the SVG pageSet spec. The multicanvas, as the multi-artboard, can (frequently must) have different sizes and can be freely placed on the 2D space. A canvas may overlap a part other canvas.&lt;br /&gt;
&lt;br /&gt;
Each canvas can be printed independently and that feature helps to unify the art conception for the most applications of an art project.&lt;br /&gt;
&lt;br /&gt;
*see this adobe tutorial [[http://www.adobe.com/designcenter/illustrator/articles/lrvid4016_ai.html here]]&lt;br /&gt;
*there is an [[http://www.vimeo.com/2503097 video]] by Valessio Brito presenting an UI mockup how multipage can be handled in inkscape&lt;br /&gt;
&lt;br /&gt;
The multicanvas feature may be incompatible with the multipage feature, so, the user may chose the working mode on the &amp;quot;document properties&amp;quot; dialog. The default must be multipage and that will show the page tabs on the interface and the &amp;quot;new page&amp;quot; button, when selecting multicanvas that will show the canvas controls and the &amp;quot;new canvas&amp;quot; button.&lt;br /&gt;
&lt;br /&gt;
Feature request registered: https://bugs.launchpad.net/inkscape/+bug/671081&lt;br /&gt;
&lt;br /&gt;
==Inkscape-pages extension ==&lt;br /&gt;
&lt;br /&gt;
Developer lixapopescu created a inkscape extension in 2011 which hacked into inkscape some multi page support. https://sourceforge.net/projects/inkscape-pages/&lt;br /&gt;
&lt;br /&gt;
The design is based on using layers as the basis for pages and it's a useful hack if the svg specification will always not include pages.&lt;br /&gt;
&lt;br /&gt;
==Implementation ==&lt;br /&gt;
*Some planning was done in [http://www.nabble.com/Multipage-plan-td16394431.html this thread]. BROKEN LINK&lt;br /&gt;
*All export dialogues must get extra properties in order to handle multiple pages, e.g. for specifying not only the elements, but also the pages to be exported.&lt;br /&gt;
*Some prelim work has landed: https://gitlab.com/inkscape/inkscape/commit/a6162e760c7eab68fc65a4ccc879e73ab0c20c1b&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Killing_Livarot&amp;diff=121854</id>
		<title>Killing Livarot</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Killing_Livarot&amp;diff=121854"/>
		<updated>2022-06-12T17:16:06Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: Updates to the work items section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details work items that need to be completed in order to remove Livarot from Inkscape's code base.&lt;br /&gt;
&lt;br /&gt;
This project requires a substantial amount of work and welcomes all volunteers who would like to contribute &lt;br /&gt;
code, help in code review, as well as help test the new functionality at later stages of the development.&lt;br /&gt;
&lt;br /&gt;
== Work items ==&lt;br /&gt;
&lt;br /&gt;
=== Project Path Operations ===&lt;br /&gt;
There's an initial implementation of path boolean operations in lib2geom (MSc thesis subject of Krzysztof Kosiński),&lt;br /&gt;
but it needs substantially more work before it has all the features and proven reliability needed to fully replace Livarot.&lt;br /&gt;
&lt;br /&gt;
==== Path Intersection Graph ====&lt;br /&gt;
The &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt; class underlies all existing boolean operations in lib2geom, implementing the [https://en.wikipedia.org/wiki/Greiner%E2%80%93Hormann_clipping_algorithm Greiner-Hormann algorithm]. &lt;br /&gt;
Unfortunately, the current implementation is flawed in several ways. &lt;br /&gt;
For instance, it cannot handle certain kinds of intersections, e.g., two paths merging and traveling together for some distance.&lt;br /&gt;
Furthermore, it's not able to compute the union, intersection or difference of two identical shapes (as of May 2022).&lt;br /&gt;
&lt;br /&gt;
* Write a path uncrossing algorithm.&amp;lt;br/&amp;gt;This provides a &amp;lt;code&amp;gt;flatten&amp;lt;/code&amp;gt; primitive which removes self-overlaps and self-crossings and replaces &amp;lt;code&amp;gt;sp_flatten&amp;lt;/code&amp;gt; [https://gitlab.com/inkscape/inkscape/-/blob/master/src/path/path-boolop.h#L17]. A path that self-intersects should be cut at the intersection points and replaced by one or several paths that do not have self-intersections. Note that we only need to remove actual transverse self-intersections and not all spurious solutions from the sweepline algorithm.&amp;lt;br/&amp;gt;In order to work as the definition of an actual “shape”, a path-vector must not have transverse intersection and must follow the convention that each path has the shape on its left and the outside on its right (if the y-axis is pointing up). Currently being worked on by [https://gitlab.com/S-Rafael @S-Rafael]. [[File:Flatten.png|frame|The &amp;quot;flatten&amp;quot; operation replaces a self-intersecting path with one that doesn't cross over itself. The result path, shown on the right, has the same fill region regardless of whether &amp;quot;even-odd&amp;quot; or &amp;quot;nonzero&amp;quot; fill rule is used.]]&lt;br /&gt;
&lt;br /&gt;
* Write a new implementation of the boolean operations, using the Greiner-Hormann algorithm and insights from Livarot. The new implementation should use a “geometric” strategy for the classification of crossings and deciding which path portions lie inside the other shape. Currently [https://gitlab.com/S-Rafael @S-Rafael] is designing this feature.&lt;br /&gt;
&lt;br /&gt;
* Write functions that implement path cutting (slicing) and division. “Slicing” refers to cutting all paths in a path-vector along all intersection points with another path-vector.  “Division” refers to using one path-vector as a “cookie cutter” which divides the other path-vector (the “dough”) into several shapes. [[File:Division.png|frame|The &amp;quot;division&amp;quot; operation is analogous to using a cookie cutter on a piece of dough. Note that the white gaps between the resulting pieces have been thickened for better visibility; in reality, these pieces should fit together perfectly.]]&lt;br /&gt;
&lt;br /&gt;
* Write a function which splits a shape into connected components; this corresponds to &amp;lt;code&amp;gt;split_non_overlapping&amp;lt;/code&amp;gt; in Inkscape and should be implemented directly in the &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Write a lot of unit tests to ensure that all this functionality is robust and handles all weird and exotic corner cases. If the “geometric” classification strategy works well, make it the default strategy.&lt;br /&gt;
&lt;br /&gt;
* If possible, remove all exceptions from &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Implement overloaded boolean operators &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; on &amp;lt;code&amp;gt;Shape&amp;lt;/code&amp;gt; operands. This is just a cherry on top of the cake and should be added once the new strategy is robust enough for general use.&lt;br /&gt;
&lt;br /&gt;
* Start migrating the path and boolean operations in Inkscape to the new lib2geom implementation. This will involve rewriting most of the source file [https://gitlab.com/inkscape/inkscape/-/blob/master/src/path/path-boolop.cpp path-boolop.cpp] in Inkscape and eventually deleting it entirely.&lt;br /&gt;
&lt;br /&gt;
* Migrate all Live Path Effects which use boolean operations to the new lib2geom facilities.&lt;br /&gt;
&lt;br /&gt;
* Implement boolean operations on sets of shapes, including nested groups [https://gitlab.com/inkscape/inbox/-/issues/7121]. [[File:Exclusion-on-groups.png|frame|The proposed &amp;quot;exclusion&amp;quot; operation on groups of shapes; based on an illustration by Chris Rogers.]]&lt;br /&gt;
&lt;br /&gt;
* Measure the performance of the new boolean operations and devise performance optimizations; in particular consider cache-friendliness of the code and whether or not &amp;lt;code&amp;gt;boost::ptr_vector&amp;lt;/code&amp;gt; is actually a good container for this use case.&lt;br /&gt;
&lt;br /&gt;
=== The Shape Tool ===&lt;br /&gt;
The new tool (shape tool/welder tool/shape welder) [https://gitlab.com/inkscape/ux/-/issues/109 was proposed] as an alternative to “shape builder” functionality found in other vector drawing programs.    &lt;br /&gt;
Developing this functionality was the subject of the 2021 Google Summer of Code project  by [https://gitlab.com/osamaahmad Osama Ahmad] under the title “On-canvas interactive boolean operations”.&lt;br /&gt;
Nonetheless, the [https://gitlab.com/inkscape/inkscape/-/merge_requests/3357 already-developed UI] requires a stable and convenient engine that can power this tool.&lt;br /&gt;
&lt;br /&gt;
=== Path outliner ===&lt;br /&gt;
Path outliner was worked on by Liam but the status of this work is unknown. &lt;br /&gt;
The biggest obstacle to a robust path outlining functionality is the unreliability of the lib2geom boolean operations as of May 2022.&lt;br /&gt;
Once the boolean operations are robust, path outlining can be developed on this basis, although it still requires some work; the main tasks are listed below.&lt;br /&gt;
&lt;br /&gt;
* Write outlining functions for all curve types used in SVG specification: quadratic and cubic Bézier curves, elliptical arcs. A design requirement is the ability to control the relative error of the outline distance (contact [https://gitlab.com/S-Rafael @S-Rafael] for more details).&lt;br /&gt;
&lt;br /&gt;
* Optionally, provide outlining algorithms for other curve types supported by lib2geom.&lt;br /&gt;
&lt;br /&gt;
* The final implementation should outline paths by outlining the constituent curves and combining the outlines with boolean union.&amp;lt;br/&amp;gt;At first glance, this may seem excessively complicated compared to the apparently simple [https://ieeexplore.ieee.org/abstract/document/4055919 Tiller–Hanson method], but is actually required for a general implementation. Note that the Tiller–Hanson algorithm was invented for shapes used in CAD, which are a lot less crazy and irregular than arbitrary paths which lib2geom must support.&lt;br /&gt;
&lt;br /&gt;
* Write unit tests for the path outliner.&lt;br /&gt;
&lt;br /&gt;
* Measure performance and optimize.&lt;br /&gt;
&lt;br /&gt;
=== Crazy text layout dependency ===&lt;br /&gt;
The text layout engine (formerly contained in the &amp;quot;libnrtype&amp;quot; library) uses Livarot for line-breaking text in flow regions. This involves using path outline and boolean operation functionality in Livarot and has been the source of some bugs and headaches. However, once path outlining is available in lib2geom, it will not be very hard to use it to create flow regions with variable padding.&lt;br /&gt;
&lt;br /&gt;
=== Python API ===&lt;br /&gt;
All of the new functionality described above should be gradually exposed in the Python API, so that Inkscape's extensions can call lib2geom directly instead of routing their calls through Inkscape. This will enable extension authors to perform advanced path operations directly in their Python code.&lt;br /&gt;
&lt;br /&gt;
=== Streaming outliner ===&lt;br /&gt;
&lt;br /&gt;
[[File:Gnarly.png|thumb|A gnarly, jagged outline created by the Eraser Tool due to the retrograde motion of the ends of the tool's nib.]]&lt;br /&gt;
The free-hand drawing tools in Inkscape, such as the Calligraphic and Eraser tools, implement a very primitive (but fast) form of path outlining via Bézier fitting. This outlining method causes some problems such as a gnarly, knotted tool trace when one of the  nib extremities experiences retrograde motion (leading to the fitting of Bézier curves with loops) [https://gitlab.com/inkscape/inkscape/-/issues/1124].&lt;br /&gt;
&lt;br /&gt;
A much more robust replacement for use in tools would be a “streaming outliner” which accepts incoming sample points in real time, outlines the incoming segments and appends them to a stored, gradually growing outline of the toolpath. This is a long-term goal, since it would require a more streaming-friendly implementation of the functionality in &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;. In addition to enabling a substantial improvement on the extremely crufty &amp;lt;code&amp;gt;FreehandBase&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;CalligraphicTool&amp;lt;/code&amp;gt; classes in Inkscape (as of May 2022), it could help improve the performance of the Pencil Tool.&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer Discussion]]&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Killing_Livarot&amp;diff=121853</id>
		<title>Killing Livarot</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Killing_Livarot&amp;diff=121853"/>
		<updated>2022-06-08T17:33:25Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: Status update on &amp;quot;flatten&amp;quot;, reflect the removal of libnrtype.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details work items that need to be completed in order to remove Livarot from Inkscape's code base.&lt;br /&gt;
&lt;br /&gt;
This project requires a substantial amount of work and welcomes all volunteers who would like to contribute &lt;br /&gt;
code, help in code review, as well as help test the new functionality at later stages of the development.&lt;br /&gt;
&lt;br /&gt;
== Work items ==&lt;br /&gt;
&lt;br /&gt;
=== Project Path Operations ===&lt;br /&gt;
There's an initial implementation of path boolean operations in lib2geom (MSc thesis subject of Krzysztof Kosiński),&lt;br /&gt;
but it needs substantially more work before it has all the features and proven reliability needed to fully replace Livarot.&lt;br /&gt;
&lt;br /&gt;
==== Path Intersection Graph ====&lt;br /&gt;
The &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt; class underlies all existing boolean operations in lib2geom, implementing the [https://en.wikipedia.org/wiki/Greiner%E2%80%93Hormann_clipping_algorithm Greiner-Hormann algorithm]. &lt;br /&gt;
Unfortunately, the current implementation is flawed in several ways. &lt;br /&gt;
For instance, it cannot handle certain kinds of intersections, e.g., two paths merging and traveling together for some distance.&lt;br /&gt;
Furthermore, it's not able to compute the union, intersection or difference of two identical shapes (as of May 2022).&lt;br /&gt;
&lt;br /&gt;
* Write additional unit tests for the &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt; to capture some of the existing breakage; currently being worked on by [https://gitlab.com/S-Rafael @S-Rafael].&lt;br /&gt;
* Rework the inclusion classification in the &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;, a key step of the Greiner-Hormann algorithm. This provides an alternative “geometric” strategy for the classification of crossings and deciding which path portions lie inside the other path-vector. Currently being worked on by [https://gitlab.com/S-Rafael @S-Rafael].&lt;br /&gt;
* Write a path uncrossing algorithm.&amp;lt;br/&amp;gt;This provides a &amp;lt;code&amp;gt;flatten&amp;lt;/code&amp;gt; primitive which removes self-overlaps and self-crossings with the help of  &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;. A path that self-intersects should be cut at the intersection points and replaced by one or several paths that do not have self-intersections. Note that we only need to remove actual transverse self-intersections and not all spurious solutions from the sweepline algorithm.&amp;lt;br/&amp;gt;Implicitly, the 2-dimensional shapes in lib2geom are defined by path-vectors using the “even-odd” fill rule. The flattening function converts such a path-vector to one which works with the “non-zero” fill rule, similar to &amp;lt;code&amp;gt;sp_flatten&amp;lt;/code&amp;gt;. At the moment, [https://gitlab.com/S-Rafael @S-Rafael] is working on some supporting functionality needed to implement this function. [https://gitlab.com/inkscape/inkscape/-/blob/master/src/path/path-boolop.h#L17]. [[File:Flatten.png|frame|The &amp;quot;flatten&amp;quot; operation replaces a self-intersecting path with one that doesn't cross over itself. The result path, shown on the right, has the same fill region regardless of whether &amp;quot;even-odd&amp;quot; or &amp;quot;nonzero&amp;quot; fill rule is used.]]&lt;br /&gt;
&lt;br /&gt;
* Write functions that implement path cutting (slicing) and division. “Slicing” refers to cutting all paths in a path-vector along all intersection points with another path-vector.  “Division” refers to using one path-vector as a “cookie cutter” which divides the other path-vector (the “dough”) into several shapes. [[File:Division.png|frame|The &amp;quot;division&amp;quot; operation is analogous to using a cookie cutter on a piece of dough. Note that the white gaps between the resulting pieces have been thickened for better visibility; in reality, these pieces should fit together perfectly.]]&lt;br /&gt;
&lt;br /&gt;
* Write a function which splits a shape into connected components; this corresponds to &amp;lt;code&amp;gt;split_non_overlapping&amp;lt;/code&amp;gt; in Inkscape and should be implemented directly in the &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Write even more unit tests to ensure that all this functionality is robust and handles all weird and exotic corner cases. If the “geometric” classification strategy works well, make it the default strategy.&lt;br /&gt;
&lt;br /&gt;
* If possible, remove all exceptions from &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Implement overloaded boolean operators &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; on &amp;lt;code&amp;gt;PathVector&amp;lt;/code&amp;gt; operands. This is just a cherry on top of the cake and should be added once the new strategy is robust enough for general use.&lt;br /&gt;
&lt;br /&gt;
* Start migrating the path and boolean operations in Inkscape to the new lib2geom implementation. This will involve rewriting most of the source file [https://gitlab.com/inkscape/inkscape/-/blob/master/src/path/path-boolop.cpp path-boolop.cpp] in Inkscape and eventually deleting it entirely.&lt;br /&gt;
&lt;br /&gt;
* Migrate all Live Path Effects which use boolean operations to the new lib2geom facilities.&lt;br /&gt;
&lt;br /&gt;
* Implement boolean operations on sets of shapes, including nested groups [https://gitlab.com/inkscape/inbox/-/issues/7121]. [[File:Exclusion-on-groups.png|frame|The proposed &amp;quot;exclusion&amp;quot; operation on groups of shapes; based on an illustration by Chris Rogers.]]&lt;br /&gt;
&lt;br /&gt;
* Measure the performance of the new boolean operations and devise performance optimizations; in particular consider cache-friendliness of the code and whether or not &amp;lt;code&amp;gt;boost::ptr_vector&amp;lt;/code&amp;gt; is actually a good container for this use case.&lt;br /&gt;
&lt;br /&gt;
=== The Shape Tool ===&lt;br /&gt;
The new tool (shape tool/welder tool/shape welder) [https://gitlab.com/inkscape/ux/-/issues/109 was proposed] as an alternative to “shape builder” functionality found in other vector drawing programs.    &lt;br /&gt;
Developing this functionality was the subject of the 2021 Google Summer of Code project  by [https://gitlab.com/osamaahmad Osama Ahmad] under the title “On-canvas interactive boolean operations”.&lt;br /&gt;
Nonetheless, the [https://gitlab.com/inkscape/inkscape/-/merge_requests/3357 already-developed UI] requires a stable and convenient engine that can power this tool.&lt;br /&gt;
&lt;br /&gt;
=== Path outliner ===&lt;br /&gt;
Path outliner was worked on by Liam but the status of this work is unknown. &lt;br /&gt;
The biggest obstacle to a robust path outlining functionality is the unreliability of the lib2geom boolean operations as of May 2022.&lt;br /&gt;
Once the boolean operations are robust, path outlining can be developed on this basis, although it still requires some work; the main tasks are listed below.&lt;br /&gt;
&lt;br /&gt;
* Write outlining functions for all curve types used in SVG specification: quadratic and cubic Bézier curves, elliptical arcs. A design requirement is the ability to control the relative error of the outline distance (contact [https://gitlab.com/S-Rafael @S-Rafael] for more details).&lt;br /&gt;
&lt;br /&gt;
* Optionally, provide outlining algorithms for other curve types supported by lib2geom.&lt;br /&gt;
&lt;br /&gt;
* The final implementation should outline paths by outlining the constituent curves and combining the outlines with boolean union.&amp;lt;br/&amp;gt;At first glance, this may seem excessively complicated compared to the apparently simple [https://ieeexplore.ieee.org/abstract/document/4055919 Tiller–Hanson method], but is actually required for a general implementation. Note that the Tiller–Hanson algorithm was invented for shapes used in CAD, which are a lot less crazy and irregular than arbitrary paths which lib2geom must support.&lt;br /&gt;
&lt;br /&gt;
* Write unit tests for the path outliner.&lt;br /&gt;
&lt;br /&gt;
* Measure performance and optimize.&lt;br /&gt;
&lt;br /&gt;
=== Crazy text layout dependency ===&lt;br /&gt;
The text layout engine (formerly contained in the &amp;quot;libnrtype&amp;quot; library) uses Livarot for line-breaking text in flow regions. This involves using path outline and boolean operation functionality in Livarot and has been the source of some bugs and headaches. However, once path outlining is available in lib2geom, it will not be very hard to use it to create flow regions with variable padding.&lt;br /&gt;
&lt;br /&gt;
=== Python API ===&lt;br /&gt;
All of the new functionality described above should be gradually exposed in the Python API, so that Inkscape's extensions can call lib2geom directly instead of routing their calls through Inkscape. This will enable extension authors to perform advanced path operations directly in their Python code.&lt;br /&gt;
&lt;br /&gt;
=== Streaming outliner ===&lt;br /&gt;
&lt;br /&gt;
[[File:Gnarly.png|thumb|A gnarly, jagged outline created by the Eraser Tool due to the retrograde motion of the ends of the tool's nib.]]&lt;br /&gt;
The free-hand drawing tools in Inkscape, such as the Calligraphic and Eraser tools, implement a very primitive (but fast) form of path outlining via Bézier fitting. This outlining method causes some problems such as a gnarly, knotted tool trace when one of the  nib extremities experiences retrograde motion (leading to the fitting of Bézier curves with loops) [https://gitlab.com/inkscape/inkscape/-/issues/1124].&lt;br /&gt;
&lt;br /&gt;
A much more robust replacement for use in tools would be a “streaming outliner” which accepts incoming sample points in real time, outlines the incoming segments and appends them to a stored, gradually growing outline of the toolpath. This is a long-term goal, since it would require a more streaming-friendly implementation of the functionality in &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;. In addition to enabling a substantial improvement on the extremely crufty &amp;lt;code&amp;gt;FreehandBase&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;CalligraphicTool&amp;lt;/code&amp;gt; classes in Inkscape (as of May 2022), it could help improve the performance of the Pencil Tool.&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer Discussion]]&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=Killing_Livarot&amp;diff=121852</id>
		<title>Killing Livarot</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=Killing_Livarot&amp;diff=121852"/>
		<updated>2022-06-06T20:09:00Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: Complete rewrite with status updates as of 2022 and significantly more detail.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page details work items that need to be completed in order to remove Livarot from Inkscape's code base.&lt;br /&gt;
&lt;br /&gt;
This project requires a substantial amount of work and welcomes all volunteers who would like to contribute &lt;br /&gt;
code, help in code review, as well as help test the new functionality at later stages of the development.&lt;br /&gt;
&lt;br /&gt;
== Work items ==&lt;br /&gt;
&lt;br /&gt;
=== Project Path Operations ===&lt;br /&gt;
There's an initial implementation of path boolean operations in lib2geom (MSc thesis subject of Krzysztof Kosiński),&lt;br /&gt;
but it needs substantially more work before it has all the features and proven reliability needed to fully replace Livarot.&lt;br /&gt;
&lt;br /&gt;
==== Path Intersection Graph ====&lt;br /&gt;
The &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt; class underlies all existing boolean operations in lib2geom, implementing the [https://en.wikipedia.org/wiki/Greiner%E2%80%93Hormann_clipping_algorithm Greiner-Hormann algorithm]. &lt;br /&gt;
Unfortunately, the current implementation is flawed in several ways. &lt;br /&gt;
For instance, it cannot handle certain kinds of intersections, e.g., two paths merging and traveling together for some distance.&lt;br /&gt;
Furthermore, it's not able to compute the union, intersection or difference of two identical shapes (as of May 2022).&lt;br /&gt;
&lt;br /&gt;
* Write additional unit tests for the &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt; to capture some of the existing breakage; currently being worked on by [https://gitlab.com/S-Rafael @S-Rafael].&lt;br /&gt;
* Rework the inclusion classification in the &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;, a key step of the Greiner-Hormann algorithm. This provides an alternative “geometric” strategy for the classification of crossings and deciding which path portions lie inside the other path-vector. Currently being worked on by [https://gitlab.com/S-Rafael @S-Rafael].&lt;br /&gt;
* Write a path uncrossing algorithm.&amp;lt;br/&amp;gt;This provides a &amp;lt;code&amp;gt;flatten&amp;lt;/code&amp;gt; primitive which removes self-overlaps and self-crossings with the help of  &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;. A path that self-intersects should be cut at the intersection points and replaced by one or several paths that do not have self-intersections. Note that we only need to remove actual transverse self-intersections and not all spurious solutions from the sweepline algorithm.&amp;lt;br/&amp;gt;Implicitly, the 2-dimensional shapes in lib2geom are defined by path-vectors using the “even-odd” fill rule. The flattening function converts such a path-vector to one which works with the “non-zero” fill rule, similar to &amp;lt;code&amp;gt;sp_flatten&amp;lt;/code&amp;gt; [https://gitlab.com/inkscape/inkscape/-/blob/master/src/path/path-boolop.h#L17]. [[File:Flatten.png|frame|The &amp;quot;flatten&amp;quot; operation replaces a self-intersecting path with one that doesn't cross over itself. The result path, shown on the right, has the same fill region regardless of whether &amp;quot;even-odd&amp;quot; or &amp;quot;nonzero&amp;quot; fill rule is used.]]&lt;br /&gt;
&lt;br /&gt;
* Write functions that implement path cutting (slicing) and division. “Slicing” refers to cutting all paths in a path-vector along all intersection points with another path-vector.  “Division” refers to using one path-vector as a “cookie cutter” which divides the other path-vector (the “dough”) into several shapes. [[File:Division.png|frame|The &amp;quot;division&amp;quot; operation is analogous to using a cookie cutter on a piece of dough. Note that the white gaps between the resulting pieces have been thickened for better visibility; in reality, these pieces should fit together perfectly.]]&lt;br /&gt;
&lt;br /&gt;
* Write a function which splits a shape into connected components; this corresponds to &amp;lt;code&amp;gt;split_non_overlapping&amp;lt;/code&amp;gt; in Inkscape and should be implemented directly in the &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Write even more unit tests to ensure that all this functionality is robust and handles all weird and exotic corner cases. If the “geometric” classification strategy works well, make it the default strategy.&lt;br /&gt;
&lt;br /&gt;
* If possible, remove all exceptions from &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Implement overloaded boolean operators &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;^&amp;lt;/code&amp;gt; on &amp;lt;code&amp;gt;PathVector&amp;lt;/code&amp;gt; operands. This is just a cherry on top of the cake and should be added once the new strategy is robust enough for general use.&lt;br /&gt;
&lt;br /&gt;
* Start migrating the path and boolean operations in Inkscape to the new lib2geom implementation. This will involve rewriting most of the source file [https://gitlab.com/inkscape/inkscape/-/blob/master/src/path/path-boolop.cpp path-boolop.cpp] in Inkscape and eventually deleting it entirely.&lt;br /&gt;
&lt;br /&gt;
* Migrate all Live Path Effects which use boolean operations to the new lib2geom facilities.&lt;br /&gt;
&lt;br /&gt;
* Implement boolean operations on sets of shapes, including nested groups [https://gitlab.com/inkscape/inbox/-/issues/7121]. [[File:Exclusion-on-groups.png|frame|The proposed &amp;quot;exclusion&amp;quot; operation on groups of shapes; based on an illustration by Chris Rogers.]]&lt;br /&gt;
&lt;br /&gt;
* Measure the performance of the new boolean operations and devise performance optimizations; in particular consider cache-friendliness of the code and whether or not &amp;lt;code&amp;gt;boost::ptr_vector&amp;lt;/code&amp;gt; is actually a good container for this use case.&lt;br /&gt;
&lt;br /&gt;
=== The Shape Tool ===&lt;br /&gt;
The new tool (shape tool/welder tool/shape welder) [https://gitlab.com/inkscape/ux/-/issues/109 was proposed] as an alternative to “shape builder” functionality found in other vector drawing programs.    &lt;br /&gt;
Developing this functionality was the subject of the 2021 Google Summer of Code project  by [https://gitlab.com/osamaahmad Osama Ahmad] under the title “On-canvas interactive boolean operations”.&lt;br /&gt;
Nonetheless, the [https://gitlab.com/inkscape/inkscape/-/merge_requests/3357 already-developed UI] requires a stable and convenient engine that can power this tool.&lt;br /&gt;
&lt;br /&gt;
=== Path outliner ===&lt;br /&gt;
Path outliner was worked on by Liam but the status of this work is unknown. &lt;br /&gt;
The biggest obstacle to a robust path outlining functionality is the unreliability of the lib2geom boolean operations as of May 2022.&lt;br /&gt;
Once the boolean operations are robust, path outlining can be developed on this basis, although it still requires some work; the main tasks are listed below.&lt;br /&gt;
&lt;br /&gt;
* Write outlining functions for all curve types used in SVG specification: quadratic and cubic Bézier curves, elliptical arcs. A design requirement is the ability to control the relative error of the outline distance (contact [https://gitlab.com/S-Rafael @S-Rafael] for more details).&lt;br /&gt;
&lt;br /&gt;
* Optionally, provide outlining algorithms for other curve types supported by lib2geom.&lt;br /&gt;
&lt;br /&gt;
* The final implementation should outline paths by outlining the constituent curves and combining the outlines with boolean union.&amp;lt;br/&amp;gt;At first glance, this may seem excessively complicated compared to the apparently simple [https://ieeexplore.ieee.org/abstract/document/4055919 Tiller–Hanson method], but is actually required for a general implementation. Note that the Tiller–Hanson algorithm was invented for shapes used in CAD, which are a lot less crazy and irregular than arbitrary paths which lib2geom must support.&lt;br /&gt;
&lt;br /&gt;
* Write unit tests for the path outliner.&lt;br /&gt;
&lt;br /&gt;
* Measure performance and optimize.&lt;br /&gt;
&lt;br /&gt;
=== Crazy libnrtype dependency ===&lt;br /&gt;
The text layout library libnrtype uses Livarot for line-breaking text in flow regions. This involves using path outline and boolean operation functionality in Livarot and has been the source of some bugs and headaches. However, once path outlining is available in lib2geom, it will not be very hard to use it to create flow regions with variable padding.&lt;br /&gt;
&lt;br /&gt;
=== Python API ===&lt;br /&gt;
All of the new functionality described above should be gradually exposed in the Python API, so that Inkscape's extensions can call lib2geom directly instead of routing their calls through Inkscape. This will enable extension authors to perform advanced path operations directly in their Python code.&lt;br /&gt;
&lt;br /&gt;
=== Streaming outliner ===&lt;br /&gt;
&lt;br /&gt;
[[File:Gnarly.png|thumb|A gnarly, jagged outline created by the Eraser Tool due to the retrograde motion of the ends of the tool's nib.]]&lt;br /&gt;
The free-hand drawing tools in Inkscape, such as the Calligraphic and Eraser tools, implement a very primitive (but fast) form of path outlining via Bézier fitting. This outlining method causes some problems such as a gnarly, knotted tool trace when one of the  nib extremities experiences retrograde motion (leading to the fitting of Bézier curves with loops) [https://gitlab.com/inkscape/inkscape/-/issues/1124].&lt;br /&gt;
&lt;br /&gt;
A much more robust replacement for use in tools would be a “streaming outliner” which accepts incoming sample points in real time, outlines the incoming segments and appends them to a stored, gradually growing outline of the toolpath. This is a long-term goal, since it would require a more streaming-friendly implementation of the functionality in &amp;lt;code&amp;gt;PathIntersectionGraph&amp;lt;/code&amp;gt;. In addition to enabling a substantial improvement on the extremely crufty &amp;lt;code&amp;gt;FreehandBase&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;CalligraphicTool&amp;lt;/code&amp;gt; classes in Inkscape (as of May 2022), it could help improve the performance of the Pencil Tool.&lt;br /&gt;
&lt;br /&gt;
== Discussion ==&lt;br /&gt;
&lt;br /&gt;
[[Category:Developer Discussion]]&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=File:Exclusion-on-groups.png&amp;diff=121851</id>
		<title>File:Exclusion-on-groups.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=File:Exclusion-on-groups.png&amp;diff=121851"/>
		<updated>2022-06-06T19:51:44Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;f&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=File:Gnarly.png&amp;diff=121850</id>
		<title>File:Gnarly.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=File:Gnarly.png&amp;diff=121850"/>
		<updated>2022-06-06T19:48:59Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Illustration of limitations of the original outline method employed by free-hand tools in Inkscape.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=File:XOR-groups.png&amp;diff=121849</id>
		<title>File:XOR-groups.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=File:XOR-groups.png&amp;diff=121849"/>
		<updated>2022-06-06T19:39:42Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An illustration of the proposed XOR operation on groups of shapes.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=File:Division.png&amp;diff=121848</id>
		<title>File:Division.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=File:Division.png&amp;diff=121848"/>
		<updated>2022-06-06T19:35:52Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An illustration of the &amp;quot;division&amp;quot; operation on paths.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
	<entry>
		<id>https://wiki.inkscape.org/wiki/index.php?title=File:Flatten.png&amp;diff=121847</id>
		<title>File:Flatten.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.inkscape.org/wiki/index.php?title=File:Flatten.png&amp;diff=121847"/>
		<updated>2022-06-06T19:32:57Z</updated>

		<summary type="html">&lt;p&gt;S-Rafael: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Illustration of the &amp;quot;flatten&amp;quot; operation.&lt;/div&gt;</summary>
		<author><name>S-Rafael</name></author>
	</entry>
</feed>