Font resources?

Aren’t they intended that way because they are not standalone characters but for putting accents on top of other characters?

Yes, that is my belief also, but I want to see what they look like on their own to check rendering. Also, it looks like the two or three glyphs that have problems have overlapping contours, so my polygon inside polygon check fails. Also, the line spacing indicated by the font seems way too big.

They way I’ve made this work, i’ll Have to go back and see if I’ve messed up any DRAWSEGMENT specification, so that’s due for more tests. And I’ve got a basic font manager implemented to list and select fonts. Requires preprocessing any TrueType (TTF) font using a Python3 program that will be supplied.

1 Like

Here’s a selection from Noto-Symbols and from Carr’s Electrical Symbols, rendered in KiCAD.

One thing that really helps with licensing is that I won’t be distributing fonts. You can download/purchase and use fonts according to your licensing needs, whether professional or personal. The preprocessed files I’m converting to are about 5x the size of the original TTF font files.

And here’s a selection from a Noto Serif font. These probably won’t look great on silkscreen, but you can put any font on any layer.

I can add holes to a DRAWSEGMENT S_POLYGON with a Python script. However, the holes are not apparently saved in KiCAD.


Is there any hope of KiCAD supporting holes in DRAWSEGMENT S_POLYGON? It is supported by the SHAPE_POLY_SET that is used by DRAWSEGMENT. Fracturing letters will create visible cuts in the glyphs.

You can ask for that feature on kicad gitlab but I don’t see why fracturing will be visible. Have you tried it?
Or you mean they are visible in the outline? So what?

I have confirmed the following on TTF fonts (using one example) and on KiCAD 5.1.6-release storage of polygons (DRAWSEGMENTs)

NotoSans-Regular font includes outlines that have a variety of top level windings:

  1. top level outlines are both CW and CCW,
  2. Child outlines (holes) are not always opposite winding of their parent.
  3. I found 32 cases in NotoSans-Regular where at least one of these is true.

I have boiled this down to requiring a hierarchical analysis (and determine polygon within polygon) to determine which are holes and which are polygons.

With KiCAD 5.1.6-release,

  • “Within” in the following context means the polygon/hole exists in the same SHAPE_POLY_SET using AddOutline() or AddHole().
  • Multiple polygons within one DRAWSEGMENT can be created, and are moved together, yet only the first one can be selected (the others are selected simultaneously)
  • multiple polygons within one DRAWSEGMENT are not saved
  • Holes within polygons are displayed, but do not move together
  • Holes within polygons are not displayed saved.

As previously recommended, in the current state of kicad, I will have to manipulate polygon outlines at least calculate “Polygon_1 not Hole_1 not Hole_2”. Alternatively, implemented “Polygon_1 not (Hole_1 union Hole_2)”. I wonder if it’s possible to have two top-level polygons specified as a single series of points (so “one DRAWSEGMENT series of points” representing the polygon) with a zero-width (or maybe 1nm width) connection between the two? If this were possible, then it would be possible for users to move each letter glyph as a single unit.

It’s possible: just find two points on these polygons that are closest to each other and then insert the outline of one of the polygons into the outline of the other creating duplicate points at the connection ends. They need to be of same winding beforehand to not create intersections.

Another thing is that it’s a bad idea if such polygon will be used on copper. Any fab will reject 1nm copper strings between polygons. Even on silk they may ignore it and may reject it.

Proper solution is to support multiple outlines in drawsegment.

It’s better to check how KiCad behaves and what the result is in gerber. The gerber format allows “simple cut-in contours” and actually KiCad uses them for zones.

HiGreg figured out holes already, his last post talks about combining 2 separate polygons into one using very thin string.

1 Like

Thank you both, @eelik and @qu1ck! I appreciate the gerber spec excerpt. I felt I learned enough about the problem and was seeking algorithmic solutions and upon review of options decided that the Clipper library was going to be useful. Then I looked at the KiCAD source code and, of course, the KiCAD developers needed the same functionality.

SHAPE_POLY_SET has several methods that might be useful. There are also boolean operations using the Clipper library (the library I would have chosen as well)

.Fracture (and Unfracture)
.Simplify

Within the Fracture() method, Simplify() is commented:

Simplify( aFastMode );    // remove overlapping holes/degeneracy

And simplify “just” does a union on all outlines of the SHAPE_POLY_SET.

The basic SHAPE_POLY_SET structure seems to support multiple outlines (filled contours) and multiple holes within each outline. However, this basic structure does not appear to be saved in full when saving the board (confirmed through experiment, but not yet through source code review). There doesn’t seem to be a method that returns several SHAPE_POLY_SETs that would allow adding those to the board as separate DRAWSEGMENT S_POLYGONs. I can do so in python if necessary. I’ll do more source code review and experimentation to find the right combination of functions, but it does seem at the moment that KiCAD provides the necessary methods and geometric functions.

And just for fun, here’s my field of fonts that I experiment with. It includes the full set of glyphs several times from several fonts.

