unipdf/pdf/model/font_test.go
2018-07-10 08:57:16 +10:00

169 lines
4.0 KiB
Go

package model_test
import (
"errors"
"testing"
"github.com/unidoc/unidoc/common"
. "github.com/unidoc/unidoc/pdf/core"
"github.com/unidoc/unidoc/pdf/model"
"github.com/unidoc/unidoc/pdf/model/fonts"
)
func init() {
common.SetLogger(common.NewConsoleLogger(common.LogLevelDebug))
}
var simpleFontDicts = []string{
`<< /Type /Font
/BaseFont /Helvetica
/Subtype /Type1
/Encoding /WinAnsiEncoding
>>`,
`<< /Type /Font
/BaseFont /Helvetica-Oblique
/Subtype /Type1
/Encoding /WinAnsiEncoding
>>`,
`<< /Type /Font
/Subtype /Type1
/FirstChar 71
/LastChar 79
/Widths [ 778 722 278 500 667 556 833 722 778 ]
/Encoding /WinAnsiEncoding
/BaseFont /AOMFKK+Helvetica
>>`,
`<< /Type /Font
/Subtype /Type1
/FirstChar 71
/LastChar 79
/Widths [ 778 722 278 500 667 556 833 722 778 ]
/Encoding /WinAnsiEncoding
/BaseFont /PETER+Helvetica
/FontDescriptor <<
/Type /FontDescriptor
/Ascent 718
/CapHeight 718
/Descent -207
/Flags 32
/FontBBox [ -166 -225 1000 931 ]
/FontName /PETER+Helvetica
/ItalicAngle 0
/StemV 88
/XHeight 523
/StemH 88
/CharSet (/G/O)
%/FontFile3 19 0 R
>>
>>`,
}
var compositeFontDicts = []string{
`<< /Type /Font
/Subtype /Type0
/Encoding /Identity-H
/DescendantFonts [<<
/Type /Font
/Subtype /CIDFontType2
/BaseFont /FLDOLC+PingFangSC-Regular
/CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >>
/W [ ]
/DW 1000
/FontDescriptor <<
/Type /FontDescriptor
/FontName /FLDOLC+PingFangSC-Regular
/Flags 4
/FontBBox [-123 -263 1177 1003]
/ItalicAngle 0
/Ascent 972
/Descent -232
/CapHeight 864
/StemV 70
/XHeight 648
/StemH 64
/AvgWidth 1000
/MaxWidth 1300
% /FontFile3 182 0 R
>>
>>]
/BaseFont /FLDOLC+PingFangSC-Regular
>>`,
}
func TestNewStandard14Font(t *testing.T) {
type expect struct {
subtype string
basefont string
fonts.CharMetrics
}
tests := map[string]expect{
"Courier": expect{
subtype: "Type1",
basefont: "Courier",
CharMetrics: fonts.CharMetrics{Wx: 600, Wy: 0}},
}
for in, expect := range tests {
font, err := model.NewStandard14Font(in)
if err != nil {
t.Fatalf("%s: %v", in, err)
}
if font.Subtype() != expect.subtype || font.BaseFont() != expect.basefont {
t.Fatalf("%s: expected BaseFont=%s SubType=%s, but got BaseFont=%s SubType=%s",
in, expect.basefont, expect.subtype, font.BaseFont(), font.Subtype())
}
metrics, ok := font.GetGlyphCharMetrics("space")
if !ok {
t.Fatalf("%s: failed to get glyph metric", in)
}
if metrics.Wx != expect.Wx || metrics.Wy != expect.Wy {
t.Fatalf("%s: expected glyph metrics is Wx=%f Wy=%f, but got Wx=%f Wy=%f",
in, expect.Wx, expect.Wy, metrics.Wx, metrics.Wy)
}
}
}
// TestSimpleFonts checks that we correctly recreate simple fonts that we parse.
func TestSimpleFonts(t *testing.T) {
for _, d := range simpleFontDicts {
objFontObj(t, d)
}
}
// TestCompositeFonts checks that we correctly recreate composite fonts that we parse.
func TestCompositeFonts(t *testing.T) {
for _, d := range compositeFontDicts {
objFontObj(t, d)
}
}
// objFontObj parses `fontDict` to a make a Font, creates a PDF object from the Font and checks that
// the new PDF object is the same as the input object
func objFontObj(t *testing.T, fontDict string) error {
parser := NewParserFromString(fontDict)
obj, err := parser.ParseDict()
if err != nil {
t.Errorf("objFontObj: Failed to parse dict obj. fontDict=%q err=%v", fontDict, err)
return err
}
font, err := model.NewPdfFontFromPdfObject(obj)
if err != nil {
t.Errorf("Failed to parse font object. obj=%s err=%v", obj, err)
return err
}
// Resolve all the indirect references in the font objects so we can compare their contents.
obj1 := FlattenObject(obj)
obj2 := FlattenObject(font.ToPdfObject())
// Check that the reconstituted font is the same as the original.
if !EqualObjects(obj1, obj2) {
t.Errorf("Different objects.\nobj1=%s\nobj2=%s\nfont=%s", obj1, obj2, font)
return errors.New("different objects")
}
return nil
}