Showing posts with label SVG. Show all posts
Showing posts with label SVG. Show all posts

2018-12-04

Scripted font generation using fontforge

This is my first attempt at making fonts using scripts... Well, apart from a digits only font, it is my first attempt to make any font! It seemed like a good use of a Sunday afternoon :-)

The plan was to make some fonts based on classic 5x9 dot matrix characters. Not a huge challenge you may think - but I did not want to spend ages positioning dots in a graphical user interface. So I ended up making some C code, that produces SVG for each character and then Python script to use fontforge to make a font from the SVG.

My 5x9 characters are defined in the C code using hex.

   {"A", {{0x20, 0x50, 0x88, 0x88, 0xF8, 0x88, 0x88}}},

That defines the capital A to look like :-
My C code makes an SVG that looks like :-

<?xml version="1.0" encoding="UTF-8">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="816" height="1024">
   <g>
      <circle cx="255" cy="51" r="40"/>
      <circle cx="153" cy="153" r="40"/>
      <circle cx="357" cy="153" r="40"/>
      <circle cx="51" cy="255" r="40"/>
      <circle cx="459" cy="255" r="40"/>
      <circle cx="51" cy="357" r="40"/>
      <circle cx="459" cy="357" r="40"/>
      <circle cx="51" cy="459" r="40"/>
      <circle cx="153" cy="459" r="40"/>
      <circle cx="255" cy="459" r="40"/>
      <circle cx="357" cy="459" r="40"/>
      <circle cx="459" cy="459" r="40"/>
      <circle cx="51" cy="561" r="40"/>
      <circle cx="459" cy="561" r="40"/>
      <circle cx="51" cy="663" r="40"/>
      <circle cx="459" cy="663" r="40"/>
   </g>
</svg>

Which, as you can see was simple enough.

I also make a Python script (from the C code) along the lines of :-

#!/usr/bin/python
import psMat
import fontforge
f=fontforge.font()
f.version="1.0"
f.encoding="unicodeFull"
f.copyright="Adrian Kennard"
f.weight="Regular"
f.familyname="FiveByNineLED"
f.fontname="FiveByNineLED-Regular"
f.fullname="FiveByNineLED Regular"
f.em=1024
f.ascent=714
f.descent=310

Which has for that letters :-

g=f.createMappedChar("u0041")
g.width=612
g.importOutlines("u0041.svg")
g.removeOverlap()
g.simplify()
g.autoHint()

And finally saves :-

f.generate("FiveByNineLED-Regular.ttf")

Simple enough :-)

As you might guess, I was not going to just make a font as simple as that. For a start it was sensible to make some different weights and an italic variant.

For different weights, I just changed the size of the dots :-


For italic I simply adjusted the position of the dots, and told the font it was italic. I picked 10 degrees.


But that was not all. A simple dotty font looked nice but I felt I could do me. You will note I called this "LED" on the basis that it looks like a simple array of round LEDs as seen on railway stations and many such signs.

But what of LCD. For this I made squares.


For bold I actually made the squares touch, and the overlap removal in fontforge creates an outline of the joined up squares.

However, to make an italic version I could not simply move the positions as I did for the LED version as that creates a staggered row of squares. Instead I had to skew the whole glyph.

My first thought was to simply put an transform="skew(-10)" in the SVG. That worked, but there are limits to what the SVG import will do on fontforge it seems. Combinations of translations on individual components and a group object with a skew did not quite work as expected. I had to make the SVG very simple. Later, with some overlapping rectangles I actually managed to not just make errors from fontforge but segfault it! So I ended up doing the skew in the python!

g.transform(psMat.skew(0.174528))

That seemed to work well for this...


But I could do more... What about the way these fonts looked on an old fashioned CRT? So I made a CRT version which joined the dots horizontally with rectangles.


But there's more. This is something I did in something like 1981 when making a printer driver for a spark jet printer that could screen print BBC Micro MODE7 but not look like crap. Back then I created 45 degree lines joining octagonal dots. This works well for most letters.


But some needed help, notably where a diagonal joins a horizontal or vertical line, I would create a right angle not a diagonal. The fix was making a second "layer" of the bit map. For LED and LCD and CRT this did not matter, a dot was a dot, but for this JTD (Join The Dots) mode, it was needed to allow for things like the diagonal of an R to work...


This was another case which was a challenge. I originally planned on using an SVG path to join the dots, but that did not work. The import messed up the translations somehow, and then the overlap removal in fontforge just did not work. By simply creating a rectangle to join each circle, that worked, even the 45 degree ones, until I tried to apply a skew at the SVG level and that got very upset. A skew applied at the phython stage worked. Oddly the 45 degree ones are still making warnings but creating clean glyphs, so close enough.