Edit (followup): Fracture seems to work, basically. Here is a short experiment of saving. After loading, it looks perfect:

All I did was add a call to polyset.Fracture(1) the (1 indicates whether it is fastmode, 0 doesn’t work but 1 does). This seems to work with multiple holes (“B”). I think I’m currently creating polygons as separate SHAPE_POLY_SETs, so I’m not testing the capability of Fracture to work with multiple polygons.

When I try to process all the glyphs in the set, KiCAD crashes. I’m wondering whether this has to do with the inconsistent windings I saw earlier.

1 Like

Ok. I tried to process all the glyphs in NotoSans-Regular again and it worked without crashing. Not sure why it crashed before. But after save and load, I only see a few artifacts from the fracture, which are totally acceptable. I’ve indicated a sample of the letters with (barely visible) artifacts with a pink dot below the letter.

Edit: drawing all the glyphs now takes significantly more time (4x-5x maybe). I am doing two things different: estimated winding with ALL points instead of “simplified points”. And Fracture()ing after each hole added to the SHAPE_POLY_SET. “Simplified points” are when I take Bezier curves and just add the end points and control points. I can estimate winding and (mostly accurate) which polygons are within others with the simplified.

I can speed some of this (back) up, but not all of it.

I myself did attempt to make a plug-in that uses HarfBuzz and FreeType to put glyphs onto PCB as a footprint (contains polygons), but never finished that. Perhaps someone else could revise this idea.

1 Like

That’s a good idea. Maybe someone will continue with it! Thanks for posting these leads to open source libraries for working with fonts.

Just for fun, I downloaded a 3x5 (super small!) font ttf file and imported. I continue to fix bugs so there’s a reasonable interface for displaying characters within KiCAD using KiCommand. You can rotate, scale, and place text anywhere.

2 Likes

Still working through bugs. To do so, I’m printing large numbers of characters from a large number of fonts. Here’s my font list, I’ve printed out the name in the respective font. The list is too long to show detail along with the entire list, but here’s a zoomed out look at the list:

And a detail screenshot that shows some of the anomalies in CamBam fonts:

A KiCAD refresh takes a minute or so with 11000 characters, and crashes entirely when I try to print all characters from all these fonts. My thought is some CamBam characters might have unexpected contour definitions (i.e. crossing or touching). I also have to make sure there are no bizarre arrangements of existing characters as a result of my testing (improperly formed polygons or polygons located outside of -1000mm to 1000mm) which KiCAD might have trouble with.

Is there any possible optimizations that could be done to reduce the refresh time, I get its a very large number of polygons, but curious if its the drawing stage or some pre-processing that has to run each refresh?

I haven’t confirmed the environment (re: bizarre polygons or out-of-range locations). But if I can get to it, I can investigate more and file a bug report. Does anyone have similar experience with 11000 or more objects? (refresh is a call in Python to pcbnew.Refresh().

Edit: I’m now up to 25K polygon DRAWSEGMENT objects and refresh is less than a second. Here’s a partial screenshot of all characters in 40 different fonts. Not sure why the top 10 are not showing all of their characters.

I’ve been able to combine all the polygons in a single glyph into one DRAWSEGMENT. Previously, each individual polygon or character component that was an “outline” was its own DRAWSEGMENT, individually movable. Now, all of them are lumped into the same DRAWSEGMENT and the select/move together. This is done with .AddOutline() and .AddHole() on one DRAWSEGMENT S_POLYGON per glyph.

Note in the above screenshot the character “a” with diacritical marks above it are all selected as a single moveable DRAWSEGMENT. This is indicated by the selected DRAWSEGMENT having edit points defining the outline. If there were multiple DRAWSEGMENTs selected, KiCAD wouldn’t highlight the individual polygon points in the outlines.

1 Like

It’s looking better each time I am able to work on it. I’ve been able to interpret OpenType fonts of type CFF and OpenType collections (*.otc files). That in addition to the TTF fonts above opens up a large number of available fonts. Here is a sample from
Noto-sans-cjk-jp-regular.

There’s still some work on tracking down the bugs in the glyphs for a, s, M, Q, S, 3, 4, and 8. I’m glad all the work I did on TTF character spacing carries over. What’s new here was building the KiFont files by the cycling through font collection, and interpreting the glyph information (“Character Strings”) in CFF and translating them to SVG. Then I relied on the SVG to KiCAD Polygon code I already had developed for TTF fonts.

Not easy, but fairly straightforward. Also interpreting the glyphs and building the KiFont files takes a long time, perhaps 2-3 minutes per font. There were 36 fonts in the CJK Sans OpenType collection. Plus the files are big, about 50MB per font. I’ll probably not try to reduce that until I get something published. For now, you only need to keep the font files from which you want to place characters. And once placed, you don’t need the files anymore.

The code probably supports TrueType collections, but that hasn’t been specifically tested yet.

2 Likes

Amazing work you are doing HiGreg. :+1: :+1: :+1:

1 Like