0
\$\begingroup\$

How can I invert a font like so:

See here: enter image description here

This is my own .ttf font, I can edit it. The image that I posted was inverted manually by me. I am searching for a way to invert automatically all characters of the font.

Invert means: convert 1 to 0 and 1 to 0. Which will convert the filled (black) parts to transparent and the transparent parts to filled.

I want a "Font Invertor" software or a simple way to achieve this. Does High-Logic FontCreator do this? I didn't find a way with the latter.

\$\endgroup\$
3
  • \$\begingroup\$ Can you clarify, are you working with a bitmap font or a vector font? With bitmap fonts, any old image editing software will let you invert your font texture, or do arbitrary processing (like omitting the coin's extrusion/shadow in your example at the right) \$\endgroup\$
    – DMGregory
    Commented Jan 28, 2016 at 18:34
  • \$\begingroup\$ @DMGregory I'm working with a .ttf font. \$\endgroup\$
    – user78110
    Commented Jan 28, 2016 at 18:51
  • \$\begingroup\$ Consider downloading the picture and inserting it within the question, because in the future if by any chance the link goes down, your question will become of little use for others who otherwise could find it by searching on a similar problem \$\endgroup\$
    – MAnd
    Commented Jan 28, 2016 at 19:37

2 Answers 2

3
\$\begingroup\$

The way outline fonts (such as ttf) work is by defining a set of curves by vector graphics (quadratic Bézier in the case of ttf).

What is inside or outside? At the moment of rendering the target area has a set of pixel where the character will be drawn. The following is a simplification of the algorithm to do so:

  • Go row by row:
    • Start by considering we are "outside"
    • If we are "outside" and we crossed an outline, are now "inside"
    • If we are "inside" and we crossed an outline, are now "outside"
    • If the current pixel is "inside" color it
    • Advance to the next pixel

Visually:

These are the outlines:

Outlines only

Now, we start outside. We advance to the first pixel. We have not crossed any outline, so the pixel is outside and we don't color it (highlighted in ligh gray):

Onlines plus first square in ligh gray

We are outside, We advance to the next pixel. We crossed an outline, so now we are inside. Since the pixel is inside, color it:

Outlines plus first square in light gray and second square in blue

Continue advancing, we don't cross any outline for the next few pixels - so we keep coloring them:

Outlines plus first square in light gray and a row of squares in blue

When we cross the other outline we are outside again:

Outlines plus first square in light gray, a row of squares in blue, and the following squares in light gray

If we do this for each row, we will have the character fully colored:

Outlines plus all squares colored

Note: this is disregarding antialias, subpixels, and any transformation applied to the character. Also, since this is a didactic explanation, I'm pretending the outlines alway fall between pixels, in reality you will have - for example - pixels that are 60% outside and 40% inside. For a more detailed explanation (and a bit of history) see the video The Font Magicians - Computerphile .


Getting the inverse outline

Now, see what happens if I remove the exterior outline:

Outlines minus the exterior one

If we follow the steps described above, the result is this:

Outlines minus the exterior one plus all squares colored

Note: To do this in FontCreator select all the points - and only the points - of the exterior outline and hit delete.

Adjust the size and position of the character as needed.


Getting the inverse bitmap

Also if you are rendering without antialias, you may always take the character bitmap...

Outlines plus all squares colored

Fill the exterior (that may be tricky, as you need to start a flood fill on a pixel that you know is outisde, the key is to check the color first):

Negative of: Outlines minus the exterior one plus all squares colored

And then get the inverse of the image:

Outlines minus the exterior one plus all squares colored

Note: this is proably ruined if you have antialias.

\$\endgroup\$
0
\$\begingroup\$

Your expected outcome contains a step that will become a problem.

To get to the result you must first determine what part of the graphic is considered a letter. Your original font is basically an outline.

So what you're looking for is to detect what part of the letter is the 'inside' and fill that.

The problem here is that it becomes hard to detect. How would you find the tittle (the dot on a i or j) to be part of what you want filled? And how to find if the inside of the p should not? And the complication added here is that you made a bitmaplike font where diagonals may be consist of separate blocks entirely. So computationally this ttf font will be complex to invert.

Since the ttf font is monochromatic you can't actually this in post processing either. Draw a text to a bitmap and inverting the bitmap will not produce the desired result. Conside the top left empty block in your image. It is white in both the normal and the regular version.

So what to do? Since you are using a bitmaplike font anyway... Use a bitmap font for this. You could use two colors to distinguish the outline and inside and use a shader/code to replace the colors with whatever you want. Use just the inside or just the outside or combine them with fancy color effects!

Note: the inverted process of creating an outline for a vector font is a lot easier, as it is basically enlarging the existing data (since that data is actually describing what is part of the glyph.

\$\endgroup\$