Using Custom Font in "text"

Hello @David_Tschumperle. This now looks much better, so thanks. The 500px is rendering nicely. I would have made them even bigger, so it actually can be used on larger images, but nice.

I looked at the gmic_fonts.gmz … and did not quite get it how it works.

And an interesting one…
text "LOVE",0.5~,0.5~,${"font \"CHEQUE BLACK\",800"},1,255,255,255

I don’t have this.

800 still remains blurry on my end. 512 seems fine though:

800 here:

512 here:

I think at the end of the day, it’ll do for my need. I’ll keep in check.

Strange, maybe the filter update is not up to date.
I don’t get this.
What font did you use ?

impact

I get this, with a height of 800.

I tried a fresh install too with 3.3.1. It doesn’t work.

Also, sorry to bother you, but how do I get persistent font for GUI filter?

Got it:

    if $text_neq||!narg($_persistent)
      if narg($_persistent)
        $_persistent remove_named output,rc_car_name _persistent=
      else
        0 l[-1] { i $_path_rc/gmic_fonts.gmz keep[impact] name _impact }
      fi
      5349,335
      text[-1] $text,.5~,.505~,${"font $_impact,490"},1,1
      autocrop[-1]
      ge. .5
      name[-1] rc_car_name
    else
      $_persistent remove_named output
      _persistent=
    fi

Funny, No answer. Again, if I understand how to do the font.gz file, I am happy to look at the Magic…

Be patient please. There’s also the option of opening a linux virtual machine to do the job. Maybe there will be a better solution. I too want to know how it works, but I think I will resort to looking at the source code within CImg.h.

I think I may have a clue now:

image

$ $_path_rc/gmic_fonts.gmz k[impact] unserialize

I think you use serialize command to put it in the format the images are stored in .gmz file in.

See - G'MIC - GREYC's Magic for Image Computing: A Full-Featured Open-Source Framework for Image Processing - Reference Documentation - serialize

Each image index correspond to the character unicode value.

Thank you! Thant will probably help! Now I only need to read the manual to find out how to turn 256 images or so into a serialised, named array.

The following creates 256 PNGs __font_01.png to __font_FF.png for a font test.ttf (hard-coded at the moment) using magick. Not very clean but it seems to serves the purpose.

     for $i<256
       echo "Generating character "$i
       istr=${"dec2str "$i}
       hstr=${"dec2hex "$i}
       if $i<16
         hstr="0"$hstr
       fi
       rm
       i 1,1
       -o "__font_"$hstr".png"
       rm
       if $i==39
        cmd="magick -background transparent -fill blue -font test.ttf -pointsize 1000 \"label:"$istr"\" '__font_"$hstr".png'"
       else
        cmd="magick -background transparent -fill blue -font test.ttf -pointsize 1000 'label:"$istr"' '__font_"$hstr".png'"
       fi
       exec 0,$cmd
       i+=1
     done

Edited so all .png get created.

1 Like

Interesting thank you.
Note that the charset used in G’MIC font does not go from code 0 to code 255, but it uses some UTF-16 characters, which was one of my issue with ImageMagick.
I know it can render UTF-8 character, but I’ve not found out how to do it properly for UTF-16 codes.

Here is the list of the 256 UTF-16 codes (in decimal) that should be considered:

32,32,8853,8854,8855,8856,8857,8747,8711,32,32,8800,8730,32,9824,9827,9829,9830,8745,8746,8743,8744,8712,32,32,32,32,32,32,32,32,8364,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,32,8734,945,946,8706,948,949,951,947,955,956,969,966,960,968,961,963,964,952,916,931,915,937,934,928,936,920,8592,8593,8594,8595,8596,8597,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255

Every code <256 is indeed an (extended) ASCII code, other are UTF-16 characters.
for instance, code 8730 is 0x221A, which is the UTF-16 code for character


GIMP GEGL and Filtre GEGL Render Pango Markup

1 Like

As far as I know, ImageMagick uses UTF-8, not UTF-16.

Text encodings are like image formats: there are zillions to choose from, with or without headers that declare what encoding is used. ImageMagick was conceived as a tool to convert from any image format to any (raster) format. A similar tool for text encodings is “recode”, available for Unix, and Cygwin for Windows, and probably anywhere else.

For example, the file http://snibgo.com/imforums/sample16.txt is encoded as UTF16 big-endian (using Windows Notepad). We can convert it to UTF-8, and render that with IM.