Creating a simple ASCII character set was not hard. But these days we need a bit more, and so I went through the extended latin and did a lot of them (that I could sensibly work in a 5x9 matrix). I am sure there are more I can add. Thanks to Ray for pointing me to the SAA5050 data sheet with additional characters. So far over 400 characters, and more may be added over time.



The accents all look a lot better in the join-the-dots version as I could make the joins allow for the accents and not stick the accent to the letter in an odd way...


P.S. In honour of a previous blog post...



P.P.S. the "TXT" version is an attempt to mimic the Mullard SAA5050 character rounding logic.

So this is the result (may be updated from time to time if I add more characters) :-

FiveByNineCRT-BoldItalic.ttf
FiveByNineCRT-Bold.ttf
FiveByNineCRT-LightItalic.ttf
FiveByNineCRT-Light.ttf
FiveByNineCRT-RegularItalic.ttf
FiveByNineCRT-Regular.ttf
FiveByNineJTD-BoldItalic.ttf
FiveByNineJTD-Bold.ttf
FiveByNineJTD-LightItalic.ttf
FiveByNineJTD-Light.ttf
FiveByNineJTD-RegularItalic.ttf
FiveByNineJTD-Regular.ttf
FiveByNineLCD-BoldItalic.ttf
FiveByNineLCD-Bold.ttf
FiveByNineLCD-LightItalic.ttf
FiveByNineLCD-Light.ttf
FiveByNineLCD-RegularItalic.ttf
FiveByNineLCD-Regular.ttf
FiveByNineLED-BoldItalic.ttf
FiveByNineLED-Bold.ttf
FiveByNineLED-LightItalic.ttf
FiveByNineLED-Light.ttf
FiveByNineLED-RegularItalic.ttf
FiveByNineLED-Regular.ttf
FiveByNineTXT-BoldItalic.ttf
FiveByNineTXT-Bold.ttf
FiveByNineTXT-LightItalic.ttf
FiveByNineTXT-Light.ttf
FiveByNineTXT-RegularItalic.ttf
FiveByNineTXT-Regular.ttf

2018-11-11

SVG all the things!

I am quite amazed how many things in the business are postscript based, i.e. code or scripts generating postscript, or just hand crafted postscript files, which are then converted to PDF or printed.

I have been working all week on this, not just the plastic card printing, but now the invoices and statements and letters from the accounts system. Because of my new library for fonts I have also been updating systems that were already SVG based but coped badly with long names and strings.

But there is still a lot to do, so this is not going to happen over night.

The main change now for invoicing is the system generates SVG files. I originally planned on making simple multiple page SVG using inkscape style "layers" but actually inkscape is slow to load a multiple page SVG anyway even though it can pick out one page to convert to PDF. SVG does not (yet) have pages as a concept, but that may happen soon. Sadly I cannot seem to easily script loading once and then converting each page, so I ended up making multiple SVG files. But I have the option to make one SVG file, and I may make one that is interactive with page turn buttons, for use in a web page as well.

As has been a big topic on my blog, of late, fonts have been the challenge. I am getting the hang of it now. Latest annoyance if font family names - where some fonts have one family name and many weights and slants and so on, but others make each combination a different family name. I have ended up with code to "normalise" this (including, in one case, removing a trailing space from a family name which refused to work in the browser even in quotes!).

It also took me a while to realise that SVG font-style is *just* the slant (normal, italic, oblique), and also that SVG font-weight is 100-900 but free type uses a totally different scale. Oh, and it is normal, not "normal" when using in a style, but always "normal" when used as an XML attribute (obviously).

Anyway, finally we have a system which uses SVG masters as a letterhead and template for the content of invoices, statements and letters. This allows a lot of fine tuning (the accounts system is used by a lot of different companies). The old system using postscript allowed even more fine tuning but only if you could code postscript. This way you can edit a letterhead or layout in inkscape, which is a lot easier.

I have even set up a system to allow font control at various levels, even per account. This means we could set up an account for large print, for example. There are limits on what will fit with invoices and statements, but we can make text much larger in most cases, and text on letters even larger. We can also control font, such as using the Open Dyslexic font, if wanted. Whilst I doubt we would get many requests, especially as such documents are almost always emailed and so easily scaled on screen, we have the option now.

The other good thing is the new PDFs have much better copy/paste of content including good unicode support. I expect this would help screen readers extract text more easily.

Whilst mostly the plan was to make an equivalent system for invoices, statements, and letters, I have taken the chance to improve some things - such as a summary and totals on page 1 of invoices when they do not fit on one page.

Right now, some customers are on new format, so we can get some feedback, but we'll switch over completely soon. The "formal" invoice remains the PGP signed plain text that is emailed, but the PDF and print versions should be much nicer now.

