BoltBait

How to make custom shapes for paint.net 4.0.6+

Recommended Posts

They are 2 different ways to create custom shapes:

The Easy Way - Shape Maker

The Hard Way - Explained below

Most of the shapes in my plugin pack were created the "hard way", that is coded by hand using the Kaxaml editor.

Before we begin, visit the Kaxaml web site and install Kaxaml: http://www.kaxaml.com/

There are 2 ways to hand code an XAML shape for paint.net:

  • Simple PathGeometry - House
  • GeometryGroup - Smart Phone / Cube

Both ways have their good points. However, you should know that there are things you can do in the GeometryGroup method that you can't do with the Simple PathGeometry. I'll explain both and you can choose which method to use.

 

 

Simple PathGeometry

Here is a template / example you can use right in Kaxaml:

<Page
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
	<Grid>  
		<Canvas>
			<Path Fill="#D2E9F6" Stroke="#5894C1" StrokeThickness="1"
				Data="F1 M 21,142 L 160,22 L 300,142 L 300,318 L 21,318 Z"
			/>
		</Canvas>
	</Grid>
</Page>

 

You just need to replace the data "F1 M 21,142 ... Z" etc. with the instructions to draw your own shape.

Here is the language reference: Language Reference for XAML Mini-Language

The string starts with either F0 (default if not specified) or F1 indicating fill mode 0 (even odd) or fill mode 1 (non-zero).

The M command moves to the specified point, the L command draws a line to the specified end point, and the Z command closes a shape by drawing a line back to the last M command.

Check the reference page for more commands, like curves, etc.

Once you are happy with the shape in Kaxaml, take the data string and drop it into the template for a paint.net shape:

<ps:SimpleGeometryShape xmlns="clr-namespace:PaintDotNet.UI.Media;assembly=PaintDotNet.Framework"
	xmlns:ps="clr-namespace:PaintDotNet.Shapes;assembly=PaintDotNet.Framework"
	DisplayName="House"
	Geometry="F1 M 21,142 L 160,22 L 300,142 L 300,318 L 21,318 Z" />

 

The "DisplayName" field is where you specify the shape name that will appear when you hover over the shape in the shape menu. The "Geometry" field is where you put your drawing instructions.

Once you've saved this file onto your Desktop, copy it to your shapes directory: C:\Program Files\paint.net\Shapes

Restart paint.net and check to see if it appears in the menu. If it doesn't appear, click the gear icon in the upper right corner of the paint.net screen and check in the plugin errors tab.

 

 

GeometryGroup

Here is a template / example you can use right in Kaxaml:

<Page
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
	<Grid>
		<Path Fill="#D2E9F6" Stroke="#5894C1" StrokeThickness="1">
			<Path.Data>
				<GeometryGroup>
					<RectangleGeometry Rect="10,10,184,307" RadiusX="10" RadiusY="10" />
					<RectangleGeometry Rect="15,40,174,227" RadiusX="10" RadiusY="10" />
					<RectangleGeometry Rect="74,21,60,7" RadiusX="10" RadiusY="10" />
					<EllipseGeometry Center="103,290" RadiusX="15" RadiusY="15" />
				</GeometryGroup>
			</Path.Data>
		</Path>
	</Grid>
</Page>

 

I chose to use basic shapes to create the cell phone because I needed to use rounded rectangles. These are easy here as you can specify RadiusX and RadiusY for rectangle corners... something you can't do using the mini-language.

And, here is how it would look as a paint.net shape:

<ps:SimpleGeometryShape xmlns="clr-namespace:PaintDotNet.UI.Media;assembly=PaintDotNet.Framework"
	xmlns:ps="clr-namespace:PaintDotNet.Shapes;assembly=PaintDotNet.Framework"
	DisplayName="Smart Phone">
		<GeometryGroup>
			<RectangleGeometry Rect="10,10,184,307" RadiusX="10" RadiusY="10" />
			<RectangleGeometry Rect="15,40,174,227" RadiusX="10" RadiusY="10" />
			<RectangleGeometry Rect="74,21,60,7" RadiusX="10" RadiusY="10" />
			<EllipseGeometry Center="103,290" RadiusX="15" RadiusY="15" />
		</GeometryGroup>
</ps:SimpleGeometryShape>

Notice the simple copy-and-paste needed. Then, don't forget to specify a Display Name.

Note: paint.net shapes are limited to one path data or one GeometryGroup.

 

 

Another Example

Here is an example of using a GeometryGroup that looks very similar to the Simple PathGeometry we learned first:

<Page
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
	<Grid>  
		<Path Fill="#D2E9F6" Stroke="#5894C1" StrokeThickness="1">
			<Path.Data>
				<PathGeometry FillRule="Nonzero">
					<PathFigure IsClosed="True" IsFilled="True" StartPoint="0,22">
						<LineSegment Point="58,0" IsSmoothJoin="True" />
						<LineSegment Point="116,22" IsSmoothJoin="True" />
						<LineSegment Point="116,93" IsSmoothJoin="True" />
						<LineSegment Point="58,116" IsSmoothJoin="True" />
						<LineSegment Point="0,93" IsSmoothJoin="True" />
						<LineSegment Point="0,22" IsSmoothJoin="True" />
					</PathFigure>
					<PathFigure IsClosed="False" IsFilled="False" StartPoint="58,46">
						<LineSegment Point="0,22" />
					</PathFigure>
					<PathFigure IsClosed="False" IsFilled="False" StartPoint="58,46">
						<LineSegment Point="58,116" />
					</PathFigure>
					<PathFigure IsClosed="False" IsFilled="False" StartPoint="58,46">
						<LineSegment Point="116,22" />
					</PathFigure>
				</PathGeometry>
			</Path.Data>
		</Path>
	</Grid>
