font/sfnt: support cmap format 6
The library provides support for CMap formats 2, 4 and 12, but
does not support CMap format 6.
CL adds support for CMap format 6 (trimmed table mapping).
Change-Id: I40657c4805c14017367af17596023da96b2c7483
Reviewed-on: https://go-review.googlesource.com/c/146079
Reviewed-by: Nigel Tao <nigeltao@golang.org>
Run-TryBot: Nigel Tao <nigeltao@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/font/sfnt/cmap.go b/font/sfnt/cmap.go
index 797e9d1..55b4ead 100644
--- a/font/sfnt/cmap.go
+++ b/font/sfnt/cmap.go
@@ -80,6 +80,8 @@
return pid == pidMacintosh && psid == psidMacintoshRoman
case 4:
return true
+ case 6:
+ return true
case 12:
return true
}
@@ -92,6 +94,8 @@
return f.makeCachedGlyphIndexFormat0(buf, offset, length)
case 4:
return f.makeCachedGlyphIndexFormat4(buf, offset, length)
+ case 6:
+ return f.makeCachedGlyphIndexFormat6(buf, offset, length)
case 12:
return f.makeCachedGlyphIndexFormat12(buf, offset, length)
}
@@ -193,6 +197,52 @@
}, nil
}
+func (f *Font) makeCachedGlyphIndexFormat6(buf []byte, offset, length uint32) ([]byte, glyphIndexFunc, error) {
+ const headerSize = 10
+ if offset+headerSize > f.cmap.length {
+ return nil, nil, errInvalidCmapTable
+ }
+ var err error
+ buf, err = f.src.view(buf, int(f.cmap.offset+offset), headerSize)
+ if err != nil {
+ return nil, nil, err
+ }
+ offset += headerSize
+
+ firstCode := u16(buf[6:])
+ entryCount := u16(buf[8:])
+
+ eLength := 2 * uint32(entryCount)
+ if offset+eLength > f.cmap.length {
+ return nil, nil, errInvalidCmapTable
+ }
+
+ if entryCount != 0 {
+ buf, err = f.src.view(buf, int(f.cmap.offset+offset), int(eLength))
+ if err != nil {
+ return nil, nil, err
+ }
+ offset += eLength
+ }
+
+ entries := make([]uint16, entryCount)
+ for i := range entries {
+ entries[i] = u16(buf[2*i:])
+ }
+
+ return buf, func(f *Font, b *Buffer, r rune) (GlyphIndex, error) {
+ if uint16(r) < firstCode {
+ return 0, nil
+ }
+
+ c := int(uint16(r) - firstCode)
+ if c >= len(entries) {
+ return 0, nil
+ }
+ return GlyphIndex(entries[c]), nil
+ }, nil
+}
+
func (f *Font) makeCachedGlyphIndexFormat12(buf []byte, offset, _ uint32) ([]byte, glyphIndexFunc, error) {
const headerSize = 16
if offset+headerSize > f.cmap.length {