Even so, much more to do - things like the call data records need changing and improving. This is a bit of a never ending task.

And finally, I have to say how excellent Google Fonts is. I have not loaded them all, but so far a reasonable selection can be seen on the card printing system, which I have managed to group by the base font family name. I'm happy to load any more free fonts if people have requests.


Thanks for the help from those that have been testing, especially Neil for his pedantry.

P.S. This seems odd in a way, laying out letters, as one of the very first projects I ever coded was a text editor and formatter for a TRS-80 written in Z80 code and printing to a daisy wheel printer over a Centronics interface. How time flies...

Non breaking spaces

Arrrg!

There is the normal space character (0x20), and there is the non breaking space character (0xA0).

I was not expecting to have to do anything with these specially in any way to be honest apart from spotting space characters for paragraph text wrapping logic...

However, I have run in to snags, and ended up having to add it as a special case in my code.

The first snag is simple - some fonts (and only a few) do not have the non-breaking space character encoded. So my new font system wants to know the size of every character to work out layout of text in SVG, and it "falls back" to Google NoTo fonts to find the character if missing.

This logic was originally for Emojis, but actually has the full Google NoTo set now, so does Egyptian hieroglyphics and so on. It works well (once you remove the Color[sic] Emoji font).

Thankfully most of the fonts I am using even have extended Latin, so things like Polish crossed "l" characters just work in the base font. Google's free fonts are pretty good!

The problem is that when the main selected font has no non breaking space I fall back, and I hit the Emoji font quite quickly which does, only it is about twice as wide as you expect!

So my text ends up with non breaking space encoded in the Emoji font, and being wide.

Well, this is not ideal, but why would I encounter non breaking spaces anyway? Well, because when I make the SVG output, extra spaces, and leading spaces, and trailing spaces, are all zapped. So any actual formatting with spaces (especially if using mono-spaced fonts) is totally lost. This is bad enough, but I have worked out the size with the spaces and so the result looks horridly stretch to fit the space it should take with all the spaces in place. This took me ages to find as one string I was testing with had a trailing space which I had not spotted. So now I convert all spaces to non breaking spaces for output to SVG.

This them hit the first snag that the non breaking spaces are not in the font, and so I ended up coding all spaces in Emoji (for some base fonts). Again, not spotted originally as the font I was using had non-breaking spaces encoded, but another font did not and just looks horrid spaced!

I have ended up:- (see P.S.)
  • Using only spaces for text wrapping (so non breaking spaces do in fact non-break)
  • Converting non breaking spaces to spaces for all width calculation
  • Converting all spaces to non-breaking spaces when making final SVG
It seems to finally work...

Fonts are fun!

P.S. xml:space="preserve" is your friend - it preserves spaces as they are.

2018-10-26

SVG being a tad special

I am pleased to say the work on fonts and SVG has, well, worked. FreeType just worked, and I was able to have a string of Google Noto fonts as backup for missing characters, so emojis, runes, Polish accents, all just worked. Even my new Farrington 7B font. Yay!

This is an update to A&A card printing.

But one aspect really fooled me.

In SVG you can have a text object, and that can be stand alone with the text as the content and attributes like font-family and font-size.

But you can include within it tspan objects. The advantage is that this allows different attributes for some text in-line.

For example changing to an Emoji font part way through, or some other font, or italic, etc, etc.

So far so good.

Then we come to the textLength attribute on text and tspan. This is meant to tell the application the calculated length of the text. As I now have FreeType working that out, and setting lower when I want to squash text, I have the figure to use. I added to the text element, and, err, nothing (when using tspan within text).

So... let's add to the tspan elements. I did this, and obviously I set the textLength on each tspan as the calculated length of that tspan.

It seems I am wrong. I do need to put the textLength on the tspan elements, but they have to be the total text calculated length not the length of the tspan!!!!

Update: For browsers I need textLength on tspan, but for inkscape (which makes the actual images for the card printing) I need textLength on the text object, so setting both!

Me no understand!

P.S. Everything but Safari struggles with a large value for font-size even when in a scaled SVG, showing things short (but stretched to textLength) and different if rotated! I may have to tinker with that at some point to work around. I am sure the SVG is fine!

P.P.S. I embedded fonts in the SVG for use as above, but even though that works in safari (and other browsers), it does not in inkscape. Shame.

P.P.P.S. This is what it looks like now.



P.P.P.P.S. I now have myself a nice svg/font library to do text objects, squashed, wrapped, justified, aligned, all sorts, based on system fonts using the fontconfig library to find system fonts and the freetype library to extract metrics. Works a treat and already deployed in four different systems we have using SVG (e.g. business cards if names are too long, etc).

