Kerning

Discussions related to mouse, keyboard, fonts and Graphical User Interface
RichardRussell

Kerning

Post by RichardRussell »

BBC BASIC does not natively support kerning; whether you output text one character at a time or as a multi-character string makes no difference, the characters will be spaced according to their individual widths only. If you want to support kerning in your own program(s) you can use the FNkern function that I have listed below; what this does is to embed MOVE BY (PLOT 0 or VDU 25,0) commands into a string so that if it is printed in VDU 5 mode the character spacing will be adjusted.

For example, suppose you want to output the string "VA" with kerning; to achieve the correct character spacing the V and the A need to be moved closer together than they would normally be printed; let's assume by two pixels. What FNkern would do in that case is to convert the character sequence '&56 &41' into the sequence '&56 &19 &00 &FE &FF &00 &00 &41', which when interpreted by the VDU emulator is equivalent to:

Code: Select all

      PRINT "V";
      MOVE BY -2,0
      PRINT "A";
FNkern has been written to be compatible with both BBC BASIC for Windows and BBC BASIC for SDL 2.0. It's simpler in BBCSDL because the WIDTH() function takes kerning into account (but that can cause its own issues when aligning strings) whereas in BB4W the code is rather more messy. Here it is, along with some test code:

Code: Select all

      OSCLI "FONT """ + @lib$ + "DejaVuSans"", 48"
      VDU 5,30
      PRINT "TATATA"
      PRINT FNkern("TATATA")
      END

      DEF FNkern(a$)
      LOCAL I%, K%, k$
      IF LEN(a$) < 2 THEN = a$
      FOR I% = 1 TO LEN(a$) - 1
        k$ += MID$(a$,I%,1)
        K% = FNwidth(MID$(a$,I%,2)) - WIDTH(MID$(a$,I%,1)) - WIDTH(MID$(a$,I%+1,1))
        IF K% k$ += CHR$25 + CHR$0 + CHR$(K%) + CHR$(K% >> 8) + CHR$0 + CHR$0
      NEXT
      = k$ + RIGHT$(a$)

      DEF FNwidth(a$) IF INKEY(-256)<>&57 THEN = WIDTH(a$)
      LOCAL G%, W% : DIM G% LOCAL 35 : !G% = 36 : G%!28 = LENa$
      SYS "GetCharacterPlacement", @memhdc%, a$, LENa$, 0, G%, 8 TO W%
      = (W% AND &FFFF) * 2
kerning.png
You do not have the required permissions to view the files attached to this post.
RichardRussell

Re: Kerning

Post by RichardRussell »

The kerning.bbc demo is bundled with BBC BASIC for SDL 2.0 version 1.12a:

kerning.png
You do not have the required permissions to view the files attached to this post.