Skip to content

Commit

Permalink
Merge pull request #552 from Nimaoth/master
Browse files Browse the repository at this point in the history
added support for open type format 12
  • Loading branch information
treeform authored Apr 28, 2024
2 parents 2ce0404 + f192718 commit 3b65ca5
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 2 deletions.
2 changes: 1 addition & 1 deletion pixie.nimble
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = "5.0.6"
version = "5.0.7"
author = "Andre von Houck and Ryan Oldenburg"
description = "Full-featured 2d graphics library for Nim."
license = "MIT"
Expand Down
41 changes: 40 additions & 1 deletion src/pixie/fontformats/opentype.nim
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ proc parseCmapTable(buf: string, offset: int): CmapTable =

let format = buf.readUint16(i + 0).swap()
if format == 4:
# https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values
type Format4 = object
format: uint16
length: uint16
Expand Down Expand Up @@ -518,8 +519,46 @@ proc parseCmapTable(buf: string, offset: int): CmapTable =
if c != 65535:
result.runeToGlyphId[Rune(c)] = glyphId.uint16
result.glyphIdToRune[glyphId.uint16] = Rune(c)

elif format == 12:
# https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#format-12-segmented-coverage
type Format12 = object
format: uint16
reserved: uint16
length: uint32
language: uint32
numGroups: uint32

buf.eofCheck(i + 16)

var subTable: Format12
subTable.format = format
subTable.reserved = buf.readUint16(i + 2).swap()
subTable.length = buf.readUint32(i + 4).swap()
subTable.language = buf.readUint32(i + 8).swap()
subTable.numGroups = buf.readUint32(i + 12).swap()
i += 16

buf.eofCheck(i + subTable.numGroups.int * 12)

for k in 0 ..< subTable.numGroups:
let startCharCode = buf.readUint32(i + 0).swap()
let endCharCode = buf.readUint32(i + 4).swap()
let startGlyphId = buf.readUint32(i + 8).swap()

for c in startCharCode .. endCharCode:
let glyphId = startGlyphId + (c - startCharCode)
if glyphId > uint16.high:
# TODO: currently only 16 bit glyph ids are supported
raise newException(PixieError, "Found glyph outside of uint16 range: " & $glyphId)

result.runeToGlyphId[Rune(c)] = uint16(glyphId)
result.glyphIdToRune[uint16(glyphId)] = Rune(c)

i += 12

else:
# TODO implement other Windows encodingIDs
# TODO implement other windows formats
discard
else:
# TODO implement other cmap platformIDs
Expand Down
Binary file added tests/fonts/NotoEmoji.otf
Binary file not shown.
Binary file added tests/fonts/masters/emoji.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions tests/test_fonts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ proc wh(image: Image): Vec2 =
## Return with and height as a size vector.
vec2(image.width.float32, image.height.float32)

block:
var font = readFont("tests/fonts/NotoEmoji.otf")
font.size = 26
let image = newImage(800, 300)
image.fill(rgba(255, 255, 255, 255))
image.fillText(font, """
๐Ÿš‘๐Ÿ‘๐Ÿ‘ญ๐Ÿ”‰๐Ÿšท๐Ÿฆฃ๐Ÿ’†๐Ÿ”๐Ÿ’บ๐Ÿšต๐Ÿ•ฆ๐Ÿ”ฆ๐Ÿ—“๐ŸฆŸ๐Ÿ˜ถ๐Ÿฆ„โŒ›๐Ÿ™๐Ÿ˜„๐Ÿ‡ฝ
๐Ÿ ๐Ÿ’“๐Ÿฆ—๐ŸŽญ๐Ÿ›๐Ÿ”ด๐Ÿซ•๐Ÿงถ๐Ÿ–๐Ÿฆ๐Ÿ‹๐ŸŒ—๐Ÿ›ฌ๐Ÿ•๐Ÿ’ก๐Ÿ‘‰๐ŸŽฏ๐Ÿ•”๐Ÿš๐Ÿšฒ
๐Ÿต๐ŸŽ๐Ÿ’ณ๐Ÿฅฌ๐ŸŸฆ๐Ÿช˜๐Ÿ“ ๐Ÿ“Š๐ŸŽง๐ŸŽฆ๐ŸŽ๐ŸŒŒ๐Ÿชฒ๐Ÿฆฉ๐Ÿคขโ˜Ž๐Ÿšบ๐Ÿšพ๐Ÿ‘บ๐Ÿšƒ
๐Ÿจ๐ŸŒ†๐Ÿฅ‰๐Ÿ’ญ๐Ÿ—ณ๐Ÿฆต๐ŸŸช๐Ÿ“†๐Ÿฅฎโฏ๐Ÿฉด๐Ÿ’ท๐Ÿฆฒโž—๐ŸŒถ๐Ÿงœ๐Ÿ––โฐ๐Ÿ›—๐Ÿ”ป
๐Ÿ“๐Ÿงž๐Ÿ˜ƒ๐ŸŒด๐Ÿšถ๓พ ซ๐Ÿฆ™๐Ÿ”Žโฒ๐Ÿ”ต๐Ÿ–โ˜ฆ๐Ÿ˜ช๐ŸŒฏ๐Ÿ™†๐Ÿ‡บ๐Ÿ˜‚๐Ÿ…๐Ÿ‡ฟ๐ŸšŸ๐Ÿคœ
๐Ÿ“ผ๐Ÿ‘ฐ๐Ÿ๐Ÿ“ฝโ˜ช๐Ÿ”„๐Ÿค๐Ÿ”ง๐Ÿฆธ๐Ÿฐ๐Ÿณ๐Ÿ”œ๐ŸŽฅ๐Ÿš‹๐Ÿ‡ซ๐Ÿฆจ๐Ÿœ๐Ÿ†–๐Ÿค๐Ÿช–โ""")

image.xray("tests/fonts/masters/emoji.png")

block:
var font = readFont("tests/fonts/Roboto-Regular_1.ttf")
font.size = 24
Expand Down

0 comments on commit 3b65ca5

Please sign in to comment.