2018-10-09

SVG, font metrics, am I being thick?

I really hope someone tells me I have missed the bleeding obvious for a change.

I think SVG lacks two key features.

1. The ability to set a maximin size on a line of text, i.e. so that if it works out longer it will be squashed in some way. There is a way to set a calculated size and have either the spacing or the spacing and glyphs adjusted to match that, but I cannot find a way to say "squash, but only if it would be too big".

2. The ability to take a block of text, give it a width (and height, why not) and line spacing and have it fill the box, breaking on spaces between words.

If there is svg magic (and I don't mean javascript to run on a web site that will do the business later), just plain svg that will easily convert to png or pdf, and still work, that is what I want.

The alternative, for which I am still massively failing to find a solution, is a simple Debian installed C code library (not C++ please) that allows me to ask "how wide is this string in this font". I found qfontmetrics which looks spot on, but is C++. Obviously, including emojis!

With this I can make the tools I current have which produce svg output (to later be converted to PDF or PNG, etc) work out when to set a line width, or break blocks of text, and work with normal svg.

All of this is a doddle in postscript, but unless someone has a patch for gs to handle utf-8 strings natively and handle a fuller character set with the likes of emojis, I need to move away from postscript, hence using svg. Just hitting this key stumbling block for now.

Update: Thanks for all the comments. I am looking at freetype at the moment. It looks like it has exactly what I need, but slightly struggling with Emojis and the like at the moment :-)

Update: Yes, FreeType has simple C functions to load a font/face and find the size of glyphs based on unicode characters, and simple to tell it does not have the character and use a noto/emoji font instead, etc. This should be simple to then work out line wrapping and sizes for SVG with tspan for emojis and the like. Now I know it is all possible and how to do it, I have to think about the project for which I was asking this - a new system for designing printed plastic cards...

2018-07-14

Some lessons learned with inkscape

As I posted, I had a bit of fun designing and drawing some playing cards. This involved code, and working on SVG artwork for court cards using inkscape. I am pleased to say they are actually being made in to packs, thanks to Ivory Graphics.


Various SVG decks are at www.me.uk/cards/

Update: Yes, we have batches of A&A and FireBrick cards arriving in a week, and we'll be selling them, but we expect to give some away as well. The A&A pack is poker size and goes up to 11 (56 card deck). The FireBrick pack is bridge card size and standard 52 card deck. Ignis is the joker, of course. Watch this space.

As I explained, I was trying to go for reasonably compact SVG files, which meant all the main cards were code generated and using some hand crafted SVG paths, even using SVG symbol objects. This worked well making quite small SVG files. The complication was the court cards, which have a lot of detail.

My solution was to use inscape, and make layers - the lowest being a scan of the antique cards I have, and then layers for Gold, Red, Blue and Black. Each layer was one fill path from which I extracted the path and made part of the final SVG without all of inskscape's bloat. It worked well, and even allowed me to make them one way up only and duplicate the rotated side.

Having spent some time drawing the court cards the first time, I decided I could have done some of it better. ..

Scale, and pixels.

One issue was that some paths inkscape made had a transform, and for this reason I made each layer a single path. I included the transform inscape had chosen in the final SVG.

However, by setting inscape to use px (pixels) everywhere I was able to convince it not to scale and translate stuff, pretty much (few exceptions easily worked around).

Concatenating paths

My final SVG did not need several paths per layer though, so I concatenated them in to one path. This did not work, and it took me a few minutes to work out why.

SVG allows relative and absolute functions in the path, but you can start a path with a relative m command (move) and have several sets of co-ordinates. The first are a move and then the rest are line draw and all are relative. But as it is the start of the path the first move is actually absolute and not relative.

Why SVG has this logic I have no idea - you have to separate the first co-ordinates from the next by something, such as white space, so could have an l (line) instead of a space.

The problem is that tacking an m on the end of an existing path is relative! So I had to change it to M and find the separator and add an explicit l after the first co-ordinates if it was running-on from the initial move.

Compressing paths

At the same time I removed the spaces before and after all of the letter commands, as not needed. That worked with no problem!

Fill or stroke

One of the things I did originally was make all layers a simple fill. However, the blue layer is almost entirely line drawing on the cards, and the rest basically colouring in between the blue lines (almost none of which is actually blue). So I decided to add an extra stroked blue layer, and even a thinner stroked blue layer used for some of the fine detail on hands and eyes.

This had a much bigger effect than I expected!

For example, if you have a simple Bezier curve like this - two points and two control points:-