</Page>

 

Here I chose to use the expanded syntax because I can control the shape of the line endings to make the drawing look better.

Here's how it looks as a paint.net shape:

<ps:SimpleGeometryShape xmlns="clr-namespace:PaintDotNet.UI.Media;assembly=PaintDotNet.Framework"
	xmlns:ps="clr-namespace:PaintDotNet.Shapes;assembly=PaintDotNet.Framework"
	DisplayName="Cube">
	<PathGeometry FillRule="Nonzero">
		<PathFigure IsClosed="True" IsFilled="True" StartPoint="0,22">
			<LineSegment Point="58,0" IsSmoothJoin="True" />
			<LineSegment Point="116,22" IsSmoothJoin="True" />
			<LineSegment Point="116,93" IsSmoothJoin="True" />
			<LineSegment Point="58,116" IsSmoothJoin="True" />
			<LineSegment Point="0,93" IsSmoothJoin="True" />
			<LineSegment Point="0,22" IsSmoothJoin="True" />
		</PathFigure>
		<PathFigure IsClosed="False" IsFilled="False" StartPoint="58,46">
			<LineSegment Point="0,22" />
		</PathFigure>
		<PathFigure IsClosed="False" IsFilled="False" StartPoint="58,46">
			<LineSegment Point="58,116" />
		</PathFigure>
		<PathFigure IsClosed="False" IsFilled="False" StartPoint="58,46">
			<LineSegment Point="116,22" />
		</PathFigure>
	</PathGeometry>
</ps:SimpleGeometryShape>

 

Just copy all of the PathGeometry tag into the paint.net template. Don't forget to specify a Display Name.

GeometryGroup and PathFigure are really the same method. You can combine them by putting a PathGeometry inside of a GeometryGroup at the same level as the RectangleGeometry or EllipseGeometry in the first example above.

____________________

  • Upvote 4

Share this post


Link to post
Share on other sites

The child element of SimpleGeometryShape can be any Geometry-derived class. You aren't restricted to PathGeometry or GroupGeometry.

 

For instance, you could have it be just an EllipseGeometry. Although at that point, just use the built-in ellipse/circle shape :)

Share this post


Link to post
Share on other sites

I wonder How many will prefer it over Shape Maker?

 

I prefer it to Shape Maker. Partly due to specifics of shapes I've made.

And I created converter script to automate geometry grafting labor. Check my topic for details.

Share this post


Link to post
Share on other sites

See - someone reads your tut @BoltBait. Took me a few tries - but by George I think I got it!

I plan to try using Kaxaml to draw my next shape.

And correct me if I'm wrong - you can't import the geo code into ShapeMaker. Figured that out all on my own but it did frustrate me for awhile.

 

Thanks for the tut and the examples. I enjoy learning new things. B)

 

 

  • Upvote 1

Share this post


Link to post
Share on other sites
52 minutes ago, AndrewDavid said:

... you can't import the geo code into ShapeMaker.

 

ShapeMaker has a nice manual; let's see what it says about 'Paste Path Stream':

Paste Path is capable of interpreting StreamGeometry strings which are a lightweight version of
PathGeometry strings. Both can appear in XAML files - but only StreamGeometry can be parsed by
ShapeMaker. Users attempting to paste in PathGeometry strings will receive an error message even
though there is nothing 'wrong' with the string.

So, you can import StreamGeometry, but not PathGeometry.

 

BoltBait's example of StreamGeometry:

F1 M 21,142 L 160,22 L 300,142 L 300,318 L 21,318 Z

 

  • Upvote 1

Share this post


Link to post
Share on other sites
1 hour ago, AndrewDavid said:

And correct me if I'm wrong - you can't import the geo code into ShapeMaker.

 

True. But, you can design something in ShapeMaker and OUTPUT the geo code using the menu File > Export Path Geometry.

  • Upvote 1

Share this post


Link to post
Share on other sites
36 minutes ago, toe_head2001 said:

Paste Path Stream

That's for the advanced users.

 

Not there yet!

Thanks for the reference though.

Haven't played with that aspect yet @toe_head2001.

I'll get there.

Share this post


Link to post
Share on other sites

It worked perfectly for me.

 

What problems are you having?

Share this post


Link to post
Share on other sites
22 minutes ago, Gustavo Lavanchy said:

Why this shape does not work correctly?

 

Please explain your issue in detail, as it appears to work just fine:

shiny.png

Share this post


Link to post
Share on other sites

Thanks for the reply.

The .xaml file is somehow stored with an error and does not appear on paint.net. It is not recognized by the system. (Of course I'm using the correct folder, that's not the problem.)

 

When I try to retrieve with shapemaker the .xaml file (import PDN shape), only nonsensical streaks appear.

 

Maybe I'm doing something wrong while editing and then saving, even though I followed the instructions.

 

Is there any step that can be done wrong and generate files with error?
because that is not the only shape with which this happens to me.

 

I will continue to try, anyway, I would appreciate if you could upload the file shiny.xaml to the forum to be able to occupy it in the meantime.

Share this post


Link to post
Share on other sites

@Gustavo Lavanchy, I've sent you a private message regarding a localization bug. (which I think is your issue)

 

I meant to release a bugfix release of ShapeMaker a few weeks ago. I'll try to post it in the coming days.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now