-
Notifications
You must be signed in to change notification settings - Fork 838
2.1 Part file format
Authors: Jonathan Cohen
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 icon), 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 keeping them separate 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. Start with the smallest simplest ones, and work your way up.
Because of the multitude
of files and links between them, the folder structure might seem
complicated at first. The metadata files for all the parts that are
shipped with Fritzing can be found in the fritzing-parts
folder in the following subfolders:
Folder | Description |
---|---|
fritzing-parts/core | FZPs of all parts in the core |
fritzing-parts/contrib | FZPs of all parts in the contrib bin |
fritzing-parts/obsolete | FZPs of obsolete parts, for backwards compatibility |
Within the fritzing-parts/svg
folder, you will find matching core, contrib and obsolete folders.
Within one of these subfolders, the structure is:
Folder | Description |
---|---|
fritzing-parts/svg/core/breadboard | SVGs for the breadboard view of the core library parts |
fritzing-parts/svg/core/icon | SVGs for the parts bin icon of the core library parts |
fritzing-parts/svg/core/pcb | SVGs for the PCB view of the core library parts (aka footprints) |
fritzing-parts/svg/core/schematic | SVGs for the schematic view of the core library parts (aka schematic symbols) |
Since version 0.9.3, the fritzing-parts
subfolder is actually a git clone of https://github.com/fritzing/fritzing-parts. Fritzing checks the github repository for updates on every launch, and does a "git pull" if the user agrees.
Some parts however are generated on-the-fly rather than simply loaded, for example, rulers, resistors, pin headers, generic DIPs. Templates for these parts are compiled in with the program.
You will also not find your own, custom-created parts and bins there. These are stored in your Fritzing documents folder, so that they don’t get lost when you install new versions of Fritzing:
Operating System | Document folder path |
---|---|
Windows | C:\Users\username\Documents\Fritzing\parts |
Mac OS X | /Users/username/Documents/Fritzing/parts |
Linux | ~/Documents/Fritzing/parts |
Finally, some part-related files are stored in the application storage area, which is usually a hidden folder in your operating system and you shouldn't have to deal with these:
- The fzz folder contains a folder for each fzz file that is currently open. If there are custom parts in the sketch, the svg and fzp files will be in the fzz folder.
- The partfactory folder contains files for generated parts, such as pin headers and generic DIPs.
- Up to version 0.9.2, custom-created parts and bins were also stored here.
The location of this folder depends on the operating system:
Operating System | Folder path |
---|---|
Windows Vista and up | C:\Users\username\AppData\Roaming\Fritzing |
Windows XP | C:\Documents and Settings\username\Application Data\Fritzing |
Mac OS X | ~/.config/Fritzing |
Linux | ~/.config/Fritzing |
You can find the location of a specific part SVG in Fritzing by opening the part in the Parts Editor. Switch to the view you are interested in and choose Show in folder under the File menu.
Fritzing core parts are
compiled into a database when Fritzing is shipped--using the data
from the fzp files. This database is used for swapping parts (this is
a quick mechanism for switching between related parts). The database
is an Sqlite file, and the assumption is that it's quicker to load
the database than to parse all the part fzp files. To compile
the database run Fritzing from the command line: fritzing.exe -db path/to/parts/parts.db
or choose Part → Regenerate parts database from the menu.
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 has already loaded one with the
same moduleId.
It would be appropriate to use something like a GUID for the moduleId
attribute value though better might be to use the part-type + a GUID.
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 most important: from the example above that
means just the “0.3.16b”.
Next comes:
<author>Stefan Hermann</author>
<version>2</version>
<title>Blue LED - 5mm</title>
<url></url>
<label>LED</label>
<date>2008-10-10</date>
<description>A generic blue LED (~1.8V)</description>
<tags>
<tag>LED</tag>
<tag>Blue LED</tag>
<tag>indicator</tag>
<tag>fritzing core</tag>
</tags>
Most of these seem self-explanatory:
- Obsolete parts use a
special version syntax
<version replacedby="">
The value of the replacedby attribute is the moduleId of the part which replaces the obsolete part. There are many examples of this in the pdb/obsolete folder. The replacedby attribute can also be applied to individual connectors; see the Connectors section below. - The
<label>
element is the part's default label string when it appears in a Fritzing sketch. - The
<description>
can be plain text or rich text format. Rich text is a subset of html that can be displayed in certain Qt widgets (Qt is Fritzing's underlying GUI framework). If you use rich text, it must be xml-escaped, so the FZPs xml structure doesn't get confused. - At present we're not doing much with
tags
, but in Fritzing you can do a search for parts from the Parts Bin, and the tags are included in that search. You should probably substitute “fritzing user” for “fritzing core” if you are creating a custom part.
Now for properties. Here's a sample from a potentiometer:
<properties>
<property name="family">Potentiometer</property>
<property name="type">Trimmer Potentiometer</property>
<property name="Maximum Resistance">10kΩ</property>
<property name="Track">Linear</property>
<property name="Size">Trimmer - 6mm</property>
</properties>
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 family property is required: Fritzing will reject parts that don't have a family property.
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”. These values come from several parts in the "potentiometer" family; each part in that family has a different value in the "type" property.
A property may have the attribute showInLabel set to yes, which means that by default, that property should appear when the part's label is visible. For example, the resistor:
<property name="Resistance" showInLabel="yes">220</property>
Now comes the <views>
element which references the SVG files used by the part:
<views>
<iconView>
<layers image="icon/LED-blue-5mmicon.svg" >
<layer layerId="icon" />
</layers>
</iconView>
<breadboardView fliphorizontal="true" flipvertical="true" >
<layers image="breadboard/LED-5mm-blue.svg" >
<layer layerId="breadboard" />
</layers>
</breadboardView>
<schematicView>
<layers image="schematic/led.svg" >
<layer layerId="schematic" />
</layers>
</schematicView>
<pcbView>
<layers image="pcb/T1.75_LED.svg" >
<layer layerId="copper0" />
<layer layerId="copper1" />
<layer layerId="silkscreen" />
</layers>
</pcbView>
</views>
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 a given layer can be set visible or hidden. All
part images in Fritzing are assigned to particular layers. Connectors
in Fritzing parts can only be assigned to certain layers.
Note that in some views,
most especially pcb view, a part exists on multiple layers. 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 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 three 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 in breadboard and
pcb view are not flippable, since this usually doesn't correspond
well with how you work with real physical parts. By contrast, in
schematic view, parts are flippable by default. However, you can
enable flipping in any view, and for each of the two axes
individually, by setting the corresponding flip- attribute value to
“true”.
In Fritzing, through-hole
parts are defined as those which use both copper0
and copper1
layers;
SMD parts use only the copper1
layer. By "use" I mean use
in the FZP for <views>
and <connectors>
, and as element
ids in the associated pcb view svg file. If an SMD part is placed
onto the bottom layer in Fritzing, the layer is dynamically updated
to copper0
. Some older THT parts use only the copper0
layer; this is
no longer correct, however Fritzing will treat these parts as if both
copper0
and copper1
were specified. Note that it is very important
that if you specify layers in the FZP, you have matching layers in
the relevant SVG (more on this below).
Now onto the connectors element:
<connectors>
<connector type="male" id="connector0" name="cathode" >
<description>cathode pin</description>
<views>
<breadboardView>
<p svgId="connector0pin" layer="breadboard" terminalId="connector0terminal" />
</breadboardView>
<schematicView>
<p svgId="connector0pin" layer="schematic" terminalId="connector0terminal" />
</schematicView>
<pcbView>
<p svgId="connector0pad" layer="copper0" />
<p svgId="connector0pad" layer="copper1" />
</pcbView>
</views>
</connector>
<connector type="male" id="connector1" name="anode" >
<description>anode pin</description>
<views>
<breadboardView>
<p svgId="connector1pin" layer="breadboard" terminalId="connector1terminal" />
</breadboardView>
<schematicView>
<p svgId="connector1pin" layer="schematic" terminalId="connector1terminal" />
</schematicView>
<pcbView>
<p svgId="connector1pad" layer="copper0" />
<p svgId="connector1pad" layer="copper1" />
</pcbView>
</views>
</connector>
</connectors>
Connector type only matters in breadboard view, where parts with male connectors can be directly attached to parts with female connectors. In all other views, you must use wires to connect connectors. Parts with female connectors include breadboards and Arduinos, but the great majority of parts have male connectors. Wires have wire type connectors, and SMD parts will usually use pad type connectors.
The <description>
element and name
attributes 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 an element in the view's SVG file with a matching id attribute. That 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”.
You may recall that an obsolete part can use a replacedby attribute to point to the moduleId of the newer version of the part. Usually, for each connector on the obsolete part, there is a matching connector on the replacement part, and usually the replacement connector has the same id as the obsolete connector, so that it's easy for the software to maintain connections when swapping out an obsolete part. But sometimes the replacement connector does not have the same id. In this case you can use the replacedby attribute on the obsolete connector, with the value being either the id or name of the replacement connector. Here is an example using the name:
<connector id='connector15' name='D0RX' type='female' replacedby='RX/D0'>
In breadboard view, a
number of parts feature rubber-band legs (also referred to as
bendable legs). Rubber-band legs can be stretched and have bendpoints
added. Legs can use straight lines or bezier curves. From the fzp
side, setting this up is pretty straightforward, for example, here is
one <connector>
from the reed switch:
<connector id="connector0" name="pin 1" type="male">
<description>Pin 1</description>
<views>
<breadboardView>
<p layer="breadboard" svgId="connector0pin" legId="connector0leg"/>
</breadboardView>
<schematicView>
<p layer="schematic" svgId="connector0pin" terminalId="connector0terminal"/>
</schematicView>
<pcbView>
<p layer="copper0" svgId="connector0pin"/>
<p layer="copper1" svgId="connector0pin"/>
</pcbView>
</views>
</connector>
Note the legId
attribute in the breadboardView <layer>
element. The legId only
works in breadboard view. A single <layer>
element may not have
a layer both legId and terminalId attributes.
As you probably
will have guessed at this point, there must be a corresponding
element with id="connector0leg"
in the breadboard view SVG
for the reed switch. This element should always be a <line>
. Of
the line's two endpoints, the one that is nearest to the center of
the part is treated as the attached end of the leg. The other end of
the line is the one that can be dragged. Here is the matching leg
from the reed switch (I have included the connector <rect>
for
additional context):
<rect id="connector0pin" x="0" y="2.937" fill="none" width="1" height="1"/>
<line id="connector0leg" stroke-linecap="round" x1="0" y1="4.062" x2="3" y2="4.062" stroke="#6D6D6D" fill="none" stroke-width="2.5"/>
It is something of an art to position the <line>
leg element
nicely in relation to the connector <rect>
element. There is a
leg variant used by a number of parts, such as capacitors and LEDs,
in which the leg extends beyond the body of the part. The trick here
is to set the draggable endpoint of the line outside the viewBox
which defines the rest of the part (some of this will make more sense
after you have read the About SVGs section below). Here is an extract
of the SVG for a capacitor:
<svg ... width="0.243056in" height="0.400278in" viewBox="0 0 17.5 28.82" >
<g id="breadboard">
<rect id="connector0pin" x="4.292" y="27.82" fill="none" width="2.083" height="1"/>
<rect id="connector1pin" x="11.365" y="27.82" fill="none" width="2.275" height="1"/>
<line id="connector0leg" stroke-linecap="round" x1="5.332" y1="28.82" x2="5.332" y2="49.0" stroke="#8C8C8C" fill="none" stroke-width="2.146" />
<line id="connector1leg" stroke-linecap="round" x1="12.502" y1="28.82" x2="12.502" y2="49.0" stroke="#8C8C8C" fill="none" stroke-width="2.346" />
Notice how the y2 coordinate for each line extends past the viewBox bottom border at 28.82.
'Hybrid' is not a good name. A hybrid is a connector that is not visible in certain views. For example there are a number of parts which have prototyping areas in breadboard view that are not visible in other views. There are around a dozen of these--mostly Sparkfun shields--that ship with Fritzing. Another use, is for boards that have internal connections between connectors, where only a single reference is needed on the schematic view (EG GND). A third case, is a board that has header connections on both the top and bottom. The bottom connections need to be shown on the PCB view, but not the top connections.
In each of these situations, the connector definition needs to set the hybrid
attribute to 'yes'
for each view where the specific connector is NOT to be shown. The layer specified with the hybrid entry must be same as would be used for a non-hybrid connector. That is, the layer must be defined in the <views>
information, and it must be a layer that contains connectors. Do not use silkscreen
, or an odd layer name to try to separate the hybrid connector pins from the rest of the connection pin graphic elements.
<connector id='connector98' type='female' name='5V@1'>
<description>5V@1</description>
<views>
<breadboardView>
<p layer='breadboard' svgId='connector98pin' />
</breadboardView>
<schematicView>
<p layer='schematic' svgId='connector98pin' terminalId='connector98terminal' hybrid='yes' />
</schematicView>
<pcbView>
<p layer='copper0' svgId='connector98pad' hybrid='yes' />
<p layer='copper1' svgId='connector98pad' hybrid='yes' />
</pcbView>
</views>
A hybrid connector will not be selectable, and will not have any wires (including ratsnest) drawn to it in that view. To make the connector completely invisible, the svg element(s) specified by the xxxId attributes need to be invisible. To arrange that, set the element fill and stroke attribute values to "none"
. This is one of the cases where is is not sufficient to set the attribute values on a wrapper (parent or ancestor) element. The attributes need to be set directly on the elements with the id attribute that matches the svgId or terminalId from the connector definition. Either the individual "fill" and "stroke" attributes can be used, or they can by combined using the "style" attribute (style="fill:none;stroke:none"
)
Since the connectors are invisible anyway, the schematic terminalId, and second copper layer have no effect. They can be left out of both the definition and the svg image files. For consistency with other connectors in the same files, they can be left in, as long as svg fill and stroke values are set correctly.
The invisible connector elements can be positioned anywhere (coordinate wise) in the image extents. They can all be placed at the same coordinates, without problems with overlapping wires. No wire ever connects to them, so there is nothing to interfere with.
It is not sufficient to make the view graphic elements invisible and/or move them out of the normal layer (groups). Doing that results in bogus ratsnest lines to the part, when a connection has been defined in another view. Especially when the connector is grouped with other connectors on a bus.
For parts that do not have any schematic or pcb view content, this technique does not work quite as desired. The empty part, and (initially) its part label is still visible in the views, even though there are no connectors. The only way to get around this, seems to be to define the part as belonging to the "breadboard" family.
A bus is what we call an internal connection between connectors (I don't think this term has this meaning outside of Fritzing). Breadboards and stripboards make heavy use of buses (and with stripboards, the user can change the bus structure dynamically). A number of other parts come with buses, most notably with GND and various ICSP pins on various Arduinos, but also the humble 4-pin pushbutton. The Parts Editor has a 'show internal connections' mode which allows one to visualize and edit buses by treating each of them as a wire. Here's the buses section for the 4-pin pushbutton. Notice there are two separate buses described:
<buses>
<bus id="bus0" >
<nodeMember connectorId="connector0" />
<nodeMember connectorId="connector1" />
</bus>
<bus id="bus1" >
<nodeMember connectorId="connector2" />
<nodeMember connectorId="connector3" />
</bus>
</buses>
The connectorId
attribute refers to the connector id
attribute in the <connectors>
element. The bus names are arbitrary, as long as each bus name is
unique within a given part (i.e within the fzp file).
We are beginning to add
SPICE modeling information to Fritzing parts. The <spice>
element is a child of the top-level <module>
element. Here is
an example from a resistor:
<spice>
<line>R{instanceTitle} {net connector0} {net connector1} {resistance}</line>
</spice>
There can be only one <spice>
element per part, but each element can have multiple <line>
elements. One <line>
element usually translates into a single
line of SPICE output. The items in curly brackets can be thought of
as variables which are filled in for each part in the sketch when the
SPICE netlist is exported:
- {instanceTitle} is the a part's label. A resistor label is typically something like R1.
- {net connector-id} is the SPICE node number to which the named connector is connected
- {property-name} is the value of the named property. In the above example, {resistance} might be 220 ohms.
If one of the <line>
elements
contains the SPICE .include command, fritzing will attempt to
find that file in the spicemodels subfolder of the Fritzing
pdb or parts folder, or in the user local storage parts folder. If
the file is found, the contents are pasted into the SPICE output.
You may also have multiple <model>
elements:
<spice>
<line … />
<line … />
<model … />
<model … />
</spice>
If you have multiple instances of one
part in a sketch, then only one set of <model>
lines is
exported to SPICE (since the rest would be redundant).
To explain, let me talk about the lm358 which is an IC that contains a pair of op-amps. Although these two parts are physically adjacent on the chip, conceptually speaking, you might want to use one op-amp in one subcircuit, and the other op-amp in another subcircuit, and if you are drawing this up in schematic view, the two subcircuits might not be located anywhere near each other. If you make some minor modifications to the fzp and schematic svg files, then in schematic view, Fritzing can treat each op-amp on the lm358 as a separate part which can be moved, rotated, flipped independently. The lm358 can in fact be treated as three subparts, two op-amps and a shared power/ground part.
In the fzp, the subparts are defined
with a <schematic-subparts>
element (a child of the top-level
<module>
element) which splits up the connectors. Here the
power and ground are in subpart1, and the op-amps are in subpart2 and
subpart3. The subpart names are arbitrary and must be unique within
the part. Each subpart's default label is made up of the part's label
concatenated to the subpart label. The lm358's part label is U, so if
a particular lm358 has the label U3, then its subparts will be
labeled U3_1, U3_2 and U3_3.
<schematic-subparts>
<subpart id="subpart1" label="1">
<connectors>
<connector id="connector3"/>
<connector id="connector7"/>
</connectors>
</subpart>
<subpart id="subpart2" label="2">
<connectors>
<connector id="connector0"/>
<connector id="connector1"/>
<connector id="connector2"/>
</connectors>
</subpart>
<subpart id="subpart3" label="3">
<connectors>
<connector id="connector4"/>
<connector id="connector5"/>
<connector id="connector6"/>
</connectors>
</subpart>
</schematic-subparts>
The schematic SVG which corresponds to
this fzp must use the 3 subpart ids as attributes in <g>
elements:
<g id="subpart1">
<g id="subpart2">
<g id="subpart3">
</g>
</g>
</g>
and the elements in that SVG must be
redistributed to be children of those <g>
elements. This can
take a bit of editing, since the existing schematic SVG may not be
organized along these lines, so you end up doing a lot of copy/paste.
Just for review, here is a high level overview of the structure of every fzp file:
<?xml version='1.0' encoding='UTF-8'?>
<module moduleId="..." fritzingVersion="...">
<!-- metadata elements like date, author, url etc -->
<tags>...</tags>
<properties>...</properties>
<views>...</views>
<connectors>...</connectors>
<buses>...</buses>
<schematic-subparts>...</schematic-subparts>
</module>
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. For example, <tspan>
and
<flowRoot>
(text flow) elements will not work.
Speaking of Illustrator and Inkscape, they both have their idiosyncrasies which sometimes cause problems with Fritzing. One tip with Inkscape is to save your SVGs as “plain SVG” rather than “Inkscape SVG”; this removes a lot of Inkscape-specific elements and attributes. This choice is only available from the “Save As” option in Inkscape. It can also cause problems if you open an Inkscape SVG with Illustrator or vice-versa. Another Inkscape quirk is elements containing internal transforms. Something between Qt and Fritzing code seems to occasionally miss these, so instead of
<circle transform=“translate(23, 34)“ … />
it is better to have
<g transform=“translate(23, 34)“ /><circle … /></g>
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.
Another really annoying problem with Illustrator is that if it loads an SVG originally created outside of Illustrator, and the SVGs units are not in pixels, then Illustrator does not update any stroke-width attributes when it converts the SVG to pixel units internally. The syndrome that most often results from an unrecalulated stroke-width is an SVG distorted by blobby lines.
Now about measurements and
SVGs. One of the pleasures of SVG is that the format can support
extremely accurate placement and sizing. 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. Illustrator and Inkscape tend to use pixel units, and since this
means something different in each program (see above), we would
prefer that you change the units in your Fritzing SVGs to cm, mm, or
inches. In Inkscape you can set the units 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'>
In other words, when you
are looking at individual SVG elements like <rect>
or <circle>
,
their coordinates will be expressed relative to the viewBox
and their
effective units will be in 1000 per inch increments.
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. Coordinates in Fritzing SVG elements should always be unitless, and therefore always refer to the implicit units defined by
the viewBox
. Inkscape, or maybe it's Illustrator, will usually abide
by this stricture, but sometimes <text>
element values will be
given in px units. Fritzing tries to make a reasonable conversion
from these units, but it doesn't always work satisfactorily. Best to
convert these to unitless values.
There are a few Fritzing-specialized SVG attributes:
-
drill=“no“.
This is used in
<circle>
elements in PCB SVGs. Normally, when the gerber exporter sees a<circle>
in a copper layer, it will consider it a location for a drill hole. If you are trying to lay down a circular pad, add the attribute drill=“no“ to the<circle>
element -
id=“nonconn“.
This is also used in
<circle>
elements in PCB SVGs. If you have a<circle>
element with an id that starts with **nonconn, **then that<circle>
is treated as a non-plated hole, possibly with a copper ring if the stroke-width is greater than zero. - id=“boardoutline“. This is used for PCB board shapes. A pcb board SVG usually consists of two layers, the board layer and the silkscreen layer (some board SVGs define just the board layer, others define the board layer and both silkscreen top and bottom layers—the board layer is the only required layer). The board layer defines the contour for the layer, but there may also be other graphical elements that you want to appear on the board layer, such as the Arduino alignment marks on an Arduino shield. If there are multiple elements on the board layer, Fritzing will by default choose the one with the largest bounding rect as the board contour. However, if it finds one of the elements has the id boardoutline, then that element will be used as the contour.
- id=“breadboardbreadboard “. This (along with a postfix of moduleId on the moduleId and the family as breadboard) triggers the breadboard code (always bottom layer, no pcb or schematic) and that is probably the only place it should be used.
For through-hole parts,
which mostly have exactly the same elements in both copper0
and
copper1
layers, it is possible to save repetition by simply making
the copper1
element a child of the copper0
element (or vice versa).
In fact the current implementation of the Parts Editor will only work
with SVG files in this form:
<g id=“copper0“>
<g id=“copper1“>
<rects, circles, etc />
</g>
</g>
The SVG standard gives a default value for most attributes. In particular, Illustrator tends to remove default-valued attributes. Fritzing tries to abide by these defaults, but nevertheless, the unexpected can happen—it is much safer for you to give values for all attributes. For one, missing stroke-width values can be troublesome.
There are more than a thousand parts now shipping with Fritzing. The best way to understand the Fritzing parts format is use these as examples.
WARNING: The conventions for part content details have evolved over time. Just because something exists, or is done a specific way, in an existing part does not mean that it is actually correct. The structure is likely to be correct, but things like colors, sizes, spacing, text content may not match what is currently preferred.
COPYRIGHT FRITZING.ORG ALL RIGHTS RESERVED