It translates to a path of "m 15,320.54165 c 15,-25 55,25 70,0" which I compress to "M15,320.54165c15,-25 55,25 70,0" which is tiny.  The co-ordinates are mostly whole numbers (because I am snapping to a pixel grid).

However, as soon as you stroke this to a fill, you get this:-


As you may be able to just about see, that has 12 points, each of which have control points. It makes a path like this "m 31.427734,303.5918 c -8.488979,-1.08833 -19.486526,2.61231 -25.0019528,11.80468 A 10.001,10.001 0 1 0 23.574219,325.6875 c 1.984573,-3.30762 1.612026,-2.73198 5.310547,-2.25781 3.69852,0.47417 10.101562,3.08984 16.976562,6.21484 6.875,3.125 14.221958,6.75933 22.710938,7.84766 8.488979,1.08833 19.486526,-2.61231 25.001953,-11.80469 A 10.001,10.001 0 1 0 76.425781,315.39648 c -1.984573,3.30763 -1.612026,2.73199 -5.310547,2.25782 -3.69852,-0.47417 -10.101562,-3.0918 -16.976562,-6.2168 -6.875,-3.125 -14.221958,-6.75737 -22.710938,-7.8457 z"

Not only has a 2 point Bezier become a set of 12 Beziers / arcs, but all of the points are no longer nice small integers (for obvious reasons).

Easier to use inkscape now

By changing to stroked paths and allowing lots of paths I was able to easily copy paths to make filled in areas within blue lines on other layers, and I could use path intersection and line cutting logic in inkscape to avoid rough edges or manual lining things up by eye.

This also makes it way easier to make tweaks and fix errors later. Previous I draw paths and then converted to stroke fill and union with the layer making edits almost impossible. Now I can simply edit the distinct paths.

Adding pips

The suit symbol is a feature of the clothing on all of the court cards. Previously this was just part of the artwork, but I have now made it use SVG symbols to show the suit symbol (pips) in the necessary size, rotation and locations. This means that if the suit symbol is different (as I did for an old style of cards) they are changed on the court cards as well. It also saves some space, just.

The end result?

Well, so far I have re-drawn one of the cards, which was slightly less tedious than before. The new Jack of Spades is 41k instead of the previous 119k. Note Chris Aguilar's Ace of Spades, saved from inkscape, is 137k.

What next?

I'll probably do all of the cards eventually. I am taking the opportunity to basically just do them better anyway. I feel a lot more like I have made some creative input to this project now, rather than just trying to exactly reproduce the (badly printed) antique card designs.

P.S. I have done two cards now, it is time consuming, tedious, and requires some artistic elements, but the end results are very nice so I plan to finish all 12 in due course just for good measure. They are also uploaded to wikimedia. If I do before the next batch of printed playing cards, they will be a nice version 2 of my designs.

P.P.S. I have done the Jacks now, it is hard work, but little things like inkscape has a (configurable) delay before snapping to an object, which means if you are too quick you get misaligned stuff (WTF?). It has a "cut path" function which "misses" and screws up some times. But I am getting better at using stroke to path to make parallel curved lines which looks better. Not only are we around ⅓ of the file size now, but much neater artwork. I also discovered I gave one of the Jacks the wrong colour of hat before, making these initial packs we are getting this week "limited edition" ones :-)

P.P.P.S. I have done them all now - the main problem is that real work takes priority, but I am happy with the end result and I have updated wikimedia. The history of playing cards being [badly] copied dates back around 500 years which is quite amazing really. I feel almost honoured to be a step is such a long tradition.

2018-06-26

SVG Vector Playing Cards

I decided to make some SVG playing cards, well, for fun. Scalable Vector Graphics is excellent for such things and works with all major browsers.

Chris Aguilar's
Queen of Spades
But first I googled, and found someone had already done it! In fact quite a few people have - with perhaps one of the best examples done by Chris Aguilar (here). There is even a rather good set of Javascript functions which work with his cards (here). Wikipedia also have an impressive set of SVG playing cards of various styles (here). People do like their playing cards, don't they!

Well, to be frank, I was almost put off. Chris Aguilar has done an excellent job, I am impressed. Well, everyone doing this has done a stunning job to be honest. But that did not quite stop me in my tracks (those that know me will not be surprised). It would be a fun exercise to do this, but really only if I can do a better (or at least different) job in at least some aspect. To be fair, that was going to be hard. From an artistic point of view, Chris Aguilar has done an excellent job as had others, and I am not really an artist, so I concentrated on the technical aspects mostly. Even so, this turned in to a week long project and a lot of work just for a bit of fun...

This is what I came up with - enjoy...

How are things better and/or different?

Licence

