Merge pull request #552 from Nimaoth/master

added support for open type format 12
This commit is contained in:
Andre von Houck 2024-04-28 11:54:11 -07:00 committed by GitHub
commit 3b65ca5605
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 56 additions and 2 deletions

View file

@ -1,4 +1,4 @@
version = "5.0.6" version = "5.0.7"
author = "Andre von Houck and Ryan Oldenburg" author = "Andre von Houck and Ryan Oldenburg"
description = "Full-featured 2d graphics library for Nim." description = "Full-featured 2d graphics library for Nim."
license = "MIT" license = "MIT"

View file

@ -455,6 +455,7 @@ proc parseCmapTable(buf: string, offset: int): CmapTable =
let format = buf.readUint16(i + 0).swap() let format = buf.readUint16(i + 0).swap()
if format == 4: if format == 4:
# https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values
type Format4 = object type Format4 = object
format: uint16 format: uint16
length: uint16 length: uint16
@ -518,8 +519,46 @@ proc parseCmapTable(buf: string, offset: int): CmapTable =
if c != 65535: if c != 65535:
result.runeToGlyphId[Rune(c)] = glyphId.uint16 result.runeToGlyphId[Rune(c)] = glyphId.uint16
result.glyphIdToRune[glyphId.uint16] = Rune(c) 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: else:
# TODO implement other Windows encodingIDs # TODO implement other windows formats
discard discard
else: else:
# TODO implement other cmap platformIDs # TODO implement other cmap platformIDs

BIN
tests/fonts/NotoEmoji.otf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View file

@ -4,6 +4,21 @@ proc wh(image: Image): Vec2 =
## Return with and height as a size vector. ## Return with and height as a size vector.
vec2(image.width.float32, image.height.float32) 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: block:
var font = readFont("tests/fonts/Roboto-Regular_1.ttf") var font = readFont("tests/fonts/Roboto-Regular_1.ttf")
font.size = 24 font.size = 24