recode UTF-16BE..utf8 <sample16.txt >s8.txt

magick -pointsize 30 caption:@s8.txt x.png

x

EDIT: In bash, we can use command substitution:

magick -pointsize 30 "caption:$(recode UTF-16BE..utf8 <sample16.txt)" x2.png
1 Like

Thanks for the detailed anwser @snibgo !

At this point, it makes me think that using ImageMagick + recode route won’t be particularly simpler than just using cutycapt, so personally, I’ll stick with this (working) solution.
I understand that this does not work well for Windows users.

What I propose is that people interested by a particular set of fonts post the font files, and I’ll generate the corresponding .gmz files.

I will try and get the ImageMagick version running as it will probably be easier for many people as they do not run X server… I think if we can generate

@David_Tschumperle, it correct that you take the fonts in the 32,32,8853,8854,8855,8856,8857,8747,8711,32,32,8800,8730,32,9824,9827,9829,9830,8745,8746,8743,8744,8712,32,32,32,32,32,32,32,32,8364,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,32,8734,945,946,8706,948,949,951,947,955,956,969,966,960,968,961,963,964,952,916,931,915,937,934,928,936,920,8592,8593,8594,8595,8596,8597,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 and each generated image is named <font name, such as arial>_c and then the whole resulting images are serialized and put into a single *.gmz file?

Can I pack more than one font into the .gmz file and if so, how do I use the resulting .gmz file with the font command?

Is there a dec2str function that actually converts a decimal above 255 into the corresponding string/character? Alterntively, having the array of 256 integers as individual, already converted characters would probably already do the trick, so it would be an array starting with " ", " "… “A” for 65, “B” for 66., … and “√” for 8730…

I might have it… " ", " ", "⊕", "⊖", "⊗", "⊘", "⊙", "∫", "∇", " ", " ", "≠", "√", " ", "♠", "♣", "♥", "♦", "∩", "∪", "∧", "∨", "∈", " ", " ", " ", " ", " ", " ", " ", " ", "€", " ", "!", """, "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", " ", "∞", "α", "β", "∂", "δ", "ε", "η", "γ", "λ", "μ", "ω", "φ", "π", "ψ", "ρ", "σ", "τ", "θ", "Δ", "Σ", "Γ", "Ω", "Φ", "Π", "Ψ", "Θ", "←", "↑", "→", "↓", "↔", "↕", " ", "¡", "¢", "£", "¤", "¥", "¦", "§", "¨", "©", "ª", "«", "¬", "­", "®", "¯", "°", "±", "²", "³", "´", "µ", "¶", "·", "¸", "¹", "º", "»", "¼", "½", "¾", "¿", "À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï", "Ð", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "×", "Ø", "Ù", "Ú", "Û", "Ü", "Ý", "Þ", "ß", "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "ì", "í", "î", "ï", "ð", "ñ", "ò", "ó", "ô", "õ", "ö", "÷", "ø", "ù", "ú", "û", "ü", "ý", "þ", "ÿ".

Some of the characters need escaping yet.

I was up too late yesterday and may find time tomorrow morning to use it with my code above, replacing the dec2str by talking one element of the array before. That should then actually more or less work.

1 Like

We can put those numbers into a text file I will call utf16chars.txt, and add a comma after the final number. Then we can read it with IM, so each number is a grayscale pixel value. Then we write that image to a headerless 16-bit binary format, g16.bin. There are 256 numbers (and 256 commas).

Windows syntax:

magick ^
  -define ftxt:format=\v, ^
  -depth 16 ^
  -size 256x1 ^
  -colorspace Gray ^
  ftxt:utf16chars.txt ^
  -endian MSB ^
  gray:g16.bin

(If we want them as separate files, insert “-crop 1x1 +repage” before “gray:g16.bin”.)

Read g16.bin as a UTF-16 file and write it as a UTF-8 file.

recode UTF-16BE..utf8 <g16.bin >g8.bin

With IM, rasterize the UTF-8 file.

magick -pointsize 30 caption:@g8.bin g8.png

1 Like

Hunger comes with eating!

What about slanted fonts to render them without gaps? Actually I have only an example of an old-fashion german script which does not look well under gmic. Here is the gmic fontfile, compressed for the list:
pf_WiegelKurrent.gmz.zip (173.7 KB)
as well as the original font file:
WiegelKurrent.otf.zip (17.6 KB)
I have added pf_ for private font to find the file easily.