One of the simplest improvements I can make is releasing my cards under a completely open Creative Commons CC0 Public Domain licence, not even requiring attribution. This makes them much easier to use. Whilst I'd like credit, obviously, and it would be appreciated if the link on the Ace of Spades was left intact, that is not a requirement. Do what you like with them.

Compact SVG

The first thing I noticed was that Chris used inkscape. This is an excellent choice, and it is pretty much the editor for SVG. It also does a good job tracing scanned images. However SVG has a lot of bloat. Making a ten of clubs resulted in a file that was 29k. One I picked on wikipedia was 33k. By making the SVG myself, not using inkscape I was able to make use of symbol objects, so only drawing the club once, then using it 12 times for example. My SVG is probably not quite as compact as I would like, but my ten of clubs is only 1.7k, so much leaner.

My 10 of Clubs
Hand crafted paths

The other thing I could do to save space was to hand craft some of the SVG, making the pips (suit symbols) and digits/letters (value symbols) from scratch. The actual shape of these has varied over time, and this allowed me to add my own subtle variation on a theme. It ensured the pips were symmetric and took less space. I am quite pleased with the result.

Separate files

One slightly odd thing about Chris's work is that he has made one large SVG image for the whole deck. I decided to make separate files for each card and a zip of them per deck. I am not sure why he did that to be honest, as he says, you can export them from the SVG he has made, but that is a tedious task, 54 times, so seems unnecessary. Wikipedia has separate files.

Court cards

The court cards are an issue. All the rest can easily be made and done so programatically, but the court cards are art! I am not an artist even if I did take O-Level art. So I had basically three choices.
  • I could use Chris's court cards, or someone else's. This is somewhat admitting defeat, and obviously I would credit him, and it would limit the licence by which I could publish.
  • I could design and draw my own - except, as I say, I am not an artist.
  • I could scan / trace / copy / draw from some actual court cards.
Antique (c.1870) Goodall & Son piquet deck
One possible issue here is one of copyright. Chris has copyright in the work he has done. Every time someone makes a design, or photograph or scan, they create a new copyright. Notably he says he has used very old designs that are out of copyright, but I noted different card manufacturers seem to have subtly different court cards and his look identical to Bicycle playing cards, but he may well have found an out of copyright original from which to make his design. My solution was to obtain some actual antique playing cards (Goodall & Son, c. 1870), so old they do not even have numbers on the cards (you have to count the pips!) but they have nice court cards and they are too old to be in copyright any more. They are thick board, square corners, badly aligned printing, and this was a Piquet pack (so no 2 to 6 cards), but the court cards were fine.

Trace of Goodall & Son
Ace of Spades
(dates to 1867-97)
I could have just used inkscape image trace, but that does not fit with the neat and compact SVGs I had done so far, and the originals are not that good, so I used inkscape to carefully manually trace the court cards creating my own new designs. Time consuming, and like most artistic projects I find you can spend forever on the fine detail. In fact, I think I have found a bigger time-suck than even 3D printing - it took over three days solidly working on these, and even then I went back to tweak a couple of cards once I got reasonably good at it.

What really bugged me is that the designs should be symmetric, in theory, but these cards are not only badly aligned print of each colour but badly drawn in the first place, so I had to be a tad artistic in places. I was drawing only half the card but kept having to preview with the 180 degree rotation to confirm things lined up with the other half. It even turned out one card was designed to not be symmetric, so I improvised, the Jack of Heats actually had a heart dead centre, so had a "way up", so I did two hearts side by side instead.

History

There is one thing that is noticeable though - modern court cards (at least English decks) all face in a standard way. It is a total mess, i.e. there are four ways they face (profile left, half left, half right, profile right) but each suit does not have all four versions. The deck I used as reference is old, and so six of the court cards actually face a different way to modern cards - it makes them that bit different.

Some of the history is interesting - it seems in the 19th Century Goodall & Son and De La Rue were cornering the market in playing cards, merging in to De La Rue in the 1920s, and going on from making playing cards to now making bank cards. I never knew bank cards had a history in playing cards!

My Queen of Spades
Coding

I did not simply make a deck of SVG cards - that is not quite my style - what I made was a C programme that creates a deck of cards. It has lots of options (see below). It is fun working out the different ways you can make cards, and some of the subtle detail - for example, the 9 of clubs needs the centre club to be slightly higher than central to avoid clashing with the clubs on the sides! Of course the SVG was made using an XML library in the code.

Then I made more C code, this time to allow me to edit and tinker with the court card drawings in SVG, and extract the raw paths to make the include file for the main C code.

Size

The design allows me to make other sizes easily but I decided to stick to standard poker deck size (2.5" by 3.5") or the metric version (63mm by 88mm). Obviously as SVGs this is pretty academic as it is scalable.

Ghost pack is confusing
Variations

