Fritzing Part Format
Fritzing Part File Specification
March 11, 2009
A Fritzing part is made up of a number of files, one required metadata file (file suffix is .fzp, so the metadata file is also referred to as an FZP), and up to four SVG files. We went with multiple image files because each part may appear in four different views (breadboard, schematic, pcb, and parts bin), often with a different image for each view. We decided not to merge all the SVGs and the metadata together in a single file, because this makes it easier for different parts to share the same image (for example, many parts share the same pcb footprint), and also because keeping the SVGs in separate files makes it easier to access individual images, e.g., for inspection, or to load into the Parts Editor.
The metadata file lists a part's title, description, and other properties, as well as a references to the part's SVG files. It also specifies a part's connectors and internal buses. Each connector's graphic is an element found in the relevant view SVG file. Since any SVG element can have an id attribute, the metadata file refers to a connector's graphic element using that element's id.
We don't have a schema yet for the FZP, so your best bet is to use an existing FZP file—one from the set of Fritzing core parts—as an example.
Because of the multitude of files and links between them, the folder structure might seem complicated at first. Almost all the parts that are shipped with Fritzing can be found in the /parts folder in the following subfolders:
|/core||FZPs of all parts in the core library|
|/contrib||FZPs of all community-contributed parts, use at own risk|
|/obsolete||FZPs of obsolete parts, for backwards compatibility|
|/svg||All SVG graphics for the above parts|
Within the /svg folder, you will find the same core, contrib, and obsolete folders, categorizing the SVGs in the same manner as the FZPs described above. And within one of these subfolders, the structure is:
|/svg/core/breadboard||SVGs for the breadboard view of the core library parts|
|/svg/core/icon||SVGs for the parts bin icon of the core library parts|
|/svg/core/pcb||SVGs for the PCB view of the core library parts (aka footprints)|
|/svg/core/schematic||SVGs for the schematic view of the core library parts (aka schematic symbols)|
Some parts are generated on-the-fly rather than simply loaded, for example, the ruler or the resistor. Templates for these parts are compiled in with the program and won't be found in the /parts folder. Curious developers can look in the source under /resources/parts.
You will also not find your own, custom-created parts in the /parts folder! These are stored in your global user folder, so that they don’t get lost when you install new versions of Fritzing. The location of this folder differs depending on your operating system, and might even be hidden by default:
|Windows XP||C:\Documents and Settings\<username>\Application Data\Fritzing|
|Mac OS X||/Users/<username>/.config/Fritzing|
And now to the metafile format. Let's start with a typical example of the first couple of lines:
<?xml version='1.0' encoding='UTF-8'?>
<module moduleId="1a4bfb87a0f0fd2c59be43f3497d72e6" fritzingVersion="0.3.16b.02.24.4002">
After the usual introductory XML boilerplate, the outermost element in an FZP file is always <module>.
The moduleId attribute is important—this must be unique across all parts—and Fritzing will reject a part if it's already loaded one with the same moduleId—so using something like a GUID for the attribute value is entirely appropriate.
For the fritzingVersion attribute, your best bet is to launch Fritzing and open up the about box, from which you can copy the version string. The first half of the version string is the important part: from the example above that means just the “0.3.16b”.
<title>Blue LED - 5mm</title>
<description>A generic blue LED (~1.8V)</description>
Most of these seem self-explanatory.
The <label> element is the part's default label string when it appears in a Fritzing sketch.
At present we're not doing much with tags, but you can do a text search for parts from the Parts Bin, and the tags are included in that search. You should probably substitute “fritzing contrib” for “fritzing core”.
Now for properties. Here's a sample from a potentiometer:
<property name="type">Trimmer Potentiometer</property>
<property name="Maximum Resistance">10kΩ</property>
<property name="Size">Trimmer - 6mm</property>
Properties are important—Fritzing uses them to make it easy to swap between related parts in a sketch. When the properties are loaded, they're stored in a database; searching that database gives a set of related parts. The most important property is the “family”—Fritzing only swaps between parts in the same family.
The values of the other properties are used to populate popup-menus in Fritzing's Inspector window. For example, when you select a potentiometer in a sketch, a popup menu will appear in the Inspector window labeled “type”, with the options “Trimmer Potentiometer”, “Slide Potentiometer”, and “Rotary Shaft Potentiometer”.
Views and layers
Now comes the <views> element which references the SVG files used by the part:
<layers image="icon/LED-blue-5mmicon.svg" >
<layer layerId="icon" />
<breadboardView fliphorizontal="true" flipvertical="true" >
<layers image="breadboard/LED-5mm-blue.svg" >
<layer layerId="breadboard" />
<layers image="schematic/led.svg" >
<layer layerId="schematic" />
<layers image="pcb/T1.75_LED.svg" >
<layer layerId="copper0" />
<layer layerId="copper1" />
<layer layerId="silkscreen" />
But before diving into details, some explanation is required. Remember that a part generally has a different SVG file for each view. But beyond that, each view has a number of layers. The layers have a particular z-ordering, and from the Fritzing UI can be independently set visible or hidden. All part images in Fritzing are assigned to particular layers. Furthermore, all of a part's connectors will be found in one layer.
Note that in some views, most especially pcb view, a part can be assigned to multiple layers. However, this doesn't mean the entire part SVG image appears on each of those layers. Rather, internally, the view SVG is split into multiple sub-SVGs, one per layer.
The way a given sub-SVG layer is marked in the SVG file is by using the element id attribute again, usually inside a <g> element. So, with the example above, it means that the T1.75_LED.svg file has a number of <g> elements:
<g id=”silkscreen”> …
<g id=”copper0”> ...
<g id=”copper1”> …
If a layer is specified in the FZP file, it is very important that an element with that id exists in the SVG file, even if it's only an empty element.
At one point we considered having separate SVG files for each layer, but we felt that having more individual files per part would make it more difficult to keep part files organized, and also when creating the SVG image for a view for a given part, having a single SVG would make it much easier to keep the elements on the different layers aligned with each other.
So, back to the sample <view> element, notice that the four views are listed: iconView, breadboardView, schematicView, and pcbView; and notice that there are five layers in PCB view.
Something you might overlook the first time through are the flipVertical and flipHorizontal attributes. In Fritzing, the default is that parts are not flippable, since this usually doesn't correspond well with real physical parts. However, you can enable flipping for each of the two axes individually by setting their values to “true”. Note that flippability is per view.
Now onto the connectors element:
<connector type="male" id="connector0" name="cathode" >
<p svgId="connector0pin" layer="breadboard" terminalId="connector0terminal" />
<p svgId="connector0pin" layer="schematic" terminalId="connector0terminal" />
<p svgId="connector0pad" layer="copper0" />
<p svgId="connector0pad" layer="copper1" />
<connector type="male" id="connector1" name="anode" >
<p svgId="connector1pin" layer="breadboard" terminalId="connector1terminal" />
<p svgId="connector1pin" layer="schematic" terminalId="connector1terminal" />
<p svgId="connector1pad" layer="copper0" />
<p svgId="connector1pad" layer="copper1" />
Note that connectors have gender, but this really only matters in breadboard view; gender is ignored in schematic and pcb view. Parts with female connectors include breadboards and Arduinos, but the great majority of parts have male connectors.
The <description> element and name attribute seem self-explanatory. But it is important to note that within a part, a connector's name and id attributes must be unique—that is, no two connectors in a given part should have the same id or the same name.
Each connector has sub-elements that reference a particular view. Each sub-element has a layer attribute (at present all parts have all their connectors on a single layer, and it's unlikely that will change).
The svgId attribute refers to the an element in the view's SVG file with a matching id attribute. This element defines the shape of the connector and gives its position in the part—it may also define the connector's actual graphic, but that could be elsewhere in the SVG. So in the above example, the “connector0pin” value for the svgId attribute in breadboard view refers to an element in the SVG file LED-5mm-blue.svg:
<rect id="connector0pin" x="4.793" y="65.307" fill="none" width="2.989" height="9.442"/>
The terminalId attribute is optional. Each connector takes up a certain area in a part (in the example above, it's a rectangle), but a wire will actually attach to a connector at a single point within the connector's area. This point of attachment is called a terminal point. The default terminal point is the center of the connector area. If you want the terminal point elsewhere, the terminalId attribute points to yet another element in the SVG file. Here is the SVG element for the terminalId attribute “connector0terminal” in breadboard view:
<rect id="connector0terminal" x="4.793" y="74.192" fill="none" width="2.989" height="0.562"/>
If you use a terminalId attribute in your FZP file, make sure an element with that id really exists in the associated SVG file. Also, although in theory you can name your terminalId attribute anything you want, as long as there's an associated SVG element with that id, in practice we find that it's best to use the connector name followed by “terminal”.
And finally, the buses section. A bus is an internal connection between connectors and only a few parts come with buses, for example, the Arduino and the 4-pin pushbutton. The Parts Editor isn't able to deal with buses, so you must add it to FZP by hand. Here's the buses section for the 4-pin pushbutton. Notice there are two separate buses described:
<bus id="bus0" >
<nodeMember connectorId="connector0" />
<nodeMember connectorId="connector1" />
<bus id="bus1" >
<nodeMember connectorId="connector2" />
<nodeMember connectorId="connector3" />
The connectorId attribute refers to the connector id attribute in the <connectors> element. The bus names are arbitrary, as long as, within the part, each bus's name is different.
Just for review, here is a high level overview of the structure of a generic fzp file:
<?xml version='1.0' encoding='UTF-8'?>
<module moduleId="..." fritzingVersion="...">
<!-- metadata elements like date, author, etc -->
Through-hole parts vs. SMD parts
So far, we have mostly been discussing matters from the point of view of the FZP. But there are a few words to add about SVGs. First off, Qt (the framework upon which Fritzing is built) supports a superset of SVG 1.2 Tiny. So, your part image may look great in Illustrator or Inkscape, but Qt won't be able to display it.
Second, both Illustrator and Inkscape have their quirks, which sometimes cause problems with Fritzing. One tip with Inkscape is to save your SVGs as “plain SVG” rather than “Inkscape SVG”. This choice is only available from the “Save As” option in Inkscape.
The most annoying quirk with Illustrator is that Illustrator defines a pixel (“px”) as 72dpi, whereas in the SVG standard, a “px” is 90dpi. So when you save images from Illustrator, if you want them to show up at the size you expect in Fritzing, save the image in units other than px (and note that if you leave out units entirely, it means "px"). Fritzing does try to correct for this problem, but your safest bet may be to open your Illustrator-based SVG in a text editor and hand-modify the width and height attributes by dividing each by 72 and putting "in" (meaning inches) as the units.
Now about measurements and SVGs. One of the pleasures of SVG is that the format can support extremely accurate placement. At the top level of the SVG, there are three attributes, "width", "height", and "viewBox". The width and height are real world measurements that can be specified in units such as cm, mm, inches, etc. You can set those in the Document Properties dialog in Inkscape's File menu (but for a more reliable approach see below).
The viewBox attribute defines a rectangle, in arbitrary dimensionless units, which are proportionally related to the width and height. In Fritzing the viewBox attribute is always of the form viewBox="0 0 w h". All the other coordinates in the SVG file (for lines, circles, paths, etc.) are then given relative to w and h.
For example, many Fritzing files use inches as units, and use 1000 dpi as the basis for the viewBox. So you might see something like
<svg width='0.46684in' height='0.20306in' viewBox='0 0 466.84 203.06'>
I haven't found a way to reliably set width, height, and viewBox in Inkscape without using the XML editor (under the edit menu) to add/modify the attributes at the top-level svg element.
But once you get those attributes set up, then when you start drawing, all the measurements will be in terms relative to the viewBox--which is proportional to the real-world width and height you've set--so it's therefore possible to position elements with a high level of both precision and accuracy