@@ -455,6 +455,7 @@ proc parseCmapTable(buf: string, offset: int): CmapTable =
455455
456456 let format = buf.readUint16 (i + 0 ).swap ()
457457 if format == 4 :
458+ # https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values
458459 type Format4 = object
459460 format: uint16
460461 length: uint16
@@ -518,8 +519,46 @@ proc parseCmapTable(buf: string, offset: int): CmapTable =
518519 if c != 65535 :
519520 result .runeToGlyphId[Rune (c)] = glyphId.uint16
520521 result .glyphIdToRune[glyphId.uint16 ] = Rune (c)
522+
523+ elif format == 12 :
524+ # https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#format-12-segmented-coverage
525+ type Format12 = object
526+ format: uint16
527+ reserved: uint16
528+ length: uint32
529+ language: uint32
530+ numGroups: uint32
531+
532+ buf.eofCheck (i + 16 )
533+
534+ var subTable: Format12
535+ subTable.format = format
536+ subTable.reserved = buf.readUint16 (i + 2 ).swap ()
537+ subTable.length = buf.readUint32 (i + 4 ).swap ()
538+ subTable.language = buf.readUint32 (i + 8 ).swap ()
539+ subTable.numGroups = buf.readUint32 (i + 12 ).swap ()
540+ i += 16
541+
542+ buf.eofCheck (i + subTable.numGroups.int * 12 )
543+
544+ for k in 0 ..< subTable.numGroups:
545+ let startCharCode = buf.readUint32 (i + 0 ).swap ()
546+ let endCharCode = buf.readUint32 (i + 4 ).swap ()
547+ let startGlyphId = buf.readUint32 (i + 8 ).swap ()
548+
549+ for c in startCharCode .. endCharCode:
550+ let glyphId = startGlyphId + (c - startCharCode)
551+ if glyphId > uint16 .high:
552+ # TODO : currently only 16 bit glyph ids are supported
553+ raise newException (PixieError , " Found glyph outside of uint16 range: " & $ glyphId)
554+
555+ result .runeToGlyphId[Rune (c)] = uint16 (glyphId)
556+ result .glyphIdToRune[uint16 (glyphId)] = Rune (c)
557+
558+ i += 12
559+
521560 else :
522- # TODO implement other Windows encodingIDs
561+ # TODO implement other windows formats
523562 discard
524563 else :
525564 # TODO implement other cmap platformIDs
0 commit comments