The C code, which I may yet publish, has a number of options which I can use in any combination. I have published a selection of decks made using some of these.
  • Ghost - all black except the small pips under the value which are red for hearts and diamonds - inspired by a Bicycle Ghost deck. No, I have not done a black ghost deck (yet).
  • Blue - Blue instead of red!
  • Plain - Court cards and joker are simple letters, making the deck much smaller SVG.
  • Box - A box is present around the court card artwork anyway, but this adds a box around all of the other cards, with a cream background
  • Ace of Spades - This is normally "special", dating back to showing tax was paid (apparently) but can be made simple, just one standard size spade pip in the middle. Custom text/URL under the ace as well.
  • No-Left - Not showing the index value and suit on the top left - so old school where you had to count the pipes
  • Right - Also showing the index value and suit on the top right, for left handed players!
  • No-Flip - Not inverting the pips on the bottom of the cards - like really old packs
  • Old - using old style pips from the 1870 deck - they look quite different to what we see these days - typically used with no-left and no-flip to give the authentic style
  • Eleven - Add an "eleven" card for extra fun - it comes between 10 and Jack.
  • And of course options for artwork with no border/outline, and with bleed area for printing, and different sizes (bridge, poker, etc).
[update] Several more options including symmetric pips and 4 colour decks, etc, as well as making print ready artwork to order real packs.

I addition, I can make custom backs, and jokers and so on for different decks.

My 11 of Clubs
Going up to 11

Obviously I have made a pack with 11s in it (between 10 and Jack). Adding an 11 seemed obvious and for some games it will be simple as the order of cards is what matters (it is clearly ... 9, 10, 11, J, Q, K). So anything based on whist is no problem. Where it gets more complex is where the cards have scores, e.g. J, Q, K count as 10 and A counts as 1 or 11. Well, should the court cards now be 11? Should the A only count as 1 now? You'd have to make your own rules. I have not found much about using 14 card suits with my googling, but have found other SVG cards for 11s, so not original by any means.

Printing

I added options to add 3mm bleed area, and no card border/outline, to make it easy to make print ready graphics. An inkscape command line easily turns the SVGs in to PDFs. I had to design in clip paths for my court cards as web browsers limit the symbol to the viewBox, but sadly inkscape seems not to do that, so "bleed" from my court card designs were showing.

I found a company that seems to know what they are doing when it comes to printing playing cards, Ivory Graphics.

One thing that did puzzle me is their print tolerances. They want 3mm bleed around the card and 5mm clearance inside. This makes no sense as surely if they can be more than 3mm off on the card cutting they will be beyond the bleed, so why expect 5mm clearance not 3mm? Anyway, they were happy to try with 3mm clearance, which fits with actual playing cards I have checked. The big issue is that even 1 or 2mm may be enough to make an asymmetric back image which can be exploited, so a serious playing card printing company has to be pretty damn good and way better than 3mm...

The other thing is the way they work - and I suspect it is just common for companies to work like this. They have a pretty slick ordering system - you ask for a quote with all the options very clearly laid out, and then send one, and you click a link to order. You upload artwork (PDF files, nice). They have artwork templates and rules, so pretty simple. Now, if I was doing it, I would allow you to arrange which artwork is front and which is back of each card and the arrange the order of the cards, but no, it just lets you upload a load of files (and only one at a time, when I know browsers can handle more than one at a time if you try). You have to give them separate instructions for how the artwork is to be used, and even then they don't necessarily follow the instructions. Then produce a "proof" which is again PDFs but one for each front and back of each card with the card outline. This process seems to take a couple of days and be somewhat manual their end. I would have made it part of the ordering system showing the "proof" there and then, and hence bypassing some manual process and removing a two or three day delay in the process. However, with all of this, they do have good expectation management saying they take 6 days - I am impatient and finding inefficiency a tad annoying. That said, they were interested in the suggestion for improvements and said they are always trying to improve.

Email was a challenge - their system did not "like" that I had ivorygraphics in the email address I gave them, and my system flagged all their emails as spam so I had to go hunting for them!

The real proof is seeing the test pack of cards.

The test pack of an A&A deck

The verdict - well the cards are good, they look and feel the same as a "real" pack of cards, but the cutting was not perfect on all cards. I have changed the design slightly for printing to have a bigger margin to avoid this being such an issue - this was a "test pack" after all. The printers have also said they were not happy with the cutting and are doing a new test pack for me now.

P.S. Having the test pack has actually allowed me to make a number of minor changes to the designs, not just margins so that print tolerance issues won't show, but also really subtle things like miter-limit on the top of the digit "4" and other details that seem more obvious looking at the actual pack.

2018-02-05

The important bit!

You have no idea how much debate this caused internally! Not just the actual design of the polycarbonate printed label, but how it shows on the web interface...


The "clever" bit was to make the FB2900 status page have an image of the front panel. Previously we have had simple rectangular boxes with colour and labels for speed/duplex. This time it was made using the design drawings and hand crafted SVG. I originally had the SVG made from a PDF made from the drawings, but that was massive by comparison and did not really help with what I need. I had an SVG but some parts of it needed to have id tags to allow some dynamic changes.

In the end I had to manually draw all the physical bits, the USB socket, the power socket, and the Ethernet sockets. My digital callipers were useful. The end result is pretty damn good.

We then have, within the ports, a rectangle with text to show a port connected. The green is port up and the purple is actually "remote fault" which I was testing. It works well.

The trick was a websocket feed of live status changes causing a simple javascript function to update the content and classes on the SVG objects in real time. It works! Next step is probably live port LEDs as well.

Technical bits included the fact that "className" is not a thing in SVG, you need "className.baseVal". That fooled me for ages. Also, for a bit, I forgot CSS does not allow // comments and just causes next thing to be ignored - arg! I hate CSS!

The labels under the SVG are simple divs with controls on width. This is because SVG makes it almost impossible to have a wrapped block of text.

So what caused all of the debate exactly? Guess!

The power connector. I spent ages drawing that to get it just right. It looks just like the real thing. Only issue is, of course, nothing is plugged in to it, and that does not reflect reality does it? But seriously this is a diagram, the RJ45s have nothing plugged in, just some green rectangles with the port speed/duplex.

So, we tried making the power green like the plugged in Ethernet or USB port - looked messy. We tried an green outline - maybe better. But both just draw attention to what is essentially a cosmetic detail like the logo and the grey background.

Final solution, add a label under it with the voltage range, sort of shows we know there is a power connection maybe? In fact the code has to handle three different power supply options on the FB2900, so not that daft.

Personally, I like the un-plugged power. It is like a deliberate grammatically error so that people post saying that it is not plugged in and create free advertising for you.

But all in all we are catching up with switches from the late 90s that show the switch graphically. I think it is really neat, and the fact it is live via web sockets even more so. The live status of ports is a really useful thing to have in many ways - this is just "pretty" as well...

P.S. We have live port LEDs now (optional), and as expected that creates blinking on the port that is used for the web socket to report the LEDs blinking :-) We may be able to improve that...

2018-02-03

svg inkscape and ghostscript...

Very technical one this time.

As I have blogged before, a lot of things are now being created as a master in SVG format. It's one failing is blocks of wrapped text, but apart from that it works really well.

So, the new FireBrick serial number labels are done in SVG, and they include a QR code of the serial number. Simples. Well, you would think.

The target printer is 300dpi, and so the design has all been done on nice hard integer units at 300dpi. This is especially important for things like bar codes which need to be pixel aligned. In this case 4 prints pixels wide per QR pixel. If this is not perfectly scaled or aligned the QR code gets all aliased in nasty ways and is not as readable.

The svg uses width/height and viewPort to ensure we can use 300dpi units but be the right size, e.g. height="27.940000mm" viewBox="0 0 1185 330" width="100.330000mm"

The SVG looks perfect, obviously, whatever scale...

I can use inkscape to convert that to a png at 300dpi and it looks perfect...


We are using a Brother QL-700 which installs nicely on (32 bit) linux using the provided drivers and operates like a normal Linux printer as postscript (using ghostscript behind the scenes). So I use inkscape to make an EPS for printing. Again, simple.

This is where it goes wrong. inkscape is making postscript using default (72 dpi) units and 3 decimal places. e.g.  28.801 28.16 m 35.52 28.16 l which means a gap there of 6.719 pt which is 27.995 pixels at 300dpi, that is 7 QR code pixels. The issue is rounding. Sometimes it would be 3.995 pixels and sometimes 4.005 and so on, so you end up with a badly aliased QR code.

The fix was to make the SVG not scaled to the right size but just using the 300 dpi units. In fact, better would have been to scale to 72 dpi units default for EPS but as it happens the default units of SVG (96 dpi) work to produce integer values. This, of course, makes a much bigger image, so a bit of sed to add a 96 300 div dup scale was all that was needed.

What an annoying mess. If only inkscape understood that EPS can have a scale command, and it could have maintained the original units from the SVG in the EPS rather than converting to 3 decimal places. I may find the developer forum and suggest a change!

Here are the before and after - the bottom is before which as you can see from the checker board is rather broken. Now we have nice readable QR codes, yay!



Microwave plates

We have many plates. They work as plates. They are fine in the microwave. But not this fucking plate. I have blisters on my fingers from pic...