fix wrong git ignore

This commit is contained in:
Adrian Zürcher
2025-12-15 17:44:00 +01:00
parent ed9f31bb96
commit 8f313c00f0
126 changed files with 70589 additions and 1 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
package model
import (
"errors"
)
var (
ErrRequiredAttributeMissing = errors.New("required attribute missing")
ErrInvalidAttribute = errors.New("invalid attribute")
ErrTypeError = errors.New("type check error")
// ErrRangeError typically occurs when an input parameter is out of range or has invalid value.
ErrRangeError = errors.New("range check error")
)

393
internal/pdf/model/font.go Normal file
View File

@@ -0,0 +1,393 @@
package model
import (
"errors"
"os"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/fonts"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// The PdfFont structure represents an underlying font structure which can be of type:
// - Type0
// - Type1
// - TrueType
// etc.
type PdfFont struct {
context any // The underlying font: Type0, Type1, Truetype, etc..
}
// Set the encoding for the underlying font.
func (font PdfFont) SetEncoder(encoder textencoding.TextEncoder) {
switch t := font.context.(type) {
case *pdfFontTrueType:
t.SetEncoder(encoder)
}
}
func (font PdfFont) GetGlyphCharMetrics(glyph string) (fonts.CharMetrics, bool) {
switch t := font.context.(type) {
case *pdfFontTrueType:
return t.GetGlyphCharMetrics(glyph)
}
return fonts.CharMetrics{}, false
}
func (font PdfFont) ToPdfObject() core.PdfObject {
switch f := font.context.(type) {
case *pdfFontTrueType:
return f.ToPdfObject()
}
// If not supported, return null..
common.Log.Debug("Unsupported font (%T) - returning null object", font.context)
return core.MakeNull()
}
type pdfFontTrueType struct {
Encoder textencoding.TextEncoder
firstChar int
lastChar int
charWidths []float64
// Subtype shall be TrueType.
// Encoding is subject to limitations that are described in 9.6.6, "Character Encoding".
// BaseFont is derived differently.
BaseFont core.PdfObject
FirstChar core.PdfObject
LastChar core.PdfObject
Widths core.PdfObject
FontDescriptor *PdfFontDescriptor
Encoding core.PdfObject
ToUnicode core.PdfObject
container *core.PdfIndirectObject
}
func (font pdfFontTrueType) SetEncoder(encoder textencoding.TextEncoder) {
font.Encoder = encoder
}
func (font pdfFontTrueType) GetGlyphCharMetrics(glyph string) (fonts.CharMetrics, bool) {
metrics := fonts.CharMetrics{}
code, found := font.Encoder.GlyphToCharcode(glyph)
if !found {
return metrics, false
}
if int(code) < font.firstChar {
common.Log.Debug("Code lower than firstchar (%d < %d)", code, font.firstChar)
return metrics, false
}
if int(code) > font.lastChar {
common.Log.Debug("Code higher than lastchar (%d < %d)", code, font.lastChar)
return metrics, false
}
index := int(code) - font.firstChar
if index >= len(font.charWidths) {
common.Log.Debug("Code outside of widths range")
return metrics, false
}
width := font.charWidths[index]
metrics.Wx = width
return metrics, true
}
func (ftt *pdfFontTrueType) ToPdfObject() core.PdfObject {
if ftt.container == nil {
ftt.container = &core.PdfIndirectObject{}
}
d := core.MakeDict()
ftt.container.PdfObject = d
d.Set("Type", core.MakeName("Font"))
d.Set("Subtype", core.MakeName("TrueType"))
if ftt.BaseFont != nil {
d.Set("BaseFont", ftt.BaseFont)
}
if ftt.FirstChar != nil {
d.Set("FirstChar", ftt.FirstChar)
}
if ftt.LastChar != nil {
d.Set("LastChar", ftt.LastChar)
}
if ftt.Widths != nil {
d.Set("Widths", ftt.Widths)
}
if ftt.FontDescriptor != nil {
d.Set("FontDescriptor", ftt.FontDescriptor.ToPdfObject())
}
if ftt.Encoding != nil {
d.Set("Encoding", ftt.Encoding)
}
if ftt.ToUnicode != nil {
d.Set("ToUnicode", ftt.ToUnicode)
}
return ftt.container
}
func NewPdfFontFromTTFFile(filePath string) (*PdfFont, error) {
ttf, err := fonts.TtfParse(filePath)
if err != nil {
common.Log.Debug("error loading ttf font: %v", err)
return nil, err
}
truefont := &pdfFontTrueType{}
truefont.Encoder = textencoding.NewWinAnsiTextEncoder()
truefont.firstChar = 32
truefont.lastChar = 255
truefont.BaseFont = core.MakeName(ttf.PostScriptName)
truefont.FirstChar = core.MakeInteger(32)
truefont.LastChar = core.MakeInteger(255)
k := 1000.0 / float64(ttf.UnitsPerEm)
if len(ttf.Widths) <= 0 {
return nil, errors.New("missing required attribute (Widths)")
}
missingWidth := k * float64(ttf.Widths[0])
vals := []float64{}
for charcode := 32; charcode <= 255; charcode++ {
runeVal, found := truefont.Encoder.CharcodeToRune(byte(charcode))
if !found {
common.Log.Debug("Rune not found (charcode: %d)", charcode)
vals = append(vals, missingWidth)
continue
}
pos, ok := ttf.Chars[uint16(runeVal)]
if !ok {
common.Log.Debug("Rune not in TTF Chars")
vals = append(vals, missingWidth)
continue
}
w := k * float64(ttf.Widths[pos])
vals = append(vals, w)
}
truefont.Widths = &core.PdfIndirectObject{PdfObject: core.MakeArrayFromFloats(vals)}
if len(vals) < (255 - 32 + 1) {
common.Log.Debug("invalid length of widths, %d < %d", len(vals), 255-32+1)
return nil, errors.New("range check error")
}
truefont.charWidths = vals[:255-32+1]
// Default.
// XXX/FIXME TODO: Only use the encoder object.
truefont.Encoding = core.MakeName("WinAnsiEncoding")
descriptor := &PdfFontDescriptor{}
descriptor.Ascent = core.MakeFloat(k * float64(ttf.TypoAscender))
descriptor.Descent = core.MakeFloat(k * float64(ttf.TypoDescender))
descriptor.CapHeight = core.MakeFloat(k * float64(ttf.CapHeight))
descriptor.FontBBox = core.MakeArrayFromFloats([]float64{k * float64(ttf.Xmin), k * float64(ttf.Ymin), k * float64(ttf.Xmax), k * float64(ttf.Ymax)})
descriptor.ItalicAngle = core.MakeFloat(float64(ttf.ItalicAngle))
descriptor.MissingWidth = core.MakeFloat(k * float64(ttf.Widths[0]))
ttfBytes, err := os.ReadFile(filePath)
if err != nil {
common.Log.Debug("Unable to read file contents: %v", err)
return nil, err
}
// XXX/TODO: Encode the file...
stream, err := core.MakeStream(ttfBytes, core.NewFlateEncoder())
if err != nil {
common.Log.Debug("Unable to make stream: %v", err)
return nil, err
}
stream.PdfObjectDictionary.Set("Length1", core.MakeInteger(int64(len(ttfBytes))))
descriptor.FontFile2 = stream
if ttf.Bold {
descriptor.StemV = core.MakeInteger(120)
} else {
descriptor.StemV = core.MakeInteger(70)
}
// Flags.
flags := 1 << 5
if ttf.IsFixedPitch {
flags |= 1
}
if ttf.ItalicAngle != 0 {
flags |= 1 << 6
}
descriptor.Flags = core.MakeInteger(int64(flags))
// Build Font.
truefont.FontDescriptor = descriptor
font := &PdfFont{}
font.context = truefont
return font, nil
}
// Font descriptors specifies metrics and other attributes of a font.
type PdfFontDescriptor struct {
FontName core.PdfObject
FontFamily core.PdfObject
FontStretch core.PdfObject
FontWeight core.PdfObject
Flags core.PdfObject
FontBBox core.PdfObject
ItalicAngle core.PdfObject
Ascent core.PdfObject
Descent core.PdfObject
Leading core.PdfObject
CapHeight core.PdfObject
XHeight core.PdfObject
StemV core.PdfObject
StemH core.PdfObject
AvgWidth core.PdfObject
MaxWidth core.PdfObject
MissingWidth core.PdfObject
FontFile core.PdfObject
FontFile2 core.PdfObject
FontFile3 core.PdfObject
CharSet core.PdfObject
// Additional entries for CIDFonts
Style core.PdfObject
Lang core.PdfObject
FD core.PdfObject
CIDSet core.PdfObject
// Container.
container *core.PdfIndirectObject
}
// Convert to a PDF dictionary inside an indirect object.
func (pfd *PdfFontDescriptor) ToPdfObject() core.PdfObject {
d := core.MakeDict()
if pfd.container == nil {
pfd.container = &core.PdfIndirectObject{}
}
pfd.container.PdfObject = d
d.Set("Type", core.MakeName("FontDescriptor"))
if pfd.FontName != nil {
d.Set("FontName", pfd.FontName)
}
if pfd.FontFamily != nil {
d.Set("FontFamily", pfd.FontFamily)
}
if pfd.FontStretch != nil {
d.Set("FontStretch", pfd.FontStretch)
}
if pfd.FontWeight != nil {
d.Set("FontWeight", pfd.FontWeight)
}
if pfd.Flags != nil {
d.Set("Flags", pfd.Flags)
}
if pfd.FontBBox != nil {
d.Set("FontBBox", pfd.FontBBox)
}
if pfd.ItalicAngle != nil {
d.Set("ItalicAngle", pfd.ItalicAngle)
}
if pfd.Ascent != nil {
d.Set("Ascent", pfd.Ascent)
}
if pfd.Descent != nil {
d.Set("Descent", pfd.Descent)
}
if pfd.Leading != nil {
d.Set("Leading", pfd.Leading)
}
if pfd.CapHeight != nil {
d.Set("CapHeight", pfd.CapHeight)
}
if pfd.XHeight != nil {
d.Set("XHeight", pfd.XHeight)
}
if pfd.StemV != nil {
d.Set("StemV", pfd.StemV)
}
if pfd.StemH != nil {
d.Set("StemH", pfd.StemH)
}
if pfd.AvgWidth != nil {
d.Set("AvgWidth", pfd.AvgWidth)
}
if pfd.MaxWidth != nil {
d.Set("MaxWidth", pfd.MaxWidth)
}
if pfd.MissingWidth != nil {
d.Set("MissingWidth", pfd.MissingWidth)
}
if pfd.FontFile != nil {
d.Set("FontFile", pfd.FontFile)
}
if pfd.FontFile2 != nil {
d.Set("FontFile2", pfd.FontFile2)
}
if pfd.FontFile3 != nil {
d.Set("FontFile3", pfd.FontFile3)
}
if pfd.CharSet != nil {
d.Set("CharSet", pfd.CharSet)
}
if pfd.Style != nil {
d.Set("FontName", pfd.FontName)
}
if pfd.Lang != nil {
d.Set("Lang", pfd.Lang)
}
if pfd.FD != nil {
d.Set("FD", pfd.FD)
}
if pfd.CIDSet != nil {
d.Set("CIDSet", pfd.CIDSet)
}
return pfd.container
}

View File

@@ -0,0 +1,342 @@
StartFontMetrics 4.1
Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
Comment Creation Date: Mon Jun 23 16:28:00 1997
Comment UniqueID 43048
Comment VMusage 41139 52164
FontName Courier-Bold
FullName Courier Bold
FamilyName Courier
Weight Bold
ItalicAngle 0
IsFixedPitch true
CharacterSet ExtendedRoman
FontBBox -113 -250 749 801
UnderlinePosition -100
UnderlineThickness 50
Version 003.000
Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
EncodingScheme AdobeStandardEncoding
CapHeight 562
XHeight 439
Ascender 629
Descender -157
StdHW 84
StdVW 106
StartCharMetrics 315
C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
C 33 ; WX 600 ; N exclam ; B 202 -15 398 572 ;
C 34 ; WX 600 ; N quotedbl ; B 135 277 465 562 ;
C 35 ; WX 600 ; N numbersign ; B 56 -45 544 651 ;
C 36 ; WX 600 ; N dollar ; B 82 -126 519 666 ;
C 37 ; WX 600 ; N percent ; B 5 -15 595 616 ;
C 38 ; WX 600 ; N ampersand ; B 36 -15 546 543 ;
C 39 ; WX 600 ; N quoteright ; B 171 277 423 562 ;
C 40 ; WX 600 ; N parenleft ; B 219 -102 461 616 ;
C 41 ; WX 600 ; N parenright ; B 139 -102 381 616 ;
C 42 ; WX 600 ; N asterisk ; B 91 219 509 601 ;
C 43 ; WX 600 ; N plus ; B 71 39 529 478 ;
C 44 ; WX 600 ; N comma ; B 123 -111 393 174 ;
C 45 ; WX 600 ; N hyphen ; B 100 203 500 313 ;
C 46 ; WX 600 ; N period ; B 192 -15 408 171 ;
C 47 ; WX 600 ; N slash ; B 98 -77 502 626 ;
C 48 ; WX 600 ; N zero ; B 87 -15 513 616 ;
C 49 ; WX 600 ; N one ; B 81 0 539 616 ;
C 50 ; WX 600 ; N two ; B 61 0 499 616 ;
C 51 ; WX 600 ; N three ; B 63 -15 501 616 ;
C 52 ; WX 600 ; N four ; B 53 0 507 616 ;
C 53 ; WX 600 ; N five ; B 70 -15 521 601 ;
C 54 ; WX 600 ; N six ; B 90 -15 521 616 ;
C 55 ; WX 600 ; N seven ; B 55 0 494 601 ;
C 56 ; WX 600 ; N eight ; B 83 -15 517 616 ;
C 57 ; WX 600 ; N nine ; B 79 -15 510 616 ;
C 58 ; WX 600 ; N colon ; B 191 -15 407 425 ;
C 59 ; WX 600 ; N semicolon ; B 123 -111 408 425 ;
C 60 ; WX 600 ; N less ; B 66 15 523 501 ;
C 61 ; WX 600 ; N equal ; B 71 118 529 398 ;
C 62 ; WX 600 ; N greater ; B 77 15 534 501 ;
C 63 ; WX 600 ; N question ; B 98 -14 501 580 ;
C 64 ; WX 600 ; N at ; B 16 -15 584 616 ;
C 65 ; WX 600 ; N A ; B -9 0 609 562 ;
C 66 ; WX 600 ; N B ; B 30 0 573 562 ;
C 67 ; WX 600 ; N C ; B 22 -18 560 580 ;
C 68 ; WX 600 ; N D ; B 30 0 594 562 ;
C 69 ; WX 600 ; N E ; B 25 0 560 562 ;
C 70 ; WX 600 ; N F ; B 39 0 570 562 ;
C 71 ; WX 600 ; N G ; B 22 -18 594 580 ;
C 72 ; WX 600 ; N H ; B 20 0 580 562 ;
C 73 ; WX 600 ; N I ; B 77 0 523 562 ;
C 74 ; WX 600 ; N J ; B 37 -18 601 562 ;
C 75 ; WX 600 ; N K ; B 21 0 599 562 ;
C 76 ; WX 600 ; N L ; B 39 0 578 562 ;
C 77 ; WX 600 ; N M ; B -2 0 602 562 ;
C 78 ; WX 600 ; N N ; B 8 -12 610 562 ;
C 79 ; WX 600 ; N O ; B 22 -18 578 580 ;
C 80 ; WX 600 ; N P ; B 48 0 559 562 ;
C 81 ; WX 600 ; N Q ; B 32 -138 578 580 ;
C 82 ; WX 600 ; N R ; B 24 0 599 562 ;
C 83 ; WX 600 ; N S ; B 47 -22 553 582 ;
C 84 ; WX 600 ; N T ; B 21 0 579 562 ;
C 85 ; WX 600 ; N U ; B 4 -18 596 562 ;
C 86 ; WX 600 ; N V ; B -13 0 613 562 ;
C 87 ; WX 600 ; N W ; B -18 0 618 562 ;
C 88 ; WX 600 ; N X ; B 12 0 588 562 ;
C 89 ; WX 600 ; N Y ; B 12 0 589 562 ;
C 90 ; WX 600 ; N Z ; B 62 0 539 562 ;
C 91 ; WX 600 ; N bracketleft ; B 245 -102 475 616 ;
C 92 ; WX 600 ; N backslash ; B 99 -77 503 626 ;
C 93 ; WX 600 ; N bracketright ; B 125 -102 355 616 ;
C 94 ; WX 600 ; N asciicircum ; B 108 250 492 616 ;
C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ;
C 96 ; WX 600 ; N quoteleft ; B 178 277 428 562 ;
C 97 ; WX 600 ; N a ; B 35 -15 570 454 ;
C 98 ; WX 600 ; N b ; B 0 -15 584 626 ;
C 99 ; WX 600 ; N c ; B 40 -15 545 459 ;
C 100 ; WX 600 ; N d ; B 20 -15 591 626 ;
C 101 ; WX 600 ; N e ; B 40 -15 563 454 ;
C 102 ; WX 600 ; N f ; B 83 0 547 626 ; L i fi ; L l fl ;
C 103 ; WX 600 ; N g ; B 30 -146 580 454 ;
C 104 ; WX 600 ; N h ; B 5 0 592 626 ;
C 105 ; WX 600 ; N i ; B 77 0 523 658 ;
C 106 ; WX 600 ; N j ; B 63 -146 440 658 ;
C 107 ; WX 600 ; N k ; B 20 0 585 626 ;
C 108 ; WX 600 ; N l ; B 77 0 523 626 ;
C 109 ; WX 600 ; N m ; B -22 0 626 454 ;
C 110 ; WX 600 ; N n ; B 18 0 592 454 ;
C 111 ; WX 600 ; N o ; B 30 -15 570 454 ;
C 112 ; WX 600 ; N p ; B -1 -142 570 454 ;
C 113 ; WX 600 ; N q ; B 20 -142 591 454 ;
C 114 ; WX 600 ; N r ; B 47 0 580 454 ;
C 115 ; WX 600 ; N s ; B 68 -17 535 459 ;
C 116 ; WX 600 ; N t ; B 47 -15 532 562 ;
C 117 ; WX 600 ; N u ; B -1 -15 569 439 ;
C 118 ; WX 600 ; N v ; B -1 0 601 439 ;
C 119 ; WX 600 ; N w ; B -18 0 618 439 ;
C 120 ; WX 600 ; N x ; B 6 0 594 439 ;
C 121 ; WX 600 ; N y ; B -4 -142 601 439 ;
C 122 ; WX 600 ; N z ; B 81 0 520 439 ;
C 123 ; WX 600 ; N braceleft ; B 160 -102 464 616 ;
C 124 ; WX 600 ; N bar ; B 255 -250 345 750 ;
C 125 ; WX 600 ; N braceright ; B 136 -102 440 616 ;
C 126 ; WX 600 ; N asciitilde ; B 71 153 530 356 ;
C 161 ; WX 600 ; N exclamdown ; B 202 -146 398 449 ;
C 162 ; WX 600 ; N cent ; B 66 -49 518 614 ;
C 163 ; WX 600 ; N sterling ; B 72 -28 558 611 ;
C 164 ; WX 600 ; N fraction ; B 25 -60 576 661 ;
C 165 ; WX 600 ; N yen ; B 10 0 590 562 ;
C 166 ; WX 600 ; N florin ; B -30 -131 572 616 ;
C 167 ; WX 600 ; N section ; B 83 -70 517 580 ;
C 168 ; WX 600 ; N currency ; B 54 49 546 517 ;
C 169 ; WX 600 ; N quotesingle ; B 227 277 373 562 ;
C 170 ; WX 600 ; N quotedblleft ; B 71 277 535 562 ;
C 171 ; WX 600 ; N guillemotleft ; B 8 70 553 446 ;
C 172 ; WX 600 ; N guilsinglleft ; B 141 70 459 446 ;
C 173 ; WX 600 ; N guilsinglright ; B 141 70 459 446 ;
C 174 ; WX 600 ; N fi ; B 12 0 593 626 ;
C 175 ; WX 600 ; N fl ; B 12 0 593 626 ;
C 177 ; WX 600 ; N endash ; B 65 203 535 313 ;
C 178 ; WX 600 ; N dagger ; B 106 -70 494 580 ;
C 179 ; WX 600 ; N daggerdbl ; B 106 -70 494 580 ;
C 180 ; WX 600 ; N periodcentered ; B 196 165 404 351 ;
C 182 ; WX 600 ; N paragraph ; B 6 -70 576 580 ;
C 183 ; WX 600 ; N bullet ; B 140 132 460 430 ;
C 184 ; WX 600 ; N quotesinglbase ; B 175 -142 427 143 ;
C 185 ; WX 600 ; N quotedblbase ; B 65 -142 529 143 ;
C 186 ; WX 600 ; N quotedblright ; B 61 277 525 562 ;
C 187 ; WX 600 ; N guillemotright ; B 47 70 592 446 ;
C 188 ; WX 600 ; N ellipsis ; B 26 -15 574 116 ;
C 189 ; WX 600 ; N perthousand ; B -113 -15 713 616 ;
C 191 ; WX 600 ; N questiondown ; B 99 -146 502 449 ;
C 193 ; WX 600 ; N grave ; B 132 508 395 661 ;
C 194 ; WX 600 ; N acute ; B 205 508 468 661 ;
C 195 ; WX 600 ; N circumflex ; B 103 483 497 657 ;
C 196 ; WX 600 ; N tilde ; B 89 493 512 636 ;
C 197 ; WX 600 ; N macron ; B 88 505 512 585 ;
C 198 ; WX 600 ; N breve ; B 83 468 517 631 ;
C 199 ; WX 600 ; N dotaccent ; B 230 498 370 638 ;
C 200 ; WX 600 ; N dieresis ; B 128 498 472 638 ;
C 202 ; WX 600 ; N ring ; B 198 481 402 678 ;
C 203 ; WX 600 ; N cedilla ; B 205 -206 387 0 ;
C 205 ; WX 600 ; N hungarumlaut ; B 68 488 588 661 ;
C 206 ; WX 600 ; N ogonek ; B 169 -199 400 0 ;
C 207 ; WX 600 ; N caron ; B 103 493 497 667 ;
C 208 ; WX 600 ; N emdash ; B -10 203 610 313 ;
C 225 ; WX 600 ; N AE ; B -29 0 602 562 ;
C 227 ; WX 600 ; N ordfeminine ; B 147 196 453 580 ;
C 232 ; WX 600 ; N Lslash ; B 39 0 578 562 ;
C 233 ; WX 600 ; N Oslash ; B 22 -22 578 584 ;
C 234 ; WX 600 ; N OE ; B -25 0 595 562 ;
C 235 ; WX 600 ; N ordmasculine ; B 147 196 453 580 ;
C 241 ; WX 600 ; N ae ; B -4 -15 601 454 ;
C 245 ; WX 600 ; N dotlessi ; B 77 0 523 439 ;
C 248 ; WX 600 ; N lslash ; B 77 0 523 626 ;
C 249 ; WX 600 ; N oslash ; B 30 -24 570 463 ;
C 250 ; WX 600 ; N oe ; B -18 -15 611 454 ;
C 251 ; WX 600 ; N germandbls ; B 22 -15 596 626 ;
C -1 ; WX 600 ; N Idieresis ; B 77 0 523 761 ;
C -1 ; WX 600 ; N eacute ; B 40 -15 563 661 ;
C -1 ; WX 600 ; N abreve ; B 35 -15 570 661 ;
C -1 ; WX 600 ; N uhungarumlaut ; B -1 -15 628 661 ;
C -1 ; WX 600 ; N ecaron ; B 40 -15 563 667 ;
C -1 ; WX 600 ; N Ydieresis ; B 12 0 589 761 ;
C -1 ; WX 600 ; N divide ; B 71 16 529 500 ;
C -1 ; WX 600 ; N Yacute ; B 12 0 589 784 ;
C -1 ; WX 600 ; N Acircumflex ; B -9 0 609 780 ;
C -1 ; WX 600 ; N aacute ; B 35 -15 570 661 ;
C -1 ; WX 600 ; N Ucircumflex ; B 4 -18 596 780 ;
C -1 ; WX 600 ; N yacute ; B -4 -142 601 661 ;
C -1 ; WX 600 ; N scommaaccent ; B 68 -250 535 459 ;
C -1 ; WX 600 ; N ecircumflex ; B 40 -15 563 657 ;
C -1 ; WX 600 ; N Uring ; B 4 -18 596 801 ;
C -1 ; WX 600 ; N Udieresis ; B 4 -18 596 761 ;
C -1 ; WX 600 ; N aogonek ; B 35 -199 586 454 ;
C -1 ; WX 600 ; N Uacute ; B 4 -18 596 784 ;
C -1 ; WX 600 ; N uogonek ; B -1 -199 585 439 ;
C -1 ; WX 600 ; N Edieresis ; B 25 0 560 761 ;
C -1 ; WX 600 ; N Dcroat ; B 30 0 594 562 ;
C -1 ; WX 600 ; N commaaccent ; B 205 -250 397 -57 ;
C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ;
C -1 ; WX 600 ; N Emacron ; B 25 0 560 708 ;
C -1 ; WX 600 ; N ccaron ; B 40 -15 545 667 ;
C -1 ; WX 600 ; N aring ; B 35 -15 570 678 ;
C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 610 562 ;
C -1 ; WX 600 ; N lacute ; B 77 0 523 801 ;
C -1 ; WX 600 ; N agrave ; B 35 -15 570 661 ;
C -1 ; WX 600 ; N Tcommaaccent ; B 21 -250 579 562 ;
C -1 ; WX 600 ; N Cacute ; B 22 -18 560 784 ;
C -1 ; WX 600 ; N atilde ; B 35 -15 570 636 ;
C -1 ; WX 600 ; N Edotaccent ; B 25 0 560 761 ;
C -1 ; WX 600 ; N scaron ; B 68 -17 535 667 ;
C -1 ; WX 600 ; N scedilla ; B 68 -206 535 459 ;
C -1 ; WX 600 ; N iacute ; B 77 0 523 661 ;
C -1 ; WX 600 ; N lozenge ; B 66 0 534 740 ;
C -1 ; WX 600 ; N Rcaron ; B 24 0 599 790 ;
C -1 ; WX 600 ; N Gcommaaccent ; B 22 -250 594 580 ;
C -1 ; WX 600 ; N ucircumflex ; B -1 -15 569 657 ;
C -1 ; WX 600 ; N acircumflex ; B 35 -15 570 657 ;
C -1 ; WX 600 ; N Amacron ; B -9 0 609 708 ;
C -1 ; WX 600 ; N rcaron ; B 47 0 580 667 ;
C -1 ; WX 600 ; N ccedilla ; B 40 -206 545 459 ;
C -1 ; WX 600 ; N Zdotaccent ; B 62 0 539 761 ;
C -1 ; WX 600 ; N Thorn ; B 48 0 557 562 ;
C -1 ; WX 600 ; N Omacron ; B 22 -18 578 708 ;
C -1 ; WX 600 ; N Racute ; B 24 0 599 784 ;
C -1 ; WX 600 ; N Sacute ; B 47 -22 553 784 ;
C -1 ; WX 600 ; N dcaron ; B 20 -15 727 626 ;
C -1 ; WX 600 ; N Umacron ; B 4 -18 596 708 ;
C -1 ; WX 600 ; N uring ; B -1 -15 569 678 ;
C -1 ; WX 600 ; N threesuperior ; B 138 222 433 616 ;
C -1 ; WX 600 ; N Ograve ; B 22 -18 578 784 ;
C -1 ; WX 600 ; N Agrave ; B -9 0 609 784 ;
C -1 ; WX 600 ; N Abreve ; B -9 0 609 784 ;
C -1 ; WX 600 ; N multiply ; B 81 39 520 478 ;
C -1 ; WX 600 ; N uacute ; B -1 -15 569 661 ;
C -1 ; WX 600 ; N Tcaron ; B 21 0 579 790 ;
C -1 ; WX 600 ; N partialdiff ; B 63 -38 537 728 ;
C -1 ; WX 600 ; N ydieresis ; B -4 -142 601 638 ;
C -1 ; WX 600 ; N Nacute ; B 8 -12 610 784 ;
C -1 ; WX 600 ; N icircumflex ; B 73 0 523 657 ;
C -1 ; WX 600 ; N Ecircumflex ; B 25 0 560 780 ;
C -1 ; WX 600 ; N adieresis ; B 35 -15 570 638 ;
C -1 ; WX 600 ; N edieresis ; B 40 -15 563 638 ;
C -1 ; WX 600 ; N cacute ; B 40 -15 545 661 ;
C -1 ; WX 600 ; N nacute ; B 18 0 592 661 ;
C -1 ; WX 600 ; N umacron ; B -1 -15 569 585 ;
C -1 ; WX 600 ; N Ncaron ; B 8 -12 610 790 ;
C -1 ; WX 600 ; N Iacute ; B 77 0 523 784 ;
C -1 ; WX 600 ; N plusminus ; B 71 24 529 515 ;
C -1 ; WX 600 ; N brokenbar ; B 255 -175 345 675 ;
C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ;
C -1 ; WX 600 ; N Gbreve ; B 22 -18 594 784 ;
C -1 ; WX 600 ; N Idotaccent ; B 77 0 523 761 ;
C -1 ; WX 600 ; N summation ; B 15 -10 586 706 ;
C -1 ; WX 600 ; N Egrave ; B 25 0 560 784 ;
C -1 ; WX 600 ; N racute ; B 47 0 580 661 ;
C -1 ; WX 600 ; N omacron ; B 30 -15 570 585 ;
C -1 ; WX 600 ; N Zacute ; B 62 0 539 784 ;
C -1 ; WX 600 ; N Zcaron ; B 62 0 539 790 ;
C -1 ; WX 600 ; N greaterequal ; B 26 0 523 696 ;
C -1 ; WX 600 ; N Eth ; B 30 0 594 562 ;
C -1 ; WX 600 ; N Ccedilla ; B 22 -206 560 580 ;
C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 523 626 ;
C -1 ; WX 600 ; N tcaron ; B 47 -15 532 703 ;
C -1 ; WX 600 ; N eogonek ; B 40 -199 563 454 ;
C -1 ; WX 600 ; N Uogonek ; B 4 -199 596 562 ;
C -1 ; WX 600 ; N Aacute ; B -9 0 609 784 ;
C -1 ; WX 600 ; N Adieresis ; B -9 0 609 761 ;
C -1 ; WX 600 ; N egrave ; B 40 -15 563 661 ;
C -1 ; WX 600 ; N zacute ; B 81 0 520 661 ;
C -1 ; WX 600 ; N iogonek ; B 77 -199 523 658 ;
C -1 ; WX 600 ; N Oacute ; B 22 -18 578 784 ;
C -1 ; WX 600 ; N oacute ; B 30 -15 570 661 ;
C -1 ; WX 600 ; N amacron ; B 35 -15 570 585 ;
C -1 ; WX 600 ; N sacute ; B 68 -17 535 661 ;
C -1 ; WX 600 ; N idieresis ; B 77 0 523 618 ;
C -1 ; WX 600 ; N Ocircumflex ; B 22 -18 578 780 ;
C -1 ; WX 600 ; N Ugrave ; B 4 -18 596 784 ;
C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ;
C -1 ; WX 600 ; N thorn ; B -14 -142 570 626 ;
C -1 ; WX 600 ; N twosuperior ; B 143 230 436 616 ;
C -1 ; WX 600 ; N Odieresis ; B 22 -18 578 761 ;
C -1 ; WX 600 ; N mu ; B -1 -142 569 439 ;
C -1 ; WX 600 ; N igrave ; B 77 0 523 661 ;
C -1 ; WX 600 ; N ohungarumlaut ; B 30 -15 668 661 ;
C -1 ; WX 600 ; N Eogonek ; B 25 -199 576 562 ;
C -1 ; WX 600 ; N dcroat ; B 20 -15 591 626 ;
C -1 ; WX 600 ; N threequarters ; B -47 -60 648 661 ;
C -1 ; WX 600 ; N Scedilla ; B 47 -206 553 582 ;
C -1 ; WX 600 ; N lcaron ; B 77 0 597 626 ;
C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 599 562 ;
C -1 ; WX 600 ; N Lacute ; B 39 0 578 784 ;
C -1 ; WX 600 ; N trademark ; B -9 230 749 562 ;
C -1 ; WX 600 ; N edotaccent ; B 40 -15 563 638 ;
C -1 ; WX 600 ; N Igrave ; B 77 0 523 784 ;
C -1 ; WX 600 ; N Imacron ; B 77 0 523 708 ;
C -1 ; WX 600 ; N Lcaron ; B 39 0 637 562 ;
C -1 ; WX 600 ; N onehalf ; B -47 -60 648 661 ;
C -1 ; WX 600 ; N lessequal ; B 26 0 523 696 ;
C -1 ; WX 600 ; N ocircumflex ; B 30 -15 570 657 ;
C -1 ; WX 600 ; N ntilde ; B 18 0 592 636 ;
C -1 ; WX 600 ; N Uhungarumlaut ; B 4 -18 638 784 ;
C -1 ; WX 600 ; N Eacute ; B 25 0 560 784 ;
C -1 ; WX 600 ; N emacron ; B 40 -15 563 585 ;
C -1 ; WX 600 ; N gbreve ; B 30 -146 580 661 ;
C -1 ; WX 600 ; N onequarter ; B -56 -60 656 661 ;
C -1 ; WX 600 ; N Scaron ; B 47 -22 553 790 ;
C -1 ; WX 600 ; N Scommaaccent ; B 47 -250 553 582 ;
C -1 ; WX 600 ; N Ohungarumlaut ; B 22 -18 628 784 ;
C -1 ; WX 600 ; N degree ; B 86 243 474 616 ;
C -1 ; WX 600 ; N ograve ; B 30 -15 570 661 ;
C -1 ; WX 600 ; N Ccaron ; B 22 -18 560 790 ;
C -1 ; WX 600 ; N ugrave ; B -1 -15 569 661 ;
C -1 ; WX 600 ; N radical ; B -19 -104 473 778 ;
C -1 ; WX 600 ; N Dcaron ; B 30 0 594 790 ;
C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 580 454 ;
C -1 ; WX 600 ; N Ntilde ; B 8 -12 610 759 ;
C -1 ; WX 600 ; N otilde ; B 30 -15 570 636 ;
C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 599 562 ;
C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 578 562 ;
C -1 ; WX 600 ; N Atilde ; B -9 0 609 759 ;
C -1 ; WX 600 ; N Aogonek ; B -9 -199 625 562 ;
C -1 ; WX 600 ; N Aring ; B -9 0 609 801 ;
C -1 ; WX 600 ; N Otilde ; B 22 -18 578 759 ;
C -1 ; WX 600 ; N zdotaccent ; B 81 0 520 638 ;
C -1 ; WX 600 ; N Ecaron ; B 25 0 560 790 ;
C -1 ; WX 600 ; N Iogonek ; B 77 -199 523 562 ;
C -1 ; WX 600 ; N kcommaaccent ; B 20 -250 585 626 ;
C -1 ; WX 600 ; N minus ; B 71 203 529 313 ;
C -1 ; WX 600 ; N Icircumflex ; B 77 0 523 780 ;
C -1 ; WX 600 ; N ncaron ; B 18 0 592 667 ;
C -1 ; WX 600 ; N tcommaaccent ; B 47 -250 532 562 ;
C -1 ; WX 600 ; N logicalnot ; B 71 103 529 413 ;
C -1 ; WX 600 ; N odieresis ; B 30 -15 570 638 ;
C -1 ; WX 600 ; N udieresis ; B -1 -15 569 638 ;
C -1 ; WX 600 ; N notequal ; B 12 -47 537 563 ;
C -1 ; WX 600 ; N gcommaaccent ; B 30 -146 580 714 ;
C -1 ; WX 600 ; N eth ; B 58 -27 543 626 ;
C -1 ; WX 600 ; N zcaron ; B 81 0 520 667 ;
C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 592 454 ;
C -1 ; WX 600 ; N onesuperior ; B 153 230 447 616 ;
C -1 ; WX 600 ; N imacron ; B 77 0 523 585 ;
C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ;
EndCharMetrics
EndFontMetrics

View File

@@ -0,0 +1,342 @@
StartFontMetrics 4.1
Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
Comment Creation Date: Mon Jun 23 16:28:46 1997
Comment UniqueID 43049
Comment VMusage 17529 79244
FontName Courier-BoldOblique
FullName Courier Bold Oblique
FamilyName Courier
Weight Bold
ItalicAngle -12
IsFixedPitch true
CharacterSet ExtendedRoman
FontBBox -57 -250 869 801
UnderlinePosition -100
UnderlineThickness 50
Version 003.000
Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
EncodingScheme AdobeStandardEncoding
CapHeight 562
XHeight 439
Ascender 629
Descender -157
StdHW 84
StdVW 106
StartCharMetrics 315
C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
C 33 ; WX 600 ; N exclam ; B 215 -15 495 572 ;
C 34 ; WX 600 ; N quotedbl ; B 211 277 585 562 ;
C 35 ; WX 600 ; N numbersign ; B 88 -45 641 651 ;
C 36 ; WX 600 ; N dollar ; B 87 -126 630 666 ;
C 37 ; WX 600 ; N percent ; B 101 -15 625 616 ;
C 38 ; WX 600 ; N ampersand ; B 61 -15 595 543 ;
C 39 ; WX 600 ; N quoteright ; B 229 277 543 562 ;
C 40 ; WX 600 ; N parenleft ; B 265 -102 592 616 ;
C 41 ; WX 600 ; N parenright ; B 117 -102 444 616 ;
C 42 ; WX 600 ; N asterisk ; B 179 219 598 601 ;
C 43 ; WX 600 ; N plus ; B 114 39 596 478 ;
C 44 ; WX 600 ; N comma ; B 99 -111 430 174 ;
C 45 ; WX 600 ; N hyphen ; B 143 203 567 313 ;
C 46 ; WX 600 ; N period ; B 206 -15 427 171 ;
C 47 ; WX 600 ; N slash ; B 90 -77 626 626 ;
C 48 ; WX 600 ; N zero ; B 135 -15 593 616 ;
C 49 ; WX 600 ; N one ; B 93 0 562 616 ;
C 50 ; WX 600 ; N two ; B 61 0 594 616 ;
C 51 ; WX 600 ; N three ; B 71 -15 571 616 ;
C 52 ; WX 600 ; N four ; B 81 0 559 616 ;
C 53 ; WX 600 ; N five ; B 77 -15 621 601 ;
C 54 ; WX 600 ; N six ; B 135 -15 652 616 ;
C 55 ; WX 600 ; N seven ; B 147 0 622 601 ;
C 56 ; WX 600 ; N eight ; B 115 -15 604 616 ;
C 57 ; WX 600 ; N nine ; B 75 -15 592 616 ;
C 58 ; WX 600 ; N colon ; B 205 -15 480 425 ;
C 59 ; WX 600 ; N semicolon ; B 99 -111 481 425 ;
C 60 ; WX 600 ; N less ; B 120 15 613 501 ;
C 61 ; WX 600 ; N equal ; B 96 118 614 398 ;
C 62 ; WX 600 ; N greater ; B 97 15 589 501 ;
C 63 ; WX 600 ; N question ; B 183 -14 592 580 ;
C 64 ; WX 600 ; N at ; B 65 -15 642 616 ;
C 65 ; WX 600 ; N A ; B -9 0 632 562 ;
C 66 ; WX 600 ; N B ; B 30 0 630 562 ;
C 67 ; WX 600 ; N C ; B 74 -18 675 580 ;
C 68 ; WX 600 ; N D ; B 30 0 664 562 ;
C 69 ; WX 600 ; N E ; B 25 0 670 562 ;
C 70 ; WX 600 ; N F ; B 39 0 684 562 ;
C 71 ; WX 600 ; N G ; B 74 -18 675 580 ;
C 72 ; WX 600 ; N H ; B 20 0 700 562 ;
C 73 ; WX 600 ; N I ; B 77 0 643 562 ;
C 74 ; WX 600 ; N J ; B 58 -18 721 562 ;
C 75 ; WX 600 ; N K ; B 21 0 692 562 ;
C 76 ; WX 600 ; N L ; B 39 0 636 562 ;
C 77 ; WX 600 ; N M ; B -2 0 722 562 ;
C 78 ; WX 600 ; N N ; B 8 -12 730 562 ;
C 79 ; WX 600 ; N O ; B 74 -18 645 580 ;
C 80 ; WX 600 ; N P ; B 48 0 643 562 ;
C 81 ; WX 600 ; N Q ; B 83 -138 636 580 ;
C 82 ; WX 600 ; N R ; B 24 0 617 562 ;
C 83 ; WX 600 ; N S ; B 54 -22 673 582 ;
C 84 ; WX 600 ; N T ; B 86 0 679 562 ;
C 85 ; WX 600 ; N U ; B 101 -18 716 562 ;
C 86 ; WX 600 ; N V ; B 84 0 733 562 ;
C 87 ; WX 600 ; N W ; B 79 0 738 562 ;
C 88 ; WX 600 ; N X ; B 12 0 690 562 ;
C 89 ; WX 600 ; N Y ; B 109 0 709 562 ;
C 90 ; WX 600 ; N Z ; B 62 0 637 562 ;
C 91 ; WX 600 ; N bracketleft ; B 223 -102 606 616 ;
C 92 ; WX 600 ; N backslash ; B 222 -77 496 626 ;
C 93 ; WX 600 ; N bracketright ; B 103 -102 486 616 ;
C 94 ; WX 600 ; N asciicircum ; B 171 250 556 616 ;
C 95 ; WX 600 ; N underscore ; B -27 -125 585 -75 ;
C 96 ; WX 600 ; N quoteleft ; B 297 277 487 562 ;
C 97 ; WX 600 ; N a ; B 61 -15 593 454 ;
C 98 ; WX 600 ; N b ; B 13 -15 636 626 ;
C 99 ; WX 600 ; N c ; B 81 -15 631 459 ;
C 100 ; WX 600 ; N d ; B 60 -15 645 626 ;
C 101 ; WX 600 ; N e ; B 81 -15 605 454 ;
C 102 ; WX 600 ; N f ; B 83 0 677 626 ; L i fi ; L l fl ;
C 103 ; WX 600 ; N g ; B 40 -146 674 454 ;
C 104 ; WX 600 ; N h ; B 18 0 615 626 ;
C 105 ; WX 600 ; N i ; B 77 0 546 658 ;
C 106 ; WX 600 ; N j ; B 36 -146 580 658 ;
C 107 ; WX 600 ; N k ; B 33 0 643 626 ;
C 108 ; WX 600 ; N l ; B 77 0 546 626 ;
C 109 ; WX 600 ; N m ; B -22 0 649 454 ;
C 110 ; WX 600 ; N n ; B 18 0 615 454 ;
C 111 ; WX 600 ; N o ; B 71 -15 622 454 ;
C 112 ; WX 600 ; N p ; B -32 -142 622 454 ;
C 113 ; WX 600 ; N q ; B 60 -142 685 454 ;
C 114 ; WX 600 ; N r ; B 47 0 655 454 ;
C 115 ; WX 600 ; N s ; B 66 -17 608 459 ;
C 116 ; WX 600 ; N t ; B 118 -15 567 562 ;
C 117 ; WX 600 ; N u ; B 70 -15 592 439 ;
C 118 ; WX 600 ; N v ; B 70 0 695 439 ;
C 119 ; WX 600 ; N w ; B 53 0 712 439 ;
C 120 ; WX 600 ; N x ; B 6 0 671 439 ;
C 121 ; WX 600 ; N y ; B -21 -142 695 439 ;
C 122 ; WX 600 ; N z ; B 81 0 614 439 ;
C 123 ; WX 600 ; N braceleft ; B 203 -102 595 616 ;
C 124 ; WX 600 ; N bar ; B 201 -250 505 750 ;
C 125 ; WX 600 ; N braceright ; B 114 -102 506 616 ;
C 126 ; WX 600 ; N asciitilde ; B 120 153 590 356 ;
C 161 ; WX 600 ; N exclamdown ; B 196 -146 477 449 ;
C 162 ; WX 600 ; N cent ; B 121 -49 605 614 ;
C 163 ; WX 600 ; N sterling ; B 106 -28 650 611 ;
C 164 ; WX 600 ; N fraction ; B 22 -60 708 661 ;
C 165 ; WX 600 ; N yen ; B 98 0 710 562 ;
C 166 ; WX 600 ; N florin ; B -57 -131 702 616 ;
C 167 ; WX 600 ; N section ; B 74 -70 620 580 ;
C 168 ; WX 600 ; N currency ; B 77 49 644 517 ;
C 169 ; WX 600 ; N quotesingle ; B 303 277 493 562 ;
C 170 ; WX 600 ; N quotedblleft ; B 190 277 594 562 ;
C 171 ; WX 600 ; N guillemotleft ; B 62 70 639 446 ;
C 172 ; WX 600 ; N guilsinglleft ; B 195 70 545 446 ;
C 173 ; WX 600 ; N guilsinglright ; B 165 70 514 446 ;
C 174 ; WX 600 ; N fi ; B 12 0 644 626 ;
C 175 ; WX 600 ; N fl ; B 12 0 644 626 ;
C 177 ; WX 600 ; N endash ; B 108 203 602 313 ;
C 178 ; WX 600 ; N dagger ; B 175 -70 586 580 ;
C 179 ; WX 600 ; N daggerdbl ; B 121 -70 587 580 ;
C 180 ; WX 600 ; N periodcentered ; B 248 165 461 351 ;
C 182 ; WX 600 ; N paragraph ; B 61 -70 700 580 ;
C 183 ; WX 600 ; N bullet ; B 196 132 523 430 ;
C 184 ; WX 600 ; N quotesinglbase ; B 144 -142 458 143 ;
C 185 ; WX 600 ; N quotedblbase ; B 34 -142 560 143 ;
C 186 ; WX 600 ; N quotedblright ; B 119 277 645 562 ;
C 187 ; WX 600 ; N guillemotright ; B 71 70 647 446 ;
C 188 ; WX 600 ; N ellipsis ; B 35 -15 587 116 ;
C 189 ; WX 600 ; N perthousand ; B -45 -15 743 616 ;
C 191 ; WX 600 ; N questiondown ; B 100 -146 509 449 ;
C 193 ; WX 600 ; N grave ; B 272 508 503 661 ;
C 194 ; WX 600 ; N acute ; B 312 508 609 661 ;
C 195 ; WX 600 ; N circumflex ; B 212 483 607 657 ;
C 196 ; WX 600 ; N tilde ; B 199 493 643 636 ;
C 197 ; WX 600 ; N macron ; B 195 505 637 585 ;
C 198 ; WX 600 ; N breve ; B 217 468 652 631 ;
C 199 ; WX 600 ; N dotaccent ; B 348 498 493 638 ;
C 200 ; WX 600 ; N dieresis ; B 246 498 595 638 ;
C 202 ; WX 600 ; N ring ; B 319 481 528 678 ;
C 203 ; WX 600 ; N cedilla ; B 168 -206 368 0 ;
C 205 ; WX 600 ; N hungarumlaut ; B 171 488 729 661 ;
C 206 ; WX 600 ; N ogonek ; B 143 -199 367 0 ;
C 207 ; WX 600 ; N caron ; B 238 493 633 667 ;
C 208 ; WX 600 ; N emdash ; B 33 203 677 313 ;
C 225 ; WX 600 ; N AE ; B -29 0 708 562 ;
C 227 ; WX 600 ; N ordfeminine ; B 188 196 526 580 ;
C 232 ; WX 600 ; N Lslash ; B 39 0 636 562 ;
C 233 ; WX 600 ; N Oslash ; B 48 -22 673 584 ;
C 234 ; WX 600 ; N OE ; B 26 0 701 562 ;
C 235 ; WX 600 ; N ordmasculine ; B 188 196 543 580 ;
C 241 ; WX 600 ; N ae ; B 21 -15 652 454 ;
C 245 ; WX 600 ; N dotlessi ; B 77 0 546 439 ;
C 248 ; WX 600 ; N lslash ; B 77 0 587 626 ;
C 249 ; WX 600 ; N oslash ; B 54 -24 638 463 ;
C 250 ; WX 600 ; N oe ; B 18 -15 662 454 ;
C 251 ; WX 600 ; N germandbls ; B 22 -15 629 626 ;
C -1 ; WX 600 ; N Idieresis ; B 77 0 643 761 ;
C -1 ; WX 600 ; N eacute ; B 81 -15 609 661 ;
C -1 ; WX 600 ; N abreve ; B 61 -15 658 661 ;
C -1 ; WX 600 ; N uhungarumlaut ; B 70 -15 769 661 ;
C -1 ; WX 600 ; N ecaron ; B 81 -15 633 667 ;
C -1 ; WX 600 ; N Ydieresis ; B 109 0 709 761 ;
C -1 ; WX 600 ; N divide ; B 114 16 596 500 ;
C -1 ; WX 600 ; N Yacute ; B 109 0 709 784 ;
C -1 ; WX 600 ; N Acircumflex ; B -9 0 632 780 ;
C -1 ; WX 600 ; N aacute ; B 61 -15 609 661 ;
C -1 ; WX 600 ; N Ucircumflex ; B 101 -18 716 780 ;
C -1 ; WX 600 ; N yacute ; B -21 -142 695 661 ;
C -1 ; WX 600 ; N scommaaccent ; B 66 -250 608 459 ;
C -1 ; WX 600 ; N ecircumflex ; B 81 -15 607 657 ;
C -1 ; WX 600 ; N Uring ; B 101 -18 716 801 ;
C -1 ; WX 600 ; N Udieresis ; B 101 -18 716 761 ;
C -1 ; WX 600 ; N aogonek ; B 61 -199 593 454 ;
C -1 ; WX 600 ; N Uacute ; B 101 -18 716 784 ;
C -1 ; WX 600 ; N uogonek ; B 70 -199 592 439 ;
C -1 ; WX 600 ; N Edieresis ; B 25 0 670 761 ;
C -1 ; WX 600 ; N Dcroat ; B 30 0 664 562 ;
C -1 ; WX 600 ; N commaaccent ; B 151 -250 385 -57 ;
C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ;
C -1 ; WX 600 ; N Emacron ; B 25 0 670 708 ;
C -1 ; WX 600 ; N ccaron ; B 81 -15 633 667 ;
C -1 ; WX 600 ; N aring ; B 61 -15 593 678 ;
C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 730 562 ;
C -1 ; WX 600 ; N lacute ; B 77 0 639 801 ;
C -1 ; WX 600 ; N agrave ; B 61 -15 593 661 ;
C -1 ; WX 600 ; N Tcommaaccent ; B 86 -250 679 562 ;
C -1 ; WX 600 ; N Cacute ; B 74 -18 675 784 ;
C -1 ; WX 600 ; N atilde ; B 61 -15 643 636 ;
C -1 ; WX 600 ; N Edotaccent ; B 25 0 670 761 ;
C -1 ; WX 600 ; N scaron ; B 66 -17 633 667 ;
C -1 ; WX 600 ; N scedilla ; B 66 -206 608 459 ;
C -1 ; WX 600 ; N iacute ; B 77 0 609 661 ;
C -1 ; WX 600 ; N lozenge ; B 145 0 614 740 ;
C -1 ; WX 600 ; N Rcaron ; B 24 0 659 790 ;
C -1 ; WX 600 ; N Gcommaaccent ; B 74 -250 675 580 ;
C -1 ; WX 600 ; N ucircumflex ; B 70 -15 597 657 ;
C -1 ; WX 600 ; N acircumflex ; B 61 -15 607 657 ;
C -1 ; WX 600 ; N Amacron ; B -9 0 633 708 ;
C -1 ; WX 600 ; N rcaron ; B 47 0 655 667 ;
C -1 ; WX 600 ; N ccedilla ; B 81 -206 631 459 ;
C -1 ; WX 600 ; N Zdotaccent ; B 62 0 637 761 ;
C -1 ; WX 600 ; N Thorn ; B 48 0 620 562 ;
C -1 ; WX 600 ; N Omacron ; B 74 -18 663 708 ;
C -1 ; WX 600 ; N Racute ; B 24 0 665 784 ;
C -1 ; WX 600 ; N Sacute ; B 54 -22 673 784 ;
C -1 ; WX 600 ; N dcaron ; B 60 -15 861 626 ;
C -1 ; WX 600 ; N Umacron ; B 101 -18 716 708 ;
C -1 ; WX 600 ; N uring ; B 70 -15 592 678 ;
C -1 ; WX 600 ; N threesuperior ; B 193 222 526 616 ;
C -1 ; WX 600 ; N Ograve ; B 74 -18 645 784 ;
C -1 ; WX 600 ; N Agrave ; B -9 0 632 784 ;
C -1 ; WX 600 ; N Abreve ; B -9 0 684 784 ;
C -1 ; WX 600 ; N multiply ; B 104 39 606 478 ;
C -1 ; WX 600 ; N uacute ; B 70 -15 599 661 ;
C -1 ; WX 600 ; N Tcaron ; B 86 0 679 790 ;
C -1 ; WX 600 ; N partialdiff ; B 91 -38 627 728 ;
C -1 ; WX 600 ; N ydieresis ; B -21 -142 695 638 ;
C -1 ; WX 600 ; N Nacute ; B 8 -12 730 784 ;
C -1 ; WX 600 ; N icircumflex ; B 77 0 577 657 ;
C -1 ; WX 600 ; N Ecircumflex ; B 25 0 670 780 ;
C -1 ; WX 600 ; N adieresis ; B 61 -15 595 638 ;
C -1 ; WX 600 ; N edieresis ; B 81 -15 605 638 ;
C -1 ; WX 600 ; N cacute ; B 81 -15 649 661 ;
C -1 ; WX 600 ; N nacute ; B 18 0 639 661 ;
C -1 ; WX 600 ; N umacron ; B 70 -15 637 585 ;
C -1 ; WX 600 ; N Ncaron ; B 8 -12 730 790 ;
C -1 ; WX 600 ; N Iacute ; B 77 0 643 784 ;
C -1 ; WX 600 ; N plusminus ; B 76 24 614 515 ;
C -1 ; WX 600 ; N brokenbar ; B 217 -175 489 675 ;
C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ;
C -1 ; WX 600 ; N Gbreve ; B 74 -18 684 784 ;
C -1 ; WX 600 ; N Idotaccent ; B 77 0 643 761 ;
C -1 ; WX 600 ; N summation ; B 15 -10 672 706 ;
C -1 ; WX 600 ; N Egrave ; B 25 0 670 784 ;
C -1 ; WX 600 ; N racute ; B 47 0 655 661 ;
C -1 ; WX 600 ; N omacron ; B 71 -15 637 585 ;
C -1 ; WX 600 ; N Zacute ; B 62 0 665 784 ;
C -1 ; WX 600 ; N Zcaron ; B 62 0 659 790 ;
C -1 ; WX 600 ; N greaterequal ; B 26 0 627 696 ;
C -1 ; WX 600 ; N Eth ; B 30 0 664 562 ;
C -1 ; WX 600 ; N Ccedilla ; B 74 -206 675 580 ;
C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 546 626 ;
C -1 ; WX 600 ; N tcaron ; B 118 -15 627 703 ;
C -1 ; WX 600 ; N eogonek ; B 81 -199 605 454 ;
C -1 ; WX 600 ; N Uogonek ; B 101 -199 716 562 ;
C -1 ; WX 600 ; N Aacute ; B -9 0 655 784 ;
C -1 ; WX 600 ; N Adieresis ; B -9 0 632 761 ;
C -1 ; WX 600 ; N egrave ; B 81 -15 605 661 ;
C -1 ; WX 600 ; N zacute ; B 81 0 614 661 ;
C -1 ; WX 600 ; N iogonek ; B 77 -199 546 658 ;
C -1 ; WX 600 ; N Oacute ; B 74 -18 645 784 ;
C -1 ; WX 600 ; N oacute ; B 71 -15 649 661 ;
C -1 ; WX 600 ; N amacron ; B 61 -15 637 585 ;
C -1 ; WX 600 ; N sacute ; B 66 -17 609 661 ;
C -1 ; WX 600 ; N idieresis ; B 77 0 561 618 ;
C -1 ; WX 600 ; N Ocircumflex ; B 74 -18 645 780 ;
C -1 ; WX 600 ; N Ugrave ; B 101 -18 716 784 ;
C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ;
C -1 ; WX 600 ; N thorn ; B -32 -142 622 626 ;
C -1 ; WX 600 ; N twosuperior ; B 191 230 542 616 ;
C -1 ; WX 600 ; N Odieresis ; B 74 -18 645 761 ;
C -1 ; WX 600 ; N mu ; B 49 -142 592 439 ;
C -1 ; WX 600 ; N igrave ; B 77 0 546 661 ;
C -1 ; WX 600 ; N ohungarumlaut ; B 71 -15 809 661 ;
C -1 ; WX 600 ; N Eogonek ; B 25 -199 670 562 ;
C -1 ; WX 600 ; N dcroat ; B 60 -15 712 626 ;
C -1 ; WX 600 ; N threequarters ; B 8 -60 699 661 ;
C -1 ; WX 600 ; N Scedilla ; B 54 -206 673 582 ;
C -1 ; WX 600 ; N lcaron ; B 77 0 731 626 ;
C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 692 562 ;
C -1 ; WX 600 ; N Lacute ; B 39 0 636 784 ;
C -1 ; WX 600 ; N trademark ; B 86 230 869 562 ;
C -1 ; WX 600 ; N edotaccent ; B 81 -15 605 638 ;
C -1 ; WX 600 ; N Igrave ; B 77 0 643 784 ;
C -1 ; WX 600 ; N Imacron ; B 77 0 663 708 ;
C -1 ; WX 600 ; N Lcaron ; B 39 0 757 562 ;
C -1 ; WX 600 ; N onehalf ; B 22 -60 716 661 ;
C -1 ; WX 600 ; N lessequal ; B 26 0 671 696 ;
C -1 ; WX 600 ; N ocircumflex ; B 71 -15 622 657 ;
C -1 ; WX 600 ; N ntilde ; B 18 0 643 636 ;
C -1 ; WX 600 ; N Uhungarumlaut ; B 101 -18 805 784 ;
C -1 ; WX 600 ; N Eacute ; B 25 0 670 784 ;
C -1 ; WX 600 ; N emacron ; B 81 -15 637 585 ;
C -1 ; WX 600 ; N gbreve ; B 40 -146 674 661 ;
C -1 ; WX 600 ; N onequarter ; B 13 -60 707 661 ;
C -1 ; WX 600 ; N Scaron ; B 54 -22 689 790 ;
C -1 ; WX 600 ; N Scommaaccent ; B 54 -250 673 582 ;
C -1 ; WX 600 ; N Ohungarumlaut ; B 74 -18 795 784 ;
C -1 ; WX 600 ; N degree ; B 173 243 570 616 ;
C -1 ; WX 600 ; N ograve ; B 71 -15 622 661 ;
C -1 ; WX 600 ; N Ccaron ; B 74 -18 689 790 ;
C -1 ; WX 600 ; N ugrave ; B 70 -15 592 661 ;
C -1 ; WX 600 ; N radical ; B 67 -104 635 778 ;
C -1 ; WX 600 ; N Dcaron ; B 30 0 664 790 ;
C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 655 454 ;
C -1 ; WX 600 ; N Ntilde ; B 8 -12 730 759 ;
C -1 ; WX 600 ; N otilde ; B 71 -15 643 636 ;
C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 617 562 ;
C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 636 562 ;
C -1 ; WX 600 ; N Atilde ; B -9 0 669 759 ;
C -1 ; WX 600 ; N Aogonek ; B -9 -199 632 562 ;
C -1 ; WX 600 ; N Aring ; B -9 0 632 801 ;
C -1 ; WX 600 ; N Otilde ; B 74 -18 669 759 ;
C -1 ; WX 600 ; N zdotaccent ; B 81 0 614 638 ;
C -1 ; WX 600 ; N Ecaron ; B 25 0 670 790 ;
C -1 ; WX 600 ; N Iogonek ; B 77 -199 643 562 ;
C -1 ; WX 600 ; N kcommaaccent ; B 33 -250 643 626 ;
C -1 ; WX 600 ; N minus ; B 114 203 596 313 ;
C -1 ; WX 600 ; N Icircumflex ; B 77 0 643 780 ;
C -1 ; WX 600 ; N ncaron ; B 18 0 633 667 ;
C -1 ; WX 600 ; N tcommaaccent ; B 118 -250 567 562 ;
C -1 ; WX 600 ; N logicalnot ; B 135 103 617 413 ;
C -1 ; WX 600 ; N odieresis ; B 71 -15 622 638 ;
C -1 ; WX 600 ; N udieresis ; B 70 -15 595 638 ;
C -1 ; WX 600 ; N notequal ; B 30 -47 626 563 ;
C -1 ; WX 600 ; N gcommaaccent ; B 40 -146 674 714 ;
C -1 ; WX 600 ; N eth ; B 93 -27 661 626 ;
C -1 ; WX 600 ; N zcaron ; B 81 0 643 667 ;
C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 615 454 ;
C -1 ; WX 600 ; N onesuperior ; B 212 230 514 616 ;
C -1 ; WX 600 ; N imacron ; B 77 0 575 585 ;
C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ;
EndCharMetrics
EndFontMetrics

View File

@@ -0,0 +1,342 @@
StartFontMetrics 4.1
Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
Comment Creation Date: Thu May 1 17:37:52 1997
Comment UniqueID 43051
Comment VMusage 16248 75829
FontName Courier-Oblique
FullName Courier Oblique
FamilyName Courier
Weight Medium
ItalicAngle -12
IsFixedPitch true
CharacterSet ExtendedRoman
FontBBox -27 -250 849 805
UnderlinePosition -100
UnderlineThickness 50
Version 003.000
Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
EncodingScheme AdobeStandardEncoding
CapHeight 562
XHeight 426
Ascender 629
Descender -157
StdHW 51
StdVW 51
StartCharMetrics 315
C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
C 33 ; WX 600 ; N exclam ; B 243 -15 464 572 ;
C 34 ; WX 600 ; N quotedbl ; B 273 328 532 562 ;
C 35 ; WX 600 ; N numbersign ; B 133 -32 596 639 ;
C 36 ; WX 600 ; N dollar ; B 108 -126 596 662 ;
C 37 ; WX 600 ; N percent ; B 134 -15 599 622 ;
C 38 ; WX 600 ; N ampersand ; B 87 -15 580 543 ;
C 39 ; WX 600 ; N quoteright ; B 283 328 495 562 ;
C 40 ; WX 600 ; N parenleft ; B 313 -108 572 622 ;
C 41 ; WX 600 ; N parenright ; B 137 -108 396 622 ;
C 42 ; WX 600 ; N asterisk ; B 212 257 580 607 ;
C 43 ; WX 600 ; N plus ; B 129 44 580 470 ;
C 44 ; WX 600 ; N comma ; B 157 -112 370 122 ;
C 45 ; WX 600 ; N hyphen ; B 152 231 558 285 ;
C 46 ; WX 600 ; N period ; B 238 -15 382 109 ;
C 47 ; WX 600 ; N slash ; B 112 -80 604 629 ;
C 48 ; WX 600 ; N zero ; B 154 -15 575 622 ;
C 49 ; WX 600 ; N one ; B 98 0 515 622 ;
C 50 ; WX 600 ; N two ; B 70 0 568 622 ;
C 51 ; WX 600 ; N three ; B 82 -15 538 622 ;
C 52 ; WX 600 ; N four ; B 108 0 541 622 ;
C 53 ; WX 600 ; N five ; B 99 -15 589 607 ;
C 54 ; WX 600 ; N six ; B 155 -15 629 622 ;
C 55 ; WX 600 ; N seven ; B 182 0 612 607 ;
C 56 ; WX 600 ; N eight ; B 132 -15 588 622 ;
C 57 ; WX 600 ; N nine ; B 93 -15 574 622 ;
C 58 ; WX 600 ; N colon ; B 238 -15 441 385 ;
C 59 ; WX 600 ; N semicolon ; B 157 -112 441 385 ;
C 60 ; WX 600 ; N less ; B 96 42 610 472 ;
C 61 ; WX 600 ; N equal ; B 109 138 600 376 ;
C 62 ; WX 600 ; N greater ; B 85 42 599 472 ;
C 63 ; WX 600 ; N question ; B 222 -15 583 572 ;
C 64 ; WX 600 ; N at ; B 127 -15 582 622 ;
C 65 ; WX 600 ; N A ; B 3 0 607 562 ;
C 66 ; WX 600 ; N B ; B 43 0 616 562 ;
C 67 ; WX 600 ; N C ; B 93 -18 655 580 ;
C 68 ; WX 600 ; N D ; B 43 0 645 562 ;
C 69 ; WX 600 ; N E ; B 53 0 660 562 ;
C 70 ; WX 600 ; N F ; B 53 0 660 562 ;
C 71 ; WX 600 ; N G ; B 83 -18 645 580 ;
C 72 ; WX 600 ; N H ; B 32 0 687 562 ;
C 73 ; WX 600 ; N I ; B 96 0 623 562 ;
C 74 ; WX 600 ; N J ; B 52 -18 685 562 ;
C 75 ; WX 600 ; N K ; B 38 0 671 562 ;
C 76 ; WX 600 ; N L ; B 47 0 607 562 ;
C 77 ; WX 600 ; N M ; B 4 0 715 562 ;
C 78 ; WX 600 ; N N ; B 7 -13 712 562 ;
C 79 ; WX 600 ; N O ; B 94 -18 625 580 ;
C 80 ; WX 600 ; N P ; B 79 0 644 562 ;
C 81 ; WX 600 ; N Q ; B 95 -138 625 580 ;
C 82 ; WX 600 ; N R ; B 38 0 598 562 ;
C 83 ; WX 600 ; N S ; B 76 -20 650 580 ;
C 84 ; WX 600 ; N T ; B 108 0 665 562 ;
C 85 ; WX 600 ; N U ; B 125 -18 702 562 ;
C 86 ; WX 600 ; N V ; B 105 -13 723 562 ;
C 87 ; WX 600 ; N W ; B 106 -13 722 562 ;
C 88 ; WX 600 ; N X ; B 23 0 675 562 ;
C 89 ; WX 600 ; N Y ; B 133 0 695 562 ;
C 90 ; WX 600 ; N Z ; B 86 0 610 562 ;
C 91 ; WX 600 ; N bracketleft ; B 246 -108 574 622 ;
C 92 ; WX 600 ; N backslash ; B 249 -80 468 629 ;
C 93 ; WX 600 ; N bracketright ; B 135 -108 463 622 ;
C 94 ; WX 600 ; N asciicircum ; B 175 354 587 622 ;
C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ;
C 96 ; WX 600 ; N quoteleft ; B 343 328 457 562 ;
C 97 ; WX 600 ; N a ; B 76 -15 569 441 ;
C 98 ; WX 600 ; N b ; B 29 -15 625 629 ;
C 99 ; WX 600 ; N c ; B 106 -15 608 441 ;
C 100 ; WX 600 ; N d ; B 85 -15 640 629 ;
C 101 ; WX 600 ; N e ; B 106 -15 598 441 ;
C 102 ; WX 600 ; N f ; B 114 0 662 629 ; L i fi ; L l fl ;
C 103 ; WX 600 ; N g ; B 61 -157 657 441 ;
C 104 ; WX 600 ; N h ; B 33 0 592 629 ;
C 105 ; WX 600 ; N i ; B 95 0 515 657 ;
C 106 ; WX 600 ; N j ; B 52 -157 550 657 ;
C 107 ; WX 600 ; N k ; B 58 0 633 629 ;
C 108 ; WX 600 ; N l ; B 95 0 515 629 ;
C 109 ; WX 600 ; N m ; B -5 0 615 441 ;
C 110 ; WX 600 ; N n ; B 26 0 585 441 ;
C 111 ; WX 600 ; N o ; B 102 -15 588 441 ;
C 112 ; WX 600 ; N p ; B -24 -157 605 441 ;
C 113 ; WX 600 ; N q ; B 85 -157 682 441 ;
C 114 ; WX 600 ; N r ; B 60 0 636 441 ;
C 115 ; WX 600 ; N s ; B 78 -15 584 441 ;
C 116 ; WX 600 ; N t ; B 167 -15 561 561 ;
C 117 ; WX 600 ; N u ; B 101 -15 572 426 ;
C 118 ; WX 600 ; N v ; B 90 -10 681 426 ;
C 119 ; WX 600 ; N w ; B 76 -10 695 426 ;
C 120 ; WX 600 ; N x ; B 20 0 655 426 ;
C 121 ; WX 600 ; N y ; B -4 -157 683 426 ;
C 122 ; WX 600 ; N z ; B 99 0 593 426 ;
C 123 ; WX 600 ; N braceleft ; B 233 -108 569 622 ;
C 124 ; WX 600 ; N bar ; B 222 -250 485 750 ;
C 125 ; WX 600 ; N braceright ; B 140 -108 477 622 ;
C 126 ; WX 600 ; N asciitilde ; B 116 197 600 320 ;
C 161 ; WX 600 ; N exclamdown ; B 225 -157 445 430 ;
C 162 ; WX 600 ; N cent ; B 151 -49 588 614 ;
C 163 ; WX 600 ; N sterling ; B 124 -21 621 611 ;
C 164 ; WX 600 ; N fraction ; B 84 -57 646 665 ;
C 165 ; WX 600 ; N yen ; B 120 0 693 562 ;
C 166 ; WX 600 ; N florin ; B -26 -143 671 622 ;
C 167 ; WX 600 ; N section ; B 104 -78 590 580 ;
C 168 ; WX 600 ; N currency ; B 94 58 628 506 ;
C 169 ; WX 600 ; N quotesingle ; B 345 328 460 562 ;
C 170 ; WX 600 ; N quotedblleft ; B 262 328 541 562 ;
C 171 ; WX 600 ; N guillemotleft ; B 92 70 652 446 ;
C 172 ; WX 600 ; N guilsinglleft ; B 204 70 540 446 ;
C 173 ; WX 600 ; N guilsinglright ; B 170 70 506 446 ;
C 174 ; WX 600 ; N fi ; B 3 0 619 629 ;
C 175 ; WX 600 ; N fl ; B 3 0 619 629 ;
C 177 ; WX 600 ; N endash ; B 124 231 586 285 ;
C 178 ; WX 600 ; N dagger ; B 217 -78 546 580 ;
C 179 ; WX 600 ; N daggerdbl ; B 163 -78 546 580 ;
C 180 ; WX 600 ; N periodcentered ; B 275 189 434 327 ;
C 182 ; WX 600 ; N paragraph ; B 100 -78 630 562 ;
C 183 ; WX 600 ; N bullet ; B 224 130 485 383 ;
C 184 ; WX 600 ; N quotesinglbase ; B 185 -134 397 100 ;
C 185 ; WX 600 ; N quotedblbase ; B 115 -134 478 100 ;
C 186 ; WX 600 ; N quotedblright ; B 213 328 576 562 ;
C 187 ; WX 600 ; N guillemotright ; B 58 70 618 446 ;
C 188 ; WX 600 ; N ellipsis ; B 46 -15 575 111 ;
C 189 ; WX 600 ; N perthousand ; B 59 -15 627 622 ;
C 191 ; WX 600 ; N questiondown ; B 105 -157 466 430 ;
C 193 ; WX 600 ; N grave ; B 294 497 484 672 ;
C 194 ; WX 600 ; N acute ; B 348 497 612 672 ;
C 195 ; WX 600 ; N circumflex ; B 229 477 581 654 ;
C 196 ; WX 600 ; N tilde ; B 212 489 629 606 ;
C 197 ; WX 600 ; N macron ; B 232 525 600 565 ;
C 198 ; WX 600 ; N breve ; B 279 501 576 609 ;
C 199 ; WX 600 ; N dotaccent ; B 373 537 478 640 ;
C 200 ; WX 600 ; N dieresis ; B 272 537 579 640 ;
C 202 ; WX 600 ; N ring ; B 332 463 500 627 ;
C 203 ; WX 600 ; N cedilla ; B 197 -151 344 10 ;
C 205 ; WX 600 ; N hungarumlaut ; B 239 497 683 672 ;
C 206 ; WX 600 ; N ogonek ; B 189 -172 377 4 ;
C 207 ; WX 600 ; N caron ; B 262 492 614 669 ;
C 208 ; WX 600 ; N emdash ; B 49 231 661 285 ;
C 225 ; WX 600 ; N AE ; B 3 0 655 562 ;
C 227 ; WX 600 ; N ordfeminine ; B 209 249 512 580 ;
C 232 ; WX 600 ; N Lslash ; B 47 0 607 562 ;
C 233 ; WX 600 ; N Oslash ; B 94 -80 625 629 ;
C 234 ; WX 600 ; N OE ; B 59 0 672 562 ;
C 235 ; WX 600 ; N ordmasculine ; B 210 249 535 580 ;
C 241 ; WX 600 ; N ae ; B 41 -15 626 441 ;
C 245 ; WX 600 ; N dotlessi ; B 95 0 515 426 ;
C 248 ; WX 600 ; N lslash ; B 95 0 587 629 ;
C 249 ; WX 600 ; N oslash ; B 102 -80 588 506 ;
C 250 ; WX 600 ; N oe ; B 54 -15 615 441 ;
C 251 ; WX 600 ; N germandbls ; B 48 -15 617 629 ;
C -1 ; WX 600 ; N Idieresis ; B 96 0 623 753 ;
C -1 ; WX 600 ; N eacute ; B 106 -15 612 672 ;
C -1 ; WX 600 ; N abreve ; B 76 -15 576 609 ;
C -1 ; WX 600 ; N uhungarumlaut ; B 101 -15 723 672 ;
C -1 ; WX 600 ; N ecaron ; B 106 -15 614 669 ;
C -1 ; WX 600 ; N Ydieresis ; B 133 0 695 753 ;
C -1 ; WX 600 ; N divide ; B 136 48 573 467 ;
C -1 ; WX 600 ; N Yacute ; B 133 0 695 805 ;
C -1 ; WX 600 ; N Acircumflex ; B 3 0 607 787 ;
C -1 ; WX 600 ; N aacute ; B 76 -15 612 672 ;
C -1 ; WX 600 ; N Ucircumflex ; B 125 -18 702 787 ;
C -1 ; WX 600 ; N yacute ; B -4 -157 683 672 ;
C -1 ; WX 600 ; N scommaaccent ; B 78 -250 584 441 ;
C -1 ; WX 600 ; N ecircumflex ; B 106 -15 598 654 ;
C -1 ; WX 600 ; N Uring ; B 125 -18 702 760 ;
C -1 ; WX 600 ; N Udieresis ; B 125 -18 702 753 ;
C -1 ; WX 600 ; N aogonek ; B 76 -172 569 441 ;
C -1 ; WX 600 ; N Uacute ; B 125 -18 702 805 ;
C -1 ; WX 600 ; N uogonek ; B 101 -172 572 426 ;
C -1 ; WX 600 ; N Edieresis ; B 53 0 660 753 ;
C -1 ; WX 600 ; N Dcroat ; B 43 0 645 562 ;
C -1 ; WX 600 ; N commaaccent ; B 145 -250 323 -58 ;
C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ;
C -1 ; WX 600 ; N Emacron ; B 53 0 660 698 ;
C -1 ; WX 600 ; N ccaron ; B 106 -15 614 669 ;
C -1 ; WX 600 ; N aring ; B 76 -15 569 627 ;
C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 712 562 ;
C -1 ; WX 600 ; N lacute ; B 95 0 640 805 ;
C -1 ; WX 600 ; N agrave ; B 76 -15 569 672 ;
C -1 ; WX 600 ; N Tcommaaccent ; B 108 -250 665 562 ;
C -1 ; WX 600 ; N Cacute ; B 93 -18 655 805 ;
C -1 ; WX 600 ; N atilde ; B 76 -15 629 606 ;
C -1 ; WX 600 ; N Edotaccent ; B 53 0 660 753 ;
C -1 ; WX 600 ; N scaron ; B 78 -15 614 669 ;
C -1 ; WX 600 ; N scedilla ; B 78 -151 584 441 ;
C -1 ; WX 600 ; N iacute ; B 95 0 612 672 ;
C -1 ; WX 600 ; N lozenge ; B 94 0 519 706 ;
C -1 ; WX 600 ; N Rcaron ; B 38 0 642 802 ;
C -1 ; WX 600 ; N Gcommaaccent ; B 83 -250 645 580 ;
C -1 ; WX 600 ; N ucircumflex ; B 101 -15 572 654 ;
C -1 ; WX 600 ; N acircumflex ; B 76 -15 581 654 ;
C -1 ; WX 600 ; N Amacron ; B 3 0 607 698 ;
C -1 ; WX 600 ; N rcaron ; B 60 0 636 669 ;
C -1 ; WX 600 ; N ccedilla ; B 106 -151 614 441 ;
C -1 ; WX 600 ; N Zdotaccent ; B 86 0 610 753 ;
C -1 ; WX 600 ; N Thorn ; B 79 0 606 562 ;
C -1 ; WX 600 ; N Omacron ; B 94 -18 628 698 ;
C -1 ; WX 600 ; N Racute ; B 38 0 670 805 ;
C -1 ; WX 600 ; N Sacute ; B 76 -20 650 805 ;
C -1 ; WX 600 ; N dcaron ; B 85 -15 849 629 ;
C -1 ; WX 600 ; N Umacron ; B 125 -18 702 698 ;
C -1 ; WX 600 ; N uring ; B 101 -15 572 627 ;
C -1 ; WX 600 ; N threesuperior ; B 213 240 501 622 ;
C -1 ; WX 600 ; N Ograve ; B 94 -18 625 805 ;
C -1 ; WX 600 ; N Agrave ; B 3 0 607 805 ;
C -1 ; WX 600 ; N Abreve ; B 3 0 607 732 ;
C -1 ; WX 600 ; N multiply ; B 103 43 607 470 ;
C -1 ; WX 600 ; N uacute ; B 101 -15 602 672 ;
C -1 ; WX 600 ; N Tcaron ; B 108 0 665 802 ;
C -1 ; WX 600 ; N partialdiff ; B 45 -38 546 710 ;
C -1 ; WX 600 ; N ydieresis ; B -4 -157 683 620 ;
C -1 ; WX 600 ; N Nacute ; B 7 -13 712 805 ;
C -1 ; WX 600 ; N icircumflex ; B 95 0 551 654 ;
C -1 ; WX 600 ; N Ecircumflex ; B 53 0 660 787 ;
C -1 ; WX 600 ; N adieresis ; B 76 -15 575 620 ;
C -1 ; WX 600 ; N edieresis ; B 106 -15 598 620 ;
C -1 ; WX 600 ; N cacute ; B 106 -15 612 672 ;
C -1 ; WX 600 ; N nacute ; B 26 0 602 672 ;
C -1 ; WX 600 ; N umacron ; B 101 -15 600 565 ;
C -1 ; WX 600 ; N Ncaron ; B 7 -13 712 802 ;
C -1 ; WX 600 ; N Iacute ; B 96 0 640 805 ;
C -1 ; WX 600 ; N plusminus ; B 96 44 594 558 ;
C -1 ; WX 600 ; N brokenbar ; B 238 -175 469 675 ;
C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ;
C -1 ; WX 600 ; N Gbreve ; B 83 -18 645 732 ;
C -1 ; WX 600 ; N Idotaccent ; B 96 0 623 753 ;
C -1 ; WX 600 ; N summation ; B 15 -10 670 706 ;
C -1 ; WX 600 ; N Egrave ; B 53 0 660 805 ;
C -1 ; WX 600 ; N racute ; B 60 0 636 672 ;
C -1 ; WX 600 ; N omacron ; B 102 -15 600 565 ;
C -1 ; WX 600 ; N Zacute ; B 86 0 670 805 ;
C -1 ; WX 600 ; N Zcaron ; B 86 0 642 802 ;
C -1 ; WX 600 ; N greaterequal ; B 98 0 594 710 ;
C -1 ; WX 600 ; N Eth ; B 43 0 645 562 ;
C -1 ; WX 600 ; N Ccedilla ; B 93 -151 658 580 ;
C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 515 629 ;
C -1 ; WX 600 ; N tcaron ; B 167 -15 587 717 ;
C -1 ; WX 600 ; N eogonek ; B 106 -172 598 441 ;
C -1 ; WX 600 ; N Uogonek ; B 124 -172 702 562 ;
C -1 ; WX 600 ; N Aacute ; B 3 0 660 805 ;
C -1 ; WX 600 ; N Adieresis ; B 3 0 607 753 ;
C -1 ; WX 600 ; N egrave ; B 106 -15 598 672 ;
C -1 ; WX 600 ; N zacute ; B 99 0 612 672 ;
C -1 ; WX 600 ; N iogonek ; B 95 -172 515 657 ;
C -1 ; WX 600 ; N Oacute ; B 94 -18 640 805 ;
C -1 ; WX 600 ; N oacute ; B 102 -15 612 672 ;
C -1 ; WX 600 ; N amacron ; B 76 -15 600 565 ;
C -1 ; WX 600 ; N sacute ; B 78 -15 612 672 ;
C -1 ; WX 600 ; N idieresis ; B 95 0 545 620 ;
C -1 ; WX 600 ; N Ocircumflex ; B 94 -18 625 787 ;
C -1 ; WX 600 ; N Ugrave ; B 125 -18 702 805 ;
C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ;
C -1 ; WX 600 ; N thorn ; B -24 -157 605 629 ;
C -1 ; WX 600 ; N twosuperior ; B 230 249 535 622 ;
C -1 ; WX 600 ; N Odieresis ; B 94 -18 625 753 ;
C -1 ; WX 600 ; N mu ; B 72 -157 572 426 ;
C -1 ; WX 600 ; N igrave ; B 95 0 515 672 ;
C -1 ; WX 600 ; N ohungarumlaut ; B 102 -15 723 672 ;
C -1 ; WX 600 ; N Eogonek ; B 53 -172 660 562 ;
C -1 ; WX 600 ; N dcroat ; B 85 -15 704 629 ;
C -1 ; WX 600 ; N threequarters ; B 73 -56 659 666 ;
C -1 ; WX 600 ; N Scedilla ; B 76 -151 650 580 ;
C -1 ; WX 600 ; N lcaron ; B 95 0 667 629 ;
C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 671 562 ;
C -1 ; WX 600 ; N Lacute ; B 47 0 607 805 ;
C -1 ; WX 600 ; N trademark ; B 75 263 742 562 ;
C -1 ; WX 600 ; N edotaccent ; B 106 -15 598 620 ;
C -1 ; WX 600 ; N Igrave ; B 96 0 623 805 ;
C -1 ; WX 600 ; N Imacron ; B 96 0 628 698 ;
C -1 ; WX 600 ; N Lcaron ; B 47 0 632 562 ;
C -1 ; WX 600 ; N onehalf ; B 65 -57 669 665 ;
C -1 ; WX 600 ; N lessequal ; B 98 0 645 710 ;
C -1 ; WX 600 ; N ocircumflex ; B 102 -15 588 654 ;
C -1 ; WX 600 ; N ntilde ; B 26 0 629 606 ;
C -1 ; WX 600 ; N Uhungarumlaut ; B 125 -18 761 805 ;
C -1 ; WX 600 ; N Eacute ; B 53 0 670 805 ;
C -1 ; WX 600 ; N emacron ; B 106 -15 600 565 ;
C -1 ; WX 600 ; N gbreve ; B 61 -157 657 609 ;
C -1 ; WX 600 ; N onequarter ; B 65 -57 674 665 ;
C -1 ; WX 600 ; N Scaron ; B 76 -20 672 802 ;
C -1 ; WX 600 ; N Scommaaccent ; B 76 -250 650 580 ;
C -1 ; WX 600 ; N Ohungarumlaut ; B 94 -18 751 805 ;
C -1 ; WX 600 ; N degree ; B 214 269 576 622 ;
C -1 ; WX 600 ; N ograve ; B 102 -15 588 672 ;
C -1 ; WX 600 ; N Ccaron ; B 93 -18 672 802 ;
C -1 ; WX 600 ; N ugrave ; B 101 -15 572 672 ;
C -1 ; WX 600 ; N radical ; B 85 -15 765 792 ;
C -1 ; WX 600 ; N Dcaron ; B 43 0 645 802 ;
C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 636 441 ;
C -1 ; WX 600 ; N Ntilde ; B 7 -13 712 729 ;
C -1 ; WX 600 ; N otilde ; B 102 -15 629 606 ;
C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 598 562 ;
C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 607 562 ;
C -1 ; WX 600 ; N Atilde ; B 3 0 655 729 ;
C -1 ; WX 600 ; N Aogonek ; B 3 -172 607 562 ;
C -1 ; WX 600 ; N Aring ; B 3 0 607 750 ;
C -1 ; WX 600 ; N Otilde ; B 94 -18 655 729 ;
C -1 ; WX 600 ; N zdotaccent ; B 99 0 593 620 ;
C -1 ; WX 600 ; N Ecaron ; B 53 0 660 802 ;
C -1 ; WX 600 ; N Iogonek ; B 96 -172 623 562 ;
C -1 ; WX 600 ; N kcommaaccent ; B 58 -250 633 629 ;
C -1 ; WX 600 ; N minus ; B 129 232 580 283 ;
C -1 ; WX 600 ; N Icircumflex ; B 96 0 623 787 ;
C -1 ; WX 600 ; N ncaron ; B 26 0 614 669 ;
C -1 ; WX 600 ; N tcommaaccent ; B 165 -250 561 561 ;
C -1 ; WX 600 ; N logicalnot ; B 155 108 591 369 ;
C -1 ; WX 600 ; N odieresis ; B 102 -15 588 620 ;
C -1 ; WX 600 ; N udieresis ; B 101 -15 575 620 ;
C -1 ; WX 600 ; N notequal ; B 43 -16 621 529 ;
C -1 ; WX 600 ; N gcommaaccent ; B 61 -157 657 708 ;
C -1 ; WX 600 ; N eth ; B 102 -15 639 629 ;
C -1 ; WX 600 ; N zcaron ; B 99 0 624 669 ;
C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 585 441 ;
C -1 ; WX 600 ; N onesuperior ; B 231 249 491 622 ;
C -1 ; WX 600 ; N imacron ; B 95 0 543 565 ;
C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ;
EndCharMetrics
EndFontMetrics

View File

@@ -0,0 +1,342 @@
StartFontMetrics 4.1
Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
Comment Creation Date: Thu May 1 17:27:09 1997
Comment UniqueID 43050
Comment VMusage 39754 50779
FontName Courier
FullName Courier
FamilyName Courier
Weight Medium
ItalicAngle 0
IsFixedPitch true
CharacterSet ExtendedRoman
FontBBox -23 -250 715 805
UnderlinePosition -100
UnderlineThickness 50
Version 003.000
Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
EncodingScheme AdobeStandardEncoding
CapHeight 562
XHeight 426
Ascender 629
Descender -157
StdHW 51
StdVW 51
StartCharMetrics 315
C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ;
C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ;
C 35 ; WX 600 ; N numbersign ; B 93 -32 507 639 ;
C 36 ; WX 600 ; N dollar ; B 105 -126 496 662 ;
C 37 ; WX 600 ; N percent ; B 81 -15 518 622 ;
C 38 ; WX 600 ; N ampersand ; B 63 -15 538 543 ;
C 39 ; WX 600 ; N quoteright ; B 213 328 376 562 ;
C 40 ; WX 600 ; N parenleft ; B 269 -108 440 622 ;
C 41 ; WX 600 ; N parenright ; B 160 -108 331 622 ;
C 42 ; WX 600 ; N asterisk ; B 116 257 484 607 ;
C 43 ; WX 600 ; N plus ; B 80 44 520 470 ;
C 44 ; WX 600 ; N comma ; B 181 -112 344 122 ;
C 45 ; WX 600 ; N hyphen ; B 103 231 497 285 ;
C 46 ; WX 600 ; N period ; B 229 -15 371 109 ;
C 47 ; WX 600 ; N slash ; B 125 -80 475 629 ;
C 48 ; WX 600 ; N zero ; B 106 -15 494 622 ;
C 49 ; WX 600 ; N one ; B 96 0 505 622 ;
C 50 ; WX 600 ; N two ; B 70 0 471 622 ;
C 51 ; WX 600 ; N three ; B 75 -15 466 622 ;
C 52 ; WX 600 ; N four ; B 78 0 500 622 ;
C 53 ; WX 600 ; N five ; B 92 -15 497 607 ;
C 54 ; WX 600 ; N six ; B 111 -15 497 622 ;
C 55 ; WX 600 ; N seven ; B 82 0 483 607 ;
C 56 ; WX 600 ; N eight ; B 102 -15 498 622 ;
C 57 ; WX 600 ; N nine ; B 96 -15 489 622 ;
C 58 ; WX 600 ; N colon ; B 229 -15 371 385 ;
C 59 ; WX 600 ; N semicolon ; B 181 -112 371 385 ;
C 60 ; WX 600 ; N less ; B 41 42 519 472 ;
C 61 ; WX 600 ; N equal ; B 80 138 520 376 ;
C 62 ; WX 600 ; N greater ; B 66 42 544 472 ;
C 63 ; WX 600 ; N question ; B 129 -15 492 572 ;
C 64 ; WX 600 ; N at ; B 77 -15 533 622 ;
C 65 ; WX 600 ; N A ; B 3 0 597 562 ;
C 66 ; WX 600 ; N B ; B 43 0 559 562 ;
C 67 ; WX 600 ; N C ; B 41 -18 540 580 ;
C 68 ; WX 600 ; N D ; B 43 0 574 562 ;
C 69 ; WX 600 ; N E ; B 53 0 550 562 ;
C 70 ; WX 600 ; N F ; B 53 0 545 562 ;
C 71 ; WX 600 ; N G ; B 31 -18 575 580 ;
C 72 ; WX 600 ; N H ; B 32 0 568 562 ;
C 73 ; WX 600 ; N I ; B 96 0 504 562 ;
C 74 ; WX 600 ; N J ; B 34 -18 566 562 ;
C 75 ; WX 600 ; N K ; B 38 0 582 562 ;
C 76 ; WX 600 ; N L ; B 47 0 554 562 ;
C 77 ; WX 600 ; N M ; B 4 0 596 562 ;
C 78 ; WX 600 ; N N ; B 7 -13 593 562 ;
C 79 ; WX 600 ; N O ; B 43 -18 557 580 ;
C 80 ; WX 600 ; N P ; B 79 0 558 562 ;
C 81 ; WX 600 ; N Q ; B 43 -138 557 580 ;
C 82 ; WX 600 ; N R ; B 38 0 588 562 ;
C 83 ; WX 600 ; N S ; B 72 -20 529 580 ;
C 84 ; WX 600 ; N T ; B 38 0 563 562 ;
C 85 ; WX 600 ; N U ; B 17 -18 583 562 ;
C 86 ; WX 600 ; N V ; B -4 -13 604 562 ;
C 87 ; WX 600 ; N W ; B -3 -13 603 562 ;
C 88 ; WX 600 ; N X ; B 23 0 577 562 ;
C 89 ; WX 600 ; N Y ; B 24 0 576 562 ;
C 90 ; WX 600 ; N Z ; B 86 0 514 562 ;
C 91 ; WX 600 ; N bracketleft ; B 269 -108 442 622 ;
C 92 ; WX 600 ; N backslash ; B 118 -80 482 629 ;
C 93 ; WX 600 ; N bracketright ; B 158 -108 331 622 ;
C 94 ; WX 600 ; N asciicircum ; B 94 354 506 622 ;
C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ;
C 96 ; WX 600 ; N quoteleft ; B 224 328 387 562 ;
C 97 ; WX 600 ; N a ; B 53 -15 559 441 ;
C 98 ; WX 600 ; N b ; B 14 -15 575 629 ;
C 99 ; WX 600 ; N c ; B 66 -15 529 441 ;
C 100 ; WX 600 ; N d ; B 45 -15 591 629 ;
C 101 ; WX 600 ; N e ; B 66 -15 548 441 ;
C 102 ; WX 600 ; N f ; B 114 0 531 629 ; L i fi ; L l fl ;
C 103 ; WX 600 ; N g ; B 45 -157 566 441 ;
C 104 ; WX 600 ; N h ; B 18 0 582 629 ;
C 105 ; WX 600 ; N i ; B 95 0 505 657 ;
C 106 ; WX 600 ; N j ; B 82 -157 410 657 ;
C 107 ; WX 600 ; N k ; B 43 0 580 629 ;
C 108 ; WX 600 ; N l ; B 95 0 505 629 ;
C 109 ; WX 600 ; N m ; B -5 0 605 441 ;
C 110 ; WX 600 ; N n ; B 26 0 575 441 ;
C 111 ; WX 600 ; N o ; B 62 -15 538 441 ;
C 112 ; WX 600 ; N p ; B 9 -157 555 441 ;
C 113 ; WX 600 ; N q ; B 45 -157 591 441 ;
C 114 ; WX 600 ; N r ; B 60 0 559 441 ;
C 115 ; WX 600 ; N s ; B 80 -15 513 441 ;
C 116 ; WX 600 ; N t ; B 87 -15 530 561 ;
C 117 ; WX 600 ; N u ; B 21 -15 562 426 ;
C 118 ; WX 600 ; N v ; B 10 -10 590 426 ;
C 119 ; WX 600 ; N w ; B -4 -10 604 426 ;
C 120 ; WX 600 ; N x ; B 20 0 580 426 ;
C 121 ; WX 600 ; N y ; B 7 -157 592 426 ;
C 122 ; WX 600 ; N z ; B 99 0 502 426 ;
C 123 ; WX 600 ; N braceleft ; B 182 -108 437 622 ;
C 124 ; WX 600 ; N bar ; B 275 -250 326 750 ;
C 125 ; WX 600 ; N braceright ; B 163 -108 418 622 ;
C 126 ; WX 600 ; N asciitilde ; B 63 197 540 320 ;
C 161 ; WX 600 ; N exclamdown ; B 236 -157 364 430 ;
C 162 ; WX 600 ; N cent ; B 96 -49 500 614 ;
C 163 ; WX 600 ; N sterling ; B 84 -21 521 611 ;
C 164 ; WX 600 ; N fraction ; B 92 -57 509 665 ;
C 165 ; WX 600 ; N yen ; B 26 0 574 562 ;
C 166 ; WX 600 ; N florin ; B 4 -143 539 622 ;
C 167 ; WX 600 ; N section ; B 113 -78 488 580 ;
C 168 ; WX 600 ; N currency ; B 73 58 527 506 ;
C 169 ; WX 600 ; N quotesingle ; B 259 328 341 562 ;
C 170 ; WX 600 ; N quotedblleft ; B 143 328 471 562 ;
C 171 ; WX 600 ; N guillemotleft ; B 37 70 563 446 ;
C 172 ; WX 600 ; N guilsinglleft ; B 149 70 451 446 ;
C 173 ; WX 600 ; N guilsinglright ; B 149 70 451 446 ;
C 174 ; WX 600 ; N fi ; B 3 0 597 629 ;
C 175 ; WX 600 ; N fl ; B 3 0 597 629 ;
C 177 ; WX 600 ; N endash ; B 75 231 525 285 ;
C 178 ; WX 600 ; N dagger ; B 141 -78 459 580 ;
C 179 ; WX 600 ; N daggerdbl ; B 141 -78 459 580 ;
C 180 ; WX 600 ; N periodcentered ; B 222 189 378 327 ;
C 182 ; WX 600 ; N paragraph ; B 50 -78 511 562 ;
C 183 ; WX 600 ; N bullet ; B 172 130 428 383 ;
C 184 ; WX 600 ; N quotesinglbase ; B 213 -134 376 100 ;
C 185 ; WX 600 ; N quotedblbase ; B 143 -134 457 100 ;
C 186 ; WX 600 ; N quotedblright ; B 143 328 457 562 ;
C 187 ; WX 600 ; N guillemotright ; B 37 70 563 446 ;
C 188 ; WX 600 ; N ellipsis ; B 37 -15 563 111 ;
C 189 ; WX 600 ; N perthousand ; B 3 -15 600 622 ;
C 191 ; WX 600 ; N questiondown ; B 108 -157 471 430 ;
C 193 ; WX 600 ; N grave ; B 151 497 378 672 ;
C 194 ; WX 600 ; N acute ; B 242 497 469 672 ;
C 195 ; WX 600 ; N circumflex ; B 124 477 476 654 ;
C 196 ; WX 600 ; N tilde ; B 105 489 503 606 ;
C 197 ; WX 600 ; N macron ; B 120 525 480 565 ;
C 198 ; WX 600 ; N breve ; B 153 501 447 609 ;
C 199 ; WX 600 ; N dotaccent ; B 249 537 352 640 ;
C 200 ; WX 600 ; N dieresis ; B 148 537 453 640 ;
C 202 ; WX 600 ; N ring ; B 218 463 382 627 ;
C 203 ; WX 600 ; N cedilla ; B 224 -151 362 10 ;
C 205 ; WX 600 ; N hungarumlaut ; B 133 497 540 672 ;
C 206 ; WX 600 ; N ogonek ; B 211 -172 407 4 ;
C 207 ; WX 600 ; N caron ; B 124 492 476 669 ;
C 208 ; WX 600 ; N emdash ; B 0 231 600 285 ;
C 225 ; WX 600 ; N AE ; B 3 0 550 562 ;
C 227 ; WX 600 ; N ordfeminine ; B 156 249 442 580 ;
C 232 ; WX 600 ; N Lslash ; B 47 0 554 562 ;
C 233 ; WX 600 ; N Oslash ; B 43 -80 557 629 ;
C 234 ; WX 600 ; N OE ; B 7 0 567 562 ;
C 235 ; WX 600 ; N ordmasculine ; B 157 249 443 580 ;
C 241 ; WX 600 ; N ae ; B 19 -15 570 441 ;
C 245 ; WX 600 ; N dotlessi ; B 95 0 505 426 ;
C 248 ; WX 600 ; N lslash ; B 95 0 505 629 ;
C 249 ; WX 600 ; N oslash ; B 62 -80 538 506 ;
C 250 ; WX 600 ; N oe ; B 19 -15 559 441 ;
C 251 ; WX 600 ; N germandbls ; B 48 -15 588 629 ;
C -1 ; WX 600 ; N Idieresis ; B 96 0 504 753 ;
C -1 ; WX 600 ; N eacute ; B 66 -15 548 672 ;
C -1 ; WX 600 ; N abreve ; B 53 -15 559 609 ;
C -1 ; WX 600 ; N uhungarumlaut ; B 21 -15 580 672 ;
C -1 ; WX 600 ; N ecaron ; B 66 -15 548 669 ;
C -1 ; WX 600 ; N Ydieresis ; B 24 0 576 753 ;
C -1 ; WX 600 ; N divide ; B 87 48 513 467 ;
C -1 ; WX 600 ; N Yacute ; B 24 0 576 805 ;
C -1 ; WX 600 ; N Acircumflex ; B 3 0 597 787 ;
C -1 ; WX 600 ; N aacute ; B 53 -15 559 672 ;
C -1 ; WX 600 ; N Ucircumflex ; B 17 -18 583 787 ;
C -1 ; WX 600 ; N yacute ; B 7 -157 592 672 ;
C -1 ; WX 600 ; N scommaaccent ; B 80 -250 513 441 ;
C -1 ; WX 600 ; N ecircumflex ; B 66 -15 548 654 ;
C -1 ; WX 600 ; N Uring ; B 17 -18 583 760 ;
C -1 ; WX 600 ; N Udieresis ; B 17 -18 583 753 ;
C -1 ; WX 600 ; N aogonek ; B 53 -172 587 441 ;
C -1 ; WX 600 ; N Uacute ; B 17 -18 583 805 ;
C -1 ; WX 600 ; N uogonek ; B 21 -172 590 426 ;
C -1 ; WX 600 ; N Edieresis ; B 53 0 550 753 ;
C -1 ; WX 600 ; N Dcroat ; B 30 0 574 562 ;
C -1 ; WX 600 ; N commaaccent ; B 198 -250 335 -58 ;
C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ;
C -1 ; WX 600 ; N Emacron ; B 53 0 550 698 ;
C -1 ; WX 600 ; N ccaron ; B 66 -15 529 669 ;
C -1 ; WX 600 ; N aring ; B 53 -15 559 627 ;
C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 593 562 ;
C -1 ; WX 600 ; N lacute ; B 95 0 505 805 ;
C -1 ; WX 600 ; N agrave ; B 53 -15 559 672 ;
C -1 ; WX 600 ; N Tcommaaccent ; B 38 -250 563 562 ;
C -1 ; WX 600 ; N Cacute ; B 41 -18 540 805 ;
C -1 ; WX 600 ; N atilde ; B 53 -15 559 606 ;
C -1 ; WX 600 ; N Edotaccent ; B 53 0 550 753 ;
C -1 ; WX 600 ; N scaron ; B 80 -15 513 669 ;
C -1 ; WX 600 ; N scedilla ; B 80 -151 513 441 ;
C -1 ; WX 600 ; N iacute ; B 95 0 505 672 ;
C -1 ; WX 600 ; N lozenge ; B 18 0 443 706 ;
C -1 ; WX 600 ; N Rcaron ; B 38 0 588 802 ;
C -1 ; WX 600 ; N Gcommaaccent ; B 31 -250 575 580 ;
C -1 ; WX 600 ; N ucircumflex ; B 21 -15 562 654 ;
C -1 ; WX 600 ; N acircumflex ; B 53 -15 559 654 ;
C -1 ; WX 600 ; N Amacron ; B 3 0 597 698 ;
C -1 ; WX 600 ; N rcaron ; B 60 0 559 669 ;
C -1 ; WX 600 ; N ccedilla ; B 66 -151 529 441 ;
C -1 ; WX 600 ; N Zdotaccent ; B 86 0 514 753 ;
C -1 ; WX 600 ; N Thorn ; B 79 0 538 562 ;
C -1 ; WX 600 ; N Omacron ; B 43 -18 557 698 ;
C -1 ; WX 600 ; N Racute ; B 38 0 588 805 ;
C -1 ; WX 600 ; N Sacute ; B 72 -20 529 805 ;
C -1 ; WX 600 ; N dcaron ; B 45 -15 715 629 ;
C -1 ; WX 600 ; N Umacron ; B 17 -18 583 698 ;
C -1 ; WX 600 ; N uring ; B 21 -15 562 627 ;
C -1 ; WX 600 ; N threesuperior ; B 155 240 406 622 ;
C -1 ; WX 600 ; N Ograve ; B 43 -18 557 805 ;
C -1 ; WX 600 ; N Agrave ; B 3 0 597 805 ;
C -1 ; WX 600 ; N Abreve ; B 3 0 597 732 ;
C -1 ; WX 600 ; N multiply ; B 87 43 515 470 ;
C -1 ; WX 600 ; N uacute ; B 21 -15 562 672 ;
C -1 ; WX 600 ; N Tcaron ; B 38 0 563 802 ;
C -1 ; WX 600 ; N partialdiff ; B 17 -38 459 710 ;
C -1 ; WX 600 ; N ydieresis ; B 7 -157 592 620 ;
C -1 ; WX 600 ; N Nacute ; B 7 -13 593 805 ;
C -1 ; WX 600 ; N icircumflex ; B 94 0 505 654 ;
C -1 ; WX 600 ; N Ecircumflex ; B 53 0 550 787 ;
C -1 ; WX 600 ; N adieresis ; B 53 -15 559 620 ;
C -1 ; WX 600 ; N edieresis ; B 66 -15 548 620 ;
C -1 ; WX 600 ; N cacute ; B 66 -15 529 672 ;
C -1 ; WX 600 ; N nacute ; B 26 0 575 672 ;
C -1 ; WX 600 ; N umacron ; B 21 -15 562 565 ;
C -1 ; WX 600 ; N Ncaron ; B 7 -13 593 802 ;
C -1 ; WX 600 ; N Iacute ; B 96 0 504 805 ;
C -1 ; WX 600 ; N plusminus ; B 87 44 513 558 ;
C -1 ; WX 600 ; N brokenbar ; B 275 -175 326 675 ;
C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ;
C -1 ; WX 600 ; N Gbreve ; B 31 -18 575 732 ;
C -1 ; WX 600 ; N Idotaccent ; B 96 0 504 753 ;
C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ;
C -1 ; WX 600 ; N Egrave ; B 53 0 550 805 ;
C -1 ; WX 600 ; N racute ; B 60 0 559 672 ;
C -1 ; WX 600 ; N omacron ; B 62 -15 538 565 ;
C -1 ; WX 600 ; N Zacute ; B 86 0 514 805 ;
C -1 ; WX 600 ; N Zcaron ; B 86 0 514 802 ;
C -1 ; WX 600 ; N greaterequal ; B 98 0 502 710 ;
C -1 ; WX 600 ; N Eth ; B 30 0 574 562 ;
C -1 ; WX 600 ; N Ccedilla ; B 41 -151 540 580 ;
C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 505 629 ;
C -1 ; WX 600 ; N tcaron ; B 87 -15 530 717 ;
C -1 ; WX 600 ; N eogonek ; B 66 -172 548 441 ;
C -1 ; WX 600 ; N Uogonek ; B 17 -172 583 562 ;
C -1 ; WX 600 ; N Aacute ; B 3 0 597 805 ;
C -1 ; WX 600 ; N Adieresis ; B 3 0 597 753 ;
C -1 ; WX 600 ; N egrave ; B 66 -15 548 672 ;
C -1 ; WX 600 ; N zacute ; B 99 0 502 672 ;
C -1 ; WX 600 ; N iogonek ; B 95 -172 505 657 ;
C -1 ; WX 600 ; N Oacute ; B 43 -18 557 805 ;
C -1 ; WX 600 ; N oacute ; B 62 -15 538 672 ;
C -1 ; WX 600 ; N amacron ; B 53 -15 559 565 ;
C -1 ; WX 600 ; N sacute ; B 80 -15 513 672 ;
C -1 ; WX 600 ; N idieresis ; B 95 0 505 620 ;
C -1 ; WX 600 ; N Ocircumflex ; B 43 -18 557 787 ;
C -1 ; WX 600 ; N Ugrave ; B 17 -18 583 805 ;
C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ;
C -1 ; WX 600 ; N thorn ; B -6 -157 555 629 ;
C -1 ; WX 600 ; N twosuperior ; B 177 249 424 622 ;
C -1 ; WX 600 ; N Odieresis ; B 43 -18 557 753 ;
C -1 ; WX 600 ; N mu ; B 21 -157 562 426 ;
C -1 ; WX 600 ; N igrave ; B 95 0 505 672 ;
C -1 ; WX 600 ; N ohungarumlaut ; B 62 -15 580 672 ;
C -1 ; WX 600 ; N Eogonek ; B 53 -172 561 562 ;
C -1 ; WX 600 ; N dcroat ; B 45 -15 591 629 ;
C -1 ; WX 600 ; N threequarters ; B 8 -56 593 666 ;
C -1 ; WX 600 ; N Scedilla ; B 72 -151 529 580 ;
C -1 ; WX 600 ; N lcaron ; B 95 0 533 629 ;
C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 582 562 ;
C -1 ; WX 600 ; N Lacute ; B 47 0 554 805 ;
C -1 ; WX 600 ; N trademark ; B -23 263 623 562 ;
C -1 ; WX 600 ; N edotaccent ; B 66 -15 548 620 ;
C -1 ; WX 600 ; N Igrave ; B 96 0 504 805 ;
C -1 ; WX 600 ; N Imacron ; B 96 0 504 698 ;
C -1 ; WX 600 ; N Lcaron ; B 47 0 554 562 ;
C -1 ; WX 600 ; N onehalf ; B 0 -57 611 665 ;
C -1 ; WX 600 ; N lessequal ; B 98 0 502 710 ;
C -1 ; WX 600 ; N ocircumflex ; B 62 -15 538 654 ;
C -1 ; WX 600 ; N ntilde ; B 26 0 575 606 ;
C -1 ; WX 600 ; N Uhungarumlaut ; B 17 -18 590 805 ;
C -1 ; WX 600 ; N Eacute ; B 53 0 550 805 ;
C -1 ; WX 600 ; N emacron ; B 66 -15 548 565 ;
C -1 ; WX 600 ; N gbreve ; B 45 -157 566 609 ;
C -1 ; WX 600 ; N onequarter ; B 0 -57 600 665 ;
C -1 ; WX 600 ; N Scaron ; B 72 -20 529 802 ;
C -1 ; WX 600 ; N Scommaaccent ; B 72 -250 529 580 ;
C -1 ; WX 600 ; N Ohungarumlaut ; B 43 -18 580 805 ;
C -1 ; WX 600 ; N degree ; B 123 269 477 622 ;
C -1 ; WX 600 ; N ograve ; B 62 -15 538 672 ;
C -1 ; WX 600 ; N Ccaron ; B 41 -18 540 802 ;
C -1 ; WX 600 ; N ugrave ; B 21 -15 562 672 ;
C -1 ; WX 600 ; N radical ; B 3 -15 597 792 ;
C -1 ; WX 600 ; N Dcaron ; B 43 0 574 802 ;
C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 559 441 ;
C -1 ; WX 600 ; N Ntilde ; B 7 -13 593 729 ;
C -1 ; WX 600 ; N otilde ; B 62 -15 538 606 ;
C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 588 562 ;
C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 554 562 ;
C -1 ; WX 600 ; N Atilde ; B 3 0 597 729 ;
C -1 ; WX 600 ; N Aogonek ; B 3 -172 608 562 ;
C -1 ; WX 600 ; N Aring ; B 3 0 597 750 ;
C -1 ; WX 600 ; N Otilde ; B 43 -18 557 729 ;
C -1 ; WX 600 ; N zdotaccent ; B 99 0 502 620 ;
C -1 ; WX 600 ; N Ecaron ; B 53 0 550 802 ;
C -1 ; WX 600 ; N Iogonek ; B 96 -172 504 562 ;
C -1 ; WX 600 ; N kcommaaccent ; B 43 -250 580 629 ;
C -1 ; WX 600 ; N minus ; B 80 232 520 283 ;
C -1 ; WX 600 ; N Icircumflex ; B 96 0 504 787 ;
C -1 ; WX 600 ; N ncaron ; B 26 0 575 669 ;
C -1 ; WX 600 ; N tcommaaccent ; B 87 -250 530 561 ;
C -1 ; WX 600 ; N logicalnot ; B 87 108 513 369 ;
C -1 ; WX 600 ; N odieresis ; B 62 -15 538 620 ;
C -1 ; WX 600 ; N udieresis ; B 21 -15 562 620 ;
C -1 ; WX 600 ; N notequal ; B 15 -16 540 529 ;
C -1 ; WX 600 ; N gcommaaccent ; B 45 -157 566 708 ;
C -1 ; WX 600 ; N eth ; B 62 -15 538 629 ;
C -1 ; WX 600 ; N zcaron ; B 99 0 502 669 ;
C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 575 441 ;
C -1 ; WX 600 ; N onesuperior ; B 172 249 428 622 ;
C -1 ; WX 600 ; N imacron ; B 95 0 505 565 ;
C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ;
EndCharMetrics
EndFontMetrics

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
<html>

View File

@@ -0,0 +1,213 @@
StartFontMetrics 4.1
Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All rights reserved.
Comment Creation Date: Thu May 1 15:12:25 1997
Comment UniqueID 43064
Comment VMusage 30820 39997
FontName Symbol
FullName Symbol
FamilyName Symbol
Weight Medium
ItalicAngle 0
IsFixedPitch false
CharacterSet Special
FontBBox -180 -293 1090 1010
UnderlinePosition -100
UnderlineThickness 50
Version 001.008
Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All rights reserved.
EncodingScheme FontSpecific
StdHW 92
StdVW 85
StartCharMetrics 190
C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
C 33 ; WX 333 ; N exclam ; B 128 -17 240 672 ;
C 34 ; WX 713 ; N universal ; B 31 0 681 705 ;
C 35 ; WX 500 ; N numbersign ; B 20 -16 481 673 ;
C 36 ; WX 549 ; N existential ; B 25 0 478 707 ;
C 37 ; WX 833 ; N percent ; B 63 -36 771 655 ;
C 38 ; WX 778 ; N ampersand ; B 41 -18 750 661 ;
C 39 ; WX 439 ; N suchthat ; B 48 -17 414 500 ;
C 40 ; WX 333 ; N parenleft ; B 53 -191 300 673 ;
C 41 ; WX 333 ; N parenright ; B 30 -191 277 673 ;
C 42 ; WX 500 ; N asteriskmath ; B 65 134 427 551 ;
C 43 ; WX 549 ; N plus ; B 10 0 539 533 ;
C 44 ; WX 250 ; N comma ; B 56 -152 194 104 ;
C 45 ; WX 549 ; N minus ; B 11 233 535 288 ;
C 46 ; WX 250 ; N period ; B 69 -17 181 95 ;
C 47 ; WX 278 ; N slash ; B 0 -18 254 646 ;
C 48 ; WX 500 ; N zero ; B 24 -14 476 685 ;
C 49 ; WX 500 ; N one ; B 117 0 390 673 ;
C 50 ; WX 500 ; N two ; B 25 0 475 685 ;
C 51 ; WX 500 ; N three ; B 43 -14 435 685 ;
C 52 ; WX 500 ; N four ; B 15 0 469 685 ;
C 53 ; WX 500 ; N five ; B 32 -14 445 690 ;
C 54 ; WX 500 ; N six ; B 34 -14 468 685 ;
C 55 ; WX 500 ; N seven ; B 24 -16 448 673 ;
C 56 ; WX 500 ; N eight ; B 56 -14 445 685 ;
C 57 ; WX 500 ; N nine ; B 30 -18 459 685 ;
C 58 ; WX 278 ; N colon ; B 81 -17 193 460 ;
C 59 ; WX 278 ; N semicolon ; B 83 -152 221 460 ;
C 60 ; WX 549 ; N less ; B 26 0 523 522 ;
C 61 ; WX 549 ; N equal ; B 11 141 537 390 ;
C 62 ; WX 549 ; N greater ; B 26 0 523 522 ;
C 63 ; WX 444 ; N question ; B 70 -17 412 686 ;
C 64 ; WX 549 ; N congruent ; B 11 0 537 475 ;
C 65 ; WX 722 ; N Alpha ; B 4 0 684 673 ;
C 66 ; WX 667 ; N Beta ; B 29 0 592 673 ;
C 67 ; WX 722 ; N Chi ; B -9 0 704 673 ;
C 68 ; WX 612 ; N Delta ; B 6 0 608 688 ;
C 69 ; WX 611 ; N Epsilon ; B 32 0 617 673 ;
C 70 ; WX 763 ; N Phi ; B 26 0 741 673 ;
C 71 ; WX 603 ; N Gamma ; B 24 0 609 673 ;
C 72 ; WX 722 ; N Eta ; B 39 0 729 673 ;
C 73 ; WX 333 ; N Iota ; B 32 0 316 673 ;
C 74 ; WX 631 ; N theta1 ; B 18 -18 623 689 ;
C 75 ; WX 722 ; N Kappa ; B 35 0 722 673 ;
C 76 ; WX 686 ; N Lambda ; B 6 0 680 688 ;
C 77 ; WX 889 ; N Mu ; B 28 0 887 673 ;
C 78 ; WX 722 ; N Nu ; B 29 -8 720 673 ;
C 79 ; WX 722 ; N Omicron ; B 41 -17 715 685 ;
C 80 ; WX 768 ; N Pi ; B 25 0 745 673 ;
C 81 ; WX 741 ; N Theta ; B 41 -17 715 685 ;
C 82 ; WX 556 ; N Rho ; B 28 0 563 673 ;
C 83 ; WX 592 ; N Sigma ; B 5 0 589 673 ;
C 84 ; WX 611 ; N Tau ; B 33 0 607 673 ;
C 85 ; WX 690 ; N Upsilon ; B -8 0 694 673 ;
C 86 ; WX 439 ; N sigma1 ; B 40 -233 436 500 ;
C 87 ; WX 768 ; N Omega ; B 34 0 736 688 ;
C 88 ; WX 645 ; N Xi ; B 40 0 599 673 ;
C 89 ; WX 795 ; N Psi ; B 15 0 781 684 ;
C 90 ; WX 611 ; N Zeta ; B 44 0 636 673 ;
C 91 ; WX 333 ; N bracketleft ; B 86 -155 299 674 ;
C 92 ; WX 863 ; N therefore ; B 163 0 701 487 ;
C 93 ; WX 333 ; N bracketright ; B 33 -155 246 674 ;
C 94 ; WX 658 ; N perpendicular ; B 15 0 652 674 ;
C 95 ; WX 500 ; N underscore ; B -2 -125 502 -75 ;
C 96 ; WX 500 ; N radicalex ; B 480 881 1090 917 ;
C 97 ; WX 631 ; N alpha ; B 41 -18 622 500 ;
C 98 ; WX 549 ; N beta ; B 61 -223 515 741 ;
C 99 ; WX 549 ; N chi ; B 12 -231 522 499 ;
C 100 ; WX 494 ; N delta ; B 40 -19 481 740 ;
C 101 ; WX 439 ; N epsilon ; B 22 -19 427 502 ;
C 102 ; WX 521 ; N phi ; B 28 -224 492 673 ;
C 103 ; WX 411 ; N gamma ; B 5 -225 484 499 ;
C 104 ; WX 603 ; N eta ; B 0 -202 527 514 ;
C 105 ; WX 329 ; N iota ; B 0 -17 301 503 ;
C 106 ; WX 603 ; N phi1 ; B 36 -224 587 499 ;
C 107 ; WX 549 ; N kappa ; B 33 0 558 501 ;
C 108 ; WX 549 ; N lambda ; B 24 -17 548 739 ;
C 109 ; WX 576 ; N mu ; B 33 -223 567 500 ;
C 110 ; WX 521 ; N nu ; B -9 -16 475 507 ;
C 111 ; WX 549 ; N omicron ; B 35 -19 501 499 ;
C 112 ; WX 549 ; N pi ; B 10 -19 530 487 ;
C 113 ; WX 521 ; N theta ; B 43 -17 485 690 ;
C 114 ; WX 549 ; N rho ; B 50 -230 490 499 ;
C 115 ; WX 603 ; N sigma ; B 30 -21 588 500 ;
C 116 ; WX 439 ; N tau ; B 10 -19 418 500 ;
C 117 ; WX 576 ; N upsilon ; B 7 -18 535 507 ;
C 118 ; WX 713 ; N omega1 ; B 12 -18 671 583 ;
C 119 ; WX 686 ; N omega ; B 42 -17 684 500 ;
C 120 ; WX 493 ; N xi ; B 27 -224 469 766 ;
C 121 ; WX 686 ; N psi ; B 12 -228 701 500 ;
C 122 ; WX 494 ; N zeta ; B 60 -225 467 756 ;
C 123 ; WX 480 ; N braceleft ; B 58 -183 397 673 ;
C 124 ; WX 200 ; N bar ; B 65 -293 135 707 ;
C 125 ; WX 480 ; N braceright ; B 79 -183 418 673 ;
C 126 ; WX 549 ; N similar ; B 17 203 529 307 ;
C 160 ; WX 750 ; N Euro ; B 20 -12 714 685 ;
C 161 ; WX 620 ; N Upsilon1 ; B -2 0 610 685 ;
C 162 ; WX 247 ; N minute ; B 27 459 228 735 ;
C 163 ; WX 549 ; N lessequal ; B 29 0 526 639 ;
C 164 ; WX 167 ; N fraction ; B -180 -12 340 677 ;
C 165 ; WX 713 ; N infinity ; B 26 124 688 404 ;
C 166 ; WX 500 ; N florin ; B 2 -193 494 686 ;
C 167 ; WX 753 ; N club ; B 86 -26 660 533 ;
C 168 ; WX 753 ; N diamond ; B 142 -36 600 550 ;
C 169 ; WX 753 ; N heart ; B 117 -33 631 532 ;
C 170 ; WX 753 ; N spade ; B 113 -36 629 548 ;
C 171 ; WX 1042 ; N arrowboth ; B 24 -15 1024 511 ;
C 172 ; WX 987 ; N arrowleft ; B 32 -15 942 511 ;
C 173 ; WX 603 ; N arrowup ; B 45 0 571 910 ;
C 174 ; WX 987 ; N arrowright ; B 49 -15 959 511 ;
C 175 ; WX 603 ; N arrowdown ; B 45 -22 571 888 ;
C 176 ; WX 400 ; N degree ; B 50 385 350 685 ;
C 177 ; WX 549 ; N plusminus ; B 10 0 539 645 ;
C 178 ; WX 411 ; N second ; B 20 459 413 737 ;
C 179 ; WX 549 ; N greaterequal ; B 29 0 526 639 ;
C 180 ; WX 549 ; N multiply ; B 17 8 533 524 ;
C 181 ; WX 713 ; N proportional ; B 27 123 639 404 ;
C 182 ; WX 494 ; N partialdiff ; B 26 -20 462 746 ;
C 183 ; WX 460 ; N bullet ; B 50 113 410 473 ;
C 184 ; WX 549 ; N divide ; B 10 71 536 456 ;
C 185 ; WX 549 ; N notequal ; B 15 -25 540 549 ;
C 186 ; WX 549 ; N equivalence ; B 14 82 538 443 ;
C 187 ; WX 549 ; N approxequal ; B 14 135 527 394 ;
C 188 ; WX 1000 ; N ellipsis ; B 111 -17 889 95 ;
C 189 ; WX 603 ; N arrowvertex ; B 280 -120 336 1010 ;
C 190 ; WX 1000 ; N arrowhorizex ; B -60 220 1050 276 ;
C 191 ; WX 658 ; N carriagereturn ; B 15 -16 602 629 ;
C 192 ; WX 823 ; N aleph ; B 175 -18 661 658 ;
C 193 ; WX 686 ; N Ifraktur ; B 10 -53 578 740 ;
C 194 ; WX 795 ; N Rfraktur ; B 26 -15 759 734 ;
C 195 ; WX 987 ; N weierstrass ; B 159 -211 870 573 ;
C 196 ; WX 768 ; N circlemultiply ; B 43 -17 733 673 ;
C 197 ; WX 768 ; N circleplus ; B 43 -15 733 675 ;
C 198 ; WX 823 ; N emptyset ; B 39 -24 781 719 ;
C 199 ; WX 768 ; N intersection ; B 40 0 732 509 ;
C 200 ; WX 768 ; N union ; B 40 -17 732 492 ;
C 201 ; WX 713 ; N propersuperset ; B 20 0 673 470 ;
C 202 ; WX 713 ; N reflexsuperset ; B 20 -125 673 470 ;
C 203 ; WX 713 ; N notsubset ; B 36 -70 690 540 ;
C 204 ; WX 713 ; N propersubset ; B 37 0 690 470 ;
C 205 ; WX 713 ; N reflexsubset ; B 37 -125 690 470 ;
C 206 ; WX 713 ; N element ; B 45 0 505 468 ;
C 207 ; WX 713 ; N notelement ; B 45 -58 505 555 ;
C 208 ; WX 768 ; N angle ; B 26 0 738 673 ;
C 209 ; WX 713 ; N gradient ; B 36 -19 681 718 ;
C 210 ; WX 790 ; N registerserif ; B 50 -17 740 673 ;
C 211 ; WX 790 ; N copyrightserif ; B 51 -15 741 675 ;
C 212 ; WX 890 ; N trademarkserif ; B 18 293 855 673 ;
C 213 ; WX 823 ; N product ; B 25 -101 803 751 ;
C 214 ; WX 549 ; N radical ; B 10 -38 515 917 ;
C 215 ; WX 250 ; N dotmath ; B 69 210 169 310 ;
C 216 ; WX 713 ; N logicalnot ; B 15 0 680 288 ;
C 217 ; WX 603 ; N logicaland ; B 23 0 583 454 ;
C 218 ; WX 603 ; N logicalor ; B 30 0 578 477 ;
C 219 ; WX 1042 ; N arrowdblboth ; B 27 -20 1023 510 ;
C 220 ; WX 987 ; N arrowdblleft ; B 30 -15 939 513 ;
C 221 ; WX 603 ; N arrowdblup ; B 39 2 567 911 ;
C 222 ; WX 987 ; N arrowdblright ; B 45 -20 954 508 ;
C 223 ; WX 603 ; N arrowdbldown ; B 44 -19 572 890 ;
C 224 ; WX 494 ; N lozenge ; B 18 0 466 745 ;
C 225 ; WX 329 ; N angleleft ; B 25 -198 306 746 ;
C 226 ; WX 790 ; N registersans ; B 50 -20 740 670 ;
C 227 ; WX 790 ; N copyrightsans ; B 49 -15 739 675 ;
C 228 ; WX 786 ; N trademarksans ; B 5 293 725 673 ;
C 229 ; WX 713 ; N summation ; B 14 -108 695 752 ;
C 230 ; WX 384 ; N parenlefttp ; B 24 -293 436 926 ;
C 231 ; WX 384 ; N parenleftex ; B 24 -85 108 925 ;
C 232 ; WX 384 ; N parenleftbt ; B 24 -293 436 926 ;
C 233 ; WX 384 ; N bracketlefttp ; B 0 -80 349 926 ;
C 234 ; WX 384 ; N bracketleftex ; B 0 -79 77 925 ;
C 235 ; WX 384 ; N bracketleftbt ; B 0 -80 349 926 ;
C 236 ; WX 494 ; N bracelefttp ; B 209 -85 445 925 ;
C 237 ; WX 494 ; N braceleftmid ; B 20 -85 284 935 ;
C 238 ; WX 494 ; N braceleftbt ; B 209 -75 445 935 ;
C 239 ; WX 494 ; N braceex ; B 209 -85 284 935 ;
C 241 ; WX 329 ; N angleright ; B 21 -198 302 746 ;
C 242 ; WX 274 ; N integral ; B 2 -107 291 916 ;
C 243 ; WX 686 ; N integraltp ; B 308 -88 675 920 ;
C 244 ; WX 686 ; N integralex ; B 308 -88 378 975 ;
C 245 ; WX 686 ; N integralbt ; B 11 -87 378 921 ;
C 246 ; WX 384 ; N parenrighttp ; B 54 -293 466 926 ;
C 247 ; WX 384 ; N parenrightex ; B 382 -85 466 925 ;
C 248 ; WX 384 ; N parenrightbt ; B 54 -293 466 926 ;
C 249 ; WX 384 ; N bracketrighttp ; B 22 -80 371 926 ;
C 250 ; WX 384 ; N bracketrightex ; B 294 -79 371 925 ;
C 251 ; WX 384 ; N bracketrightbt ; B 22 -80 371 926 ;
C 252 ; WX 494 ; N bracerighttp ; B 48 -85 284 925 ;
C 253 ; WX 494 ; N bracerightmid ; B 209 -85 473 935 ;
C 254 ; WX 494 ; N bracerightbt ; B 48 -75 284 935 ;
C -1 ; WX 790 ; N apple ; B 56 -3 733 808 ;
EndCharMetrics
EndFontMetrics

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,225 @@
StartFontMetrics 4.1
Comment Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved.
Comment Creation Date: Thu May 1 15:14:13 1997
Comment UniqueID 43082
Comment VMusage 45775 55535
FontName ZapfDingbats
FullName ITC Zapf Dingbats
FamilyName ZapfDingbats
Weight Medium
ItalicAngle 0
IsFixedPitch false
CharacterSet Special
FontBBox -1 -143 981 820
UnderlinePosition -100
UnderlineThickness 50
Version 002.000
Notice Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved.ITC Zapf Dingbats is a registered trademark of International Typeface Corporation.
EncodingScheme FontSpecific
StdHW 28
StdVW 90
StartCharMetrics 202
C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
C 33 ; WX 974 ; N a1 ; B 35 72 939 621 ;
C 34 ; WX 961 ; N a2 ; B 35 81 927 611 ;
C 35 ; WX 974 ; N a202 ; B 35 72 939 621 ;
C 36 ; WX 980 ; N a3 ; B 35 0 945 692 ;
C 37 ; WX 719 ; N a4 ; B 34 139 685 566 ;
C 38 ; WX 789 ; N a5 ; B 35 -14 755 705 ;
C 39 ; WX 790 ; N a119 ; B 35 -14 755 705 ;
C 40 ; WX 791 ; N a118 ; B 35 -13 761 705 ;
C 41 ; WX 690 ; N a117 ; B 34 138 655 553 ;
C 42 ; WX 960 ; N a11 ; B 35 123 925 568 ;
C 43 ; WX 939 ; N a12 ; B 35 134 904 559 ;
C 44 ; WX 549 ; N a13 ; B 29 -11 516 705 ;
C 45 ; WX 855 ; N a14 ; B 34 59 820 632 ;
C 46 ; WX 911 ; N a15 ; B 35 50 876 642 ;
C 47 ; WX 933 ; N a16 ; B 35 139 899 550 ;
C 48 ; WX 911 ; N a105 ; B 35 50 876 642 ;
C 49 ; WX 945 ; N a17 ; B 35 139 909 553 ;
C 50 ; WX 974 ; N a18 ; B 35 104 938 587 ;
C 51 ; WX 755 ; N a19 ; B 34 -13 721 705 ;
C 52 ; WX 846 ; N a20 ; B 36 -14 811 705 ;
C 53 ; WX 762 ; N a21 ; B 35 0 727 692 ;
C 54 ; WX 761 ; N a22 ; B 35 0 727 692 ;
C 55 ; WX 571 ; N a23 ; B -1 -68 571 661 ;
C 56 ; WX 677 ; N a24 ; B 36 -13 642 705 ;
C 57 ; WX 763 ; N a25 ; B 35 0 728 692 ;
C 58 ; WX 760 ; N a26 ; B 35 0 726 692 ;
C 59 ; WX 759 ; N a27 ; B 35 0 725 692 ;
C 60 ; WX 754 ; N a28 ; B 35 0 720 692 ;
C 61 ; WX 494 ; N a6 ; B 35 0 460 692 ;
C 62 ; WX 552 ; N a7 ; B 35 0 517 692 ;
C 63 ; WX 537 ; N a8 ; B 35 0 503 692 ;
C 64 ; WX 577 ; N a9 ; B 35 96 542 596 ;
C 65 ; WX 692 ; N a10 ; B 35 -14 657 705 ;
C 66 ; WX 786 ; N a29 ; B 35 -14 751 705 ;
C 67 ; WX 788 ; N a30 ; B 35 -14 752 705 ;
C 68 ; WX 788 ; N a31 ; B 35 -14 753 705 ;
C 69 ; WX 790 ; N a32 ; B 35 -14 756 705 ;
C 70 ; WX 793 ; N a33 ; B 35 -13 759 705 ;
C 71 ; WX 794 ; N a34 ; B 35 -13 759 705 ;
C 72 ; WX 816 ; N a35 ; B 35 -14 782 705 ;
C 73 ; WX 823 ; N a36 ; B 35 -14 787 705 ;
C 74 ; WX 789 ; N a37 ; B 35 -14 754 705 ;
C 75 ; WX 841 ; N a38 ; B 35 -14 807 705 ;
C 76 ; WX 823 ; N a39 ; B 35 -14 789 705 ;
C 77 ; WX 833 ; N a40 ; B 35 -14 798 705 ;
C 78 ; WX 816 ; N a41 ; B 35 -13 782 705 ;
C 79 ; WX 831 ; N a42 ; B 35 -14 796 705 ;
C 80 ; WX 923 ; N a43 ; B 35 -14 888 705 ;
C 81 ; WX 744 ; N a44 ; B 35 0 710 692 ;
C 82 ; WX 723 ; N a45 ; B 35 0 688 692 ;
C 83 ; WX 749 ; N a46 ; B 35 0 714 692 ;
C 84 ; WX 790 ; N a47 ; B 34 -14 756 705 ;
C 85 ; WX 792 ; N a48 ; B 35 -14 758 705 ;
C 86 ; WX 695 ; N a49 ; B 35 -14 661 706 ;
C 87 ; WX 776 ; N a50 ; B 35 -6 741 699 ;
C 88 ; WX 768 ; N a51 ; B 35 -7 734 699 ;
C 89 ; WX 792 ; N a52 ; B 35 -14 757 705 ;
C 90 ; WX 759 ; N a53 ; B 35 0 725 692 ;
C 91 ; WX 707 ; N a54 ; B 35 -13 672 704 ;
C 92 ; WX 708 ; N a55 ; B 35 -14 672 705 ;
C 93 ; WX 682 ; N a56 ; B 35 -14 647 705 ;
C 94 ; WX 701 ; N a57 ; B 35 -14 666 705 ;
C 95 ; WX 826 ; N a58 ; B 35 -14 791 705 ;
C 96 ; WX 815 ; N a59 ; B 35 -14 780 705 ;
C 97 ; WX 789 ; N a60 ; B 35 -14 754 705 ;
C 98 ; WX 789 ; N a61 ; B 35 -14 754 705 ;
C 99 ; WX 707 ; N a62 ; B 34 -14 673 705 ;
C 100 ; WX 687 ; N a63 ; B 36 0 651 692 ;
C 101 ; WX 696 ; N a64 ; B 35 0 661 691 ;
C 102 ; WX 689 ; N a65 ; B 35 0 655 692 ;
C 103 ; WX 786 ; N a66 ; B 34 -14 751 705 ;
C 104 ; WX 787 ; N a67 ; B 35 -14 752 705 ;
C 105 ; WX 713 ; N a68 ; B 35 -14 678 705 ;
C 106 ; WX 791 ; N a69 ; B 35 -14 756 705 ;
C 107 ; WX 785 ; N a70 ; B 36 -14 751 705 ;
C 108 ; WX 791 ; N a71 ; B 35 -14 757 705 ;
C 109 ; WX 873 ; N a72 ; B 35 -14 838 705 ;
C 110 ; WX 761 ; N a73 ; B 35 0 726 692 ;
C 111 ; WX 762 ; N a74 ; B 35 0 727 692 ;
C 112 ; WX 762 ; N a203 ; B 35 0 727 692 ;
C 113 ; WX 759 ; N a75 ; B 35 0 725 692 ;
C 114 ; WX 759 ; N a204 ; B 35 0 725 692 ;
C 115 ; WX 892 ; N a76 ; B 35 0 858 705 ;
C 116 ; WX 892 ; N a77 ; B 35 -14 858 692 ;
C 117 ; WX 788 ; N a78 ; B 35 -14 754 705 ;
C 118 ; WX 784 ; N a79 ; B 35 -14 749 705 ;
C 119 ; WX 438 ; N a81 ; B 35 -14 403 705 ;
C 120 ; WX 138 ; N a82 ; B 35 0 104 692 ;
C 121 ; WX 277 ; N a83 ; B 35 0 242 692 ;
C 122 ; WX 415 ; N a84 ; B 35 0 380 692 ;
C 123 ; WX 392 ; N a97 ; B 35 263 357 705 ;
C 124 ; WX 392 ; N a98 ; B 34 263 357 705 ;
C 125 ; WX 668 ; N a99 ; B 35 263 633 705 ;
C 126 ; WX 668 ; N a100 ; B 36 263 634 705 ;
C 128 ; WX 390 ; N a89 ; B 35 -14 356 705 ;
C 129 ; WX 390 ; N a90 ; B 35 -14 355 705 ;
C 130 ; WX 317 ; N a93 ; B 35 0 283 692 ;
C 131 ; WX 317 ; N a94 ; B 35 0 283 692 ;
C 132 ; WX 276 ; N a91 ; B 35 0 242 692 ;
C 133 ; WX 276 ; N a92 ; B 35 0 242 692 ;
C 134 ; WX 509 ; N a205 ; B 35 0 475 692 ;
C 135 ; WX 509 ; N a85 ; B 35 0 475 692 ;
C 136 ; WX 410 ; N a206 ; B 35 0 375 692 ;
C 137 ; WX 410 ; N a86 ; B 35 0 375 692 ;
C 138 ; WX 234 ; N a87 ; B 35 -14 199 705 ;
C 139 ; WX 234 ; N a88 ; B 35 -14 199 705 ;
C 140 ; WX 334 ; N a95 ; B 35 0 299 692 ;
C 141 ; WX 334 ; N a96 ; B 35 0 299 692 ;
C 161 ; WX 732 ; N a101 ; B 35 -143 697 806 ;
C 162 ; WX 544 ; N a102 ; B 56 -14 488 706 ;
C 163 ; WX 544 ; N a103 ; B 34 -14 508 705 ;
C 164 ; WX 910 ; N a104 ; B 35 40 875 651 ;
C 165 ; WX 667 ; N a106 ; B 35 -14 633 705 ;
C 166 ; WX 760 ; N a107 ; B 35 -14 726 705 ;
C 167 ; WX 760 ; N a108 ; B 0 121 758 569 ;
C 168 ; WX 776 ; N a112 ; B 35 0 741 705 ;
C 169 ; WX 595 ; N a111 ; B 34 -14 560 705 ;
C 170 ; WX 694 ; N a110 ; B 35 -14 659 705 ;
C 171 ; WX 626 ; N a109 ; B 34 0 591 705 ;
C 172 ; WX 788 ; N a120 ; B 35 -14 754 705 ;
C 173 ; WX 788 ; N a121 ; B 35 -14 754 705 ;
C 174 ; WX 788 ; N a122 ; B 35 -14 754 705 ;
C 175 ; WX 788 ; N a123 ; B 35 -14 754 705 ;
C 176 ; WX 788 ; N a124 ; B 35 -14 754 705 ;
C 177 ; WX 788 ; N a125 ; B 35 -14 754 705 ;
C 178 ; WX 788 ; N a126 ; B 35 -14 754 705 ;
C 179 ; WX 788 ; N a127 ; B 35 -14 754 705 ;
C 180 ; WX 788 ; N a128 ; B 35 -14 754 705 ;
C 181 ; WX 788 ; N a129 ; B 35 -14 754 705 ;
C 182 ; WX 788 ; N a130 ; B 35 -14 754 705 ;
C 183 ; WX 788 ; N a131 ; B 35 -14 754 705 ;
C 184 ; WX 788 ; N a132 ; B 35 -14 754 705 ;
C 185 ; WX 788 ; N a133 ; B 35 -14 754 705 ;
C 186 ; WX 788 ; N a134 ; B 35 -14 754 705 ;
C 187 ; WX 788 ; N a135 ; B 35 -14 754 705 ;
C 188 ; WX 788 ; N a136 ; B 35 -14 754 705 ;
C 189 ; WX 788 ; N a137 ; B 35 -14 754 705 ;
C 190 ; WX 788 ; N a138 ; B 35 -14 754 705 ;
C 191 ; WX 788 ; N a139 ; B 35 -14 754 705 ;
C 192 ; WX 788 ; N a140 ; B 35 -14 754 705 ;
C 193 ; WX 788 ; N a141 ; B 35 -14 754 705 ;
C 194 ; WX 788 ; N a142 ; B 35 -14 754 705 ;
C 195 ; WX 788 ; N a143 ; B 35 -14 754 705 ;
C 196 ; WX 788 ; N a144 ; B 35 -14 754 705 ;
C 197 ; WX 788 ; N a145 ; B 35 -14 754 705 ;
C 198 ; WX 788 ; N a146 ; B 35 -14 754 705 ;
C 199 ; WX 788 ; N a147 ; B 35 -14 754 705 ;
C 200 ; WX 788 ; N a148 ; B 35 -14 754 705 ;
C 201 ; WX 788 ; N a149 ; B 35 -14 754 705 ;
C 202 ; WX 788 ; N a150 ; B 35 -14 754 705 ;
C 203 ; WX 788 ; N a151 ; B 35 -14 754 705 ;
C 204 ; WX 788 ; N a152 ; B 35 -14 754 705 ;
C 205 ; WX 788 ; N a153 ; B 35 -14 754 705 ;
C 206 ; WX 788 ; N a154 ; B 35 -14 754 705 ;
C 207 ; WX 788 ; N a155 ; B 35 -14 754 705 ;
C 208 ; WX 788 ; N a156 ; B 35 -14 754 705 ;
C 209 ; WX 788 ; N a157 ; B 35 -14 754 705 ;
C 210 ; WX 788 ; N a158 ; B 35 -14 754 705 ;
C 211 ; WX 788 ; N a159 ; B 35 -14 754 705 ;
C 212 ; WX 894 ; N a160 ; B 35 58 860 634 ;
C 213 ; WX 838 ; N a161 ; B 35 152 803 540 ;
C 214 ; WX 1016 ; N a163 ; B 34 152 981 540 ;
C 215 ; WX 458 ; N a164 ; B 35 -127 422 820 ;
C 216 ; WX 748 ; N a196 ; B 35 94 698 597 ;
C 217 ; WX 924 ; N a165 ; B 35 140 890 552 ;
C 218 ; WX 748 ; N a192 ; B 35 94 698 597 ;
C 219 ; WX 918 ; N a166 ; B 35 166 884 526 ;
C 220 ; WX 927 ; N a167 ; B 35 32 892 660 ;
C 221 ; WX 928 ; N a168 ; B 35 129 891 562 ;
C 222 ; WX 928 ; N a169 ; B 35 128 893 563 ;
C 223 ; WX 834 ; N a170 ; B 35 155 799 537 ;
C 224 ; WX 873 ; N a171 ; B 35 93 838 599 ;
C 225 ; WX 828 ; N a172 ; B 35 104 791 588 ;
C 226 ; WX 924 ; N a173 ; B 35 98 889 594 ;
C 227 ; WX 924 ; N a162 ; B 35 98 889 594 ;
C 228 ; WX 917 ; N a174 ; B 35 0 882 692 ;
C 229 ; WX 930 ; N a175 ; B 35 84 896 608 ;
C 230 ; WX 931 ; N a176 ; B 35 84 896 608 ;
C 231 ; WX 463 ; N a177 ; B 35 -99 429 791 ;
C 232 ; WX 883 ; N a178 ; B 35 71 848 623 ;
C 233 ; WX 836 ; N a179 ; B 35 44 802 648 ;
C 234 ; WX 836 ; N a193 ; B 35 44 802 648 ;
C 235 ; WX 867 ; N a180 ; B 35 101 832 591 ;
C 236 ; WX 867 ; N a199 ; B 35 101 832 591 ;
C 237 ; WX 696 ; N a181 ; B 35 44 661 648 ;
C 238 ; WX 696 ; N a200 ; B 35 44 661 648 ;
C 239 ; WX 874 ; N a182 ; B 35 77 840 619 ;
C 241 ; WX 874 ; N a201 ; B 35 73 840 615 ;
C 242 ; WX 760 ; N a183 ; B 35 0 725 692 ;
C 243 ; WX 946 ; N a184 ; B 35 160 911 533 ;
C 244 ; WX 771 ; N a197 ; B 34 37 736 655 ;
C 245 ; WX 865 ; N a185 ; B 35 207 830 481 ;
C 246 ; WX 771 ; N a194 ; B 34 37 736 655 ;
C 247 ; WX 888 ; N a198 ; B 34 -19 853 712 ;
C 248 ; WX 967 ; N a186 ; B 35 124 932 568 ;
C 249 ; WX 888 ; N a195 ; B 34 -19 853 712 ;
C 250 ; WX 831 ; N a187 ; B 35 113 796 579 ;
C 251 ; WX 873 ; N a188 ; B 36 118 838 578 ;
C 252 ; WX 927 ; N a189 ; B 35 150 891 542 ;
C 253 ; WX 970 ; N a190 ; B 35 76 931 616 ;
C 254 ; WX 918 ; N a191 ; B 34 99 884 593 ;
EndCharMetrics
EndFontMetrics

View File

@@ -0,0 +1,362 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Courier. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontCourier struct {
encoder textencoding.TextEncoder
}
func NewFontCourier() fontCourier {
font := fontCourier{}
font.encoder = textencoding.NewWinAnsiTextEncoder() // Default
return font
}
func (font fontCourier) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontCourier) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := courierCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontCourier) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Courier"))
fontDict.Set("Encoding", font.encoder.ToPdfObject())
obj.PdfObject = fontDict
return obj
}
var courierCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"A": {GlyphName: "A", Wx: 600.000000, Wy: 0.000000},
"AE": {GlyphName: "AE", Wx: 600.000000, Wy: 0.000000},
"Aacute": {GlyphName: "Aacute", Wx: 600.000000, Wy: 0.000000},
"Abreve": {GlyphName: "Abreve", Wx: 600.000000, Wy: 0.000000},
"Acircumflex": {GlyphName: "Acircumflex", Wx: 600.000000, Wy: 0.000000},
"Adieresis": {GlyphName: "Adieresis", Wx: 600.000000, Wy: 0.000000},
"Agrave": {GlyphName: "Agrave", Wx: 600.000000, Wy: 0.000000},
"Amacron": {GlyphName: "Amacron", Wx: 600.000000, Wy: 0.000000},
"Aogonek": {GlyphName: "Aogonek", Wx: 600.000000, Wy: 0.000000},
"Aring": {GlyphName: "Aring", Wx: 600.000000, Wy: 0.000000},
"Atilde": {GlyphName: "Atilde", Wx: 600.000000, Wy: 0.000000},
"B": {GlyphName: "B", Wx: 600.000000, Wy: 0.000000},
"C": {GlyphName: "C", Wx: 600.000000, Wy: 0.000000},
"Cacute": {GlyphName: "Cacute", Wx: 600.000000, Wy: 0.000000},
"Ccaron": {GlyphName: "Ccaron", Wx: 600.000000, Wy: 0.000000},
"Ccedilla": {GlyphName: "Ccedilla", Wx: 600.000000, Wy: 0.000000},
"D": {GlyphName: "D", Wx: 600.000000, Wy: 0.000000},
"Dcaron": {GlyphName: "Dcaron", Wx: 600.000000, Wy: 0.000000},
"Dcroat": {GlyphName: "Dcroat", Wx: 600.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 600.000000, Wy: 0.000000},
"E": {GlyphName: "E", Wx: 600.000000, Wy: 0.000000},
"Eacute": {GlyphName: "Eacute", Wx: 600.000000, Wy: 0.000000},
"Ecaron": {GlyphName: "Ecaron", Wx: 600.000000, Wy: 0.000000},
"Ecircumflex": {GlyphName: "Ecircumflex", Wx: 600.000000, Wy: 0.000000},
"Edieresis": {GlyphName: "Edieresis", Wx: 600.000000, Wy: 0.000000},
"Edotaccent": {GlyphName: "Edotaccent", Wx: 600.000000, Wy: 0.000000},
"Egrave": {GlyphName: "Egrave", Wx: 600.000000, Wy: 0.000000},
"Emacron": {GlyphName: "Emacron", Wx: 600.000000, Wy: 0.000000},
"Eogonek": {GlyphName: "Eogonek", Wx: 600.000000, Wy: 0.000000},
"Eth": {GlyphName: "Eth", Wx: 600.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 600.000000, Wy: 0.000000},
"F": {GlyphName: "F", Wx: 600.000000, Wy: 0.000000},
"G": {GlyphName: "G", Wx: 600.000000, Wy: 0.000000},
"Gbreve": {GlyphName: "Gbreve", Wx: 600.000000, Wy: 0.000000},
"Gcommaaccent": {GlyphName: "Gcommaaccent", Wx: 600.000000, Wy: 0.000000},
"H": {GlyphName: "H", Wx: 600.000000, Wy: 0.000000},
"I": {GlyphName: "I", Wx: 600.000000, Wy: 0.000000},
"Iacute": {GlyphName: "Iacute", Wx: 600.000000, Wy: 0.000000},
"Icircumflex": {GlyphName: "Icircumflex", Wx: 600.000000, Wy: 0.000000},
"Idieresis": {GlyphName: "Idieresis", Wx: 600.000000, Wy: 0.000000},
"Idotaccent": {GlyphName: "Idotaccent", Wx: 600.000000, Wy: 0.000000},
"Igrave": {GlyphName: "Igrave", Wx: 600.000000, Wy: 0.000000},
"Imacron": {GlyphName: "Imacron", Wx: 600.000000, Wy: 0.000000},
"Iogonek": {GlyphName: "Iogonek", Wx: 600.000000, Wy: 0.000000},
"J": {GlyphName: "J", Wx: 600.000000, Wy: 0.000000},
"K": {GlyphName: "K", Wx: 600.000000, Wy: 0.000000},
"Kcommaaccent": {GlyphName: "Kcommaaccent", Wx: 600.000000, Wy: 0.000000},
"L": {GlyphName: "L", Wx: 600.000000, Wy: 0.000000},
"Lacute": {GlyphName: "Lacute", Wx: 600.000000, Wy: 0.000000},
"Lcaron": {GlyphName: "Lcaron", Wx: 600.000000, Wy: 0.000000},
"Lcommaaccent": {GlyphName: "Lcommaaccent", Wx: 600.000000, Wy: 0.000000},
"Lslash": {GlyphName: "Lslash", Wx: 600.000000, Wy: 0.000000},
"M": {GlyphName: "M", Wx: 600.000000, Wy: 0.000000},
"N": {GlyphName: "N", Wx: 600.000000, Wy: 0.000000},
"Nacute": {GlyphName: "Nacute", Wx: 600.000000, Wy: 0.000000},
"Ncaron": {GlyphName: "Ncaron", Wx: 600.000000, Wy: 0.000000},
"Ncommaaccent": {GlyphName: "Ncommaaccent", Wx: 600.000000, Wy: 0.000000},
"Ntilde": {GlyphName: "Ntilde", Wx: 600.000000, Wy: 0.000000},
"O": {GlyphName: "O", Wx: 600.000000, Wy: 0.000000},
"OE": {GlyphName: "OE", Wx: 600.000000, Wy: 0.000000},
"Oacute": {GlyphName: "Oacute", Wx: 600.000000, Wy: 0.000000},
"Ocircumflex": {GlyphName: "Ocircumflex", Wx: 600.000000, Wy: 0.000000},
"Odieresis": {GlyphName: "Odieresis", Wx: 600.000000, Wy: 0.000000},
"Ograve": {GlyphName: "Ograve", Wx: 600.000000, Wy: 0.000000},
"Ohungarumlaut": {GlyphName: "Ohungarumlaut", Wx: 600.000000, Wy: 0.000000},
"Omacron": {GlyphName: "Omacron", Wx: 600.000000, Wy: 0.000000},
"Oslash": {GlyphName: "Oslash", Wx: 600.000000, Wy: 0.000000},
"Otilde": {GlyphName: "Otilde", Wx: 600.000000, Wy: 0.000000},
"P": {GlyphName: "P", Wx: 600.000000, Wy: 0.000000},
"Q": {GlyphName: "Q", Wx: 600.000000, Wy: 0.000000},
"R": {GlyphName: "R", Wx: 600.000000, Wy: 0.000000},
"Racute": {GlyphName: "Racute", Wx: 600.000000, Wy: 0.000000},
"Rcaron": {GlyphName: "Rcaron", Wx: 600.000000, Wy: 0.000000},
"Rcommaaccent": {GlyphName: "Rcommaaccent", Wx: 600.000000, Wy: 0.000000},
"S": {GlyphName: "S", Wx: 600.000000, Wy: 0.000000},
"Sacute": {GlyphName: "Sacute", Wx: 600.000000, Wy: 0.000000},
"Scaron": {GlyphName: "Scaron", Wx: 600.000000, Wy: 0.000000},
"Scedilla": {GlyphName: "Scedilla", Wx: 600.000000, Wy: 0.000000},
"Scommaaccent": {GlyphName: "Scommaaccent", Wx: 600.000000, Wy: 0.000000},
"T": {GlyphName: "T", Wx: 600.000000, Wy: 0.000000},
"Tcaron": {GlyphName: "Tcaron", Wx: 600.000000, Wy: 0.000000},
"Tcommaaccent": {GlyphName: "Tcommaaccent", Wx: 600.000000, Wy: 0.000000},
"Thorn": {GlyphName: "Thorn", Wx: 600.000000, Wy: 0.000000},
"U": {GlyphName: "U", Wx: 600.000000, Wy: 0.000000},
"Uacute": {GlyphName: "Uacute", Wx: 600.000000, Wy: 0.000000},
"Ucircumflex": {GlyphName: "Ucircumflex", Wx: 600.000000, Wy: 0.000000},
"Udieresis": {GlyphName: "Udieresis", Wx: 600.000000, Wy: 0.000000},
"Ugrave": {GlyphName: "Ugrave", Wx: 600.000000, Wy: 0.000000},
"Uhungarumlaut": {GlyphName: "Uhungarumlaut", Wx: 600.000000, Wy: 0.000000},
"Umacron": {GlyphName: "Umacron", Wx: 600.000000, Wy: 0.000000},
"Uogonek": {GlyphName: "Uogonek", Wx: 600.000000, Wy: 0.000000},
"Uring": {GlyphName: "Uring", Wx: 600.000000, Wy: 0.000000},
"V": {GlyphName: "V", Wx: 600.000000, Wy: 0.000000},
"W": {GlyphName: "W", Wx: 600.000000, Wy: 0.000000},
"X": {GlyphName: "X", Wx: 600.000000, Wy: 0.000000},
"Y": {GlyphName: "Y", Wx: 600.000000, Wy: 0.000000},
"Yacute": {GlyphName: "Yacute", Wx: 600.000000, Wy: 0.000000},
"Ydieresis": {GlyphName: "Ydieresis", Wx: 600.000000, Wy: 0.000000},
"Z": {GlyphName: "Z", Wx: 600.000000, Wy: 0.000000},
"Zacute": {GlyphName: "Zacute", Wx: 600.000000, Wy: 0.000000},
"Zcaron": {GlyphName: "Zcaron", Wx: 600.000000, Wy: 0.000000},
"Zdotaccent": {GlyphName: "Zdotaccent", Wx: 600.000000, Wy: 0.000000},
"a": {GlyphName: "a", Wx: 600.000000, Wy: 0.000000},
"aacute": {GlyphName: "aacute", Wx: 600.000000, Wy: 0.000000},
"abreve": {GlyphName: "abreve", Wx: 600.000000, Wy: 0.000000},
"acircumflex": {GlyphName: "acircumflex", Wx: 600.000000, Wy: 0.000000},
"acute": {GlyphName: "acute", Wx: 600.000000, Wy: 0.000000},
"adieresis": {GlyphName: "adieresis", Wx: 600.000000, Wy: 0.000000},
"ae": {GlyphName: "ae", Wx: 600.000000, Wy: 0.000000},
"agrave": {GlyphName: "agrave", Wx: 600.000000, Wy: 0.000000},
"amacron": {GlyphName: "amacron", Wx: 600.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 600.000000, Wy: 0.000000},
"aogonek": {GlyphName: "aogonek", Wx: 600.000000, Wy: 0.000000},
"aring": {GlyphName: "aring", Wx: 600.000000, Wy: 0.000000},
"asciicircum": {GlyphName: "asciicircum", Wx: 600.000000, Wy: 0.000000},
"asciitilde": {GlyphName: "asciitilde", Wx: 600.000000, Wy: 0.000000},
"asterisk": {GlyphName: "asterisk", Wx: 600.000000, Wy: 0.000000},
"at": {GlyphName: "at", Wx: 600.000000, Wy: 0.000000},
"atilde": {GlyphName: "atilde", Wx: 600.000000, Wy: 0.000000},
"b": {GlyphName: "b", Wx: 600.000000, Wy: 0.000000},
"backslash": {GlyphName: "backslash", Wx: 600.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 600.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 600.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 600.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 600.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 600.000000, Wy: 0.000000},
"breve": {GlyphName: "breve", Wx: 600.000000, Wy: 0.000000},
"brokenbar": {GlyphName: "brokenbar", Wx: 600.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 600.000000, Wy: 0.000000},
"c": {GlyphName: "c", Wx: 600.000000, Wy: 0.000000},
"cacute": {GlyphName: "cacute", Wx: 600.000000, Wy: 0.000000},
"caron": {GlyphName: "caron", Wx: 600.000000, Wy: 0.000000},
"ccaron": {GlyphName: "ccaron", Wx: 600.000000, Wy: 0.000000},
"ccedilla": {GlyphName: "ccedilla", Wx: 600.000000, Wy: 0.000000},
"cedilla": {GlyphName: "cedilla", Wx: 600.000000, Wy: 0.000000},
"cent": {GlyphName: "cent", Wx: 600.000000, Wy: 0.000000},
"circumflex": {GlyphName: "circumflex", Wx: 600.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 600.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 600.000000, Wy: 0.000000},
"commaaccent": {GlyphName: "commaaccent", Wx: 600.000000, Wy: 0.000000},
"copyright": {GlyphName: "copyright", Wx: 600.000000, Wy: 0.000000},
"currency": {GlyphName: "currency", Wx: 600.000000, Wy: 0.000000},
"d": {GlyphName: "d", Wx: 600.000000, Wy: 0.000000},
"dagger": {GlyphName: "dagger", Wx: 600.000000, Wy: 0.000000},
"daggerdbl": {GlyphName: "daggerdbl", Wx: 600.000000, Wy: 0.000000},
"dcaron": {GlyphName: "dcaron", Wx: 600.000000, Wy: 0.000000},
"dcroat": {GlyphName: "dcroat", Wx: 600.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 600.000000, Wy: 0.000000},
"dieresis": {GlyphName: "dieresis", Wx: 600.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 600.000000, Wy: 0.000000},
"dollar": {GlyphName: "dollar", Wx: 600.000000, Wy: 0.000000},
"dotaccent": {GlyphName: "dotaccent", Wx: 600.000000, Wy: 0.000000},
"dotlessi": {GlyphName: "dotlessi", Wx: 600.000000, Wy: 0.000000},
"e": {GlyphName: "e", Wx: 600.000000, Wy: 0.000000},
"eacute": {GlyphName: "eacute", Wx: 600.000000, Wy: 0.000000},
"ecaron": {GlyphName: "ecaron", Wx: 600.000000, Wy: 0.000000},
"ecircumflex": {GlyphName: "ecircumflex", Wx: 600.000000, Wy: 0.000000},
"edieresis": {GlyphName: "edieresis", Wx: 600.000000, Wy: 0.000000},
"edotaccent": {GlyphName: "edotaccent", Wx: 600.000000, Wy: 0.000000},
"egrave": {GlyphName: "egrave", Wx: 600.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 600.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 600.000000, Wy: 0.000000},
"emacron": {GlyphName: "emacron", Wx: 600.000000, Wy: 0.000000},
"emdash": {GlyphName: "emdash", Wx: 600.000000, Wy: 0.000000},
"endash": {GlyphName: "endash", Wx: 600.000000, Wy: 0.000000},
"eogonek": {GlyphName: "eogonek", Wx: 600.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 600.000000, Wy: 0.000000},
"eth": {GlyphName: "eth", Wx: 600.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 600.000000, Wy: 0.000000},
"exclamdown": {GlyphName: "exclamdown", Wx: 600.000000, Wy: 0.000000},
"f": {GlyphName: "f", Wx: 600.000000, Wy: 0.000000},
"fi": {GlyphName: "fi", Wx: 600.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 600.000000, Wy: 0.000000},
"fl": {GlyphName: "fl", Wx: 600.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 600.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 600.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 600.000000, Wy: 0.000000},
"g": {GlyphName: "g", Wx: 600.000000, Wy: 0.000000},
"gbreve": {GlyphName: "gbreve", Wx: 600.000000, Wy: 0.000000},
"gcommaaccent": {GlyphName: "gcommaaccent", Wx: 600.000000, Wy: 0.000000},
"germandbls": {GlyphName: "germandbls", Wx: 600.000000, Wy: 0.000000},
"grave": {GlyphName: "grave", Wx: 600.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 600.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 600.000000, Wy: 0.000000},
"guillemotleft": {GlyphName: "guillemotleft", Wx: 600.000000, Wy: 0.000000},
"guillemotright": {GlyphName: "guillemotright", Wx: 600.000000, Wy: 0.000000},
"guilsinglleft": {GlyphName: "guilsinglleft", Wx: 600.000000, Wy: 0.000000},
"guilsinglright": {GlyphName: "guilsinglright", Wx: 600.000000, Wy: 0.000000},
"h": {GlyphName: "h", Wx: 600.000000, Wy: 0.000000},
"hungarumlaut": {GlyphName: "hungarumlaut", Wx: 600.000000, Wy: 0.000000},
"hyphen": {GlyphName: "hyphen", Wx: 600.000000, Wy: 0.000000},
"i": {GlyphName: "i", Wx: 600.000000, Wy: 0.000000},
"iacute": {GlyphName: "iacute", Wx: 600.000000, Wy: 0.000000},
"icircumflex": {GlyphName: "icircumflex", Wx: 600.000000, Wy: 0.000000},
"idieresis": {GlyphName: "idieresis", Wx: 600.000000, Wy: 0.000000},
"igrave": {GlyphName: "igrave", Wx: 600.000000, Wy: 0.000000},
"imacron": {GlyphName: "imacron", Wx: 600.000000, Wy: 0.000000},
"iogonek": {GlyphName: "iogonek", Wx: 600.000000, Wy: 0.000000},
"j": {GlyphName: "j", Wx: 600.000000, Wy: 0.000000},
"k": {GlyphName: "k", Wx: 600.000000, Wy: 0.000000},
"kcommaaccent": {GlyphName: "kcommaaccent", Wx: 600.000000, Wy: 0.000000},
"l": {GlyphName: "l", Wx: 600.000000, Wy: 0.000000},
"lacute": {GlyphName: "lacute", Wx: 600.000000, Wy: 0.000000},
"lcaron": {GlyphName: "lcaron", Wx: 600.000000, Wy: 0.000000},
"lcommaaccent": {GlyphName: "lcommaaccent", Wx: 600.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 600.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 600.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 600.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 600.000000, Wy: 0.000000},
"lslash": {GlyphName: "lslash", Wx: 600.000000, Wy: 0.000000},
"m": {GlyphName: "m", Wx: 600.000000, Wy: 0.000000},
"macron": {GlyphName: "macron", Wx: 600.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 600.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 600.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 600.000000, Wy: 0.000000},
"n": {GlyphName: "n", Wx: 600.000000, Wy: 0.000000},
"nacute": {GlyphName: "nacute", Wx: 600.000000, Wy: 0.000000},
"ncaron": {GlyphName: "ncaron", Wx: 600.000000, Wy: 0.000000},
"ncommaaccent": {GlyphName: "ncommaaccent", Wx: 600.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 600.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 600.000000, Wy: 0.000000},
"ntilde": {GlyphName: "ntilde", Wx: 600.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 600.000000, Wy: 0.000000},
"o": {GlyphName: "o", Wx: 600.000000, Wy: 0.000000},
"oacute": {GlyphName: "oacute", Wx: 600.000000, Wy: 0.000000},
"ocircumflex": {GlyphName: "ocircumflex", Wx: 600.000000, Wy: 0.000000},
"odieresis": {GlyphName: "odieresis", Wx: 600.000000, Wy: 0.000000},
"oe": {GlyphName: "oe", Wx: 600.000000, Wy: 0.000000},
"ogonek": {GlyphName: "ogonek", Wx: 600.000000, Wy: 0.000000},
"ograve": {GlyphName: "ograve", Wx: 600.000000, Wy: 0.000000},
"ohungarumlaut": {GlyphName: "ohungarumlaut", Wx: 600.000000, Wy: 0.000000},
"omacron": {GlyphName: "omacron", Wx: 600.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 600.000000, Wy: 0.000000},
"onehalf": {GlyphName: "onehalf", Wx: 600.000000, Wy: 0.000000},
"onequarter": {GlyphName: "onequarter", Wx: 600.000000, Wy: 0.000000},
"onesuperior": {GlyphName: "onesuperior", Wx: 600.000000, Wy: 0.000000},
"ordfeminine": {GlyphName: "ordfeminine", Wx: 600.000000, Wy: 0.000000},
"ordmasculine": {GlyphName: "ordmasculine", Wx: 600.000000, Wy: 0.000000},
"oslash": {GlyphName: "oslash", Wx: 600.000000, Wy: 0.000000},
"otilde": {GlyphName: "otilde", Wx: 600.000000, Wy: 0.000000},
"p": {GlyphName: "p", Wx: 600.000000, Wy: 0.000000},
"paragraph": {GlyphName: "paragraph", Wx: 600.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 600.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 600.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 600.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 600.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 600.000000, Wy: 0.000000},
"periodcentered": {GlyphName: "periodcentered", Wx: 600.000000, Wy: 0.000000},
"perthousand": {GlyphName: "perthousand", Wx: 600.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 600.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 600.000000, Wy: 0.000000},
"q": {GlyphName: "q", Wx: 600.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 600.000000, Wy: 0.000000},
"questiondown": {GlyphName: "questiondown", Wx: 600.000000, Wy: 0.000000},
"quotedbl": {GlyphName: "quotedbl", Wx: 600.000000, Wy: 0.000000},
"quotedblbase": {GlyphName: "quotedblbase", Wx: 600.000000, Wy: 0.000000},
"quotedblleft": {GlyphName: "quotedblleft", Wx: 600.000000, Wy: 0.000000},
"quotedblright": {GlyphName: "quotedblright", Wx: 600.000000, Wy: 0.000000},
"quoteleft": {GlyphName: "quoteleft", Wx: 600.000000, Wy: 0.000000},
"quoteright": {GlyphName: "quoteright", Wx: 600.000000, Wy: 0.000000},
"quotesinglbase": {GlyphName: "quotesinglbase", Wx: 600.000000, Wy: 0.000000},
"quotesingle": {GlyphName: "quotesingle", Wx: 600.000000, Wy: 0.000000},
"r": {GlyphName: "r", Wx: 600.000000, Wy: 0.000000},
"racute": {GlyphName: "racute", Wx: 600.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 600.000000, Wy: 0.000000},
"rcaron": {GlyphName: "rcaron", Wx: 600.000000, Wy: 0.000000},
"rcommaaccent": {GlyphName: "rcommaaccent", Wx: 600.000000, Wy: 0.000000},
"registered": {GlyphName: "registered", Wx: 600.000000, Wy: 0.000000},
"ring": {GlyphName: "ring", Wx: 600.000000, Wy: 0.000000},
"s": {GlyphName: "s", Wx: 600.000000, Wy: 0.000000},
"sacute": {GlyphName: "sacute", Wx: 600.000000, Wy: 0.000000},
"scaron": {GlyphName: "scaron", Wx: 600.000000, Wy: 0.000000},
"scedilla": {GlyphName: "scedilla", Wx: 600.000000, Wy: 0.000000},
"scommaaccent": {GlyphName: "scommaaccent", Wx: 600.000000, Wy: 0.000000},
"section": {GlyphName: "section", Wx: 600.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 600.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 600.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 600.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 600.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 600.000000, Wy: 0.000000},
"sterling": {GlyphName: "sterling", Wx: 600.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 600.000000, Wy: 0.000000},
"t": {GlyphName: "t", Wx: 600.000000, Wy: 0.000000},
"tcaron": {GlyphName: "tcaron", Wx: 600.000000, Wy: 0.000000},
"tcommaaccent": {GlyphName: "tcommaaccent", Wx: 600.000000, Wy: 0.000000},
"thorn": {GlyphName: "thorn", Wx: 600.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 600.000000, Wy: 0.000000},
"threequarters": {GlyphName: "threequarters", Wx: 600.000000, Wy: 0.000000},
"threesuperior": {GlyphName: "threesuperior", Wx: 600.000000, Wy: 0.000000},
"tilde": {GlyphName: "tilde", Wx: 600.000000, Wy: 0.000000},
"trademark": {GlyphName: "trademark", Wx: 600.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 600.000000, Wy: 0.000000},
"twosuperior": {GlyphName: "twosuperior", Wx: 600.000000, Wy: 0.000000},
"u": {GlyphName: "u", Wx: 600.000000, Wy: 0.000000},
"uacute": {GlyphName: "uacute", Wx: 600.000000, Wy: 0.000000},
"ucircumflex": {GlyphName: "ucircumflex", Wx: 600.000000, Wy: 0.000000},
"udieresis": {GlyphName: "udieresis", Wx: 600.000000, Wy: 0.000000},
"ugrave": {GlyphName: "ugrave", Wx: 600.000000, Wy: 0.000000},
"uhungarumlaut": {GlyphName: "uhungarumlaut", Wx: 600.000000, Wy: 0.000000},
"umacron": {GlyphName: "umacron", Wx: 600.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 600.000000, Wy: 0.000000},
"uogonek": {GlyphName: "uogonek", Wx: 600.000000, Wy: 0.000000},
"uring": {GlyphName: "uring", Wx: 600.000000, Wy: 0.000000},
"v": {GlyphName: "v", Wx: 600.000000, Wy: 0.000000},
"w": {GlyphName: "w", Wx: 600.000000, Wy: 0.000000},
"x": {GlyphName: "x", Wx: 600.000000, Wy: 0.000000},
"y": {GlyphName: "y", Wx: 600.000000, Wy: 0.000000},
"yacute": {GlyphName: "yacute", Wx: 600.000000, Wy: 0.000000},
"ydieresis": {GlyphName: "ydieresis", Wx: 600.000000, Wy: 0.000000},
"yen": {GlyphName: "yen", Wx: 600.000000, Wy: 0.000000},
"z": {GlyphName: "z", Wx: 600.000000, Wy: 0.000000},
"zacute": {GlyphName: "zacute", Wx: 600.000000, Wy: 0.000000},
"zcaron": {GlyphName: "zcaron", Wx: 600.000000, Wy: 0.000000},
"zdotaccent": {GlyphName: "zdotaccent", Wx: 600.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 600.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,362 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Courier-Bold. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontCourierBold struct {
encoder textencoding.TextEncoder
}
func NewFontCourierBold() fontCourierBold {
font := fontCourierBold{}
font.encoder = textencoding.NewWinAnsiTextEncoder() // Default
return font
}
func (font fontCourierBold) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontCourierBold) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := courierBoldCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontCourierBold) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Courier-Bold"))
fontDict.Set("Encoding", font.encoder.ToPdfObject())
obj.PdfObject = fontDict
return obj
}
var courierBoldCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"A": {GlyphName: "A", Wx: 600.000000, Wy: 0.000000},
"AE": {GlyphName: "AE", Wx: 600.000000, Wy: 0.000000},
"Aacute": {GlyphName: "Aacute", Wx: 600.000000, Wy: 0.000000},
"Abreve": {GlyphName: "Abreve", Wx: 600.000000, Wy: 0.000000},
"Acircumflex": {GlyphName: "Acircumflex", Wx: 600.000000, Wy: 0.000000},
"Adieresis": {GlyphName: "Adieresis", Wx: 600.000000, Wy: 0.000000},
"Agrave": {GlyphName: "Agrave", Wx: 600.000000, Wy: 0.000000},
"Amacron": {GlyphName: "Amacron", Wx: 600.000000, Wy: 0.000000},
"Aogonek": {GlyphName: "Aogonek", Wx: 600.000000, Wy: 0.000000},
"Aring": {GlyphName: "Aring", Wx: 600.000000, Wy: 0.000000},
"Atilde": {GlyphName: "Atilde", Wx: 600.000000, Wy: 0.000000},
"B": {GlyphName: "B", Wx: 600.000000, Wy: 0.000000},
"C": {GlyphName: "C", Wx: 600.000000, Wy: 0.000000},
"Cacute": {GlyphName: "Cacute", Wx: 600.000000, Wy: 0.000000},
"Ccaron": {GlyphName: "Ccaron", Wx: 600.000000, Wy: 0.000000},
"Ccedilla": {GlyphName: "Ccedilla", Wx: 600.000000, Wy: 0.000000},
"D": {GlyphName: "D", Wx: 600.000000, Wy: 0.000000},
"Dcaron": {GlyphName: "Dcaron", Wx: 600.000000, Wy: 0.000000},
"Dcroat": {GlyphName: "Dcroat", Wx: 600.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 600.000000, Wy: 0.000000},
"E": {GlyphName: "E", Wx: 600.000000, Wy: 0.000000},
"Eacute": {GlyphName: "Eacute", Wx: 600.000000, Wy: 0.000000},
"Ecaron": {GlyphName: "Ecaron", Wx: 600.000000, Wy: 0.000000},
"Ecircumflex": {GlyphName: "Ecircumflex", Wx: 600.000000, Wy: 0.000000},
"Edieresis": {GlyphName: "Edieresis", Wx: 600.000000, Wy: 0.000000},
"Edotaccent": {GlyphName: "Edotaccent", Wx: 600.000000, Wy: 0.000000},
"Egrave": {GlyphName: "Egrave", Wx: 600.000000, Wy: 0.000000},
"Emacron": {GlyphName: "Emacron", Wx: 600.000000, Wy: 0.000000},
"Eogonek": {GlyphName: "Eogonek", Wx: 600.000000, Wy: 0.000000},
"Eth": {GlyphName: "Eth", Wx: 600.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 600.000000, Wy: 0.000000},
"F": {GlyphName: "F", Wx: 600.000000, Wy: 0.000000},
"G": {GlyphName: "G", Wx: 600.000000, Wy: 0.000000},
"Gbreve": {GlyphName: "Gbreve", Wx: 600.000000, Wy: 0.000000},
"Gcommaaccent": {GlyphName: "Gcommaaccent", Wx: 600.000000, Wy: 0.000000},
"H": {GlyphName: "H", Wx: 600.000000, Wy: 0.000000},
"I": {GlyphName: "I", Wx: 600.000000, Wy: 0.000000},
"Iacute": {GlyphName: "Iacute", Wx: 600.000000, Wy: 0.000000},
"Icircumflex": {GlyphName: "Icircumflex", Wx: 600.000000, Wy: 0.000000},
"Idieresis": {GlyphName: "Idieresis", Wx: 600.000000, Wy: 0.000000},
"Idotaccent": {GlyphName: "Idotaccent", Wx: 600.000000, Wy: 0.000000},
"Igrave": {GlyphName: "Igrave", Wx: 600.000000, Wy: 0.000000},
"Imacron": {GlyphName: "Imacron", Wx: 600.000000, Wy: 0.000000},
"Iogonek": {GlyphName: "Iogonek", Wx: 600.000000, Wy: 0.000000},
"J": {GlyphName: "J", Wx: 600.000000, Wy: 0.000000},
"K": {GlyphName: "K", Wx: 600.000000, Wy: 0.000000},
"Kcommaaccent": {GlyphName: "Kcommaaccent", Wx: 600.000000, Wy: 0.000000},
"L": {GlyphName: "L", Wx: 600.000000, Wy: 0.000000},
"Lacute": {GlyphName: "Lacute", Wx: 600.000000, Wy: 0.000000},
"Lcaron": {GlyphName: "Lcaron", Wx: 600.000000, Wy: 0.000000},
"Lcommaaccent": {GlyphName: "Lcommaaccent", Wx: 600.000000, Wy: 0.000000},
"Lslash": {GlyphName: "Lslash", Wx: 600.000000, Wy: 0.000000},
"M": {GlyphName: "M", Wx: 600.000000, Wy: 0.000000},
"N": {GlyphName: "N", Wx: 600.000000, Wy: 0.000000},
"Nacute": {GlyphName: "Nacute", Wx: 600.000000, Wy: 0.000000},
"Ncaron": {GlyphName: "Ncaron", Wx: 600.000000, Wy: 0.000000},
"Ncommaaccent": {GlyphName: "Ncommaaccent", Wx: 600.000000, Wy: 0.000000},
"Ntilde": {GlyphName: "Ntilde", Wx: 600.000000, Wy: 0.000000},
"O": {GlyphName: "O", Wx: 600.000000, Wy: 0.000000},
"OE": {GlyphName: "OE", Wx: 600.000000, Wy: 0.000000},
"Oacute": {GlyphName: "Oacute", Wx: 600.000000, Wy: 0.000000},
"Ocircumflex": {GlyphName: "Ocircumflex", Wx: 600.000000, Wy: 0.000000},
"Odieresis": {GlyphName: "Odieresis", Wx: 600.000000, Wy: 0.000000},
"Ograve": {GlyphName: "Ograve", Wx: 600.000000, Wy: 0.000000},
"Ohungarumlaut": {GlyphName: "Ohungarumlaut", Wx: 600.000000, Wy: 0.000000},
"Omacron": {GlyphName: "Omacron", Wx: 600.000000, Wy: 0.000000},
"Oslash": {GlyphName: "Oslash", Wx: 600.000000, Wy: 0.000000},
"Otilde": {GlyphName: "Otilde", Wx: 600.000000, Wy: 0.000000},
"P": {GlyphName: "P", Wx: 600.000000, Wy: 0.000000},
"Q": {GlyphName: "Q", Wx: 600.000000, Wy: 0.000000},
"R": {GlyphName: "R", Wx: 600.000000, Wy: 0.000000},
"Racute": {GlyphName: "Racute", Wx: 600.000000, Wy: 0.000000},
"Rcaron": {GlyphName: "Rcaron", Wx: 600.000000, Wy: 0.000000},
"Rcommaaccent": {GlyphName: "Rcommaaccent", Wx: 600.000000, Wy: 0.000000},
"S": {GlyphName: "S", Wx: 600.000000, Wy: 0.000000},
"Sacute": {GlyphName: "Sacute", Wx: 600.000000, Wy: 0.000000},
"Scaron": {GlyphName: "Scaron", Wx: 600.000000, Wy: 0.000000},
"Scedilla": {GlyphName: "Scedilla", Wx: 600.000000, Wy: 0.000000},
"Scommaaccent": {GlyphName: "Scommaaccent", Wx: 600.000000, Wy: 0.000000},
"T": {GlyphName: "T", Wx: 600.000000, Wy: 0.000000},
"Tcaron": {GlyphName: "Tcaron", Wx: 600.000000, Wy: 0.000000},
"Tcommaaccent": {GlyphName: "Tcommaaccent", Wx: 600.000000, Wy: 0.000000},
"Thorn": {GlyphName: "Thorn", Wx: 600.000000, Wy: 0.000000},
"U": {GlyphName: "U", Wx: 600.000000, Wy: 0.000000},
"Uacute": {GlyphName: "Uacute", Wx: 600.000000, Wy: 0.000000},
"Ucircumflex": {GlyphName: "Ucircumflex", Wx: 600.000000, Wy: 0.000000},
"Udieresis": {GlyphName: "Udieresis", Wx: 600.000000, Wy: 0.000000},
"Ugrave": {GlyphName: "Ugrave", Wx: 600.000000, Wy: 0.000000},
"Uhungarumlaut": {GlyphName: "Uhungarumlaut", Wx: 600.000000, Wy: 0.000000},
"Umacron": {GlyphName: "Umacron", Wx: 600.000000, Wy: 0.000000},
"Uogonek": {GlyphName: "Uogonek", Wx: 600.000000, Wy: 0.000000},
"Uring": {GlyphName: "Uring", Wx: 600.000000, Wy: 0.000000},
"V": {GlyphName: "V", Wx: 600.000000, Wy: 0.000000},
"W": {GlyphName: "W", Wx: 600.000000, Wy: 0.000000},
"X": {GlyphName: "X", Wx: 600.000000, Wy: 0.000000},
"Y": {GlyphName: "Y", Wx: 600.000000, Wy: 0.000000},
"Yacute": {GlyphName: "Yacute", Wx: 600.000000, Wy: 0.000000},
"Ydieresis": {GlyphName: "Ydieresis", Wx: 600.000000, Wy: 0.000000},
"Z": {GlyphName: "Z", Wx: 600.000000, Wy: 0.000000},
"Zacute": {GlyphName: "Zacute", Wx: 600.000000, Wy: 0.000000},
"Zcaron": {GlyphName: "Zcaron", Wx: 600.000000, Wy: 0.000000},
"Zdotaccent": {GlyphName: "Zdotaccent", Wx: 600.000000, Wy: 0.000000},
"a": {GlyphName: "a", Wx: 600.000000, Wy: 0.000000},
"aacute": {GlyphName: "aacute", Wx: 600.000000, Wy: 0.000000},
"abreve": {GlyphName: "abreve", Wx: 600.000000, Wy: 0.000000},
"acircumflex": {GlyphName: "acircumflex", Wx: 600.000000, Wy: 0.000000},
"acute": {GlyphName: "acute", Wx: 600.000000, Wy: 0.000000},
"adieresis": {GlyphName: "adieresis", Wx: 600.000000, Wy: 0.000000},
"ae": {GlyphName: "ae", Wx: 600.000000, Wy: 0.000000},
"agrave": {GlyphName: "agrave", Wx: 600.000000, Wy: 0.000000},
"amacron": {GlyphName: "amacron", Wx: 600.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 600.000000, Wy: 0.000000},
"aogonek": {GlyphName: "aogonek", Wx: 600.000000, Wy: 0.000000},
"aring": {GlyphName: "aring", Wx: 600.000000, Wy: 0.000000},
"asciicircum": {GlyphName: "asciicircum", Wx: 600.000000, Wy: 0.000000},
"asciitilde": {GlyphName: "asciitilde", Wx: 600.000000, Wy: 0.000000},
"asterisk": {GlyphName: "asterisk", Wx: 600.000000, Wy: 0.000000},
"at": {GlyphName: "at", Wx: 600.000000, Wy: 0.000000},
"atilde": {GlyphName: "atilde", Wx: 600.000000, Wy: 0.000000},
"b": {GlyphName: "b", Wx: 600.000000, Wy: 0.000000},
"backslash": {GlyphName: "backslash", Wx: 600.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 600.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 600.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 600.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 600.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 600.000000, Wy: 0.000000},
"breve": {GlyphName: "breve", Wx: 600.000000, Wy: 0.000000},
"brokenbar": {GlyphName: "brokenbar", Wx: 600.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 600.000000, Wy: 0.000000},
"c": {GlyphName: "c", Wx: 600.000000, Wy: 0.000000},
"cacute": {GlyphName: "cacute", Wx: 600.000000, Wy: 0.000000},
"caron": {GlyphName: "caron", Wx: 600.000000, Wy: 0.000000},
"ccaron": {GlyphName: "ccaron", Wx: 600.000000, Wy: 0.000000},
"ccedilla": {GlyphName: "ccedilla", Wx: 600.000000, Wy: 0.000000},
"cedilla": {GlyphName: "cedilla", Wx: 600.000000, Wy: 0.000000},
"cent": {GlyphName: "cent", Wx: 600.000000, Wy: 0.000000},
"circumflex": {GlyphName: "circumflex", Wx: 600.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 600.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 600.000000, Wy: 0.000000},
"commaaccent": {GlyphName: "commaaccent", Wx: 600.000000, Wy: 0.000000},
"copyright": {GlyphName: "copyright", Wx: 600.000000, Wy: 0.000000},
"currency": {GlyphName: "currency", Wx: 600.000000, Wy: 0.000000},
"d": {GlyphName: "d", Wx: 600.000000, Wy: 0.000000},
"dagger": {GlyphName: "dagger", Wx: 600.000000, Wy: 0.000000},
"daggerdbl": {GlyphName: "daggerdbl", Wx: 600.000000, Wy: 0.000000},
"dcaron": {GlyphName: "dcaron", Wx: 600.000000, Wy: 0.000000},
"dcroat": {GlyphName: "dcroat", Wx: 600.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 600.000000, Wy: 0.000000},
"dieresis": {GlyphName: "dieresis", Wx: 600.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 600.000000, Wy: 0.000000},
"dollar": {GlyphName: "dollar", Wx: 600.000000, Wy: 0.000000},
"dotaccent": {GlyphName: "dotaccent", Wx: 600.000000, Wy: 0.000000},
"dotlessi": {GlyphName: "dotlessi", Wx: 600.000000, Wy: 0.000000},
"e": {GlyphName: "e", Wx: 600.000000, Wy: 0.000000},
"eacute": {GlyphName: "eacute", Wx: 600.000000, Wy: 0.000000},
"ecaron": {GlyphName: "ecaron", Wx: 600.000000, Wy: 0.000000},
"ecircumflex": {GlyphName: "ecircumflex", Wx: 600.000000, Wy: 0.000000},
"edieresis": {GlyphName: "edieresis", Wx: 600.000000, Wy: 0.000000},
"edotaccent": {GlyphName: "edotaccent", Wx: 600.000000, Wy: 0.000000},
"egrave": {GlyphName: "egrave", Wx: 600.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 600.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 600.000000, Wy: 0.000000},
"emacron": {GlyphName: "emacron", Wx: 600.000000, Wy: 0.000000},
"emdash": {GlyphName: "emdash", Wx: 600.000000, Wy: 0.000000},
"endash": {GlyphName: "endash", Wx: 600.000000, Wy: 0.000000},
"eogonek": {GlyphName: "eogonek", Wx: 600.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 600.000000, Wy: 0.000000},
"eth": {GlyphName: "eth", Wx: 600.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 600.000000, Wy: 0.000000},
"exclamdown": {GlyphName: "exclamdown", Wx: 600.000000, Wy: 0.000000},
"f": {GlyphName: "f", Wx: 600.000000, Wy: 0.000000},
"fi": {GlyphName: "fi", Wx: 600.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 600.000000, Wy: 0.000000},
"fl": {GlyphName: "fl", Wx: 600.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 600.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 600.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 600.000000, Wy: 0.000000},
"g": {GlyphName: "g", Wx: 600.000000, Wy: 0.000000},
"gbreve": {GlyphName: "gbreve", Wx: 600.000000, Wy: 0.000000},
"gcommaaccent": {GlyphName: "gcommaaccent", Wx: 600.000000, Wy: 0.000000},
"germandbls": {GlyphName: "germandbls", Wx: 600.000000, Wy: 0.000000},
"grave": {GlyphName: "grave", Wx: 600.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 600.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 600.000000, Wy: 0.000000},
"guillemotleft": {GlyphName: "guillemotleft", Wx: 600.000000, Wy: 0.000000},
"guillemotright": {GlyphName: "guillemotright", Wx: 600.000000, Wy: 0.000000},
"guilsinglleft": {GlyphName: "guilsinglleft", Wx: 600.000000, Wy: 0.000000},
"guilsinglright": {GlyphName: "guilsinglright", Wx: 600.000000, Wy: 0.000000},
"h": {GlyphName: "h", Wx: 600.000000, Wy: 0.000000},
"hungarumlaut": {GlyphName: "hungarumlaut", Wx: 600.000000, Wy: 0.000000},
"hyphen": {GlyphName: "hyphen", Wx: 600.000000, Wy: 0.000000},
"i": {GlyphName: "i", Wx: 600.000000, Wy: 0.000000},
"iacute": {GlyphName: "iacute", Wx: 600.000000, Wy: 0.000000},
"icircumflex": {GlyphName: "icircumflex", Wx: 600.000000, Wy: 0.000000},
"idieresis": {GlyphName: "idieresis", Wx: 600.000000, Wy: 0.000000},
"igrave": {GlyphName: "igrave", Wx: 600.000000, Wy: 0.000000},
"imacron": {GlyphName: "imacron", Wx: 600.000000, Wy: 0.000000},
"iogonek": {GlyphName: "iogonek", Wx: 600.000000, Wy: 0.000000},
"j": {GlyphName: "j", Wx: 600.000000, Wy: 0.000000},
"k": {GlyphName: "k", Wx: 600.000000, Wy: 0.000000},
"kcommaaccent": {GlyphName: "kcommaaccent", Wx: 600.000000, Wy: 0.000000},
"l": {GlyphName: "l", Wx: 600.000000, Wy: 0.000000},
"lacute": {GlyphName: "lacute", Wx: 600.000000, Wy: 0.000000},
"lcaron": {GlyphName: "lcaron", Wx: 600.000000, Wy: 0.000000},
"lcommaaccent": {GlyphName: "lcommaaccent", Wx: 600.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 600.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 600.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 600.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 600.000000, Wy: 0.000000},
"lslash": {GlyphName: "lslash", Wx: 600.000000, Wy: 0.000000},
"m": {GlyphName: "m", Wx: 600.000000, Wy: 0.000000},
"macron": {GlyphName: "macron", Wx: 600.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 600.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 600.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 600.000000, Wy: 0.000000},
"n": {GlyphName: "n", Wx: 600.000000, Wy: 0.000000},
"nacute": {GlyphName: "nacute", Wx: 600.000000, Wy: 0.000000},
"ncaron": {GlyphName: "ncaron", Wx: 600.000000, Wy: 0.000000},
"ncommaaccent": {GlyphName: "ncommaaccent", Wx: 600.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 600.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 600.000000, Wy: 0.000000},
"ntilde": {GlyphName: "ntilde", Wx: 600.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 600.000000, Wy: 0.000000},
"o": {GlyphName: "o", Wx: 600.000000, Wy: 0.000000},
"oacute": {GlyphName: "oacute", Wx: 600.000000, Wy: 0.000000},
"ocircumflex": {GlyphName: "ocircumflex", Wx: 600.000000, Wy: 0.000000},
"odieresis": {GlyphName: "odieresis", Wx: 600.000000, Wy: 0.000000},
"oe": {GlyphName: "oe", Wx: 600.000000, Wy: 0.000000},
"ogonek": {GlyphName: "ogonek", Wx: 600.000000, Wy: 0.000000},
"ograve": {GlyphName: "ograve", Wx: 600.000000, Wy: 0.000000},
"ohungarumlaut": {GlyphName: "ohungarumlaut", Wx: 600.000000, Wy: 0.000000},
"omacron": {GlyphName: "omacron", Wx: 600.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 600.000000, Wy: 0.000000},
"onehalf": {GlyphName: "onehalf", Wx: 600.000000, Wy: 0.000000},
"onequarter": {GlyphName: "onequarter", Wx: 600.000000, Wy: 0.000000},
"onesuperior": {GlyphName: "onesuperior", Wx: 600.000000, Wy: 0.000000},
"ordfeminine": {GlyphName: "ordfeminine", Wx: 600.000000, Wy: 0.000000},
"ordmasculine": {GlyphName: "ordmasculine", Wx: 600.000000, Wy: 0.000000},
"oslash": {GlyphName: "oslash", Wx: 600.000000, Wy: 0.000000},
"otilde": {GlyphName: "otilde", Wx: 600.000000, Wy: 0.000000},
"p": {GlyphName: "p", Wx: 600.000000, Wy: 0.000000},
"paragraph": {GlyphName: "paragraph", Wx: 600.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 600.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 600.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 600.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 600.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 600.000000, Wy: 0.000000},
"periodcentered": {GlyphName: "periodcentered", Wx: 600.000000, Wy: 0.000000},
"perthousand": {GlyphName: "perthousand", Wx: 600.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 600.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 600.000000, Wy: 0.000000},
"q": {GlyphName: "q", Wx: 600.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 600.000000, Wy: 0.000000},
"questiondown": {GlyphName: "questiondown", Wx: 600.000000, Wy: 0.000000},
"quotedbl": {GlyphName: "quotedbl", Wx: 600.000000, Wy: 0.000000},
"quotedblbase": {GlyphName: "quotedblbase", Wx: 600.000000, Wy: 0.000000},
"quotedblleft": {GlyphName: "quotedblleft", Wx: 600.000000, Wy: 0.000000},
"quotedblright": {GlyphName: "quotedblright", Wx: 600.000000, Wy: 0.000000},
"quoteleft": {GlyphName: "quoteleft", Wx: 600.000000, Wy: 0.000000},
"quoteright": {GlyphName: "quoteright", Wx: 600.000000, Wy: 0.000000},
"quotesinglbase": {GlyphName: "quotesinglbase", Wx: 600.000000, Wy: 0.000000},
"quotesingle": {GlyphName: "quotesingle", Wx: 600.000000, Wy: 0.000000},
"r": {GlyphName: "r", Wx: 600.000000, Wy: 0.000000},
"racute": {GlyphName: "racute", Wx: 600.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 600.000000, Wy: 0.000000},
"rcaron": {GlyphName: "rcaron", Wx: 600.000000, Wy: 0.000000},
"rcommaaccent": {GlyphName: "rcommaaccent", Wx: 600.000000, Wy: 0.000000},
"registered": {GlyphName: "registered", Wx: 600.000000, Wy: 0.000000},
"ring": {GlyphName: "ring", Wx: 600.000000, Wy: 0.000000},
"s": {GlyphName: "s", Wx: 600.000000, Wy: 0.000000},
"sacute": {GlyphName: "sacute", Wx: 600.000000, Wy: 0.000000},
"scaron": {GlyphName: "scaron", Wx: 600.000000, Wy: 0.000000},
"scedilla": {GlyphName: "scedilla", Wx: 600.000000, Wy: 0.000000},
"scommaaccent": {GlyphName: "scommaaccent", Wx: 600.000000, Wy: 0.000000},
"section": {GlyphName: "section", Wx: 600.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 600.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 600.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 600.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 600.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 600.000000, Wy: 0.000000},
"sterling": {GlyphName: "sterling", Wx: 600.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 600.000000, Wy: 0.000000},
"t": {GlyphName: "t", Wx: 600.000000, Wy: 0.000000},
"tcaron": {GlyphName: "tcaron", Wx: 600.000000, Wy: 0.000000},
"tcommaaccent": {GlyphName: "tcommaaccent", Wx: 600.000000, Wy: 0.000000},
"thorn": {GlyphName: "thorn", Wx: 600.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 600.000000, Wy: 0.000000},
"threequarters": {GlyphName: "threequarters", Wx: 600.000000, Wy: 0.000000},
"threesuperior": {GlyphName: "threesuperior", Wx: 600.000000, Wy: 0.000000},
"tilde": {GlyphName: "tilde", Wx: 600.000000, Wy: 0.000000},
"trademark": {GlyphName: "trademark", Wx: 600.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 600.000000, Wy: 0.000000},
"twosuperior": {GlyphName: "twosuperior", Wx: 600.000000, Wy: 0.000000},
"u": {GlyphName: "u", Wx: 600.000000, Wy: 0.000000},
"uacute": {GlyphName: "uacute", Wx: 600.000000, Wy: 0.000000},
"ucircumflex": {GlyphName: "ucircumflex", Wx: 600.000000, Wy: 0.000000},
"udieresis": {GlyphName: "udieresis", Wx: 600.000000, Wy: 0.000000},
"ugrave": {GlyphName: "ugrave", Wx: 600.000000, Wy: 0.000000},
"uhungarumlaut": {GlyphName: "uhungarumlaut", Wx: 600.000000, Wy: 0.000000},
"umacron": {GlyphName: "umacron", Wx: 600.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 600.000000, Wy: 0.000000},
"uogonek": {GlyphName: "uogonek", Wx: 600.000000, Wy: 0.000000},
"uring": {GlyphName: "uring", Wx: 600.000000, Wy: 0.000000},
"v": {GlyphName: "v", Wx: 600.000000, Wy: 0.000000},
"w": {GlyphName: "w", Wx: 600.000000, Wy: 0.000000},
"x": {GlyphName: "x", Wx: 600.000000, Wy: 0.000000},
"y": {GlyphName: "y", Wx: 600.000000, Wy: 0.000000},
"yacute": {GlyphName: "yacute", Wx: 600.000000, Wy: 0.000000},
"ydieresis": {GlyphName: "ydieresis", Wx: 600.000000, Wy: 0.000000},
"yen": {GlyphName: "yen", Wx: 600.000000, Wy: 0.000000},
"z": {GlyphName: "z", Wx: 600.000000, Wy: 0.000000},
"zacute": {GlyphName: "zacute", Wx: 600.000000, Wy: 0.000000},
"zcaron": {GlyphName: "zcaron", Wx: 600.000000, Wy: 0.000000},
"zdotaccent": {GlyphName: "zdotaccent", Wx: 600.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 600.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,362 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Courier-BoldOblique. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontCourierBoldOblique struct {
encoder textencoding.TextEncoder
}
func NewFontCourierBoldOblique() fontCourierBoldOblique {
font := fontCourierBoldOblique{}
font.encoder = textencoding.NewWinAnsiTextEncoder() // Default
return font
}
func (font fontCourierBoldOblique) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontCourierBoldOblique) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := courierBoldObliqueCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontCourierBoldOblique) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Courier-BoldOblique"))
fontDict.Set("Encoding", font.encoder.ToPdfObject())
obj.PdfObject = fontDict
return obj
}
var courierBoldObliqueCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"A": {GlyphName: "A", Wx: 600.000000, Wy: 0.000000},
"AE": {GlyphName: "AE", Wx: 600.000000, Wy: 0.000000},
"Aacute": {GlyphName: "Aacute", Wx: 600.000000, Wy: 0.000000},
"Abreve": {GlyphName: "Abreve", Wx: 600.000000, Wy: 0.000000},
"Acircumflex": {GlyphName: "Acircumflex", Wx: 600.000000, Wy: 0.000000},
"Adieresis": {GlyphName: "Adieresis", Wx: 600.000000, Wy: 0.000000},
"Agrave": {GlyphName: "Agrave", Wx: 600.000000, Wy: 0.000000},
"Amacron": {GlyphName: "Amacron", Wx: 600.000000, Wy: 0.000000},
"Aogonek": {GlyphName: "Aogonek", Wx: 600.000000, Wy: 0.000000},
"Aring": {GlyphName: "Aring", Wx: 600.000000, Wy: 0.000000},
"Atilde": {GlyphName: "Atilde", Wx: 600.000000, Wy: 0.000000},
"B": {GlyphName: "B", Wx: 600.000000, Wy: 0.000000},
"C": {GlyphName: "C", Wx: 600.000000, Wy: 0.000000},
"Cacute": {GlyphName: "Cacute", Wx: 600.000000, Wy: 0.000000},
"Ccaron": {GlyphName: "Ccaron", Wx: 600.000000, Wy: 0.000000},
"Ccedilla": {GlyphName: "Ccedilla", Wx: 600.000000, Wy: 0.000000},
"D": {GlyphName: "D", Wx: 600.000000, Wy: 0.000000},
"Dcaron": {GlyphName: "Dcaron", Wx: 600.000000, Wy: 0.000000},
"Dcroat": {GlyphName: "Dcroat", Wx: 600.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 600.000000, Wy: 0.000000},
"E": {GlyphName: "E", Wx: 600.000000, Wy: 0.000000},
"Eacute": {GlyphName: "Eacute", Wx: 600.000000, Wy: 0.000000},
"Ecaron": {GlyphName: "Ecaron", Wx: 600.000000, Wy: 0.000000},
"Ecircumflex": {GlyphName: "Ecircumflex", Wx: 600.000000, Wy: 0.000000},
"Edieresis": {GlyphName: "Edieresis", Wx: 600.000000, Wy: 0.000000},
"Edotaccent": {GlyphName: "Edotaccent", Wx: 600.000000, Wy: 0.000000},
"Egrave": {GlyphName: "Egrave", Wx: 600.000000, Wy: 0.000000},
"Emacron": {GlyphName: "Emacron", Wx: 600.000000, Wy: 0.000000},
"Eogonek": {GlyphName: "Eogonek", Wx: 600.000000, Wy: 0.000000},
"Eth": {GlyphName: "Eth", Wx: 600.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 600.000000, Wy: 0.000000},
"F": {GlyphName: "F", Wx: 600.000000, Wy: 0.000000},
"G": {GlyphName: "G", Wx: 600.000000, Wy: 0.000000},
"Gbreve": {GlyphName: "Gbreve", Wx: 600.000000, Wy: 0.000000},
"Gcommaaccent": {GlyphName: "Gcommaaccent", Wx: 600.000000, Wy: 0.000000},
"H": {GlyphName: "H", Wx: 600.000000, Wy: 0.000000},
"I": {GlyphName: "I", Wx: 600.000000, Wy: 0.000000},
"Iacute": {GlyphName: "Iacute", Wx: 600.000000, Wy: 0.000000},
"Icircumflex": {GlyphName: "Icircumflex", Wx: 600.000000, Wy: 0.000000},
"Idieresis": {GlyphName: "Idieresis", Wx: 600.000000, Wy: 0.000000},
"Idotaccent": {GlyphName: "Idotaccent", Wx: 600.000000, Wy: 0.000000},
"Igrave": {GlyphName: "Igrave", Wx: 600.000000, Wy: 0.000000},
"Imacron": {GlyphName: "Imacron", Wx: 600.000000, Wy: 0.000000},
"Iogonek": {GlyphName: "Iogonek", Wx: 600.000000, Wy: 0.000000},
"J": {GlyphName: "J", Wx: 600.000000, Wy: 0.000000},
"K": {GlyphName: "K", Wx: 600.000000, Wy: 0.000000},
"Kcommaaccent": {GlyphName: "Kcommaaccent", Wx: 600.000000, Wy: 0.000000},
"L": {GlyphName: "L", Wx: 600.000000, Wy: 0.000000},
"Lacute": {GlyphName: "Lacute", Wx: 600.000000, Wy: 0.000000},
"Lcaron": {GlyphName: "Lcaron", Wx: 600.000000, Wy: 0.000000},
"Lcommaaccent": {GlyphName: "Lcommaaccent", Wx: 600.000000, Wy: 0.000000},
"Lslash": {GlyphName: "Lslash", Wx: 600.000000, Wy: 0.000000},
"M": {GlyphName: "M", Wx: 600.000000, Wy: 0.000000},
"N": {GlyphName: "N", Wx: 600.000000, Wy: 0.000000},
"Nacute": {GlyphName: "Nacute", Wx: 600.000000, Wy: 0.000000},
"Ncaron": {GlyphName: "Ncaron", Wx: 600.000000, Wy: 0.000000},
"Ncommaaccent": {GlyphName: "Ncommaaccent", Wx: 600.000000, Wy: 0.000000},
"Ntilde": {GlyphName: "Ntilde", Wx: 600.000000, Wy: 0.000000},
"O": {GlyphName: "O", Wx: 600.000000, Wy: 0.000000},
"OE": {GlyphName: "OE", Wx: 600.000000, Wy: 0.000000},
"Oacute": {GlyphName: "Oacute", Wx: 600.000000, Wy: 0.000000},
"Ocircumflex": {GlyphName: "Ocircumflex", Wx: 600.000000, Wy: 0.000000},
"Odieresis": {GlyphName: "Odieresis", Wx: 600.000000, Wy: 0.000000},
"Ograve": {GlyphName: "Ograve", Wx: 600.000000, Wy: 0.000000},
"Ohungarumlaut": {GlyphName: "Ohungarumlaut", Wx: 600.000000, Wy: 0.000000},
"Omacron": {GlyphName: "Omacron", Wx: 600.000000, Wy: 0.000000},
"Oslash": {GlyphName: "Oslash", Wx: 600.000000, Wy: 0.000000},
"Otilde": {GlyphName: "Otilde", Wx: 600.000000, Wy: 0.000000},
"P": {GlyphName: "P", Wx: 600.000000, Wy: 0.000000},
"Q": {GlyphName: "Q", Wx: 600.000000, Wy: 0.000000},
"R": {GlyphName: "R", Wx: 600.000000, Wy: 0.000000},
"Racute": {GlyphName: "Racute", Wx: 600.000000, Wy: 0.000000},
"Rcaron": {GlyphName: "Rcaron", Wx: 600.000000, Wy: 0.000000},
"Rcommaaccent": {GlyphName: "Rcommaaccent", Wx: 600.000000, Wy: 0.000000},
"S": {GlyphName: "S", Wx: 600.000000, Wy: 0.000000},
"Sacute": {GlyphName: "Sacute", Wx: 600.000000, Wy: 0.000000},
"Scaron": {GlyphName: "Scaron", Wx: 600.000000, Wy: 0.000000},
"Scedilla": {GlyphName: "Scedilla", Wx: 600.000000, Wy: 0.000000},
"Scommaaccent": {GlyphName: "Scommaaccent", Wx: 600.000000, Wy: 0.000000},
"T": {GlyphName: "T", Wx: 600.000000, Wy: 0.000000},
"Tcaron": {GlyphName: "Tcaron", Wx: 600.000000, Wy: 0.000000},
"Tcommaaccent": {GlyphName: "Tcommaaccent", Wx: 600.000000, Wy: 0.000000},
"Thorn": {GlyphName: "Thorn", Wx: 600.000000, Wy: 0.000000},
"U": {GlyphName: "U", Wx: 600.000000, Wy: 0.000000},
"Uacute": {GlyphName: "Uacute", Wx: 600.000000, Wy: 0.000000},
"Ucircumflex": {GlyphName: "Ucircumflex", Wx: 600.000000, Wy: 0.000000},
"Udieresis": {GlyphName: "Udieresis", Wx: 600.000000, Wy: 0.000000},
"Ugrave": {GlyphName: "Ugrave", Wx: 600.000000, Wy: 0.000000},
"Uhungarumlaut": {GlyphName: "Uhungarumlaut", Wx: 600.000000, Wy: 0.000000},
"Umacron": {GlyphName: "Umacron", Wx: 600.000000, Wy: 0.000000},
"Uogonek": {GlyphName: "Uogonek", Wx: 600.000000, Wy: 0.000000},
"Uring": {GlyphName: "Uring", Wx: 600.000000, Wy: 0.000000},
"V": {GlyphName: "V", Wx: 600.000000, Wy: 0.000000},
"W": {GlyphName: "W", Wx: 600.000000, Wy: 0.000000},
"X": {GlyphName: "X", Wx: 600.000000, Wy: 0.000000},
"Y": {GlyphName: "Y", Wx: 600.000000, Wy: 0.000000},
"Yacute": {GlyphName: "Yacute", Wx: 600.000000, Wy: 0.000000},
"Ydieresis": {GlyphName: "Ydieresis", Wx: 600.000000, Wy: 0.000000},
"Z": {GlyphName: "Z", Wx: 600.000000, Wy: 0.000000},
"Zacute": {GlyphName: "Zacute", Wx: 600.000000, Wy: 0.000000},
"Zcaron": {GlyphName: "Zcaron", Wx: 600.000000, Wy: 0.000000},
"Zdotaccent": {GlyphName: "Zdotaccent", Wx: 600.000000, Wy: 0.000000},
"a": {GlyphName: "a", Wx: 600.000000, Wy: 0.000000},
"aacute": {GlyphName: "aacute", Wx: 600.000000, Wy: 0.000000},
"abreve": {GlyphName: "abreve", Wx: 600.000000, Wy: 0.000000},
"acircumflex": {GlyphName: "acircumflex", Wx: 600.000000, Wy: 0.000000},
"acute": {GlyphName: "acute", Wx: 600.000000, Wy: 0.000000},
"adieresis": {GlyphName: "adieresis", Wx: 600.000000, Wy: 0.000000},
"ae": {GlyphName: "ae", Wx: 600.000000, Wy: 0.000000},
"agrave": {GlyphName: "agrave", Wx: 600.000000, Wy: 0.000000},
"amacron": {GlyphName: "amacron", Wx: 600.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 600.000000, Wy: 0.000000},
"aogonek": {GlyphName: "aogonek", Wx: 600.000000, Wy: 0.000000},
"aring": {GlyphName: "aring", Wx: 600.000000, Wy: 0.000000},
"asciicircum": {GlyphName: "asciicircum", Wx: 600.000000, Wy: 0.000000},
"asciitilde": {GlyphName: "asciitilde", Wx: 600.000000, Wy: 0.000000},
"asterisk": {GlyphName: "asterisk", Wx: 600.000000, Wy: 0.000000},
"at": {GlyphName: "at", Wx: 600.000000, Wy: 0.000000},
"atilde": {GlyphName: "atilde", Wx: 600.000000, Wy: 0.000000},
"b": {GlyphName: "b", Wx: 600.000000, Wy: 0.000000},
"backslash": {GlyphName: "backslash", Wx: 600.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 600.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 600.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 600.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 600.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 600.000000, Wy: 0.000000},
"breve": {GlyphName: "breve", Wx: 600.000000, Wy: 0.000000},
"brokenbar": {GlyphName: "brokenbar", Wx: 600.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 600.000000, Wy: 0.000000},
"c": {GlyphName: "c", Wx: 600.000000, Wy: 0.000000},
"cacute": {GlyphName: "cacute", Wx: 600.000000, Wy: 0.000000},
"caron": {GlyphName: "caron", Wx: 600.000000, Wy: 0.000000},
"ccaron": {GlyphName: "ccaron", Wx: 600.000000, Wy: 0.000000},
"ccedilla": {GlyphName: "ccedilla", Wx: 600.000000, Wy: 0.000000},
"cedilla": {GlyphName: "cedilla", Wx: 600.000000, Wy: 0.000000},
"cent": {GlyphName: "cent", Wx: 600.000000, Wy: 0.000000},
"circumflex": {GlyphName: "circumflex", Wx: 600.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 600.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 600.000000, Wy: 0.000000},
"commaaccent": {GlyphName: "commaaccent", Wx: 600.000000, Wy: 0.000000},
"copyright": {GlyphName: "copyright", Wx: 600.000000, Wy: 0.000000},
"currency": {GlyphName: "currency", Wx: 600.000000, Wy: 0.000000},
"d": {GlyphName: "d", Wx: 600.000000, Wy: 0.000000},
"dagger": {GlyphName: "dagger", Wx: 600.000000, Wy: 0.000000},
"daggerdbl": {GlyphName: "daggerdbl", Wx: 600.000000, Wy: 0.000000},
"dcaron": {GlyphName: "dcaron", Wx: 600.000000, Wy: 0.000000},
"dcroat": {GlyphName: "dcroat", Wx: 600.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 600.000000, Wy: 0.000000},
"dieresis": {GlyphName: "dieresis", Wx: 600.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 600.000000, Wy: 0.000000},
"dollar": {GlyphName: "dollar", Wx: 600.000000, Wy: 0.000000},
"dotaccent": {GlyphName: "dotaccent", Wx: 600.000000, Wy: 0.000000},
"dotlessi": {GlyphName: "dotlessi", Wx: 600.000000, Wy: 0.000000},
"e": {GlyphName: "e", Wx: 600.000000, Wy: 0.000000},
"eacute": {GlyphName: "eacute", Wx: 600.000000, Wy: 0.000000},
"ecaron": {GlyphName: "ecaron", Wx: 600.000000, Wy: 0.000000},
"ecircumflex": {GlyphName: "ecircumflex", Wx: 600.000000, Wy: 0.000000},
"edieresis": {GlyphName: "edieresis", Wx: 600.000000, Wy: 0.000000},
"edotaccent": {GlyphName: "edotaccent", Wx: 600.000000, Wy: 0.000000},
"egrave": {GlyphName: "egrave", Wx: 600.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 600.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 600.000000, Wy: 0.000000},
"emacron": {GlyphName: "emacron", Wx: 600.000000, Wy: 0.000000},
"emdash": {GlyphName: "emdash", Wx: 600.000000, Wy: 0.000000},
"endash": {GlyphName: "endash", Wx: 600.000000, Wy: 0.000000},
"eogonek": {GlyphName: "eogonek", Wx: 600.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 600.000000, Wy: 0.000000},
"eth": {GlyphName: "eth", Wx: 600.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 600.000000, Wy: 0.000000},
"exclamdown": {GlyphName: "exclamdown", Wx: 600.000000, Wy: 0.000000},
"f": {GlyphName: "f", Wx: 600.000000, Wy: 0.000000},
"fi": {GlyphName: "fi", Wx: 600.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 600.000000, Wy: 0.000000},
"fl": {GlyphName: "fl", Wx: 600.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 600.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 600.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 600.000000, Wy: 0.000000},
"g": {GlyphName: "g", Wx: 600.000000, Wy: 0.000000},
"gbreve": {GlyphName: "gbreve", Wx: 600.000000, Wy: 0.000000},
"gcommaaccent": {GlyphName: "gcommaaccent", Wx: 600.000000, Wy: 0.000000},
"germandbls": {GlyphName: "germandbls", Wx: 600.000000, Wy: 0.000000},
"grave": {GlyphName: "grave", Wx: 600.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 600.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 600.000000, Wy: 0.000000},
"guillemotleft": {GlyphName: "guillemotleft", Wx: 600.000000, Wy: 0.000000},
"guillemotright": {GlyphName: "guillemotright", Wx: 600.000000, Wy: 0.000000},
"guilsinglleft": {GlyphName: "guilsinglleft", Wx: 600.000000, Wy: 0.000000},
"guilsinglright": {GlyphName: "guilsinglright", Wx: 600.000000, Wy: 0.000000},
"h": {GlyphName: "h", Wx: 600.000000, Wy: 0.000000},
"hungarumlaut": {GlyphName: "hungarumlaut", Wx: 600.000000, Wy: 0.000000},
"hyphen": {GlyphName: "hyphen", Wx: 600.000000, Wy: 0.000000},
"i": {GlyphName: "i", Wx: 600.000000, Wy: 0.000000},
"iacute": {GlyphName: "iacute", Wx: 600.000000, Wy: 0.000000},
"icircumflex": {GlyphName: "icircumflex", Wx: 600.000000, Wy: 0.000000},
"idieresis": {GlyphName: "idieresis", Wx: 600.000000, Wy: 0.000000},
"igrave": {GlyphName: "igrave", Wx: 600.000000, Wy: 0.000000},
"imacron": {GlyphName: "imacron", Wx: 600.000000, Wy: 0.000000},
"iogonek": {GlyphName: "iogonek", Wx: 600.000000, Wy: 0.000000},
"j": {GlyphName: "j", Wx: 600.000000, Wy: 0.000000},
"k": {GlyphName: "k", Wx: 600.000000, Wy: 0.000000},
"kcommaaccent": {GlyphName: "kcommaaccent", Wx: 600.000000, Wy: 0.000000},
"l": {GlyphName: "l", Wx: 600.000000, Wy: 0.000000},
"lacute": {GlyphName: "lacute", Wx: 600.000000, Wy: 0.000000},
"lcaron": {GlyphName: "lcaron", Wx: 600.000000, Wy: 0.000000},
"lcommaaccent": {GlyphName: "lcommaaccent", Wx: 600.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 600.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 600.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 600.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 600.000000, Wy: 0.000000},
"lslash": {GlyphName: "lslash", Wx: 600.000000, Wy: 0.000000},
"m": {GlyphName: "m", Wx: 600.000000, Wy: 0.000000},
"macron": {GlyphName: "macron", Wx: 600.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 600.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 600.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 600.000000, Wy: 0.000000},
"n": {GlyphName: "n", Wx: 600.000000, Wy: 0.000000},
"nacute": {GlyphName: "nacute", Wx: 600.000000, Wy: 0.000000},
"ncaron": {GlyphName: "ncaron", Wx: 600.000000, Wy: 0.000000},
"ncommaaccent": {GlyphName: "ncommaaccent", Wx: 600.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 600.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 600.000000, Wy: 0.000000},
"ntilde": {GlyphName: "ntilde", Wx: 600.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 600.000000, Wy: 0.000000},
"o": {GlyphName: "o", Wx: 600.000000, Wy: 0.000000},
"oacute": {GlyphName: "oacute", Wx: 600.000000, Wy: 0.000000},
"ocircumflex": {GlyphName: "ocircumflex", Wx: 600.000000, Wy: 0.000000},
"odieresis": {GlyphName: "odieresis", Wx: 600.000000, Wy: 0.000000},
"oe": {GlyphName: "oe", Wx: 600.000000, Wy: 0.000000},
"ogonek": {GlyphName: "ogonek", Wx: 600.000000, Wy: 0.000000},
"ograve": {GlyphName: "ograve", Wx: 600.000000, Wy: 0.000000},
"ohungarumlaut": {GlyphName: "ohungarumlaut", Wx: 600.000000, Wy: 0.000000},
"omacron": {GlyphName: "omacron", Wx: 600.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 600.000000, Wy: 0.000000},
"onehalf": {GlyphName: "onehalf", Wx: 600.000000, Wy: 0.000000},
"onequarter": {GlyphName: "onequarter", Wx: 600.000000, Wy: 0.000000},
"onesuperior": {GlyphName: "onesuperior", Wx: 600.000000, Wy: 0.000000},
"ordfeminine": {GlyphName: "ordfeminine", Wx: 600.000000, Wy: 0.000000},
"ordmasculine": {GlyphName: "ordmasculine", Wx: 600.000000, Wy: 0.000000},
"oslash": {GlyphName: "oslash", Wx: 600.000000, Wy: 0.000000},
"otilde": {GlyphName: "otilde", Wx: 600.000000, Wy: 0.000000},
"p": {GlyphName: "p", Wx: 600.000000, Wy: 0.000000},
"paragraph": {GlyphName: "paragraph", Wx: 600.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 600.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 600.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 600.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 600.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 600.000000, Wy: 0.000000},
"periodcentered": {GlyphName: "periodcentered", Wx: 600.000000, Wy: 0.000000},
"perthousand": {GlyphName: "perthousand", Wx: 600.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 600.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 600.000000, Wy: 0.000000},
"q": {GlyphName: "q", Wx: 600.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 600.000000, Wy: 0.000000},
"questiondown": {GlyphName: "questiondown", Wx: 600.000000, Wy: 0.000000},
"quotedbl": {GlyphName: "quotedbl", Wx: 600.000000, Wy: 0.000000},
"quotedblbase": {GlyphName: "quotedblbase", Wx: 600.000000, Wy: 0.000000},
"quotedblleft": {GlyphName: "quotedblleft", Wx: 600.000000, Wy: 0.000000},
"quotedblright": {GlyphName: "quotedblright", Wx: 600.000000, Wy: 0.000000},
"quoteleft": {GlyphName: "quoteleft", Wx: 600.000000, Wy: 0.000000},
"quoteright": {GlyphName: "quoteright", Wx: 600.000000, Wy: 0.000000},
"quotesinglbase": {GlyphName: "quotesinglbase", Wx: 600.000000, Wy: 0.000000},
"quotesingle": {GlyphName: "quotesingle", Wx: 600.000000, Wy: 0.000000},
"r": {GlyphName: "r", Wx: 600.000000, Wy: 0.000000},
"racute": {GlyphName: "racute", Wx: 600.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 600.000000, Wy: 0.000000},
"rcaron": {GlyphName: "rcaron", Wx: 600.000000, Wy: 0.000000},
"rcommaaccent": {GlyphName: "rcommaaccent", Wx: 600.000000, Wy: 0.000000},
"registered": {GlyphName: "registered", Wx: 600.000000, Wy: 0.000000},
"ring": {GlyphName: "ring", Wx: 600.000000, Wy: 0.000000},
"s": {GlyphName: "s", Wx: 600.000000, Wy: 0.000000},
"sacute": {GlyphName: "sacute", Wx: 600.000000, Wy: 0.000000},
"scaron": {GlyphName: "scaron", Wx: 600.000000, Wy: 0.000000},
"scedilla": {GlyphName: "scedilla", Wx: 600.000000, Wy: 0.000000},
"scommaaccent": {GlyphName: "scommaaccent", Wx: 600.000000, Wy: 0.000000},
"section": {GlyphName: "section", Wx: 600.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 600.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 600.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 600.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 600.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 600.000000, Wy: 0.000000},
"sterling": {GlyphName: "sterling", Wx: 600.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 600.000000, Wy: 0.000000},
"t": {GlyphName: "t", Wx: 600.000000, Wy: 0.000000},
"tcaron": {GlyphName: "tcaron", Wx: 600.000000, Wy: 0.000000},
"tcommaaccent": {GlyphName: "tcommaaccent", Wx: 600.000000, Wy: 0.000000},
"thorn": {GlyphName: "thorn", Wx: 600.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 600.000000, Wy: 0.000000},
"threequarters": {GlyphName: "threequarters", Wx: 600.000000, Wy: 0.000000},
"threesuperior": {GlyphName: "threesuperior", Wx: 600.000000, Wy: 0.000000},
"tilde": {GlyphName: "tilde", Wx: 600.000000, Wy: 0.000000},
"trademark": {GlyphName: "trademark", Wx: 600.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 600.000000, Wy: 0.000000},
"twosuperior": {GlyphName: "twosuperior", Wx: 600.000000, Wy: 0.000000},
"u": {GlyphName: "u", Wx: 600.000000, Wy: 0.000000},
"uacute": {GlyphName: "uacute", Wx: 600.000000, Wy: 0.000000},
"ucircumflex": {GlyphName: "ucircumflex", Wx: 600.000000, Wy: 0.000000},
"udieresis": {GlyphName: "udieresis", Wx: 600.000000, Wy: 0.000000},
"ugrave": {GlyphName: "ugrave", Wx: 600.000000, Wy: 0.000000},
"uhungarumlaut": {GlyphName: "uhungarumlaut", Wx: 600.000000, Wy: 0.000000},
"umacron": {GlyphName: "umacron", Wx: 600.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 600.000000, Wy: 0.000000},
"uogonek": {GlyphName: "uogonek", Wx: 600.000000, Wy: 0.000000},
"uring": {GlyphName: "uring", Wx: 600.000000, Wy: 0.000000},
"v": {GlyphName: "v", Wx: 600.000000, Wy: 0.000000},
"w": {GlyphName: "w", Wx: 600.000000, Wy: 0.000000},
"x": {GlyphName: "x", Wx: 600.000000, Wy: 0.000000},
"y": {GlyphName: "y", Wx: 600.000000, Wy: 0.000000},
"yacute": {GlyphName: "yacute", Wx: 600.000000, Wy: 0.000000},
"ydieresis": {GlyphName: "ydieresis", Wx: 600.000000, Wy: 0.000000},
"yen": {GlyphName: "yen", Wx: 600.000000, Wy: 0.000000},
"z": {GlyphName: "z", Wx: 600.000000, Wy: 0.000000},
"zacute": {GlyphName: "zacute", Wx: 600.000000, Wy: 0.000000},
"zcaron": {GlyphName: "zcaron", Wx: 600.000000, Wy: 0.000000},
"zdotaccent": {GlyphName: "zdotaccent", Wx: 600.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 600.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,362 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Courier-Oblique. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontCourierOblique struct {
encoder textencoding.TextEncoder
}
func NewFontCourierOblique() fontCourierOblique {
font := fontCourierOblique{}
font.encoder = textencoding.NewWinAnsiTextEncoder() // Default
return font
}
func (font fontCourierOblique) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontCourierOblique) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := courierObliqueCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontCourierOblique) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Courier-Oblique"))
fontDict.Set("Encoding", font.encoder.ToPdfObject())
obj.PdfObject = fontDict
return obj
}
var courierObliqueCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"A": {GlyphName: "A", Wx: 600.000000, Wy: 0.000000},
"AE": {GlyphName: "AE", Wx: 600.000000, Wy: 0.000000},
"Aacute": {GlyphName: "Aacute", Wx: 600.000000, Wy: 0.000000},
"Abreve": {GlyphName: "Abreve", Wx: 600.000000, Wy: 0.000000},
"Acircumflex": {GlyphName: "Acircumflex", Wx: 600.000000, Wy: 0.000000},
"Adieresis": {GlyphName: "Adieresis", Wx: 600.000000, Wy: 0.000000},
"Agrave": {GlyphName: "Agrave", Wx: 600.000000, Wy: 0.000000},
"Amacron": {GlyphName: "Amacron", Wx: 600.000000, Wy: 0.000000},
"Aogonek": {GlyphName: "Aogonek", Wx: 600.000000, Wy: 0.000000},
"Aring": {GlyphName: "Aring", Wx: 600.000000, Wy: 0.000000},
"Atilde": {GlyphName: "Atilde", Wx: 600.000000, Wy: 0.000000},
"B": {GlyphName: "B", Wx: 600.000000, Wy: 0.000000},
"C": {GlyphName: "C", Wx: 600.000000, Wy: 0.000000},
"Cacute": {GlyphName: "Cacute", Wx: 600.000000, Wy: 0.000000},
"Ccaron": {GlyphName: "Ccaron", Wx: 600.000000, Wy: 0.000000},
"Ccedilla": {GlyphName: "Ccedilla", Wx: 600.000000, Wy: 0.000000},
"D": {GlyphName: "D", Wx: 600.000000, Wy: 0.000000},
"Dcaron": {GlyphName: "Dcaron", Wx: 600.000000, Wy: 0.000000},
"Dcroat": {GlyphName: "Dcroat", Wx: 600.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 600.000000, Wy: 0.000000},
"E": {GlyphName: "E", Wx: 600.000000, Wy: 0.000000},
"Eacute": {GlyphName: "Eacute", Wx: 600.000000, Wy: 0.000000},
"Ecaron": {GlyphName: "Ecaron", Wx: 600.000000, Wy: 0.000000},
"Ecircumflex": {GlyphName: "Ecircumflex", Wx: 600.000000, Wy: 0.000000},
"Edieresis": {GlyphName: "Edieresis", Wx: 600.000000, Wy: 0.000000},
"Edotaccent": {GlyphName: "Edotaccent", Wx: 600.000000, Wy: 0.000000},
"Egrave": {GlyphName: "Egrave", Wx: 600.000000, Wy: 0.000000},
"Emacron": {GlyphName: "Emacron", Wx: 600.000000, Wy: 0.000000},
"Eogonek": {GlyphName: "Eogonek", Wx: 600.000000, Wy: 0.000000},
"Eth": {GlyphName: "Eth", Wx: 600.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 600.000000, Wy: 0.000000},
"F": {GlyphName: "F", Wx: 600.000000, Wy: 0.000000},
"G": {GlyphName: "G", Wx: 600.000000, Wy: 0.000000},
"Gbreve": {GlyphName: "Gbreve", Wx: 600.000000, Wy: 0.000000},
"Gcommaaccent": {GlyphName: "Gcommaaccent", Wx: 600.000000, Wy: 0.000000},
"H": {GlyphName: "H", Wx: 600.000000, Wy: 0.000000},
"I": {GlyphName: "I", Wx: 600.000000, Wy: 0.000000},
"Iacute": {GlyphName: "Iacute", Wx: 600.000000, Wy: 0.000000},
"Icircumflex": {GlyphName: "Icircumflex", Wx: 600.000000, Wy: 0.000000},
"Idieresis": {GlyphName: "Idieresis", Wx: 600.000000, Wy: 0.000000},
"Idotaccent": {GlyphName: "Idotaccent", Wx: 600.000000, Wy: 0.000000},
"Igrave": {GlyphName: "Igrave", Wx: 600.000000, Wy: 0.000000},
"Imacron": {GlyphName: "Imacron", Wx: 600.000000, Wy: 0.000000},
"Iogonek": {GlyphName: "Iogonek", Wx: 600.000000, Wy: 0.000000},
"J": {GlyphName: "J", Wx: 600.000000, Wy: 0.000000},
"K": {GlyphName: "K", Wx: 600.000000, Wy: 0.000000},
"Kcommaaccent": {GlyphName: "Kcommaaccent", Wx: 600.000000, Wy: 0.000000},
"L": {GlyphName: "L", Wx: 600.000000, Wy: 0.000000},
"Lacute": {GlyphName: "Lacute", Wx: 600.000000, Wy: 0.000000},
"Lcaron": {GlyphName: "Lcaron", Wx: 600.000000, Wy: 0.000000},
"Lcommaaccent": {GlyphName: "Lcommaaccent", Wx: 600.000000, Wy: 0.000000},
"Lslash": {GlyphName: "Lslash", Wx: 600.000000, Wy: 0.000000},
"M": {GlyphName: "M", Wx: 600.000000, Wy: 0.000000},
"N": {GlyphName: "N", Wx: 600.000000, Wy: 0.000000},
"Nacute": {GlyphName: "Nacute", Wx: 600.000000, Wy: 0.000000},
"Ncaron": {GlyphName: "Ncaron", Wx: 600.000000, Wy: 0.000000},
"Ncommaaccent": {GlyphName: "Ncommaaccent", Wx: 600.000000, Wy: 0.000000},
"Ntilde": {GlyphName: "Ntilde", Wx: 600.000000, Wy: 0.000000},
"O": {GlyphName: "O", Wx: 600.000000, Wy: 0.000000},
"OE": {GlyphName: "OE", Wx: 600.000000, Wy: 0.000000},
"Oacute": {GlyphName: "Oacute", Wx: 600.000000, Wy: 0.000000},
"Ocircumflex": {GlyphName: "Ocircumflex", Wx: 600.000000, Wy: 0.000000},
"Odieresis": {GlyphName: "Odieresis", Wx: 600.000000, Wy: 0.000000},
"Ograve": {GlyphName: "Ograve", Wx: 600.000000, Wy: 0.000000},
"Ohungarumlaut": {GlyphName: "Ohungarumlaut", Wx: 600.000000, Wy: 0.000000},
"Omacron": {GlyphName: "Omacron", Wx: 600.000000, Wy: 0.000000},
"Oslash": {GlyphName: "Oslash", Wx: 600.000000, Wy: 0.000000},
"Otilde": {GlyphName: "Otilde", Wx: 600.000000, Wy: 0.000000},
"P": {GlyphName: "P", Wx: 600.000000, Wy: 0.000000},
"Q": {GlyphName: "Q", Wx: 600.000000, Wy: 0.000000},
"R": {GlyphName: "R", Wx: 600.000000, Wy: 0.000000},
"Racute": {GlyphName: "Racute", Wx: 600.000000, Wy: 0.000000},
"Rcaron": {GlyphName: "Rcaron", Wx: 600.000000, Wy: 0.000000},
"Rcommaaccent": {GlyphName: "Rcommaaccent", Wx: 600.000000, Wy: 0.000000},
"S": {GlyphName: "S", Wx: 600.000000, Wy: 0.000000},
"Sacute": {GlyphName: "Sacute", Wx: 600.000000, Wy: 0.000000},
"Scaron": {GlyphName: "Scaron", Wx: 600.000000, Wy: 0.000000},
"Scedilla": {GlyphName: "Scedilla", Wx: 600.000000, Wy: 0.000000},
"Scommaaccent": {GlyphName: "Scommaaccent", Wx: 600.000000, Wy: 0.000000},
"T": {GlyphName: "T", Wx: 600.000000, Wy: 0.000000},
"Tcaron": {GlyphName: "Tcaron", Wx: 600.000000, Wy: 0.000000},
"Tcommaaccent": {GlyphName: "Tcommaaccent", Wx: 600.000000, Wy: 0.000000},
"Thorn": {GlyphName: "Thorn", Wx: 600.000000, Wy: 0.000000},
"U": {GlyphName: "U", Wx: 600.000000, Wy: 0.000000},
"Uacute": {GlyphName: "Uacute", Wx: 600.000000, Wy: 0.000000},
"Ucircumflex": {GlyphName: "Ucircumflex", Wx: 600.000000, Wy: 0.000000},
"Udieresis": {GlyphName: "Udieresis", Wx: 600.000000, Wy: 0.000000},
"Ugrave": {GlyphName: "Ugrave", Wx: 600.000000, Wy: 0.000000},
"Uhungarumlaut": {GlyphName: "Uhungarumlaut", Wx: 600.000000, Wy: 0.000000},
"Umacron": {GlyphName: "Umacron", Wx: 600.000000, Wy: 0.000000},
"Uogonek": {GlyphName: "Uogonek", Wx: 600.000000, Wy: 0.000000},
"Uring": {GlyphName: "Uring", Wx: 600.000000, Wy: 0.000000},
"V": {GlyphName: "V", Wx: 600.000000, Wy: 0.000000},
"W": {GlyphName: "W", Wx: 600.000000, Wy: 0.000000},
"X": {GlyphName: "X", Wx: 600.000000, Wy: 0.000000},
"Y": {GlyphName: "Y", Wx: 600.000000, Wy: 0.000000},
"Yacute": {GlyphName: "Yacute", Wx: 600.000000, Wy: 0.000000},
"Ydieresis": {GlyphName: "Ydieresis", Wx: 600.000000, Wy: 0.000000},
"Z": {GlyphName: "Z", Wx: 600.000000, Wy: 0.000000},
"Zacute": {GlyphName: "Zacute", Wx: 600.000000, Wy: 0.000000},
"Zcaron": {GlyphName: "Zcaron", Wx: 600.000000, Wy: 0.000000},
"Zdotaccent": {GlyphName: "Zdotaccent", Wx: 600.000000, Wy: 0.000000},
"a": {GlyphName: "a", Wx: 600.000000, Wy: 0.000000},
"aacute": {GlyphName: "aacute", Wx: 600.000000, Wy: 0.000000},
"abreve": {GlyphName: "abreve", Wx: 600.000000, Wy: 0.000000},
"acircumflex": {GlyphName: "acircumflex", Wx: 600.000000, Wy: 0.000000},
"acute": {GlyphName: "acute", Wx: 600.000000, Wy: 0.000000},
"adieresis": {GlyphName: "adieresis", Wx: 600.000000, Wy: 0.000000},
"ae": {GlyphName: "ae", Wx: 600.000000, Wy: 0.000000},
"agrave": {GlyphName: "agrave", Wx: 600.000000, Wy: 0.000000},
"amacron": {GlyphName: "amacron", Wx: 600.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 600.000000, Wy: 0.000000},
"aogonek": {GlyphName: "aogonek", Wx: 600.000000, Wy: 0.000000},
"aring": {GlyphName: "aring", Wx: 600.000000, Wy: 0.000000},
"asciicircum": {GlyphName: "asciicircum", Wx: 600.000000, Wy: 0.000000},
"asciitilde": {GlyphName: "asciitilde", Wx: 600.000000, Wy: 0.000000},
"asterisk": {GlyphName: "asterisk", Wx: 600.000000, Wy: 0.000000},
"at": {GlyphName: "at", Wx: 600.000000, Wy: 0.000000},
"atilde": {GlyphName: "atilde", Wx: 600.000000, Wy: 0.000000},
"b": {GlyphName: "b", Wx: 600.000000, Wy: 0.000000},
"backslash": {GlyphName: "backslash", Wx: 600.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 600.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 600.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 600.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 600.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 600.000000, Wy: 0.000000},
"breve": {GlyphName: "breve", Wx: 600.000000, Wy: 0.000000},
"brokenbar": {GlyphName: "brokenbar", Wx: 600.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 600.000000, Wy: 0.000000},
"c": {GlyphName: "c", Wx: 600.000000, Wy: 0.000000},
"cacute": {GlyphName: "cacute", Wx: 600.000000, Wy: 0.000000},
"caron": {GlyphName: "caron", Wx: 600.000000, Wy: 0.000000},
"ccaron": {GlyphName: "ccaron", Wx: 600.000000, Wy: 0.000000},
"ccedilla": {GlyphName: "ccedilla", Wx: 600.000000, Wy: 0.000000},
"cedilla": {GlyphName: "cedilla", Wx: 600.000000, Wy: 0.000000},
"cent": {GlyphName: "cent", Wx: 600.000000, Wy: 0.000000},
"circumflex": {GlyphName: "circumflex", Wx: 600.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 600.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 600.000000, Wy: 0.000000},
"commaaccent": {GlyphName: "commaaccent", Wx: 600.000000, Wy: 0.000000},
"copyright": {GlyphName: "copyright", Wx: 600.000000, Wy: 0.000000},
"currency": {GlyphName: "currency", Wx: 600.000000, Wy: 0.000000},
"d": {GlyphName: "d", Wx: 600.000000, Wy: 0.000000},
"dagger": {GlyphName: "dagger", Wx: 600.000000, Wy: 0.000000},
"daggerdbl": {GlyphName: "daggerdbl", Wx: 600.000000, Wy: 0.000000},
"dcaron": {GlyphName: "dcaron", Wx: 600.000000, Wy: 0.000000},
"dcroat": {GlyphName: "dcroat", Wx: 600.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 600.000000, Wy: 0.000000},
"dieresis": {GlyphName: "dieresis", Wx: 600.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 600.000000, Wy: 0.000000},
"dollar": {GlyphName: "dollar", Wx: 600.000000, Wy: 0.000000},
"dotaccent": {GlyphName: "dotaccent", Wx: 600.000000, Wy: 0.000000},
"dotlessi": {GlyphName: "dotlessi", Wx: 600.000000, Wy: 0.000000},
"e": {GlyphName: "e", Wx: 600.000000, Wy: 0.000000},
"eacute": {GlyphName: "eacute", Wx: 600.000000, Wy: 0.000000},
"ecaron": {GlyphName: "ecaron", Wx: 600.000000, Wy: 0.000000},
"ecircumflex": {GlyphName: "ecircumflex", Wx: 600.000000, Wy: 0.000000},
"edieresis": {GlyphName: "edieresis", Wx: 600.000000, Wy: 0.000000},
"edotaccent": {GlyphName: "edotaccent", Wx: 600.000000, Wy: 0.000000},
"egrave": {GlyphName: "egrave", Wx: 600.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 600.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 600.000000, Wy: 0.000000},
"emacron": {GlyphName: "emacron", Wx: 600.000000, Wy: 0.000000},
"emdash": {GlyphName: "emdash", Wx: 600.000000, Wy: 0.000000},
"endash": {GlyphName: "endash", Wx: 600.000000, Wy: 0.000000},
"eogonek": {GlyphName: "eogonek", Wx: 600.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 600.000000, Wy: 0.000000},
"eth": {GlyphName: "eth", Wx: 600.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 600.000000, Wy: 0.000000},
"exclamdown": {GlyphName: "exclamdown", Wx: 600.000000, Wy: 0.000000},
"f": {GlyphName: "f", Wx: 600.000000, Wy: 0.000000},
"fi": {GlyphName: "fi", Wx: 600.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 600.000000, Wy: 0.000000},
"fl": {GlyphName: "fl", Wx: 600.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 600.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 600.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 600.000000, Wy: 0.000000},
"g": {GlyphName: "g", Wx: 600.000000, Wy: 0.000000},
"gbreve": {GlyphName: "gbreve", Wx: 600.000000, Wy: 0.000000},
"gcommaaccent": {GlyphName: "gcommaaccent", Wx: 600.000000, Wy: 0.000000},
"germandbls": {GlyphName: "germandbls", Wx: 600.000000, Wy: 0.000000},
"grave": {GlyphName: "grave", Wx: 600.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 600.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 600.000000, Wy: 0.000000},
"guillemotleft": {GlyphName: "guillemotleft", Wx: 600.000000, Wy: 0.000000},
"guillemotright": {GlyphName: "guillemotright", Wx: 600.000000, Wy: 0.000000},
"guilsinglleft": {GlyphName: "guilsinglleft", Wx: 600.000000, Wy: 0.000000},
"guilsinglright": {GlyphName: "guilsinglright", Wx: 600.000000, Wy: 0.000000},
"h": {GlyphName: "h", Wx: 600.000000, Wy: 0.000000},
"hungarumlaut": {GlyphName: "hungarumlaut", Wx: 600.000000, Wy: 0.000000},
"hyphen": {GlyphName: "hyphen", Wx: 600.000000, Wy: 0.000000},
"i": {GlyphName: "i", Wx: 600.000000, Wy: 0.000000},
"iacute": {GlyphName: "iacute", Wx: 600.000000, Wy: 0.000000},
"icircumflex": {GlyphName: "icircumflex", Wx: 600.000000, Wy: 0.000000},
"idieresis": {GlyphName: "idieresis", Wx: 600.000000, Wy: 0.000000},
"igrave": {GlyphName: "igrave", Wx: 600.000000, Wy: 0.000000},
"imacron": {GlyphName: "imacron", Wx: 600.000000, Wy: 0.000000},
"iogonek": {GlyphName: "iogonek", Wx: 600.000000, Wy: 0.000000},
"j": {GlyphName: "j", Wx: 600.000000, Wy: 0.000000},
"k": {GlyphName: "k", Wx: 600.000000, Wy: 0.000000},
"kcommaaccent": {GlyphName: "kcommaaccent", Wx: 600.000000, Wy: 0.000000},
"l": {GlyphName: "l", Wx: 600.000000, Wy: 0.000000},
"lacute": {GlyphName: "lacute", Wx: 600.000000, Wy: 0.000000},
"lcaron": {GlyphName: "lcaron", Wx: 600.000000, Wy: 0.000000},
"lcommaaccent": {GlyphName: "lcommaaccent", Wx: 600.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 600.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 600.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 600.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 600.000000, Wy: 0.000000},
"lslash": {GlyphName: "lslash", Wx: 600.000000, Wy: 0.000000},
"m": {GlyphName: "m", Wx: 600.000000, Wy: 0.000000},
"macron": {GlyphName: "macron", Wx: 600.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 600.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 600.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 600.000000, Wy: 0.000000},
"n": {GlyphName: "n", Wx: 600.000000, Wy: 0.000000},
"nacute": {GlyphName: "nacute", Wx: 600.000000, Wy: 0.000000},
"ncaron": {GlyphName: "ncaron", Wx: 600.000000, Wy: 0.000000},
"ncommaaccent": {GlyphName: "ncommaaccent", Wx: 600.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 600.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 600.000000, Wy: 0.000000},
"ntilde": {GlyphName: "ntilde", Wx: 600.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 600.000000, Wy: 0.000000},
"o": {GlyphName: "o", Wx: 600.000000, Wy: 0.000000},
"oacute": {GlyphName: "oacute", Wx: 600.000000, Wy: 0.000000},
"ocircumflex": {GlyphName: "ocircumflex", Wx: 600.000000, Wy: 0.000000},
"odieresis": {GlyphName: "odieresis", Wx: 600.000000, Wy: 0.000000},
"oe": {GlyphName: "oe", Wx: 600.000000, Wy: 0.000000},
"ogonek": {GlyphName: "ogonek", Wx: 600.000000, Wy: 0.000000},
"ograve": {GlyphName: "ograve", Wx: 600.000000, Wy: 0.000000},
"ohungarumlaut": {GlyphName: "ohungarumlaut", Wx: 600.000000, Wy: 0.000000},
"omacron": {GlyphName: "omacron", Wx: 600.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 600.000000, Wy: 0.000000},
"onehalf": {GlyphName: "onehalf", Wx: 600.000000, Wy: 0.000000},
"onequarter": {GlyphName: "onequarter", Wx: 600.000000, Wy: 0.000000},
"onesuperior": {GlyphName: "onesuperior", Wx: 600.000000, Wy: 0.000000},
"ordfeminine": {GlyphName: "ordfeminine", Wx: 600.000000, Wy: 0.000000},
"ordmasculine": {GlyphName: "ordmasculine", Wx: 600.000000, Wy: 0.000000},
"oslash": {GlyphName: "oslash", Wx: 600.000000, Wy: 0.000000},
"otilde": {GlyphName: "otilde", Wx: 600.000000, Wy: 0.000000},
"p": {GlyphName: "p", Wx: 600.000000, Wy: 0.000000},
"paragraph": {GlyphName: "paragraph", Wx: 600.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 600.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 600.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 600.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 600.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 600.000000, Wy: 0.000000},
"periodcentered": {GlyphName: "periodcentered", Wx: 600.000000, Wy: 0.000000},
"perthousand": {GlyphName: "perthousand", Wx: 600.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 600.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 600.000000, Wy: 0.000000},
"q": {GlyphName: "q", Wx: 600.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 600.000000, Wy: 0.000000},
"questiondown": {GlyphName: "questiondown", Wx: 600.000000, Wy: 0.000000},
"quotedbl": {GlyphName: "quotedbl", Wx: 600.000000, Wy: 0.000000},
"quotedblbase": {GlyphName: "quotedblbase", Wx: 600.000000, Wy: 0.000000},
"quotedblleft": {GlyphName: "quotedblleft", Wx: 600.000000, Wy: 0.000000},
"quotedblright": {GlyphName: "quotedblright", Wx: 600.000000, Wy: 0.000000},
"quoteleft": {GlyphName: "quoteleft", Wx: 600.000000, Wy: 0.000000},
"quoteright": {GlyphName: "quoteright", Wx: 600.000000, Wy: 0.000000},
"quotesinglbase": {GlyphName: "quotesinglbase", Wx: 600.000000, Wy: 0.000000},
"quotesingle": {GlyphName: "quotesingle", Wx: 600.000000, Wy: 0.000000},
"r": {GlyphName: "r", Wx: 600.000000, Wy: 0.000000},
"racute": {GlyphName: "racute", Wx: 600.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 600.000000, Wy: 0.000000},
"rcaron": {GlyphName: "rcaron", Wx: 600.000000, Wy: 0.000000},
"rcommaaccent": {GlyphName: "rcommaaccent", Wx: 600.000000, Wy: 0.000000},
"registered": {GlyphName: "registered", Wx: 600.000000, Wy: 0.000000},
"ring": {GlyphName: "ring", Wx: 600.000000, Wy: 0.000000},
"s": {GlyphName: "s", Wx: 600.000000, Wy: 0.000000},
"sacute": {GlyphName: "sacute", Wx: 600.000000, Wy: 0.000000},
"scaron": {GlyphName: "scaron", Wx: 600.000000, Wy: 0.000000},
"scedilla": {GlyphName: "scedilla", Wx: 600.000000, Wy: 0.000000},
"scommaaccent": {GlyphName: "scommaaccent", Wx: 600.000000, Wy: 0.000000},
"section": {GlyphName: "section", Wx: 600.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 600.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 600.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 600.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 600.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 600.000000, Wy: 0.000000},
"sterling": {GlyphName: "sterling", Wx: 600.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 600.000000, Wy: 0.000000},
"t": {GlyphName: "t", Wx: 600.000000, Wy: 0.000000},
"tcaron": {GlyphName: "tcaron", Wx: 600.000000, Wy: 0.000000},
"tcommaaccent": {GlyphName: "tcommaaccent", Wx: 600.000000, Wy: 0.000000},
"thorn": {GlyphName: "thorn", Wx: 600.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 600.000000, Wy: 0.000000},
"threequarters": {GlyphName: "threequarters", Wx: 600.000000, Wy: 0.000000},
"threesuperior": {GlyphName: "threesuperior", Wx: 600.000000, Wy: 0.000000},
"tilde": {GlyphName: "tilde", Wx: 600.000000, Wy: 0.000000},
"trademark": {GlyphName: "trademark", Wx: 600.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 600.000000, Wy: 0.000000},
"twosuperior": {GlyphName: "twosuperior", Wx: 600.000000, Wy: 0.000000},
"u": {GlyphName: "u", Wx: 600.000000, Wy: 0.000000},
"uacute": {GlyphName: "uacute", Wx: 600.000000, Wy: 0.000000},
"ucircumflex": {GlyphName: "ucircumflex", Wx: 600.000000, Wy: 0.000000},
"udieresis": {GlyphName: "udieresis", Wx: 600.000000, Wy: 0.000000},
"ugrave": {GlyphName: "ugrave", Wx: 600.000000, Wy: 0.000000},
"uhungarumlaut": {GlyphName: "uhungarumlaut", Wx: 600.000000, Wy: 0.000000},
"umacron": {GlyphName: "umacron", Wx: 600.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 600.000000, Wy: 0.000000},
"uogonek": {GlyphName: "uogonek", Wx: 600.000000, Wy: 0.000000},
"uring": {GlyphName: "uring", Wx: 600.000000, Wy: 0.000000},
"v": {GlyphName: "v", Wx: 600.000000, Wy: 0.000000},
"w": {GlyphName: "w", Wx: 600.000000, Wy: 0.000000},
"x": {GlyphName: "x", Wx: 600.000000, Wy: 0.000000},
"y": {GlyphName: "y", Wx: 600.000000, Wy: 0.000000},
"yacute": {GlyphName: "yacute", Wx: 600.000000, Wy: 0.000000},
"ydieresis": {GlyphName: "ydieresis", Wx: 600.000000, Wy: 0.000000},
"yen": {GlyphName: "yen", Wx: 600.000000, Wy: 0.000000},
"z": {GlyphName: "z", Wx: 600.000000, Wy: 0.000000},
"zacute": {GlyphName: "zacute", Wx: 600.000000, Wy: 0.000000},
"zcaron": {GlyphName: "zcaron", Wx: 600.000000, Wy: 0.000000},
"zdotaccent": {GlyphName: "zdotaccent", Wx: 600.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 600.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,18 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
type Font interface {
SetEncoder(encoder textencoding.TextEncoder)
GetGlyphCharMetrics(glyph string) (CharMetrics, bool)
ToPdfObject() core.PdfObject
}
type CharMetrics struct {
GlyphName string
Wx float64
Wy float64
}

View File

@@ -0,0 +1,362 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Helvetica. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontHelvetica struct {
encoder textencoding.TextEncoder
}
func NewFontHelvetica() fontHelvetica {
font := fontHelvetica{}
font.encoder = textencoding.NewWinAnsiTextEncoder() // Default
return font
}
func (font fontHelvetica) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontHelvetica) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := helveticaCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontHelvetica) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Helvetica"))
fontDict.Set("Encoding", font.encoder.ToPdfObject())
obj.PdfObject = fontDict
return obj
}
var helveticaCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"A": {GlyphName: "A", Wx: 667.000000, Wy: 0.000000},
"AE": {GlyphName: "AE", Wx: 1000.000000, Wy: 0.000000},
"Aacute": {GlyphName: "Aacute", Wx: 667.000000, Wy: 0.000000},
"Abreve": {GlyphName: "Abreve", Wx: 667.000000, Wy: 0.000000},
"Acircumflex": {GlyphName: "Acircumflex", Wx: 667.000000, Wy: 0.000000},
"Adieresis": {GlyphName: "Adieresis", Wx: 667.000000, Wy: 0.000000},
"Agrave": {GlyphName: "Agrave", Wx: 667.000000, Wy: 0.000000},
"Amacron": {GlyphName: "Amacron", Wx: 667.000000, Wy: 0.000000},
"Aogonek": {GlyphName: "Aogonek", Wx: 667.000000, Wy: 0.000000},
"Aring": {GlyphName: "Aring", Wx: 667.000000, Wy: 0.000000},
"Atilde": {GlyphName: "Atilde", Wx: 667.000000, Wy: 0.000000},
"B": {GlyphName: "B", Wx: 667.000000, Wy: 0.000000},
"C": {GlyphName: "C", Wx: 722.000000, Wy: 0.000000},
"Cacute": {GlyphName: "Cacute", Wx: 722.000000, Wy: 0.000000},
"Ccaron": {GlyphName: "Ccaron", Wx: 722.000000, Wy: 0.000000},
"Ccedilla": {GlyphName: "Ccedilla", Wx: 722.000000, Wy: 0.000000},
"D": {GlyphName: "D", Wx: 722.000000, Wy: 0.000000},
"Dcaron": {GlyphName: "Dcaron", Wx: 722.000000, Wy: 0.000000},
"Dcroat": {GlyphName: "Dcroat", Wx: 722.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 612.000000, Wy: 0.000000},
"E": {GlyphName: "E", Wx: 667.000000, Wy: 0.000000},
"Eacute": {GlyphName: "Eacute", Wx: 667.000000, Wy: 0.000000},
"Ecaron": {GlyphName: "Ecaron", Wx: 667.000000, Wy: 0.000000},
"Ecircumflex": {GlyphName: "Ecircumflex", Wx: 667.000000, Wy: 0.000000},
"Edieresis": {GlyphName: "Edieresis", Wx: 667.000000, Wy: 0.000000},
"Edotaccent": {GlyphName: "Edotaccent", Wx: 667.000000, Wy: 0.000000},
"Egrave": {GlyphName: "Egrave", Wx: 667.000000, Wy: 0.000000},
"Emacron": {GlyphName: "Emacron", Wx: 667.000000, Wy: 0.000000},
"Eogonek": {GlyphName: "Eogonek", Wx: 667.000000, Wy: 0.000000},
"Eth": {GlyphName: "Eth", Wx: 722.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 556.000000, Wy: 0.000000},
"F": {GlyphName: "F", Wx: 611.000000, Wy: 0.000000},
"G": {GlyphName: "G", Wx: 778.000000, Wy: 0.000000},
"Gbreve": {GlyphName: "Gbreve", Wx: 778.000000, Wy: 0.000000},
"Gcommaaccent": {GlyphName: "Gcommaaccent", Wx: 778.000000, Wy: 0.000000},
"H": {GlyphName: "H", Wx: 722.000000, Wy: 0.000000},
"I": {GlyphName: "I", Wx: 278.000000, Wy: 0.000000},
"Iacute": {GlyphName: "Iacute", Wx: 278.000000, Wy: 0.000000},
"Icircumflex": {GlyphName: "Icircumflex", Wx: 278.000000, Wy: 0.000000},
"Idieresis": {GlyphName: "Idieresis", Wx: 278.000000, Wy: 0.000000},
"Idotaccent": {GlyphName: "Idotaccent", Wx: 278.000000, Wy: 0.000000},
"Igrave": {GlyphName: "Igrave", Wx: 278.000000, Wy: 0.000000},
"Imacron": {GlyphName: "Imacron", Wx: 278.000000, Wy: 0.000000},
"Iogonek": {GlyphName: "Iogonek", Wx: 278.000000, Wy: 0.000000},
"J": {GlyphName: "J", Wx: 500.000000, Wy: 0.000000},
"K": {GlyphName: "K", Wx: 667.000000, Wy: 0.000000},
"Kcommaaccent": {GlyphName: "Kcommaaccent", Wx: 667.000000, Wy: 0.000000},
"L": {GlyphName: "L", Wx: 556.000000, Wy: 0.000000},
"Lacute": {GlyphName: "Lacute", Wx: 556.000000, Wy: 0.000000},
"Lcaron": {GlyphName: "Lcaron", Wx: 556.000000, Wy: 0.000000},
"Lcommaaccent": {GlyphName: "Lcommaaccent", Wx: 556.000000, Wy: 0.000000},
"Lslash": {GlyphName: "Lslash", Wx: 556.000000, Wy: 0.000000},
"M": {GlyphName: "M", Wx: 833.000000, Wy: 0.000000},
"N": {GlyphName: "N", Wx: 722.000000, Wy: 0.000000},
"Nacute": {GlyphName: "Nacute", Wx: 722.000000, Wy: 0.000000},
"Ncaron": {GlyphName: "Ncaron", Wx: 722.000000, Wy: 0.000000},
"Ncommaaccent": {GlyphName: "Ncommaaccent", Wx: 722.000000, Wy: 0.000000},
"Ntilde": {GlyphName: "Ntilde", Wx: 722.000000, Wy: 0.000000},
"O": {GlyphName: "O", Wx: 778.000000, Wy: 0.000000},
"OE": {GlyphName: "OE", Wx: 1000.000000, Wy: 0.000000},
"Oacute": {GlyphName: "Oacute", Wx: 778.000000, Wy: 0.000000},
"Ocircumflex": {GlyphName: "Ocircumflex", Wx: 778.000000, Wy: 0.000000},
"Odieresis": {GlyphName: "Odieresis", Wx: 778.000000, Wy: 0.000000},
"Ograve": {GlyphName: "Ograve", Wx: 778.000000, Wy: 0.000000},
"Ohungarumlaut": {GlyphName: "Ohungarumlaut", Wx: 778.000000, Wy: 0.000000},
"Omacron": {GlyphName: "Omacron", Wx: 778.000000, Wy: 0.000000},
"Oslash": {GlyphName: "Oslash", Wx: 778.000000, Wy: 0.000000},
"Otilde": {GlyphName: "Otilde", Wx: 778.000000, Wy: 0.000000},
"P": {GlyphName: "P", Wx: 667.000000, Wy: 0.000000},
"Q": {GlyphName: "Q", Wx: 778.000000, Wy: 0.000000},
"R": {GlyphName: "R", Wx: 722.000000, Wy: 0.000000},
"Racute": {GlyphName: "Racute", Wx: 722.000000, Wy: 0.000000},
"Rcaron": {GlyphName: "Rcaron", Wx: 722.000000, Wy: 0.000000},
"Rcommaaccent": {GlyphName: "Rcommaaccent", Wx: 722.000000, Wy: 0.000000},
"S": {GlyphName: "S", Wx: 667.000000, Wy: 0.000000},
"Sacute": {GlyphName: "Sacute", Wx: 667.000000, Wy: 0.000000},
"Scaron": {GlyphName: "Scaron", Wx: 667.000000, Wy: 0.000000},
"Scedilla": {GlyphName: "Scedilla", Wx: 667.000000, Wy: 0.000000},
"Scommaaccent": {GlyphName: "Scommaaccent", Wx: 667.000000, Wy: 0.000000},
"T": {GlyphName: "T", Wx: 611.000000, Wy: 0.000000},
"Tcaron": {GlyphName: "Tcaron", Wx: 611.000000, Wy: 0.000000},
"Tcommaaccent": {GlyphName: "Tcommaaccent", Wx: 611.000000, Wy: 0.000000},
"Thorn": {GlyphName: "Thorn", Wx: 667.000000, Wy: 0.000000},
"U": {GlyphName: "U", Wx: 722.000000, Wy: 0.000000},
"Uacute": {GlyphName: "Uacute", Wx: 722.000000, Wy: 0.000000},
"Ucircumflex": {GlyphName: "Ucircumflex", Wx: 722.000000, Wy: 0.000000},
"Udieresis": {GlyphName: "Udieresis", Wx: 722.000000, Wy: 0.000000},
"Ugrave": {GlyphName: "Ugrave", Wx: 722.000000, Wy: 0.000000},
"Uhungarumlaut": {GlyphName: "Uhungarumlaut", Wx: 722.000000, Wy: 0.000000},
"Umacron": {GlyphName: "Umacron", Wx: 722.000000, Wy: 0.000000},
"Uogonek": {GlyphName: "Uogonek", Wx: 722.000000, Wy: 0.000000},
"Uring": {GlyphName: "Uring", Wx: 722.000000, Wy: 0.000000},
"V": {GlyphName: "V", Wx: 667.000000, Wy: 0.000000},
"W": {GlyphName: "W", Wx: 944.000000, Wy: 0.000000},
"X": {GlyphName: "X", Wx: 667.000000, Wy: 0.000000},
"Y": {GlyphName: "Y", Wx: 667.000000, Wy: 0.000000},
"Yacute": {GlyphName: "Yacute", Wx: 667.000000, Wy: 0.000000},
"Ydieresis": {GlyphName: "Ydieresis", Wx: 667.000000, Wy: 0.000000},
"Z": {GlyphName: "Z", Wx: 611.000000, Wy: 0.000000},
"Zacute": {GlyphName: "Zacute", Wx: 611.000000, Wy: 0.000000},
"Zcaron": {GlyphName: "Zcaron", Wx: 611.000000, Wy: 0.000000},
"Zdotaccent": {GlyphName: "Zdotaccent", Wx: 611.000000, Wy: 0.000000},
"a": {GlyphName: "a", Wx: 556.000000, Wy: 0.000000},
"aacute": {GlyphName: "aacute", Wx: 556.000000, Wy: 0.000000},
"abreve": {GlyphName: "abreve", Wx: 556.000000, Wy: 0.000000},
"acircumflex": {GlyphName: "acircumflex", Wx: 556.000000, Wy: 0.000000},
"acute": {GlyphName: "acute", Wx: 333.000000, Wy: 0.000000},
"adieresis": {GlyphName: "adieresis", Wx: 556.000000, Wy: 0.000000},
"ae": {GlyphName: "ae", Wx: 889.000000, Wy: 0.000000},
"agrave": {GlyphName: "agrave", Wx: 556.000000, Wy: 0.000000},
"amacron": {GlyphName: "amacron", Wx: 556.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 667.000000, Wy: 0.000000},
"aogonek": {GlyphName: "aogonek", Wx: 556.000000, Wy: 0.000000},
"aring": {GlyphName: "aring", Wx: 556.000000, Wy: 0.000000},
"asciicircum": {GlyphName: "asciicircum", Wx: 469.000000, Wy: 0.000000},
"asciitilde": {GlyphName: "asciitilde", Wx: 584.000000, Wy: 0.000000},
"asterisk": {GlyphName: "asterisk", Wx: 389.000000, Wy: 0.000000},
"at": {GlyphName: "at", Wx: 1015.000000, Wy: 0.000000},
"atilde": {GlyphName: "atilde", Wx: 556.000000, Wy: 0.000000},
"b": {GlyphName: "b", Wx: 556.000000, Wy: 0.000000},
"backslash": {GlyphName: "backslash", Wx: 278.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 260.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 334.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 334.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 278.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 278.000000, Wy: 0.000000},
"breve": {GlyphName: "breve", Wx: 333.000000, Wy: 0.000000},
"brokenbar": {GlyphName: "brokenbar", Wx: 260.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 350.000000, Wy: 0.000000},
"c": {GlyphName: "c", Wx: 500.000000, Wy: 0.000000},
"cacute": {GlyphName: "cacute", Wx: 500.000000, Wy: 0.000000},
"caron": {GlyphName: "caron", Wx: 333.000000, Wy: 0.000000},
"ccaron": {GlyphName: "ccaron", Wx: 500.000000, Wy: 0.000000},
"ccedilla": {GlyphName: "ccedilla", Wx: 500.000000, Wy: 0.000000},
"cedilla": {GlyphName: "cedilla", Wx: 333.000000, Wy: 0.000000},
"cent": {GlyphName: "cent", Wx: 556.000000, Wy: 0.000000},
"circumflex": {GlyphName: "circumflex", Wx: 333.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 278.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 278.000000, Wy: 0.000000},
"commaaccent": {GlyphName: "commaaccent", Wx: 250.000000, Wy: 0.000000},
"copyright": {GlyphName: "copyright", Wx: 737.000000, Wy: 0.000000},
"currency": {GlyphName: "currency", Wx: 556.000000, Wy: 0.000000},
"d": {GlyphName: "d", Wx: 556.000000, Wy: 0.000000},
"dagger": {GlyphName: "dagger", Wx: 556.000000, Wy: 0.000000},
"daggerdbl": {GlyphName: "daggerdbl", Wx: 556.000000, Wy: 0.000000},
"dcaron": {GlyphName: "dcaron", Wx: 643.000000, Wy: 0.000000},
"dcroat": {GlyphName: "dcroat", Wx: 556.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 400.000000, Wy: 0.000000},
"dieresis": {GlyphName: "dieresis", Wx: 333.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 584.000000, Wy: 0.000000},
"dollar": {GlyphName: "dollar", Wx: 556.000000, Wy: 0.000000},
"dotaccent": {GlyphName: "dotaccent", Wx: 333.000000, Wy: 0.000000},
"dotlessi": {GlyphName: "dotlessi", Wx: 278.000000, Wy: 0.000000},
"e": {GlyphName: "e", Wx: 556.000000, Wy: 0.000000},
"eacute": {GlyphName: "eacute", Wx: 556.000000, Wy: 0.000000},
"ecaron": {GlyphName: "ecaron", Wx: 556.000000, Wy: 0.000000},
"ecircumflex": {GlyphName: "ecircumflex", Wx: 556.000000, Wy: 0.000000},
"edieresis": {GlyphName: "edieresis", Wx: 556.000000, Wy: 0.000000},
"edotaccent": {GlyphName: "edotaccent", Wx: 556.000000, Wy: 0.000000},
"egrave": {GlyphName: "egrave", Wx: 556.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 556.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 1000.000000, Wy: 0.000000},
"emacron": {GlyphName: "emacron", Wx: 556.000000, Wy: 0.000000},
"emdash": {GlyphName: "emdash", Wx: 1000.000000, Wy: 0.000000},
"endash": {GlyphName: "endash", Wx: 556.000000, Wy: 0.000000},
"eogonek": {GlyphName: "eogonek", Wx: 556.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 584.000000, Wy: 0.000000},
"eth": {GlyphName: "eth", Wx: 556.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 278.000000, Wy: 0.000000},
"exclamdown": {GlyphName: "exclamdown", Wx: 333.000000, Wy: 0.000000},
"f": {GlyphName: "f", Wx: 278.000000, Wy: 0.000000},
"fi": {GlyphName: "fi", Wx: 500.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 556.000000, Wy: 0.000000},
"fl": {GlyphName: "fl", Wx: 500.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 556.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 556.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 167.000000, Wy: 0.000000},
"g": {GlyphName: "g", Wx: 556.000000, Wy: 0.000000},
"gbreve": {GlyphName: "gbreve", Wx: 556.000000, Wy: 0.000000},
"gcommaaccent": {GlyphName: "gcommaaccent", Wx: 556.000000, Wy: 0.000000},
"germandbls": {GlyphName: "germandbls", Wx: 611.000000, Wy: 0.000000},
"grave": {GlyphName: "grave", Wx: 333.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 584.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 549.000000, Wy: 0.000000},
"guillemotleft": {GlyphName: "guillemotleft", Wx: 556.000000, Wy: 0.000000},
"guillemotright": {GlyphName: "guillemotright", Wx: 556.000000, Wy: 0.000000},
"guilsinglleft": {GlyphName: "guilsinglleft", Wx: 333.000000, Wy: 0.000000},
"guilsinglright": {GlyphName: "guilsinglright", Wx: 333.000000, Wy: 0.000000},
"h": {GlyphName: "h", Wx: 556.000000, Wy: 0.000000},
"hungarumlaut": {GlyphName: "hungarumlaut", Wx: 333.000000, Wy: 0.000000},
"hyphen": {GlyphName: "hyphen", Wx: 333.000000, Wy: 0.000000},
"i": {GlyphName: "i", Wx: 222.000000, Wy: 0.000000},
"iacute": {GlyphName: "iacute", Wx: 278.000000, Wy: 0.000000},
"icircumflex": {GlyphName: "icircumflex", Wx: 278.000000, Wy: 0.000000},
"idieresis": {GlyphName: "idieresis", Wx: 278.000000, Wy: 0.000000},
"igrave": {GlyphName: "igrave", Wx: 278.000000, Wy: 0.000000},
"imacron": {GlyphName: "imacron", Wx: 278.000000, Wy: 0.000000},
"iogonek": {GlyphName: "iogonek", Wx: 222.000000, Wy: 0.000000},
"j": {GlyphName: "j", Wx: 222.000000, Wy: 0.000000},
"k": {GlyphName: "k", Wx: 500.000000, Wy: 0.000000},
"kcommaaccent": {GlyphName: "kcommaaccent", Wx: 500.000000, Wy: 0.000000},
"l": {GlyphName: "l", Wx: 222.000000, Wy: 0.000000},
"lacute": {GlyphName: "lacute", Wx: 222.000000, Wy: 0.000000},
"lcaron": {GlyphName: "lcaron", Wx: 299.000000, Wy: 0.000000},
"lcommaaccent": {GlyphName: "lcommaaccent", Wx: 222.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 584.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 549.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 584.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 471.000000, Wy: 0.000000},
"lslash": {GlyphName: "lslash", Wx: 222.000000, Wy: 0.000000},
"m": {GlyphName: "m", Wx: 833.000000, Wy: 0.000000},
"macron": {GlyphName: "macron", Wx: 333.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 584.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 556.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 584.000000, Wy: 0.000000},
"n": {GlyphName: "n", Wx: 556.000000, Wy: 0.000000},
"nacute": {GlyphName: "nacute", Wx: 556.000000, Wy: 0.000000},
"ncaron": {GlyphName: "ncaron", Wx: 556.000000, Wy: 0.000000},
"ncommaaccent": {GlyphName: "ncommaaccent", Wx: 556.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 556.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 549.000000, Wy: 0.000000},
"ntilde": {GlyphName: "ntilde", Wx: 556.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 556.000000, Wy: 0.000000},
"o": {GlyphName: "o", Wx: 556.000000, Wy: 0.000000},
"oacute": {GlyphName: "oacute", Wx: 556.000000, Wy: 0.000000},
"ocircumflex": {GlyphName: "ocircumflex", Wx: 556.000000, Wy: 0.000000},
"odieresis": {GlyphName: "odieresis", Wx: 556.000000, Wy: 0.000000},
"oe": {GlyphName: "oe", Wx: 944.000000, Wy: 0.000000},
"ogonek": {GlyphName: "ogonek", Wx: 333.000000, Wy: 0.000000},
"ograve": {GlyphName: "ograve", Wx: 556.000000, Wy: 0.000000},
"ohungarumlaut": {GlyphName: "ohungarumlaut", Wx: 556.000000, Wy: 0.000000},
"omacron": {GlyphName: "omacron", Wx: 556.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 556.000000, Wy: 0.000000},
"onehalf": {GlyphName: "onehalf", Wx: 834.000000, Wy: 0.000000},
"onequarter": {GlyphName: "onequarter", Wx: 834.000000, Wy: 0.000000},
"onesuperior": {GlyphName: "onesuperior", Wx: 333.000000, Wy: 0.000000},
"ordfeminine": {GlyphName: "ordfeminine", Wx: 370.000000, Wy: 0.000000},
"ordmasculine": {GlyphName: "ordmasculine", Wx: 365.000000, Wy: 0.000000},
"oslash": {GlyphName: "oslash", Wx: 611.000000, Wy: 0.000000},
"otilde": {GlyphName: "otilde", Wx: 556.000000, Wy: 0.000000},
"p": {GlyphName: "p", Wx: 556.000000, Wy: 0.000000},
"paragraph": {GlyphName: "paragraph", Wx: 537.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 333.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 333.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 476.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 889.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 278.000000, Wy: 0.000000},
"periodcentered": {GlyphName: "periodcentered", Wx: 278.000000, Wy: 0.000000},
"perthousand": {GlyphName: "perthousand", Wx: 1000.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 584.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 584.000000, Wy: 0.000000},
"q": {GlyphName: "q", Wx: 556.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 556.000000, Wy: 0.000000},
"questiondown": {GlyphName: "questiondown", Wx: 611.000000, Wy: 0.000000},
"quotedbl": {GlyphName: "quotedbl", Wx: 355.000000, Wy: 0.000000},
"quotedblbase": {GlyphName: "quotedblbase", Wx: 333.000000, Wy: 0.000000},
"quotedblleft": {GlyphName: "quotedblleft", Wx: 333.000000, Wy: 0.000000},
"quotedblright": {GlyphName: "quotedblright", Wx: 333.000000, Wy: 0.000000},
"quoteleft": {GlyphName: "quoteleft", Wx: 222.000000, Wy: 0.000000},
"quoteright": {GlyphName: "quoteright", Wx: 222.000000, Wy: 0.000000},
"quotesinglbase": {GlyphName: "quotesinglbase", Wx: 222.000000, Wy: 0.000000},
"quotesingle": {GlyphName: "quotesingle", Wx: 191.000000, Wy: 0.000000},
"r": {GlyphName: "r", Wx: 333.000000, Wy: 0.000000},
"racute": {GlyphName: "racute", Wx: 333.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 453.000000, Wy: 0.000000},
"rcaron": {GlyphName: "rcaron", Wx: 333.000000, Wy: 0.000000},
"rcommaaccent": {GlyphName: "rcommaaccent", Wx: 333.000000, Wy: 0.000000},
"registered": {GlyphName: "registered", Wx: 737.000000, Wy: 0.000000},
"ring": {GlyphName: "ring", Wx: 333.000000, Wy: 0.000000},
"s": {GlyphName: "s", Wx: 500.000000, Wy: 0.000000},
"sacute": {GlyphName: "sacute", Wx: 500.000000, Wy: 0.000000},
"scaron": {GlyphName: "scaron", Wx: 500.000000, Wy: 0.000000},
"scedilla": {GlyphName: "scedilla", Wx: 500.000000, Wy: 0.000000},
"scommaaccent": {GlyphName: "scommaaccent", Wx: 500.000000, Wy: 0.000000},
"section": {GlyphName: "section", Wx: 556.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 278.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 556.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 556.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 278.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 278.000000, Wy: 0.000000},
"sterling": {GlyphName: "sterling", Wx: 556.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 600.000000, Wy: 0.000000},
"t": {GlyphName: "t", Wx: 278.000000, Wy: 0.000000},
"tcaron": {GlyphName: "tcaron", Wx: 317.000000, Wy: 0.000000},
"tcommaaccent": {GlyphName: "tcommaaccent", Wx: 278.000000, Wy: 0.000000},
"thorn": {GlyphName: "thorn", Wx: 556.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 556.000000, Wy: 0.000000},
"threequarters": {GlyphName: "threequarters", Wx: 834.000000, Wy: 0.000000},
"threesuperior": {GlyphName: "threesuperior", Wx: 333.000000, Wy: 0.000000},
"tilde": {GlyphName: "tilde", Wx: 333.000000, Wy: 0.000000},
"trademark": {GlyphName: "trademark", Wx: 1000.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 556.000000, Wy: 0.000000},
"twosuperior": {GlyphName: "twosuperior", Wx: 333.000000, Wy: 0.000000},
"u": {GlyphName: "u", Wx: 556.000000, Wy: 0.000000},
"uacute": {GlyphName: "uacute", Wx: 556.000000, Wy: 0.000000},
"ucircumflex": {GlyphName: "ucircumflex", Wx: 556.000000, Wy: 0.000000},
"udieresis": {GlyphName: "udieresis", Wx: 556.000000, Wy: 0.000000},
"ugrave": {GlyphName: "ugrave", Wx: 556.000000, Wy: 0.000000},
"uhungarumlaut": {GlyphName: "uhungarumlaut", Wx: 556.000000, Wy: 0.000000},
"umacron": {GlyphName: "umacron", Wx: 556.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 556.000000, Wy: 0.000000},
"uogonek": {GlyphName: "uogonek", Wx: 556.000000, Wy: 0.000000},
"uring": {GlyphName: "uring", Wx: 556.000000, Wy: 0.000000},
"v": {GlyphName: "v", Wx: 500.000000, Wy: 0.000000},
"w": {GlyphName: "w", Wx: 722.000000, Wy: 0.000000},
"x": {GlyphName: "x", Wx: 500.000000, Wy: 0.000000},
"y": {GlyphName: "y", Wx: 500.000000, Wy: 0.000000},
"yacute": {GlyphName: "yacute", Wx: 500.000000, Wy: 0.000000},
"ydieresis": {GlyphName: "ydieresis", Wx: 500.000000, Wy: 0.000000},
"yen": {GlyphName: "yen", Wx: 556.000000, Wy: 0.000000},
"z": {GlyphName: "z", Wx: 500.000000, Wy: 0.000000},
"zacute": {GlyphName: "zacute", Wx: 500.000000, Wy: 0.000000},
"zcaron": {GlyphName: "zcaron", Wx: 500.000000, Wy: 0.000000},
"zdotaccent": {GlyphName: "zdotaccent", Wx: 500.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 556.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,362 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Helvetica-Bold. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontHelveticaBold struct {
encoder textencoding.TextEncoder
}
func NewFontHelveticaBold() fontHelveticaBold {
font := fontHelveticaBold{}
font.encoder = textencoding.NewWinAnsiTextEncoder() // Default
return font
}
func (font fontHelveticaBold) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontHelveticaBold) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := helveticaBoldCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontHelveticaBold) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Helvetica-Bold"))
fontDict.Set("Encoding", font.encoder.ToPdfObject())
obj.PdfObject = fontDict
return obj
}
var helveticaBoldCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"A": {GlyphName: "A", Wx: 722.000000, Wy: 0.000000},
"AE": {GlyphName: "AE", Wx: 1000.000000, Wy: 0.000000},
"Aacute": {GlyphName: "Aacute", Wx: 722.000000, Wy: 0.000000},
"Abreve": {GlyphName: "Abreve", Wx: 722.000000, Wy: 0.000000},
"Acircumflex": {GlyphName: "Acircumflex", Wx: 722.000000, Wy: 0.000000},
"Adieresis": {GlyphName: "Adieresis", Wx: 722.000000, Wy: 0.000000},
"Agrave": {GlyphName: "Agrave", Wx: 722.000000, Wy: 0.000000},
"Amacron": {GlyphName: "Amacron", Wx: 722.000000, Wy: 0.000000},
"Aogonek": {GlyphName: "Aogonek", Wx: 722.000000, Wy: 0.000000},
"Aring": {GlyphName: "Aring", Wx: 722.000000, Wy: 0.000000},
"Atilde": {GlyphName: "Atilde", Wx: 722.000000, Wy: 0.000000},
"B": {GlyphName: "B", Wx: 722.000000, Wy: 0.000000},
"C": {GlyphName: "C", Wx: 722.000000, Wy: 0.000000},
"Cacute": {GlyphName: "Cacute", Wx: 722.000000, Wy: 0.000000},
"Ccaron": {GlyphName: "Ccaron", Wx: 722.000000, Wy: 0.000000},
"Ccedilla": {GlyphName: "Ccedilla", Wx: 722.000000, Wy: 0.000000},
"D": {GlyphName: "D", Wx: 722.000000, Wy: 0.000000},
"Dcaron": {GlyphName: "Dcaron", Wx: 722.000000, Wy: 0.000000},
"Dcroat": {GlyphName: "Dcroat", Wx: 722.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 612.000000, Wy: 0.000000},
"E": {GlyphName: "E", Wx: 667.000000, Wy: 0.000000},
"Eacute": {GlyphName: "Eacute", Wx: 667.000000, Wy: 0.000000},
"Ecaron": {GlyphName: "Ecaron", Wx: 667.000000, Wy: 0.000000},
"Ecircumflex": {GlyphName: "Ecircumflex", Wx: 667.000000, Wy: 0.000000},
"Edieresis": {GlyphName: "Edieresis", Wx: 667.000000, Wy: 0.000000},
"Edotaccent": {GlyphName: "Edotaccent", Wx: 667.000000, Wy: 0.000000},
"Egrave": {GlyphName: "Egrave", Wx: 667.000000, Wy: 0.000000},
"Emacron": {GlyphName: "Emacron", Wx: 667.000000, Wy: 0.000000},
"Eogonek": {GlyphName: "Eogonek", Wx: 667.000000, Wy: 0.000000},
"Eth": {GlyphName: "Eth", Wx: 722.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 556.000000, Wy: 0.000000},
"F": {GlyphName: "F", Wx: 611.000000, Wy: 0.000000},
"G": {GlyphName: "G", Wx: 778.000000, Wy: 0.000000},
"Gbreve": {GlyphName: "Gbreve", Wx: 778.000000, Wy: 0.000000},
"Gcommaaccent": {GlyphName: "Gcommaaccent", Wx: 778.000000, Wy: 0.000000},
"H": {GlyphName: "H", Wx: 722.000000, Wy: 0.000000},
"I": {GlyphName: "I", Wx: 278.000000, Wy: 0.000000},
"Iacute": {GlyphName: "Iacute", Wx: 278.000000, Wy: 0.000000},
"Icircumflex": {GlyphName: "Icircumflex", Wx: 278.000000, Wy: 0.000000},
"Idieresis": {GlyphName: "Idieresis", Wx: 278.000000, Wy: 0.000000},
"Idotaccent": {GlyphName: "Idotaccent", Wx: 278.000000, Wy: 0.000000},
"Igrave": {GlyphName: "Igrave", Wx: 278.000000, Wy: 0.000000},
"Imacron": {GlyphName: "Imacron", Wx: 278.000000, Wy: 0.000000},
"Iogonek": {GlyphName: "Iogonek", Wx: 278.000000, Wy: 0.000000},
"J": {GlyphName: "J", Wx: 556.000000, Wy: 0.000000},
"K": {GlyphName: "K", Wx: 722.000000, Wy: 0.000000},
"Kcommaaccent": {GlyphName: "Kcommaaccent", Wx: 722.000000, Wy: 0.000000},
"L": {GlyphName: "L", Wx: 611.000000, Wy: 0.000000},
"Lacute": {GlyphName: "Lacute", Wx: 611.000000, Wy: 0.000000},
"Lcaron": {GlyphName: "Lcaron", Wx: 611.000000, Wy: 0.000000},
"Lcommaaccent": {GlyphName: "Lcommaaccent", Wx: 611.000000, Wy: 0.000000},
"Lslash": {GlyphName: "Lslash", Wx: 611.000000, Wy: 0.000000},
"M": {GlyphName: "M", Wx: 833.000000, Wy: 0.000000},
"N": {GlyphName: "N", Wx: 722.000000, Wy: 0.000000},
"Nacute": {GlyphName: "Nacute", Wx: 722.000000, Wy: 0.000000},
"Ncaron": {GlyphName: "Ncaron", Wx: 722.000000, Wy: 0.000000},
"Ncommaaccent": {GlyphName: "Ncommaaccent", Wx: 722.000000, Wy: 0.000000},
"Ntilde": {GlyphName: "Ntilde", Wx: 722.000000, Wy: 0.000000},
"O": {GlyphName: "O", Wx: 778.000000, Wy: 0.000000},
"OE": {GlyphName: "OE", Wx: 1000.000000, Wy: 0.000000},
"Oacute": {GlyphName: "Oacute", Wx: 778.000000, Wy: 0.000000},
"Ocircumflex": {GlyphName: "Ocircumflex", Wx: 778.000000, Wy: 0.000000},
"Odieresis": {GlyphName: "Odieresis", Wx: 778.000000, Wy: 0.000000},
"Ograve": {GlyphName: "Ograve", Wx: 778.000000, Wy: 0.000000},
"Ohungarumlaut": {GlyphName: "Ohungarumlaut", Wx: 778.000000, Wy: 0.000000},
"Omacron": {GlyphName: "Omacron", Wx: 778.000000, Wy: 0.000000},
"Oslash": {GlyphName: "Oslash", Wx: 778.000000, Wy: 0.000000},
"Otilde": {GlyphName: "Otilde", Wx: 778.000000, Wy: 0.000000},
"P": {GlyphName: "P", Wx: 667.000000, Wy: 0.000000},
"Q": {GlyphName: "Q", Wx: 778.000000, Wy: 0.000000},
"R": {GlyphName: "R", Wx: 722.000000, Wy: 0.000000},
"Racute": {GlyphName: "Racute", Wx: 722.000000, Wy: 0.000000},
"Rcaron": {GlyphName: "Rcaron", Wx: 722.000000, Wy: 0.000000},
"Rcommaaccent": {GlyphName: "Rcommaaccent", Wx: 722.000000, Wy: 0.000000},
"S": {GlyphName: "S", Wx: 667.000000, Wy: 0.000000},
"Sacute": {GlyphName: "Sacute", Wx: 667.000000, Wy: 0.000000},
"Scaron": {GlyphName: "Scaron", Wx: 667.000000, Wy: 0.000000},
"Scedilla": {GlyphName: "Scedilla", Wx: 667.000000, Wy: 0.000000},
"Scommaaccent": {GlyphName: "Scommaaccent", Wx: 667.000000, Wy: 0.000000},
"T": {GlyphName: "T", Wx: 611.000000, Wy: 0.000000},
"Tcaron": {GlyphName: "Tcaron", Wx: 611.000000, Wy: 0.000000},
"Tcommaaccent": {GlyphName: "Tcommaaccent", Wx: 611.000000, Wy: 0.000000},
"Thorn": {GlyphName: "Thorn", Wx: 667.000000, Wy: 0.000000},
"U": {GlyphName: "U", Wx: 722.000000, Wy: 0.000000},
"Uacute": {GlyphName: "Uacute", Wx: 722.000000, Wy: 0.000000},
"Ucircumflex": {GlyphName: "Ucircumflex", Wx: 722.000000, Wy: 0.000000},
"Udieresis": {GlyphName: "Udieresis", Wx: 722.000000, Wy: 0.000000},
"Ugrave": {GlyphName: "Ugrave", Wx: 722.000000, Wy: 0.000000},
"Uhungarumlaut": {GlyphName: "Uhungarumlaut", Wx: 722.000000, Wy: 0.000000},
"Umacron": {GlyphName: "Umacron", Wx: 722.000000, Wy: 0.000000},
"Uogonek": {GlyphName: "Uogonek", Wx: 722.000000, Wy: 0.000000},
"Uring": {GlyphName: "Uring", Wx: 722.000000, Wy: 0.000000},
"V": {GlyphName: "V", Wx: 667.000000, Wy: 0.000000},
"W": {GlyphName: "W", Wx: 944.000000, Wy: 0.000000},
"X": {GlyphName: "X", Wx: 667.000000, Wy: 0.000000},
"Y": {GlyphName: "Y", Wx: 667.000000, Wy: 0.000000},
"Yacute": {GlyphName: "Yacute", Wx: 667.000000, Wy: 0.000000},
"Ydieresis": {GlyphName: "Ydieresis", Wx: 667.000000, Wy: 0.000000},
"Z": {GlyphName: "Z", Wx: 611.000000, Wy: 0.000000},
"Zacute": {GlyphName: "Zacute", Wx: 611.000000, Wy: 0.000000},
"Zcaron": {GlyphName: "Zcaron", Wx: 611.000000, Wy: 0.000000},
"Zdotaccent": {GlyphName: "Zdotaccent", Wx: 611.000000, Wy: 0.000000},
"a": {GlyphName: "a", Wx: 556.000000, Wy: 0.000000},
"aacute": {GlyphName: "aacute", Wx: 556.000000, Wy: 0.000000},
"abreve": {GlyphName: "abreve", Wx: 556.000000, Wy: 0.000000},
"acircumflex": {GlyphName: "acircumflex", Wx: 556.000000, Wy: 0.000000},
"acute": {GlyphName: "acute", Wx: 333.000000, Wy: 0.000000},
"adieresis": {GlyphName: "adieresis", Wx: 556.000000, Wy: 0.000000},
"ae": {GlyphName: "ae", Wx: 889.000000, Wy: 0.000000},
"agrave": {GlyphName: "agrave", Wx: 556.000000, Wy: 0.000000},
"amacron": {GlyphName: "amacron", Wx: 556.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 722.000000, Wy: 0.000000},
"aogonek": {GlyphName: "aogonek", Wx: 556.000000, Wy: 0.000000},
"aring": {GlyphName: "aring", Wx: 556.000000, Wy: 0.000000},
"asciicircum": {GlyphName: "asciicircum", Wx: 584.000000, Wy: 0.000000},
"asciitilde": {GlyphName: "asciitilde", Wx: 584.000000, Wy: 0.000000},
"asterisk": {GlyphName: "asterisk", Wx: 389.000000, Wy: 0.000000},
"at": {GlyphName: "at", Wx: 975.000000, Wy: 0.000000},
"atilde": {GlyphName: "atilde", Wx: 556.000000, Wy: 0.000000},
"b": {GlyphName: "b", Wx: 611.000000, Wy: 0.000000},
"backslash": {GlyphName: "backslash", Wx: 278.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 280.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 389.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 389.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 333.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 333.000000, Wy: 0.000000},
"breve": {GlyphName: "breve", Wx: 333.000000, Wy: 0.000000},
"brokenbar": {GlyphName: "brokenbar", Wx: 280.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 350.000000, Wy: 0.000000},
"c": {GlyphName: "c", Wx: 556.000000, Wy: 0.000000},
"cacute": {GlyphName: "cacute", Wx: 556.000000, Wy: 0.000000},
"caron": {GlyphName: "caron", Wx: 333.000000, Wy: 0.000000},
"ccaron": {GlyphName: "ccaron", Wx: 556.000000, Wy: 0.000000},
"ccedilla": {GlyphName: "ccedilla", Wx: 556.000000, Wy: 0.000000},
"cedilla": {GlyphName: "cedilla", Wx: 333.000000, Wy: 0.000000},
"cent": {GlyphName: "cent", Wx: 556.000000, Wy: 0.000000},
"circumflex": {GlyphName: "circumflex", Wx: 333.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 333.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 278.000000, Wy: 0.000000},
"commaaccent": {GlyphName: "commaaccent", Wx: 250.000000, Wy: 0.000000},
"copyright": {GlyphName: "copyright", Wx: 737.000000, Wy: 0.000000},
"currency": {GlyphName: "currency", Wx: 556.000000, Wy: 0.000000},
"d": {GlyphName: "d", Wx: 611.000000, Wy: 0.000000},
"dagger": {GlyphName: "dagger", Wx: 556.000000, Wy: 0.000000},
"daggerdbl": {GlyphName: "daggerdbl", Wx: 556.000000, Wy: 0.000000},
"dcaron": {GlyphName: "dcaron", Wx: 743.000000, Wy: 0.000000},
"dcroat": {GlyphName: "dcroat", Wx: 611.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 400.000000, Wy: 0.000000},
"dieresis": {GlyphName: "dieresis", Wx: 333.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 584.000000, Wy: 0.000000},
"dollar": {GlyphName: "dollar", Wx: 556.000000, Wy: 0.000000},
"dotaccent": {GlyphName: "dotaccent", Wx: 333.000000, Wy: 0.000000},
"dotlessi": {GlyphName: "dotlessi", Wx: 278.000000, Wy: 0.000000},
"e": {GlyphName: "e", Wx: 556.000000, Wy: 0.000000},
"eacute": {GlyphName: "eacute", Wx: 556.000000, Wy: 0.000000},
"ecaron": {GlyphName: "ecaron", Wx: 556.000000, Wy: 0.000000},
"ecircumflex": {GlyphName: "ecircumflex", Wx: 556.000000, Wy: 0.000000},
"edieresis": {GlyphName: "edieresis", Wx: 556.000000, Wy: 0.000000},
"edotaccent": {GlyphName: "edotaccent", Wx: 556.000000, Wy: 0.000000},
"egrave": {GlyphName: "egrave", Wx: 556.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 556.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 1000.000000, Wy: 0.000000},
"emacron": {GlyphName: "emacron", Wx: 556.000000, Wy: 0.000000},
"emdash": {GlyphName: "emdash", Wx: 1000.000000, Wy: 0.000000},
"endash": {GlyphName: "endash", Wx: 556.000000, Wy: 0.000000},
"eogonek": {GlyphName: "eogonek", Wx: 556.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 584.000000, Wy: 0.000000},
"eth": {GlyphName: "eth", Wx: 611.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 333.000000, Wy: 0.000000},
"exclamdown": {GlyphName: "exclamdown", Wx: 333.000000, Wy: 0.000000},
"f": {GlyphName: "f", Wx: 333.000000, Wy: 0.000000},
"fi": {GlyphName: "fi", Wx: 611.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 556.000000, Wy: 0.000000},
"fl": {GlyphName: "fl", Wx: 611.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 556.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 556.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 167.000000, Wy: 0.000000},
"g": {GlyphName: "g", Wx: 611.000000, Wy: 0.000000},
"gbreve": {GlyphName: "gbreve", Wx: 611.000000, Wy: 0.000000},
"gcommaaccent": {GlyphName: "gcommaaccent", Wx: 611.000000, Wy: 0.000000},
"germandbls": {GlyphName: "germandbls", Wx: 611.000000, Wy: 0.000000},
"grave": {GlyphName: "grave", Wx: 333.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 584.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 549.000000, Wy: 0.000000},
"guillemotleft": {GlyphName: "guillemotleft", Wx: 556.000000, Wy: 0.000000},
"guillemotright": {GlyphName: "guillemotright", Wx: 556.000000, Wy: 0.000000},
"guilsinglleft": {GlyphName: "guilsinglleft", Wx: 333.000000, Wy: 0.000000},
"guilsinglright": {GlyphName: "guilsinglright", Wx: 333.000000, Wy: 0.000000},
"h": {GlyphName: "h", Wx: 611.000000, Wy: 0.000000},
"hungarumlaut": {GlyphName: "hungarumlaut", Wx: 333.000000, Wy: 0.000000},
"hyphen": {GlyphName: "hyphen", Wx: 333.000000, Wy: 0.000000},
"i": {GlyphName: "i", Wx: 278.000000, Wy: 0.000000},
"iacute": {GlyphName: "iacute", Wx: 278.000000, Wy: 0.000000},
"icircumflex": {GlyphName: "icircumflex", Wx: 278.000000, Wy: 0.000000},
"idieresis": {GlyphName: "idieresis", Wx: 278.000000, Wy: 0.000000},
"igrave": {GlyphName: "igrave", Wx: 278.000000, Wy: 0.000000},
"imacron": {GlyphName: "imacron", Wx: 278.000000, Wy: 0.000000},
"iogonek": {GlyphName: "iogonek", Wx: 278.000000, Wy: 0.000000},
"j": {GlyphName: "j", Wx: 278.000000, Wy: 0.000000},
"k": {GlyphName: "k", Wx: 556.000000, Wy: 0.000000},
"kcommaaccent": {GlyphName: "kcommaaccent", Wx: 556.000000, Wy: 0.000000},
"l": {GlyphName: "l", Wx: 278.000000, Wy: 0.000000},
"lacute": {GlyphName: "lacute", Wx: 278.000000, Wy: 0.000000},
"lcaron": {GlyphName: "lcaron", Wx: 400.000000, Wy: 0.000000},
"lcommaaccent": {GlyphName: "lcommaaccent", Wx: 278.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 584.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 549.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 584.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 494.000000, Wy: 0.000000},
"lslash": {GlyphName: "lslash", Wx: 278.000000, Wy: 0.000000},
"m": {GlyphName: "m", Wx: 889.000000, Wy: 0.000000},
"macron": {GlyphName: "macron", Wx: 333.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 584.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 611.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 584.000000, Wy: 0.000000},
"n": {GlyphName: "n", Wx: 611.000000, Wy: 0.000000},
"nacute": {GlyphName: "nacute", Wx: 611.000000, Wy: 0.000000},
"ncaron": {GlyphName: "ncaron", Wx: 611.000000, Wy: 0.000000},
"ncommaaccent": {GlyphName: "ncommaaccent", Wx: 611.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 556.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 549.000000, Wy: 0.000000},
"ntilde": {GlyphName: "ntilde", Wx: 611.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 556.000000, Wy: 0.000000},
"o": {GlyphName: "o", Wx: 611.000000, Wy: 0.000000},
"oacute": {GlyphName: "oacute", Wx: 611.000000, Wy: 0.000000},
"ocircumflex": {GlyphName: "ocircumflex", Wx: 611.000000, Wy: 0.000000},
"odieresis": {GlyphName: "odieresis", Wx: 611.000000, Wy: 0.000000},
"oe": {GlyphName: "oe", Wx: 944.000000, Wy: 0.000000},
"ogonek": {GlyphName: "ogonek", Wx: 333.000000, Wy: 0.000000},
"ograve": {GlyphName: "ograve", Wx: 611.000000, Wy: 0.000000},
"ohungarumlaut": {GlyphName: "ohungarumlaut", Wx: 611.000000, Wy: 0.000000},
"omacron": {GlyphName: "omacron", Wx: 611.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 556.000000, Wy: 0.000000},
"onehalf": {GlyphName: "onehalf", Wx: 834.000000, Wy: 0.000000},
"onequarter": {GlyphName: "onequarter", Wx: 834.000000, Wy: 0.000000},
"onesuperior": {GlyphName: "onesuperior", Wx: 333.000000, Wy: 0.000000},
"ordfeminine": {GlyphName: "ordfeminine", Wx: 370.000000, Wy: 0.000000},
"ordmasculine": {GlyphName: "ordmasculine", Wx: 365.000000, Wy: 0.000000},
"oslash": {GlyphName: "oslash", Wx: 611.000000, Wy: 0.000000},
"otilde": {GlyphName: "otilde", Wx: 611.000000, Wy: 0.000000},
"p": {GlyphName: "p", Wx: 611.000000, Wy: 0.000000},
"paragraph": {GlyphName: "paragraph", Wx: 556.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 333.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 333.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 494.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 889.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 278.000000, Wy: 0.000000},
"periodcentered": {GlyphName: "periodcentered", Wx: 278.000000, Wy: 0.000000},
"perthousand": {GlyphName: "perthousand", Wx: 1000.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 584.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 584.000000, Wy: 0.000000},
"q": {GlyphName: "q", Wx: 611.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 611.000000, Wy: 0.000000},
"questiondown": {GlyphName: "questiondown", Wx: 611.000000, Wy: 0.000000},
"quotedbl": {GlyphName: "quotedbl", Wx: 474.000000, Wy: 0.000000},
"quotedblbase": {GlyphName: "quotedblbase", Wx: 500.000000, Wy: 0.000000},
"quotedblleft": {GlyphName: "quotedblleft", Wx: 500.000000, Wy: 0.000000},
"quotedblright": {GlyphName: "quotedblright", Wx: 500.000000, Wy: 0.000000},
"quoteleft": {GlyphName: "quoteleft", Wx: 278.000000, Wy: 0.000000},
"quoteright": {GlyphName: "quoteright", Wx: 278.000000, Wy: 0.000000},
"quotesinglbase": {GlyphName: "quotesinglbase", Wx: 278.000000, Wy: 0.000000},
"quotesingle": {GlyphName: "quotesingle", Wx: 238.000000, Wy: 0.000000},
"r": {GlyphName: "r", Wx: 389.000000, Wy: 0.000000},
"racute": {GlyphName: "racute", Wx: 389.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 549.000000, Wy: 0.000000},
"rcaron": {GlyphName: "rcaron", Wx: 389.000000, Wy: 0.000000},
"rcommaaccent": {GlyphName: "rcommaaccent", Wx: 389.000000, Wy: 0.000000},
"registered": {GlyphName: "registered", Wx: 737.000000, Wy: 0.000000},
"ring": {GlyphName: "ring", Wx: 333.000000, Wy: 0.000000},
"s": {GlyphName: "s", Wx: 556.000000, Wy: 0.000000},
"sacute": {GlyphName: "sacute", Wx: 556.000000, Wy: 0.000000},
"scaron": {GlyphName: "scaron", Wx: 556.000000, Wy: 0.000000},
"scedilla": {GlyphName: "scedilla", Wx: 556.000000, Wy: 0.000000},
"scommaaccent": {GlyphName: "scommaaccent", Wx: 556.000000, Wy: 0.000000},
"section": {GlyphName: "section", Wx: 556.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 333.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 556.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 556.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 278.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 278.000000, Wy: 0.000000},
"sterling": {GlyphName: "sterling", Wx: 556.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 600.000000, Wy: 0.000000},
"t": {GlyphName: "t", Wx: 333.000000, Wy: 0.000000},
"tcaron": {GlyphName: "tcaron", Wx: 389.000000, Wy: 0.000000},
"tcommaaccent": {GlyphName: "tcommaaccent", Wx: 333.000000, Wy: 0.000000},
"thorn": {GlyphName: "thorn", Wx: 611.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 556.000000, Wy: 0.000000},
"threequarters": {GlyphName: "threequarters", Wx: 834.000000, Wy: 0.000000},
"threesuperior": {GlyphName: "threesuperior", Wx: 333.000000, Wy: 0.000000},
"tilde": {GlyphName: "tilde", Wx: 333.000000, Wy: 0.000000},
"trademark": {GlyphName: "trademark", Wx: 1000.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 556.000000, Wy: 0.000000},
"twosuperior": {GlyphName: "twosuperior", Wx: 333.000000, Wy: 0.000000},
"u": {GlyphName: "u", Wx: 611.000000, Wy: 0.000000},
"uacute": {GlyphName: "uacute", Wx: 611.000000, Wy: 0.000000},
"ucircumflex": {GlyphName: "ucircumflex", Wx: 611.000000, Wy: 0.000000},
"udieresis": {GlyphName: "udieresis", Wx: 611.000000, Wy: 0.000000},
"ugrave": {GlyphName: "ugrave", Wx: 611.000000, Wy: 0.000000},
"uhungarumlaut": {GlyphName: "uhungarumlaut", Wx: 611.000000, Wy: 0.000000},
"umacron": {GlyphName: "umacron", Wx: 611.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 556.000000, Wy: 0.000000},
"uogonek": {GlyphName: "uogonek", Wx: 611.000000, Wy: 0.000000},
"uring": {GlyphName: "uring", Wx: 611.000000, Wy: 0.000000},
"v": {GlyphName: "v", Wx: 556.000000, Wy: 0.000000},
"w": {GlyphName: "w", Wx: 778.000000, Wy: 0.000000},
"x": {GlyphName: "x", Wx: 556.000000, Wy: 0.000000},
"y": {GlyphName: "y", Wx: 556.000000, Wy: 0.000000},
"yacute": {GlyphName: "yacute", Wx: 556.000000, Wy: 0.000000},
"ydieresis": {GlyphName: "ydieresis", Wx: 556.000000, Wy: 0.000000},
"yen": {GlyphName: "yen", Wx: 556.000000, Wy: 0.000000},
"z": {GlyphName: "z", Wx: 500.000000, Wy: 0.000000},
"zacute": {GlyphName: "zacute", Wx: 500.000000, Wy: 0.000000},
"zcaron": {GlyphName: "zcaron", Wx: 500.000000, Wy: 0.000000},
"zdotaccent": {GlyphName: "zdotaccent", Wx: 500.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 556.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,362 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Helvetica-BoldOblique. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontHelveticaBoldOblique struct {
encoder textencoding.TextEncoder
}
func NewFontHelveticaBoldOblique() fontHelveticaBoldOblique {
font := fontHelveticaBoldOblique{}
font.encoder = textencoding.NewWinAnsiTextEncoder() // Default
return font
}
func (font fontHelveticaBoldOblique) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontHelveticaBoldOblique) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := helveticaBoldObliqueCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontHelveticaBoldOblique) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Helvetica-BoldOblique"))
fontDict.Set("Encoding", font.encoder.ToPdfObject())
obj.PdfObject = fontDict
return obj
}
var helveticaBoldObliqueCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"A": {GlyphName: "A", Wx: 722.000000, Wy: 0.000000},
"AE": {GlyphName: "AE", Wx: 1000.000000, Wy: 0.000000},
"Aacute": {GlyphName: "Aacute", Wx: 722.000000, Wy: 0.000000},
"Abreve": {GlyphName: "Abreve", Wx: 722.000000, Wy: 0.000000},
"Acircumflex": {GlyphName: "Acircumflex", Wx: 722.000000, Wy: 0.000000},
"Adieresis": {GlyphName: "Adieresis", Wx: 722.000000, Wy: 0.000000},
"Agrave": {GlyphName: "Agrave", Wx: 722.000000, Wy: 0.000000},
"Amacron": {GlyphName: "Amacron", Wx: 722.000000, Wy: 0.000000},
"Aogonek": {GlyphName: "Aogonek", Wx: 722.000000, Wy: 0.000000},
"Aring": {GlyphName: "Aring", Wx: 722.000000, Wy: 0.000000},
"Atilde": {GlyphName: "Atilde", Wx: 722.000000, Wy: 0.000000},
"B": {GlyphName: "B", Wx: 722.000000, Wy: 0.000000},
"C": {GlyphName: "C", Wx: 722.000000, Wy: 0.000000},
"Cacute": {GlyphName: "Cacute", Wx: 722.000000, Wy: 0.000000},
"Ccaron": {GlyphName: "Ccaron", Wx: 722.000000, Wy: 0.000000},
"Ccedilla": {GlyphName: "Ccedilla", Wx: 722.000000, Wy: 0.000000},
"D": {GlyphName: "D", Wx: 722.000000, Wy: 0.000000},
"Dcaron": {GlyphName: "Dcaron", Wx: 722.000000, Wy: 0.000000},
"Dcroat": {GlyphName: "Dcroat", Wx: 722.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 612.000000, Wy: 0.000000},
"E": {GlyphName: "E", Wx: 667.000000, Wy: 0.000000},
"Eacute": {GlyphName: "Eacute", Wx: 667.000000, Wy: 0.000000},
"Ecaron": {GlyphName: "Ecaron", Wx: 667.000000, Wy: 0.000000},
"Ecircumflex": {GlyphName: "Ecircumflex", Wx: 667.000000, Wy: 0.000000},
"Edieresis": {GlyphName: "Edieresis", Wx: 667.000000, Wy: 0.000000},
"Edotaccent": {GlyphName: "Edotaccent", Wx: 667.000000, Wy: 0.000000},
"Egrave": {GlyphName: "Egrave", Wx: 667.000000, Wy: 0.000000},
"Emacron": {GlyphName: "Emacron", Wx: 667.000000, Wy: 0.000000},
"Eogonek": {GlyphName: "Eogonek", Wx: 667.000000, Wy: 0.000000},
"Eth": {GlyphName: "Eth", Wx: 722.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 556.000000, Wy: 0.000000},
"F": {GlyphName: "F", Wx: 611.000000, Wy: 0.000000},
"G": {GlyphName: "G", Wx: 778.000000, Wy: 0.000000},
"Gbreve": {GlyphName: "Gbreve", Wx: 778.000000, Wy: 0.000000},
"Gcommaaccent": {GlyphName: "Gcommaaccent", Wx: 778.000000, Wy: 0.000000},
"H": {GlyphName: "H", Wx: 722.000000, Wy: 0.000000},
"I": {GlyphName: "I", Wx: 278.000000, Wy: 0.000000},
"Iacute": {GlyphName: "Iacute", Wx: 278.000000, Wy: 0.000000},
"Icircumflex": {GlyphName: "Icircumflex", Wx: 278.000000, Wy: 0.000000},
"Idieresis": {GlyphName: "Idieresis", Wx: 278.000000, Wy: 0.000000},
"Idotaccent": {GlyphName: "Idotaccent", Wx: 278.000000, Wy: 0.000000},
"Igrave": {GlyphName: "Igrave", Wx: 278.000000, Wy: 0.000000},
"Imacron": {GlyphName: "Imacron", Wx: 278.000000, Wy: 0.000000},
"Iogonek": {GlyphName: "Iogonek", Wx: 278.000000, Wy: 0.000000},
"J": {GlyphName: "J", Wx: 556.000000, Wy: 0.000000},
"K": {GlyphName: "K", Wx: 722.000000, Wy: 0.000000},
"Kcommaaccent": {GlyphName: "Kcommaaccent", Wx: 722.000000, Wy: 0.000000},
"L": {GlyphName: "L", Wx: 611.000000, Wy: 0.000000},
"Lacute": {GlyphName: "Lacute", Wx: 611.000000, Wy: 0.000000},
"Lcaron": {GlyphName: "Lcaron", Wx: 611.000000, Wy: 0.000000},
"Lcommaaccent": {GlyphName: "Lcommaaccent", Wx: 611.000000, Wy: 0.000000},
"Lslash": {GlyphName: "Lslash", Wx: 611.000000, Wy: 0.000000},
"M": {GlyphName: "M", Wx: 833.000000, Wy: 0.000000},
"N": {GlyphName: "N", Wx: 722.000000, Wy: 0.000000},
"Nacute": {GlyphName: "Nacute", Wx: 722.000000, Wy: 0.000000},
"Ncaron": {GlyphName: "Ncaron", Wx: 722.000000, Wy: 0.000000},
"Ncommaaccent": {GlyphName: "Ncommaaccent", Wx: 722.000000, Wy: 0.000000},
"Ntilde": {GlyphName: "Ntilde", Wx: 722.000000, Wy: 0.000000},
"O": {GlyphName: "O", Wx: 778.000000, Wy: 0.000000},
"OE": {GlyphName: "OE", Wx: 1000.000000, Wy: 0.000000},
"Oacute": {GlyphName: "Oacute", Wx: 778.000000, Wy: 0.000000},
"Ocircumflex": {GlyphName: "Ocircumflex", Wx: 778.000000, Wy: 0.000000},
"Odieresis": {GlyphName: "Odieresis", Wx: 778.000000, Wy: 0.000000},
"Ograve": {GlyphName: "Ograve", Wx: 778.000000, Wy: 0.000000},
"Ohungarumlaut": {GlyphName: "Ohungarumlaut", Wx: 778.000000, Wy: 0.000000},
"Omacron": {GlyphName: "Omacron", Wx: 778.000000, Wy: 0.000000},
"Oslash": {GlyphName: "Oslash", Wx: 778.000000, Wy: 0.000000},
"Otilde": {GlyphName: "Otilde", Wx: 778.000000, Wy: 0.000000},
"P": {GlyphName: "P", Wx: 667.000000, Wy: 0.000000},
"Q": {GlyphName: "Q", Wx: 778.000000, Wy: 0.000000},
"R": {GlyphName: "R", Wx: 722.000000, Wy: 0.000000},
"Racute": {GlyphName: "Racute", Wx: 722.000000, Wy: 0.000000},
"Rcaron": {GlyphName: "Rcaron", Wx: 722.000000, Wy: 0.000000},
"Rcommaaccent": {GlyphName: "Rcommaaccent", Wx: 722.000000, Wy: 0.000000},
"S": {GlyphName: "S", Wx: 667.000000, Wy: 0.000000},
"Sacute": {GlyphName: "Sacute", Wx: 667.000000, Wy: 0.000000},
"Scaron": {GlyphName: "Scaron", Wx: 667.000000, Wy: 0.000000},
"Scedilla": {GlyphName: "Scedilla", Wx: 667.000000, Wy: 0.000000},
"Scommaaccent": {GlyphName: "Scommaaccent", Wx: 667.000000, Wy: 0.000000},
"T": {GlyphName: "T", Wx: 611.000000, Wy: 0.000000},
"Tcaron": {GlyphName: "Tcaron", Wx: 611.000000, Wy: 0.000000},
"Tcommaaccent": {GlyphName: "Tcommaaccent", Wx: 611.000000, Wy: 0.000000},
"Thorn": {GlyphName: "Thorn", Wx: 667.000000, Wy: 0.000000},
"U": {GlyphName: "U", Wx: 722.000000, Wy: 0.000000},
"Uacute": {GlyphName: "Uacute", Wx: 722.000000, Wy: 0.000000},
"Ucircumflex": {GlyphName: "Ucircumflex", Wx: 722.000000, Wy: 0.000000},
"Udieresis": {GlyphName: "Udieresis", Wx: 722.000000, Wy: 0.000000},
"Ugrave": {GlyphName: "Ugrave", Wx: 722.000000, Wy: 0.000000},
"Uhungarumlaut": {GlyphName: "Uhungarumlaut", Wx: 722.000000, Wy: 0.000000},
"Umacron": {GlyphName: "Umacron", Wx: 722.000000, Wy: 0.000000},
"Uogonek": {GlyphName: "Uogonek", Wx: 722.000000, Wy: 0.000000},
"Uring": {GlyphName: "Uring", Wx: 722.000000, Wy: 0.000000},
"V": {GlyphName: "V", Wx: 667.000000, Wy: 0.000000},
"W": {GlyphName: "W", Wx: 944.000000, Wy: 0.000000},
"X": {GlyphName: "X", Wx: 667.000000, Wy: 0.000000},
"Y": {GlyphName: "Y", Wx: 667.000000, Wy: 0.000000},
"Yacute": {GlyphName: "Yacute", Wx: 667.000000, Wy: 0.000000},
"Ydieresis": {GlyphName: "Ydieresis", Wx: 667.000000, Wy: 0.000000},
"Z": {GlyphName: "Z", Wx: 611.000000, Wy: 0.000000},
"Zacute": {GlyphName: "Zacute", Wx: 611.000000, Wy: 0.000000},
"Zcaron": {GlyphName: "Zcaron", Wx: 611.000000, Wy: 0.000000},
"Zdotaccent": {GlyphName: "Zdotaccent", Wx: 611.000000, Wy: 0.000000},
"a": {GlyphName: "a", Wx: 556.000000, Wy: 0.000000},
"aacute": {GlyphName: "aacute", Wx: 556.000000, Wy: 0.000000},
"abreve": {GlyphName: "abreve", Wx: 556.000000, Wy: 0.000000},
"acircumflex": {GlyphName: "acircumflex", Wx: 556.000000, Wy: 0.000000},
"acute": {GlyphName: "acute", Wx: 333.000000, Wy: 0.000000},
"adieresis": {GlyphName: "adieresis", Wx: 556.000000, Wy: 0.000000},
"ae": {GlyphName: "ae", Wx: 889.000000, Wy: 0.000000},
"agrave": {GlyphName: "agrave", Wx: 556.000000, Wy: 0.000000},
"amacron": {GlyphName: "amacron", Wx: 556.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 722.000000, Wy: 0.000000},
"aogonek": {GlyphName: "aogonek", Wx: 556.000000, Wy: 0.000000},
"aring": {GlyphName: "aring", Wx: 556.000000, Wy: 0.000000},
"asciicircum": {GlyphName: "asciicircum", Wx: 584.000000, Wy: 0.000000},
"asciitilde": {GlyphName: "asciitilde", Wx: 584.000000, Wy: 0.000000},
"asterisk": {GlyphName: "asterisk", Wx: 389.000000, Wy: 0.000000},
"at": {GlyphName: "at", Wx: 975.000000, Wy: 0.000000},
"atilde": {GlyphName: "atilde", Wx: 556.000000, Wy: 0.000000},
"b": {GlyphName: "b", Wx: 611.000000, Wy: 0.000000},
"backslash": {GlyphName: "backslash", Wx: 278.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 280.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 389.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 389.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 333.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 333.000000, Wy: 0.000000},
"breve": {GlyphName: "breve", Wx: 333.000000, Wy: 0.000000},
"brokenbar": {GlyphName: "brokenbar", Wx: 280.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 350.000000, Wy: 0.000000},
"c": {GlyphName: "c", Wx: 556.000000, Wy: 0.000000},
"cacute": {GlyphName: "cacute", Wx: 556.000000, Wy: 0.000000},
"caron": {GlyphName: "caron", Wx: 333.000000, Wy: 0.000000},
"ccaron": {GlyphName: "ccaron", Wx: 556.000000, Wy: 0.000000},
"ccedilla": {GlyphName: "ccedilla", Wx: 556.000000, Wy: 0.000000},
"cedilla": {GlyphName: "cedilla", Wx: 333.000000, Wy: 0.000000},
"cent": {GlyphName: "cent", Wx: 556.000000, Wy: 0.000000},
"circumflex": {GlyphName: "circumflex", Wx: 333.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 333.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 278.000000, Wy: 0.000000},
"commaaccent": {GlyphName: "commaaccent", Wx: 250.000000, Wy: 0.000000},
"copyright": {GlyphName: "copyright", Wx: 737.000000, Wy: 0.000000},
"currency": {GlyphName: "currency", Wx: 556.000000, Wy: 0.000000},
"d": {GlyphName: "d", Wx: 611.000000, Wy: 0.000000},
"dagger": {GlyphName: "dagger", Wx: 556.000000, Wy: 0.000000},
"daggerdbl": {GlyphName: "daggerdbl", Wx: 556.000000, Wy: 0.000000},
"dcaron": {GlyphName: "dcaron", Wx: 743.000000, Wy: 0.000000},
"dcroat": {GlyphName: "dcroat", Wx: 611.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 400.000000, Wy: 0.000000},
"dieresis": {GlyphName: "dieresis", Wx: 333.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 584.000000, Wy: 0.000000},
"dollar": {GlyphName: "dollar", Wx: 556.000000, Wy: 0.000000},
"dotaccent": {GlyphName: "dotaccent", Wx: 333.000000, Wy: 0.000000},
"dotlessi": {GlyphName: "dotlessi", Wx: 278.000000, Wy: 0.000000},
"e": {GlyphName: "e", Wx: 556.000000, Wy: 0.000000},
"eacute": {GlyphName: "eacute", Wx: 556.000000, Wy: 0.000000},
"ecaron": {GlyphName: "ecaron", Wx: 556.000000, Wy: 0.000000},
"ecircumflex": {GlyphName: "ecircumflex", Wx: 556.000000, Wy: 0.000000},
"edieresis": {GlyphName: "edieresis", Wx: 556.000000, Wy: 0.000000},
"edotaccent": {GlyphName: "edotaccent", Wx: 556.000000, Wy: 0.000000},
"egrave": {GlyphName: "egrave", Wx: 556.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 556.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 1000.000000, Wy: 0.000000},
"emacron": {GlyphName: "emacron", Wx: 556.000000, Wy: 0.000000},
"emdash": {GlyphName: "emdash", Wx: 1000.000000, Wy: 0.000000},
"endash": {GlyphName: "endash", Wx: 556.000000, Wy: 0.000000},
"eogonek": {GlyphName: "eogonek", Wx: 556.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 584.000000, Wy: 0.000000},
"eth": {GlyphName: "eth", Wx: 611.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 333.000000, Wy: 0.000000},
"exclamdown": {GlyphName: "exclamdown", Wx: 333.000000, Wy: 0.000000},
"f": {GlyphName: "f", Wx: 333.000000, Wy: 0.000000},
"fi": {GlyphName: "fi", Wx: 611.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 556.000000, Wy: 0.000000},
"fl": {GlyphName: "fl", Wx: 611.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 556.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 556.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 167.000000, Wy: 0.000000},
"g": {GlyphName: "g", Wx: 611.000000, Wy: 0.000000},
"gbreve": {GlyphName: "gbreve", Wx: 611.000000, Wy: 0.000000},
"gcommaaccent": {GlyphName: "gcommaaccent", Wx: 611.000000, Wy: 0.000000},
"germandbls": {GlyphName: "germandbls", Wx: 611.000000, Wy: 0.000000},
"grave": {GlyphName: "grave", Wx: 333.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 584.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 549.000000, Wy: 0.000000},
"guillemotleft": {GlyphName: "guillemotleft", Wx: 556.000000, Wy: 0.000000},
"guillemotright": {GlyphName: "guillemotright", Wx: 556.000000, Wy: 0.000000},
"guilsinglleft": {GlyphName: "guilsinglleft", Wx: 333.000000, Wy: 0.000000},
"guilsinglright": {GlyphName: "guilsinglright", Wx: 333.000000, Wy: 0.000000},
"h": {GlyphName: "h", Wx: 611.000000, Wy: 0.000000},
"hungarumlaut": {GlyphName: "hungarumlaut", Wx: 333.000000, Wy: 0.000000},
"hyphen": {GlyphName: "hyphen", Wx: 333.000000, Wy: 0.000000},
"i": {GlyphName: "i", Wx: 278.000000, Wy: 0.000000},
"iacute": {GlyphName: "iacute", Wx: 278.000000, Wy: 0.000000},
"icircumflex": {GlyphName: "icircumflex", Wx: 278.000000, Wy: 0.000000},
"idieresis": {GlyphName: "idieresis", Wx: 278.000000, Wy: 0.000000},
"igrave": {GlyphName: "igrave", Wx: 278.000000, Wy: 0.000000},
"imacron": {GlyphName: "imacron", Wx: 278.000000, Wy: 0.000000},
"iogonek": {GlyphName: "iogonek", Wx: 278.000000, Wy: 0.000000},
"j": {GlyphName: "j", Wx: 278.000000, Wy: 0.000000},
"k": {GlyphName: "k", Wx: 556.000000, Wy: 0.000000},
"kcommaaccent": {GlyphName: "kcommaaccent", Wx: 556.000000, Wy: 0.000000},
"l": {GlyphName: "l", Wx: 278.000000, Wy: 0.000000},
"lacute": {GlyphName: "lacute", Wx: 278.000000, Wy: 0.000000},
"lcaron": {GlyphName: "lcaron", Wx: 400.000000, Wy: 0.000000},
"lcommaaccent": {GlyphName: "lcommaaccent", Wx: 278.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 584.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 549.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 584.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 494.000000, Wy: 0.000000},
"lslash": {GlyphName: "lslash", Wx: 278.000000, Wy: 0.000000},
"m": {GlyphName: "m", Wx: 889.000000, Wy: 0.000000},
"macron": {GlyphName: "macron", Wx: 333.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 584.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 611.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 584.000000, Wy: 0.000000},
"n": {GlyphName: "n", Wx: 611.000000, Wy: 0.000000},
"nacute": {GlyphName: "nacute", Wx: 611.000000, Wy: 0.000000},
"ncaron": {GlyphName: "ncaron", Wx: 611.000000, Wy: 0.000000},
"ncommaaccent": {GlyphName: "ncommaaccent", Wx: 611.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 556.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 549.000000, Wy: 0.000000},
"ntilde": {GlyphName: "ntilde", Wx: 611.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 556.000000, Wy: 0.000000},
"o": {GlyphName: "o", Wx: 611.000000, Wy: 0.000000},
"oacute": {GlyphName: "oacute", Wx: 611.000000, Wy: 0.000000},
"ocircumflex": {GlyphName: "ocircumflex", Wx: 611.000000, Wy: 0.000000},
"odieresis": {GlyphName: "odieresis", Wx: 611.000000, Wy: 0.000000},
"oe": {GlyphName: "oe", Wx: 944.000000, Wy: 0.000000},
"ogonek": {GlyphName: "ogonek", Wx: 333.000000, Wy: 0.000000},
"ograve": {GlyphName: "ograve", Wx: 611.000000, Wy: 0.000000},
"ohungarumlaut": {GlyphName: "ohungarumlaut", Wx: 611.000000, Wy: 0.000000},
"omacron": {GlyphName: "omacron", Wx: 611.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 556.000000, Wy: 0.000000},
"onehalf": {GlyphName: "onehalf", Wx: 834.000000, Wy: 0.000000},
"onequarter": {GlyphName: "onequarter", Wx: 834.000000, Wy: 0.000000},
"onesuperior": {GlyphName: "onesuperior", Wx: 333.000000, Wy: 0.000000},
"ordfeminine": {GlyphName: "ordfeminine", Wx: 370.000000, Wy: 0.000000},
"ordmasculine": {GlyphName: "ordmasculine", Wx: 365.000000, Wy: 0.000000},
"oslash": {GlyphName: "oslash", Wx: 611.000000, Wy: 0.000000},
"otilde": {GlyphName: "otilde", Wx: 611.000000, Wy: 0.000000},
"p": {GlyphName: "p", Wx: 611.000000, Wy: 0.000000},
"paragraph": {GlyphName: "paragraph", Wx: 556.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 333.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 333.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 494.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 889.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 278.000000, Wy: 0.000000},
"periodcentered": {GlyphName: "periodcentered", Wx: 278.000000, Wy: 0.000000},
"perthousand": {GlyphName: "perthousand", Wx: 1000.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 584.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 584.000000, Wy: 0.000000},
"q": {GlyphName: "q", Wx: 611.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 611.000000, Wy: 0.000000},
"questiondown": {GlyphName: "questiondown", Wx: 611.000000, Wy: 0.000000},
"quotedbl": {GlyphName: "quotedbl", Wx: 474.000000, Wy: 0.000000},
"quotedblbase": {GlyphName: "quotedblbase", Wx: 500.000000, Wy: 0.000000},
"quotedblleft": {GlyphName: "quotedblleft", Wx: 500.000000, Wy: 0.000000},
"quotedblright": {GlyphName: "quotedblright", Wx: 500.000000, Wy: 0.000000},
"quoteleft": {GlyphName: "quoteleft", Wx: 278.000000, Wy: 0.000000},
"quoteright": {GlyphName: "quoteright", Wx: 278.000000, Wy: 0.000000},
"quotesinglbase": {GlyphName: "quotesinglbase", Wx: 278.000000, Wy: 0.000000},
"quotesingle": {GlyphName: "quotesingle", Wx: 238.000000, Wy: 0.000000},
"r": {GlyphName: "r", Wx: 389.000000, Wy: 0.000000},
"racute": {GlyphName: "racute", Wx: 389.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 549.000000, Wy: 0.000000},
"rcaron": {GlyphName: "rcaron", Wx: 389.000000, Wy: 0.000000},
"rcommaaccent": {GlyphName: "rcommaaccent", Wx: 389.000000, Wy: 0.000000},
"registered": {GlyphName: "registered", Wx: 737.000000, Wy: 0.000000},
"ring": {GlyphName: "ring", Wx: 333.000000, Wy: 0.000000},
"s": {GlyphName: "s", Wx: 556.000000, Wy: 0.000000},
"sacute": {GlyphName: "sacute", Wx: 556.000000, Wy: 0.000000},
"scaron": {GlyphName: "scaron", Wx: 556.000000, Wy: 0.000000},
"scedilla": {GlyphName: "scedilla", Wx: 556.000000, Wy: 0.000000},
"scommaaccent": {GlyphName: "scommaaccent", Wx: 556.000000, Wy: 0.000000},
"section": {GlyphName: "section", Wx: 556.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 333.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 556.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 556.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 278.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 278.000000, Wy: 0.000000},
"sterling": {GlyphName: "sterling", Wx: 556.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 600.000000, Wy: 0.000000},
"t": {GlyphName: "t", Wx: 333.000000, Wy: 0.000000},
"tcaron": {GlyphName: "tcaron", Wx: 389.000000, Wy: 0.000000},
"tcommaaccent": {GlyphName: "tcommaaccent", Wx: 333.000000, Wy: 0.000000},
"thorn": {GlyphName: "thorn", Wx: 611.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 556.000000, Wy: 0.000000},
"threequarters": {GlyphName: "threequarters", Wx: 834.000000, Wy: 0.000000},
"threesuperior": {GlyphName: "threesuperior", Wx: 333.000000, Wy: 0.000000},
"tilde": {GlyphName: "tilde", Wx: 333.000000, Wy: 0.000000},
"trademark": {GlyphName: "trademark", Wx: 1000.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 556.000000, Wy: 0.000000},
"twosuperior": {GlyphName: "twosuperior", Wx: 333.000000, Wy: 0.000000},
"u": {GlyphName: "u", Wx: 611.000000, Wy: 0.000000},
"uacute": {GlyphName: "uacute", Wx: 611.000000, Wy: 0.000000},
"ucircumflex": {GlyphName: "ucircumflex", Wx: 611.000000, Wy: 0.000000},
"udieresis": {GlyphName: "udieresis", Wx: 611.000000, Wy: 0.000000},
"ugrave": {GlyphName: "ugrave", Wx: 611.000000, Wy: 0.000000},
"uhungarumlaut": {GlyphName: "uhungarumlaut", Wx: 611.000000, Wy: 0.000000},
"umacron": {GlyphName: "umacron", Wx: 611.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 556.000000, Wy: 0.000000},
"uogonek": {GlyphName: "uogonek", Wx: 611.000000, Wy: 0.000000},
"uring": {GlyphName: "uring", Wx: 611.000000, Wy: 0.000000},
"v": {GlyphName: "v", Wx: 556.000000, Wy: 0.000000},
"w": {GlyphName: "w", Wx: 778.000000, Wy: 0.000000},
"x": {GlyphName: "x", Wx: 556.000000, Wy: 0.000000},
"y": {GlyphName: "y", Wx: 556.000000, Wy: 0.000000},
"yacute": {GlyphName: "yacute", Wx: 556.000000, Wy: 0.000000},
"ydieresis": {GlyphName: "ydieresis", Wx: 556.000000, Wy: 0.000000},
"yen": {GlyphName: "yen", Wx: 556.000000, Wy: 0.000000},
"z": {GlyphName: "z", Wx: 500.000000, Wy: 0.000000},
"zacute": {GlyphName: "zacute", Wx: 500.000000, Wy: 0.000000},
"zcaron": {GlyphName: "zcaron", Wx: 500.000000, Wy: 0.000000},
"zdotaccent": {GlyphName: "zdotaccent", Wx: 500.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 556.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,362 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Helvetica-Oblique. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontHelveticaOblique struct {
encoder textencoding.TextEncoder
}
func NewFontHelveticaOblique() fontHelveticaOblique {
font := fontHelveticaOblique{}
font.encoder = textencoding.NewWinAnsiTextEncoder() // Default
return font
}
func (font fontHelveticaOblique) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontHelveticaOblique) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := helveticaObliqueCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontHelveticaOblique) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Helvetica-Oblique"))
fontDict.Set("Encoding", font.encoder.ToPdfObject())
obj.PdfObject = fontDict
return obj
}
var helveticaObliqueCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"A": {GlyphName: "A", Wx: 667.000000, Wy: 0.000000},
"AE": {GlyphName: "AE", Wx: 1000.000000, Wy: 0.000000},
"Aacute": {GlyphName: "Aacute", Wx: 667.000000, Wy: 0.000000},
"Abreve": {GlyphName: "Abreve", Wx: 667.000000, Wy: 0.000000},
"Acircumflex": {GlyphName: "Acircumflex", Wx: 667.000000, Wy: 0.000000},
"Adieresis": {GlyphName: "Adieresis", Wx: 667.000000, Wy: 0.000000},
"Agrave": {GlyphName: "Agrave", Wx: 667.000000, Wy: 0.000000},
"Amacron": {GlyphName: "Amacron", Wx: 667.000000, Wy: 0.000000},
"Aogonek": {GlyphName: "Aogonek", Wx: 667.000000, Wy: 0.000000},
"Aring": {GlyphName: "Aring", Wx: 667.000000, Wy: 0.000000},
"Atilde": {GlyphName: "Atilde", Wx: 667.000000, Wy: 0.000000},
"B": {GlyphName: "B", Wx: 667.000000, Wy: 0.000000},
"C": {GlyphName: "C", Wx: 722.000000, Wy: 0.000000},
"Cacute": {GlyphName: "Cacute", Wx: 722.000000, Wy: 0.000000},
"Ccaron": {GlyphName: "Ccaron", Wx: 722.000000, Wy: 0.000000},
"Ccedilla": {GlyphName: "Ccedilla", Wx: 722.000000, Wy: 0.000000},
"D": {GlyphName: "D", Wx: 722.000000, Wy: 0.000000},
"Dcaron": {GlyphName: "Dcaron", Wx: 722.000000, Wy: 0.000000},
"Dcroat": {GlyphName: "Dcroat", Wx: 722.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 612.000000, Wy: 0.000000},
"E": {GlyphName: "E", Wx: 667.000000, Wy: 0.000000},
"Eacute": {GlyphName: "Eacute", Wx: 667.000000, Wy: 0.000000},
"Ecaron": {GlyphName: "Ecaron", Wx: 667.000000, Wy: 0.000000},
"Ecircumflex": {GlyphName: "Ecircumflex", Wx: 667.000000, Wy: 0.000000},
"Edieresis": {GlyphName: "Edieresis", Wx: 667.000000, Wy: 0.000000},
"Edotaccent": {GlyphName: "Edotaccent", Wx: 667.000000, Wy: 0.000000},
"Egrave": {GlyphName: "Egrave", Wx: 667.000000, Wy: 0.000000},
"Emacron": {GlyphName: "Emacron", Wx: 667.000000, Wy: 0.000000},
"Eogonek": {GlyphName: "Eogonek", Wx: 667.000000, Wy: 0.000000},
"Eth": {GlyphName: "Eth", Wx: 722.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 556.000000, Wy: 0.000000},
"F": {GlyphName: "F", Wx: 611.000000, Wy: 0.000000},
"G": {GlyphName: "G", Wx: 778.000000, Wy: 0.000000},
"Gbreve": {GlyphName: "Gbreve", Wx: 778.000000, Wy: 0.000000},
"Gcommaaccent": {GlyphName: "Gcommaaccent", Wx: 778.000000, Wy: 0.000000},
"H": {GlyphName: "H", Wx: 722.000000, Wy: 0.000000},
"I": {GlyphName: "I", Wx: 278.000000, Wy: 0.000000},
"Iacute": {GlyphName: "Iacute", Wx: 278.000000, Wy: 0.000000},
"Icircumflex": {GlyphName: "Icircumflex", Wx: 278.000000, Wy: 0.000000},
"Idieresis": {GlyphName: "Idieresis", Wx: 278.000000, Wy: 0.000000},
"Idotaccent": {GlyphName: "Idotaccent", Wx: 278.000000, Wy: 0.000000},
"Igrave": {GlyphName: "Igrave", Wx: 278.000000, Wy: 0.000000},
"Imacron": {GlyphName: "Imacron", Wx: 278.000000, Wy: 0.000000},
"Iogonek": {GlyphName: "Iogonek", Wx: 278.000000, Wy: 0.000000},
"J": {GlyphName: "J", Wx: 500.000000, Wy: 0.000000},
"K": {GlyphName: "K", Wx: 667.000000, Wy: 0.000000},
"Kcommaaccent": {GlyphName: "Kcommaaccent", Wx: 667.000000, Wy: 0.000000},
"L": {GlyphName: "L", Wx: 556.000000, Wy: 0.000000},
"Lacute": {GlyphName: "Lacute", Wx: 556.000000, Wy: 0.000000},
"Lcaron": {GlyphName: "Lcaron", Wx: 556.000000, Wy: 0.000000},
"Lcommaaccent": {GlyphName: "Lcommaaccent", Wx: 556.000000, Wy: 0.000000},
"Lslash": {GlyphName: "Lslash", Wx: 556.000000, Wy: 0.000000},
"M": {GlyphName: "M", Wx: 833.000000, Wy: 0.000000},
"N": {GlyphName: "N", Wx: 722.000000, Wy: 0.000000},
"Nacute": {GlyphName: "Nacute", Wx: 722.000000, Wy: 0.000000},
"Ncaron": {GlyphName: "Ncaron", Wx: 722.000000, Wy: 0.000000},
"Ncommaaccent": {GlyphName: "Ncommaaccent", Wx: 722.000000, Wy: 0.000000},
"Ntilde": {GlyphName: "Ntilde", Wx: 722.000000, Wy: 0.000000},
"O": {GlyphName: "O", Wx: 778.000000, Wy: 0.000000},
"OE": {GlyphName: "OE", Wx: 1000.000000, Wy: 0.000000},
"Oacute": {GlyphName: "Oacute", Wx: 778.000000, Wy: 0.000000},
"Ocircumflex": {GlyphName: "Ocircumflex", Wx: 778.000000, Wy: 0.000000},
"Odieresis": {GlyphName: "Odieresis", Wx: 778.000000, Wy: 0.000000},
"Ograve": {GlyphName: "Ograve", Wx: 778.000000, Wy: 0.000000},
"Ohungarumlaut": {GlyphName: "Ohungarumlaut", Wx: 778.000000, Wy: 0.000000},
"Omacron": {GlyphName: "Omacron", Wx: 778.000000, Wy: 0.000000},
"Oslash": {GlyphName: "Oslash", Wx: 778.000000, Wy: 0.000000},
"Otilde": {GlyphName: "Otilde", Wx: 778.000000, Wy: 0.000000},
"P": {GlyphName: "P", Wx: 667.000000, Wy: 0.000000},
"Q": {GlyphName: "Q", Wx: 778.000000, Wy: 0.000000},
"R": {GlyphName: "R", Wx: 722.000000, Wy: 0.000000},
"Racute": {GlyphName: "Racute", Wx: 722.000000, Wy: 0.000000},
"Rcaron": {GlyphName: "Rcaron", Wx: 722.000000, Wy: 0.000000},
"Rcommaaccent": {GlyphName: "Rcommaaccent", Wx: 722.000000, Wy: 0.000000},
"S": {GlyphName: "S", Wx: 667.000000, Wy: 0.000000},
"Sacute": {GlyphName: "Sacute", Wx: 667.000000, Wy: 0.000000},
"Scaron": {GlyphName: "Scaron", Wx: 667.000000, Wy: 0.000000},
"Scedilla": {GlyphName: "Scedilla", Wx: 667.000000, Wy: 0.000000},
"Scommaaccent": {GlyphName: "Scommaaccent", Wx: 667.000000, Wy: 0.000000},
"T": {GlyphName: "T", Wx: 611.000000, Wy: 0.000000},
"Tcaron": {GlyphName: "Tcaron", Wx: 611.000000, Wy: 0.000000},
"Tcommaaccent": {GlyphName: "Tcommaaccent", Wx: 611.000000, Wy: 0.000000},
"Thorn": {GlyphName: "Thorn", Wx: 667.000000, Wy: 0.000000},
"U": {GlyphName: "U", Wx: 722.000000, Wy: 0.000000},
"Uacute": {GlyphName: "Uacute", Wx: 722.000000, Wy: 0.000000},
"Ucircumflex": {GlyphName: "Ucircumflex", Wx: 722.000000, Wy: 0.000000},
"Udieresis": {GlyphName: "Udieresis", Wx: 722.000000, Wy: 0.000000},
"Ugrave": {GlyphName: "Ugrave", Wx: 722.000000, Wy: 0.000000},
"Uhungarumlaut": {GlyphName: "Uhungarumlaut", Wx: 722.000000, Wy: 0.000000},
"Umacron": {GlyphName: "Umacron", Wx: 722.000000, Wy: 0.000000},
"Uogonek": {GlyphName: "Uogonek", Wx: 722.000000, Wy: 0.000000},
"Uring": {GlyphName: "Uring", Wx: 722.000000, Wy: 0.000000},
"V": {GlyphName: "V", Wx: 667.000000, Wy: 0.000000},
"W": {GlyphName: "W", Wx: 944.000000, Wy: 0.000000},
"X": {GlyphName: "X", Wx: 667.000000, Wy: 0.000000},
"Y": {GlyphName: "Y", Wx: 667.000000, Wy: 0.000000},
"Yacute": {GlyphName: "Yacute", Wx: 667.000000, Wy: 0.000000},
"Ydieresis": {GlyphName: "Ydieresis", Wx: 667.000000, Wy: 0.000000},
"Z": {GlyphName: "Z", Wx: 611.000000, Wy: 0.000000},
"Zacute": {GlyphName: "Zacute", Wx: 611.000000, Wy: 0.000000},
"Zcaron": {GlyphName: "Zcaron", Wx: 611.000000, Wy: 0.000000},
"Zdotaccent": {GlyphName: "Zdotaccent", Wx: 611.000000, Wy: 0.000000},
"a": {GlyphName: "a", Wx: 556.000000, Wy: 0.000000},
"aacute": {GlyphName: "aacute", Wx: 556.000000, Wy: 0.000000},
"abreve": {GlyphName: "abreve", Wx: 556.000000, Wy: 0.000000},
"acircumflex": {GlyphName: "acircumflex", Wx: 556.000000, Wy: 0.000000},
"acute": {GlyphName: "acute", Wx: 333.000000, Wy: 0.000000},
"adieresis": {GlyphName: "adieresis", Wx: 556.000000, Wy: 0.000000},
"ae": {GlyphName: "ae", Wx: 889.000000, Wy: 0.000000},
"agrave": {GlyphName: "agrave", Wx: 556.000000, Wy: 0.000000},
"amacron": {GlyphName: "amacron", Wx: 556.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 667.000000, Wy: 0.000000},
"aogonek": {GlyphName: "aogonek", Wx: 556.000000, Wy: 0.000000},
"aring": {GlyphName: "aring", Wx: 556.000000, Wy: 0.000000},
"asciicircum": {GlyphName: "asciicircum", Wx: 469.000000, Wy: 0.000000},
"asciitilde": {GlyphName: "asciitilde", Wx: 584.000000, Wy: 0.000000},
"asterisk": {GlyphName: "asterisk", Wx: 389.000000, Wy: 0.000000},
"at": {GlyphName: "at", Wx: 1015.000000, Wy: 0.000000},
"atilde": {GlyphName: "atilde", Wx: 556.000000, Wy: 0.000000},
"b": {GlyphName: "b", Wx: 556.000000, Wy: 0.000000},
"backslash": {GlyphName: "backslash", Wx: 278.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 260.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 334.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 334.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 278.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 278.000000, Wy: 0.000000},
"breve": {GlyphName: "breve", Wx: 333.000000, Wy: 0.000000},
"brokenbar": {GlyphName: "brokenbar", Wx: 260.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 350.000000, Wy: 0.000000},
"c": {GlyphName: "c", Wx: 500.000000, Wy: 0.000000},
"cacute": {GlyphName: "cacute", Wx: 500.000000, Wy: 0.000000},
"caron": {GlyphName: "caron", Wx: 333.000000, Wy: 0.000000},
"ccaron": {GlyphName: "ccaron", Wx: 500.000000, Wy: 0.000000},
"ccedilla": {GlyphName: "ccedilla", Wx: 500.000000, Wy: 0.000000},
"cedilla": {GlyphName: "cedilla", Wx: 333.000000, Wy: 0.000000},
"cent": {GlyphName: "cent", Wx: 556.000000, Wy: 0.000000},
"circumflex": {GlyphName: "circumflex", Wx: 333.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 278.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 278.000000, Wy: 0.000000},
"commaaccent": {GlyphName: "commaaccent", Wx: 250.000000, Wy: 0.000000},
"copyright": {GlyphName: "copyright", Wx: 737.000000, Wy: 0.000000},
"currency": {GlyphName: "currency", Wx: 556.000000, Wy: 0.000000},
"d": {GlyphName: "d", Wx: 556.000000, Wy: 0.000000},
"dagger": {GlyphName: "dagger", Wx: 556.000000, Wy: 0.000000},
"daggerdbl": {GlyphName: "daggerdbl", Wx: 556.000000, Wy: 0.000000},
"dcaron": {GlyphName: "dcaron", Wx: 643.000000, Wy: 0.000000},
"dcroat": {GlyphName: "dcroat", Wx: 556.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 400.000000, Wy: 0.000000},
"dieresis": {GlyphName: "dieresis", Wx: 333.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 584.000000, Wy: 0.000000},
"dollar": {GlyphName: "dollar", Wx: 556.000000, Wy: 0.000000},
"dotaccent": {GlyphName: "dotaccent", Wx: 333.000000, Wy: 0.000000},
"dotlessi": {GlyphName: "dotlessi", Wx: 278.000000, Wy: 0.000000},
"e": {GlyphName: "e", Wx: 556.000000, Wy: 0.000000},
"eacute": {GlyphName: "eacute", Wx: 556.000000, Wy: 0.000000},
"ecaron": {GlyphName: "ecaron", Wx: 556.000000, Wy: 0.000000},
"ecircumflex": {GlyphName: "ecircumflex", Wx: 556.000000, Wy: 0.000000},
"edieresis": {GlyphName: "edieresis", Wx: 556.000000, Wy: 0.000000},
"edotaccent": {GlyphName: "edotaccent", Wx: 556.000000, Wy: 0.000000},
"egrave": {GlyphName: "egrave", Wx: 556.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 556.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 1000.000000, Wy: 0.000000},
"emacron": {GlyphName: "emacron", Wx: 556.000000, Wy: 0.000000},
"emdash": {GlyphName: "emdash", Wx: 1000.000000, Wy: 0.000000},
"endash": {GlyphName: "endash", Wx: 556.000000, Wy: 0.000000},
"eogonek": {GlyphName: "eogonek", Wx: 556.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 584.000000, Wy: 0.000000},
"eth": {GlyphName: "eth", Wx: 556.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 278.000000, Wy: 0.000000},
"exclamdown": {GlyphName: "exclamdown", Wx: 333.000000, Wy: 0.000000},
"f": {GlyphName: "f", Wx: 278.000000, Wy: 0.000000},
"fi": {GlyphName: "fi", Wx: 500.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 556.000000, Wy: 0.000000},
"fl": {GlyphName: "fl", Wx: 500.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 556.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 556.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 167.000000, Wy: 0.000000},
"g": {GlyphName: "g", Wx: 556.000000, Wy: 0.000000},
"gbreve": {GlyphName: "gbreve", Wx: 556.000000, Wy: 0.000000},
"gcommaaccent": {GlyphName: "gcommaaccent", Wx: 556.000000, Wy: 0.000000},
"germandbls": {GlyphName: "germandbls", Wx: 611.000000, Wy: 0.000000},
"grave": {GlyphName: "grave", Wx: 333.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 584.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 549.000000, Wy: 0.000000},
"guillemotleft": {GlyphName: "guillemotleft", Wx: 556.000000, Wy: 0.000000},
"guillemotright": {GlyphName: "guillemotright", Wx: 556.000000, Wy: 0.000000},
"guilsinglleft": {GlyphName: "guilsinglleft", Wx: 333.000000, Wy: 0.000000},
"guilsinglright": {GlyphName: "guilsinglright", Wx: 333.000000, Wy: 0.000000},
"h": {GlyphName: "h", Wx: 556.000000, Wy: 0.000000},
"hungarumlaut": {GlyphName: "hungarumlaut", Wx: 333.000000, Wy: 0.000000},
"hyphen": {GlyphName: "hyphen", Wx: 333.000000, Wy: 0.000000},
"i": {GlyphName: "i", Wx: 222.000000, Wy: 0.000000},
"iacute": {GlyphName: "iacute", Wx: 278.000000, Wy: 0.000000},
"icircumflex": {GlyphName: "icircumflex", Wx: 278.000000, Wy: 0.000000},
"idieresis": {GlyphName: "idieresis", Wx: 278.000000, Wy: 0.000000},
"igrave": {GlyphName: "igrave", Wx: 278.000000, Wy: 0.000000},
"imacron": {GlyphName: "imacron", Wx: 278.000000, Wy: 0.000000},
"iogonek": {GlyphName: "iogonek", Wx: 222.000000, Wy: 0.000000},
"j": {GlyphName: "j", Wx: 222.000000, Wy: 0.000000},
"k": {GlyphName: "k", Wx: 500.000000, Wy: 0.000000},
"kcommaaccent": {GlyphName: "kcommaaccent", Wx: 500.000000, Wy: 0.000000},
"l": {GlyphName: "l", Wx: 222.000000, Wy: 0.000000},
"lacute": {GlyphName: "lacute", Wx: 222.000000, Wy: 0.000000},
"lcaron": {GlyphName: "lcaron", Wx: 299.000000, Wy: 0.000000},
"lcommaaccent": {GlyphName: "lcommaaccent", Wx: 222.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 584.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 549.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 584.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 471.000000, Wy: 0.000000},
"lslash": {GlyphName: "lslash", Wx: 222.000000, Wy: 0.000000},
"m": {GlyphName: "m", Wx: 833.000000, Wy: 0.000000},
"macron": {GlyphName: "macron", Wx: 333.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 584.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 556.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 584.000000, Wy: 0.000000},
"n": {GlyphName: "n", Wx: 556.000000, Wy: 0.000000},
"nacute": {GlyphName: "nacute", Wx: 556.000000, Wy: 0.000000},
"ncaron": {GlyphName: "ncaron", Wx: 556.000000, Wy: 0.000000},
"ncommaaccent": {GlyphName: "ncommaaccent", Wx: 556.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 556.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 549.000000, Wy: 0.000000},
"ntilde": {GlyphName: "ntilde", Wx: 556.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 556.000000, Wy: 0.000000},
"o": {GlyphName: "o", Wx: 556.000000, Wy: 0.000000},
"oacute": {GlyphName: "oacute", Wx: 556.000000, Wy: 0.000000},
"ocircumflex": {GlyphName: "ocircumflex", Wx: 556.000000, Wy: 0.000000},
"odieresis": {GlyphName: "odieresis", Wx: 556.000000, Wy: 0.000000},
"oe": {GlyphName: "oe", Wx: 944.000000, Wy: 0.000000},
"ogonek": {GlyphName: "ogonek", Wx: 333.000000, Wy: 0.000000},
"ograve": {GlyphName: "ograve", Wx: 556.000000, Wy: 0.000000},
"ohungarumlaut": {GlyphName: "ohungarumlaut", Wx: 556.000000, Wy: 0.000000},
"omacron": {GlyphName: "omacron", Wx: 556.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 556.000000, Wy: 0.000000},
"onehalf": {GlyphName: "onehalf", Wx: 834.000000, Wy: 0.000000},
"onequarter": {GlyphName: "onequarter", Wx: 834.000000, Wy: 0.000000},
"onesuperior": {GlyphName: "onesuperior", Wx: 333.000000, Wy: 0.000000},
"ordfeminine": {GlyphName: "ordfeminine", Wx: 370.000000, Wy: 0.000000},
"ordmasculine": {GlyphName: "ordmasculine", Wx: 365.000000, Wy: 0.000000},
"oslash": {GlyphName: "oslash", Wx: 611.000000, Wy: 0.000000},
"otilde": {GlyphName: "otilde", Wx: 556.000000, Wy: 0.000000},
"p": {GlyphName: "p", Wx: 556.000000, Wy: 0.000000},
"paragraph": {GlyphName: "paragraph", Wx: 537.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 333.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 333.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 476.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 889.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 278.000000, Wy: 0.000000},
"periodcentered": {GlyphName: "periodcentered", Wx: 278.000000, Wy: 0.000000},
"perthousand": {GlyphName: "perthousand", Wx: 1000.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 584.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 584.000000, Wy: 0.000000},
"q": {GlyphName: "q", Wx: 556.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 556.000000, Wy: 0.000000},
"questiondown": {GlyphName: "questiondown", Wx: 611.000000, Wy: 0.000000},
"quotedbl": {GlyphName: "quotedbl", Wx: 355.000000, Wy: 0.000000},
"quotedblbase": {GlyphName: "quotedblbase", Wx: 333.000000, Wy: 0.000000},
"quotedblleft": {GlyphName: "quotedblleft", Wx: 333.000000, Wy: 0.000000},
"quotedblright": {GlyphName: "quotedblright", Wx: 333.000000, Wy: 0.000000},
"quoteleft": {GlyphName: "quoteleft", Wx: 222.000000, Wy: 0.000000},
"quoteright": {GlyphName: "quoteright", Wx: 222.000000, Wy: 0.000000},
"quotesinglbase": {GlyphName: "quotesinglbase", Wx: 222.000000, Wy: 0.000000},
"quotesingle": {GlyphName: "quotesingle", Wx: 191.000000, Wy: 0.000000},
"r": {GlyphName: "r", Wx: 333.000000, Wy: 0.000000},
"racute": {GlyphName: "racute", Wx: 333.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 453.000000, Wy: 0.000000},
"rcaron": {GlyphName: "rcaron", Wx: 333.000000, Wy: 0.000000},
"rcommaaccent": {GlyphName: "rcommaaccent", Wx: 333.000000, Wy: 0.000000},
"registered": {GlyphName: "registered", Wx: 737.000000, Wy: 0.000000},
"ring": {GlyphName: "ring", Wx: 333.000000, Wy: 0.000000},
"s": {GlyphName: "s", Wx: 500.000000, Wy: 0.000000},
"sacute": {GlyphName: "sacute", Wx: 500.000000, Wy: 0.000000},
"scaron": {GlyphName: "scaron", Wx: 500.000000, Wy: 0.000000},
"scedilla": {GlyphName: "scedilla", Wx: 500.000000, Wy: 0.000000},
"scommaaccent": {GlyphName: "scommaaccent", Wx: 500.000000, Wy: 0.000000},
"section": {GlyphName: "section", Wx: 556.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 278.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 556.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 556.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 278.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 278.000000, Wy: 0.000000},
"sterling": {GlyphName: "sterling", Wx: 556.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 600.000000, Wy: 0.000000},
"t": {GlyphName: "t", Wx: 278.000000, Wy: 0.000000},
"tcaron": {GlyphName: "tcaron", Wx: 317.000000, Wy: 0.000000},
"tcommaaccent": {GlyphName: "tcommaaccent", Wx: 278.000000, Wy: 0.000000},
"thorn": {GlyphName: "thorn", Wx: 556.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 556.000000, Wy: 0.000000},
"threequarters": {GlyphName: "threequarters", Wx: 834.000000, Wy: 0.000000},
"threesuperior": {GlyphName: "threesuperior", Wx: 333.000000, Wy: 0.000000},
"tilde": {GlyphName: "tilde", Wx: 333.000000, Wy: 0.000000},
"trademark": {GlyphName: "trademark", Wx: 1000.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 556.000000, Wy: 0.000000},
"twosuperior": {GlyphName: "twosuperior", Wx: 333.000000, Wy: 0.000000},
"u": {GlyphName: "u", Wx: 556.000000, Wy: 0.000000},
"uacute": {GlyphName: "uacute", Wx: 556.000000, Wy: 0.000000},
"ucircumflex": {GlyphName: "ucircumflex", Wx: 556.000000, Wy: 0.000000},
"udieresis": {GlyphName: "udieresis", Wx: 556.000000, Wy: 0.000000},
"ugrave": {GlyphName: "ugrave", Wx: 556.000000, Wy: 0.000000},
"uhungarumlaut": {GlyphName: "uhungarumlaut", Wx: 556.000000, Wy: 0.000000},
"umacron": {GlyphName: "umacron", Wx: 556.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 556.000000, Wy: 0.000000},
"uogonek": {GlyphName: "uogonek", Wx: 556.000000, Wy: 0.000000},
"uring": {GlyphName: "uring", Wx: 556.000000, Wy: 0.000000},
"v": {GlyphName: "v", Wx: 500.000000, Wy: 0.000000},
"w": {GlyphName: "w", Wx: 722.000000, Wy: 0.000000},
"x": {GlyphName: "x", Wx: 500.000000, Wy: 0.000000},
"y": {GlyphName: "y", Wx: 500.000000, Wy: 0.000000},
"yacute": {GlyphName: "yacute", Wx: 500.000000, Wy: 0.000000},
"ydieresis": {GlyphName: "ydieresis", Wx: 500.000000, Wy: 0.000000},
"yen": {GlyphName: "yen", Wx: 556.000000, Wy: 0.000000},
"z": {GlyphName: "z", Wx: 500.000000, Wy: 0.000000},
"zacute": {GlyphName: "zacute", Wx: 500.000000, Wy: 0.000000},
"zcaron": {GlyphName: "zcaron", Wx: 500.000000, Wy: 0.000000},
"zdotaccent": {GlyphName: "zdotaccent", Wx: 500.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 556.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,239 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Symbol. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontSymbol struct {
// By default encoder is not set, which means that we use the font's built in encoding.
encoder textencoding.TextEncoder
}
func NewFontSymbol() fontSymbol {
font := fontSymbol{}
return font
}
func (font fontSymbol) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontSymbol) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := symbolCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontSymbol) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Symbol"))
if font.encoder != nil {
fontDict.Set("Encoding", font.encoder.ToPdfObject())
}
obj.PdfObject = fontDict
return obj
}
var symbolCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"Alpha": {GlyphName: "Alpha", Wx: 722.000000, Wy: 0.000000},
"Beta": {GlyphName: "Beta", Wx: 667.000000, Wy: 0.000000},
"Chi": {GlyphName: "Chi", Wx: 722.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 612.000000, Wy: 0.000000},
"Epsilon": {GlyphName: "Epsilon", Wx: 611.000000, Wy: 0.000000},
"Eta": {GlyphName: "Eta", Wx: 722.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 750.000000, Wy: 0.000000},
"Gamma": {GlyphName: "Gamma", Wx: 603.000000, Wy: 0.000000},
"Ifraktur": {GlyphName: "Ifraktur", Wx: 686.000000, Wy: 0.000000},
"Iota": {GlyphName: "Iota", Wx: 333.000000, Wy: 0.000000},
"Kappa": {GlyphName: "Kappa", Wx: 722.000000, Wy: 0.000000},
"Lambda": {GlyphName: "Lambda", Wx: 686.000000, Wy: 0.000000},
"Mu": {GlyphName: "Mu", Wx: 889.000000, Wy: 0.000000},
"Nu": {GlyphName: "Nu", Wx: 722.000000, Wy: 0.000000},
"Omega": {GlyphName: "Omega", Wx: 768.000000, Wy: 0.000000},
"Omicron": {GlyphName: "Omicron", Wx: 722.000000, Wy: 0.000000},
"Phi": {GlyphName: "Phi", Wx: 763.000000, Wy: 0.000000},
"Pi": {GlyphName: "Pi", Wx: 768.000000, Wy: 0.000000},
"Psi": {GlyphName: "Psi", Wx: 795.000000, Wy: 0.000000},
"Rfraktur": {GlyphName: "Rfraktur", Wx: 795.000000, Wy: 0.000000},
"Rho": {GlyphName: "Rho", Wx: 556.000000, Wy: 0.000000},
"Sigma": {GlyphName: "Sigma", Wx: 592.000000, Wy: 0.000000},
"Tau": {GlyphName: "Tau", Wx: 611.000000, Wy: 0.000000},
"Theta": {GlyphName: "Theta", Wx: 741.000000, Wy: 0.000000},
"Upsilon": {GlyphName: "Upsilon", Wx: 690.000000, Wy: 0.000000},
"Upsilon1": {GlyphName: "Upsilon1", Wx: 620.000000, Wy: 0.000000},
"Xi": {GlyphName: "Xi", Wx: 645.000000, Wy: 0.000000},
"Zeta": {GlyphName: "Zeta", Wx: 611.000000, Wy: 0.000000},
"aleph": {GlyphName: "aleph", Wx: 823.000000, Wy: 0.000000},
"alpha": {GlyphName: "alpha", Wx: 631.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 778.000000, Wy: 0.000000},
"angle": {GlyphName: "angle", Wx: 768.000000, Wy: 0.000000},
"angleleft": {GlyphName: "angleleft", Wx: 329.000000, Wy: 0.000000},
"angleright": {GlyphName: "angleright", Wx: 329.000000, Wy: 0.000000},
"apple": {GlyphName: "apple", Wx: 790.000000, Wy: 0.000000},
"approxequal": {GlyphName: "approxequal", Wx: 549.000000, Wy: 0.000000},
"arrowboth": {GlyphName: "arrowboth", Wx: 1042.000000, Wy: 0.000000},
"arrowdblboth": {GlyphName: "arrowdblboth", Wx: 1042.000000, Wy: 0.000000},
"arrowdbldown": {GlyphName: "arrowdbldown", Wx: 603.000000, Wy: 0.000000},
"arrowdblleft": {GlyphName: "arrowdblleft", Wx: 987.000000, Wy: 0.000000},
"arrowdblright": {GlyphName: "arrowdblright", Wx: 987.000000, Wy: 0.000000},
"arrowdblup": {GlyphName: "arrowdblup", Wx: 603.000000, Wy: 0.000000},
"arrowdown": {GlyphName: "arrowdown", Wx: 603.000000, Wy: 0.000000},
"arrowhorizex": {GlyphName: "arrowhorizex", Wx: 1000.000000, Wy: 0.000000},
"arrowleft": {GlyphName: "arrowleft", Wx: 987.000000, Wy: 0.000000},
"arrowright": {GlyphName: "arrowright", Wx: 987.000000, Wy: 0.000000},
"arrowup": {GlyphName: "arrowup", Wx: 603.000000, Wy: 0.000000},
"arrowvertex": {GlyphName: "arrowvertex", Wx: 603.000000, Wy: 0.000000},
"asteriskmath": {GlyphName: "asteriskmath", Wx: 500.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 200.000000, Wy: 0.000000},
"beta": {GlyphName: "beta", Wx: 549.000000, Wy: 0.000000},
"braceex": {GlyphName: "braceex", Wx: 494.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 480.000000, Wy: 0.000000},
"braceleftbt": {GlyphName: "braceleftbt", Wx: 494.000000, Wy: 0.000000},
"braceleftmid": {GlyphName: "braceleftmid", Wx: 494.000000, Wy: 0.000000},
"bracelefttp": {GlyphName: "bracelefttp", Wx: 494.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 480.000000, Wy: 0.000000},
"bracerightbt": {GlyphName: "bracerightbt", Wx: 494.000000, Wy: 0.000000},
"bracerightmid": {GlyphName: "bracerightmid", Wx: 494.000000, Wy: 0.000000},
"bracerighttp": {GlyphName: "bracerighttp", Wx: 494.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 333.000000, Wy: 0.000000},
"bracketleftbt": {GlyphName: "bracketleftbt", Wx: 384.000000, Wy: 0.000000},
"bracketleftex": {GlyphName: "bracketleftex", Wx: 384.000000, Wy: 0.000000},
"bracketlefttp": {GlyphName: "bracketlefttp", Wx: 384.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 333.000000, Wy: 0.000000},
"bracketrightbt": {GlyphName: "bracketrightbt", Wx: 384.000000, Wy: 0.000000},
"bracketrightex": {GlyphName: "bracketrightex", Wx: 384.000000, Wy: 0.000000},
"bracketrighttp": {GlyphName: "bracketrighttp", Wx: 384.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 460.000000, Wy: 0.000000},
"carriagereturn": {GlyphName: "carriagereturn", Wx: 658.000000, Wy: 0.000000},
"chi": {GlyphName: "chi", Wx: 549.000000, Wy: 0.000000},
"circlemultiply": {GlyphName: "circlemultiply", Wx: 768.000000, Wy: 0.000000},
"circleplus": {GlyphName: "circleplus", Wx: 768.000000, Wy: 0.000000},
"club": {GlyphName: "club", Wx: 753.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 278.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 250.000000, Wy: 0.000000},
"congruent": {GlyphName: "congruent", Wx: 549.000000, Wy: 0.000000},
"copyrightsans": {GlyphName: "copyrightsans", Wx: 790.000000, Wy: 0.000000},
"copyrightserif": {GlyphName: "copyrightserif", Wx: 790.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 400.000000, Wy: 0.000000},
"delta": {GlyphName: "delta", Wx: 494.000000, Wy: 0.000000},
"diamond": {GlyphName: "diamond", Wx: 753.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 549.000000, Wy: 0.000000},
"dotmath": {GlyphName: "dotmath", Wx: 250.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 500.000000, Wy: 0.000000},
"element": {GlyphName: "element", Wx: 713.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 1000.000000, Wy: 0.000000},
"emptyset": {GlyphName: "emptyset", Wx: 823.000000, Wy: 0.000000},
"epsilon": {GlyphName: "epsilon", Wx: 439.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 549.000000, Wy: 0.000000},
"equivalence": {GlyphName: "equivalence", Wx: 549.000000, Wy: 0.000000},
"eta": {GlyphName: "eta", Wx: 603.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 333.000000, Wy: 0.000000},
"existential": {GlyphName: "existential", Wx: 549.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 500.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 500.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 500.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 167.000000, Wy: 0.000000},
"gamma": {GlyphName: "gamma", Wx: 411.000000, Wy: 0.000000},
"gradient": {GlyphName: "gradient", Wx: 713.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 549.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 549.000000, Wy: 0.000000},
"heart": {GlyphName: "heart", Wx: 753.000000, Wy: 0.000000},
"infinity": {GlyphName: "infinity", Wx: 713.000000, Wy: 0.000000},
"integral": {GlyphName: "integral", Wx: 274.000000, Wy: 0.000000},
"integralbt": {GlyphName: "integralbt", Wx: 686.000000, Wy: 0.000000},
"integralex": {GlyphName: "integralex", Wx: 686.000000, Wy: 0.000000},
"integraltp": {GlyphName: "integraltp", Wx: 686.000000, Wy: 0.000000},
"intersection": {GlyphName: "intersection", Wx: 768.000000, Wy: 0.000000},
"iota": {GlyphName: "iota", Wx: 329.000000, Wy: 0.000000},
"kappa": {GlyphName: "kappa", Wx: 549.000000, Wy: 0.000000},
"lambda": {GlyphName: "lambda", Wx: 549.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 549.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 549.000000, Wy: 0.000000},
"logicaland": {GlyphName: "logicaland", Wx: 603.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 713.000000, Wy: 0.000000},
"logicalor": {GlyphName: "logicalor", Wx: 603.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 494.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 549.000000, Wy: 0.000000},
"minute": {GlyphName: "minute", Wx: 247.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 576.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 549.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 500.000000, Wy: 0.000000},
"notelement": {GlyphName: "notelement", Wx: 713.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 549.000000, Wy: 0.000000},
"notsubset": {GlyphName: "notsubset", Wx: 713.000000, Wy: 0.000000},
"nu": {GlyphName: "nu", Wx: 521.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 500.000000, Wy: 0.000000},
"omega": {GlyphName: "omega", Wx: 686.000000, Wy: 0.000000},
"omega1": {GlyphName: "omega1", Wx: 713.000000, Wy: 0.000000},
"omicron": {GlyphName: "omicron", Wx: 549.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 500.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 333.000000, Wy: 0.000000},
"parenleftbt": {GlyphName: "parenleftbt", Wx: 384.000000, Wy: 0.000000},
"parenleftex": {GlyphName: "parenleftex", Wx: 384.000000, Wy: 0.000000},
"parenlefttp": {GlyphName: "parenlefttp", Wx: 384.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 333.000000, Wy: 0.000000},
"parenrightbt": {GlyphName: "parenrightbt", Wx: 384.000000, Wy: 0.000000},
"parenrightex": {GlyphName: "parenrightex", Wx: 384.000000, Wy: 0.000000},
"parenrighttp": {GlyphName: "parenrighttp", Wx: 384.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 494.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 833.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 250.000000, Wy: 0.000000},
"perpendicular": {GlyphName: "perpendicular", Wx: 658.000000, Wy: 0.000000},
"phi": {GlyphName: "phi", Wx: 521.000000, Wy: 0.000000},
"phi1": {GlyphName: "phi1", Wx: 603.000000, Wy: 0.000000},
"pi": {GlyphName: "pi", Wx: 549.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 549.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 549.000000, Wy: 0.000000},
"product": {GlyphName: "product", Wx: 823.000000, Wy: 0.000000},
"propersubset": {GlyphName: "propersubset", Wx: 713.000000, Wy: 0.000000},
"propersuperset": {GlyphName: "propersuperset", Wx: 713.000000, Wy: 0.000000},
"proportional": {GlyphName: "proportional", Wx: 713.000000, Wy: 0.000000},
"psi": {GlyphName: "psi", Wx: 686.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 444.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 549.000000, Wy: 0.000000},
"radicalex": {GlyphName: "radicalex", Wx: 500.000000, Wy: 0.000000},
"reflexsubset": {GlyphName: "reflexsubset", Wx: 713.000000, Wy: 0.000000},
"reflexsuperset": {GlyphName: "reflexsuperset", Wx: 713.000000, Wy: 0.000000},
"registersans": {GlyphName: "registersans", Wx: 790.000000, Wy: 0.000000},
"registerserif": {GlyphName: "registerserif", Wx: 790.000000, Wy: 0.000000},
"rho": {GlyphName: "rho", Wx: 549.000000, Wy: 0.000000},
"second": {GlyphName: "second", Wx: 411.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 278.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 500.000000, Wy: 0.000000},
"sigma": {GlyphName: "sigma", Wx: 603.000000, Wy: 0.000000},
"sigma1": {GlyphName: "sigma1", Wx: 439.000000, Wy: 0.000000},
"similar": {GlyphName: "similar", Wx: 549.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 500.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 278.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 250.000000, Wy: 0.000000},
"spade": {GlyphName: "spade", Wx: 753.000000, Wy: 0.000000},
"suchthat": {GlyphName: "suchthat", Wx: 439.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 713.000000, Wy: 0.000000},
"tau": {GlyphName: "tau", Wx: 439.000000, Wy: 0.000000},
"therefore": {GlyphName: "therefore", Wx: 863.000000, Wy: 0.000000},
"theta": {GlyphName: "theta", Wx: 521.000000, Wy: 0.000000},
"theta1": {GlyphName: "theta1", Wx: 631.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 500.000000, Wy: 0.000000},
"trademarksans": {GlyphName: "trademarksans", Wx: 786.000000, Wy: 0.000000},
"trademarkserif": {GlyphName: "trademarkserif", Wx: 890.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 500.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 500.000000, Wy: 0.000000},
"union": {GlyphName: "union", Wx: 768.000000, Wy: 0.000000},
"universal": {GlyphName: "universal", Wx: 713.000000, Wy: 0.000000},
"upsilon": {GlyphName: "upsilon", Wx: 576.000000, Wy: 0.000000},
"weierstrass": {GlyphName: "weierstrass", Wx: 987.000000, Wy: 0.000000},
"xi": {GlyphName: "xi", Wx: 493.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 500.000000, Wy: 0.000000},
"zeta": {GlyphName: "zeta", Wx: 494.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,362 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Times-Bold. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontTimesBold struct {
encoder textencoding.TextEncoder
}
func NewFontTimesBold() fontTimesBold {
font := fontTimesBold{}
font.encoder = textencoding.NewWinAnsiTextEncoder() // Default
return font
}
func (font fontTimesBold) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontTimesBold) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := timesBoldCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontTimesBold) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Times-Bold"))
fontDict.Set("Encoding", font.encoder.ToPdfObject())
obj.PdfObject = fontDict
return obj
}
var timesBoldCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"A": {GlyphName: "A", Wx: 722.000000, Wy: 0.000000},
"AE": {GlyphName: "AE", Wx: 1000.000000, Wy: 0.000000},
"Aacute": {GlyphName: "Aacute", Wx: 722.000000, Wy: 0.000000},
"Abreve": {GlyphName: "Abreve", Wx: 722.000000, Wy: 0.000000},
"Acircumflex": {GlyphName: "Acircumflex", Wx: 722.000000, Wy: 0.000000},
"Adieresis": {GlyphName: "Adieresis", Wx: 722.000000, Wy: 0.000000},
"Agrave": {GlyphName: "Agrave", Wx: 722.000000, Wy: 0.000000},
"Amacron": {GlyphName: "Amacron", Wx: 722.000000, Wy: 0.000000},
"Aogonek": {GlyphName: "Aogonek", Wx: 722.000000, Wy: 0.000000},
"Aring": {GlyphName: "Aring", Wx: 722.000000, Wy: 0.000000},
"Atilde": {GlyphName: "Atilde", Wx: 722.000000, Wy: 0.000000},
"B": {GlyphName: "B", Wx: 667.000000, Wy: 0.000000},
"C": {GlyphName: "C", Wx: 722.000000, Wy: 0.000000},
"Cacute": {GlyphName: "Cacute", Wx: 722.000000, Wy: 0.000000},
"Ccaron": {GlyphName: "Ccaron", Wx: 722.000000, Wy: 0.000000},
"Ccedilla": {GlyphName: "Ccedilla", Wx: 722.000000, Wy: 0.000000},
"D": {GlyphName: "D", Wx: 722.000000, Wy: 0.000000},
"Dcaron": {GlyphName: "Dcaron", Wx: 722.000000, Wy: 0.000000},
"Dcroat": {GlyphName: "Dcroat", Wx: 722.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 612.000000, Wy: 0.000000},
"E": {GlyphName: "E", Wx: 667.000000, Wy: 0.000000},
"Eacute": {GlyphName: "Eacute", Wx: 667.000000, Wy: 0.000000},
"Ecaron": {GlyphName: "Ecaron", Wx: 667.000000, Wy: 0.000000},
"Ecircumflex": {GlyphName: "Ecircumflex", Wx: 667.000000, Wy: 0.000000},
"Edieresis": {GlyphName: "Edieresis", Wx: 667.000000, Wy: 0.000000},
"Edotaccent": {GlyphName: "Edotaccent", Wx: 667.000000, Wy: 0.000000},
"Egrave": {GlyphName: "Egrave", Wx: 667.000000, Wy: 0.000000},
"Emacron": {GlyphName: "Emacron", Wx: 667.000000, Wy: 0.000000},
"Eogonek": {GlyphName: "Eogonek", Wx: 667.000000, Wy: 0.000000},
"Eth": {GlyphName: "Eth", Wx: 722.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 500.000000, Wy: 0.000000},
"F": {GlyphName: "F", Wx: 611.000000, Wy: 0.000000},
"G": {GlyphName: "G", Wx: 778.000000, Wy: 0.000000},
"Gbreve": {GlyphName: "Gbreve", Wx: 778.000000, Wy: 0.000000},
"Gcommaaccent": {GlyphName: "Gcommaaccent", Wx: 778.000000, Wy: 0.000000},
"H": {GlyphName: "H", Wx: 778.000000, Wy: 0.000000},
"I": {GlyphName: "I", Wx: 389.000000, Wy: 0.000000},
"Iacute": {GlyphName: "Iacute", Wx: 389.000000, Wy: 0.000000},
"Icircumflex": {GlyphName: "Icircumflex", Wx: 389.000000, Wy: 0.000000},
"Idieresis": {GlyphName: "Idieresis", Wx: 389.000000, Wy: 0.000000},
"Idotaccent": {GlyphName: "Idotaccent", Wx: 389.000000, Wy: 0.000000},
"Igrave": {GlyphName: "Igrave", Wx: 389.000000, Wy: 0.000000},
"Imacron": {GlyphName: "Imacron", Wx: 389.000000, Wy: 0.000000},
"Iogonek": {GlyphName: "Iogonek", Wx: 389.000000, Wy: 0.000000},
"J": {GlyphName: "J", Wx: 500.000000, Wy: 0.000000},
"K": {GlyphName: "K", Wx: 778.000000, Wy: 0.000000},
"Kcommaaccent": {GlyphName: "Kcommaaccent", Wx: 778.000000, Wy: 0.000000},
"L": {GlyphName: "L", Wx: 667.000000, Wy: 0.000000},
"Lacute": {GlyphName: "Lacute", Wx: 667.000000, Wy: 0.000000},
"Lcaron": {GlyphName: "Lcaron", Wx: 667.000000, Wy: 0.000000},
"Lcommaaccent": {GlyphName: "Lcommaaccent", Wx: 667.000000, Wy: 0.000000},
"Lslash": {GlyphName: "Lslash", Wx: 667.000000, Wy: 0.000000},
"M": {GlyphName: "M", Wx: 944.000000, Wy: 0.000000},
"N": {GlyphName: "N", Wx: 722.000000, Wy: 0.000000},
"Nacute": {GlyphName: "Nacute", Wx: 722.000000, Wy: 0.000000},
"Ncaron": {GlyphName: "Ncaron", Wx: 722.000000, Wy: 0.000000},
"Ncommaaccent": {GlyphName: "Ncommaaccent", Wx: 722.000000, Wy: 0.000000},
"Ntilde": {GlyphName: "Ntilde", Wx: 722.000000, Wy: 0.000000},
"O": {GlyphName: "O", Wx: 778.000000, Wy: 0.000000},
"OE": {GlyphName: "OE", Wx: 1000.000000, Wy: 0.000000},
"Oacute": {GlyphName: "Oacute", Wx: 778.000000, Wy: 0.000000},
"Ocircumflex": {GlyphName: "Ocircumflex", Wx: 778.000000, Wy: 0.000000},
"Odieresis": {GlyphName: "Odieresis", Wx: 778.000000, Wy: 0.000000},
"Ograve": {GlyphName: "Ograve", Wx: 778.000000, Wy: 0.000000},
"Ohungarumlaut": {GlyphName: "Ohungarumlaut", Wx: 778.000000, Wy: 0.000000},
"Omacron": {GlyphName: "Omacron", Wx: 778.000000, Wy: 0.000000},
"Oslash": {GlyphName: "Oslash", Wx: 778.000000, Wy: 0.000000},
"Otilde": {GlyphName: "Otilde", Wx: 778.000000, Wy: 0.000000},
"P": {GlyphName: "P", Wx: 611.000000, Wy: 0.000000},
"Q": {GlyphName: "Q", Wx: 778.000000, Wy: 0.000000},
"R": {GlyphName: "R", Wx: 722.000000, Wy: 0.000000},
"Racute": {GlyphName: "Racute", Wx: 722.000000, Wy: 0.000000},
"Rcaron": {GlyphName: "Rcaron", Wx: 722.000000, Wy: 0.000000},
"Rcommaaccent": {GlyphName: "Rcommaaccent", Wx: 722.000000, Wy: 0.000000},
"S": {GlyphName: "S", Wx: 556.000000, Wy: 0.000000},
"Sacute": {GlyphName: "Sacute", Wx: 556.000000, Wy: 0.000000},
"Scaron": {GlyphName: "Scaron", Wx: 556.000000, Wy: 0.000000},
"Scedilla": {GlyphName: "Scedilla", Wx: 556.000000, Wy: 0.000000},
"Scommaaccent": {GlyphName: "Scommaaccent", Wx: 556.000000, Wy: 0.000000},
"T": {GlyphName: "T", Wx: 667.000000, Wy: 0.000000},
"Tcaron": {GlyphName: "Tcaron", Wx: 667.000000, Wy: 0.000000},
"Tcommaaccent": {GlyphName: "Tcommaaccent", Wx: 667.000000, Wy: 0.000000},
"Thorn": {GlyphName: "Thorn", Wx: 611.000000, Wy: 0.000000},
"U": {GlyphName: "U", Wx: 722.000000, Wy: 0.000000},
"Uacute": {GlyphName: "Uacute", Wx: 722.000000, Wy: 0.000000},
"Ucircumflex": {GlyphName: "Ucircumflex", Wx: 722.000000, Wy: 0.000000},
"Udieresis": {GlyphName: "Udieresis", Wx: 722.000000, Wy: 0.000000},
"Ugrave": {GlyphName: "Ugrave", Wx: 722.000000, Wy: 0.000000},
"Uhungarumlaut": {GlyphName: "Uhungarumlaut", Wx: 722.000000, Wy: 0.000000},
"Umacron": {GlyphName: "Umacron", Wx: 722.000000, Wy: 0.000000},
"Uogonek": {GlyphName: "Uogonek", Wx: 722.000000, Wy: 0.000000},
"Uring": {GlyphName: "Uring", Wx: 722.000000, Wy: 0.000000},
"V": {GlyphName: "V", Wx: 722.000000, Wy: 0.000000},
"W": {GlyphName: "W", Wx: 1000.000000, Wy: 0.000000},
"X": {GlyphName: "X", Wx: 722.000000, Wy: 0.000000},
"Y": {GlyphName: "Y", Wx: 722.000000, Wy: 0.000000},
"Yacute": {GlyphName: "Yacute", Wx: 722.000000, Wy: 0.000000},
"Ydieresis": {GlyphName: "Ydieresis", Wx: 722.000000, Wy: 0.000000},
"Z": {GlyphName: "Z", Wx: 667.000000, Wy: 0.000000},
"Zacute": {GlyphName: "Zacute", Wx: 667.000000, Wy: 0.000000},
"Zcaron": {GlyphName: "Zcaron", Wx: 667.000000, Wy: 0.000000},
"Zdotaccent": {GlyphName: "Zdotaccent", Wx: 667.000000, Wy: 0.000000},
"a": {GlyphName: "a", Wx: 500.000000, Wy: 0.000000},
"aacute": {GlyphName: "aacute", Wx: 500.000000, Wy: 0.000000},
"abreve": {GlyphName: "abreve", Wx: 500.000000, Wy: 0.000000},
"acircumflex": {GlyphName: "acircumflex", Wx: 500.000000, Wy: 0.000000},
"acute": {GlyphName: "acute", Wx: 333.000000, Wy: 0.000000},
"adieresis": {GlyphName: "adieresis", Wx: 500.000000, Wy: 0.000000},
"ae": {GlyphName: "ae", Wx: 722.000000, Wy: 0.000000},
"agrave": {GlyphName: "agrave", Wx: 500.000000, Wy: 0.000000},
"amacron": {GlyphName: "amacron", Wx: 500.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 833.000000, Wy: 0.000000},
"aogonek": {GlyphName: "aogonek", Wx: 500.000000, Wy: 0.000000},
"aring": {GlyphName: "aring", Wx: 500.000000, Wy: 0.000000},
"asciicircum": {GlyphName: "asciicircum", Wx: 581.000000, Wy: 0.000000},
"asciitilde": {GlyphName: "asciitilde", Wx: 520.000000, Wy: 0.000000},
"asterisk": {GlyphName: "asterisk", Wx: 500.000000, Wy: 0.000000},
"at": {GlyphName: "at", Wx: 930.000000, Wy: 0.000000},
"atilde": {GlyphName: "atilde", Wx: 500.000000, Wy: 0.000000},
"b": {GlyphName: "b", Wx: 556.000000, Wy: 0.000000},
"backslash": {GlyphName: "backslash", Wx: 278.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 220.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 394.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 394.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 333.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 333.000000, Wy: 0.000000},
"breve": {GlyphName: "breve", Wx: 333.000000, Wy: 0.000000},
"brokenbar": {GlyphName: "brokenbar", Wx: 220.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 350.000000, Wy: 0.000000},
"c": {GlyphName: "c", Wx: 444.000000, Wy: 0.000000},
"cacute": {GlyphName: "cacute", Wx: 444.000000, Wy: 0.000000},
"caron": {GlyphName: "caron", Wx: 333.000000, Wy: 0.000000},
"ccaron": {GlyphName: "ccaron", Wx: 444.000000, Wy: 0.000000},
"ccedilla": {GlyphName: "ccedilla", Wx: 444.000000, Wy: 0.000000},
"cedilla": {GlyphName: "cedilla", Wx: 333.000000, Wy: 0.000000},
"cent": {GlyphName: "cent", Wx: 500.000000, Wy: 0.000000},
"circumflex": {GlyphName: "circumflex", Wx: 333.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 333.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 250.000000, Wy: 0.000000},
"commaaccent": {GlyphName: "commaaccent", Wx: 250.000000, Wy: 0.000000},
"copyright": {GlyphName: "copyright", Wx: 747.000000, Wy: 0.000000},
"currency": {GlyphName: "currency", Wx: 500.000000, Wy: 0.000000},
"d": {GlyphName: "d", Wx: 556.000000, Wy: 0.000000},
"dagger": {GlyphName: "dagger", Wx: 500.000000, Wy: 0.000000},
"daggerdbl": {GlyphName: "daggerdbl", Wx: 500.000000, Wy: 0.000000},
"dcaron": {GlyphName: "dcaron", Wx: 672.000000, Wy: 0.000000},
"dcroat": {GlyphName: "dcroat", Wx: 556.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 400.000000, Wy: 0.000000},
"dieresis": {GlyphName: "dieresis", Wx: 333.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 570.000000, Wy: 0.000000},
"dollar": {GlyphName: "dollar", Wx: 500.000000, Wy: 0.000000},
"dotaccent": {GlyphName: "dotaccent", Wx: 333.000000, Wy: 0.000000},
"dotlessi": {GlyphName: "dotlessi", Wx: 278.000000, Wy: 0.000000},
"e": {GlyphName: "e", Wx: 444.000000, Wy: 0.000000},
"eacute": {GlyphName: "eacute", Wx: 444.000000, Wy: 0.000000},
"ecaron": {GlyphName: "ecaron", Wx: 444.000000, Wy: 0.000000},
"ecircumflex": {GlyphName: "ecircumflex", Wx: 444.000000, Wy: 0.000000},
"edieresis": {GlyphName: "edieresis", Wx: 444.000000, Wy: 0.000000},
"edotaccent": {GlyphName: "edotaccent", Wx: 444.000000, Wy: 0.000000},
"egrave": {GlyphName: "egrave", Wx: 444.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 500.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 1000.000000, Wy: 0.000000},
"emacron": {GlyphName: "emacron", Wx: 444.000000, Wy: 0.000000},
"emdash": {GlyphName: "emdash", Wx: 1000.000000, Wy: 0.000000},
"endash": {GlyphName: "endash", Wx: 500.000000, Wy: 0.000000},
"eogonek": {GlyphName: "eogonek", Wx: 444.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 570.000000, Wy: 0.000000},
"eth": {GlyphName: "eth", Wx: 500.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 333.000000, Wy: 0.000000},
"exclamdown": {GlyphName: "exclamdown", Wx: 333.000000, Wy: 0.000000},
"f": {GlyphName: "f", Wx: 333.000000, Wy: 0.000000},
"fi": {GlyphName: "fi", Wx: 556.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 500.000000, Wy: 0.000000},
"fl": {GlyphName: "fl", Wx: 556.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 500.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 500.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 167.000000, Wy: 0.000000},
"g": {GlyphName: "g", Wx: 500.000000, Wy: 0.000000},
"gbreve": {GlyphName: "gbreve", Wx: 500.000000, Wy: 0.000000},
"gcommaaccent": {GlyphName: "gcommaaccent", Wx: 500.000000, Wy: 0.000000},
"germandbls": {GlyphName: "germandbls", Wx: 556.000000, Wy: 0.000000},
"grave": {GlyphName: "grave", Wx: 333.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 570.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 549.000000, Wy: 0.000000},
"guillemotleft": {GlyphName: "guillemotleft", Wx: 500.000000, Wy: 0.000000},
"guillemotright": {GlyphName: "guillemotright", Wx: 500.000000, Wy: 0.000000},
"guilsinglleft": {GlyphName: "guilsinglleft", Wx: 333.000000, Wy: 0.000000},
"guilsinglright": {GlyphName: "guilsinglright", Wx: 333.000000, Wy: 0.000000},
"h": {GlyphName: "h", Wx: 556.000000, Wy: 0.000000},
"hungarumlaut": {GlyphName: "hungarumlaut", Wx: 333.000000, Wy: 0.000000},
"hyphen": {GlyphName: "hyphen", Wx: 333.000000, Wy: 0.000000},
"i": {GlyphName: "i", Wx: 278.000000, Wy: 0.000000},
"iacute": {GlyphName: "iacute", Wx: 278.000000, Wy: 0.000000},
"icircumflex": {GlyphName: "icircumflex", Wx: 278.000000, Wy: 0.000000},
"idieresis": {GlyphName: "idieresis", Wx: 278.000000, Wy: 0.000000},
"igrave": {GlyphName: "igrave", Wx: 278.000000, Wy: 0.000000},
"imacron": {GlyphName: "imacron", Wx: 278.000000, Wy: 0.000000},
"iogonek": {GlyphName: "iogonek", Wx: 278.000000, Wy: 0.000000},
"j": {GlyphName: "j", Wx: 333.000000, Wy: 0.000000},
"k": {GlyphName: "k", Wx: 556.000000, Wy: 0.000000},
"kcommaaccent": {GlyphName: "kcommaaccent", Wx: 556.000000, Wy: 0.000000},
"l": {GlyphName: "l", Wx: 278.000000, Wy: 0.000000},
"lacute": {GlyphName: "lacute", Wx: 278.000000, Wy: 0.000000},
"lcaron": {GlyphName: "lcaron", Wx: 394.000000, Wy: 0.000000},
"lcommaaccent": {GlyphName: "lcommaaccent", Wx: 278.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 570.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 549.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 570.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 494.000000, Wy: 0.000000},
"lslash": {GlyphName: "lslash", Wx: 278.000000, Wy: 0.000000},
"m": {GlyphName: "m", Wx: 833.000000, Wy: 0.000000},
"macron": {GlyphName: "macron", Wx: 333.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 570.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 556.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 570.000000, Wy: 0.000000},
"n": {GlyphName: "n", Wx: 556.000000, Wy: 0.000000},
"nacute": {GlyphName: "nacute", Wx: 556.000000, Wy: 0.000000},
"ncaron": {GlyphName: "ncaron", Wx: 556.000000, Wy: 0.000000},
"ncommaaccent": {GlyphName: "ncommaaccent", Wx: 556.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 500.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 549.000000, Wy: 0.000000},
"ntilde": {GlyphName: "ntilde", Wx: 556.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 500.000000, Wy: 0.000000},
"o": {GlyphName: "o", Wx: 500.000000, Wy: 0.000000},
"oacute": {GlyphName: "oacute", Wx: 500.000000, Wy: 0.000000},
"ocircumflex": {GlyphName: "ocircumflex", Wx: 500.000000, Wy: 0.000000},
"odieresis": {GlyphName: "odieresis", Wx: 500.000000, Wy: 0.000000},
"oe": {GlyphName: "oe", Wx: 722.000000, Wy: 0.000000},
"ogonek": {GlyphName: "ogonek", Wx: 333.000000, Wy: 0.000000},
"ograve": {GlyphName: "ograve", Wx: 500.000000, Wy: 0.000000},
"ohungarumlaut": {GlyphName: "ohungarumlaut", Wx: 500.000000, Wy: 0.000000},
"omacron": {GlyphName: "omacron", Wx: 500.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 500.000000, Wy: 0.000000},
"onehalf": {GlyphName: "onehalf", Wx: 750.000000, Wy: 0.000000},
"onequarter": {GlyphName: "onequarter", Wx: 750.000000, Wy: 0.000000},
"onesuperior": {GlyphName: "onesuperior", Wx: 300.000000, Wy: 0.000000},
"ordfeminine": {GlyphName: "ordfeminine", Wx: 300.000000, Wy: 0.000000},
"ordmasculine": {GlyphName: "ordmasculine", Wx: 330.000000, Wy: 0.000000},
"oslash": {GlyphName: "oslash", Wx: 500.000000, Wy: 0.000000},
"otilde": {GlyphName: "otilde", Wx: 500.000000, Wy: 0.000000},
"p": {GlyphName: "p", Wx: 556.000000, Wy: 0.000000},
"paragraph": {GlyphName: "paragraph", Wx: 540.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 333.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 333.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 494.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 1000.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 250.000000, Wy: 0.000000},
"periodcentered": {GlyphName: "periodcentered", Wx: 250.000000, Wy: 0.000000},
"perthousand": {GlyphName: "perthousand", Wx: 1000.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 570.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 570.000000, Wy: 0.000000},
"q": {GlyphName: "q", Wx: 556.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 500.000000, Wy: 0.000000},
"questiondown": {GlyphName: "questiondown", Wx: 500.000000, Wy: 0.000000},
"quotedbl": {GlyphName: "quotedbl", Wx: 555.000000, Wy: 0.000000},
"quotedblbase": {GlyphName: "quotedblbase", Wx: 500.000000, Wy: 0.000000},
"quotedblleft": {GlyphName: "quotedblleft", Wx: 500.000000, Wy: 0.000000},
"quotedblright": {GlyphName: "quotedblright", Wx: 500.000000, Wy: 0.000000},
"quoteleft": {GlyphName: "quoteleft", Wx: 333.000000, Wy: 0.000000},
"quoteright": {GlyphName: "quoteright", Wx: 333.000000, Wy: 0.000000},
"quotesinglbase": {GlyphName: "quotesinglbase", Wx: 333.000000, Wy: 0.000000},
"quotesingle": {GlyphName: "quotesingle", Wx: 278.000000, Wy: 0.000000},
"r": {GlyphName: "r", Wx: 444.000000, Wy: 0.000000},
"racute": {GlyphName: "racute", Wx: 444.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 549.000000, Wy: 0.000000},
"rcaron": {GlyphName: "rcaron", Wx: 444.000000, Wy: 0.000000},
"rcommaaccent": {GlyphName: "rcommaaccent", Wx: 444.000000, Wy: 0.000000},
"registered": {GlyphName: "registered", Wx: 747.000000, Wy: 0.000000},
"ring": {GlyphName: "ring", Wx: 333.000000, Wy: 0.000000},
"s": {GlyphName: "s", Wx: 389.000000, Wy: 0.000000},
"sacute": {GlyphName: "sacute", Wx: 389.000000, Wy: 0.000000},
"scaron": {GlyphName: "scaron", Wx: 389.000000, Wy: 0.000000},
"scedilla": {GlyphName: "scedilla", Wx: 389.000000, Wy: 0.000000},
"scommaaccent": {GlyphName: "scommaaccent", Wx: 389.000000, Wy: 0.000000},
"section": {GlyphName: "section", Wx: 500.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 333.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 500.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 500.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 278.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 250.000000, Wy: 0.000000},
"sterling": {GlyphName: "sterling", Wx: 500.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 600.000000, Wy: 0.000000},
"t": {GlyphName: "t", Wx: 333.000000, Wy: 0.000000},
"tcaron": {GlyphName: "tcaron", Wx: 416.000000, Wy: 0.000000},
"tcommaaccent": {GlyphName: "tcommaaccent", Wx: 333.000000, Wy: 0.000000},
"thorn": {GlyphName: "thorn", Wx: 556.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 500.000000, Wy: 0.000000},
"threequarters": {GlyphName: "threequarters", Wx: 750.000000, Wy: 0.000000},
"threesuperior": {GlyphName: "threesuperior", Wx: 300.000000, Wy: 0.000000},
"tilde": {GlyphName: "tilde", Wx: 333.000000, Wy: 0.000000},
"trademark": {GlyphName: "trademark", Wx: 1000.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 500.000000, Wy: 0.000000},
"twosuperior": {GlyphName: "twosuperior", Wx: 300.000000, Wy: 0.000000},
"u": {GlyphName: "u", Wx: 556.000000, Wy: 0.000000},
"uacute": {GlyphName: "uacute", Wx: 556.000000, Wy: 0.000000},
"ucircumflex": {GlyphName: "ucircumflex", Wx: 556.000000, Wy: 0.000000},
"udieresis": {GlyphName: "udieresis", Wx: 556.000000, Wy: 0.000000},
"ugrave": {GlyphName: "ugrave", Wx: 556.000000, Wy: 0.000000},
"uhungarumlaut": {GlyphName: "uhungarumlaut", Wx: 556.000000, Wy: 0.000000},
"umacron": {GlyphName: "umacron", Wx: 556.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 500.000000, Wy: 0.000000},
"uogonek": {GlyphName: "uogonek", Wx: 556.000000, Wy: 0.000000},
"uring": {GlyphName: "uring", Wx: 556.000000, Wy: 0.000000},
"v": {GlyphName: "v", Wx: 500.000000, Wy: 0.000000},
"w": {GlyphName: "w", Wx: 722.000000, Wy: 0.000000},
"x": {GlyphName: "x", Wx: 500.000000, Wy: 0.000000},
"y": {GlyphName: "y", Wx: 500.000000, Wy: 0.000000},
"yacute": {GlyphName: "yacute", Wx: 500.000000, Wy: 0.000000},
"ydieresis": {GlyphName: "ydieresis", Wx: 500.000000, Wy: 0.000000},
"yen": {GlyphName: "yen", Wx: 500.000000, Wy: 0.000000},
"z": {GlyphName: "z", Wx: 444.000000, Wy: 0.000000},
"zacute": {GlyphName: "zacute", Wx: 444.000000, Wy: 0.000000},
"zcaron": {GlyphName: "zcaron", Wx: 444.000000, Wy: 0.000000},
"zdotaccent": {GlyphName: "zdotaccent", Wx: 444.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 500.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,362 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Times-BoldItalic. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontTimesBoldItalic struct {
encoder textencoding.TextEncoder
}
func NewFontTimesBoldItalic() fontTimesBoldItalic {
font := fontTimesBoldItalic{}
font.encoder = textencoding.NewWinAnsiTextEncoder() // Default
return font
}
func (font fontTimesBoldItalic) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontTimesBoldItalic) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := timesBoldItalicCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontTimesBoldItalic) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Times-BoldItalic"))
fontDict.Set("Encoding", font.encoder.ToPdfObject())
obj.PdfObject = fontDict
return obj
}
var timesBoldItalicCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"A": {GlyphName: "A", Wx: 667.000000, Wy: 0.000000},
"AE": {GlyphName: "AE", Wx: 944.000000, Wy: 0.000000},
"Aacute": {GlyphName: "Aacute", Wx: 667.000000, Wy: 0.000000},
"Abreve": {GlyphName: "Abreve", Wx: 667.000000, Wy: 0.000000},
"Acircumflex": {GlyphName: "Acircumflex", Wx: 667.000000, Wy: 0.000000},
"Adieresis": {GlyphName: "Adieresis", Wx: 667.000000, Wy: 0.000000},
"Agrave": {GlyphName: "Agrave", Wx: 667.000000, Wy: 0.000000},
"Amacron": {GlyphName: "Amacron", Wx: 667.000000, Wy: 0.000000},
"Aogonek": {GlyphName: "Aogonek", Wx: 667.000000, Wy: 0.000000},
"Aring": {GlyphName: "Aring", Wx: 667.000000, Wy: 0.000000},
"Atilde": {GlyphName: "Atilde", Wx: 667.000000, Wy: 0.000000},
"B": {GlyphName: "B", Wx: 667.000000, Wy: 0.000000},
"C": {GlyphName: "C", Wx: 667.000000, Wy: 0.000000},
"Cacute": {GlyphName: "Cacute", Wx: 667.000000, Wy: 0.000000},
"Ccaron": {GlyphName: "Ccaron", Wx: 667.000000, Wy: 0.000000},
"Ccedilla": {GlyphName: "Ccedilla", Wx: 667.000000, Wy: 0.000000},
"D": {GlyphName: "D", Wx: 722.000000, Wy: 0.000000},
"Dcaron": {GlyphName: "Dcaron", Wx: 722.000000, Wy: 0.000000},
"Dcroat": {GlyphName: "Dcroat", Wx: 722.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 612.000000, Wy: 0.000000},
"E": {GlyphName: "E", Wx: 667.000000, Wy: 0.000000},
"Eacute": {GlyphName: "Eacute", Wx: 667.000000, Wy: 0.000000},
"Ecaron": {GlyphName: "Ecaron", Wx: 667.000000, Wy: 0.000000},
"Ecircumflex": {GlyphName: "Ecircumflex", Wx: 667.000000, Wy: 0.000000},
"Edieresis": {GlyphName: "Edieresis", Wx: 667.000000, Wy: 0.000000},
"Edotaccent": {GlyphName: "Edotaccent", Wx: 667.000000, Wy: 0.000000},
"Egrave": {GlyphName: "Egrave", Wx: 667.000000, Wy: 0.000000},
"Emacron": {GlyphName: "Emacron", Wx: 667.000000, Wy: 0.000000},
"Eogonek": {GlyphName: "Eogonek", Wx: 667.000000, Wy: 0.000000},
"Eth": {GlyphName: "Eth", Wx: 722.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 500.000000, Wy: 0.000000},
"F": {GlyphName: "F", Wx: 667.000000, Wy: 0.000000},
"G": {GlyphName: "G", Wx: 722.000000, Wy: 0.000000},
"Gbreve": {GlyphName: "Gbreve", Wx: 722.000000, Wy: 0.000000},
"Gcommaaccent": {GlyphName: "Gcommaaccent", Wx: 722.000000, Wy: 0.000000},
"H": {GlyphName: "H", Wx: 778.000000, Wy: 0.000000},
"I": {GlyphName: "I", Wx: 389.000000, Wy: 0.000000},
"Iacute": {GlyphName: "Iacute", Wx: 389.000000, Wy: 0.000000},
"Icircumflex": {GlyphName: "Icircumflex", Wx: 389.000000, Wy: 0.000000},
"Idieresis": {GlyphName: "Idieresis", Wx: 389.000000, Wy: 0.000000},
"Idotaccent": {GlyphName: "Idotaccent", Wx: 389.000000, Wy: 0.000000},
"Igrave": {GlyphName: "Igrave", Wx: 389.000000, Wy: 0.000000},
"Imacron": {GlyphName: "Imacron", Wx: 389.000000, Wy: 0.000000},
"Iogonek": {GlyphName: "Iogonek", Wx: 389.000000, Wy: 0.000000},
"J": {GlyphName: "J", Wx: 500.000000, Wy: 0.000000},
"K": {GlyphName: "K", Wx: 667.000000, Wy: 0.000000},
"Kcommaaccent": {GlyphName: "Kcommaaccent", Wx: 667.000000, Wy: 0.000000},
"L": {GlyphName: "L", Wx: 611.000000, Wy: 0.000000},
"Lacute": {GlyphName: "Lacute", Wx: 611.000000, Wy: 0.000000},
"Lcaron": {GlyphName: "Lcaron", Wx: 611.000000, Wy: 0.000000},
"Lcommaaccent": {GlyphName: "Lcommaaccent", Wx: 611.000000, Wy: 0.000000},
"Lslash": {GlyphName: "Lslash", Wx: 611.000000, Wy: 0.000000},
"M": {GlyphName: "M", Wx: 889.000000, Wy: 0.000000},
"N": {GlyphName: "N", Wx: 722.000000, Wy: 0.000000},
"Nacute": {GlyphName: "Nacute", Wx: 722.000000, Wy: 0.000000},
"Ncaron": {GlyphName: "Ncaron", Wx: 722.000000, Wy: 0.000000},
"Ncommaaccent": {GlyphName: "Ncommaaccent", Wx: 722.000000, Wy: 0.000000},
"Ntilde": {GlyphName: "Ntilde", Wx: 722.000000, Wy: 0.000000},
"O": {GlyphName: "O", Wx: 722.000000, Wy: 0.000000},
"OE": {GlyphName: "OE", Wx: 944.000000, Wy: 0.000000},
"Oacute": {GlyphName: "Oacute", Wx: 722.000000, Wy: 0.000000},
"Ocircumflex": {GlyphName: "Ocircumflex", Wx: 722.000000, Wy: 0.000000},
"Odieresis": {GlyphName: "Odieresis", Wx: 722.000000, Wy: 0.000000},
"Ograve": {GlyphName: "Ograve", Wx: 722.000000, Wy: 0.000000},
"Ohungarumlaut": {GlyphName: "Ohungarumlaut", Wx: 722.000000, Wy: 0.000000},
"Omacron": {GlyphName: "Omacron", Wx: 722.000000, Wy: 0.000000},
"Oslash": {GlyphName: "Oslash", Wx: 722.000000, Wy: 0.000000},
"Otilde": {GlyphName: "Otilde", Wx: 722.000000, Wy: 0.000000},
"P": {GlyphName: "P", Wx: 611.000000, Wy: 0.000000},
"Q": {GlyphName: "Q", Wx: 722.000000, Wy: 0.000000},
"R": {GlyphName: "R", Wx: 667.000000, Wy: 0.000000},
"Racute": {GlyphName: "Racute", Wx: 667.000000, Wy: 0.000000},
"Rcaron": {GlyphName: "Rcaron", Wx: 667.000000, Wy: 0.000000},
"Rcommaaccent": {GlyphName: "Rcommaaccent", Wx: 667.000000, Wy: 0.000000},
"S": {GlyphName: "S", Wx: 556.000000, Wy: 0.000000},
"Sacute": {GlyphName: "Sacute", Wx: 556.000000, Wy: 0.000000},
"Scaron": {GlyphName: "Scaron", Wx: 556.000000, Wy: 0.000000},
"Scedilla": {GlyphName: "Scedilla", Wx: 556.000000, Wy: 0.000000},
"Scommaaccent": {GlyphName: "Scommaaccent", Wx: 556.000000, Wy: 0.000000},
"T": {GlyphName: "T", Wx: 611.000000, Wy: 0.000000},
"Tcaron": {GlyphName: "Tcaron", Wx: 611.000000, Wy: 0.000000},
"Tcommaaccent": {GlyphName: "Tcommaaccent", Wx: 611.000000, Wy: 0.000000},
"Thorn": {GlyphName: "Thorn", Wx: 611.000000, Wy: 0.000000},
"U": {GlyphName: "U", Wx: 722.000000, Wy: 0.000000},
"Uacute": {GlyphName: "Uacute", Wx: 722.000000, Wy: 0.000000},
"Ucircumflex": {GlyphName: "Ucircumflex", Wx: 722.000000, Wy: 0.000000},
"Udieresis": {GlyphName: "Udieresis", Wx: 722.000000, Wy: 0.000000},
"Ugrave": {GlyphName: "Ugrave", Wx: 722.000000, Wy: 0.000000},
"Uhungarumlaut": {GlyphName: "Uhungarumlaut", Wx: 722.000000, Wy: 0.000000},
"Umacron": {GlyphName: "Umacron", Wx: 722.000000, Wy: 0.000000},
"Uogonek": {GlyphName: "Uogonek", Wx: 722.000000, Wy: 0.000000},
"Uring": {GlyphName: "Uring", Wx: 722.000000, Wy: 0.000000},
"V": {GlyphName: "V", Wx: 667.000000, Wy: 0.000000},
"W": {GlyphName: "W", Wx: 889.000000, Wy: 0.000000},
"X": {GlyphName: "X", Wx: 667.000000, Wy: 0.000000},
"Y": {GlyphName: "Y", Wx: 611.000000, Wy: 0.000000},
"Yacute": {GlyphName: "Yacute", Wx: 611.000000, Wy: 0.000000},
"Ydieresis": {GlyphName: "Ydieresis", Wx: 611.000000, Wy: 0.000000},
"Z": {GlyphName: "Z", Wx: 611.000000, Wy: 0.000000},
"Zacute": {GlyphName: "Zacute", Wx: 611.000000, Wy: 0.000000},
"Zcaron": {GlyphName: "Zcaron", Wx: 611.000000, Wy: 0.000000},
"Zdotaccent": {GlyphName: "Zdotaccent", Wx: 611.000000, Wy: 0.000000},
"a": {GlyphName: "a", Wx: 500.000000, Wy: 0.000000},
"aacute": {GlyphName: "aacute", Wx: 500.000000, Wy: 0.000000},
"abreve": {GlyphName: "abreve", Wx: 500.000000, Wy: 0.000000},
"acircumflex": {GlyphName: "acircumflex", Wx: 500.000000, Wy: 0.000000},
"acute": {GlyphName: "acute", Wx: 333.000000, Wy: 0.000000},
"adieresis": {GlyphName: "adieresis", Wx: 500.000000, Wy: 0.000000},
"ae": {GlyphName: "ae", Wx: 722.000000, Wy: 0.000000},
"agrave": {GlyphName: "agrave", Wx: 500.000000, Wy: 0.000000},
"amacron": {GlyphName: "amacron", Wx: 500.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 778.000000, Wy: 0.000000},
"aogonek": {GlyphName: "aogonek", Wx: 500.000000, Wy: 0.000000},
"aring": {GlyphName: "aring", Wx: 500.000000, Wy: 0.000000},
"asciicircum": {GlyphName: "asciicircum", Wx: 570.000000, Wy: 0.000000},
"asciitilde": {GlyphName: "asciitilde", Wx: 570.000000, Wy: 0.000000},
"asterisk": {GlyphName: "asterisk", Wx: 500.000000, Wy: 0.000000},
"at": {GlyphName: "at", Wx: 832.000000, Wy: 0.000000},
"atilde": {GlyphName: "atilde", Wx: 500.000000, Wy: 0.000000},
"b": {GlyphName: "b", Wx: 500.000000, Wy: 0.000000},
"backslash": {GlyphName: "backslash", Wx: 278.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 220.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 348.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 348.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 333.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 333.000000, Wy: 0.000000},
"breve": {GlyphName: "breve", Wx: 333.000000, Wy: 0.000000},
"brokenbar": {GlyphName: "brokenbar", Wx: 220.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 350.000000, Wy: 0.000000},
"c": {GlyphName: "c", Wx: 444.000000, Wy: 0.000000},
"cacute": {GlyphName: "cacute", Wx: 444.000000, Wy: 0.000000},
"caron": {GlyphName: "caron", Wx: 333.000000, Wy: 0.000000},
"ccaron": {GlyphName: "ccaron", Wx: 444.000000, Wy: 0.000000},
"ccedilla": {GlyphName: "ccedilla", Wx: 444.000000, Wy: 0.000000},
"cedilla": {GlyphName: "cedilla", Wx: 333.000000, Wy: 0.000000},
"cent": {GlyphName: "cent", Wx: 500.000000, Wy: 0.000000},
"circumflex": {GlyphName: "circumflex", Wx: 333.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 333.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 250.000000, Wy: 0.000000},
"commaaccent": {GlyphName: "commaaccent", Wx: 250.000000, Wy: 0.000000},
"copyright": {GlyphName: "copyright", Wx: 747.000000, Wy: 0.000000},
"currency": {GlyphName: "currency", Wx: 500.000000, Wy: 0.000000},
"d": {GlyphName: "d", Wx: 500.000000, Wy: 0.000000},
"dagger": {GlyphName: "dagger", Wx: 500.000000, Wy: 0.000000},
"daggerdbl": {GlyphName: "daggerdbl", Wx: 500.000000, Wy: 0.000000},
"dcaron": {GlyphName: "dcaron", Wx: 608.000000, Wy: 0.000000},
"dcroat": {GlyphName: "dcroat", Wx: 500.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 400.000000, Wy: 0.000000},
"dieresis": {GlyphName: "dieresis", Wx: 333.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 570.000000, Wy: 0.000000},
"dollar": {GlyphName: "dollar", Wx: 500.000000, Wy: 0.000000},
"dotaccent": {GlyphName: "dotaccent", Wx: 333.000000, Wy: 0.000000},
"dotlessi": {GlyphName: "dotlessi", Wx: 278.000000, Wy: 0.000000},
"e": {GlyphName: "e", Wx: 444.000000, Wy: 0.000000},
"eacute": {GlyphName: "eacute", Wx: 444.000000, Wy: 0.000000},
"ecaron": {GlyphName: "ecaron", Wx: 444.000000, Wy: 0.000000},
"ecircumflex": {GlyphName: "ecircumflex", Wx: 444.000000, Wy: 0.000000},
"edieresis": {GlyphName: "edieresis", Wx: 444.000000, Wy: 0.000000},
"edotaccent": {GlyphName: "edotaccent", Wx: 444.000000, Wy: 0.000000},
"egrave": {GlyphName: "egrave", Wx: 444.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 500.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 1000.000000, Wy: 0.000000},
"emacron": {GlyphName: "emacron", Wx: 444.000000, Wy: 0.000000},
"emdash": {GlyphName: "emdash", Wx: 1000.000000, Wy: 0.000000},
"endash": {GlyphName: "endash", Wx: 500.000000, Wy: 0.000000},
"eogonek": {GlyphName: "eogonek", Wx: 444.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 570.000000, Wy: 0.000000},
"eth": {GlyphName: "eth", Wx: 500.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 389.000000, Wy: 0.000000},
"exclamdown": {GlyphName: "exclamdown", Wx: 389.000000, Wy: 0.000000},
"f": {GlyphName: "f", Wx: 333.000000, Wy: 0.000000},
"fi": {GlyphName: "fi", Wx: 556.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 500.000000, Wy: 0.000000},
"fl": {GlyphName: "fl", Wx: 556.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 500.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 500.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 167.000000, Wy: 0.000000},
"g": {GlyphName: "g", Wx: 500.000000, Wy: 0.000000},
"gbreve": {GlyphName: "gbreve", Wx: 500.000000, Wy: 0.000000},
"gcommaaccent": {GlyphName: "gcommaaccent", Wx: 500.000000, Wy: 0.000000},
"germandbls": {GlyphName: "germandbls", Wx: 500.000000, Wy: 0.000000},
"grave": {GlyphName: "grave", Wx: 333.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 570.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 549.000000, Wy: 0.000000},
"guillemotleft": {GlyphName: "guillemotleft", Wx: 500.000000, Wy: 0.000000},
"guillemotright": {GlyphName: "guillemotright", Wx: 500.000000, Wy: 0.000000},
"guilsinglleft": {GlyphName: "guilsinglleft", Wx: 333.000000, Wy: 0.000000},
"guilsinglright": {GlyphName: "guilsinglright", Wx: 333.000000, Wy: 0.000000},
"h": {GlyphName: "h", Wx: 556.000000, Wy: 0.000000},
"hungarumlaut": {GlyphName: "hungarumlaut", Wx: 333.000000, Wy: 0.000000},
"hyphen": {GlyphName: "hyphen", Wx: 333.000000, Wy: 0.000000},
"i": {GlyphName: "i", Wx: 278.000000, Wy: 0.000000},
"iacute": {GlyphName: "iacute", Wx: 278.000000, Wy: 0.000000},
"icircumflex": {GlyphName: "icircumflex", Wx: 278.000000, Wy: 0.000000},
"idieresis": {GlyphName: "idieresis", Wx: 278.000000, Wy: 0.000000},
"igrave": {GlyphName: "igrave", Wx: 278.000000, Wy: 0.000000},
"imacron": {GlyphName: "imacron", Wx: 278.000000, Wy: 0.000000},
"iogonek": {GlyphName: "iogonek", Wx: 278.000000, Wy: 0.000000},
"j": {GlyphName: "j", Wx: 278.000000, Wy: 0.000000},
"k": {GlyphName: "k", Wx: 500.000000, Wy: 0.000000},
"kcommaaccent": {GlyphName: "kcommaaccent", Wx: 500.000000, Wy: 0.000000},
"l": {GlyphName: "l", Wx: 278.000000, Wy: 0.000000},
"lacute": {GlyphName: "lacute", Wx: 278.000000, Wy: 0.000000},
"lcaron": {GlyphName: "lcaron", Wx: 382.000000, Wy: 0.000000},
"lcommaaccent": {GlyphName: "lcommaaccent", Wx: 278.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 570.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 549.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 606.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 494.000000, Wy: 0.000000},
"lslash": {GlyphName: "lslash", Wx: 278.000000, Wy: 0.000000},
"m": {GlyphName: "m", Wx: 778.000000, Wy: 0.000000},
"macron": {GlyphName: "macron", Wx: 333.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 606.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 576.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 570.000000, Wy: 0.000000},
"n": {GlyphName: "n", Wx: 556.000000, Wy: 0.000000},
"nacute": {GlyphName: "nacute", Wx: 556.000000, Wy: 0.000000},
"ncaron": {GlyphName: "ncaron", Wx: 556.000000, Wy: 0.000000},
"ncommaaccent": {GlyphName: "ncommaaccent", Wx: 556.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 500.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 549.000000, Wy: 0.000000},
"ntilde": {GlyphName: "ntilde", Wx: 556.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 500.000000, Wy: 0.000000},
"o": {GlyphName: "o", Wx: 500.000000, Wy: 0.000000},
"oacute": {GlyphName: "oacute", Wx: 500.000000, Wy: 0.000000},
"ocircumflex": {GlyphName: "ocircumflex", Wx: 500.000000, Wy: 0.000000},
"odieresis": {GlyphName: "odieresis", Wx: 500.000000, Wy: 0.000000},
"oe": {GlyphName: "oe", Wx: 722.000000, Wy: 0.000000},
"ogonek": {GlyphName: "ogonek", Wx: 333.000000, Wy: 0.000000},
"ograve": {GlyphName: "ograve", Wx: 500.000000, Wy: 0.000000},
"ohungarumlaut": {GlyphName: "ohungarumlaut", Wx: 500.000000, Wy: 0.000000},
"omacron": {GlyphName: "omacron", Wx: 500.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 500.000000, Wy: 0.000000},
"onehalf": {GlyphName: "onehalf", Wx: 750.000000, Wy: 0.000000},
"onequarter": {GlyphName: "onequarter", Wx: 750.000000, Wy: 0.000000},
"onesuperior": {GlyphName: "onesuperior", Wx: 300.000000, Wy: 0.000000},
"ordfeminine": {GlyphName: "ordfeminine", Wx: 266.000000, Wy: 0.000000},
"ordmasculine": {GlyphName: "ordmasculine", Wx: 300.000000, Wy: 0.000000},
"oslash": {GlyphName: "oslash", Wx: 500.000000, Wy: 0.000000},
"otilde": {GlyphName: "otilde", Wx: 500.000000, Wy: 0.000000},
"p": {GlyphName: "p", Wx: 500.000000, Wy: 0.000000},
"paragraph": {GlyphName: "paragraph", Wx: 500.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 333.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 333.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 494.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 833.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 250.000000, Wy: 0.000000},
"periodcentered": {GlyphName: "periodcentered", Wx: 250.000000, Wy: 0.000000},
"perthousand": {GlyphName: "perthousand", Wx: 1000.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 570.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 570.000000, Wy: 0.000000},
"q": {GlyphName: "q", Wx: 500.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 500.000000, Wy: 0.000000},
"questiondown": {GlyphName: "questiondown", Wx: 500.000000, Wy: 0.000000},
"quotedbl": {GlyphName: "quotedbl", Wx: 555.000000, Wy: 0.000000},
"quotedblbase": {GlyphName: "quotedblbase", Wx: 500.000000, Wy: 0.000000},
"quotedblleft": {GlyphName: "quotedblleft", Wx: 500.000000, Wy: 0.000000},
"quotedblright": {GlyphName: "quotedblright", Wx: 500.000000, Wy: 0.000000},
"quoteleft": {GlyphName: "quoteleft", Wx: 333.000000, Wy: 0.000000},
"quoteright": {GlyphName: "quoteright", Wx: 333.000000, Wy: 0.000000},
"quotesinglbase": {GlyphName: "quotesinglbase", Wx: 333.000000, Wy: 0.000000},
"quotesingle": {GlyphName: "quotesingle", Wx: 278.000000, Wy: 0.000000},
"r": {GlyphName: "r", Wx: 389.000000, Wy: 0.000000},
"racute": {GlyphName: "racute", Wx: 389.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 549.000000, Wy: 0.000000},
"rcaron": {GlyphName: "rcaron", Wx: 389.000000, Wy: 0.000000},
"rcommaaccent": {GlyphName: "rcommaaccent", Wx: 389.000000, Wy: 0.000000},
"registered": {GlyphName: "registered", Wx: 747.000000, Wy: 0.000000},
"ring": {GlyphName: "ring", Wx: 333.000000, Wy: 0.000000},
"s": {GlyphName: "s", Wx: 389.000000, Wy: 0.000000},
"sacute": {GlyphName: "sacute", Wx: 389.000000, Wy: 0.000000},
"scaron": {GlyphName: "scaron", Wx: 389.000000, Wy: 0.000000},
"scedilla": {GlyphName: "scedilla", Wx: 389.000000, Wy: 0.000000},
"scommaaccent": {GlyphName: "scommaaccent", Wx: 389.000000, Wy: 0.000000},
"section": {GlyphName: "section", Wx: 500.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 333.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 500.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 500.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 278.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 250.000000, Wy: 0.000000},
"sterling": {GlyphName: "sterling", Wx: 500.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 600.000000, Wy: 0.000000},
"t": {GlyphName: "t", Wx: 278.000000, Wy: 0.000000},
"tcaron": {GlyphName: "tcaron", Wx: 366.000000, Wy: 0.000000},
"tcommaaccent": {GlyphName: "tcommaaccent", Wx: 278.000000, Wy: 0.000000},
"thorn": {GlyphName: "thorn", Wx: 500.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 500.000000, Wy: 0.000000},
"threequarters": {GlyphName: "threequarters", Wx: 750.000000, Wy: 0.000000},
"threesuperior": {GlyphName: "threesuperior", Wx: 300.000000, Wy: 0.000000},
"tilde": {GlyphName: "tilde", Wx: 333.000000, Wy: 0.000000},
"trademark": {GlyphName: "trademark", Wx: 1000.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 500.000000, Wy: 0.000000},
"twosuperior": {GlyphName: "twosuperior", Wx: 300.000000, Wy: 0.000000},
"u": {GlyphName: "u", Wx: 556.000000, Wy: 0.000000},
"uacute": {GlyphName: "uacute", Wx: 556.000000, Wy: 0.000000},
"ucircumflex": {GlyphName: "ucircumflex", Wx: 556.000000, Wy: 0.000000},
"udieresis": {GlyphName: "udieresis", Wx: 556.000000, Wy: 0.000000},
"ugrave": {GlyphName: "ugrave", Wx: 556.000000, Wy: 0.000000},
"uhungarumlaut": {GlyphName: "uhungarumlaut", Wx: 556.000000, Wy: 0.000000},
"umacron": {GlyphName: "umacron", Wx: 556.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 500.000000, Wy: 0.000000},
"uogonek": {GlyphName: "uogonek", Wx: 556.000000, Wy: 0.000000},
"uring": {GlyphName: "uring", Wx: 556.000000, Wy: 0.000000},
"v": {GlyphName: "v", Wx: 444.000000, Wy: 0.000000},
"w": {GlyphName: "w", Wx: 667.000000, Wy: 0.000000},
"x": {GlyphName: "x", Wx: 500.000000, Wy: 0.000000},
"y": {GlyphName: "y", Wx: 444.000000, Wy: 0.000000},
"yacute": {GlyphName: "yacute", Wx: 444.000000, Wy: 0.000000},
"ydieresis": {GlyphName: "ydieresis", Wx: 444.000000, Wy: 0.000000},
"yen": {GlyphName: "yen", Wx: 500.000000, Wy: 0.000000},
"z": {GlyphName: "z", Wx: 389.000000, Wy: 0.000000},
"zacute": {GlyphName: "zacute", Wx: 389.000000, Wy: 0.000000},
"zcaron": {GlyphName: "zcaron", Wx: 389.000000, Wy: 0.000000},
"zdotaccent": {GlyphName: "zdotaccent", Wx: 389.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 500.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,362 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Times-Italic. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontTimesItalic struct {
encoder textencoding.TextEncoder
}
func NewFontTimesItalic() fontTimesItalic {
font := fontTimesItalic{}
font.encoder = textencoding.NewWinAnsiTextEncoder() // Default
return font
}
func (font fontTimesItalic) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontTimesItalic) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := timesItalicCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontTimesItalic) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Times-Italic"))
fontDict.Set("Encoding", font.encoder.ToPdfObject())
obj.PdfObject = fontDict
return obj
}
var timesItalicCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"A": {GlyphName: "A", Wx: 611.000000, Wy: 0.000000},
"AE": {GlyphName: "AE", Wx: 889.000000, Wy: 0.000000},
"Aacute": {GlyphName: "Aacute", Wx: 611.000000, Wy: 0.000000},
"Abreve": {GlyphName: "Abreve", Wx: 611.000000, Wy: 0.000000},
"Acircumflex": {GlyphName: "Acircumflex", Wx: 611.000000, Wy: 0.000000},
"Adieresis": {GlyphName: "Adieresis", Wx: 611.000000, Wy: 0.000000},
"Agrave": {GlyphName: "Agrave", Wx: 611.000000, Wy: 0.000000},
"Amacron": {GlyphName: "Amacron", Wx: 611.000000, Wy: 0.000000},
"Aogonek": {GlyphName: "Aogonek", Wx: 611.000000, Wy: 0.000000},
"Aring": {GlyphName: "Aring", Wx: 611.000000, Wy: 0.000000},
"Atilde": {GlyphName: "Atilde", Wx: 611.000000, Wy: 0.000000},
"B": {GlyphName: "B", Wx: 611.000000, Wy: 0.000000},
"C": {GlyphName: "C", Wx: 667.000000, Wy: 0.000000},
"Cacute": {GlyphName: "Cacute", Wx: 667.000000, Wy: 0.000000},
"Ccaron": {GlyphName: "Ccaron", Wx: 667.000000, Wy: 0.000000},
"Ccedilla": {GlyphName: "Ccedilla", Wx: 667.000000, Wy: 0.000000},
"D": {GlyphName: "D", Wx: 722.000000, Wy: 0.000000},
"Dcaron": {GlyphName: "Dcaron", Wx: 722.000000, Wy: 0.000000},
"Dcroat": {GlyphName: "Dcroat", Wx: 722.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 612.000000, Wy: 0.000000},
"E": {GlyphName: "E", Wx: 611.000000, Wy: 0.000000},
"Eacute": {GlyphName: "Eacute", Wx: 611.000000, Wy: 0.000000},
"Ecaron": {GlyphName: "Ecaron", Wx: 611.000000, Wy: 0.000000},
"Ecircumflex": {GlyphName: "Ecircumflex", Wx: 611.000000, Wy: 0.000000},
"Edieresis": {GlyphName: "Edieresis", Wx: 611.000000, Wy: 0.000000},
"Edotaccent": {GlyphName: "Edotaccent", Wx: 611.000000, Wy: 0.000000},
"Egrave": {GlyphName: "Egrave", Wx: 611.000000, Wy: 0.000000},
"Emacron": {GlyphName: "Emacron", Wx: 611.000000, Wy: 0.000000},
"Eogonek": {GlyphName: "Eogonek", Wx: 611.000000, Wy: 0.000000},
"Eth": {GlyphName: "Eth", Wx: 722.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 500.000000, Wy: 0.000000},
"F": {GlyphName: "F", Wx: 611.000000, Wy: 0.000000},
"G": {GlyphName: "G", Wx: 722.000000, Wy: 0.000000},
"Gbreve": {GlyphName: "Gbreve", Wx: 722.000000, Wy: 0.000000},
"Gcommaaccent": {GlyphName: "Gcommaaccent", Wx: 722.000000, Wy: 0.000000},
"H": {GlyphName: "H", Wx: 722.000000, Wy: 0.000000},
"I": {GlyphName: "I", Wx: 333.000000, Wy: 0.000000},
"Iacute": {GlyphName: "Iacute", Wx: 333.000000, Wy: 0.000000},
"Icircumflex": {GlyphName: "Icircumflex", Wx: 333.000000, Wy: 0.000000},
"Idieresis": {GlyphName: "Idieresis", Wx: 333.000000, Wy: 0.000000},
"Idotaccent": {GlyphName: "Idotaccent", Wx: 333.000000, Wy: 0.000000},
"Igrave": {GlyphName: "Igrave", Wx: 333.000000, Wy: 0.000000},
"Imacron": {GlyphName: "Imacron", Wx: 333.000000, Wy: 0.000000},
"Iogonek": {GlyphName: "Iogonek", Wx: 333.000000, Wy: 0.000000},
"J": {GlyphName: "J", Wx: 444.000000, Wy: 0.000000},
"K": {GlyphName: "K", Wx: 667.000000, Wy: 0.000000},
"Kcommaaccent": {GlyphName: "Kcommaaccent", Wx: 667.000000, Wy: 0.000000},
"L": {GlyphName: "L", Wx: 556.000000, Wy: 0.000000},
"Lacute": {GlyphName: "Lacute", Wx: 556.000000, Wy: 0.000000},
"Lcaron": {GlyphName: "Lcaron", Wx: 611.000000, Wy: 0.000000},
"Lcommaaccent": {GlyphName: "Lcommaaccent", Wx: 556.000000, Wy: 0.000000},
"Lslash": {GlyphName: "Lslash", Wx: 556.000000, Wy: 0.000000},
"M": {GlyphName: "M", Wx: 833.000000, Wy: 0.000000},
"N": {GlyphName: "N", Wx: 667.000000, Wy: 0.000000},
"Nacute": {GlyphName: "Nacute", Wx: 667.000000, Wy: 0.000000},
"Ncaron": {GlyphName: "Ncaron", Wx: 667.000000, Wy: 0.000000},
"Ncommaaccent": {GlyphName: "Ncommaaccent", Wx: 667.000000, Wy: 0.000000},
"Ntilde": {GlyphName: "Ntilde", Wx: 667.000000, Wy: 0.000000},
"O": {GlyphName: "O", Wx: 722.000000, Wy: 0.000000},
"OE": {GlyphName: "OE", Wx: 944.000000, Wy: 0.000000},
"Oacute": {GlyphName: "Oacute", Wx: 722.000000, Wy: 0.000000},
"Ocircumflex": {GlyphName: "Ocircumflex", Wx: 722.000000, Wy: 0.000000},
"Odieresis": {GlyphName: "Odieresis", Wx: 722.000000, Wy: 0.000000},
"Ograve": {GlyphName: "Ograve", Wx: 722.000000, Wy: 0.000000},
"Ohungarumlaut": {GlyphName: "Ohungarumlaut", Wx: 722.000000, Wy: 0.000000},
"Omacron": {GlyphName: "Omacron", Wx: 722.000000, Wy: 0.000000},
"Oslash": {GlyphName: "Oslash", Wx: 722.000000, Wy: 0.000000},
"Otilde": {GlyphName: "Otilde", Wx: 722.000000, Wy: 0.000000},
"P": {GlyphName: "P", Wx: 611.000000, Wy: 0.000000},
"Q": {GlyphName: "Q", Wx: 722.000000, Wy: 0.000000},
"R": {GlyphName: "R", Wx: 611.000000, Wy: 0.000000},
"Racute": {GlyphName: "Racute", Wx: 611.000000, Wy: 0.000000},
"Rcaron": {GlyphName: "Rcaron", Wx: 611.000000, Wy: 0.000000},
"Rcommaaccent": {GlyphName: "Rcommaaccent", Wx: 611.000000, Wy: 0.000000},
"S": {GlyphName: "S", Wx: 500.000000, Wy: 0.000000},
"Sacute": {GlyphName: "Sacute", Wx: 500.000000, Wy: 0.000000},
"Scaron": {GlyphName: "Scaron", Wx: 500.000000, Wy: 0.000000},
"Scedilla": {GlyphName: "Scedilla", Wx: 500.000000, Wy: 0.000000},
"Scommaaccent": {GlyphName: "Scommaaccent", Wx: 500.000000, Wy: 0.000000},
"T": {GlyphName: "T", Wx: 556.000000, Wy: 0.000000},
"Tcaron": {GlyphName: "Tcaron", Wx: 556.000000, Wy: 0.000000},
"Tcommaaccent": {GlyphName: "Tcommaaccent", Wx: 556.000000, Wy: 0.000000},
"Thorn": {GlyphName: "Thorn", Wx: 611.000000, Wy: 0.000000},
"U": {GlyphName: "U", Wx: 722.000000, Wy: 0.000000},
"Uacute": {GlyphName: "Uacute", Wx: 722.000000, Wy: 0.000000},
"Ucircumflex": {GlyphName: "Ucircumflex", Wx: 722.000000, Wy: 0.000000},
"Udieresis": {GlyphName: "Udieresis", Wx: 722.000000, Wy: 0.000000},
"Ugrave": {GlyphName: "Ugrave", Wx: 722.000000, Wy: 0.000000},
"Uhungarumlaut": {GlyphName: "Uhungarumlaut", Wx: 722.000000, Wy: 0.000000},
"Umacron": {GlyphName: "Umacron", Wx: 722.000000, Wy: 0.000000},
"Uogonek": {GlyphName: "Uogonek", Wx: 722.000000, Wy: 0.000000},
"Uring": {GlyphName: "Uring", Wx: 722.000000, Wy: 0.000000},
"V": {GlyphName: "V", Wx: 611.000000, Wy: 0.000000},
"W": {GlyphName: "W", Wx: 833.000000, Wy: 0.000000},
"X": {GlyphName: "X", Wx: 611.000000, Wy: 0.000000},
"Y": {GlyphName: "Y", Wx: 556.000000, Wy: 0.000000},
"Yacute": {GlyphName: "Yacute", Wx: 556.000000, Wy: 0.000000},
"Ydieresis": {GlyphName: "Ydieresis", Wx: 556.000000, Wy: 0.000000},
"Z": {GlyphName: "Z", Wx: 556.000000, Wy: 0.000000},
"Zacute": {GlyphName: "Zacute", Wx: 556.000000, Wy: 0.000000},
"Zcaron": {GlyphName: "Zcaron", Wx: 556.000000, Wy: 0.000000},
"Zdotaccent": {GlyphName: "Zdotaccent", Wx: 556.000000, Wy: 0.000000},
"a": {GlyphName: "a", Wx: 500.000000, Wy: 0.000000},
"aacute": {GlyphName: "aacute", Wx: 500.000000, Wy: 0.000000},
"abreve": {GlyphName: "abreve", Wx: 500.000000, Wy: 0.000000},
"acircumflex": {GlyphName: "acircumflex", Wx: 500.000000, Wy: 0.000000},
"acute": {GlyphName: "acute", Wx: 333.000000, Wy: 0.000000},
"adieresis": {GlyphName: "adieresis", Wx: 500.000000, Wy: 0.000000},
"ae": {GlyphName: "ae", Wx: 667.000000, Wy: 0.000000},
"agrave": {GlyphName: "agrave", Wx: 500.000000, Wy: 0.000000},
"amacron": {GlyphName: "amacron", Wx: 500.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 778.000000, Wy: 0.000000},
"aogonek": {GlyphName: "aogonek", Wx: 500.000000, Wy: 0.000000},
"aring": {GlyphName: "aring", Wx: 500.000000, Wy: 0.000000},
"asciicircum": {GlyphName: "asciicircum", Wx: 422.000000, Wy: 0.000000},
"asciitilde": {GlyphName: "asciitilde", Wx: 541.000000, Wy: 0.000000},
"asterisk": {GlyphName: "asterisk", Wx: 500.000000, Wy: 0.000000},
"at": {GlyphName: "at", Wx: 920.000000, Wy: 0.000000},
"atilde": {GlyphName: "atilde", Wx: 500.000000, Wy: 0.000000},
"b": {GlyphName: "b", Wx: 500.000000, Wy: 0.000000},
"backslash": {GlyphName: "backslash", Wx: 278.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 275.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 400.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 400.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 389.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 389.000000, Wy: 0.000000},
"breve": {GlyphName: "breve", Wx: 333.000000, Wy: 0.000000},
"brokenbar": {GlyphName: "brokenbar", Wx: 275.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 350.000000, Wy: 0.000000},
"c": {GlyphName: "c", Wx: 444.000000, Wy: 0.000000},
"cacute": {GlyphName: "cacute", Wx: 444.000000, Wy: 0.000000},
"caron": {GlyphName: "caron", Wx: 333.000000, Wy: 0.000000},
"ccaron": {GlyphName: "ccaron", Wx: 444.000000, Wy: 0.000000},
"ccedilla": {GlyphName: "ccedilla", Wx: 444.000000, Wy: 0.000000},
"cedilla": {GlyphName: "cedilla", Wx: 333.000000, Wy: 0.000000},
"cent": {GlyphName: "cent", Wx: 500.000000, Wy: 0.000000},
"circumflex": {GlyphName: "circumflex", Wx: 333.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 333.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 250.000000, Wy: 0.000000},
"commaaccent": {GlyphName: "commaaccent", Wx: 250.000000, Wy: 0.000000},
"copyright": {GlyphName: "copyright", Wx: 760.000000, Wy: 0.000000},
"currency": {GlyphName: "currency", Wx: 500.000000, Wy: 0.000000},
"d": {GlyphName: "d", Wx: 500.000000, Wy: 0.000000},
"dagger": {GlyphName: "dagger", Wx: 500.000000, Wy: 0.000000},
"daggerdbl": {GlyphName: "daggerdbl", Wx: 500.000000, Wy: 0.000000},
"dcaron": {GlyphName: "dcaron", Wx: 544.000000, Wy: 0.000000},
"dcroat": {GlyphName: "dcroat", Wx: 500.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 400.000000, Wy: 0.000000},
"dieresis": {GlyphName: "dieresis", Wx: 333.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 675.000000, Wy: 0.000000},
"dollar": {GlyphName: "dollar", Wx: 500.000000, Wy: 0.000000},
"dotaccent": {GlyphName: "dotaccent", Wx: 333.000000, Wy: 0.000000},
"dotlessi": {GlyphName: "dotlessi", Wx: 278.000000, Wy: 0.000000},
"e": {GlyphName: "e", Wx: 444.000000, Wy: 0.000000},
"eacute": {GlyphName: "eacute", Wx: 444.000000, Wy: 0.000000},
"ecaron": {GlyphName: "ecaron", Wx: 444.000000, Wy: 0.000000},
"ecircumflex": {GlyphName: "ecircumflex", Wx: 444.000000, Wy: 0.000000},
"edieresis": {GlyphName: "edieresis", Wx: 444.000000, Wy: 0.000000},
"edotaccent": {GlyphName: "edotaccent", Wx: 444.000000, Wy: 0.000000},
"egrave": {GlyphName: "egrave", Wx: 444.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 500.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 889.000000, Wy: 0.000000},
"emacron": {GlyphName: "emacron", Wx: 444.000000, Wy: 0.000000},
"emdash": {GlyphName: "emdash", Wx: 889.000000, Wy: 0.000000},
"endash": {GlyphName: "endash", Wx: 500.000000, Wy: 0.000000},
"eogonek": {GlyphName: "eogonek", Wx: 444.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 675.000000, Wy: 0.000000},
"eth": {GlyphName: "eth", Wx: 500.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 333.000000, Wy: 0.000000},
"exclamdown": {GlyphName: "exclamdown", Wx: 389.000000, Wy: 0.000000},
"f": {GlyphName: "f", Wx: 278.000000, Wy: 0.000000},
"fi": {GlyphName: "fi", Wx: 500.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 500.000000, Wy: 0.000000},
"fl": {GlyphName: "fl", Wx: 500.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 500.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 500.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 167.000000, Wy: 0.000000},
"g": {GlyphName: "g", Wx: 500.000000, Wy: 0.000000},
"gbreve": {GlyphName: "gbreve", Wx: 500.000000, Wy: 0.000000},
"gcommaaccent": {GlyphName: "gcommaaccent", Wx: 500.000000, Wy: 0.000000},
"germandbls": {GlyphName: "germandbls", Wx: 500.000000, Wy: 0.000000},
"grave": {GlyphName: "grave", Wx: 333.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 675.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 549.000000, Wy: 0.000000},
"guillemotleft": {GlyphName: "guillemotleft", Wx: 500.000000, Wy: 0.000000},
"guillemotright": {GlyphName: "guillemotright", Wx: 500.000000, Wy: 0.000000},
"guilsinglleft": {GlyphName: "guilsinglleft", Wx: 333.000000, Wy: 0.000000},
"guilsinglright": {GlyphName: "guilsinglright", Wx: 333.000000, Wy: 0.000000},
"h": {GlyphName: "h", Wx: 500.000000, Wy: 0.000000},
"hungarumlaut": {GlyphName: "hungarumlaut", Wx: 333.000000, Wy: 0.000000},
"hyphen": {GlyphName: "hyphen", Wx: 333.000000, Wy: 0.000000},
"i": {GlyphName: "i", Wx: 278.000000, Wy: 0.000000},
"iacute": {GlyphName: "iacute", Wx: 278.000000, Wy: 0.000000},
"icircumflex": {GlyphName: "icircumflex", Wx: 278.000000, Wy: 0.000000},
"idieresis": {GlyphName: "idieresis", Wx: 278.000000, Wy: 0.000000},
"igrave": {GlyphName: "igrave", Wx: 278.000000, Wy: 0.000000},
"imacron": {GlyphName: "imacron", Wx: 278.000000, Wy: 0.000000},
"iogonek": {GlyphName: "iogonek", Wx: 278.000000, Wy: 0.000000},
"j": {GlyphName: "j", Wx: 278.000000, Wy: 0.000000},
"k": {GlyphName: "k", Wx: 444.000000, Wy: 0.000000},
"kcommaaccent": {GlyphName: "kcommaaccent", Wx: 444.000000, Wy: 0.000000},
"l": {GlyphName: "l", Wx: 278.000000, Wy: 0.000000},
"lacute": {GlyphName: "lacute", Wx: 278.000000, Wy: 0.000000},
"lcaron": {GlyphName: "lcaron", Wx: 300.000000, Wy: 0.000000},
"lcommaaccent": {GlyphName: "lcommaaccent", Wx: 278.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 675.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 549.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 675.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 471.000000, Wy: 0.000000},
"lslash": {GlyphName: "lslash", Wx: 278.000000, Wy: 0.000000},
"m": {GlyphName: "m", Wx: 722.000000, Wy: 0.000000},
"macron": {GlyphName: "macron", Wx: 333.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 675.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 500.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 675.000000, Wy: 0.000000},
"n": {GlyphName: "n", Wx: 500.000000, Wy: 0.000000},
"nacute": {GlyphName: "nacute", Wx: 500.000000, Wy: 0.000000},
"ncaron": {GlyphName: "ncaron", Wx: 500.000000, Wy: 0.000000},
"ncommaaccent": {GlyphName: "ncommaaccent", Wx: 500.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 500.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 549.000000, Wy: 0.000000},
"ntilde": {GlyphName: "ntilde", Wx: 500.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 500.000000, Wy: 0.000000},
"o": {GlyphName: "o", Wx: 500.000000, Wy: 0.000000},
"oacute": {GlyphName: "oacute", Wx: 500.000000, Wy: 0.000000},
"ocircumflex": {GlyphName: "ocircumflex", Wx: 500.000000, Wy: 0.000000},
"odieresis": {GlyphName: "odieresis", Wx: 500.000000, Wy: 0.000000},
"oe": {GlyphName: "oe", Wx: 667.000000, Wy: 0.000000},
"ogonek": {GlyphName: "ogonek", Wx: 333.000000, Wy: 0.000000},
"ograve": {GlyphName: "ograve", Wx: 500.000000, Wy: 0.000000},
"ohungarumlaut": {GlyphName: "ohungarumlaut", Wx: 500.000000, Wy: 0.000000},
"omacron": {GlyphName: "omacron", Wx: 500.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 500.000000, Wy: 0.000000},
"onehalf": {GlyphName: "onehalf", Wx: 750.000000, Wy: 0.000000},
"onequarter": {GlyphName: "onequarter", Wx: 750.000000, Wy: 0.000000},
"onesuperior": {GlyphName: "onesuperior", Wx: 300.000000, Wy: 0.000000},
"ordfeminine": {GlyphName: "ordfeminine", Wx: 276.000000, Wy: 0.000000},
"ordmasculine": {GlyphName: "ordmasculine", Wx: 310.000000, Wy: 0.000000},
"oslash": {GlyphName: "oslash", Wx: 500.000000, Wy: 0.000000},
"otilde": {GlyphName: "otilde", Wx: 500.000000, Wy: 0.000000},
"p": {GlyphName: "p", Wx: 500.000000, Wy: 0.000000},
"paragraph": {GlyphName: "paragraph", Wx: 523.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 333.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 333.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 476.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 833.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 250.000000, Wy: 0.000000},
"periodcentered": {GlyphName: "periodcentered", Wx: 250.000000, Wy: 0.000000},
"perthousand": {GlyphName: "perthousand", Wx: 1000.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 675.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 675.000000, Wy: 0.000000},
"q": {GlyphName: "q", Wx: 500.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 500.000000, Wy: 0.000000},
"questiondown": {GlyphName: "questiondown", Wx: 500.000000, Wy: 0.000000},
"quotedbl": {GlyphName: "quotedbl", Wx: 420.000000, Wy: 0.000000},
"quotedblbase": {GlyphName: "quotedblbase", Wx: 556.000000, Wy: 0.000000},
"quotedblleft": {GlyphName: "quotedblleft", Wx: 556.000000, Wy: 0.000000},
"quotedblright": {GlyphName: "quotedblright", Wx: 556.000000, Wy: 0.000000},
"quoteleft": {GlyphName: "quoteleft", Wx: 333.000000, Wy: 0.000000},
"quoteright": {GlyphName: "quoteright", Wx: 333.000000, Wy: 0.000000},
"quotesinglbase": {GlyphName: "quotesinglbase", Wx: 333.000000, Wy: 0.000000},
"quotesingle": {GlyphName: "quotesingle", Wx: 214.000000, Wy: 0.000000},
"r": {GlyphName: "r", Wx: 389.000000, Wy: 0.000000},
"racute": {GlyphName: "racute", Wx: 389.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 453.000000, Wy: 0.000000},
"rcaron": {GlyphName: "rcaron", Wx: 389.000000, Wy: 0.000000},
"rcommaaccent": {GlyphName: "rcommaaccent", Wx: 389.000000, Wy: 0.000000},
"registered": {GlyphName: "registered", Wx: 760.000000, Wy: 0.000000},
"ring": {GlyphName: "ring", Wx: 333.000000, Wy: 0.000000},
"s": {GlyphName: "s", Wx: 389.000000, Wy: 0.000000},
"sacute": {GlyphName: "sacute", Wx: 389.000000, Wy: 0.000000},
"scaron": {GlyphName: "scaron", Wx: 389.000000, Wy: 0.000000},
"scedilla": {GlyphName: "scedilla", Wx: 389.000000, Wy: 0.000000},
"scommaaccent": {GlyphName: "scommaaccent", Wx: 389.000000, Wy: 0.000000},
"section": {GlyphName: "section", Wx: 500.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 333.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 500.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 500.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 278.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 250.000000, Wy: 0.000000},
"sterling": {GlyphName: "sterling", Wx: 500.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 600.000000, Wy: 0.000000},
"t": {GlyphName: "t", Wx: 278.000000, Wy: 0.000000},
"tcaron": {GlyphName: "tcaron", Wx: 300.000000, Wy: 0.000000},
"tcommaaccent": {GlyphName: "tcommaaccent", Wx: 278.000000, Wy: 0.000000},
"thorn": {GlyphName: "thorn", Wx: 500.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 500.000000, Wy: 0.000000},
"threequarters": {GlyphName: "threequarters", Wx: 750.000000, Wy: 0.000000},
"threesuperior": {GlyphName: "threesuperior", Wx: 300.000000, Wy: 0.000000},
"tilde": {GlyphName: "tilde", Wx: 333.000000, Wy: 0.000000},
"trademark": {GlyphName: "trademark", Wx: 980.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 500.000000, Wy: 0.000000},
"twosuperior": {GlyphName: "twosuperior", Wx: 300.000000, Wy: 0.000000},
"u": {GlyphName: "u", Wx: 500.000000, Wy: 0.000000},
"uacute": {GlyphName: "uacute", Wx: 500.000000, Wy: 0.000000},
"ucircumflex": {GlyphName: "ucircumflex", Wx: 500.000000, Wy: 0.000000},
"udieresis": {GlyphName: "udieresis", Wx: 500.000000, Wy: 0.000000},
"ugrave": {GlyphName: "ugrave", Wx: 500.000000, Wy: 0.000000},
"uhungarumlaut": {GlyphName: "uhungarumlaut", Wx: 500.000000, Wy: 0.000000},
"umacron": {GlyphName: "umacron", Wx: 500.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 500.000000, Wy: 0.000000},
"uogonek": {GlyphName: "uogonek", Wx: 500.000000, Wy: 0.000000},
"uring": {GlyphName: "uring", Wx: 500.000000, Wy: 0.000000},
"v": {GlyphName: "v", Wx: 444.000000, Wy: 0.000000},
"w": {GlyphName: "w", Wx: 667.000000, Wy: 0.000000},
"x": {GlyphName: "x", Wx: 444.000000, Wy: 0.000000},
"y": {GlyphName: "y", Wx: 444.000000, Wy: 0.000000},
"yacute": {GlyphName: "yacute", Wx: 444.000000, Wy: 0.000000},
"ydieresis": {GlyphName: "ydieresis", Wx: 444.000000, Wy: 0.000000},
"yen": {GlyphName: "yen", Wx: 500.000000, Wy: 0.000000},
"z": {GlyphName: "z", Wx: 389.000000, Wy: 0.000000},
"zacute": {GlyphName: "zacute", Wx: 389.000000, Wy: 0.000000},
"zcaron": {GlyphName: "zcaron", Wx: 389.000000, Wy: 0.000000},
"zdotaccent": {GlyphName: "zdotaccent", Wx: 389.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 500.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,362 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font Times-Roman. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontTimesRoman struct {
encoder textencoding.TextEncoder
}
func NewFontTimesRoman() fontTimesRoman {
font := fontTimesRoman{}
font.encoder = textencoding.NewWinAnsiTextEncoder() // Default
return font
}
func (font fontTimesRoman) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontTimesRoman) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := timesRomanCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontTimesRoman) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("Times-Roman"))
fontDict.Set("Encoding", font.encoder.ToPdfObject())
obj.PdfObject = fontDict
return obj
}
var timesRomanCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"A": {GlyphName: "A", Wx: 722.000000, Wy: 0.000000},
"AE": {GlyphName: "AE", Wx: 889.000000, Wy: 0.000000},
"Aacute": {GlyphName: "Aacute", Wx: 722.000000, Wy: 0.000000},
"Abreve": {GlyphName: "Abreve", Wx: 722.000000, Wy: 0.000000},
"Acircumflex": {GlyphName: "Acircumflex", Wx: 722.000000, Wy: 0.000000},
"Adieresis": {GlyphName: "Adieresis", Wx: 722.000000, Wy: 0.000000},
"Agrave": {GlyphName: "Agrave", Wx: 722.000000, Wy: 0.000000},
"Amacron": {GlyphName: "Amacron", Wx: 722.000000, Wy: 0.000000},
"Aogonek": {GlyphName: "Aogonek", Wx: 722.000000, Wy: 0.000000},
"Aring": {GlyphName: "Aring", Wx: 722.000000, Wy: 0.000000},
"Atilde": {GlyphName: "Atilde", Wx: 722.000000, Wy: 0.000000},
"B": {GlyphName: "B", Wx: 667.000000, Wy: 0.000000},
"C": {GlyphName: "C", Wx: 667.000000, Wy: 0.000000},
"Cacute": {GlyphName: "Cacute", Wx: 667.000000, Wy: 0.000000},
"Ccaron": {GlyphName: "Ccaron", Wx: 667.000000, Wy: 0.000000},
"Ccedilla": {GlyphName: "Ccedilla", Wx: 667.000000, Wy: 0.000000},
"D": {GlyphName: "D", Wx: 722.000000, Wy: 0.000000},
"Dcaron": {GlyphName: "Dcaron", Wx: 722.000000, Wy: 0.000000},
"Dcroat": {GlyphName: "Dcroat", Wx: 722.000000, Wy: 0.000000},
"Delta": {GlyphName: "Delta", Wx: 612.000000, Wy: 0.000000},
"E": {GlyphName: "E", Wx: 611.000000, Wy: 0.000000},
"Eacute": {GlyphName: "Eacute", Wx: 611.000000, Wy: 0.000000},
"Ecaron": {GlyphName: "Ecaron", Wx: 611.000000, Wy: 0.000000},
"Ecircumflex": {GlyphName: "Ecircumflex", Wx: 611.000000, Wy: 0.000000},
"Edieresis": {GlyphName: "Edieresis", Wx: 611.000000, Wy: 0.000000},
"Edotaccent": {GlyphName: "Edotaccent", Wx: 611.000000, Wy: 0.000000},
"Egrave": {GlyphName: "Egrave", Wx: 611.000000, Wy: 0.000000},
"Emacron": {GlyphName: "Emacron", Wx: 611.000000, Wy: 0.000000},
"Eogonek": {GlyphName: "Eogonek", Wx: 611.000000, Wy: 0.000000},
"Eth": {GlyphName: "Eth", Wx: 722.000000, Wy: 0.000000},
"Euro": {GlyphName: "Euro", Wx: 500.000000, Wy: 0.000000},
"F": {GlyphName: "F", Wx: 556.000000, Wy: 0.000000},
"G": {GlyphName: "G", Wx: 722.000000, Wy: 0.000000},
"Gbreve": {GlyphName: "Gbreve", Wx: 722.000000, Wy: 0.000000},
"Gcommaaccent": {GlyphName: "Gcommaaccent", Wx: 722.000000, Wy: 0.000000},
"H": {GlyphName: "H", Wx: 722.000000, Wy: 0.000000},
"I": {GlyphName: "I", Wx: 333.000000, Wy: 0.000000},
"Iacute": {GlyphName: "Iacute", Wx: 333.000000, Wy: 0.000000},
"Icircumflex": {GlyphName: "Icircumflex", Wx: 333.000000, Wy: 0.000000},
"Idieresis": {GlyphName: "Idieresis", Wx: 333.000000, Wy: 0.000000},
"Idotaccent": {GlyphName: "Idotaccent", Wx: 333.000000, Wy: 0.000000},
"Igrave": {GlyphName: "Igrave", Wx: 333.000000, Wy: 0.000000},
"Imacron": {GlyphName: "Imacron", Wx: 333.000000, Wy: 0.000000},
"Iogonek": {GlyphName: "Iogonek", Wx: 333.000000, Wy: 0.000000},
"J": {GlyphName: "J", Wx: 389.000000, Wy: 0.000000},
"K": {GlyphName: "K", Wx: 722.000000, Wy: 0.000000},
"Kcommaaccent": {GlyphName: "Kcommaaccent", Wx: 722.000000, Wy: 0.000000},
"L": {GlyphName: "L", Wx: 611.000000, Wy: 0.000000},
"Lacute": {GlyphName: "Lacute", Wx: 611.000000, Wy: 0.000000},
"Lcaron": {GlyphName: "Lcaron", Wx: 611.000000, Wy: 0.000000},
"Lcommaaccent": {GlyphName: "Lcommaaccent", Wx: 611.000000, Wy: 0.000000},
"Lslash": {GlyphName: "Lslash", Wx: 611.000000, Wy: 0.000000},
"M": {GlyphName: "M", Wx: 889.000000, Wy: 0.000000},
"N": {GlyphName: "N", Wx: 722.000000, Wy: 0.000000},
"Nacute": {GlyphName: "Nacute", Wx: 722.000000, Wy: 0.000000},
"Ncaron": {GlyphName: "Ncaron", Wx: 722.000000, Wy: 0.000000},
"Ncommaaccent": {GlyphName: "Ncommaaccent", Wx: 722.000000, Wy: 0.000000},
"Ntilde": {GlyphName: "Ntilde", Wx: 722.000000, Wy: 0.000000},
"O": {GlyphName: "O", Wx: 722.000000, Wy: 0.000000},
"OE": {GlyphName: "OE", Wx: 889.000000, Wy: 0.000000},
"Oacute": {GlyphName: "Oacute", Wx: 722.000000, Wy: 0.000000},
"Ocircumflex": {GlyphName: "Ocircumflex", Wx: 722.000000, Wy: 0.000000},
"Odieresis": {GlyphName: "Odieresis", Wx: 722.000000, Wy: 0.000000},
"Ograve": {GlyphName: "Ograve", Wx: 722.000000, Wy: 0.000000},
"Ohungarumlaut": {GlyphName: "Ohungarumlaut", Wx: 722.000000, Wy: 0.000000},
"Omacron": {GlyphName: "Omacron", Wx: 722.000000, Wy: 0.000000},
"Oslash": {GlyphName: "Oslash", Wx: 722.000000, Wy: 0.000000},
"Otilde": {GlyphName: "Otilde", Wx: 722.000000, Wy: 0.000000},
"P": {GlyphName: "P", Wx: 556.000000, Wy: 0.000000},
"Q": {GlyphName: "Q", Wx: 722.000000, Wy: 0.000000},
"R": {GlyphName: "R", Wx: 667.000000, Wy: 0.000000},
"Racute": {GlyphName: "Racute", Wx: 667.000000, Wy: 0.000000},
"Rcaron": {GlyphName: "Rcaron", Wx: 667.000000, Wy: 0.000000},
"Rcommaaccent": {GlyphName: "Rcommaaccent", Wx: 667.000000, Wy: 0.000000},
"S": {GlyphName: "S", Wx: 556.000000, Wy: 0.000000},
"Sacute": {GlyphName: "Sacute", Wx: 556.000000, Wy: 0.000000},
"Scaron": {GlyphName: "Scaron", Wx: 556.000000, Wy: 0.000000},
"Scedilla": {GlyphName: "Scedilla", Wx: 556.000000, Wy: 0.000000},
"Scommaaccent": {GlyphName: "Scommaaccent", Wx: 556.000000, Wy: 0.000000},
"T": {GlyphName: "T", Wx: 611.000000, Wy: 0.000000},
"Tcaron": {GlyphName: "Tcaron", Wx: 611.000000, Wy: 0.000000},
"Tcommaaccent": {GlyphName: "Tcommaaccent", Wx: 611.000000, Wy: 0.000000},
"Thorn": {GlyphName: "Thorn", Wx: 556.000000, Wy: 0.000000},
"U": {GlyphName: "U", Wx: 722.000000, Wy: 0.000000},
"Uacute": {GlyphName: "Uacute", Wx: 722.000000, Wy: 0.000000},
"Ucircumflex": {GlyphName: "Ucircumflex", Wx: 722.000000, Wy: 0.000000},
"Udieresis": {GlyphName: "Udieresis", Wx: 722.000000, Wy: 0.000000},
"Ugrave": {GlyphName: "Ugrave", Wx: 722.000000, Wy: 0.000000},
"Uhungarumlaut": {GlyphName: "Uhungarumlaut", Wx: 722.000000, Wy: 0.000000},
"Umacron": {GlyphName: "Umacron", Wx: 722.000000, Wy: 0.000000},
"Uogonek": {GlyphName: "Uogonek", Wx: 722.000000, Wy: 0.000000},
"Uring": {GlyphName: "Uring", Wx: 722.000000, Wy: 0.000000},
"V": {GlyphName: "V", Wx: 722.000000, Wy: 0.000000},
"W": {GlyphName: "W", Wx: 944.000000, Wy: 0.000000},
"X": {GlyphName: "X", Wx: 722.000000, Wy: 0.000000},
"Y": {GlyphName: "Y", Wx: 722.000000, Wy: 0.000000},
"Yacute": {GlyphName: "Yacute", Wx: 722.000000, Wy: 0.000000},
"Ydieresis": {GlyphName: "Ydieresis", Wx: 722.000000, Wy: 0.000000},
"Z": {GlyphName: "Z", Wx: 611.000000, Wy: 0.000000},
"Zacute": {GlyphName: "Zacute", Wx: 611.000000, Wy: 0.000000},
"Zcaron": {GlyphName: "Zcaron", Wx: 611.000000, Wy: 0.000000},
"Zdotaccent": {GlyphName: "Zdotaccent", Wx: 611.000000, Wy: 0.000000},
"a": {GlyphName: "a", Wx: 444.000000, Wy: 0.000000},
"aacute": {GlyphName: "aacute", Wx: 444.000000, Wy: 0.000000},
"abreve": {GlyphName: "abreve", Wx: 444.000000, Wy: 0.000000},
"acircumflex": {GlyphName: "acircumflex", Wx: 444.000000, Wy: 0.000000},
"acute": {GlyphName: "acute", Wx: 333.000000, Wy: 0.000000},
"adieresis": {GlyphName: "adieresis", Wx: 444.000000, Wy: 0.000000},
"ae": {GlyphName: "ae", Wx: 667.000000, Wy: 0.000000},
"agrave": {GlyphName: "agrave", Wx: 444.000000, Wy: 0.000000},
"amacron": {GlyphName: "amacron", Wx: 444.000000, Wy: 0.000000},
"ampersand": {GlyphName: "ampersand", Wx: 778.000000, Wy: 0.000000},
"aogonek": {GlyphName: "aogonek", Wx: 444.000000, Wy: 0.000000},
"aring": {GlyphName: "aring", Wx: 444.000000, Wy: 0.000000},
"asciicircum": {GlyphName: "asciicircum", Wx: 469.000000, Wy: 0.000000},
"asciitilde": {GlyphName: "asciitilde", Wx: 541.000000, Wy: 0.000000},
"asterisk": {GlyphName: "asterisk", Wx: 500.000000, Wy: 0.000000},
"at": {GlyphName: "at", Wx: 921.000000, Wy: 0.000000},
"atilde": {GlyphName: "atilde", Wx: 444.000000, Wy: 0.000000},
"b": {GlyphName: "b", Wx: 500.000000, Wy: 0.000000},
"backslash": {GlyphName: "backslash", Wx: 278.000000, Wy: 0.000000},
"bar": {GlyphName: "bar", Wx: 200.000000, Wy: 0.000000},
"braceleft": {GlyphName: "braceleft", Wx: 480.000000, Wy: 0.000000},
"braceright": {GlyphName: "braceright", Wx: 480.000000, Wy: 0.000000},
"bracketleft": {GlyphName: "bracketleft", Wx: 333.000000, Wy: 0.000000},
"bracketright": {GlyphName: "bracketright", Wx: 333.000000, Wy: 0.000000},
"breve": {GlyphName: "breve", Wx: 333.000000, Wy: 0.000000},
"brokenbar": {GlyphName: "brokenbar", Wx: 200.000000, Wy: 0.000000},
"bullet": {GlyphName: "bullet", Wx: 350.000000, Wy: 0.000000},
"c": {GlyphName: "c", Wx: 444.000000, Wy: 0.000000},
"cacute": {GlyphName: "cacute", Wx: 444.000000, Wy: 0.000000},
"caron": {GlyphName: "caron", Wx: 333.000000, Wy: 0.000000},
"ccaron": {GlyphName: "ccaron", Wx: 444.000000, Wy: 0.000000},
"ccedilla": {GlyphName: "ccedilla", Wx: 444.000000, Wy: 0.000000},
"cedilla": {GlyphName: "cedilla", Wx: 333.000000, Wy: 0.000000},
"cent": {GlyphName: "cent", Wx: 500.000000, Wy: 0.000000},
"circumflex": {GlyphName: "circumflex", Wx: 333.000000, Wy: 0.000000},
"colon": {GlyphName: "colon", Wx: 278.000000, Wy: 0.000000},
"comma": {GlyphName: "comma", Wx: 250.000000, Wy: 0.000000},
"commaaccent": {GlyphName: "commaaccent", Wx: 250.000000, Wy: 0.000000},
"copyright": {GlyphName: "copyright", Wx: 760.000000, Wy: 0.000000},
"currency": {GlyphName: "currency", Wx: 500.000000, Wy: 0.000000},
"d": {GlyphName: "d", Wx: 500.000000, Wy: 0.000000},
"dagger": {GlyphName: "dagger", Wx: 500.000000, Wy: 0.000000},
"daggerdbl": {GlyphName: "daggerdbl", Wx: 500.000000, Wy: 0.000000},
"dcaron": {GlyphName: "dcaron", Wx: 588.000000, Wy: 0.000000},
"dcroat": {GlyphName: "dcroat", Wx: 500.000000, Wy: 0.000000},
"degree": {GlyphName: "degree", Wx: 400.000000, Wy: 0.000000},
"dieresis": {GlyphName: "dieresis", Wx: 333.000000, Wy: 0.000000},
"divide": {GlyphName: "divide", Wx: 564.000000, Wy: 0.000000},
"dollar": {GlyphName: "dollar", Wx: 500.000000, Wy: 0.000000},
"dotaccent": {GlyphName: "dotaccent", Wx: 333.000000, Wy: 0.000000},
"dotlessi": {GlyphName: "dotlessi", Wx: 278.000000, Wy: 0.000000},
"e": {GlyphName: "e", Wx: 444.000000, Wy: 0.000000},
"eacute": {GlyphName: "eacute", Wx: 444.000000, Wy: 0.000000},
"ecaron": {GlyphName: "ecaron", Wx: 444.000000, Wy: 0.000000},
"ecircumflex": {GlyphName: "ecircumflex", Wx: 444.000000, Wy: 0.000000},
"edieresis": {GlyphName: "edieresis", Wx: 444.000000, Wy: 0.000000},
"edotaccent": {GlyphName: "edotaccent", Wx: 444.000000, Wy: 0.000000},
"egrave": {GlyphName: "egrave", Wx: 444.000000, Wy: 0.000000},
"eight": {GlyphName: "eight", Wx: 500.000000, Wy: 0.000000},
"ellipsis": {GlyphName: "ellipsis", Wx: 1000.000000, Wy: 0.000000},
"emacron": {GlyphName: "emacron", Wx: 444.000000, Wy: 0.000000},
"emdash": {GlyphName: "emdash", Wx: 1000.000000, Wy: 0.000000},
"endash": {GlyphName: "endash", Wx: 500.000000, Wy: 0.000000},
"eogonek": {GlyphName: "eogonek", Wx: 444.000000, Wy: 0.000000},
"equal": {GlyphName: "equal", Wx: 564.000000, Wy: 0.000000},
"eth": {GlyphName: "eth", Wx: 500.000000, Wy: 0.000000},
"exclam": {GlyphName: "exclam", Wx: 333.000000, Wy: 0.000000},
"exclamdown": {GlyphName: "exclamdown", Wx: 333.000000, Wy: 0.000000},
"f": {GlyphName: "f", Wx: 333.000000, Wy: 0.000000},
"fi": {GlyphName: "fi", Wx: 556.000000, Wy: 0.000000},
"five": {GlyphName: "five", Wx: 500.000000, Wy: 0.000000},
"fl": {GlyphName: "fl", Wx: 556.000000, Wy: 0.000000},
"florin": {GlyphName: "florin", Wx: 500.000000, Wy: 0.000000},
"four": {GlyphName: "four", Wx: 500.000000, Wy: 0.000000},
"fraction": {GlyphName: "fraction", Wx: 167.000000, Wy: 0.000000},
"g": {GlyphName: "g", Wx: 500.000000, Wy: 0.000000},
"gbreve": {GlyphName: "gbreve", Wx: 500.000000, Wy: 0.000000},
"gcommaaccent": {GlyphName: "gcommaaccent", Wx: 500.000000, Wy: 0.000000},
"germandbls": {GlyphName: "germandbls", Wx: 500.000000, Wy: 0.000000},
"grave": {GlyphName: "grave", Wx: 333.000000, Wy: 0.000000},
"greater": {GlyphName: "greater", Wx: 564.000000, Wy: 0.000000},
"greaterequal": {GlyphName: "greaterequal", Wx: 549.000000, Wy: 0.000000},
"guillemotleft": {GlyphName: "guillemotleft", Wx: 500.000000, Wy: 0.000000},
"guillemotright": {GlyphName: "guillemotright", Wx: 500.000000, Wy: 0.000000},
"guilsinglleft": {GlyphName: "guilsinglleft", Wx: 333.000000, Wy: 0.000000},
"guilsinglright": {GlyphName: "guilsinglright", Wx: 333.000000, Wy: 0.000000},
"h": {GlyphName: "h", Wx: 500.000000, Wy: 0.000000},
"hungarumlaut": {GlyphName: "hungarumlaut", Wx: 333.000000, Wy: 0.000000},
"hyphen": {GlyphName: "hyphen", Wx: 333.000000, Wy: 0.000000},
"i": {GlyphName: "i", Wx: 278.000000, Wy: 0.000000},
"iacute": {GlyphName: "iacute", Wx: 278.000000, Wy: 0.000000},
"icircumflex": {GlyphName: "icircumflex", Wx: 278.000000, Wy: 0.000000},
"idieresis": {GlyphName: "idieresis", Wx: 278.000000, Wy: 0.000000},
"igrave": {GlyphName: "igrave", Wx: 278.000000, Wy: 0.000000},
"imacron": {GlyphName: "imacron", Wx: 278.000000, Wy: 0.000000},
"iogonek": {GlyphName: "iogonek", Wx: 278.000000, Wy: 0.000000},
"j": {GlyphName: "j", Wx: 278.000000, Wy: 0.000000},
"k": {GlyphName: "k", Wx: 500.000000, Wy: 0.000000},
"kcommaaccent": {GlyphName: "kcommaaccent", Wx: 500.000000, Wy: 0.000000},
"l": {GlyphName: "l", Wx: 278.000000, Wy: 0.000000},
"lacute": {GlyphName: "lacute", Wx: 278.000000, Wy: 0.000000},
"lcaron": {GlyphName: "lcaron", Wx: 344.000000, Wy: 0.000000},
"lcommaaccent": {GlyphName: "lcommaaccent", Wx: 278.000000, Wy: 0.000000},
"less": {GlyphName: "less", Wx: 564.000000, Wy: 0.000000},
"lessequal": {GlyphName: "lessequal", Wx: 549.000000, Wy: 0.000000},
"logicalnot": {GlyphName: "logicalnot", Wx: 564.000000, Wy: 0.000000},
"lozenge": {GlyphName: "lozenge", Wx: 471.000000, Wy: 0.000000},
"lslash": {GlyphName: "lslash", Wx: 278.000000, Wy: 0.000000},
"m": {GlyphName: "m", Wx: 778.000000, Wy: 0.000000},
"macron": {GlyphName: "macron", Wx: 333.000000, Wy: 0.000000},
"minus": {GlyphName: "minus", Wx: 564.000000, Wy: 0.000000},
"mu": {GlyphName: "mu", Wx: 500.000000, Wy: 0.000000},
"multiply": {GlyphName: "multiply", Wx: 564.000000, Wy: 0.000000},
"n": {GlyphName: "n", Wx: 500.000000, Wy: 0.000000},
"nacute": {GlyphName: "nacute", Wx: 500.000000, Wy: 0.000000},
"ncaron": {GlyphName: "ncaron", Wx: 500.000000, Wy: 0.000000},
"ncommaaccent": {GlyphName: "ncommaaccent", Wx: 500.000000, Wy: 0.000000},
"nine": {GlyphName: "nine", Wx: 500.000000, Wy: 0.000000},
"notequal": {GlyphName: "notequal", Wx: 549.000000, Wy: 0.000000},
"ntilde": {GlyphName: "ntilde", Wx: 500.000000, Wy: 0.000000},
"numbersign": {GlyphName: "numbersign", Wx: 500.000000, Wy: 0.000000},
"o": {GlyphName: "o", Wx: 500.000000, Wy: 0.000000},
"oacute": {GlyphName: "oacute", Wx: 500.000000, Wy: 0.000000},
"ocircumflex": {GlyphName: "ocircumflex", Wx: 500.000000, Wy: 0.000000},
"odieresis": {GlyphName: "odieresis", Wx: 500.000000, Wy: 0.000000},
"oe": {GlyphName: "oe", Wx: 722.000000, Wy: 0.000000},
"ogonek": {GlyphName: "ogonek", Wx: 333.000000, Wy: 0.000000},
"ograve": {GlyphName: "ograve", Wx: 500.000000, Wy: 0.000000},
"ohungarumlaut": {GlyphName: "ohungarumlaut", Wx: 500.000000, Wy: 0.000000},
"omacron": {GlyphName: "omacron", Wx: 500.000000, Wy: 0.000000},
"one": {GlyphName: "one", Wx: 500.000000, Wy: 0.000000},
"onehalf": {GlyphName: "onehalf", Wx: 750.000000, Wy: 0.000000},
"onequarter": {GlyphName: "onequarter", Wx: 750.000000, Wy: 0.000000},
"onesuperior": {GlyphName: "onesuperior", Wx: 300.000000, Wy: 0.000000},
"ordfeminine": {GlyphName: "ordfeminine", Wx: 276.000000, Wy: 0.000000},
"ordmasculine": {GlyphName: "ordmasculine", Wx: 310.000000, Wy: 0.000000},
"oslash": {GlyphName: "oslash", Wx: 500.000000, Wy: 0.000000},
"otilde": {GlyphName: "otilde", Wx: 500.000000, Wy: 0.000000},
"p": {GlyphName: "p", Wx: 500.000000, Wy: 0.000000},
"paragraph": {GlyphName: "paragraph", Wx: 453.000000, Wy: 0.000000},
"parenleft": {GlyphName: "parenleft", Wx: 333.000000, Wy: 0.000000},
"parenright": {GlyphName: "parenright", Wx: 333.000000, Wy: 0.000000},
"partialdiff": {GlyphName: "partialdiff", Wx: 476.000000, Wy: 0.000000},
"percent": {GlyphName: "percent", Wx: 833.000000, Wy: 0.000000},
"period": {GlyphName: "period", Wx: 250.000000, Wy: 0.000000},
"periodcentered": {GlyphName: "periodcentered", Wx: 250.000000, Wy: 0.000000},
"perthousand": {GlyphName: "perthousand", Wx: 1000.000000, Wy: 0.000000},
"plus": {GlyphName: "plus", Wx: 564.000000, Wy: 0.000000},
"plusminus": {GlyphName: "plusminus", Wx: 564.000000, Wy: 0.000000},
"q": {GlyphName: "q", Wx: 500.000000, Wy: 0.000000},
"question": {GlyphName: "question", Wx: 444.000000, Wy: 0.000000},
"questiondown": {GlyphName: "questiondown", Wx: 444.000000, Wy: 0.000000},
"quotedbl": {GlyphName: "quotedbl", Wx: 408.000000, Wy: 0.000000},
"quotedblbase": {GlyphName: "quotedblbase", Wx: 444.000000, Wy: 0.000000},
"quotedblleft": {GlyphName: "quotedblleft", Wx: 444.000000, Wy: 0.000000},
"quotedblright": {GlyphName: "quotedblright", Wx: 444.000000, Wy: 0.000000},
"quoteleft": {GlyphName: "quoteleft", Wx: 333.000000, Wy: 0.000000},
"quoteright": {GlyphName: "quoteright", Wx: 333.000000, Wy: 0.000000},
"quotesinglbase": {GlyphName: "quotesinglbase", Wx: 333.000000, Wy: 0.000000},
"quotesingle": {GlyphName: "quotesingle", Wx: 180.000000, Wy: 0.000000},
"r": {GlyphName: "r", Wx: 333.000000, Wy: 0.000000},
"racute": {GlyphName: "racute", Wx: 333.000000, Wy: 0.000000},
"radical": {GlyphName: "radical", Wx: 453.000000, Wy: 0.000000},
"rcaron": {GlyphName: "rcaron", Wx: 333.000000, Wy: 0.000000},
"rcommaaccent": {GlyphName: "rcommaaccent", Wx: 333.000000, Wy: 0.000000},
"registered": {GlyphName: "registered", Wx: 760.000000, Wy: 0.000000},
"ring": {GlyphName: "ring", Wx: 333.000000, Wy: 0.000000},
"s": {GlyphName: "s", Wx: 389.000000, Wy: 0.000000},
"sacute": {GlyphName: "sacute", Wx: 389.000000, Wy: 0.000000},
"scaron": {GlyphName: "scaron", Wx: 389.000000, Wy: 0.000000},
"scedilla": {GlyphName: "scedilla", Wx: 389.000000, Wy: 0.000000},
"scommaaccent": {GlyphName: "scommaaccent", Wx: 389.000000, Wy: 0.000000},
"section": {GlyphName: "section", Wx: 500.000000, Wy: 0.000000},
"semicolon": {GlyphName: "semicolon", Wx: 278.000000, Wy: 0.000000},
"seven": {GlyphName: "seven", Wx: 500.000000, Wy: 0.000000},
"six": {GlyphName: "six", Wx: 500.000000, Wy: 0.000000},
"slash": {GlyphName: "slash", Wx: 278.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 250.000000, Wy: 0.000000},
"sterling": {GlyphName: "sterling", Wx: 500.000000, Wy: 0.000000},
"summation": {GlyphName: "summation", Wx: 600.000000, Wy: 0.000000},
"t": {GlyphName: "t", Wx: 278.000000, Wy: 0.000000},
"tcaron": {GlyphName: "tcaron", Wx: 326.000000, Wy: 0.000000},
"tcommaaccent": {GlyphName: "tcommaaccent", Wx: 278.000000, Wy: 0.000000},
"thorn": {GlyphName: "thorn", Wx: 500.000000, Wy: 0.000000},
"three": {GlyphName: "three", Wx: 500.000000, Wy: 0.000000},
"threequarters": {GlyphName: "threequarters", Wx: 750.000000, Wy: 0.000000},
"threesuperior": {GlyphName: "threesuperior", Wx: 300.000000, Wy: 0.000000},
"tilde": {GlyphName: "tilde", Wx: 333.000000, Wy: 0.000000},
"trademark": {GlyphName: "trademark", Wx: 980.000000, Wy: 0.000000},
"two": {GlyphName: "two", Wx: 500.000000, Wy: 0.000000},
"twosuperior": {GlyphName: "twosuperior", Wx: 300.000000, Wy: 0.000000},
"u": {GlyphName: "u", Wx: 500.000000, Wy: 0.000000},
"uacute": {GlyphName: "uacute", Wx: 500.000000, Wy: 0.000000},
"ucircumflex": {GlyphName: "ucircumflex", Wx: 500.000000, Wy: 0.000000},
"udieresis": {GlyphName: "udieresis", Wx: 500.000000, Wy: 0.000000},
"ugrave": {GlyphName: "ugrave", Wx: 500.000000, Wy: 0.000000},
"uhungarumlaut": {GlyphName: "uhungarumlaut", Wx: 500.000000, Wy: 0.000000},
"umacron": {GlyphName: "umacron", Wx: 500.000000, Wy: 0.000000},
"underscore": {GlyphName: "underscore", Wx: 500.000000, Wy: 0.000000},
"uogonek": {GlyphName: "uogonek", Wx: 500.000000, Wy: 0.000000},
"uring": {GlyphName: "uring", Wx: 500.000000, Wy: 0.000000},
"v": {GlyphName: "v", Wx: 500.000000, Wy: 0.000000},
"w": {GlyphName: "w", Wx: 722.000000, Wy: 0.000000},
"x": {GlyphName: "x", Wx: 500.000000, Wy: 0.000000},
"y": {GlyphName: "y", Wx: 500.000000, Wy: 0.000000},
"yacute": {GlyphName: "yacute", Wx: 500.000000, Wy: 0.000000},
"ydieresis": {GlyphName: "ydieresis", Wx: 500.000000, Wy: 0.000000},
"yen": {GlyphName: "yen", Wx: 500.000000, Wy: 0.000000},
"z": {GlyphName: "z", Wx: 444.000000, Wy: 0.000000},
"zacute": {GlyphName: "zacute", Wx: 444.000000, Wy: 0.000000},
"zcaron": {GlyphName: "zcaron", Wx: 444.000000, Wy: 0.000000},
"zdotaccent": {GlyphName: "zdotaccent", Wx: 444.000000, Wy: 0.000000},
"zero": {GlyphName: "zero", Wx: 500.000000, Wy: 0.000000},
}

View File

@@ -0,0 +1,374 @@
/*
* Copyright (c) 2013 Kurt Jung (Gmail: kurt.w.jung)
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package fonts
// Utility to parse TTF font files
// Version: 1.0
// Date: 2011-06-18
// Author: Olivier PLATHEY
// Port to Go: Kurt Jung, 2013-07-15
import (
"encoding/binary"
"fmt"
"os"
"regexp"
"strings"
)
// TtfType contains metrics of a TrueType font.
type TtfType struct {
Embeddable bool
UnitsPerEm uint16
PostScriptName string
Bold bool
ItalicAngle int16
IsFixedPitch bool
TypoAscender int16
TypoDescender int16
UnderlinePosition int16
UnderlineThickness int16
Xmin, Ymin, Xmax, Ymax int16
CapHeight int16
Widths []uint16
Chars map[uint16]uint16
}
type ttfParser struct {
rec TtfType
f *os.File
tables map[string]uint32
numberOfHMetrics uint16
numGlyphs uint16
}
// TtfParse extracts various metrics from a TrueType font file.
func TtfParse(fileStr string) (TtfRec TtfType, err error) {
var t ttfParser
t.f, err = os.Open(fileStr)
if err != nil {
return
}
version, err := t.ReadStr(4)
if err != nil {
return
}
if version == "OTTO" {
err = fmt.Errorf("fonts based on PostScript outlines are not supported")
return
}
if version != "\x00\x01\x00\x00" {
err = fmt.Errorf("unrecognized file format")
return
}
numTables := int(t.ReadUShort())
t.Skip(3 * 2) // searchRange, entrySelector, rangeShift
t.tables = make(map[string]uint32)
var tag string
for j := 0; j < numTables; j++ {
tag, err = t.ReadStr(4)
if err != nil {
return
}
t.Skip(4) // checkSum
offset := t.ReadULong()
t.Skip(4) // length
t.tables[tag] = offset
}
err = t.ParseComponents()
if err != nil {
return
}
t.f.Close()
TtfRec = t.rec
return
}
func (t *ttfParser) ParseComponents() (err error) {
err = t.ParseHead()
if err == nil {
err = t.ParseHhea()
if err == nil {
err = t.ParseMaxp()
if err == nil {
err = t.ParseHmtx()
if err == nil {
err = t.ParseCmap()
if err == nil {
err = t.ParseName()
if err == nil {
err = t.ParseOS2()
if err == nil {
err = t.ParsePost()
}
}
}
}
}
}
}
return
}
func (t *ttfParser) ParseHead() (err error) {
err = t.Seek("head")
t.Skip(3 * 4) // version, fontRevision, checkSumAdjustment
magicNumber := t.ReadULong()
if magicNumber != 0x5F0F3CF5 {
err = fmt.Errorf("incorrect magic number")
return
}
t.Skip(2) // flags
t.rec.UnitsPerEm = t.ReadUShort()
t.Skip(2 * 8) // created, modified
t.rec.Xmin = t.ReadShort()
t.rec.Ymin = t.ReadShort()
t.rec.Xmax = t.ReadShort()
t.rec.Ymax = t.ReadShort()
return
}
func (t *ttfParser) ParseHhea() (err error) {
err = t.Seek("hhea")
if err == nil {
t.Skip(4 + 15*2)
t.numberOfHMetrics = t.ReadUShort()
}
return
}
func (t *ttfParser) ParseMaxp() (err error) {
err = t.Seek("maxp")
if err == nil {
t.Skip(4)
t.numGlyphs = t.ReadUShort()
}
return
}
func (t *ttfParser) ParseHmtx() (err error) {
err = t.Seek("hmtx")
if err == nil {
t.rec.Widths = make([]uint16, 0, 8)
for j := uint16(0); j < t.numberOfHMetrics; j++ {
t.rec.Widths = append(t.rec.Widths, t.ReadUShort())
t.Skip(2) // lsb
}
if t.numberOfHMetrics < t.numGlyphs {
lastWidth := t.rec.Widths[t.numberOfHMetrics-1]
for j := t.numberOfHMetrics; j < t.numGlyphs; j++ {
t.rec.Widths = append(t.rec.Widths, lastWidth)
}
}
}
return
}
func (t *ttfParser) ParseCmap() (err error) {
var offset int64
if err = t.Seek("cmap"); err != nil {
return
}
t.Skip(2) // version
numTables := int(t.ReadUShort())
offset31 := int64(0)
for j := 0; j < numTables; j++ {
platformID := t.ReadUShort()
encodingID := t.ReadUShort()
offset = int64(t.ReadULong())
if platformID == 3 && encodingID == 1 {
offset31 = offset
}
}
if offset31 == 0 {
err = fmt.Errorf("no Unicode encoding found")
return
}
startCount := make([]uint16, 0, 8)
endCount := make([]uint16, 0, 8)
idDelta := make([]int16, 0, 8)
idRangeOffset := make([]uint16, 0, 8)
t.rec.Chars = make(map[uint16]uint16)
t.f.Seek(int64(t.tables["cmap"])+offset31, os.SEEK_SET)
format := t.ReadUShort()
if format != 4 {
err = fmt.Errorf("unexpected subtable format: %d", format)
return
}
t.Skip(2 * 2) // length, language
segCount := int(t.ReadUShort() / 2)
t.Skip(3 * 2) // searchRange, entrySelector, rangeShift
for j := 0; j < segCount; j++ {
endCount = append(endCount, t.ReadUShort())
}
t.Skip(2) // reservedPad
for j := 0; j < segCount; j++ {
startCount = append(startCount, t.ReadUShort())
}
for j := 0; j < segCount; j++ {
idDelta = append(idDelta, t.ReadShort())
}
offset, _ = t.f.Seek(int64(0), os.SEEK_CUR)
for j := 0; j < segCount; j++ {
idRangeOffset = append(idRangeOffset, t.ReadUShort())
}
for j := 0; j < segCount; j++ {
c1 := startCount[j]
c2 := endCount[j]
d := idDelta[j]
ro := idRangeOffset[j]
if ro > 0 {
t.f.Seek(offset+2*int64(j)+int64(ro), os.SEEK_SET)
}
for c := c1; c <= c2; c++ {
if c == 0xFFFF {
break
}
var gid int32
if ro > 0 {
gid = int32(t.ReadUShort())
if gid > 0 {
gid += int32(d)
}
} else {
gid = int32(c) + int32(d)
}
if gid >= 65536 {
gid -= 65536
}
if gid > 0 {
t.rec.Chars[c] = uint16(gid)
}
}
}
return
}
func (t *ttfParser) ParseName() (err error) {
err = t.Seek("name")
if err == nil {
tableOffset, _ := t.f.Seek(0, os.SEEK_CUR)
t.rec.PostScriptName = ""
t.Skip(2) // format
count := t.ReadUShort()
stringOffset := t.ReadUShort()
for j := uint16(0); j < count && t.rec.PostScriptName == ""; j++ {
t.Skip(3 * 2) // platformID, encodingID, languageID
nameID := t.ReadUShort()
length := t.ReadUShort()
offset := t.ReadUShort()
if nameID == 6 {
// PostScript name
t.f.Seek(int64(tableOffset)+int64(stringOffset)+int64(offset), os.SEEK_SET)
var s string
s, err = t.ReadStr(int(length))
if err != nil {
return
}
s = strings.Replace(s, "\x00", "", -1)
var re *regexp.Regexp
if re, err = regexp.Compile("[(){}<> /%[\\]]"); err != nil {
return
}
t.rec.PostScriptName = re.ReplaceAllString(s, "")
}
}
if t.rec.PostScriptName == "" {
err = fmt.Errorf("the name PostScript was not found")
}
}
return
}
func (t *ttfParser) ParseOS2() (err error) {
err = t.Seek("OS/2")
if err == nil {
version := t.ReadUShort()
t.Skip(3 * 2) // xAvgCharWidth, usWeightClass, usWidthClass
fsType := t.ReadUShort()
t.rec.Embeddable = (fsType != 2) && (fsType&0x200) == 0
t.Skip(11*2 + 10 + 4*4 + 4)
fsSelection := t.ReadUShort()
t.rec.Bold = (fsSelection & 32) != 0
t.Skip(2 * 2) // usFirstCharIndex, usLastCharIndex
t.rec.TypoAscender = t.ReadShort()
t.rec.TypoDescender = t.ReadShort()
if version >= 2 {
t.Skip(3*2 + 2*4 + 2)
t.rec.CapHeight = t.ReadShort()
} else {
t.rec.CapHeight = 0
}
}
return
}
func (t *ttfParser) ParsePost() (err error) {
err = t.Seek("post")
if err == nil {
t.Skip(4) // version
t.rec.ItalicAngle = t.ReadShort()
t.Skip(2) // Skip decimal part
t.rec.UnderlinePosition = t.ReadShort()
t.rec.UnderlineThickness = t.ReadShort()
t.rec.IsFixedPitch = t.ReadULong() != 0
}
return
}
func (t *ttfParser) Seek(tag string) (err error) {
ofs, ok := t.tables[tag]
if ok {
t.f.Seek(int64(ofs), os.SEEK_SET)
} else {
err = fmt.Errorf("table not found: %s", tag)
}
return
}
func (t *ttfParser) Skip(n int) {
t.f.Seek(int64(n), os.SEEK_CUR)
}
func (t *ttfParser) ReadStr(length int) (str string, err error) {
var n int
buf := make([]byte, length)
n, err = t.f.Read(buf)
if err == nil {
if n == length {
str = string(buf)
} else {
err = fmt.Errorf("unable to read %d bytes", length)
}
}
return
}
func (t *ttfParser) ReadUShort() (val uint16) {
binary.Read(t.f, binary.BigEndian, &val)
return
}
func (t *ttfParser) ReadShort() (val int16) {
binary.Read(t.f, binary.BigEndian, &val)
return
}
func (t *ttfParser) ReadULong() (val uint32) {
binary.Read(t.f, binary.BigEndian, &val)
return
}

View File

@@ -0,0 +1,251 @@
package fonts
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/textencoding"
)
// Font ZapfDingbats. Implements Font interface.
// This is a built-in font and it is assumed that every reader has access to it.
type fontZapfDingbats struct {
// By default encoder is not set, which means that we use the font's built in encoding.
encoder textencoding.TextEncoder
}
func NewFontZapfDingbats() fontZapfDingbats {
font := fontZapfDingbats{}
return font
}
func (font fontZapfDingbats) SetEncoder(encoder textencoding.TextEncoder) {
font.encoder = encoder
}
func (font fontZapfDingbats) GetGlyphCharMetrics(glyph string) (CharMetrics, bool) {
metrics, has := zapfDingbatsCharMetrics[glyph]
if !has {
return metrics, false
}
return metrics, true
}
func (font fontZapfDingbats) ToPdfObject() core.PdfObject {
obj := &core.PdfIndirectObject{}
fontDict := core.MakeDict()
fontDict.Set("Type", core.MakeName("Font"))
fontDict.Set("Subtype", core.MakeName("Type1"))
fontDict.Set("BaseFont", core.MakeName("ZapfDingbats"))
if font.encoder != nil {
fontDict.Set("Encoding", font.encoder.ToPdfObject())
}
obj.PdfObject = fontDict
return obj
}
var zapfDingbatsCharMetrics map[string]CharMetrics = map[string]CharMetrics{
"a1": {GlyphName: "a1", Wx: 974.000000, Wy: 0.000000},
"a10": {GlyphName: "a10", Wx: 692.000000, Wy: 0.000000},
"a100": {GlyphName: "a100", Wx: 668.000000, Wy: 0.000000},
"a101": {GlyphName: "a101", Wx: 732.000000, Wy: 0.000000},
"a102": {GlyphName: "a102", Wx: 544.000000, Wy: 0.000000},
"a103": {GlyphName: "a103", Wx: 544.000000, Wy: 0.000000},
"a104": {GlyphName: "a104", Wx: 910.000000, Wy: 0.000000},
"a105": {GlyphName: "a105", Wx: 911.000000, Wy: 0.000000},
"a106": {GlyphName: "a106", Wx: 667.000000, Wy: 0.000000},
"a107": {GlyphName: "a107", Wx: 760.000000, Wy: 0.000000},
"a108": {GlyphName: "a108", Wx: 760.000000, Wy: 0.000000},
"a109": {GlyphName: "a109", Wx: 626.000000, Wy: 0.000000},
"a11": {GlyphName: "a11", Wx: 960.000000, Wy: 0.000000},
"a110": {GlyphName: "a110", Wx: 694.000000, Wy: 0.000000},
"a111": {GlyphName: "a111", Wx: 595.000000, Wy: 0.000000},
"a112": {GlyphName: "a112", Wx: 776.000000, Wy: 0.000000},
"a117": {GlyphName: "a117", Wx: 690.000000, Wy: 0.000000},
"a118": {GlyphName: "a118", Wx: 791.000000, Wy: 0.000000},
"a119": {GlyphName: "a119", Wx: 790.000000, Wy: 0.000000},
"a12": {GlyphName: "a12", Wx: 939.000000, Wy: 0.000000},
"a120": {GlyphName: "a120", Wx: 788.000000, Wy: 0.000000},
"a121": {GlyphName: "a121", Wx: 788.000000, Wy: 0.000000},
"a122": {GlyphName: "a122", Wx: 788.000000, Wy: 0.000000},
"a123": {GlyphName: "a123", Wx: 788.000000, Wy: 0.000000},
"a124": {GlyphName: "a124", Wx: 788.000000, Wy: 0.000000},
"a125": {GlyphName: "a125", Wx: 788.000000, Wy: 0.000000},
"a126": {GlyphName: "a126", Wx: 788.000000, Wy: 0.000000},
"a127": {GlyphName: "a127", Wx: 788.000000, Wy: 0.000000},
"a128": {GlyphName: "a128", Wx: 788.000000, Wy: 0.000000},
"a129": {GlyphName: "a129", Wx: 788.000000, Wy: 0.000000},
"a13": {GlyphName: "a13", Wx: 549.000000, Wy: 0.000000},
"a130": {GlyphName: "a130", Wx: 788.000000, Wy: 0.000000},
"a131": {GlyphName: "a131", Wx: 788.000000, Wy: 0.000000},
"a132": {GlyphName: "a132", Wx: 788.000000, Wy: 0.000000},
"a133": {GlyphName: "a133", Wx: 788.000000, Wy: 0.000000},
"a134": {GlyphName: "a134", Wx: 788.000000, Wy: 0.000000},
"a135": {GlyphName: "a135", Wx: 788.000000, Wy: 0.000000},
"a136": {GlyphName: "a136", Wx: 788.000000, Wy: 0.000000},
"a137": {GlyphName: "a137", Wx: 788.000000, Wy: 0.000000},
"a138": {GlyphName: "a138", Wx: 788.000000, Wy: 0.000000},
"a139": {GlyphName: "a139", Wx: 788.000000, Wy: 0.000000},
"a14": {GlyphName: "a14", Wx: 855.000000, Wy: 0.000000},
"a140": {GlyphName: "a140", Wx: 788.000000, Wy: 0.000000},
"a141": {GlyphName: "a141", Wx: 788.000000, Wy: 0.000000},
"a142": {GlyphName: "a142", Wx: 788.000000, Wy: 0.000000},
"a143": {GlyphName: "a143", Wx: 788.000000, Wy: 0.000000},
"a144": {GlyphName: "a144", Wx: 788.000000, Wy: 0.000000},
"a145": {GlyphName: "a145", Wx: 788.000000, Wy: 0.000000},
"a146": {GlyphName: "a146", Wx: 788.000000, Wy: 0.000000},
"a147": {GlyphName: "a147", Wx: 788.000000, Wy: 0.000000},
"a148": {GlyphName: "a148", Wx: 788.000000, Wy: 0.000000},
"a149": {GlyphName: "a149", Wx: 788.000000, Wy: 0.000000},
"a15": {GlyphName: "a15", Wx: 911.000000, Wy: 0.000000},
"a150": {GlyphName: "a150", Wx: 788.000000, Wy: 0.000000},
"a151": {GlyphName: "a151", Wx: 788.000000, Wy: 0.000000},
"a152": {GlyphName: "a152", Wx: 788.000000, Wy: 0.000000},
"a153": {GlyphName: "a153", Wx: 788.000000, Wy: 0.000000},
"a154": {GlyphName: "a154", Wx: 788.000000, Wy: 0.000000},
"a155": {GlyphName: "a155", Wx: 788.000000, Wy: 0.000000},
"a156": {GlyphName: "a156", Wx: 788.000000, Wy: 0.000000},
"a157": {GlyphName: "a157", Wx: 788.000000, Wy: 0.000000},
"a158": {GlyphName: "a158", Wx: 788.000000, Wy: 0.000000},
"a159": {GlyphName: "a159", Wx: 788.000000, Wy: 0.000000},
"a16": {GlyphName: "a16", Wx: 933.000000, Wy: 0.000000},
"a160": {GlyphName: "a160", Wx: 894.000000, Wy: 0.000000},
"a161": {GlyphName: "a161", Wx: 838.000000, Wy: 0.000000},
"a162": {GlyphName: "a162", Wx: 924.000000, Wy: 0.000000},
"a163": {GlyphName: "a163", Wx: 1016.000000, Wy: 0.000000},
"a164": {GlyphName: "a164", Wx: 458.000000, Wy: 0.000000},
"a165": {GlyphName: "a165", Wx: 924.000000, Wy: 0.000000},
"a166": {GlyphName: "a166", Wx: 918.000000, Wy: 0.000000},
"a167": {GlyphName: "a167", Wx: 927.000000, Wy: 0.000000},
"a168": {GlyphName: "a168", Wx: 928.000000, Wy: 0.000000},
"a169": {GlyphName: "a169", Wx: 928.000000, Wy: 0.000000},
"a17": {GlyphName: "a17", Wx: 945.000000, Wy: 0.000000},
"a170": {GlyphName: "a170", Wx: 834.000000, Wy: 0.000000},
"a171": {GlyphName: "a171", Wx: 873.000000, Wy: 0.000000},
"a172": {GlyphName: "a172", Wx: 828.000000, Wy: 0.000000},
"a173": {GlyphName: "a173", Wx: 924.000000, Wy: 0.000000},
"a174": {GlyphName: "a174", Wx: 917.000000, Wy: 0.000000},
"a175": {GlyphName: "a175", Wx: 930.000000, Wy: 0.000000},
"a176": {GlyphName: "a176", Wx: 931.000000, Wy: 0.000000},
"a177": {GlyphName: "a177", Wx: 463.000000, Wy: 0.000000},
"a178": {GlyphName: "a178", Wx: 883.000000, Wy: 0.000000},
"a179": {GlyphName: "a179", Wx: 836.000000, Wy: 0.000000},
"a18": {GlyphName: "a18", Wx: 974.000000, Wy: 0.000000},
"a180": {GlyphName: "a180", Wx: 867.000000, Wy: 0.000000},
"a181": {GlyphName: "a181", Wx: 696.000000, Wy: 0.000000},
"a182": {GlyphName: "a182", Wx: 874.000000, Wy: 0.000000},
"a183": {GlyphName: "a183", Wx: 760.000000, Wy: 0.000000},
"a184": {GlyphName: "a184", Wx: 946.000000, Wy: 0.000000},
"a185": {GlyphName: "a185", Wx: 865.000000, Wy: 0.000000},
"a186": {GlyphName: "a186", Wx: 967.000000, Wy: 0.000000},
"a187": {GlyphName: "a187", Wx: 831.000000, Wy: 0.000000},
"a188": {GlyphName: "a188", Wx: 873.000000, Wy: 0.000000},
"a189": {GlyphName: "a189", Wx: 927.000000, Wy: 0.000000},
"a19": {GlyphName: "a19", Wx: 755.000000, Wy: 0.000000},
"a190": {GlyphName: "a190", Wx: 970.000000, Wy: 0.000000},
"a191": {GlyphName: "a191", Wx: 918.000000, Wy: 0.000000},
"a192": {GlyphName: "a192", Wx: 748.000000, Wy: 0.000000},
"a193": {GlyphName: "a193", Wx: 836.000000, Wy: 0.000000},
"a194": {GlyphName: "a194", Wx: 771.000000, Wy: 0.000000},
"a195": {GlyphName: "a195", Wx: 888.000000, Wy: 0.000000},
"a196": {GlyphName: "a196", Wx: 748.000000, Wy: 0.000000},
"a197": {GlyphName: "a197", Wx: 771.000000, Wy: 0.000000},
"a198": {GlyphName: "a198", Wx: 888.000000, Wy: 0.000000},
"a199": {GlyphName: "a199", Wx: 867.000000, Wy: 0.000000},
"a2": {GlyphName: "a2", Wx: 961.000000, Wy: 0.000000},
"a20": {GlyphName: "a20", Wx: 846.000000, Wy: 0.000000},
"a200": {GlyphName: "a200", Wx: 696.000000, Wy: 0.000000},
"a201": {GlyphName: "a201", Wx: 874.000000, Wy: 0.000000},
"a202": {GlyphName: "a202", Wx: 974.000000, Wy: 0.000000},
"a203": {GlyphName: "a203", Wx: 762.000000, Wy: 0.000000},
"a204": {GlyphName: "a204", Wx: 759.000000, Wy: 0.000000},
"a205": {GlyphName: "a205", Wx: 509.000000, Wy: 0.000000},
"a206": {GlyphName: "a206", Wx: 410.000000, Wy: 0.000000},
"a21": {GlyphName: "a21", Wx: 762.000000, Wy: 0.000000},
"a22": {GlyphName: "a22", Wx: 761.000000, Wy: 0.000000},
"a23": {GlyphName: "a23", Wx: 571.000000, Wy: 0.000000},
"a24": {GlyphName: "a24", Wx: 677.000000, Wy: 0.000000},
"a25": {GlyphName: "a25", Wx: 763.000000, Wy: 0.000000},
"a26": {GlyphName: "a26", Wx: 760.000000, Wy: 0.000000},
"a27": {GlyphName: "a27", Wx: 759.000000, Wy: 0.000000},
"a28": {GlyphName: "a28", Wx: 754.000000, Wy: 0.000000},
"a29": {GlyphName: "a29", Wx: 786.000000, Wy: 0.000000},
"a3": {GlyphName: "a3", Wx: 980.000000, Wy: 0.000000},
"a30": {GlyphName: "a30", Wx: 788.000000, Wy: 0.000000},
"a31": {GlyphName: "a31", Wx: 788.000000, Wy: 0.000000},
"a32": {GlyphName: "a32", Wx: 790.000000, Wy: 0.000000},
"a33": {GlyphName: "a33", Wx: 793.000000, Wy: 0.000000},
"a34": {GlyphName: "a34", Wx: 794.000000, Wy: 0.000000},
"a35": {GlyphName: "a35", Wx: 816.000000, Wy: 0.000000},
"a36": {GlyphName: "a36", Wx: 823.000000, Wy: 0.000000},
"a37": {GlyphName: "a37", Wx: 789.000000, Wy: 0.000000},
"a38": {GlyphName: "a38", Wx: 841.000000, Wy: 0.000000},
"a39": {GlyphName: "a39", Wx: 823.000000, Wy: 0.000000},
"a4": {GlyphName: "a4", Wx: 719.000000, Wy: 0.000000},
"a40": {GlyphName: "a40", Wx: 833.000000, Wy: 0.000000},
"a41": {GlyphName: "a41", Wx: 816.000000, Wy: 0.000000},
"a42": {GlyphName: "a42", Wx: 831.000000, Wy: 0.000000},
"a43": {GlyphName: "a43", Wx: 923.000000, Wy: 0.000000},
"a44": {GlyphName: "a44", Wx: 744.000000, Wy: 0.000000},
"a45": {GlyphName: "a45", Wx: 723.000000, Wy: 0.000000},
"a46": {GlyphName: "a46", Wx: 749.000000, Wy: 0.000000},
"a47": {GlyphName: "a47", Wx: 790.000000, Wy: 0.000000},
"a48": {GlyphName: "a48", Wx: 792.000000, Wy: 0.000000},
"a49": {GlyphName: "a49", Wx: 695.000000, Wy: 0.000000},
"a5": {GlyphName: "a5", Wx: 789.000000, Wy: 0.000000},
"a50": {GlyphName: "a50", Wx: 776.000000, Wy: 0.000000},
"a51": {GlyphName: "a51", Wx: 768.000000, Wy: 0.000000},
"a52": {GlyphName: "a52", Wx: 792.000000, Wy: 0.000000},
"a53": {GlyphName: "a53", Wx: 759.000000, Wy: 0.000000},
"a54": {GlyphName: "a54", Wx: 707.000000, Wy: 0.000000},
"a55": {GlyphName: "a55", Wx: 708.000000, Wy: 0.000000},
"a56": {GlyphName: "a56", Wx: 682.000000, Wy: 0.000000},
"a57": {GlyphName: "a57", Wx: 701.000000, Wy: 0.000000},
"a58": {GlyphName: "a58", Wx: 826.000000, Wy: 0.000000},
"a59": {GlyphName: "a59", Wx: 815.000000, Wy: 0.000000},
"a6": {GlyphName: "a6", Wx: 494.000000, Wy: 0.000000},
"a60": {GlyphName: "a60", Wx: 789.000000, Wy: 0.000000},
"a61": {GlyphName: "a61", Wx: 789.000000, Wy: 0.000000},
"a62": {GlyphName: "a62", Wx: 707.000000, Wy: 0.000000},
"a63": {GlyphName: "a63", Wx: 687.000000, Wy: 0.000000},
"a64": {GlyphName: "a64", Wx: 696.000000, Wy: 0.000000},
"a65": {GlyphName: "a65", Wx: 689.000000, Wy: 0.000000},
"a66": {GlyphName: "a66", Wx: 786.000000, Wy: 0.000000},
"a67": {GlyphName: "a67", Wx: 787.000000, Wy: 0.000000},
"a68": {GlyphName: "a68", Wx: 713.000000, Wy: 0.000000},
"a69": {GlyphName: "a69", Wx: 791.000000, Wy: 0.000000},
"a7": {GlyphName: "a7", Wx: 552.000000, Wy: 0.000000},
"a70": {GlyphName: "a70", Wx: 785.000000, Wy: 0.000000},
"a71": {GlyphName: "a71", Wx: 791.000000, Wy: 0.000000},
"a72": {GlyphName: "a72", Wx: 873.000000, Wy: 0.000000},
"a73": {GlyphName: "a73", Wx: 761.000000, Wy: 0.000000},
"a74": {GlyphName: "a74", Wx: 762.000000, Wy: 0.000000},
"a75": {GlyphName: "a75", Wx: 759.000000, Wy: 0.000000},
"a76": {GlyphName: "a76", Wx: 892.000000, Wy: 0.000000},
"a77": {GlyphName: "a77", Wx: 892.000000, Wy: 0.000000},
"a78": {GlyphName: "a78", Wx: 788.000000, Wy: 0.000000},
"a79": {GlyphName: "a79", Wx: 784.000000, Wy: 0.000000},
"a8": {GlyphName: "a8", Wx: 537.000000, Wy: 0.000000},
"a81": {GlyphName: "a81", Wx: 438.000000, Wy: 0.000000},
"a82": {GlyphName: "a82", Wx: 138.000000, Wy: 0.000000},
"a83": {GlyphName: "a83", Wx: 277.000000, Wy: 0.000000},
"a84": {GlyphName: "a84", Wx: 415.000000, Wy: 0.000000},
"a85": {GlyphName: "a85", Wx: 509.000000, Wy: 0.000000},
"a86": {GlyphName: "a86", Wx: 410.000000, Wy: 0.000000},
"a87": {GlyphName: "a87", Wx: 234.000000, Wy: 0.000000},
"a88": {GlyphName: "a88", Wx: 234.000000, Wy: 0.000000},
"a89": {GlyphName: "a89", Wx: 390.000000, Wy: 0.000000},
"a9": {GlyphName: "a9", Wx: 577.000000, Wy: 0.000000},
"a90": {GlyphName: "a90", Wx: 390.000000, Wy: 0.000000},
"a91": {GlyphName: "a91", Wx: 276.000000, Wy: 0.000000},
"a92": {GlyphName: "a92", Wx: 276.000000, Wy: 0.000000},
"a93": {GlyphName: "a93", Wx: 317.000000, Wy: 0.000000},
"a94": {GlyphName: "a94", Wx: 317.000000, Wy: 0.000000},
"a95": {GlyphName: "a95", Wx: 334.000000, Wy: 0.000000},
"a96": {GlyphName: "a96", Wx: 334.000000, Wy: 0.000000},
"a97": {GlyphName: "a97", Wx: 392.000000, Wy: 0.000000},
"a98": {GlyphName: "a98", Wx: 392.000000, Wy: 0.000000},
"a99": {GlyphName: "a99", Wx: 668.000000, Wy: 0.000000},
"space": {GlyphName: "space", Wx: 278.000000, Wy: 0.000000},
}

412
internal/pdf/model/forms.go Normal file
View File

@@ -0,0 +1,412 @@
package model
import (
"fmt"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// High level manipulation of forms (AcroForm).
type PdfAcroForm struct {
Fields *[]*PdfField
NeedAppearances *core.PdfObjectBool
SigFlags *core.PdfObjectInteger
CO *core.PdfObjectArray
DR *PdfPageResources
DA *core.PdfObjectString
Q *core.PdfObjectInteger
XFA core.PdfObject
primitive *core.PdfIndirectObject
}
func NewPdfAcroForm() *PdfAcroForm {
acroForm := &PdfAcroForm{}
container := &core.PdfIndirectObject{}
container.PdfObject = core.MakeDict()
acroForm.primitive = container
return acroForm
}
// Used when loading forms from PDF files.
func (r *PdfReader) newPdfAcroFormFromDict(d *core.PdfObjectDictionary) (*PdfAcroForm, error) {
acroForm := NewPdfAcroForm()
if obj := d.Get("Fields"); obj != nil {
obj, err := r.traceToObject(obj)
if err != nil {
return nil, err
}
fieldArray, ok := core.TraceToDirectObject(obj).(*core.PdfObjectArray)
if !ok {
return nil, fmt.Errorf("fields not an array (%T)", obj)
}
fields := []*PdfField{}
for _, obj := range *fieldArray {
obj, err := r.traceToObject(obj)
if err != nil {
return nil, err
}
container, isIndirect := obj.(*core.PdfIndirectObject)
if !isIndirect {
if _, isNull := obj.(*core.PdfObjectNull); isNull {
common.Log.Trace("Skipping over null field")
continue
}
common.Log.Debug("Field not contained in indirect object %T", obj)
return nil, fmt.Errorf("field not in an indirect object")
}
field, err := r.newPdfFieldFromIndirectObject(container, nil)
if err != nil {
return nil, err
}
common.Log.Trace("AcroForm Field: %+v", *field)
fields = append(fields, field)
}
acroForm.Fields = &fields
}
if obj := d.Get("NeedAppearances"); obj != nil {
val, ok := obj.(*core.PdfObjectBool)
if ok {
acroForm.NeedAppearances = val
} else {
common.Log.Debug("error: NeedAppearances invalid (got %T)", obj)
}
}
if obj := d.Get("SigFlags"); obj != nil {
val, ok := obj.(*core.PdfObjectInteger)
if ok {
acroForm.SigFlags = val
} else {
common.Log.Debug("error: SigFlags invalid (got %T)", obj)
}
}
if obj := d.Get("CO"); obj != nil {
obj = core.TraceToDirectObject(obj)
arr, ok := obj.(*core.PdfObjectArray)
if ok {
acroForm.CO = arr
} else {
common.Log.Debug("error: CO invalid (got %T)", obj)
}
}
if obj := d.Get("DR"); obj != nil {
obj = core.TraceToDirectObject(obj)
if d, ok := obj.(*core.PdfObjectDictionary); ok {
resources, err := NewPdfPageResourcesFromDict(d)
if err != nil {
common.Log.Error("invalid DR: %v", err)
return nil, err
}
acroForm.DR = resources
} else {
common.Log.Debug("error: DR invalid (got %T)", obj)
}
}
if obj := d.Get("DA"); obj != nil {
str, ok := obj.(*core.PdfObjectString)
if ok {
acroForm.DA = str
} else {
common.Log.Debug("error: DA invalid (got %T)", obj)
}
}
if obj := d.Get("Q"); obj != nil {
val, ok := obj.(*core.PdfObjectInteger)
if ok {
acroForm.Q = val
} else {
common.Log.Debug("error: Q invalid (got %T)", obj)
}
}
if obj := d.Get("XFA"); obj != nil {
acroForm.XFA = obj
}
return acroForm, nil
}
func (af *PdfAcroForm) GetContainingPdfObject() core.PdfObject {
return af.primitive
}
func (af *PdfAcroForm) ToPdfObject() core.PdfObject {
container := af.primitive
dict := container.PdfObject.(*core.PdfObjectDictionary)
if af.Fields != nil {
arr := core.PdfObjectArray{}
for _, field := range *af.Fields {
arr = append(arr, field.ToPdfObject())
}
dict.Set("Fields", &arr)
}
if af.NeedAppearances != nil {
dict.Set("NeedAppearances", af.NeedAppearances)
}
if af.SigFlags != nil {
dict.Set("SigFlags", af.SigFlags)
}
if af.CO != nil {
dict.Set("CO", af.CO)
}
if af.DR != nil {
dict.Set("DR", af.DR.ToPdfObject())
}
if af.DA != nil {
dict.Set("DA", af.DA)
}
if af.Q != nil {
dict.Set("Q", af.Q)
}
if af.XFA != nil {
dict.Set("XFA", af.XFA)
}
return container
}
// PdfField represents a field of an interactive form.
// Implements PdfModel interface.
type PdfField struct {
FT *core.PdfObjectName // field type
Parent *PdfField
// In a non-terminal field, the Kids array shall refer to field dictionaries that are immediate descendants of this field.
// In a terminal field, the Kids array ordinarily shall refer to one or more separate widget annotations that are associated
// with this field. However, if there is only one associated widget annotation, and its contents have been merged into the field
// dictionary, Kids shall be omitted.
KidsF []PdfModel // Kids can be array of other fields or widgets (PdfModel).
KidsA []*PdfAnnotation
T core.PdfObject
TU core.PdfObject
TM core.PdfObject
Ff core.PdfObject // field flag
V core.PdfObject //value
DV core.PdfObject
AA core.PdfObject
// Variable Text:
DA core.PdfObject
Q core.PdfObject
DS core.PdfObject
RV core.PdfObject
primitive *core.PdfIndirectObject
}
func NewPdfField() *PdfField {
field := &PdfField{}
container := &core.PdfIndirectObject{}
container.PdfObject = core.MakeDict()
field.primitive = container
return field
}
// Used when loading fields from PDF files.
func (r *PdfReader) newPdfFieldFromIndirectObject(container *core.PdfIndirectObject, parent *PdfField) (*PdfField, error) {
d, isDict := container.PdfObject.(*core.PdfObjectDictionary)
if !isDict {
return nil, fmt.Errorf("pdf Field indirect object not containing a dictionary")
}
field := NewPdfField()
// Field type (required in terminal fields).
// Can be /Btn /Tx /Ch /Sig
// Required for a terminal field (inheritable).
var err error
if obj := d.Get("FT"); obj != nil {
obj, err = r.traceToObject(obj)
if err != nil {
return nil, err
}
name, ok := obj.(*core.PdfObjectName)
if !ok {
return nil, fmt.Errorf("invalid type of FT field (%T)", obj)
}
field.FT = name
}
// Partial field name (Optional)
field.T = d.Get("T")
// Alternate description (Optional)
field.TU = d.Get("TU")
// Mapping name (Optional)
field.TM = d.Get("TM")
// Field flag. (Optional; inheritable)
field.Ff = d.Get("Ff")
// Value (Optional; inheritable) - Various types depending on the field type.
field.V = d.Get("V")
// Default value for reset (Optional; inheritable)
field.DV = d.Get("DV")
// Additional actions dictionary (Optional)
field.AA = d.Get("AA")
// Variable text:
field.DA = d.Get("DA")
field.Q = d.Get("Q")
field.DS = d.Get("DS")
field.RV = d.Get("RV")
// In a non-terminal field, the Kids array shall refer to field dictionaries that are immediate descendants of this field.
// In a terminal field, the Kids array ordinarily shall refer to one or more separate widget annotations that are associated
// with this field. However, if there is only one associated widget annotation, and its contents have been merged into the field
// dictionary, Kids shall be omitted.
// Set ourself?
if parent != nil {
field.Parent = parent
}
// Has a merged-in widget annotation?
if obj := d.Get("Subtype"); obj != nil {
obj, err = r.traceToObject(obj)
if err != nil {
return nil, err
}
common.Log.Trace("Merged in annotation (%T)", obj)
name, ok := obj.(*core.PdfObjectName)
if !ok {
return nil, fmt.Errorf("invalid type of Subtype (%T)", obj)
}
if *name == "Widget" {
// Is a merged field / widget dict.
// Check if the annotation has already been loaded?
// Most likely referenced to by a page... Could be in either direction.
// r.newPdfAnnotationFromIndirectObject acts as a caching mechanism.
annot, err := r.newPdfAnnotationFromIndirectObject(container)
if err != nil {
return nil, err
}
widget, ok := annot.GetContext().(*PdfAnnotationWidget)
if !ok {
return nil, fmt.Errorf("invalid widget")
}
widget.Parent = field.GetContainingPdfObject()
field.KidsA = append(field.KidsA, annot)
return field, nil
}
}
if obj := d.Get("Kids"); obj != nil {
obj, err := r.traceToObject(obj)
if err != nil {
return nil, err
}
fieldArray, ok := core.TraceToDirectObject(obj).(*core.PdfObjectArray)
if !ok {
return nil, fmt.Errorf("kids not an array (%T)", obj)
}
field.KidsF = []PdfModel{}
for _, obj := range *fieldArray {
obj, err := r.traceToObject(obj)
if err != nil {
return nil, err
}
container, isIndirect := obj.(*core.PdfIndirectObject)
if !isIndirect {
return nil, fmt.Errorf("not an indirect object (form field)")
}
childField, err := r.newPdfFieldFromIndirectObject(container, field)
if err != nil {
return nil, err
}
field.KidsF = append(field.KidsF, childField)
}
}
return field, nil
}
func (pf *PdfField) GetContainingPdfObject() core.PdfObject {
return pf.primitive
}
// If Kids refer only to a single pdf widget annotation widget, then can merge it in.
// Currently not merging it in.
func (pf *PdfField) ToPdfObject() core.PdfObject {
container := pf.primitive
dict := container.PdfObject.(*core.PdfObjectDictionary)
if pf.Parent != nil {
dict.Set("Parent", pf.Parent.GetContainingPdfObject())
}
if pf.KidsF != nil {
// Create an array of the kids (fields or widgets).
common.Log.Trace("KidsF: %+v", pf.KidsF)
arr := core.PdfObjectArray{}
for _, child := range pf.KidsF {
arr = append(arr, child.ToPdfObject())
}
dict.Set("Kids", &arr)
}
if pf.KidsA != nil {
common.Log.Trace("KidsA: %+v", pf.KidsA)
_, hasKids := dict.Get("Kids").(*core.PdfObjectArray)
if !hasKids {
dict.Set("Kids", &core.PdfObjectArray{})
}
arr := dict.Get("Kids").(*core.PdfObjectArray)
for _, child := range pf.KidsA {
*arr = append(*arr, child.GetContext().ToPdfObject())
}
}
if pf.FT != nil {
dict.Set("FT", pf.FT)
}
if pf.T != nil {
dict.Set("T", pf.T)
}
if pf.TU != nil {
dict.Set("TU", pf.TU)
}
if pf.TM != nil {
dict.Set("TM", pf.TM)
}
if pf.Ff != nil {
dict.Set("Ff", pf.Ff)
}
if pf.V != nil {
dict.Set("V", pf.V)
}
if pf.DV != nil {
dict.Set("DV", pf.DV)
}
if pf.AA != nil {
dict.Set("AA", pf.AA)
}
// Variable text:
dict.SetIfNotNil("DA", pf.DA)
dict.SetIfNotNil("Q", pf.Q)
dict.SetIfNotNil("DS", pf.DS)
dict.SetIfNotNil("RV", pf.RV)
return container
}

View File

@@ -0,0 +1,853 @@
package model
import (
"errors"
"math"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/sampling"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/ps"
)
type PdfValue any
type PdfFunction interface {
Evaluate([]float64) ([]float64, error)
ToPdfObject() core.PdfObject
}
// In PDF: A function object may be a dictionary or a stream, depending on the type of function.
// - Stream: Type 0, Type 4
// - Dictionary: Type 2, Type 3.
// Loads a PDF Function from a PdfObject (can be either stream or dictionary).
func newPdfFunctionFromPdfObject(obj core.PdfObject) (PdfFunction, error) {
if stream, is := obj.(*core.PdfObjectStream); is {
dict := stream.PdfObjectDictionary
ftype, ok := dict.Get("FunctionType").(*core.PdfObjectInteger)
if !ok {
common.Log.Error("FunctionType number missing")
return nil, errors.New("invalid parameter or missing")
}
switch *ftype {
case 0:
return newPdfFunctionType0FromStream(stream)
case 4:
return newPdfFunctionType4FromStream(stream)
default:
return nil, errors.New("invalid function type")
}
} else if indObj, is := obj.(*core.PdfIndirectObject); is {
// Indirect object containing a dictionary.
// The indirect object is the container (which is tracked).
dict, ok := indObj.PdfObject.(*core.PdfObjectDictionary)
if !ok {
common.Log.Error("Function Indirect object not containing dictionary")
return nil, errors.New("invalid parameter or missing")
}
ftype, ok := dict.Get("FunctionType").(*core.PdfObjectInteger)
if !ok {
common.Log.Error("FunctionType number missing")
return nil, errors.New("invalid parameter or missing")
}
switch *ftype {
case 2:
return newPdfFunctionType2FromPdfObject(indObj)
case 3:
return newPdfFunctionType3FromPdfObject(indObj)
default:
return nil, errors.New("invalid function type")
}
} else if dict, is := obj.(*core.PdfObjectDictionary); is {
ftype, ok := dict.Get("FunctionType").(*core.PdfObjectInteger)
if !ok {
common.Log.Error("FunctionType number missing")
return nil, errors.New("invalid parameter or missing")
}
switch *ftype {
case 2:
return newPdfFunctionType2FromPdfObject(dict)
case 3:
return newPdfFunctionType3FromPdfObject(dict)
default:
return nil, errors.New("invalid function type")
}
} else {
common.Log.Debug("Function Type error: %#v", obj)
return nil, errors.New("type error")
}
}
// Simple linear interpolation from the PDF manual.
func interpolate(x, xmin, xmax, ymin, ymax float64) float64 {
if math.Abs(xmax-xmin) < 0.000001 {
return ymin
}
y := ymin + (x-xmin)*(ymax-ymin)/(xmax-xmin)
return y
}
// Type 0 functions use a sequence of sample values (contained in a stream) to provide an approximation
// for functions whose domains and ranges are bounded. The samples are organized as an m-dimensional
// table in which each entry has n components
type PdfFunctionType0 struct {
Domain []float64 // required; 2*m length; where m is the number of input values
Range []float64 // required (type 0); 2*n length; where n is the number of output values
NumInputs int
NumOutputs int
Size []int
BitsPerSample int
Order int // Values 1 or 3 (linear or cubic spline interpolation)
Encode []float64
Decode []float64
rawData []byte
data []uint32
container *core.PdfObjectStream
}
// Construct the PDF function object from a stream object (typically loaded from a PDF file).
func newPdfFunctionType0FromStream(stream *core.PdfObjectStream) (*PdfFunctionType0, error) {
fun := &PdfFunctionType0{}
fun.container = stream
dict := stream.PdfObjectDictionary
// Domain
array, has := core.TraceToDirectObject(dict.Get("Domain")).(*core.PdfObjectArray)
if !has {
common.Log.Error("Domain not specified")
return nil, errors.New("required attribute missing or invalid")
}
if len(*array)%2 != 0 {
common.Log.Error("Domain invalid")
return nil, errors.New("invalid domain range")
}
fun.NumInputs = len(*array) / 2
domain, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.Domain = domain
// Range
array, has = core.TraceToDirectObject(dict.Get("Range")).(*core.PdfObjectArray)
if !has {
common.Log.Error("Range not specified")
return nil, errors.New("required attribute missing or invalid")
}
if len(*array)%2 != 0 {
return nil, errors.New("invalid range")
}
fun.NumOutputs = len(*array) / 2
rang, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.Range = rang
// Number of samples in each input dimension
array, has = core.TraceToDirectObject(dict.Get("Size")).(*core.PdfObjectArray)
if !has {
common.Log.Error("Size not specified")
return nil, errors.New("required attribute missing or invalid")
}
tablesize, err := array.ToIntegerArray()
if err != nil {
return nil, err
}
if len(tablesize) != fun.NumInputs {
common.Log.Error("Table size not matching number of inputs")
return nil, errors.New("range check")
}
fun.Size = tablesize
// BitsPerSample
bps, has := core.TraceToDirectObject(dict.Get("BitsPerSample")).(*core.PdfObjectInteger)
if !has {
common.Log.Error("BitsPerSample not specified")
return nil, errors.New("required attribute missing or invalid")
}
if *bps != 1 && *bps != 2 && *bps != 4 && *bps != 8 && *bps != 12 && *bps != 16 && *bps != 24 && *bps != 32 {
common.Log.Error("Bits per sample outside range (%d)", *bps)
return nil, errors.New("range check")
}
fun.BitsPerSample = int(*bps)
fun.Order = 1
order, has := core.TraceToDirectObject(dict.Get("Order")).(*core.PdfObjectInteger)
if has {
if *order != 1 && *order != 3 {
common.Log.Error("invalid order (%d)", *order)
return nil, errors.New("range check")
}
fun.Order = int(*order)
}
// Encode: is a 2*m array specifying the linear mapping of input values into the domain of the function's
// sample table.
array, has = core.TraceToDirectObject(dict.Get("Encode")).(*core.PdfObjectArray)
if has {
encode, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.Encode = encode
}
// Decode
array, has = core.TraceToDirectObject(dict.Get("Decode")).(*core.PdfObjectArray)
if has {
decode, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.Decode = decode
}
data, err := core.DecodeStream(stream)
if err != nil {
return nil, err
}
fun.rawData = data
return fun, nil
}
func (pft *PdfFunctionType0) ToPdfObject() core.PdfObject {
container := pft.container
if container != nil {
pft.container = &core.PdfObjectStream{}
}
dict := core.MakeDict()
dict.Set("FunctionType", core.MakeInteger(0))
// Domain (required).
domainArray := &core.PdfObjectArray{}
for _, val := range pft.Domain {
domainArray.Append(core.MakeFloat(val))
}
dict.Set("Domain", domainArray)
// Range (required).
rangeArray := &core.PdfObjectArray{}
for _, val := range pft.Range {
rangeArray.Append(core.MakeFloat(val))
}
dict.Set("Range", rangeArray)
// Size (required).
sizeArray := &core.PdfObjectArray{}
for _, val := range pft.Size {
sizeArray.Append(core.MakeInteger(int64(val)))
}
dict.Set("Size", sizeArray)
dict.Set("BitsPerSample", core.MakeInteger(int64(pft.BitsPerSample)))
if pft.Order != 1 {
dict.Set("Order", core.MakeInteger(int64(pft.Order)))
}
// TODO: Encode.
// Either here, or automatically later on when writing out.
dict.Set("Length", core.MakeInteger(int64(len(pft.rawData))))
container.Stream = pft.rawData
container.PdfObjectDictionary = dict
return container
}
func (pft *PdfFunctionType0) Evaluate(x []float64) ([]float64, error) {
if len(x) != pft.NumInputs {
common.Log.Error("Number of inputs not matching what is needed")
return nil, errors.New("range check error")
}
if pft.data == nil {
// Process the samples if not already done.
err := pft.processSamples()
if err != nil {
return nil, err
}
}
// Fall back to default Encode/Decode params if not set.
encode := pft.Encode
if encode == nil {
encode = []float64{}
for i := 0; i < len(pft.Size); i++ {
encode = append(encode, 0)
encode = append(encode, float64(pft.Size[i]-1))
}
}
decode := pft.Decode
if decode == nil {
decode = pft.Range
}
indices := []int{}
// Start with nearest neighbour interpolation.
for i := 0; i < len(x); i++ {
xi := x[i]
xip := math.Min(math.Max(xi, pft.Domain[2*i]), pft.Domain[2*i+1])
ei := interpolate(xip, pft.Domain[2*i], pft.Domain[2*i+1], encode[2*i], encode[2*i+1])
eip := math.Min(math.Max(ei, 0), float64(pft.Size[i]))
// eip represents coordinate into the data table.
// At this point it is real values.
// Interpolation shall be used to to determine output values
// from the nearest surrounding values in the sample table.
// Initial implementation is simply nearest neighbour.
// Then will add the linear and possibly bicubic/spline.
index := int(math.Floor(eip + 0.5))
if index < 0 {
index = 0
} else if index > pft.Size[i] {
index = pft.Size[i] - 1
}
indices = append(indices, index)
}
// Calculate the index
m := indices[0]
for i := 1; i < pft.NumInputs; i++ {
add := indices[i]
for j := 0; j < i; j++ {
add *= pft.Size[j]
}
m += add
}
m *= pft.NumOutputs
// Output values.
outputs := []float64{}
for j := 0; j < pft.NumOutputs; j++ {
rj := pft.data[m+j]
rjp := interpolate(float64(rj), 0, math.Pow(2, float64(pft.BitsPerSample)), decode[2*j], decode[2*j+1])
yj := math.Min(math.Max(rjp, pft.Range[2*j]), pft.Range[2*j+1])
outputs = append(outputs, yj)
}
return outputs, nil
}
// Convert raw data to data table. The maximum supported BitsPerSample is 32, so we store the resulting data
// in a uint32 array. This is somewhat wasteful in the case of a small BitsPerSample, but these tables are
// presumably not huge at any rate.
func (pft *PdfFunctionType0) processSamples() error {
data := sampling.ResampleBytes(pft.rawData, pft.BitsPerSample)
pft.data = data
return nil
}
// Type 2 functions define an exponential interpolation of one input value and n
// output values:
//
// f(x) = y_0, ..., y_(n-1)
//
// y_j = C0_j + x^N * (C1_j - C0_j); for 0 <= j < n
// When N=1 ; linear interpolation between C0 and C1.
type PdfFunctionType2 struct {
Domain []float64
Range []float64
C0 []float64
C1 []float64
N float64
container *core.PdfIndirectObject
}
// Can be either indirect object or dictionary. If indirect, then must be holding a dictionary,
// i.e. acting as a container. When converting back to pdf object, will use the container provided.
func newPdfFunctionType2FromPdfObject(obj core.PdfObject) (*PdfFunctionType2, error) {
fun := &PdfFunctionType2{}
var dict *core.PdfObjectDictionary
if indObj, is := obj.(*core.PdfIndirectObject); is {
d, ok := indObj.PdfObject.(*core.PdfObjectDictionary)
if !ok {
return nil, errors.New("type check error")
}
fun.container = indObj
dict = d
} else if d, is := obj.(*core.PdfObjectDictionary); is {
dict = d
} else {
return nil, errors.New("type check error")
}
common.Log.Trace("FUNC2: %s", dict.String())
// Domain
array, has := core.TraceToDirectObject(dict.Get("Domain")).(*core.PdfObjectArray)
if !has {
common.Log.Error("Domain not specified")
return nil, errors.New("required attribute missing or invalid")
}
if len(*array)%2 != 0 {
common.Log.Error("Domain range invalid")
return nil, errors.New("invalid domain range")
}
domain, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.Domain = domain
// Range
array, has = core.TraceToDirectObject(dict.Get("Range")).(*core.PdfObjectArray)
if has {
if len(*array)%2 != 0 {
return nil, errors.New("invalid range")
}
rang, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.Range = rang
}
// C0.
array, has = core.TraceToDirectObject(dict.Get("C0")).(*core.PdfObjectArray)
if has {
c0, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.C0 = c0
}
// C1.
array, has = core.TraceToDirectObject(dict.Get("C1")).(*core.PdfObjectArray)
if has {
c1, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.C1 = c1
}
if len(fun.C0) != len(fun.C1) {
common.Log.Error("C0 and C1 not matching")
return nil, errors.New("range check")
}
// Exponent.
N, err := getNumberAsFloat(core.TraceToDirectObject(dict.Get("N")))
if err != nil {
common.Log.Error("N missing or invalid, dict: %s", dict.String())
return nil, err
}
fun.N = N
return fun, nil
}
func (ftt *PdfFunctionType2) ToPdfObject() core.PdfObject {
dict := core.MakeDict()
dict.Set("FunctionType", core.MakeInteger(2))
// Domain (required).
domainArray := &core.PdfObjectArray{}
for _, val := range ftt.Domain {
domainArray.Append(core.MakeFloat(val))
}
dict.Set("Domain", domainArray)
// Range (required).
if ftt.Range != nil {
rangeArray := &core.PdfObjectArray{}
for _, val := range ftt.Range {
rangeArray.Append(core.MakeFloat(val))
}
dict.Set("Range", rangeArray)
}
// C0.
if ftt.C0 != nil {
c0Array := &core.PdfObjectArray{}
for _, val := range ftt.C0 {
c0Array.Append(core.MakeFloat(val))
}
dict.Set("C0", c0Array)
}
// C1.
if ftt.C1 != nil {
c1Array := &core.PdfObjectArray{}
for _, val := range ftt.C1 {
c1Array.Append(core.MakeFloat(val))
}
dict.Set("C1", c1Array)
}
// exponent
dict.Set("N", core.MakeFloat(ftt.N))
// Wrap in a container if we have one already specified.
if ftt.container != nil {
ftt.container.PdfObject = dict
return ftt.container
} else {
return dict
}
}
func (ftt *PdfFunctionType2) Evaluate(x []float64) ([]float64, error) {
if len(x) != 1 {
common.Log.Error("Only one input allowed")
return nil, errors.New("range check")
}
// Prepare.
c0 := []float64{0.0}
if ftt.C0 != nil {
c0 = ftt.C0
}
c1 := []float64{1.0}
if ftt.C1 != nil {
c1 = ftt.C1
}
y := []float64{}
for i := 0; i < len(c0); i++ {
yi := c0[i] + math.Pow(x[0], ftt.N)*(c1[i]-c0[i])
y = append(y, yi)
}
return y, nil
}
// Type 3 functions define stitching of the subdomains of serveral 1-input functions to produce
// a single new 1-input function.
type PdfFunctionType3 struct {
Domain []float64
Range []float64
Functions []PdfFunction // k-1 input functions
Bounds []float64 // k-1 numbers; defines the intervals where each function applies
Encode []float64 // Array of 2k numbers..
container *core.PdfIndirectObject
}
func (*PdfFunctionType3) Evaluate(x []float64) ([]float64, error) {
if len(x) != 1 {
common.Log.Error("Only one input allowed")
return nil, errors.New("range check")
}
// Determine which function to use
// Encode
return nil, errors.New("not implemented yet")
}
func newPdfFunctionType3FromPdfObject(obj core.PdfObject) (*PdfFunctionType3, error) {
fun := &PdfFunctionType3{}
var dict *core.PdfObjectDictionary
if indObj, is := obj.(*core.PdfIndirectObject); is {
d, ok := indObj.PdfObject.(*core.PdfObjectDictionary)
if !ok {
return nil, errors.New("type check error")
}
fun.container = indObj
dict = d
} else if d, is := obj.(*core.PdfObjectDictionary); is {
dict = d
} else {
return nil, errors.New("type check error")
}
// Domain
array, has := core.TraceToDirectObject(dict.Get("Domain")).(*core.PdfObjectArray)
if !has {
common.Log.Error("Domain not specified")
return nil, errors.New("required attribute missing or invalid")
}
if len(*array) != 2 {
common.Log.Error("Domain invalid")
return nil, errors.New("invalid domain range")
}
domain, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.Domain = domain
// Range
array, has = core.TraceToDirectObject(dict.Get("Range")).(*core.PdfObjectArray)
if has {
if len(*array)%2 != 0 {
return nil, errors.New("invalid range")
}
rang, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.Range = rang
}
// Functions.
array, has = core.TraceToDirectObject(dict.Get("Functions")).(*core.PdfObjectArray)
if !has {
common.Log.Error("Functions not specified")
return nil, errors.New("required attribute missing or invalid")
}
fun.Functions = []PdfFunction{}
for _, obj := range *array {
subf, err := newPdfFunctionFromPdfObject(obj)
if err != nil {
return nil, err
}
fun.Functions = append(fun.Functions, subf)
}
// Bounds
array, has = core.TraceToDirectObject(dict.Get("Bounds")).(*core.PdfObjectArray)
if !has {
common.Log.Error("Bounds not specified")
return nil, errors.New("required attribute missing or invalid")
}
bounds, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.Bounds = bounds
if len(fun.Bounds) != len(fun.Functions)-1 {
common.Log.Error("Bounds (%d) and num functions (%d) not matching", len(fun.Bounds), len(fun.Functions))
return nil, errors.New("range check")
}
// Encode.
array, has = core.TraceToDirectObject(dict.Get("Encode")).(*core.PdfObjectArray)
if !has {
common.Log.Error("Encode not specified")
return nil, errors.New("required attribute missing or invalid")
}
encode, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.Encode = encode
if len(fun.Encode) != 2*len(fun.Functions) {
common.Log.Error("Len encode (%d) and num functions (%d) not matching up", len(fun.Encode), len(fun.Functions))
return nil, errors.New("range check")
}
return fun, nil
}
func (ftt *PdfFunctionType3) ToPdfObject() core.PdfObject {
dict := core.MakeDict()
dict.Set("FunctionType", core.MakeInteger(3))
// Domain (required).
domainArray := &core.PdfObjectArray{}
for _, val := range ftt.Domain {
domainArray.Append(core.MakeFloat(val))
}
dict.Set("Domain", domainArray)
// Range (required).
if ftt.Range != nil {
rangeArray := &core.PdfObjectArray{}
for _, val := range ftt.Range {
rangeArray.Append(core.MakeFloat(val))
}
dict.Set("Range", rangeArray)
}
// Functions
if ftt.Functions != nil {
fArray := &core.PdfObjectArray{}
for _, fun := range ftt.Functions {
fArray.Append(fun.ToPdfObject())
}
dict.Set("Functions", fArray)
}
// Bounds.
if ftt.Bounds != nil {
bArray := &core.PdfObjectArray{}
for _, val := range ftt.Bounds {
bArray.Append(core.MakeFloat(val))
}
dict.Set("Bounds", bArray)
}
// Encode.
if ftt.Encode != nil {
eArray := &core.PdfObjectArray{}
for _, val := range ftt.Encode {
eArray.Append(core.MakeFloat(val))
}
dict.Set("Encode", eArray)
}
// Wrap in a container if we have one already specified.
if ftt.container != nil {
ftt.container.PdfObject = dict
return ftt.container
} else {
return dict
}
}
// Type 4. Postscript calculator functions.
type PdfFunctionType4 struct {
Domain []float64
Range []float64
Program *ps.PSProgram
executor *ps.PSExecutor
decodedData []byte
container *core.PdfObjectStream
}
// Input [x1 x2 x3]
func (ftt *PdfFunctionType4) Evaluate(xVec []float64) ([]float64, error) {
if ftt.executor == nil {
ftt.executor = ps.NewPSExecutor(ftt.Program)
}
inputs := []ps.PSObject{}
for _, val := range xVec {
inputs = append(inputs, ps.MakeReal(val))
}
outputs, err := ftt.executor.Execute(inputs)
if err != nil {
return nil, err
}
// After execution the outputs are on the stack [y1 ... yM]
// Convert to floats.
yVec, err := ps.PSObjectArrayToFloat64Array(outputs)
if err != nil {
return nil, err
}
return yVec, nil
}
// Load a type 4 function from a PDF stream object.
func newPdfFunctionType4FromStream(stream *core.PdfObjectStream) (*PdfFunctionType4, error) {
fun := &PdfFunctionType4{}
fun.container = stream
dict := stream.PdfObjectDictionary
// Domain
array, has := core.TraceToDirectObject(dict.Get("Domain")).(*core.PdfObjectArray)
if !has {
common.Log.Error("Domain not specified")
return nil, errors.New("required attribute missing or invalid")
}
if len(*array)%2 != 0 {
common.Log.Error("Domain invalid")
return nil, errors.New("invalid domain range")
}
domain, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.Domain = domain
// Range
array, has = core.TraceToDirectObject(dict.Get("Range")).(*core.PdfObjectArray)
if has {
if len(*array)%2 != 0 {
return nil, errors.New("invalid range")
}
rang, err := array.ToFloat64Array()
if err != nil {
return nil, err
}
fun.Range = rang
}
// Program. Decode the program and parse the PS code.
decoded, err := core.DecodeStream(stream)
if err != nil {
return nil, err
}
fun.decodedData = decoded
psParser := ps.NewPSParser([]byte(decoded))
prog, err := psParser.Parse()
if err != nil {
return nil, err
}
fun.Program = prog
return fun, nil
}
func (ftt *PdfFunctionType4) ToPdfObject() core.PdfObject {
container := ftt.container
if container == nil {
ftt.container = &core.PdfObjectStream{}
container = ftt.container
}
dict := core.MakeDict()
dict.Set("FunctionType", core.MakeInteger(4))
// Domain (required).
domainArray := &core.PdfObjectArray{}
for _, val := range ftt.Domain {
domainArray.Append(core.MakeFloat(val))
}
dict.Set("Domain", domainArray)
// Range (required).
rangeArray := &core.PdfObjectArray{}
for _, val := range ftt.Range {
rangeArray.Append(core.MakeFloat(val))
}
dict.Set("Range", rangeArray)
if ftt.decodedData == nil && ftt.Program != nil {
// Update data. This is used for created functions (not parsed ones).
ftt.decodedData = []byte(ftt.Program.String())
}
// TODO: Encode.
// Either here, or automatically later on when writing out.
dict.Set("Length", core.MakeInteger(int64(len(ftt.decodedData))))
container.Stream = ftt.decodedData
container.PdfObjectDictionary = dict
return container
}

294
internal/pdf/model/image.go Normal file
View File

@@ -0,0 +1,294 @@
package model
import (
"errors"
goimage "image"
gocolor "image/color"
"image/draw"
_ "image/gif"
_ "image/png"
"io"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/model/sampling"
)
// Basic representation of an image.
// The colorspace is not specified, but must be known when handling the image.
type Image struct {
Width int64 // The width of the image in samples
Height int64 // The height of the image in samples
BitsPerComponent int64 // The number of bits per color component
ColorComponents int // Color components per pixel
Data []byte // Image data stored as bytes.
// Transparency data: alpha channel.
// Stored in same bits per component as original data with 1 color component.
alphaData []byte // Alpha channel data.
hasAlpha bool // Indicates whether the alpha channel data is available.
decode []float64 // [Dmin Dmax ... values for each color component]
}
// Threshold alpha channel. Set all alpha values below threshold to transparent.
type AlphaMapFunc func(alpha byte) byte
// Allow mapping of alpha data for transformations. Can allow custom filtering of alpha data etc.
func (img Image) AlphaMap(mapFunc AlphaMapFunc) {
for idx, alpha := range img.alphaData {
img.alphaData[idx] = mapFunc(alpha)
}
}
// Convert the raw byte slice into samples which are stored in a uint32 bit array.
// Each sample is represented by BitsPerComponent consecutive bits in the raw data.
func (img *Image) GetSamples() []uint32 {
samples := sampling.ResampleBytes(img.Data, int(img.BitsPerComponent))
expectedLen := int(img.Width) * int(img.Height) * img.ColorComponents
if len(samples) < expectedLen {
// Return error, or fill with 0s?
common.Log.Debug("error: Too few samples (got %d, expecting %d)", len(samples), expectedLen)
return samples
} else if len(samples) > expectedLen {
samples = samples[:expectedLen]
}
return samples
}
// Convert samples to byte-data.
func (img *Image) SetSamples(samples []uint32) {
resampled := sampling.ResampleUint32(samples, int(img.BitsPerComponent), 8)
data := []byte{}
for _, val := range resampled {
data = append(data, byte(val))
}
img.Data = data
}
// Resample resamples the image data converting from current BitsPerComponent to a target BitsPerComponent
// value. Sets the image's BitsPerComponent to the target value following resampling.
//
// For example, converting an 8-bit RGB image to 1-bit grayscale (common for scanned images):
//
// // Convert RGB image to grayscale.
// rgbColorSpace := pdf.NewPdfColorspaceDeviceRGB()
// grayImage, err := rgbColorSpace.ImageToGray(rgbImage)
// if err != nil {
// return err
// }
// // Resample as 1 bit.
// grayImage.Resample(1)
func (img *Image) Resample(targetBitsPerComponent int64) {
samples := img.GetSamples()
// Image data are stored row by row. If the number of bits per row is not a multiple of 8, the end of the
// row needs to be padded with extra bits to fill out the last byte.
// Thus the processing is done on a row by row basis below.
// This one simply resamples the data so that each component has target bits per component...
// So if the original data was 10011010, then will have 1 0 0 1 1 0 1 0... much longer
// The key to resampling is that we need to upsample/downsample,
// i.e. 10011010 >> targetBitsPerComponent
// Current bits: 8, target bits: 1... need to downsample by 8-1 = 7
if targetBitsPerComponent < img.BitsPerComponent {
downsampling := img.BitsPerComponent - targetBitsPerComponent
for i := range samples {
samples[i] >>= uint(downsampling)
}
} else if targetBitsPerComponent > img.BitsPerComponent {
upsampling := targetBitsPerComponent - img.BitsPerComponent
for i := range samples {
samples[i] <<= uint(upsampling)
}
} else {
return
}
// Write out row by row...
data := []byte{}
for i := int64(0); i < img.Height; i++ {
ind1 := i * img.Width * int64(img.ColorComponents)
ind2 := (i+1)*img.Width*int64(img.ColorComponents) - 1
resampled := sampling.ResampleUint32(samples[ind1:ind2], int(targetBitsPerComponent), 8)
for _, val := range resampled {
data = append(data, byte(val))
}
}
img.Data = data
img.BitsPerComponent = int64(targetBitsPerComponent)
}
// Converts the Image to a golang Image structure.
func (im *Image) ToGoImage() (goimage.Image, error) {
common.Log.Trace("Converting to go image")
bounds := goimage.Rect(0, 0, int(im.Width), int(im.Height))
var img core.DrawableImage
switch im.ColorComponents {
case 1:
if im.BitsPerComponent == 16 {
img = goimage.NewGray16(bounds)
} else {
img = goimage.NewGray(bounds)
}
case 3:
if im.BitsPerComponent == 16 {
img = goimage.NewRGBA64(bounds)
} else {
img = goimage.NewRGBA(bounds)
}
case 4:
img = goimage.NewCMYK(bounds)
default:
// XXX? Force RGB convert?
common.Log.Debug("Unsupported number of colors components per sample: %d", im.ColorComponents)
return nil, errors.New("unsupported colors")
}
// Draw the data on the image..
x := 0
y := 0
aidx := 0
samples := im.GetSamples()
//bytesPerColor := colorComponents * int(this.BitsPerComponent) / 8
bytesPerColor := im.ColorComponents
for i := 0; i+bytesPerColor-1 < len(samples); i += bytesPerColor {
var c gocolor.Color
switch im.ColorComponents {
case 1:
if im.BitsPerComponent == 16 {
val := uint16(samples[i])<<8 | uint16(samples[i+1])
c = gocolor.Gray16{val}
} else {
val := uint8(samples[i] & 0xff)
c = gocolor.Gray{val}
}
case 3:
if im.BitsPerComponent == 16 {
r := uint16(samples[i])<<8 | uint16(samples[i+1])
g := uint16(samples[i+2])<<8 | uint16(samples[i+3])
b := uint16(samples[i+4])<<8 | uint16(samples[i+5])
a := uint16(0xffff) // Default: solid (0xffff) whereas transparent=0.
if im.alphaData != nil && len(im.alphaData) > aidx+1 {
a = (uint16(im.alphaData[aidx]) << 8) | uint16(im.alphaData[aidx+1])
aidx += 2
}
c = gocolor.RGBA64{R: r, G: g, B: b, A: a}
} else {
r := uint8(samples[i] & 0xff)
g := uint8(samples[i+1] & 0xff)
b := uint8(samples[i+2] & 0xff)
a := uint8(0xff) // Default: solid (0xff) whereas transparent=0.
if im.alphaData != nil && len(im.alphaData) > aidx {
a = uint8(im.alphaData[aidx])
aidx++
}
c = gocolor.RGBA{R: r, G: g, B: b, A: a}
}
case 4:
c1 := uint8(samples[i] & 0xff)
m1 := uint8(samples[i+1] & 0xff)
y1 := uint8(samples[i+2] & 0xff)
k1 := uint8(samples[i+3] & 0xff)
c = gocolor.CMYK{C: c1, M: m1, Y: y1, K: k1}
}
img.Set(x, y, c)
x++
if x == int(im.Width) {
x = 0
y++
}
}
return img, nil
}
// The ImageHandler interface implements common image loading and processing tasks.
// Implementing as an interface allows for the possibility to use non-standard libraries for faster
// loading and processing of images.
type ImageHandler interface {
// Read any image type and load into a new Image object.
Read(r io.Reader) (*Image, error)
// Load a Image from a standard Go image structure.
NewImageFromGoImage(goimg goimage.Image) (*Image, error)
// Compress an image.
Compress(input *Image, quality int64) (*Image, error)
}
// Default implementation.
type DefaultImageHandler struct{}
// Create a Image from a golang Image.
func (dih DefaultImageHandler) NewImageFromGoImage(goimg goimage.Image) (*Image, error) {
// Speed up jpeg encoding by converting to RGBA first.
// Will not be required once the golang image/jpeg package is optimized.
b := goimg.Bounds()
m := goimage.NewRGBA(goimage.Rect(0, 0, b.Dx(), b.Dy()))
draw.Draw(m, m.Bounds(), goimg, b.Min, draw.Src)
alphaData := []byte{}
hasAlpha := false
data := []byte{}
for i := 0; i < len(m.Pix); i += 4 {
data = append(data, m.Pix[i], m.Pix[i+1], m.Pix[i+2])
alpha := m.Pix[i+3]
if alpha != 255 {
// If all alpha values are 255 (opaque), means that the alpha transparency channel is unnecessary.
hasAlpha = true
}
alphaData = append(alphaData, alpha)
}
imag := Image{}
imag.Width = int64(b.Dx())
imag.Height = int64(b.Dy())
imag.BitsPerComponent = 8 // RGBA colormap
imag.ColorComponents = 3
imag.Data = data // buf.Bytes()
imag.hasAlpha = hasAlpha
if hasAlpha {
imag.alphaData = alphaData
}
return &imag, nil
}
// Reads an image and loads into a new Image object with an RGB
// colormap and 8 bits per component.
func (dih DefaultImageHandler) Read(reader io.Reader) (*Image, error) {
// Load the image with the native implementation.
goimg, _, err := goimage.Decode(reader)
if err != nil {
common.Log.Debug("error decoding file: %s", err)
return nil, err
}
return dih.NewImageFromGoImage(goimg)
}
// To be implemented.
// Should be able to compress in terms of JPEG quality parameter,
// and DPI threshold (need to know bounding area dimensions).
func (DefaultImageHandler) Compress(input *Image, quality int64) (*Image, error) {
return input, nil
}
var ImageHandling ImageHandler = DefaultImageHandler{}
func SetImageHandler(imgHandling ImageHandler) {
ImageHandling = imgHandling
}

View File

@@ -0,0 +1,56 @@
package model
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// A PDFModel is a higher level PDF construct which can be collapsed into a PDF primitive.
// Each PDFModel has an underlying Primitive and vice versa.
// Copies can be made, but care must be taken to do it properly.
type PdfModel interface {
ToPdfObject() core.PdfObject
GetContainingPdfObject() core.PdfObject
}
// The model manager is used to cache Primitive <-> Model mappings where needed.
// In many cases only Model -> Primitive mapping is needed and only a reference to the Primitive
// is stored in the Model. In some cases, the Model needs to be found from the Primitive,
// and that is where the ModelManager can be used (in both directions).
//
// Note that it is not always used, the Primitive <-> Model mapping needs to be registered
// for each time it is used. Thus, it is only used for special cases, commonly where the same
// object is used by two higher level objects. (Example PDF Widgets owned by both Page Annotations,
// and the interactive form - AcroForm).
type ModelManager struct {
primitiveCache map[PdfModel]core.PdfObject
modelCache map[core.PdfObject]PdfModel
}
func NewModelManager() *ModelManager {
mm := ModelManager{}
mm.primitiveCache = map[PdfModel]core.PdfObject{}
mm.modelCache = map[core.PdfObject]PdfModel{}
return &mm
}
// Register (cache) a model to primitive relationship.
func (mm *ModelManager) Register(primitive core.PdfObject, model PdfModel) {
mm.primitiveCache[model] = primitive
mm.modelCache[primitive] = model
}
func (mm *ModelManager) GetPrimitiveFromModel(model PdfModel) core.PdfObject {
primitive, has := mm.primitiveCache[model]
if !has {
return nil
}
return primitive
}
func (mm *ModelManager) GetModelFromPrimitive(primitive core.PdfObject) PdfModel {
model, has := mm.modelCache[primitive]
if !has {
return nil
}
return model
}

View File

@@ -0,0 +1,294 @@
package model
import (
"fmt"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
type PdfOutlineTreeNode struct {
context any // Allow accessing outer structure.
First *PdfOutlineTreeNode
Last *PdfOutlineTreeNode
}
// PDF outline dictionary (Table 152 - p. 376).
type PdfOutline struct {
PdfOutlineTreeNode
Parent *PdfOutlineTreeNode
Count *int64
primitive *core.PdfIndirectObject
}
// Pdf outline item dictionary (Table 153 - pp. 376 - 377).
type PdfOutlineItem struct {
PdfOutlineTreeNode
Title *core.PdfObjectString
Parent *PdfOutlineTreeNode
Prev *PdfOutlineTreeNode
Next *PdfOutlineTreeNode
Count *int64
Dest core.PdfObject
A core.PdfObject
SE core.PdfObject
C core.PdfObject
F core.PdfObject
primitive *core.PdfIndirectObject
}
func NewPdfOutline() *PdfOutline {
outline := &PdfOutline{}
container := &core.PdfIndirectObject{}
container.PdfObject = core.MakeDict()
outline.primitive = container
return outline
}
func NewPdfOutlineTree() *PdfOutline {
outlineTree := NewPdfOutline()
outlineTree.context = &outlineTree
return outlineTree
}
func NewPdfOutlineItem() *PdfOutlineItem {
outlineItem := &PdfOutlineItem{}
container := &core.PdfIndirectObject{}
container.PdfObject = core.MakeDict()
outlineItem.primitive = container
return outlineItem
}
func NewOutlineBookmark(title string, page *core.PdfIndirectObject) *PdfOutlineItem {
bookmark := PdfOutlineItem{}
bookmark.context = &bookmark
bookmark.Title = core.MakeString(title)
destArray := core.PdfObjectArray{}
destArray = append(destArray, page)
destArray = append(destArray, core.MakeName("Fit"))
bookmark.Dest = &destArray
return &bookmark
}
// Does not traverse the tree.
func newPdfOutlineFromIndirectObject(container *core.PdfIndirectObject) (*PdfOutline, error) {
dict, isDict := container.PdfObject.(*core.PdfObjectDictionary)
if !isDict {
return nil, fmt.Errorf("outline object not a dictionary")
}
outline := PdfOutline{}
outline.primitive = container
outline.context = &outline
if obj := dict.Get("Type"); obj != nil {
typeVal, ok := obj.(*core.PdfObjectName)
if ok {
if *typeVal != "Outlines" {
common.Log.Debug("error Type != Outlines (%s)", *typeVal)
// Should be "Outlines" if there, but some files have other types
// Log as an error but do not quit.
// Might be a good idea to log this kind of deviation from the standard separately.
}
}
}
if obj := dict.Get("Count"); obj != nil {
// This should always be an integer, but in a few cases has been a float.
count, err := getNumberAsInt64(obj)
if err != nil {
return nil, err
}
outline.Count = &count
}
return &outline, nil
}
// Does not traverse the tree.
func (pr *PdfReader) newPdfOutlineItemFromIndirectObject(container *core.PdfIndirectObject) (*PdfOutlineItem, error) {
dict, isDict := container.PdfObject.(*core.PdfObjectDictionary)
if !isDict {
return nil, fmt.Errorf("outline object not a dictionary")
}
item := PdfOutlineItem{}
item.primitive = container
item.context = &item
// Title (required).
obj := dict.Get("Title")
if obj == nil {
return nil, fmt.Errorf("missing Title from Outline Item (required)")
}
obj, err := pr.traceToObject(obj)
if err != nil {
return nil, err
}
title, ok := core.TraceToDirectObject(obj).(*core.PdfObjectString)
if !ok {
return nil, fmt.Errorf("title not a string (%T)", obj)
}
item.Title = title
// Count (optional).
if obj := dict.Get("Count"); obj != nil {
countVal, ok := obj.(*core.PdfObjectInteger)
if !ok {
return nil, fmt.Errorf("count not an integer (%T)", obj)
}
count := int64(*countVal)
item.Count = &count
}
// Other keys.
if obj := dict.Get("Dest"); obj != nil {
item.Dest, err = pr.traceToObject(obj)
if err != nil {
return nil, err
}
err := pr.traverseObjectData(item.Dest)
if err != nil {
return nil, err
}
}
if obj := dict.Get("A"); obj != nil {
item.A, err = pr.traceToObject(obj)
if err != nil {
return nil, err
}
err := pr.traverseObjectData(item.A)
if err != nil {
return nil, err
}
}
if obj := dict.Get("SE"); obj != nil {
// XXX: To add structure element support.
// Currently not supporting structure elements.
item.SE = nil
}
if obj := dict.Get("C"); obj != nil {
item.C, err = pr.traceToObject(obj)
if err != nil {
return nil, err
}
}
if obj := dict.Get("F"); obj != nil {
item.F, err = pr.traceToObject(obj)
if err != nil {
return nil, err
}
}
return &item, nil
}
// Get the outer object of the tree node (Outline or OutlineItem).
func (n *PdfOutlineTreeNode) getOuter() PdfModel {
if outline, isOutline := n.context.(*PdfOutline); isOutline {
return outline
}
if outlineItem, isOutlineItem := n.context.(*PdfOutlineItem); isOutlineItem {
return outlineItem
}
common.Log.Debug("error Invalid outline tree node item") // Should never happen.
return nil
}
func (pot *PdfOutlineTreeNode) GetContainingPdfObject() core.PdfObject {
return pot.getOuter().GetContainingPdfObject()
}
func (pot *PdfOutlineTreeNode) ToPdfObject() core.PdfObject {
return pot.getOuter().ToPdfObject()
}
func (po *PdfOutline) GetContainingPdfObject() core.PdfObject {
return po.primitive
}
// Recursively build the Outline tree PDF object.
func (po *PdfOutline) ToPdfObject() core.PdfObject {
container := po.primitive
dict := container.PdfObject.(*core.PdfObjectDictionary)
dict.Set("Type", core.MakeName("Outlines"))
if po.First != nil {
dict.Set("First", po.First.ToPdfObject())
}
if po.Last != nil {
dict.Set("Last", po.Last.getOuter().GetContainingPdfObject())
//PdfObjectConverterCache[this.Last.getOuter()]
}
if po.Parent != nil {
dict.Set("Parent", po.Parent.getOuter().GetContainingPdfObject())
}
return container
}
func (poi *PdfOutlineItem) GetContainingPdfObject() core.PdfObject {
return poi.primitive
}
// Outline item.
// Recursively build the Outline tree PDF object.
func (poi *PdfOutlineItem) ToPdfObject() core.PdfObject {
container := poi.primitive
dict := container.PdfObject.(*core.PdfObjectDictionary)
dict.Set("Title", poi.Title)
if poi.A != nil {
dict.Set("A", poi.A)
}
if obj := dict.Get("SE"); obj != nil {
// XXX: Currently not supporting structure element hierarchy.
// Remove it.
dict.Remove("SE")
// delete(*dict, "SE")
}
if poi.C != nil {
dict.Set("C", poi.C)
}
if poi.Dest != nil {
dict.Set("Dest", poi.Dest)
}
if poi.F != nil {
dict.Set("F", poi.F)
}
if poi.Count != nil {
dict.Set("Count", core.MakeInteger(*poi.Count))
}
if poi.Next != nil {
dict.Set("Next", poi.Next.ToPdfObject())
}
if poi.First != nil {
dict.Set("First", poi.First.ToPdfObject())
}
if poi.Prev != nil {
dict.Set("Prev", poi.Prev.getOuter().GetContainingPdfObject())
}
if poi.Last != nil {
dict.Set("Last", poi.Last.getOuter().GetContainingPdfObject())
}
if poi.Parent != nil {
dict.Set("Parent", poi.Parent.getOuter().GetContainingPdfObject())
}
return container
}

908
internal/pdf/model/page.go Normal file
View File

@@ -0,0 +1,908 @@
package model
import (
"errors"
"fmt"
"strings"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// PDF page object (7.7.3.3 - Table 30).
type PdfPage struct {
Parent core.PdfObject
LastModified *PdfDate
Resources *PdfPageResources
CropBox *PdfRectangle
MediaBox *PdfRectangle
BleedBox *PdfRectangle
TrimBox *PdfRectangle
ArtBox *PdfRectangle
BoxColorInfo core.PdfObject
Contents core.PdfObject
Rotate *int64
Group core.PdfObject
Thumb core.PdfObject
B core.PdfObject
Dur core.PdfObject
Trans core.PdfObject
AA core.PdfObject
Metadata core.PdfObject
PieceInfo core.PdfObject
StructParents core.PdfObject
ID core.PdfObject
PZ core.PdfObject
SeparationInfo core.PdfObject
Tabs core.PdfObject
TemplateInstantiated core.PdfObject
PresSteps core.PdfObject
UserUnit core.PdfObject
VP core.PdfObject
Annotations []*PdfAnnotation
// Primitive container.
pageDict *core.PdfObjectDictionary
primitive *core.PdfIndirectObject
}
func NewPdfPage() *PdfPage {
page := PdfPage{}
page.pageDict = core.MakeDict()
container := core.PdfIndirectObject{}
container.PdfObject = page.pageDict
page.primitive = &container
return &page
}
func (pp *PdfPage) setContainer(container *core.PdfIndirectObject) {
container.PdfObject = pp.pageDict
pp.primitive = container
}
func (pp *PdfPage) Duplicate() *PdfPage {
dup := *pp
dup.pageDict = core.MakeDict()
dup.primitive = core.MakeIndirectObject(dup.pageDict)
return &dup
}
// Build a PdfPage based on the underlying dictionary.
// Used in loading existing PDF files.
// Note that a new container is created (indirect object).
func (reader *PdfReader) newPdfPageFromDict(p *core.PdfObjectDictionary) (*PdfPage, error) {
page := NewPdfPage()
page.pageDict = p //XXX?
d := *p
pType, ok := d.Get("Type").(*core.PdfObjectName)
if !ok {
return nil, errors.New("missing/Invalid Page dictionary Type")
}
if *pType != "Page" {
return nil, errors.New("page dictionary Type != Page")
}
if obj := d.Get("Parent"); obj != nil {
page.Parent = obj
}
if obj := d.Get("LastModified"); obj != nil {
var err error
obj, err = reader.traceToObject(obj)
if err != nil {
return nil, err
}
strObj, ok := core.TraceToDirectObject(obj).(*core.PdfObjectString)
if !ok {
return nil, errors.New("page dictionary LastModified != string")
}
lastmod, err := NewPdfDate(string(*strObj))
if err != nil {
return nil, err
}
page.LastModified = &lastmod
}
if obj := d.Get("Resources"); obj != nil {
var err error
obj, err = reader.traceToObject(obj)
if err != nil {
return nil, err
}
dict, ok := core.TraceToDirectObject(obj).(*core.PdfObjectDictionary)
if !ok {
return nil, fmt.Errorf("invalid resource dictionary (%T)", obj)
}
page.Resources, err = NewPdfPageResourcesFromDict(dict)
if err != nil {
return nil, err
}
} else {
// If Resources not explicitly defined, look up the tree (Parent objects) using
// the getResources() function. Resources should always be accessible.
resources, err := page.getResources()
if err != nil {
return nil, err
}
if resources == nil {
resources = NewPdfPageResources()
}
page.Resources = resources
}
if obj := d.Get("MediaBox"); obj != nil {
var err error
obj, err = reader.traceToObject(obj)
if err != nil {
return nil, err
}
boxArr, ok := core.TraceToDirectObject(obj).(*core.PdfObjectArray)
if !ok {
return nil, errors.New("page MediaBox not an array")
}
page.MediaBox, err = NewPdfRectangle(*boxArr)
if err != nil {
return nil, err
}
}
if obj := d.Get("CropBox"); obj != nil {
var err error
obj, err = reader.traceToObject(obj)
if err != nil {
return nil, err
}
boxArr, ok := core.TraceToDirectObject(obj).(*core.PdfObjectArray)
if !ok {
return nil, errors.New("page CropBox not an array")
}
page.CropBox, err = NewPdfRectangle(*boxArr)
if err != nil {
return nil, err
}
}
if obj := d.Get("BleedBox"); obj != nil {
var err error
obj, err = reader.traceToObject(obj)
if err != nil {
return nil, err
}
boxArr, ok := core.TraceToDirectObject(obj).(*core.PdfObjectArray)
if !ok {
return nil, errors.New("page BleedBox not an array")
}
page.BleedBox, err = NewPdfRectangle(*boxArr)
if err != nil {
return nil, err
}
}
if obj := d.Get("TrimBox"); obj != nil {
var err error
obj, err = reader.traceToObject(obj)
if err != nil {
return nil, err
}
boxArr, ok := core.TraceToDirectObject(obj).(*core.PdfObjectArray)
if !ok {
return nil, errors.New("page TrimBox not an array")
}
page.TrimBox, err = NewPdfRectangle(*boxArr)
if err != nil {
return nil, err
}
}
if obj := d.Get("ArtBox"); obj != nil {
var err error
obj, err = reader.traceToObject(obj)
if err != nil {
return nil, err
}
boxArr, ok := core.TraceToDirectObject(obj).(*core.PdfObjectArray)
if !ok {
return nil, errors.New("page ArtBox not an array")
}
page.ArtBox, err = NewPdfRectangle(*boxArr)
if err != nil {
return nil, err
}
}
if obj := d.Get("BoxColorInfo"); obj != nil {
page.BoxColorInfo = obj
}
if obj := d.Get("Contents"); obj != nil {
page.Contents = obj
}
if obj := d.Get("Rotate"); obj != nil {
var err error
obj, err = reader.traceToObject(obj)
if err != nil {
return nil, err
}
iObj, ok := core.TraceToDirectObject(obj).(*core.PdfObjectInteger)
if !ok {
return nil, errors.New("invalid Page Rotate object")
}
iVal := int64(*iObj)
page.Rotate = &iVal
}
if obj := d.Get("Group"); obj != nil {
page.Group = obj
}
if obj := d.Get("Thumb"); obj != nil {
page.Thumb = obj
}
if obj := d.Get("B"); obj != nil {
page.B = obj
}
if obj := d.Get("Dur"); obj != nil {
page.Dur = obj
}
if obj := d.Get("Trans"); obj != nil {
page.Trans = obj
}
//if obj := d.Get("Annots"); obj != nil {
// page.Annots = obj
//}
if obj := d.Get("AA"); obj != nil {
page.AA = obj
}
if obj := d.Get("Metadata"); obj != nil {
page.Metadata = obj
}
if obj := d.Get("PieceInfo"); obj != nil {
page.PieceInfo = obj
}
if obj := d.Get("StructParents"); obj != nil {
page.StructParents = obj
}
if obj := d.Get("ID"); obj != nil {
page.ID = obj
}
if obj := d.Get("PZ"); obj != nil {
page.PZ = obj
}
if obj := d.Get("SeparationInfo"); obj != nil {
page.SeparationInfo = obj
}
if obj := d.Get("Tabs"); obj != nil {
page.Tabs = obj
}
if obj := d.Get("TemplateInstantiated"); obj != nil {
page.TemplateInstantiated = obj
}
if obj := d.Get("PresSteps"); obj != nil {
page.PresSteps = obj
}
if obj := d.Get("UserUnit"); obj != nil {
page.UserUnit = obj
}
if obj := d.Get("VP"); obj != nil {
page.VP = obj
}
var err error
page.Annotations, err = reader.LoadAnnotations(&d)
if err != nil {
return nil, err
}
return page, nil
}
func (reader *PdfReader) LoadAnnotations(d *core.PdfObjectDictionary) ([]*PdfAnnotation, error) {
annotsObj := d.Get("Annots")
if annotsObj == nil {
return nil, nil
}
var err error
annotsObj, err = reader.traceToObject(annotsObj)
if err != nil {
return nil, err
}
annotsArr, ok := core.TraceToDirectObject(annotsObj).(*core.PdfObjectArray)
if !ok {
return nil, fmt.Errorf("annots not an array")
}
annotations := []*PdfAnnotation{}
for _, obj := range *annotsArr {
obj, err = reader.traceToObject(obj)
if err != nil {
return nil, err
}
// Technically all annotation dictionaries should be inside indirect objects.
// In reality, sometimes the annotation dictionary is inline within the Annots array.
if _, isNull := obj.(*core.PdfObjectNull); isNull {
// Can safely ignore.
continue
}
annotDict, isDict := obj.(*core.PdfObjectDictionary)
indirectObj, isIndirect := obj.(*core.PdfIndirectObject)
if isDict {
// Create a container; indirect object; around the dictionary.
indirectObj = &core.PdfIndirectObject{}
indirectObj.PdfObject = annotDict
} else {
if !isIndirect {
return nil, fmt.Errorf("annotation not in an indirect object")
}
}
annot, err := reader.newPdfAnnotationFromIndirectObject(indirectObj)
if err != nil {
return nil, err
}
annotations = append(annotations, annot)
}
return annotations, nil
}
// Get the inheritable media box value, either from the page
// or a higher up page/pages struct.
func (pp *PdfPage) GetMediaBox() (*PdfRectangle, error) {
if pp.MediaBox != nil {
return pp.MediaBox, nil
}
node := pp.Parent
for node != nil {
dictObj, ok := node.(*core.PdfIndirectObject)
if !ok {
return nil, errors.New("invalid parent object")
}
dict, ok := dictObj.PdfObject.(*core.PdfObjectDictionary)
if !ok {
return nil, errors.New("invalid parent objects dictionary")
}
if obj := dict.Get("MediaBox"); obj != nil {
arr, ok := obj.(*core.PdfObjectArray)
if !ok {
return nil, errors.New("invalid media box")
}
rect, err := NewPdfRectangle(*arr)
if err != nil {
return nil, err
}
return rect, nil
}
node = dict.Get("Parent")
}
return nil, errors.New("media box not defined")
}
// Get the inheritable resources, either from the page or or a higher up page/pages struct.
func (pp *PdfPage) getResources() (*PdfPageResources, error) {
if pp.Resources != nil {
return pp.Resources, nil
}
node := pp.Parent
for node != nil {
dictObj, ok := node.(*core.PdfIndirectObject)
if !ok {
return nil, errors.New("invalid parent object")
}
dict, ok := dictObj.PdfObject.(*core.PdfObjectDictionary)
if !ok {
return nil, errors.New("invalid parent objects dictionary")
}
if obj := dict.Get("Resources"); obj != nil {
prDict, ok := core.TraceToDirectObject(obj).(*core.PdfObjectDictionary)
if !ok {
return nil, errors.New("invalid resource dict")
}
resources, err := NewPdfPageResourcesFromDict(prDict)
if err != nil {
return nil, err
}
return resources, nil
}
// Keep moving up the tree...
node = dict.Get("Parent")
}
// No resources defined...
return nil, nil
}
// Convert the Page to a PDF object dictionary.
func (pp *PdfPage) GetPageDict() *core.PdfObjectDictionary {
p := pp.pageDict
p.Set("Type", core.MakeName("Page"))
p.Set("Parent", pp.Parent)
if pp.LastModified != nil {
p.Set("LastModified", pp.LastModified.ToPdfObject())
}
if pp.Resources != nil {
p.Set("Resources", pp.Resources.ToPdfObject())
}
if pp.CropBox != nil {
p.Set("CropBox", pp.CropBox.ToPdfObject())
}
if pp.MediaBox != nil {
p.Set("MediaBox", pp.MediaBox.ToPdfObject())
}
if pp.BleedBox != nil {
p.Set("BleedBox", pp.BleedBox.ToPdfObject())
}
if pp.TrimBox != nil {
p.Set("TrimBox", pp.TrimBox.ToPdfObject())
}
if pp.ArtBox != nil {
p.Set("ArtBox", pp.ArtBox.ToPdfObject())
}
p.SetIfNotNil("BoxColorInfo", pp.BoxColorInfo)
p.SetIfNotNil("Contents", pp.Contents)
if pp.Rotate != nil {
p.Set("Rotate", core.MakeInteger(*pp.Rotate))
}
p.SetIfNotNil("Group", pp.Group)
p.SetIfNotNil("Thumb", pp.Thumb)
p.SetIfNotNil("B", pp.B)
p.SetIfNotNil("Dur", pp.Dur)
p.SetIfNotNil("Trans", pp.Trans)
p.SetIfNotNil("AA", pp.AA)
p.SetIfNotNil("Metadata", pp.Metadata)
p.SetIfNotNil("PieceInfo", pp.PieceInfo)
p.SetIfNotNil("StructParents", pp.StructParents)
p.SetIfNotNil("ID", pp.ID)
p.SetIfNotNil("PZ", pp.PZ)
p.SetIfNotNil("SeparationInfo", pp.SeparationInfo)
p.SetIfNotNil("Tabs", pp.Tabs)
p.SetIfNotNil("TemplateInstantiated", pp.TemplateInstantiated)
p.SetIfNotNil("PresSteps", pp.PresSteps)
p.SetIfNotNil("UserUnit", pp.UserUnit)
p.SetIfNotNil("VP", pp.VP)
if pp.Annotations != nil {
arr := core.PdfObjectArray{}
for _, annot := range pp.Annotations {
if subannot := annot.GetContext(); subannot != nil {
arr = append(arr, subannot.ToPdfObject())
} else {
// Generic annotation dict (without subtype).
arr = append(arr, annot.ToPdfObject())
}
}
p.Set("Annots", &arr)
}
return p
}
// Get the page object as an indirect objects. Wraps the Page
// dictionary into an indirect object.
func (pp *PdfPage) GetPageAsIndirectObject() *core.PdfIndirectObject {
return pp.primitive
}
func (pp *PdfPage) GetContainingPdfObject() core.PdfObject {
return pp.primitive
}
func (pp *PdfPage) ToPdfObject() core.PdfObject {
container := pp.primitive
pp.GetPageDict() // update.
return container
}
// Add an image to the XObject resources.
func (pp *PdfPage) AddImageResource(name core.PdfObjectName, ximg *XObjectImage) error {
var xresDict *core.PdfObjectDictionary
if pp.Resources.XObject == nil {
xresDict = core.MakeDict()
pp.Resources.XObject = xresDict
} else {
var ok bool
xresDict, ok = (pp.Resources.XObject).(*core.PdfObjectDictionary)
if !ok {
return errors.New("invalid xres dict type")
}
}
// Make a stream object container.
xresDict.Set(name, ximg.ToPdfObject())
return nil
}
// Check if has XObject resource by name.
func (pp *PdfPage) HasXObjectByName(name core.PdfObjectName) bool {
xresDict, has := pp.Resources.XObject.(*core.PdfObjectDictionary)
if !has {
return false
}
if obj := xresDict.Get(name); obj != nil {
return true
} else {
return false
}
}
// Get XObject by name.
func (pp *PdfPage) GetXObjectByName(name core.PdfObjectName) (core.PdfObject, bool) {
xresDict, has := pp.Resources.XObject.(*core.PdfObjectDictionary)
if !has {
return nil, false
}
if obj := xresDict.Get(name); obj != nil {
return obj, true
} else {
return nil, false
}
}
// Check if has font resource by name.
func (pp *PdfPage) HasFontByName(name core.PdfObjectName) bool {
fontDict, has := pp.Resources.Font.(*core.PdfObjectDictionary)
if !has {
return false
}
if obj := fontDict.Get(name); obj != nil {
return true
} else {
return false
}
}
// Check if ExtGState name is available.
func (pp *PdfPage) HasExtGState(name core.PdfObjectName) bool {
if pp.Resources == nil {
return false
}
if pp.Resources.ExtGState == nil {
return false
}
egsDict, ok := core.TraceToDirectObject(pp.Resources.ExtGState).(*core.PdfObjectDictionary)
if !ok {
common.Log.Debug("Expected ExtGState dictionary is not a dictionary: %v", core.TraceToDirectObject(pp.Resources.ExtGState))
return false
}
// Update the dictionary.
obj := egsDict.Get(name)
has := obj != nil
return has
}
// Add a graphics state to the XObject resources.
func (pp *PdfPage) AddExtGState(name core.PdfObjectName, egs *core.PdfObjectDictionary) error {
if pp.Resources == nil {
//this.Resources = &PdfPageResources{}
pp.Resources = NewPdfPageResources()
}
if pp.Resources.ExtGState == nil {
pp.Resources.ExtGState = core.MakeDict()
}
egsDict, ok := core.TraceToDirectObject(pp.Resources.ExtGState).(*core.PdfObjectDictionary)
if !ok {
common.Log.Debug("Expected ExtGState dictionary is not a dictionary: %v", core.TraceToDirectObject(pp.Resources.ExtGState))
return errors.New("type check error")
}
egsDict.Set(name, egs)
return nil
}
// Add a font dictionary to the Font resources.
func (pp *PdfPage) AddFont(name core.PdfObjectName, font core.PdfObject) error {
if pp.Resources == nil {
pp.Resources = NewPdfPageResources()
}
if pp.Resources.Font == nil {
pp.Resources.Font = core.MakeDict()
}
fontDict, ok := core.TraceToDirectObject(pp.Resources.Font).(*core.PdfObjectDictionary)
if !ok {
common.Log.Debug("Expected font dictionary is not a dictionary: %v", core.TraceToDirectObject(pp.Resources.Font))
return errors.New("type check error")
}
// Update the dictionary.
fontDict.Set(name, font)
return nil
}
type WatermarkImageOptions struct {
Alpha float64
FitToWidth bool
PreserveAspectRatio bool
}
// Add a watermark to the page.
func (pp *PdfPage) AddWatermarkImage(ximg *XObjectImage, opt WatermarkImageOptions) error {
// Page dimensions.
bbox, err := pp.GetMediaBox()
if err != nil {
return err
}
pWidth := bbox.Urx - bbox.Llx
pHeight := bbox.Ury - bbox.Lly
wWidth := float64(*ximg.Width)
xOffset := (float64(pWidth) - float64(wWidth)) / 2
if opt.FitToWidth {
wWidth = pWidth
xOffset = 0
}
wHeight := pHeight
yOffset := float64(0)
if opt.PreserveAspectRatio {
wHeight = wWidth * float64(*ximg.Height) / float64(*ximg.Width)
yOffset = (pHeight - wHeight) / 2
}
if pp.Resources == nil {
pp.Resources = NewPdfPageResources()
}
// Find available image name for this page.
i := 0
imgName := core.PdfObjectName(fmt.Sprintf("Imw%d", i))
for pp.Resources.HasXObjectByName(imgName) {
i++
imgName = core.PdfObjectName(fmt.Sprintf("Imw%d", i))
}
err = pp.AddImageResource(imgName, ximg)
if err != nil {
return err
}
i = 0
gsName := core.PdfObjectName(fmt.Sprintf("GS%d", i))
for pp.HasExtGState(gsName) {
i++
gsName = core.PdfObjectName(fmt.Sprintf("GS%d", i))
}
gs0 := core.MakeDict()
gs0.Set("BM", core.MakeName("Normal"))
gs0.Set("CA", core.MakeFloat(opt.Alpha))
gs0.Set("ca", core.MakeFloat(opt.Alpha))
err = pp.AddExtGState(gsName, gs0)
if err != nil {
return err
}
contentStr := fmt.Sprintf("q\n"+
"/%s gs\n"+
"%.0f 0 0 %.0f %.4f %.4f cm\n"+
"/%s Do\n"+
"Q", gsName, wWidth, wHeight, xOffset, yOffset, imgName)
pp.AddContentStreamByString(contentStr)
return nil
}
// Add content stream by string. Puts the content string into a stream
// object and points the content stream towards it.
func (pp *PdfPage) AddContentStreamByString(contentStr string) {
stream := core.PdfObjectStream{}
sDict := core.MakeDict()
stream.PdfObjectDictionary = sDict
sDict.Set("Length", core.MakeInteger(int64(len(contentStr))))
stream.Stream = []byte(contentStr)
if pp.Contents == nil {
// If not set, place it directly.
pp.Contents = &stream
} else if contArray, isArray := core.TraceToDirectObject(pp.Contents).(*core.PdfObjectArray); isArray {
// If an array of content streams, append it.
*contArray = append(*contArray, &stream)
} else {
// Only 1 element in place. Wrap inside a new array and add the new one.
contArray := core.PdfObjectArray{}
contArray = append(contArray, pp.Contents)
contArray = append(contArray, &stream)
pp.Contents = &contArray
}
}
// Set the content streams based on a string array. Will make 1 object stream
// for each string and reference from the page Contents. Each stream will be
// encoded using the encoding specified by the StreamEncoder, if empty, will
// use identity encoding (raw data).
func (pp *PdfPage) SetContentStreams(cStreams []string, encoder core.StreamEncoder) error {
if len(cStreams) == 0 {
pp.Contents = nil
return nil
}
// If encoding is not set, use default raw encoder.
if encoder == nil {
encoder = core.NewRawEncoder()
}
streamObjs := []*core.PdfObjectStream{}
for _, cStream := range cStreams {
stream := &core.PdfObjectStream{}
// Make a new stream dict based on the encoding parameters.
sDict := encoder.MakeStreamDict()
encoded, err := encoder.EncodeBytes([]byte(cStream))
if err != nil {
return err
}
sDict.Set("Length", core.MakeInteger(int64(len(encoded))))
stream.PdfObjectDictionary = sDict
stream.Stream = []byte(encoded)
streamObjs = append(streamObjs, stream)
}
// Set the page contents.
// Point directly to the object stream if only one, or embed in an array.
if len(streamObjs) == 1 {
pp.Contents = streamObjs[0]
} else {
contArray := core.PdfObjectArray{}
for _, streamObj := range streamObjs {
contArray = append(contArray, streamObj)
}
pp.Contents = &contArray
}
return nil
}
func getContentStreamAsString(cstreamObj core.PdfObject) (string, error) {
if cstream, ok := core.TraceToDirectObject(cstreamObj).(*core.PdfObjectString); ok {
return string(*cstream), nil
}
if cstream, ok := core.TraceToDirectObject(cstreamObj).(*core.PdfObjectStream); ok {
buf, err := core.DecodeStream(cstream)
if err != nil {
return "", err
}
return string(buf), nil
}
return "", fmt.Errorf("invalid content stream object holder (%T)", core.TraceToDirectObject(cstreamObj))
}
// Get Content Stream as an array of strings.
func (pp *PdfPage) GetContentStreams() ([]string, error) {
if pp.Contents == nil {
return nil, nil
}
contents := core.TraceToDirectObject(pp.Contents)
if contArray, isArray := contents.(*core.PdfObjectArray); isArray {
// If an array of content streams, append it.
cstreams := []string{}
for _, cstreamObj := range *contArray {
cstreamStr, err := getContentStreamAsString(cstreamObj)
if err != nil {
return nil, err
}
cstreams = append(cstreams, cstreamStr)
}
return cstreams, nil
} else {
// Only 1 element in place. Wrap inside a new array and add the new one.
cstreamStr, err := getContentStreamAsString(contents)
if err != nil {
return nil, err
}
cstreams := []string{cstreamStr}
return cstreams, nil
}
}
// Get all the content streams for a page as one string.
func (pp *PdfPage) GetAllContentStreams() (string, error) {
cstreams, err := pp.GetContentStreams()
if err != nil {
return "", err
}
return strings.Join(cstreams, " "), nil
}
// Needs to have matching name and colorspace map entry. The Names define the order.
type PdfPageResourcesColorspaces struct {
Names []string
Colorspaces map[string]PdfColorspace
container *core.PdfIndirectObject
}
func NewPdfPageResourcesColorspaces() *PdfPageResourcesColorspaces {
colorspaces := &PdfPageResourcesColorspaces{}
colorspaces.Names = []string{}
colorspaces.Colorspaces = map[string]PdfColorspace{}
colorspaces.container = &core.PdfIndirectObject{}
return colorspaces
}
// Set the colorspace corresponding to key. Add to Names if not set.
func (pp *PdfPageResourcesColorspaces) Set(key core.PdfObjectName, val PdfColorspace) {
if _, has := pp.Colorspaces[string(key)]; !has {
pp.Names = append(pp.Names, string(key))
}
pp.Colorspaces[string(key)] = val
}
func newPdfPageResourcesColorspacesFromPdfObject(obj core.PdfObject) (*PdfPageResourcesColorspaces, error) {
colorspaces := &PdfPageResourcesColorspaces{}
if indObj, isIndirect := obj.(*core.PdfIndirectObject); isIndirect {
colorspaces.container = indObj
obj = indObj.PdfObject
}
dict, ok := obj.(*core.PdfObjectDictionary)
if !ok {
return nil, errors.New("CS attribute type error")
}
colorspaces.Names = []string{}
colorspaces.Colorspaces = map[string]PdfColorspace{}
for _, csName := range dict.Keys() {
csObj := dict.Get(csName)
colorspaces.Names = append(colorspaces.Names, string(csName))
cs, err := NewPdfColorspaceFromPdfObject(csObj)
if err != nil {
return nil, err
}
colorspaces.Colorspaces[string(csName)] = cs
}
return colorspaces, nil
}
func (pp *PdfPageResourcesColorspaces) ToPdfObject() core.PdfObject {
dict := core.MakeDict()
for _, csName := range pp.Names {
dict.Set(core.PdfObjectName(csName), pp.Colorspaces[csName].ToPdfObject())
}
if pp.container != nil {
pp.container.PdfObject = dict
return pp.container
}
return dict
}

View File

@@ -0,0 +1,420 @@
package model
import (
"errors"
"fmt"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// A PdfPattern can represent a Pattern, either a tiling pattern or a shading pattern.
// Note that all patterns shall be treated as colours; a Pattern colour space shall be established with the CS or cs
// operator just like other colour spaces, and a particular pattern shall be installed as the current colour with the
// SCN or scn operator.
type PdfPattern struct {
// Type: Pattern
PatternType int64
context PdfModel // The sub pattern, either PdfTilingPattern (Type 1) or PdfShadingPattern (Type 2).
container core.PdfObject
}
func (pp *PdfPattern) GetContainingPdfObject() core.PdfObject {
return pp.container
}
// Context in this case is a reference to the subpattern entry: either PdfTilingPattern or PdfShadingPattern.
func (pp *PdfPattern) GetContext() PdfModel {
return pp.context
}
// Set the sub pattern (context). Either PdfTilingPattern or PdfShadingPattern.
func (pp *PdfPattern) SetContext(ctx PdfModel) {
pp.context = ctx
}
func (pp *PdfPattern) IsTiling() bool {
return pp.PatternType == 1
}
func (pp *PdfPattern) IsShading() bool {
return pp.PatternType == 2
}
// Check with IsTiling() prior to using this to ensure is a tiling pattern.
func (pp *PdfPattern) GetAsTilingPattern() *PdfTilingPattern {
return pp.context.(*PdfTilingPattern)
}
// Check with IsShading() prior to using this, to ensure is a shading pattern.
func (pp *PdfPattern) GetAsShadingPattern() *PdfShadingPattern {
return pp.context.(*PdfShadingPattern)
}
// A Tiling pattern consists of repetitions of a pattern cell with defined intervals.
// It is a type 1 pattern. (PatternType = 1).
// A tiling pattern is represented by a stream object, where the stream content is
// a content stream that describes the pattern cell.
type PdfTilingPattern struct {
*PdfPattern
PaintType *core.PdfObjectInteger // Colored or uncolored tiling pattern.
TilingType *core.PdfObjectInteger // Constant spacing, no distortion or constant spacing/faster tiling.
BBox *PdfRectangle
XStep *core.PdfObjectFloat
YStep *core.PdfObjectFloat
Resources *PdfPageResources
Matrix *core.PdfObjectArray // Pattern matrix (6 numbers).
}
func (ptp *PdfTilingPattern) IsColored() bool {
if ptp.PaintType != nil && *ptp.PaintType == 1 {
return true
} else {
return false
}
}
// GetContentStream returns the pattern cell's content stream
func (ptp *PdfTilingPattern) GetContentStream() ([]byte, error) {
decoded, _, err := ptp.GetContentStreamWithEncoder()
return decoded, err
}
// GetContentStreamWithEncoder returns the pattern cell's content stream and its encoder
// TODO (v3): Change GetContentStreamWithEncoder to GetContentStream
func (ptp *PdfTilingPattern) GetContentStreamWithEncoder() ([]byte, core.StreamEncoder, error) {
streamObj, ok := ptp.container.(*core.PdfObjectStream)
if !ok {
common.Log.Debug("Tiling pattern container not a stream (got %T)", ptp.container)
return nil, nil, ErrTypeError
}
decoded, err := core.DecodeStream(streamObj)
if err != nil {
common.Log.Debug("Failed decoding stream, err: %v", err)
return nil, nil, err
}
encoder, err := core.NewEncoderFromStream(streamObj)
if err != nil {
common.Log.Debug("Failed finding decoding encoder: %v", err)
return nil, nil, err
}
return decoded, encoder, nil
}
// Set the pattern cell's content stream.
func (ptp *PdfTilingPattern) SetContentStream(content []byte, encoder core.StreamEncoder) error {
streamObj, ok := ptp.container.(*core.PdfObjectStream)
if !ok {
common.Log.Debug("Tiling pattern container not a stream (got %T)", ptp.container)
return ErrTypeError
}
// If encoding is not set, use raw encoder.
if encoder == nil {
encoder = core.NewRawEncoder()
}
streamDict := streamObj.PdfObjectDictionary
// Make a new stream dict based on the encoding parameters.
encDict := encoder.MakeStreamDict()
// Merge the encoding dict into the stream dict.
streamDict.Merge(encDict)
encoded, err := encoder.EncodeBytes(content)
if err != nil {
return err
}
// Update length.
streamDict.Set("Length", core.MakeInteger(int64(len(encoded))))
streamObj.Stream = []byte(encoded)
return nil
}
// Shading patterns provide a smooth transition between colors across an area to be painted, i.e.
// color(x,y) = f(x,y) at each point.
// It is a type 2 pattern (PatternType = 2).
type PdfShadingPattern struct {
*PdfPattern
Shading *PdfShading
Matrix *core.PdfObjectArray
ExtGState core.PdfObject
}
// Load a pdf pattern from an indirect object. Used in parsing/loading PDFs.
func newPdfPatternFromPdfObject(container core.PdfObject) (*PdfPattern, error) {
pattern := &PdfPattern{}
var dict *core.PdfObjectDictionary
if indObj, is := container.(*core.PdfIndirectObject); is {
pattern.container = indObj
d, ok := indObj.PdfObject.(*core.PdfObjectDictionary)
if !ok {
common.Log.Debug("Pattern indirect object not containing dictionary (got %T)", indObj.PdfObject)
return nil, ErrTypeError
}
dict = d
} else if streamObj, is := container.(*core.PdfObjectStream); is {
pattern.container = streamObj
dict = streamObj.PdfObjectDictionary
} else {
common.Log.Debug("Pattern not an indirect object or stream")
return nil, ErrTypeError
}
// PatternType.
obj := dict.Get("PatternType")
if obj == nil {
common.Log.Debug("Pdf Pattern not containing PatternType")
return nil, ErrRequiredAttributeMissing
}
patternType, ok := obj.(*core.PdfObjectInteger)
if !ok {
common.Log.Debug("Pattern type not an integer (got %T)", obj)
return nil, ErrTypeError
}
if *patternType != 1 && *patternType != 2 {
common.Log.Debug("Pattern type != 1/2 (got %d)", *patternType)
return nil, ErrRangeError
}
pattern.PatternType = int64(*patternType)
switch *patternType {
case 1: // Tiling pattern.
ctx, err := newPdfTilingPatternFromDictionary(dict)
if err != nil {
return nil, err
}
ctx.PdfPattern = pattern
pattern.context = ctx
return pattern, nil
case 2: // Shading pattern.
ctx, err := newPdfShadingPatternFromDictionary(dict)
if err != nil {
return nil, err
}
ctx.PdfPattern = pattern
pattern.context = ctx
return pattern, nil
}
return nil, errors.New("unknown pattern")
}
// Load entries specific to a pdf tiling pattern from a dictionary. Used in parsing/loading PDFs.
func newPdfTilingPatternFromDictionary(dict *core.PdfObjectDictionary) (*PdfTilingPattern, error) {
pattern := &PdfTilingPattern{}
// PaintType (required).
obj := dict.Get("PaintType")
if obj == nil {
common.Log.Debug("PaintType missing")
return nil, ErrRequiredAttributeMissing
}
paintType, ok := obj.(*core.PdfObjectInteger)
if !ok {
common.Log.Debug("PaintType not an integer (got %T)", obj)
return nil, ErrTypeError
}
pattern.PaintType = paintType
// TilingType (required).
obj = dict.Get("TilingType")
if obj == nil {
common.Log.Debug("TilingType missing")
return nil, ErrRequiredAttributeMissing
}
tilingType, ok := obj.(*core.PdfObjectInteger)
if !ok {
common.Log.Debug("TilingType not an integer (got %T)", obj)
return nil, ErrTypeError
}
pattern.TilingType = tilingType
// BBox (required).
obj = dict.Get("BBox")
if obj == nil {
common.Log.Debug("BBox missing")
return nil, ErrRequiredAttributeMissing
}
obj = core.TraceToDirectObject(obj)
arr, ok := obj.(*core.PdfObjectArray)
if !ok {
common.Log.Debug("BBox should be specified by an array (got %T)", obj)
return nil, ErrTypeError
}
rect, err := NewPdfRectangle(*arr)
if err != nil {
common.Log.Debug("BBox error: %v", err)
return nil, err
}
pattern.BBox = rect
// XStep (required).
obj = dict.Get("XStep")
if obj == nil {
common.Log.Debug("XStep missing")
return nil, ErrRequiredAttributeMissing
}
xStep, err := getNumberAsFloat(obj)
if err != nil {
common.Log.Debug("error getting XStep as float: %v", xStep)
return nil, err
}
pattern.XStep = core.MakeFloat(xStep)
// YStep (required).
obj = dict.Get("YStep")
if obj == nil {
common.Log.Debug("YStep missing")
return nil, ErrRequiredAttributeMissing
}
yStep, err := getNumberAsFloat(obj)
if err != nil {
common.Log.Debug("error getting YStep as float: %v", yStep)
return nil, err
}
pattern.YStep = core.MakeFloat(yStep)
// Resources (required).
obj = dict.Get("Resources")
if obj == nil {
common.Log.Debug("Resources missing")
return nil, ErrRequiredAttributeMissing
}
dict, ok = core.TraceToDirectObject(obj).(*core.PdfObjectDictionary)
if !ok {
return nil, fmt.Errorf("invalid resource dictionary (%T)", obj)
}
resources, err := NewPdfPageResourcesFromDict(dict)
if err != nil {
return nil, err
}
pattern.Resources = resources
// Matrix (optional).
if obj := dict.Get("Matrix"); obj != nil {
arr, ok := obj.(*core.PdfObjectArray)
if !ok {
common.Log.Debug("Matrix not an array (got %T)", obj)
return nil, ErrTypeError
}
pattern.Matrix = arr
}
return pattern, nil
}
// Load entries specific to a pdf shading pattern from a dictionary. Used in parsing/loading PDFs.
func newPdfShadingPatternFromDictionary(dict *core.PdfObjectDictionary) (*PdfShadingPattern, error) {
pattern := &PdfShadingPattern{}
// Shading (required).
obj := dict.Get("Shading")
if obj == nil {
common.Log.Debug("Shading missing")
return nil, ErrRequiredAttributeMissing
}
shading, err := newPdfShadingFromPdfObject(obj)
if err != nil {
common.Log.Debug("error loading shading: %v", err)
return nil, err
}
pattern.Shading = shading
// Matrix (optional).
if obj := dict.Get("Matrix"); obj != nil {
arr, ok := obj.(*core.PdfObjectArray)
if !ok {
common.Log.Debug("Matrix not an array (got %T)", obj)
return nil, ErrTypeError
}
pattern.Matrix = arr
}
// ExtGState (optional).
if obj := dict.Get("ExtGState"); obj != nil {
pattern.ExtGState = obj
}
return pattern, nil
}
/* Conversions to pdf objects. */
func (pp *PdfPattern) getDict() *core.PdfObjectDictionary {
if indObj, is := pp.container.(*core.PdfIndirectObject); is {
dict, ok := indObj.PdfObject.(*core.PdfObjectDictionary)
if !ok {
return nil
}
return dict
} else if streamObj, is := pp.container.(*core.PdfObjectStream); is {
return streamObj.PdfObjectDictionary
} else {
common.Log.Debug("Trying to access pattern dictionary of invalid object type (%T)", pp.container)
return nil
}
}
func (pp *PdfPattern) ToPdfObject() core.PdfObject {
d := pp.getDict()
d.Set("Type", core.MakeName("Pattern"))
d.Set("PatternType", core.MakeInteger(pp.PatternType))
return pp.container
}
func (pt *PdfTilingPattern) ToPdfObject() core.PdfObject {
pt.PdfPattern.ToPdfObject()
d := pt.getDict()
if pt.PaintType != nil {
d.Set("PaintType", pt.PaintType)
}
if pt.TilingType != nil {
d.Set("TilingType", pt.TilingType)
}
if pt.BBox != nil {
d.Set("BBox", pt.BBox.ToPdfObject())
}
if pt.XStep != nil {
d.Set("XStep", pt.XStep)
}
if pt.YStep != nil {
d.Set("YStep", pt.YStep)
}
if pt.Resources != nil {
d.Set("Resources", pt.Resources.ToPdfObject())
}
if pt.Matrix != nil {
d.Set("Matrix", pt.Matrix)
}
return pt.container
}
func (psp *PdfShadingPattern) ToPdfObject() core.PdfObject {
psp.PdfPattern.ToPdfObject()
d := psp.getDict()
if psp.Shading != nil {
d.Set("Shading", psp.Shading.ToPdfObject())
}
if psp.Matrix != nil {
d.Set("Matrix", psp.Matrix)
}
if psp.ExtGState != nil {
d.Set("ExtGState", psp.ExtGState)
}
return psp.container
}

View File

@@ -0,0 +1,763 @@
package model
import (
"errors"
"fmt"
"io"
"strings"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// PdfReader represents a PDF file reader. It is a frontend to the lower level parsing mechanism and provides
// a higher level access to work with PDF structure and information, such as the page structure etc.
type PdfReader struct {
parser *core.PdfParser
root core.PdfObject
pages *core.PdfObjectDictionary
pageList []*core.PdfIndirectObject
PageList []*PdfPage
pageCount int
catalog *core.PdfObjectDictionary
outlineTree *PdfOutlineTreeNode
AcroForm *PdfAcroForm
modelManager *ModelManager
// For tracking traversal (cache).
traversed map[core.PdfObject]bool
}
// NewPdfReader returns a new PdfReader for an input io.ReadSeeker interface. Can be used to read PDF from
// memory or file. Immediately loads and traverses the PDF structure including pages and page contents (if
// not encrypted).
func NewPdfReader(rs io.ReadSeeker) (*PdfReader, error) {
pdfReader := &PdfReader{}
pdfReader.traversed = map[core.PdfObject]bool{}
pdfReader.modelManager = NewModelManager()
// Create the parser, loads the cross reference table and trailer.
parser, err := core.NewParser(rs)
if err != nil {
return nil, err
}
pdfReader.parser = parser
isEncrypted, err := pdfReader.IsEncrypted()
if err != nil {
return nil, err
}
// Load pdf doc structure if not encrypted.
if !isEncrypted {
err = pdfReader.loadStructure()
if err != nil {
return nil, err
}
}
return pdfReader, nil
}
// IsEncrypted returns true if the PDF file is encrypted.
func (pp *PdfReader) IsEncrypted() (bool, error) {
return pp.parser.IsEncrypted()
}
// GetEncryptionMethod returns a string containing some information about the encryption method used.
// XXX/TODO: May be better to return a standardized struct with information.
func (pp *PdfReader) GetEncryptionMethod() string {
crypter := pp.parser.GetCrypter()
str := crypter.Filter + " - "
if crypter.V == 0 {
str += "Undocumented algorithm"
} else if crypter.V == 1 {
// RC4 or AES (bits: 40)
str += "RC4: 40 bits"
} else if crypter.V == 2 {
str += fmt.Sprintf("RC4: %d bits", crypter.Length)
} else if crypter.V == 3 {
str += "Unpublished algorithm"
} else if crypter.V >= 4 {
// Look at CF, StmF, StrF
str += fmt.Sprintf("Stream filter: %s - String filter: %s", crypter.StreamFilter, crypter.StringFilter)
str += "; Crypt filters:"
for name, cf := range crypter.CryptFilters {
str += fmt.Sprintf(" - %s: %s (%d)", name, cf.Cfm, cf.Length)
}
}
perms := crypter.GetAccessPermissions()
str += fmt.Sprintf(" - %#v", perms)
return str
}
// Decrypt decrypts the PDF file with a specified password. Also tries to
// decrypt with an empty password. Returns true if successful,
// false otherwise.
func (pp *PdfReader) Decrypt(password []byte) (bool, error) {
success, err := pp.parser.Decrypt(password)
if err != nil {
return false, err
}
if !success {
return false, nil
}
err = pp.loadStructure()
if err != nil {
common.Log.Debug("error: Fail to load structure (%s)", err)
return false, err
}
return true, nil
}
// CheckAccessRights checks access rights and permissions for a specified password. If either user/owner
// password is specified, full rights are granted, otherwise the access rights are specified by the
// Permissions flag.
//
// The bool flag indicates that the user can access and view the file.
// The AccessPermissions shows what access the user has for editing etc.
// An error is returned if there was a problem performing the authentication.
func (pp *PdfReader) CheckAccessRights(password []byte) (bool, core.AccessPermissions, error) {
return pp.parser.CheckAccessRights(password)
}
// Loads the structure of the pdf file: pages, outlines, etc.
func (pp *PdfReader) loadStructure() error {
if pp.parser.GetCrypter() != nil && !pp.parser.IsAuthenticated() {
return fmt.Errorf("file need to be decrypted first")
}
trailerDict := pp.parser.GetTrailer()
if trailerDict == nil {
return fmt.Errorf("missing trailer")
}
// Catalog.
root, ok := trailerDict.Get("Root").(*core.PdfObjectReference)
if !ok {
return fmt.Errorf("invalid Root (trailer: %s)", *trailerDict)
}
oc, err := pp.parser.LookupByReference(*root)
if err != nil {
common.Log.Debug("error: Failed to read root element catalog: %s", err)
return err
}
pcatalog, ok := oc.(*core.PdfIndirectObject)
if !ok {
common.Log.Debug("error: Missing catalog: (root %q) (trailer %s)", oc, *trailerDict)
return errors.New("missing catalog")
}
catalog, ok := (*pcatalog).PdfObject.(*core.PdfObjectDictionary)
if !ok {
common.Log.Debug("error: Invalid catalog (%s)", pcatalog.PdfObject)
return errors.New("invalid catalog")
}
common.Log.Trace("Catalog: %s", catalog)
// Pages.
pagesRef, ok := catalog.Get("Pages").(*core.PdfObjectReference)
if !ok {
return errors.New("pages in catalog should be a reference")
}
op, err := pp.parser.LookupByReference(*pagesRef)
if err != nil {
common.Log.Debug("error: Failed to read pages")
return err
}
ppages, ok := op.(*core.PdfIndirectObject)
if !ok {
common.Log.Debug("error: Pages object invalid")
common.Log.Debug("op: %p", ppages)
return errors.New("pages object invalid")
}
pages, ok := ppages.PdfObject.(*core.PdfObjectDictionary)
if !ok {
common.Log.Debug("error: Pages object invalid (%s)", ppages)
return errors.New("pages object invalid")
}
pageCount, ok := pages.Get("Count").(*core.PdfObjectInteger)
if !ok {
common.Log.Debug("error: Pages count object invalid")
return errors.New("pages count invalid")
}
pp.root = root
pp.catalog = catalog
pp.pages = pages
pp.pageCount = int(*pageCount)
pp.pageList = []*core.PdfIndirectObject{}
traversedPageNodes := map[core.PdfObject]bool{}
err = pp.buildPageList(ppages, nil, traversedPageNodes)
if err != nil {
return err
}
common.Log.Trace("---")
common.Log.Trace("TOC")
common.Log.Trace("Pages")
common.Log.Trace("%d: %s", len(pp.pageList), pp.pageList)
// Outlines.
pp.outlineTree, err = pp.loadOutlines()
if err != nil {
common.Log.Debug("error: Failed to build outline tree (%s)", err)
return err
}
// Load interactive forms and fields.
pp.AcroForm, err = pp.loadForms()
if err != nil {
return err
}
return nil
}
// Trace to object. Keeps a list of already visited references to avoid circular references.
//
// Example circular reference.
// 1 0 obj << /Next 2 0 R >>
// 2 0 obj << /Next 1 0 R >>
func (pp *PdfReader) traceToObjectWrapper(obj core.PdfObject, refList map[*core.PdfObjectReference]bool) (core.PdfObject, error) {
// Keep a list of references to avoid circular references.
ref, isRef := obj.(*core.PdfObjectReference)
if isRef {
// Make sure not already visited (circular ref).
if _, alreadyTraversed := refList[ref]; alreadyTraversed {
return nil, errors.New("circular reference")
}
refList[ref] = true
obj, err := pp.parser.LookupByReference(*ref)
if err != nil {
return nil, err
}
return pp.traceToObjectWrapper(obj, refList)
}
// Not a reference, an object. Can be indirect or any direct pdf object (other than reference).
return obj, nil
}
func (pp *PdfReader) traceToObject(obj core.PdfObject) (core.PdfObject, error) {
refList := map[*core.PdfObjectReference]bool{}
return pp.traceToObjectWrapper(obj, refList)
}
func (pp *PdfReader) loadOutlines() (*PdfOutlineTreeNode, error) {
if pp.parser.GetCrypter() != nil && !pp.parser.IsAuthenticated() {
return nil, fmt.Errorf("file need to be decrypted first")
}
// Has outlines? Otherwise return an empty outlines structure.
catalog := pp.catalog
outlinesObj := catalog.Get("Outlines")
if outlinesObj == nil {
return nil, nil
}
common.Log.Trace("-Has outlines")
// Trace references to the object.
outlineRootObj, err := pp.traceToObject(outlinesObj)
if err != nil {
common.Log.Debug("error: Failed to read outlines")
return nil, err
}
common.Log.Trace("Outline root: %v", outlineRootObj)
if _, isNull := outlineRootObj.(*core.PdfObjectNull); isNull {
common.Log.Trace("Outline root is null - no outlines")
return nil, nil
}
outlineRoot, ok := outlineRootObj.(*core.PdfIndirectObject)
if !ok {
return nil, errors.New("outline root should be an indirect object")
}
dict, ok := outlineRoot.PdfObject.(*core.PdfObjectDictionary)
if !ok {
return nil, errors.New("outline indirect object should contain a dictionary")
}
common.Log.Trace("Outline root dict: %v", dict)
outlineTree, _, err := pp.buildOutlineTree(outlineRoot, nil, nil)
if err != nil {
return nil, err
}
common.Log.Trace("Resulting outline tree: %v", outlineTree)
return outlineTree, nil
}
// Recursive build outline tree.
// prev PdfObject,
// Input: The indirect object containing an Outlines or Outline item dictionary.
// Parent, Prev are the parent or previous node in the hierarchy.
// The function returns the corresponding tree node and the last node which is used
// for setting the Last pointer of the tree node structures.
func (pp *PdfReader) buildOutlineTree(obj core.PdfObject, parent *PdfOutlineTreeNode, prev *PdfOutlineTreeNode) (*PdfOutlineTreeNode, *PdfOutlineTreeNode, error) {
container, isInd := obj.(*core.PdfIndirectObject)
if !isInd {
return nil, nil, fmt.Errorf("outline container not an indirect object %T", obj)
}
dict, ok := container.PdfObject.(*core.PdfObjectDictionary)
if !ok {
return nil, nil, errors.New("not a dictionary object")
}
common.Log.Trace("build outline tree: dict: %v (%v) p: %p", dict, container, container)
if obj := dict.Get("Title"); obj != nil {
// Outline item has a title. (required)
outlineItem, err := pp.newPdfOutlineItemFromIndirectObject(container)
if err != nil {
return nil, nil, err
}
outlineItem.Parent = parent
outlineItem.Prev = prev
if firstObj := dict.Get("First"); firstObj != nil {
firstObj, err = pp.traceToObject(firstObj)
if err != nil {
return nil, nil, err
}
if _, isNull := firstObj.(*core.PdfObjectNull); !isNull {
first, last, err := pp.buildOutlineTree(firstObj, &outlineItem.PdfOutlineTreeNode, nil)
if err != nil {
return nil, nil, err
}
outlineItem.First = first
outlineItem.Last = last
}
}
// Resolve the reference to next
if nextObj := dict.Get("Next"); nextObj != nil {
nextObj, err = pp.traceToObject(nextObj)
if err != nil {
return nil, nil, err
}
if _, isNull := nextObj.(*core.PdfObjectNull); !isNull {
next, last, err := pp.buildOutlineTree(nextObj, parent, &outlineItem.PdfOutlineTreeNode)
if err != nil {
return nil, nil, err
}
outlineItem.Next = next
return &outlineItem.PdfOutlineTreeNode, last, nil
}
}
return &outlineItem.PdfOutlineTreeNode, &outlineItem.PdfOutlineTreeNode, nil
} else {
// Outline dictionary (structure element).
outline, err := newPdfOutlineFromIndirectObject(container)
if err != nil {
return nil, nil, err
}
outline.Parent = parent
//outline.Prev = parent
if firstObj := dict.Get("First"); firstObj != nil {
// Has children...
firstObj, err = pp.traceToObject(firstObj)
if err != nil {
return nil, nil, err
}
if _, isNull := firstObj.(*core.PdfObjectNull); !isNull {
first, last, err := pp.buildOutlineTree(firstObj, &outline.PdfOutlineTreeNode, nil)
if err != nil {
return nil, nil, err
}
outline.First = first
outline.Last = last
}
}
return &outline.PdfOutlineTreeNode, &outline.PdfOutlineTreeNode, nil
}
}
// GetOutlineTree returns the outline tree.
func (pp *PdfReader) GetOutlineTree() *PdfOutlineTreeNode {
return pp.outlineTree
}
// GetOutlinesFlattened returns a flattened list of tree nodes and titles.
func (pp *PdfReader) GetOutlinesFlattened() ([]*PdfOutlineTreeNode, []string, error) {
outlineNodeList := []*PdfOutlineTreeNode{}
flattenedTitleList := []string{}
// Recursive flattening function.
var flattenFunc func(*PdfOutlineTreeNode, *[]*PdfOutlineTreeNode, *[]string, int)
flattenFunc = func(node *PdfOutlineTreeNode, outlineList *[]*PdfOutlineTreeNode, titleList *[]string, depth int) {
if node == nil {
return
}
if node.context == nil {
common.Log.Debug("error: Missing node.context") // Should not happen ever.
return
}
if item, isItem := node.context.(*PdfOutlineItem); isItem {
*outlineList = append(*outlineList, &item.PdfOutlineTreeNode)
title := strings.Repeat(" ", depth*2) + string(*item.Title)
*titleList = append(*titleList, title)
if item.Next != nil {
flattenFunc(item.Next, outlineList, titleList, depth)
}
}
if node.First != nil {
title := strings.Repeat(" ", depth*2) + "+"
*titleList = append(*titleList, title)
flattenFunc(node.First, outlineList, titleList, depth+1)
}
}
flattenFunc(pp.outlineTree, &outlineNodeList, &flattenedTitleList, 0)
return outlineNodeList, flattenedTitleList, nil
}
// loadForms loads the AcroForm.
func (pp *PdfReader) loadForms() (*PdfAcroForm, error) {
if pp.parser.GetCrypter() != nil && !pp.parser.IsAuthenticated() {
return nil, fmt.Errorf("file need to be decrypted first")
}
// Has forms?
catalog := pp.catalog
obj := catalog.Get("AcroForm")
if obj == nil {
// Nothing to load.
return nil, nil
}
var err error
obj, err = pp.traceToObject(obj)
if err != nil {
return nil, err
}
obj = core.TraceToDirectObject(obj)
if _, isNull := obj.(*core.PdfObjectNull); isNull {
common.Log.Trace("Acroform is a null object (empty)\n")
return nil, nil
}
formsDict, ok := obj.(*core.PdfObjectDictionary)
if !ok {
common.Log.Debug("invalid AcroForm entry %T", obj)
common.Log.Debug("Does not have forms")
return nil, fmt.Errorf("invalid acroform entry %T", obj)
}
common.Log.Trace("Has Acro forms")
// Load it.
// Ensure we have access to everything.
common.Log.Trace("Traverse the Acroforms structure")
err = pp.traverseObjectData(formsDict)
if err != nil {
common.Log.Debug("error: Unable to traverse AcroForms (%s)", err)
return nil, err
}
// Create the acro forms object.
acroForm, err := pp.newPdfAcroFormFromDict(formsDict)
if err != nil {
return nil, err
}
return acroForm, nil
}
// Build the table of contents.
// tree, ex: Pages -> Pages -> Pages -> Page
// Traverse through the whole thing recursively.
func (pp *PdfReader) buildPageList(node *core.PdfIndirectObject, parent *core.PdfIndirectObject, traversedPageNodes map[core.PdfObject]bool) error {
if node == nil {
return nil
}
if _, alreadyTraversed := traversedPageNodes[node]; alreadyTraversed {
common.Log.Debug("Cyclic recursion, skipping")
return nil
}
traversedPageNodes[node] = true
nodeDict, ok := node.PdfObject.(*core.PdfObjectDictionary)
if !ok {
return errors.New("node not a dictionary")
}
objType, ok := (*nodeDict).Get("Type").(*core.PdfObjectName)
if !ok {
return errors.New("node missing Type (Required)")
}
common.Log.Trace("buildPageList node type: %s", *objType)
if *objType == "Page" {
p, err := pp.newPdfPageFromDict(nodeDict)
if err != nil {
return err
}
p.setContainer(node)
if parent != nil {
// Set the parent (in case missing or incorrect).
nodeDict.Set("Parent", parent)
}
pp.pageList = append(pp.pageList, node)
pp.PageList = append(pp.PageList, p)
return nil
}
if *objType != "Pages" {
common.Log.Debug("error: Table of content containing non Page/Pages object! (%s)", objType)
return errors.New("table of content containing non Page/Pages object")
}
// A Pages object. Update the parent.
if parent != nil {
nodeDict.Set("Parent", parent)
}
// Resolve the object recursively.
err := pp.traverseObjectData(node)
if err != nil {
return err
}
kidsObj, err := pp.parser.Trace(nodeDict.Get("Kids"))
if err != nil {
common.Log.Debug("error: Failed loading Kids object")
return err
}
var kids *core.PdfObjectArray
kids, ok = kidsObj.(*core.PdfObjectArray)
if !ok {
kidsIndirect, isIndirect := kidsObj.(*core.PdfIndirectObject)
if !isIndirect {
return errors.New("invalid Kids object")
}
kids, ok = kidsIndirect.PdfObject.(*core.PdfObjectArray)
if !ok {
return errors.New("invalid Kids indirect object")
}
}
common.Log.Trace("Kids: %s", kids)
for idx, child := range *kids {
child, ok := child.(*core.PdfIndirectObject)
if !ok {
common.Log.Debug("error: Page not indirect object - (%s)", child)
return errors.New("page not indirect object")
}
(*kids)[idx] = child
err = pp.buildPageList(child, node, traversedPageNodes)
if err != nil {
return err
}
}
return nil
}
// GetNumPages returns the number of pages in the document.
func (pp *PdfReader) GetNumPages() (int, error) {
if pp.parser.GetCrypter() != nil && !pp.parser.IsAuthenticated() {
return 0, fmt.Errorf("file need to be decrypted first")
}
return len(pp.pageList), nil
}
// Resolves a reference, returning the object and indicates whether or not
// it was cached.
func (pp *PdfReader) resolveReference(ref *core.PdfObjectReference) (core.PdfObject, bool, error) {
cachedObj, isCached := pp.parser.ObjCache[int(ref.ObjectNumber)]
if !isCached {
common.Log.Trace("Reader Lookup ref: %s", ref)
obj, err := pp.parser.LookupByReference(*ref)
if err != nil {
return nil, false, err
}
pp.parser.ObjCache[int(ref.ObjectNumber)] = obj
return obj, false, nil
}
return cachedObj, true, nil
}
/*
* Recursively traverse through the page object data and look up
* references to indirect objects.
*
* GH: Are we fully protected against circular references? (Add tests).
*/
func (pp *PdfReader) traverseObjectData(o core.PdfObject) error {
common.Log.Trace("Traverse object data")
if _, isTraversed := pp.traversed[o]; isTraversed {
common.Log.Trace("-Already traversed...")
return nil
}
pp.traversed[o] = true
if io, isIndirectObj := o.(*core.PdfIndirectObject); isIndirectObj {
common.Log.Trace("io: %s", io)
common.Log.Trace("- %s", io.PdfObject)
err := pp.traverseObjectData(io.PdfObject)
return err
}
if so, isStreamObj := o.(*core.PdfObjectStream); isStreamObj {
err := pp.traverseObjectData(so.PdfObjectDictionary)
return err
}
if dict, isDict := o.(*core.PdfObjectDictionary); isDict {
common.Log.Trace("- dict: %s", dict)
for _, name := range dict.Keys() {
v := dict.Get(name)
if ref, isRef := v.(*core.PdfObjectReference); isRef {
resolvedObj, _, err := pp.resolveReference(ref)
if err != nil {
return err
}
dict.Set(name, resolvedObj)
err = pp.traverseObjectData(resolvedObj)
if err != nil {
return err
}
} else {
err := pp.traverseObjectData(v)
if err != nil {
return err
}
}
}
return nil
}
if arr, isArray := o.(*core.PdfObjectArray); isArray {
common.Log.Trace("- array: %s", arr)
for idx, v := range *arr {
if ref, isRef := v.(*core.PdfObjectReference); isRef {
resolvedObj, _, err := pp.resolveReference(ref)
if err != nil {
return err
}
(*arr)[idx] = resolvedObj
err = pp.traverseObjectData(resolvedObj)
if err != nil {
return err
}
} else {
err := pp.traverseObjectData(v)
if err != nil {
return err
}
}
}
return nil
}
if _, isRef := o.(*core.PdfObjectReference); isRef {
common.Log.Debug("error: Reader tracing a reference!")
return errors.New("reader tracing a reference")
}
return nil
}
// GetPageAsIndirectObject returns an indirect object containing the page dictionary for a specified page number.
func (pp *PdfReader) GetPageAsIndirectObject(pageNumber int) (core.PdfObject, error) {
if pp.parser.GetCrypter() != nil && !pp.parser.IsAuthenticated() {
return nil, fmt.Errorf("file needs to be decrypted first")
}
if len(pp.pageList) < pageNumber {
return nil, errors.New("invalid page number (page count too short)")
}
page := pp.pageList[pageNumber-1]
// Look up all references related to page and load everything.
err := pp.traverseObjectData(page)
if err != nil {
return nil, err
}
common.Log.Trace("Page: %T %s", page, page)
common.Log.Trace("- %T %s", page.PdfObject, page.PdfObject)
return page, nil
}
// GetPage returns the PdfPage model for the specified page number.
func (pp *PdfReader) GetPage(pageNumber int) (*PdfPage, error) {
if pp.parser.GetCrypter() != nil && !pp.parser.IsAuthenticated() {
return nil, fmt.Errorf("file needs to be decrypted first")
}
if len(pp.pageList) < pageNumber {
return nil, errors.New("invalid page number (page count too short)")
}
idx := pageNumber - 1
if idx < 0 {
return nil, fmt.Errorf("page numbering must start at 1")
}
page := pp.PageList[idx]
return page, nil
}
// GetOCProperties returns the optional content properties PdfObject.
func (pp *PdfReader) GetOCProperties() (core.PdfObject, error) {
dict := pp.catalog
obj := dict.Get("OCProperties")
var err error
obj, err = pp.traceToObject(obj)
if err != nil {
return nil, err
}
// Resolve all references...
// Should be pretty safe. Should not be referencing to pages or
// any large structures. Local structures and references
// to OC Groups.
err = pp.traverseObjectData(obj)
if err != nil {
return nil, err
}
return obj, nil
}
// Inspect inspects the object types, subtypes and content in the PDF file returning a map of
// object type to number of instances of each.
func (pp *PdfReader) Inspect() (map[string]int, error) {
return pp.parser.Inspect()
}
// GetObjectNums returns the object numbers of the PDF objects in the file
// Numbered objects are either indirect objects or stream objects.
// e.g. objNums := pdfReader.GetObjectNums()
// The underlying objects can then be accessed with
// pdfReader.GetIndirectObjectByNumber(objNums[0]) for the first available object.
func (r *PdfReader) GetObjectNums() []int {
return r.parser.GetObjectNums()
}
// GetIndirectObjectByNumber retrieves and returns a specific PdfObject by object number.
func (pp *PdfReader) GetIndirectObjectByNumber(number int) (core.PdfObject, error) {
obj, err := pp.parser.LookupByNumber(number)
return obj, err
}
// GetTrailer returns the PDF's trailer dictionary.
func (pp *PdfReader) GetTrailer() (*core.PdfObjectDictionary, error) {
trailerDict := pp.parser.GetTrailer()
if trailerDict == nil {
return nil, errors.New("trailer missing")
}
return trailerDict, nil
}

View File

@@ -0,0 +1,406 @@
package model
import (
"errors"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// Page resources model.
// Implements PdfModel.
type PdfPageResources struct {
ExtGState core.PdfObject
ColorSpace *PdfPageResourcesColorspaces
Pattern core.PdfObject
Shading core.PdfObject
XObject core.PdfObject
Font core.PdfObject
ProcSet core.PdfObject
Properties core.PdfObject
// Primitive reource container.
primitive *core.PdfObjectDictionary
}
func NewPdfPageResources() *PdfPageResources {
r := &PdfPageResources{}
r.primitive = core.MakeDict()
return r
}
func NewPdfPageResourcesFromDict(dict *core.PdfObjectDictionary) (*PdfPageResources, error) {
r := NewPdfPageResources()
if obj := dict.Get("ExtGState"); obj != nil {
r.ExtGState = obj
}
if obj := dict.Get("ColorSpace"); obj != nil && !isNullObject(obj) {
colorspaces, err := newPdfPageResourcesColorspacesFromPdfObject(obj)
if err != nil {
return nil, err
}
r.ColorSpace = colorspaces
}
if obj := dict.Get("Pattern"); obj != nil {
r.Pattern = obj
}
if obj := dict.Get("Shading"); obj != nil {
r.Shading = obj
}
if obj := dict.Get("XObject"); obj != nil {
r.XObject = obj
}
if obj := dict.Get("Font"); obj != nil {
r.Font = obj
}
if obj := dict.Get("ProcSet"); obj != nil {
r.ProcSet = obj
}
if obj := dict.Get("Properties"); obj != nil {
r.Properties = obj
}
return r, nil
}
func (r *PdfPageResources) GetContainingPdfObject() core.PdfObject {
return r.primitive
}
func (r *PdfPageResources) ToPdfObject() core.PdfObject {
d := r.primitive
d.SetIfNotNil("ExtGState", r.ExtGState)
if r.ColorSpace != nil {
d.SetIfNotNil("ColorSpace", r.ColorSpace.ToPdfObject())
}
d.SetIfNotNil("Pattern", r.Pattern)
d.SetIfNotNil("Shading", r.Shading)
d.SetIfNotNil("XObject", r.XObject)
d.SetIfNotNil("Font", r.Font)
d.SetIfNotNil("ProcSet", r.ProcSet)
d.SetIfNotNil("Properties", r.Properties)
return d
}
// Add External Graphics State (GState). The gsDict can be specified either directly as a dictionary or an indirect
// object containing a dictionary.
func (r *PdfPageResources) AddExtGState(gsName core.PdfObjectName, gsDict core.PdfObject) error {
if r.ExtGState == nil {
r.ExtGState = core.MakeDict()
}
obj := r.ExtGState
dict, ok := core.TraceToDirectObject(obj).(*core.PdfObjectDictionary)
if !ok {
common.Log.Debug("ExtGState type error (got %T/%T)", obj, core.TraceToDirectObject(obj))
return ErrTypeError
}
dict.Set(gsName, gsDict)
return nil
}
// Get the ExtGState specified by keyName. Returns a bool indicating whether it was found or not.
func (r *PdfPageResources) GetExtGState(keyName core.PdfObjectName) (core.PdfObject, bool) {
if r.ExtGState == nil {
return nil, false
}
dict, ok := core.TraceToDirectObject(r.ExtGState).(*core.PdfObjectDictionary)
if !ok {
common.Log.Debug("error: Invalid ExtGState entry - not a dict (got %T)", r.ExtGState)
return nil, false
}
if obj := dict.Get(keyName); obj != nil {
return obj, true
} else {
return nil, false
}
}
// Check whether a font is defined by the specified keyName.
func (r *PdfPageResources) HasExtGState(keyName core.PdfObjectName) bool {
_, has := r.GetFontByName(keyName)
return has
}
// Get the shading specified by keyName. Returns nil if not existing. The bool flag indicated whether it was found
// or not.
func (r *PdfPageResources) GetShadingByName(keyName core.PdfObjectName) (*PdfShading, bool) {
if r.Shading == nil {
return nil, false
}
shadingDict, ok := core.TraceToDirectObject(r.Shading).(*core.PdfObjectDictionary)
if !ok {
common.Log.Debug("error: Invalid Shading entry - not a dict (got %T)", r.Shading)
return nil, false
}
if obj := shadingDict.Get(keyName); obj != nil {
shading, err := newPdfShadingFromPdfObject(obj)
if err != nil {
common.Log.Debug("error: failed to load pdf shading: %v", err)
return nil, false
}
return shading, true
} else {
return nil, false
}
}
// Set a shading resource specified by keyName.
func (r *PdfPageResources) SetShadingByName(keyName core.PdfObjectName, shadingObj core.PdfObject) error {
if r.Shading == nil {
r.Shading = core.MakeDict()
}
shadingDict, has := r.Shading.(*core.PdfObjectDictionary)
if !has {
return ErrTypeError
}
shadingDict.Set(keyName, shadingObj)
return nil
}
// Get the pattern specified by keyName. Returns nil if not existing. The bool flag indicated whether it was found
// or not.
func (r *PdfPageResources) GetPatternByName(keyName core.PdfObjectName) (*PdfPattern, bool) {
if r.Pattern == nil {
return nil, false
}
patternDict, ok := core.TraceToDirectObject(r.Pattern).(*core.PdfObjectDictionary)
if !ok {
common.Log.Debug("error: Invalid Pattern entry - not a dict (got %T)", r.Pattern)
return nil, false
}
if obj := patternDict.Get(keyName); obj != nil {
pattern, err := newPdfPatternFromPdfObject(obj)
if err != nil {
common.Log.Debug("error: failed to load pdf pattern: %v", err)
return nil, false
}
return pattern, true
} else {
return nil, false
}
}
// Set a pattern resource specified by keyName.
func (r *PdfPageResources) SetPatternByName(keyName core.PdfObjectName, pattern core.PdfObject) error {
if r.Pattern == nil {
r.Pattern = core.MakeDict()
}
patternDict, has := r.Pattern.(*core.PdfObjectDictionary)
if !has {
return ErrTypeError
}
patternDict.Set(keyName, pattern)
return nil
}
// Get the font specified by keyName. Returns the PdfObject which the entry refers to.
// Returns a bool value indicating whether or not the entry was found.
func (r *PdfPageResources) GetFontByName(keyName core.PdfObjectName) (core.PdfObject, bool) {
if r.Font == nil {
return nil, false
}
fontDict, has := core.TraceToDirectObject(r.Font).(*core.PdfObjectDictionary)
if !has {
common.Log.Debug("error: Font not a dictionary! (got %T)", core.TraceToDirectObject(r.Font))
return nil, false
}
if obj := fontDict.Get(keyName); obj != nil {
return obj, true
} else {
return nil, false
}
}
// Check whether a font is defined by the specified keyName.
func (r *PdfPageResources) HasFontByName(keyName core.PdfObjectName) bool {
_, has := r.GetFontByName(keyName)
return has
}
// Set the font specified by keyName to the given object.
func (r *PdfPageResources) SetFontByName(keyName core.PdfObjectName, obj core.PdfObject) error {
if r.Font == nil {
// Create if not existing.
r.Font = core.MakeDict()
}
fontDict, has := core.TraceToDirectObject(r.Font).(*core.PdfObjectDictionary)
if !has {
common.Log.Debug("error: Font not a dictionary! (got %T)", core.TraceToDirectObject(r.Font))
return ErrTypeError
}
fontDict.Set(keyName, obj)
return nil
}
func (r *PdfPageResources) GetColorspaceByName(keyName core.PdfObjectName) (PdfColorspace, bool) {
if r.ColorSpace == nil {
return nil, false
}
cs, has := r.ColorSpace.Colorspaces[string(keyName)]
if !has {
return nil, false
}
return cs, true
}
func (r *PdfPageResources) HasColorspaceByName(keyName core.PdfObjectName) bool {
if r.ColorSpace == nil {
return false
}
_, has := r.ColorSpace.Colorspaces[string(keyName)]
return has
}
func (r *PdfPageResources) SetColorspaceByName(keyName core.PdfObjectName, cs PdfColorspace) error {
if r.ColorSpace == nil {
r.ColorSpace = NewPdfPageResourcesColorspaces()
}
r.ColorSpace.Set(keyName, cs)
return nil
}
// Check if an XObject with a specified keyName is defined.
func (r *PdfPageResources) HasXObjectByName(keyName core.PdfObjectName) bool {
obj, _ := r.GetXObjectByName(keyName)
if obj != nil {
return true
} else {
return false
}
}
type XObjectType int
const (
XObjectTypeUndefined XObjectType = iota
XObjectTypeImage XObjectType = iota
XObjectTypeForm XObjectType = iota
XObjectTypePS XObjectType = iota
XObjectTypeUnknown XObjectType = iota
)
// Returns the XObject with the specified keyName and the object type.
func (r *PdfPageResources) GetXObjectByName(keyName core.PdfObjectName) (*core.PdfObjectStream, XObjectType) {
if r.XObject == nil {
return nil, XObjectTypeUndefined
}
xresDict, has := core.TraceToDirectObject(r.XObject).(*core.PdfObjectDictionary)
if !has {
common.Log.Debug("error: XObject not a dictionary! (got %T)", core.TraceToDirectObject(r.XObject))
return nil, XObjectTypeUndefined
}
if obj := xresDict.Get(keyName); obj != nil {
stream, ok := obj.(*core.PdfObjectStream)
if !ok {
common.Log.Debug("XObject not pointing to a stream %T", obj)
return nil, XObjectTypeUndefined
}
dict := stream.PdfObjectDictionary
name, ok := core.TraceToDirectObject(dict.Get("Subtype")).(*core.PdfObjectName)
if !ok {
common.Log.Debug("XObject Subtype not a Name, dict: %s", dict.String())
return nil, XObjectTypeUndefined
}
switch *name {
case "Image":
return stream, XObjectTypeImage
case "Form":
return stream, XObjectTypeForm
case "PS":
return stream, XObjectTypePS
default:
common.Log.Debug("XObject Subtype not known (%s)", *name)
return nil, XObjectTypeUndefined
}
} else {
return nil, XObjectTypeUndefined
}
}
func (r *PdfPageResources) SetXObjectByName(keyName core.PdfObjectName, stream *core.PdfObjectStream) error {
if r.XObject == nil {
r.XObject = core.MakeDict()
}
obj := core.TraceToDirectObject(r.XObject)
xresDict, has := obj.(*core.PdfObjectDictionary)
if !has {
common.Log.Debug("invalid XObject, got %T/%T", r.XObject, obj)
return errors.New("type check error")
}
xresDict.Set(keyName, stream)
return nil
}
func (r *PdfPageResources) GetXObjectImageByName(keyName core.PdfObjectName) (*XObjectImage, error) {
stream, xtype := r.GetXObjectByName(keyName)
if stream == nil {
return nil, nil
}
if xtype != XObjectTypeImage {
return nil, errors.New("not an image")
}
ximg, err := NewXObjectImageFromStream(stream)
if err != nil {
return nil, err
}
return ximg, nil
}
func (r *PdfPageResources) SetXObjectImageByName(keyName core.PdfObjectName, ximg *XObjectImage) error {
stream := ximg.ToPdfObject().(*core.PdfObjectStream)
err := r.SetXObjectByName(keyName, stream)
return err
}
func (r *PdfPageResources) GetXObjectFormByName(keyName core.PdfObjectName) (*XObjectForm, error) {
stream, xtype := r.GetXObjectByName(keyName)
if stream == nil {
return nil, nil
}
if xtype != XObjectTypeForm {
return nil, errors.New("not a form")
}
xform, err := NewXObjectFormFromStream(stream)
if err != nil {
return nil, err
}
return xform, nil
}
func (r *PdfPageResources) SetXObjectFormByName(keyName core.PdfObjectName, xform *XObjectForm) error {
stream := xform.ToPdfObject().(*core.PdfObjectStream)
err := r.SetXObjectByName(keyName, stream)
return err
}

View File

@@ -0,0 +1,191 @@
package sampling
// Resample the raw data which is in 8-bit (byte) format as a different
// bit count per sample, up to 32 bits (uint32).
func ResampleBytes(data []byte, bitsPerSample int) []uint32 {
samples := []uint32{}
bitsLeftPerSample := bitsPerSample
var sample uint32
var remainder byte
remainderBits := 0
index := 0
i := 0
for i < len(data) {
// Start with the remainder.
if remainderBits > 0 {
take := remainderBits
if bitsLeftPerSample < take {
take = bitsLeftPerSample
}
sample = (sample << uint(take)) | uint32(remainder>>uint(8-take))
remainderBits -= take
if remainderBits > 0 {
remainder = remainder << uint(take)
} else {
remainder = 0
}
bitsLeftPerSample -= take
if bitsLeftPerSample == 0 {
//samples[index] = sample
samples = append(samples, sample)
bitsLeftPerSample = bitsPerSample
sample = 0
index++
}
} else {
// Take next byte
b := data[i]
i++
// 8 bits.
take := 8
if bitsLeftPerSample < take {
take = bitsLeftPerSample
}
remainderBits = 8 - take
sample = (sample << uint(take)) | uint32(b>>uint(remainderBits))
if take < 8 {
remainder = b << uint(take)
}
bitsLeftPerSample -= take
if bitsLeftPerSample == 0 {
//samples[index] = sample
samples = append(samples, sample)
bitsLeftPerSample = bitsPerSample
sample = 0
index++
}
}
}
// Take care of remaining samples (if enough data available).
for remainderBits >= bitsPerSample {
take := remainderBits
if bitsLeftPerSample < take {
take = bitsLeftPerSample
}
sample = (sample << uint(take)) | uint32(remainder>>uint(8-take))
remainderBits -= take
if remainderBits > 0 {
remainder = remainder << uint(take)
} else {
remainder = 0
}
bitsLeftPerSample -= take
if bitsLeftPerSample == 0 {
//samples[index] = sample
samples = append(samples, sample)
bitsLeftPerSample = bitsPerSample
sample = 0
index++
}
}
return samples
}
// Resample the raw data which is in <=32-bit (uint32) format as a different
// bit count per sample, up to 32 bits (uint32).
//
// bitsPerOutputSample is the number of bits for each output sample (up to 32)
// bitsPerInputSample is the number of bits used in each input sample (up to 32)
func ResampleUint32(data []uint32, bitsPerInputSample int, bitsPerOutputSample int) []uint32 {
samples := []uint32{}
bitsLeftPerSample := bitsPerOutputSample
var sample uint32
var remainder uint32
remainderBits := 0
index := 0
i := 0
for i < len(data) {
// Start with the remainder.
if remainderBits > 0 {
take := remainderBits
if bitsLeftPerSample < take {
take = bitsLeftPerSample
}
sample = (sample << uint(take)) | uint32(remainder>>uint(bitsPerInputSample-take))
remainderBits -= take
if remainderBits > 0 {
remainder = remainder << uint(take)
} else {
remainder = 0
}
bitsLeftPerSample -= take
if bitsLeftPerSample == 0 {
//samples[index] = sample
samples = append(samples, sample)
bitsLeftPerSample = bitsPerOutputSample
sample = 0
index++
}
} else {
// Take next byte
b := data[i]
i++
// 32 bits.
take := bitsPerInputSample
if bitsLeftPerSample < take {
take = bitsLeftPerSample
}
remainderBits = bitsPerInputSample - take
sample = (sample << uint(take)) | uint32(b>>uint(remainderBits))
if take < bitsPerInputSample {
remainder = b << uint(take)
}
bitsLeftPerSample -= take
if bitsLeftPerSample == 0 {
//samples[index] = sample
samples = append(samples, sample)
bitsLeftPerSample = bitsPerOutputSample
sample = 0
index++
}
}
}
// Take care of remaining samples (if enough data available).
for remainderBits >= bitsPerOutputSample {
take := remainderBits
if bitsLeftPerSample < take {
take = bitsLeftPerSample
}
sample = (sample << uint(take)) | uint32(remainder>>uint(bitsPerInputSample-take))
remainderBits -= take
if remainderBits > 0 {
remainder = remainder << uint(take)
} else {
remainder = 0
}
bitsLeftPerSample -= take
if bitsLeftPerSample == 0 {
samples = append(samples, sample)
bitsLeftPerSample = bitsPerOutputSample
sample = 0
index++
}
}
// If there are partial output samples, pad with 0s.
if bitsLeftPerSample > 0 && bitsLeftPerSample < bitsPerOutputSample {
sample <<= uint(bitsLeftPerSample)
samples = append(samples, sample)
}
return samples
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,129 @@
package model
// Common basic data structures: PdfRectangle, PdfDate, etc.
// These kinds of data structures can be copied, do not need a unique copy of each object.
import (
"errors"
"fmt"
"regexp"
"strconv"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// Definition of a rectangle.
type PdfRectangle struct {
Llx float64 // Lower left corner (ll).
Lly float64
Urx float64 // Upper right corner (ur).
Ury float64
}
// Create a PDF rectangle object based on an input array of 4 integers.
// Defining the lower left (LL) and upper right (UR) corners with
// floating point numbers.
func NewPdfRectangle(arr core.PdfObjectArray) (*PdfRectangle, error) {
rect := PdfRectangle{}
if len(arr) != 4 {
return nil, errors.New("invalid rectangle array, len != 4")
}
var err error
rect.Llx, err = getNumberAsFloat(arr[0])
if err != nil {
return nil, err
}
rect.Lly, err = getNumberAsFloat(arr[1])
if err != nil {
return nil, err
}
rect.Urx, err = getNumberAsFloat(arr[2])
if err != nil {
return nil, err
}
rect.Ury, err = getNumberAsFloat(arr[3])
if err != nil {
return nil, err
}
return &rect, nil
}
// Convert to a PDF object.
func (rect *PdfRectangle) ToPdfObject() core.PdfObject {
arr := core.PdfObjectArray{}
arr = append(arr, core.MakeFloat(rect.Llx))
arr = append(arr, core.MakeFloat(rect.Lly))
arr = append(arr, core.MakeFloat(rect.Urx))
arr = append(arr, core.MakeFloat(rect.Ury))
return &arr
}
// A date is a PDF string of the form:
// (D:YYYYMMDDHHmmSSOHH'mm)
type PdfDate struct {
year int64 // YYYY
month int64 // MM (01-12)
day int64 // DD (01-31)
hour int64 // HH (00-23)
minute int64 // mm (00-59)
second int64 // SS (00-59)
utOffsetSign byte // O ('+' / '-' / 'Z')
utOffsetHours int64 // HH' (00-23 followed by ')
utOffsetMins int64 // mm (00-59)
}
var reDate = regexp.MustCompile(`\s*D\s*:\s*(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})([+-Z])?(\d{2})?'?(\d{2})?`)
// Make a new PdfDate object from a PDF date string (see 7.9.4 Dates).
// format: "D: YYYYMMDDHHmmSSOHH'mm"
func NewPdfDate(dateStr string) (PdfDate, error) {
d := PdfDate{}
matches := reDate.FindAllStringSubmatch(dateStr, 1)
if len(matches) < 1 {
return d, fmt.Errorf("invalid date string (%s)", dateStr)
}
if len(matches[0]) != 10 {
return d, errors.New("invalid regexp group match length != 10")
}
// No need to handle err from ParseInt, as pre-validated via regexp.
d.year, _ = strconv.ParseInt(matches[0][1], 10, 32)
d.month, _ = strconv.ParseInt(matches[0][2], 10, 32)
d.day, _ = strconv.ParseInt(matches[0][3], 10, 32)
d.hour, _ = strconv.ParseInt(matches[0][4], 10, 32)
d.minute, _ = strconv.ParseInt(matches[0][5], 10, 32)
d.second, _ = strconv.ParseInt(matches[0][6], 10, 32)
// Some poor implementations do not include the offset.
if len(matches[0][7]) > 0 {
d.utOffsetSign = matches[0][7][0]
} else {
d.utOffsetSign = '+'
}
if len(matches[0][8]) > 0 {
d.utOffsetHours, _ = strconv.ParseInt(matches[0][8], 10, 32)
} else {
d.utOffsetHours = 0
}
if len(matches[0][9]) > 0 {
d.utOffsetMins, _ = strconv.ParseInt(matches[0][9], 10, 32)
} else {
d.utOffsetMins = 0
}
return d, nil
}
// Convert to a PDF string object.
func (date *PdfDate) ToPdfObject() core.PdfObject {
str := fmt.Sprintf("D:%.4d%.2d%.2d%.2d%.2d%.2d%c%.2d'%.2d'",
date.year, date.month, date.day, date.hour, date.minute, date.second,
date.utOffsetSign, date.utOffsetHours, date.utOffsetMins)
pdfStr := core.PdfObjectString(str)
return &pdfStr
}

View File

@@ -0,0 +1,34 @@
package textencoding
import "gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
type TextEncoder interface {
// Convert a raw utf8 string (series of runes) to an encoded string (series of character codes) to be used in PDF.
Encode(raw string) string
// Conversion between character code and glyph name.
// The bool return flag is true if there was a match, and false otherwise.
CharcodeToGlyph(code byte) (string, bool)
// Conversion between glyph name and character code.
// The bool return flag is true if there was a match, and false otherwise.
GlyphToCharcode(glyph string) (byte, bool)
// Convert rune to character code.
// The bool return flag is true if there was a match, and false otherwise.
RuneToCharcode(val rune) (byte, bool)
// Convert character code to rune.
// The bool return flag is true if there was a match, and false otherwise.
CharcodeToRune(charcode byte) (rune, bool)
// Convert rune to glyph name.
// The bool return flag is true if there was a match, and false otherwise.
RuneToGlyph(val rune) (string, bool)
// Convert glyph to rune.
// The bool return flag is true if there was a match, and false otherwise.
GlyphToRune(glyph string) (rune, bool)
ToPdfObject() core.PdfObject
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,409 @@
package textencoding
var zapfdingbatsGlyphToRuneMap = map[string]rune{
"a1": '\u2701',
"a10": '\u2721',
"a100": '\u275e',
"a101": '\u2761',
"a102": '\u2762',
"a103": '\u2763',
"a104": '\u2764',
"a105": '\u2710',
"a106": '\u2765',
"a107": '\u2766',
"a108": '\u2767',
"a109": '\u2660',
"a11": '\u261b',
"a110": '\u2665',
"a111": '\u2666',
"a112": '\u2663',
"a117": '\u2709',
"a118": '\u2708',
"a119": '\u2707',
"a12": '\u261e',
"a120": '\u2460',
"a121": '\u2461',
"a122": '\u2462',
"a123": '\u2463',
"a124": '\u2464',
"a125": '\u2465',
"a126": '\u2466',
"a127": '\u2467',
"a128": '\u2468',
"a129": '\u2469',
"a13": '\u270c',
"a130": '\u2776',
"a131": '\u2777',
"a132": '\u2778',
"a133": '\u2779',
"a134": '\u277a',
"a135": '\u277b',
"a136": '\u277c',
"a137": '\u277d',
"a138": '\u277e',
"a139": '\u277f',
"a14": '\u270d',
"a140": '\u2780',
"a141": '\u2781',
"a142": '\u2782',
"a143": '\u2783',
"a144": '\u2784',
"a145": '\u2785',
"a146": '\u2786',
"a147": '\u2787',
"a148": '\u2788',
"a149": '\u2789',
"a15": '\u270e',
"a150": '\u278a',
"a151": '\u278b',
"a152": '\u278c',
"a153": '\u278d',
"a154": '\u278e',
"a155": '\u278f',
"a156": '\u2790',
"a157": '\u2791',
"a158": '\u2792',
"a159": '\u2793',
"a16": '\u270f',
"a160": '\u2794',
"a161": '\u2192',
"a162": '\u27a3',
"a163": '\u2194',
"a164": '\u2195',
"a165": '\u2799',
"a166": '\u279b',
"a167": '\u279c',
"a168": '\u279d',
"a169": '\u279e',
"a17": '\u2711',
"a170": '\u279f',
"a171": '\u27a0',
"a172": '\u27a1',
"a173": '\u27a2',
"a174": '\u27a4',
"a175": '\u27a5',
"a176": '\u27a6',
"a177": '\u27a7',
"a178": '\u27a8',
"a179": '\u27a9',
"a18": '\u2712',
"a180": '\u27ab',
"a181": '\u27ad',
"a182": '\u27af',
"a183": '\u27b2',
"a184": '\u27b3',
"a185": '\u27b5',
"a186": '\u27b8',
"a187": '\u27ba',
"a188": '\u27bb',
"a189": '\u27bc',
"a19": '\u2713',
"a190": '\u27bd',
"a191": '\u27be',
"a192": '\u279a',
"a193": '\u27aa',
"a194": '\u27b6',
"a195": '\u27b9',
"a196": '\u2798',
"a197": '\u27b4',
"a198": '\u27b7',
"a199": '\u27ac',
"a2": '\u2702',
"a20": '\u2714',
"a200": '\u27ae',
"a201": '\u27b1',
"a202": '\u2703',
"a203": '\u2750',
"a204": '\u2752',
"a205": '\u276e',
"a206": '\u2770',
"a21": '\u2715',
"a22": '\u2716',
"a23": '\u2717',
"a24": '\u2718',
"a25": '\u2719',
"a26": '\u271a',
"a27": '\u271b',
"a28": '\u271c',
"a29": '\u2722',
"a3": '\u2704',
"a30": '\u2723',
"a31": '\u2724',
"a32": '\u2725',
"a33": '\u2726',
"a34": '\u2727',
"a35": '\u2605',
"a36": '\u2729',
"a37": '\u272a',
"a38": '\u272b',
"a39": '\u272c',
"a4": '\u260e',
"a40": '\u272d',
"a41": '\u272e',
"a42": '\u272f',
"a43": '\u2730',
"a44": '\u2731',
"a45": '\u2732',
"a46": '\u2733',
"a47": '\u2734',
"a48": '\u2735',
"a49": '\u2736',
"a5": '\u2706',
"a50": '\u2737',
"a51": '\u2738',
"a52": '\u2739',
"a53": '\u273a',
"a54": '\u273b',
"a55": '\u273c',
"a56": '\u273d',
"a57": '\u273e',
"a58": '\u273f',
"a59": '\u2740',
"a6": '\u271d',
"a60": '\u2741',
"a61": '\u2742',
"a62": '\u2743',
"a63": '\u2744',
"a64": '\u2745',
"a65": '\u2746',
"a66": '\u2747',
"a67": '\u2748',
"a68": '\u2749',
"a69": '\u274a',
"a7": '\u271e',
"a70": '\u274b',
"a71": '\u25cf',
"a72": '\u274d',
"a73": '\u25a0',
"a74": '\u274f',
"a75": '\u2751',
"a76": '\u25b2',
"a77": '\u25bc',
"a78": '\u25c6',
"a79": '\u2756',
"a8": '\u271f',
"a81": '\u25d7',
"a82": '\u2758',
"a83": '\u2759',
"a84": '\u275a',
"a85": '\u276f',
"a86": '\u2771',
"a87": '\u2772',
"a88": '\u2773',
"a89": '\u2768',
"a9": '\u2720',
"a90": '\u2769',
"a91": '\u276c',
"a92": '\u276d',
"a93": '\u276a',
"a94": '\u276b',
"a95": '\u2774',
"a96": '\u2775',
"a97": '\u275b',
"a98": '\u275c',
"a99": '\u275d',
}
var zapfdingbatsRuneToGlyphMap = map[rune]string{
'\u2701': "a1",
'\u2721': "a10",
'\u275e': "a100",
'\u2761': "a101",
'\u2762': "a102",
'\u2763': "a103",
'\u2764': "a104",
'\u2710': "a105",
'\u2765': "a106",
'\u2766': "a107",
'\u2767': "a108",
'\u2660': "a109",
'\u261b': "a11",
'\u2665': "a110",
'\u2666': "a111",
'\u2663': "a112",
'\u2709': "a117",
'\u2708': "a118",
'\u2707': "a119",
'\u261e': "a12",
'\u2460': "a120",
'\u2461': "a121",
'\u2462': "a122",
'\u2463': "a123",
'\u2464': "a124",
'\u2465': "a125",
'\u2466': "a126",
'\u2467': "a127",
'\u2468': "a128",
'\u2469': "a129",
'\u270c': "a13",
'\u2776': "a130",
'\u2777': "a131",
'\u2778': "a132",
'\u2779': "a133",
'\u277a': "a134",
'\u277b': "a135",
'\u277c': "a136",
'\u277d': "a137",
'\u277e': "a138",
'\u277f': "a139",
'\u270d': "a14",
'\u2780': "a140",
'\u2781': "a141",
'\u2782': "a142",
'\u2783': "a143",
'\u2784': "a144",
'\u2785': "a145",
'\u2786': "a146",
'\u2787': "a147",
'\u2788': "a148",
'\u2789': "a149",
'\u270e': "a15",
'\u278a': "a150",
'\u278b': "a151",
'\u278c': "a152",
'\u278d': "a153",
'\u278e': "a154",
'\u278f': "a155",
'\u2790': "a156",
'\u2791': "a157",
'\u2792': "a158",
'\u2793': "a159",
'\u270f': "a16",
'\u2794': "a160",
'\u2192': "a161",
'\u27a3': "a162",
'\u2194': "a163",
'\u2195': "a164",
'\u2799': "a165",
'\u279b': "a166",
'\u279c': "a167",
'\u279d': "a168",
'\u279e': "a169",
'\u2711': "a17",
'\u279f': "a170",
'\u27a0': "a171",
'\u27a1': "a172",
'\u27a2': "a173",
'\u27a4': "a174",
'\u27a5': "a175",
'\u27a6': "a176",
'\u27a7': "a177",
'\u27a8': "a178",
'\u27a9': "a179",
'\u2712': "a18",
'\u27ab': "a180",
'\u27ad': "a181",
'\u27af': "a182",
'\u27b2': "a183",
'\u27b3': "a184",
'\u27b5': "a185",
'\u27b8': "a186",
'\u27ba': "a187",
'\u27bb': "a188",
'\u27bc': "a189",
'\u2713': "a19",
'\u27bd': "a190",
'\u27be': "a191",
'\u279a': "a192",
'\u27aa': "a193",
'\u27b6': "a194",
'\u27b9': "a195",
'\u2798': "a196",
'\u27b4': "a197",
'\u27b7': "a198",
'\u27ac': "a199",
'\u2702': "a2",
'\u2714': "a20",
'\u27ae': "a200",
'\u27b1': "a201",
'\u2703': "a202",
'\u2750': "a203",
'\u2752': "a204",
'\u276e': "a205",
'\u2770': "a206",
'\u2715': "a21",
'\u2716': "a22",
'\u2717': "a23",
'\u2718': "a24",
'\u2719': "a25",
'\u271a': "a26",
'\u271b': "a27",
'\u271c': "a28",
'\u2722': "a29",
'\u2704': "a3",
'\u2723': "a30",
'\u2724': "a31",
'\u2725': "a32",
'\u2726': "a33",
'\u2727': "a34",
'\u2605': "a35",
'\u2729': "a36",
'\u272a': "a37",
'\u272b': "a38",
'\u272c': "a39",
'\u260e': "a4",
'\u272d': "a40",
'\u272e': "a41",
'\u272f': "a42",
'\u2730': "a43",
'\u2731': "a44",
'\u2732': "a45",
'\u2733': "a46",
'\u2734': "a47",
'\u2735': "a48",
'\u2736': "a49",
'\u2706': "a5",
'\u2737': "a50",
'\u2738': "a51",
'\u2739': "a52",
'\u273a': "a53",
'\u273b': "a54",
'\u273c': "a55",
'\u273d': "a56",
'\u273e': "a57",
'\u273f': "a58",
'\u2740': "a59",
'\u271d': "a6",
'\u2741': "a60",
'\u2742': "a61",
'\u2743': "a62",
'\u2744': "a63",
'\u2745': "a64",
'\u2746': "a65",
'\u2747': "a66",
'\u2748': "a67",
'\u2749': "a68",
'\u274a': "a69",
'\u271e': "a7",
'\u274b': "a70",
'\u25cf': "a71",
'\u274d': "a72",
'\u25a0': "a73",
'\u274f': "a74",
'\u2751': "a75",
'\u25b2': "a76",
'\u25bc': "a77",
'\u25c6': "a78",
'\u2756': "a79",
'\u271f': "a8",
'\u25d7': "a81",
'\u2758': "a82",
'\u2759': "a83",
'\u275a': "a84",
'\u276f': "a85",
'\u2771': "a86",
'\u2772': "a87",
'\u2773': "a88",
'\u2768': "a89",
'\u2720': "a9",
'\u2769': "a90",
'\u276c': "a91",
'\u276d': "a92",
'\u276a': "a93",
'\u276b': "a94",
'\u2774': "a95",
'\u2775': "a96",
'\u275b': "a97",
'\u275c': "a98",
'\u275d': "a99",
}

View File

@@ -0,0 +1,496 @@
package textencoding
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// Encoding for Symbol font.
type SymbolEncoder struct {
}
func NewSymbolEncoder() SymbolEncoder {
encoder := SymbolEncoder{}
return encoder
}
// Convert a raw utf8 string (series of runes) to an encoded string (series of character codes) to be used in PDF.
func (enc SymbolEncoder) Encode(raw string) string {
encoded := []byte{}
for _, rune := range raw {
code, found := enc.RuneToCharcode(rune)
if !found {
continue
}
encoded = append(encoded, code)
}
return string(encoded)
}
// Conversion between character code and glyph name.
// The bool return flag is true if there was a match, and false otherwise.
func (enc SymbolEncoder) CharcodeToGlyph(code byte) (string, bool) {
glyph, has := symbolEncodingCharcodeToGlyphMap[code]
if !has {
common.Log.Debug("Symbol encoding error: unable to find charcode->glyph entry (%v)", code)
return "", false
}
return glyph, true
}
// Conversion between glyph name and character code.
// The bool return flag is true if there was a match, and false otherwise.
func (enc SymbolEncoder) GlyphToCharcode(glyph string) (byte, bool) {
code, found := symbolEncodingGlyphToCharcodeMap[glyph]
if !found {
common.Log.Debug("Symbol encoding error: unable to find glyph->charcode entry (%s)", glyph)
return 0, false
}
return code, found
}
// Convert rune to character code.
// The bool return flag is true if there was a match, and false otherwise.
func (enc SymbolEncoder) RuneToCharcode(val rune) (byte, bool) {
glyph, found := runeToGlyph(val, glyphlistRuneToGlyphMap)
if !found {
common.Log.Debug("Symbol encoding error: unable to find rune->glyph entry (%v)", val)
return 0, false
}
code, found := symbolEncodingGlyphToCharcodeMap[glyph]
if !found {
common.Log.Debug("Symbol encoding error: unable to find glyph->charcode entry (%s)", glyph)
return 0, false
}
return code, true
}
// Convert character code to rune.
// The bool return flag is true if there was a match, and false otherwise.
func (enc SymbolEncoder) CharcodeToRune(charcode byte) (rune, bool) {
glyph, found := symbolEncodingCharcodeToGlyphMap[charcode]
if !found {
common.Log.Debug("Symbol encoding error: unable to find charcode->glyph entry (%d)", charcode)
return 0, false
}
val, found := glyphToRune(glyph, glyphlistGlyphToRuneMap)
if !found {
return 0, false
}
return val, true
}
// Convert rune to glyph name.
// The bool return flag is true if there was a match, and false otherwise.
func (enc SymbolEncoder) RuneToGlyph(val rune) (string, bool) {
return runeToGlyph(val, glyphlistRuneToGlyphMap)
}
// Convert glyph to rune.
// The bool return flag is true if there was a match, and false otherwise.
func (enc SymbolEncoder) GlyphToRune(glyph string) (rune, bool) {
return glyphToRune(glyph, glyphlistGlyphToRuneMap)
}
// Convert to PDF Object.
func (enc SymbolEncoder) ToPdfObject() core.PdfObject {
dict := core.MakeDict()
dict.Set("Type", core.MakeName("Encoding"))
// Returning an empty Encoding object with no differences. Indicates that we are using the font's built-in
// encoding.
return core.MakeIndirectObject(dict)
}
// Charcode to Glyph map (Symbol encoding)
var symbolEncodingCharcodeToGlyphMap map[byte]string = map[byte]string{
32: "space",
33: "exclam",
34: "universal",
35: "numbersign",
36: "existential",
37: "percent",
38: "ampersand",
39: "suchthat",
40: "parenleft",
41: "parenright",
42: "asteriskmath",
43: "plus",
44: "comma",
45: "minus",
46: "period",
47: "slash",
48: "zero",
49: "one",
50: "two",
51: "three",
52: "four",
53: "five",
54: "six",
55: "seven",
56: "eight",
57: "nine",
58: "colon",
59: "semicolon",
60: "less",
61: "equal",
62: "greater",
63: "question",
64: "congruent",
65: "Alpha",
66: "Beta",
67: "Chi",
68: "Delta",
69: "Epsilon",
70: "Phi",
71: "Gamma",
72: "Eta",
73: "Iota",
74: "theta1",
75: "Kappa",
76: "Lambda",
77: "Mu",
78: "Nu",
79: "Omicron",
80: "Pi",
81: "Theta",
82: "Rho",
83: "Sigma",
84: "Tau",
85: "Upsilon",
86: "sigma1",
87: "Omega",
88: "Xi",
89: "Psi",
90: "Zeta",
91: "bracketleft",
92: "therefore",
93: "bracketright",
94: "perpendicular",
95: "underscore",
96: "radicalex",
97: "alpha",
98: "beta",
99: "chi",
100: "delta",
101: "epsilon",
102: "phi",
103: "gamma",
104: "eta",
105: "iota",
106: "phi1",
107: "kappa",
108: "lambda",
109: "mu",
110: "nu",
111: "omicron",
112: "pi",
113: "theta",
114: "rho",
115: "sigma",
116: "tau",
117: "upsilon",
118: "omega1",
119: "omega",
120: "xi",
121: "psi",
122: "zeta",
123: "braceleft",
124: "bar",
125: "braceright",
126: "similar",
160: "Euro",
161: "Upsilon1",
162: "minute",
163: "lessequal",
164: "fraction",
165: "infinity",
166: "florin",
167: "club",
168: "diamond",
169: "heart",
170: "spade",
171: "arrowboth",
172: "arrowleft",
173: "arrowup",
174: "arrowright",
175: "arrowdown",
176: "degree",
177: "plusminus",
178: "second",
179: "greaterequal",
180: "multiply",
181: "proportional",
182: "partialdiff",
183: "bullet",
184: "divide",
185: "notequal",
186: "equivalence",
187: "approxequal",
188: "ellipsis",
189: "arrowvertex",
190: "arrowhorizex",
191: "carriagereturn",
192: "aleph",
193: "Ifraktur",
194: "Rfraktur",
195: "weierstrass",
196: "circlemultiply",
197: "circleplus",
198: "emptyset",
199: "intersection",
200: "union",
201: "propersuperset",
202: "reflexsuperset",
203: "notsubset",
204: "propersubset",
205: "reflexsubset",
206: "element",
207: "notelement",
208: "angle",
209: "gradient",
210: "registerserif",
211: "copyrightserif",
212: "trademarkserif",
213: "product",
214: "radical",
215: "dotmath",
216: "logicalnot",
217: "logicaland",
218: "logicalor",
219: "arrowdblboth",
220: "arrowdblleft",
221: "arrowdblup",
222: "arrowdblright",
223: "arrowdbldown",
224: "lozenge",
225: "angleleft",
226: "registersans",
227: "copyrightsans",
228: "trademarksans",
229: "summation",
230: "parenlefttp",
231: "parenleftex",
232: "parenleftbt",
233: "bracketlefttp",
234: "bracketleftex",
235: "bracketleftbt",
236: "bracelefttp",
237: "braceleftmid",
238: "braceleftbt",
239: "braceex",
241: "angleright",
242: "integral",
243: "integraltp",
244: "integralex",
245: "integralbt",
246: "parenrighttp",
247: "parenrightex",
248: "parenrightbt",
249: "bracketrighttp",
250: "bracketrightex",
251: "bracketrightbt",
252: "bracerighttp",
253: "bracerightmid",
254: "bracerightbt",
}
// Glyph to charcode map (Symbol encoding).
var symbolEncodingGlyphToCharcodeMap map[string]byte = map[string]byte{
"space": 32,
"exclam": 33,
"universal": 34,
"numbersign": 35,
"existential": 36,
"percent": 37,
"ampersand": 38,
"suchthat": 39,
"parenleft": 40,
"parenright": 41,
"asteriskmath": 42,
"plus": 43,
"comma": 44,
"minus": 45,
"period": 46,
"slash": 47,
"zero": 48,
"one": 49,
"two": 50,
"three": 51,
"four": 52,
"five": 53,
"six": 54,
"seven": 55,
"eight": 56,
"nine": 57,
"colon": 58,
"semicolon": 59,
"less": 60,
"equal": 61,
"greater": 62,
"question": 63,
"congruent": 64,
"Alpha": 65,
"Beta": 66,
"Chi": 67,
"Delta": 68,
"Epsilon": 69,
"Phi": 70,
"Gamma": 71,
"Eta": 72,
"Iota": 73,
"theta1": 74,
"Kappa": 75,
"Lambda": 76,
"Mu": 77,
"Nu": 78,
"Omicron": 79,
"Pi": 80,
"Theta": 81,
"Rho": 82,
"Sigma": 83,
"Tau": 84,
"Upsilon": 85,
"sigma1": 86,
"Omega": 87,
"Xi": 88,
"Psi": 89,
"Zeta": 90,
"bracketleft": 91,
"therefore": 92,
"bracketright": 93,
"perpendicular": 94,
"underscore": 95,
"radicalex": 96,
"alpha": 97,
"beta": 98,
"chi": 99,
"delta": 100,
"epsilon": 101,
"phi": 102,
"gamma": 103,
"eta": 104,
"iota": 105,
"phi1": 106,
"kappa": 107,
"lambda": 108,
"mu": 109,
"nu": 110,
"omicron": 111,
"pi": 112,
"theta": 113,
"rho": 114,
"sigma": 115,
"tau": 116,
"upsilon": 117,
"omega1": 118,
"omega": 119,
"xi": 120,
"psi": 121,
"zeta": 122,
"braceleft": 123,
"bar": 124,
"braceright": 125,
"similar": 126,
"Euro": 160,
"Upsilon1": 161,
"minute": 162,
"lessequal": 163,
"fraction": 164,
"infinity": 165,
"florin": 166,
"club": 167,
"diamond": 168,
"heart": 169,
"spade": 170,
"arrowboth": 171,
"arrowleft": 172,
"arrowup": 173,
"arrowright": 174,
"arrowdown": 175,
"degree": 176,
"plusminus": 177,
"second": 178,
"greaterequal": 179,
"multiply": 180,
"proportional": 181,
"partialdiff": 182,
"bullet": 183,
"divide": 184,
"notequal": 185,
"equivalence": 186,
"approxequal": 187,
"ellipsis": 188,
"arrowvertex": 189,
"arrowhorizex": 190,
"carriagereturn": 191,
"aleph": 192,
"Ifraktur": 193,
"Rfraktur": 194,
"weierstrass": 195,
"circlemultiply": 196,
"circleplus": 197,
"emptyset": 198,
"intersection": 199,
"union": 200,
"propersuperset": 201,
"reflexsuperset": 202,
"notsubset": 203,
"propersubset": 204,
"reflexsubset": 205,
"element": 206,
"notelement": 207,
"angle": 208,
"gradient": 209,
"registerserif": 210,
"copyrightserif": 211,
"trademarkserif": 212,
"product": 213,
"radical": 214,
"dotmath": 215,
"logicalnot": 216,
"logicaland": 217,
"logicalor": 218,
"arrowdblboth": 219,
"arrowdblleft": 220,
"arrowdblup": 221,
"arrowdblright": 222,
"arrowdbldown": 223,
"lozenge": 224,
"angleleft": 225,
"registersans": 226,
"copyrightsans": 227,
"trademarksans": 228,
"summation": 229,
"parenlefttp": 230,
"parenleftex": 231,
"parenleftbt": 232,
"bracketlefttp": 233,
"bracketleftex": 234,
"bracketleftbt": 235,
"bracelefttp": 236,
"braceleftmid": 237,
"braceleftbt": 238,
"braceex": 239,
"angleright": 241,
"integral": 242,
"integraltp": 243,
"integralex": 244,
"integralbt": 245,
"parenrighttp": 246,
"parenrightex": 247,
"parenrightbt": 248,
"bracketrighttp": 249,
"bracketrightex": 250,
"bracketrightbt": 251,
"bracerighttp": 252,
"bracerightmid": 253,
"bracerightbt": 254,
}

View File

@@ -0,0 +1,51 @@
package textencoding
import "gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
func glyphToRune(glyph string, glyphToRuneMap map[string]rune) (rune, bool) {
ucode, found := glyphToRuneMap[glyph]
if found {
return ucode, true
}
//common.Log.Debug("Glyph->Rune ERROR: Unable to find glyph %s", glyph)
return 0, false
}
func runeToGlyph(ucode rune, runeToGlyphMap map[rune]string) (string, bool) {
glyph, found := runeToGlyphMap[ucode]
if found {
return glyph, true
}
//common.Log.Debug("Rune->Glyph ERROR: Unable to find rune %v", ucode)
return "", false
}
func splitWords(raw string, encoder TextEncoder) []string {
runes := []rune(raw)
words := []string{}
startsAt := 0
for idx, code := range runes {
glyph, found := encoder.RuneToGlyph(code)
if !found {
common.Log.Debug("Glyph not found for code: %s\n", string(code))
continue
}
if glyph == "space" {
word := runes[startsAt:idx]
words = append(words, string(word))
startsAt = idx + 1
}
}
word := runes[startsAt:]
if len(word) > 0 {
words = append(words, string(word))
}
return words
}

View File

@@ -0,0 +1,557 @@
package textencoding
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// WinAnsiEncoding.
type WinAnsiEncoder struct {
}
func NewWinAnsiTextEncoder() WinAnsiEncoder {
encoder := WinAnsiEncoder{}
return encoder
}
func (winenc WinAnsiEncoder) ToPdfObject() core.PdfObject {
return core.MakeName("WinAnsiEncoding")
}
// Convert a raw utf8 string (series of runes) to an encoded string (series of character codes) to be used in PDF.
func (winenc WinAnsiEncoder) Encode(raw string) string {
encoded := []byte{}
for _, rune := range raw {
code, has := winenc.RuneToCharcode(rune)
if has {
encoded = append(encoded, code)
}
}
return string(encoded)
}
// Conversion between character code and glyph name.
// The bool return flag is true if there was a match, and false otherwise.
func (winenc WinAnsiEncoder) CharcodeToGlyph(code byte) (string, bool) {
glyph, has := winansiEncodingCharcodeToGlyphMap[code]
if !has {
common.Log.Debug("Charcode -> Glyph error: charcode not found: %d\n", code)
return "", false
}
return glyph, true
}
// Conversion between glyph name and character code.
// The bool return flag is true if there was a match, and false otherwise.
func (winenc WinAnsiEncoder) GlyphToCharcode(glyph string) (byte, bool) {
code, found := winansiEncodingGlyphToCharcodeMap[glyph]
if !found {
common.Log.Debug("Glyph -> Charcode error: glyph not found: %s\n", glyph)
return 0, false
}
return code, true
}
// Convert rune to character code.
// The bool return flag is true if there was a match, and false otherwise.
func (winenc WinAnsiEncoder) RuneToCharcode(val rune) (byte, bool) {
glyph, found := winenc.RuneToGlyph(val)
if !found {
return 0, false
}
code, found := winansiEncodingGlyphToCharcodeMap[glyph]
if !found {
common.Log.Debug("Glyph -> Charcode error: glyph not found %s\n", glyph)
return 0, false
}
return code, true
}
// Convert character code to rune.
// The bool return flag is true if there was a match, and false otherwise.
func (winenc WinAnsiEncoder) CharcodeToRune(charcode byte) (rune, bool) {
glyph, found := winansiEncodingCharcodeToGlyphMap[charcode]
if !found {
common.Log.Debug("Charcode -> Glyph error: charcode not found: %d\n", charcode)
return 0, false
}
ucode, found := glyphToRune(glyph, glyphlistGlyphToRuneMap)
if !found {
return 0, false
}
return ucode, true
}
// Convert rune to glyph name.
// The bool return flag is true if there was a match, and false otherwise.
func (winenc WinAnsiEncoder) RuneToGlyph(val rune) (string, bool) {
return runeToGlyph(val, glyphlistRuneToGlyphMap)
}
// Convert glyph to rune.
// The bool return flag is true if there was a match, and false otherwise.
func (winenc WinAnsiEncoder) GlyphToRune(glyph string) (rune, bool) {
return glyphToRune(glyph, glyphlistGlyphToRuneMap)
}
// Charcode to glyph name map (WinAnsiEncoding).
var winansiEncodingCharcodeToGlyphMap = map[byte]string{
32: "space",
33: "exclam",
34: "quotedbl",
35: "numbersign",
36: "dollar",
37: "percent",
38: "ampersand",
39: "quotesingle",
40: "parenleft",
41: "parenright",
42: "asterisk",
43: "plus",
44: "comma",
45: "hyphen",
46: "period",
47: "slash",
48: "zero",
49: "one",
50: "two",
51: "three",
52: "four",
53: "five",
54: "six",
55: "seven",
56: "eight",
57: "nine",
58: "colon",
59: "semicolon",
60: "less",
61: "equal",
62: "greater",
63: "question",
64: "at",
65: "A",
66: "B",
67: "C",
68: "D",
69: "E",
70: "F",
71: "G",
72: "H",
73: "I",
74: "J",
75: "K",
76: "L",
77: "M",
78: "N",
79: "O",
80: "P",
81: "Q",
82: "R",
83: "S",
84: "T",
85: "U",
86: "V",
87: "W",
88: "X",
89: "Y",
90: "Z",
91: "bracketleft",
92: "backslash",
93: "bracketright",
94: "asciicircum",
95: "underscore",
96: "grave",
97: "a",
98: "b",
99: "c",
100: "d",
101: "e",
102: "f",
103: "g",
104: "h",
105: "i",
106: "j",
107: "k",
108: "l",
109: "m",
110: "n",
111: "o",
112: "p",
113: "q",
114: "r",
115: "s",
116: "t",
117: "u",
118: "v",
119: "w",
120: "x",
121: "y",
122: "z",
123: "braceleft",
124: "bar",
125: "braceright",
126: "asciitilde",
127: "bullet",
128: "Euro",
129: "bullet",
130: "quotesinglbase",
131: "florin",
132: "quotedblbase",
133: "ellipsis",
134: "dagger",
135: "daggerdbl",
136: "circumflex",
137: "perthousand",
138: "Scaron",
139: "guilsinglleft",
140: "OE",
141: "bullet",
142: "Zcaron",
143: "bullet",
144: "bullet",
145: "quoteleft",
146: "quoteright",
147: "quotedblleft",
148: "quotedblright",
149: "bullet",
150: "endash",
151: "emdash",
152: "tilde",
153: "trademark",
154: "scaron",
155: "guilsinglright",
156: "oe",
157: "bullet",
158: "zcaron",
159: "Ydieresis",
160: "space",
161: "exclamdown",
162: "cent",
163: "sterling",
164: "currency",
165: "yen",
166: "brokenbar",
167: "section",
168: "dieresis",
169: "copyright",
170: "ordfeminine",
171: "guillemotleft",
172: "logicalnot",
173: "hyphen",
174: "registered",
175: "macron",
176: "degree",
177: "plusminus",
178: "twosuperior",
179: "threesuperior",
180: "acute",
181: "mu",
182: "paragraph",
183: "periodcentered",
184: "cedilla",
185: "onesuperior",
186: "ordmasculine",
187: "guillemotright",
188: "onequarter",
189: "onehalf",
190: "threequarters",
191: "questiondown",
192: "Agrave",
193: "Aacute",
194: "Acircumflex",
195: "Atilde",
196: "Adieresis",
197: "Aring",
198: "AE",
199: "Ccedilla",
200: "Egrave",
201: "Eacute",
202: "Ecircumflex",
203: "Edieresis",
204: "Igrave",
205: "Iacute",
206: "Icircumflex",
207: "Idieresis",
208: "Eth",
209: "Ntilde",
210: "Ograve",
211: "Oacute",
212: "Ocircumflex",
213: "Otilde",
214: "Odieresis",
215: "multiply",
216: "Oslash",
217: "Ugrave",
218: "Uacute",
219: "Ucircumflex",
220: "Udieresis",
221: "Yacute",
222: "Thorn",
223: "germandbls",
224: "agrave",
225: "aacute",
226: "acircumflex",
227: "atilde",
228: "adieresis",
229: "aring",
230: "ae",
231: "ccedilla",
232: "egrave",
233: "eacute",
234: "ecircumflex",
235: "edieresis",
236: "igrave",
237: "iacute",
238: "icircumflex",
239: "idieresis",
240: "eth",
241: "ntilde",
242: "ograve",
243: "oacute",
244: "ocircumflex",
245: "otilde",
246: "odieresis",
247: "divide",
248: "oslash",
249: "ugrave",
250: "uacute",
251: "ucircumflex",
252: "udieresis",
253: "yacute",
254: "thorn",
255: "ydieresis",
}
// Glyph to charcode map (WinAnsiEncoding).
var winansiEncodingGlyphToCharcodeMap = map[string]byte{
"space": 32,
"exclam": 33,
"quotedbl": 34,
"numbersign": 35,
"dollar": 36,
"percent": 37,
"ampersand": 38,
"quotesingle": 39,
"parenleft": 40,
"parenright": 41,
"asterisk": 42,
"plus": 43,
"comma": 44,
"hyphen": 45,
"period": 46,
"slash": 47,
"zero": 48,
"one": 49,
"two": 50,
"three": 51,
"four": 52,
"five": 53,
"six": 54,
"seven": 55,
"eight": 56,
"nine": 57,
"colon": 58,
"semicolon": 59,
"less": 60,
"equal": 61,
"greater": 62,
"question": 63,
"at": 64,
"A": 65,
"B": 66,
"C": 67,
"D": 68,
"E": 69,
"F": 70,
"G": 71,
"H": 72,
"I": 73,
"J": 74,
"K": 75,
"L": 76,
"M": 77,
"N": 78,
"O": 79,
"P": 80,
"Q": 81,
"R": 82,
"S": 83,
"T": 84,
"U": 85,
"V": 86,
"W": 87,
"X": 88,
"Y": 89,
"Z": 90,
"bracketleft": 91,
"backslash": 92,
"bracketright": 93,
"asciicircum": 94,
"underscore": 95,
"grave": 96,
"a": 97,
"b": 98,
"c": 99,
"d": 100,
"e": 101,
"f": 102,
"g": 103,
"h": 104,
"i": 105,
"j": 106,
"k": 107,
"l": 108,
"m": 109,
"n": 110,
"o": 111,
"p": 112,
"q": 113,
"r": 114,
"s": 115,
"t": 116,
"u": 117,
"v": 118,
"w": 119,
"x": 120,
"y": 121,
"z": 122,
"braceleft": 123,
"bar": 124,
"braceright": 125,
"asciitilde": 126,
"bullet": 127,
"Euro": 128,
//"bullet": 129,
"quotesinglbase": 130,
"florin": 131,
"quotedblbase": 132,
"ellipsis": 133,
"dagger": 134,
"daggerdbl": 135,
"circumflex": 136,
"perthousand": 137,
"Scaron": 138,
"guilsinglleft": 139,
"OE": 140,
//"bullet": 141,
"Zcaron": 142,
//"bullet": 143,
//"bullet": 144,
"quoteleft": 145,
"quoteright": 146,
"quotedblleft": 147,
"quotedblright": 148,
//"bullet": 149,
"endash": 150,
"emdash": 151,
"tilde": 152,
"trademark": 153,
"scaron": 154,
"guilsinglright": 155,
"oe": 156,
//"bullet": 157,
"zcaron": 158,
"Ydieresis": 159,
//"space": 160,
"exclamdown": 161,
"cent": 162,
"sterling": 163,
"currency": 164,
"yen": 165,
"brokenbar": 166,
"section": 167,
"dieresis": 168,
"copyright": 169,
"ordfeminine": 170,
"guillemotleft": 171,
"logicalnot": 172,
//"hyphen": 173,
"registered": 174,
"macron": 175,
"degree": 176,
"plusminus": 177,
"twosuperior": 178,
"threesuperior": 179,
"acute": 180,
"mu": 181,
"paragraph": 182,
"periodcentered": 183,
"cedilla": 184,
"onesuperior": 185,
"ordmasculine": 186,
"guillemotright": 187,
"onequarter": 188,
"onehalf": 189,
"threequarters": 190,
"questiondown": 191,
"Agrave": 192,
"Aacute": 193,
"Acircumflex": 194,
"Atilde": 195,
"Adieresis": 196,
"Aring": 197,
"AE": 198,
"Ccedilla": 199,
"Egrave": 200,
"Eacute": 201,
"Ecircumflex": 202,
"Edieresis": 203,
"Igrave": 204,
"Iacute": 205,
"Icircumflex": 206,
"Idieresis": 207,
"Eth": 208,
"Ntilde": 209,
"Ograve": 210,
"Oacute": 211,
"Ocircumflex": 212,
"Otilde": 213,
"Odieresis": 214,
"multiply": 215,
"Oslash": 216,
"Ugrave": 217,
"Uacute": 218,
"Ucircumflex": 219,
"Udieresis": 220,
"Yacute": 221,
"Thorn": 222,
"germandbls": 223,
"agrave": 224,
"aacute": 225,
"acircumflex": 226,
"atilde": 227,
"adieresis": 228,
"aring": 229,
"ae": 230,
"ccedilla": 231,
"egrave": 232,
"eacute": 233,
"ecircumflex": 234,
"edieresis": 235,
"igrave": 236,
"iacute": 237,
"icircumflex": 238,
"idieresis": 239,
"eth": 240,
"ntilde": 241,
"ograve": 242,
"oacute": 243,
"ocircumflex": 244,
"otilde": 245,
"odieresis": 246,
"divide": 247,
"oslash": 248,
"ugrave": 249,
"uacute": 250,
"ucircumflex": 251,
"udieresis": 252,
"yacute": 253,
"thorn": 254,
"ydieresis": 255,
}

View File

@@ -0,0 +1,537 @@
package textencoding
import (
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// Encoding for ZapfDingbats font.
type ZapfDingbatsEncoder struct {
}
func NewZapfDingbatsEncoder() ZapfDingbatsEncoder {
encoder := ZapfDingbatsEncoder{}
return encoder
}
// Convert a raw utf8 string (series of runes) to an encoded string (series of character codes) to be used in PDF.
func (enc ZapfDingbatsEncoder) Encode(raw string) string {
encoded := []byte{}
for _, rune := range raw {
code, found := enc.RuneToCharcode(rune)
if !found {
continue
}
encoded = append(encoded, code)
}
return string(encoded)
}
// Conversion between character code and glyph name.
// The bool return flag is true if there was a match, and false otherwise.
func (enc ZapfDingbatsEncoder) CharcodeToGlyph(code byte) (string, bool) {
glyph, has := zapfDingbatsEncodingCharcodeToGlyphMap[code]
if !has {
common.Log.Debug("ZapfDingbats encoding error: unable to find charcode->glyph entry (%v)", code)
return "", false
}
return glyph, true
}
// Conversion between glyph name and character code.
// The bool return flag is true if there was a match, and false otherwise.
func (enc ZapfDingbatsEncoder) GlyphToCharcode(glyph string) (byte, bool) {
code, found := zapfDingbatsEncodingGlyphToCharcodeMap[glyph]
if !found {
common.Log.Debug("ZapfDingbats encoding error: unable to find glyph->charcode entry (%s)", glyph)
return 0, false
}
return code, found
}
// Convert rune to character code.
// The bool return flag is true if there was a match, and false otherwise.
func (enc ZapfDingbatsEncoder) RuneToCharcode(val rune) (byte, bool) {
glyph, found := enc.RuneToGlyph(val)
if !found {
common.Log.Debug("ZapfDingbats encoding error: unable to find rune->glyph entry (%v)", val)
return 0, false
}
code, found := zapfDingbatsEncodingGlyphToCharcodeMap[glyph]
if !found {
common.Log.Debug("ZapfDingbats encoding error: unable to find glyph->charcode entry (%s)", glyph)
return 0, false
}
return code, true
}
// Convert character code to rune.
// The bool return flag is true if there was a match, and false otherwise.
func (enc ZapfDingbatsEncoder) CharcodeToRune(charcode byte) (rune, bool) {
glyph, found := zapfDingbatsEncodingCharcodeToGlyphMap[charcode]
if !found {
common.Log.Debug("ZapfDingbats encoding error: unable to find charcode->glyph entry (%d)", charcode)
return 0, false
}
return enc.GlyphToRune(glyph)
}
// Convert rune to glyph name.
// The bool return flag is true if there was a match, and false otherwise.
func (enc ZapfDingbatsEncoder) RuneToGlyph(val rune) (string, bool) {
// Seek in the zapfdingbats list first.
glyph, found := runeToGlyph(val, zapfdingbatsRuneToGlyphMap)
if !found {
// Then revert to glyphlist if not found.
glyph, found = runeToGlyph(val, glyphlistRuneToGlyphMap)
if !found {
common.Log.Debug("ZapfDingbats encoding error: unable to find rune->glyph entry (%v)", val)
return "", false
}
}
return glyph, true
}
// Convert glyph to rune.
// The bool return flag is true if there was a match, and false otherwise.
func (enc ZapfDingbatsEncoder) GlyphToRune(glyph string) (rune, bool) {
// Seek in the zapfdingbats list first.
val, found := glyphToRune(glyph, zapfdingbatsGlyphToRuneMap)
if !found {
// Then revert to glyphlist if not found.
val, found = glyphToRune(glyph, glyphlistGlyphToRuneMap)
if !found {
common.Log.Debug("Symbol encoding error: unable to find glyph->rune entry (%v)", glyph)
return 0, false
}
}
return val, true
}
// Convert to PDF Object.
func (enc ZapfDingbatsEncoder) ToPdfObject() core.PdfObject {
dict := core.MakeDict()
dict.Set("Type", core.MakeName("Encoding"))
// Returning an empty Encoding object with no differences. Indicates that we are using the font's built-in
// encoding.
return core.MakeIndirectObject(dict)
}
var zapfDingbatsEncodingCharcodeToGlyphMap = map[byte]string{
32: "space",
33: "a1",
34: "a2",
35: "a202",
36: "a3",
37: "a4",
38: "a5",
39: "a119",
40: "a118",
41: "a117",
42: "a11",
43: "a12",
44: "a13",
45: "a14",
46: "a15",
47: "a16",
48: "a105",
49: "a17",
50: "a18",
51: "a19",
52: "a20",
53: "a21",
54: "a22",
55: "a23",
56: "a24",
57: "a25",
58: "a26",
59: "a27",
60: "a28",
61: "a6",
62: "a7",
63: "a8",
64: "a9",
65: "a10",
66: "a29",
67: "a30",
68: "a31",
69: "a32",
70: "a33",
71: "a34",
72: "a35",
73: "a36",
74: "a37",
75: "a38",
76: "a39",
77: "a40",
78: "a41",
79: "a42",
80: "a43",
81: "a44",
82: "a45",
83: "a46",
84: "a47",
85: "a48",
86: "a49",
87: "a50",
88: "a51",
89: "a52",
90: "a53",
91: "a54",
92: "a55",
93: "a56",
94: "a57",
95: "a58",
96: "a59",
97: "a60",
98: "a61",
99: "a62",
100: "a63",
101: "a64",
102: "a65",
103: "a66",
104: "a67",
105: "a68",
106: "a69",
107: "a70",
108: "a71",
109: "a72",
110: "a73",
111: "a74",
112: "a203",
113: "a75",
114: "a204",
115: "a76",
116: "a77",
117: "a78",
118: "a79",
119: "a81",
120: "a82",
121: "a83",
122: "a84",
123: "a97",
124: "a98",
125: "a99",
126: "a100",
128: "a89",
129: "a90",
130: "a93",
131: "a94",
132: "a91",
133: "a92",
134: "a205",
135: "a85",
136: "a206",
137: "a86",
138: "a87",
139: "a88",
140: "a95",
141: "a96",
161: "a101",
162: "a102",
163: "a103",
164: "a104",
165: "a106",
166: "a107",
167: "a108",
168: "a112",
169: "a111",
170: "a110",
171: "a109",
172: "a120",
173: "a121",
174: "a122",
175: "a123",
176: "a124",
177: "a125",
178: "a126",
179: "a127",
180: "a128",
181: "a129",
182: "a130",
183: "a131",
184: "a132",
185: "a133",
186: "a134",
187: "a135",
188: "a136",
189: "a137",
190: "a138",
191: "a139",
192: "a140",
193: "a141",
194: "a142",
195: "a143",
196: "a144",
197: "a145",
198: "a146",
199: "a147",
200: "a148",
201: "a149",
202: "a150",
203: "a151",
204: "a152",
205: "a153",
206: "a154",
207: "a155",
208: "a156",
209: "a157",
210: "a158",
211: "a159",
212: "a160",
213: "a161",
214: "a163",
215: "a164",
216: "a196",
217: "a165",
218: "a192",
219: "a166",
220: "a167",
221: "a168",
222: "a169",
223: "a170",
224: "a171",
225: "a172",
226: "a173",
227: "a162",
228: "a174",
229: "a175",
230: "a176",
231: "a177",
232: "a178",
233: "a179",
234: "a193",
235: "a180",
236: "a199",
237: "a181",
238: "a200",
239: "a182",
241: "a201",
242: "a183",
243: "a184",
244: "a197",
245: "a185",
246: "a194",
247: "a198",
248: "a186",
249: "a195",
250: "a187",
251: "a188",
252: "a189",
253: "a190",
254: "a191",
}
var zapfDingbatsEncodingGlyphToCharcodeMap = map[string]byte{
"space": 32,
"a1": 33,
"a2": 34,
"a202": 35,
"a3": 36,
"a4": 37,
"a5": 38,
"a119": 39,
"a118": 40,
"a117": 41,
"a11": 42,
"a12": 43,
"a13": 44,
"a14": 45,
"a15": 46,
"a16": 47,
"a105": 48,
"a17": 49,
"a18": 50,
"a19": 51,
"a20": 52,
"a21": 53,
"a22": 54,
"a23": 55,
"a24": 56,
"a25": 57,
"a26": 58,
"a27": 59,
"a28": 60,
"a6": 61,
"a7": 62,
"a8": 63,
"a9": 64,
"a10": 65,
"a29": 66,
"a30": 67,
"a31": 68,
"a32": 69,
"a33": 70,
"a34": 71,
"a35": 72,
"a36": 73,
"a37": 74,
"a38": 75,
"a39": 76,
"a40": 77,
"a41": 78,
"a42": 79,
"a43": 80,
"a44": 81,
"a45": 82,
"a46": 83,
"a47": 84,
"a48": 85,
"a49": 86,
"a50": 87,
"a51": 88,
"a52": 89,
"a53": 90,
"a54": 91,
"a55": 92,
"a56": 93,
"a57": 94,
"a58": 95,
"a59": 96,
"a60": 97,
"a61": 98,
"a62": 99,
"a63": 100,
"a64": 101,
"a65": 102,
"a66": 103,
"a67": 104,
"a68": 105,
"a69": 106,
"a70": 107,
"a71": 108,
"a72": 109,
"a73": 110,
"a74": 111,
"a203": 112,
"a75": 113,
"a204": 114,
"a76": 115,
"a77": 116,
"a78": 117,
"a79": 118,
"a81": 119,
"a82": 120,
"a83": 121,
"a84": 122,
"a97": 123,
"a98": 124,
"a99": 125,
"a100": 126,
"a89": 128,
"a90": 129,
"a93": 130,
"a94": 131,
"a91": 132,
"a92": 133,
"a205": 134,
"a85": 135,
"a206": 136,
"a86": 137,
"a87": 138,
"a88": 139,
"a95": 140,
"a96": 141,
"a101": 161,
"a102": 162,
"a103": 163,
"a104": 164,
"a106": 165,
"a107": 166,
"a108": 167,
"a112": 168,
"a111": 169,
"a110": 170,
"a109": 171,
"a120": 172,
"a121": 173,
"a122": 174,
"a123": 175,
"a124": 176,
"a125": 177,
"a126": 178,
"a127": 179,
"a128": 180,
"a129": 181,
"a130": 182,
"a131": 183,
"a132": 184,
"a133": 185,
"a134": 186,
"a135": 187,
"a136": 188,
"a137": 189,
"a138": 190,
"a139": 191,
"a140": 192,
"a141": 193,
"a142": 194,
"a143": 195,
"a144": 196,
"a145": 197,
"a146": 198,
"a147": 199,
"a148": 200,
"a149": 201,
"a150": 202,
"a151": 203,
"a152": 204,
"a153": 205,
"a154": 206,
"a155": 207,
"a156": 208,
"a157": 209,
"a158": 210,
"a159": 211,
"a160": 212,
"a161": 213,
"a163": 214,
"a164": 215,
"a196": 216,
"a165": 217,
"a192": 218,
"a166": 219,
"a167": 220,
"a168": 221,
"a169": 222,
"a170": 223,
"a171": 224,
"a172": 225,
"a173": 226,
"a162": 227,
"a174": 228,
"a175": 229,
"a176": 230,
"a177": 231,
"a178": 232,
"a179": 233,
"a193": 234,
"a180": 235,
"a199": 236,
"a181": 237,
"a200": 238,
"a182": 239,
"a201": 241,
"a183": 242,
"a184": 243,
"a197": 244,
"a185": 245,
"a194": 246,
"a198": 247,
"a186": 248,
"a195": 249,
"a187": 250,
"a188": 251,
"a189": 252,
"a190": 253,
"a191": 254,
}

View File

@@ -0,0 +1,57 @@
package model
import (
"errors"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
func getNumberAsFloat(obj core.PdfObject) (float64, error) {
if fObj, ok := obj.(*core.PdfObjectFloat); ok {
return float64(*fObj), nil
}
if iObj, ok := obj.(*core.PdfObjectInteger); ok {
return float64(*iObj), nil
}
return 0, errors.New("not a number")
}
func isNullObject(obj core.PdfObject) bool {
if _, isNull := obj.(*core.PdfObjectNull); isNull {
return true
} else {
return false
}
}
// Convert a list of pdf objects representing floats or integers to a slice of float64 values.
func getNumbersAsFloat(objects []core.PdfObject) ([]float64, error) {
floats := []float64{}
for _, obj := range objects {
val, err := getNumberAsFloat(obj)
if err != nil {
return nil, err
}
floats = append(floats, val)
}
return floats, nil
}
// Cases where expecting an integer, but some implementations actually
// store the number in a floating point format.
func getNumberAsInt64(obj core.PdfObject) (int64, error) {
if iObj, ok := obj.(*core.PdfObjectInteger); ok {
return int64(*iObj), nil
}
if fObj, ok := obj.(*core.PdfObjectFloat); ok {
common.Log.Debug("Number expected as integer was stored as float (type casting used)")
return int64(*fObj), nil
}
return 0, errors.New("not a number")
}

View File

@@ -0,0 +1,639 @@
package model
import (
"bufio"
"crypto/md5"
"crypto/rand"
"errors"
"fmt"
"io"
"math"
"os"
"time"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
var pdfCreator = ""
func getPdfCreator() string {
if len(pdfCreator) > 0 {
return pdfCreator
}
// Return default.
return ""
}
func SetPdfCreator(creator string) {
pdfCreator = creator
}
type PdfWriter struct {
root *core.PdfIndirectObject
pages *core.PdfIndirectObject
objects []core.PdfObject
objectsMap map[core.PdfObject]bool // Quick lookup table.
writer *bufio.Writer
outlineTree *PdfOutlineTreeNode
catalog *core.PdfObjectDictionary
infoObj *core.PdfIndirectObject
// Encryption
crypter *core.PdfCrypt
encryptDict *core.PdfObjectDictionary
encryptObj *core.PdfIndirectObject
ids *core.PdfObjectArray
// PDF version
majorVersion int
minorVersion int
// Objects to be followed up on prior to writing.
// These are objects that are added and reference objects that are not included
// for writing.
// The map stores the object and the dictionary it is contained in.
// Only way so we can access the dictionary entry later.
pendingObjects map[core.PdfObject]*core.PdfObjectDictionary
// Forms.
acroForm *PdfAcroForm
}
func NewPdfWriter() PdfWriter {
w := PdfWriter{}
w.objectsMap = map[core.PdfObject]bool{}
w.objects = []core.PdfObject{}
w.pendingObjects = map[core.PdfObject]*core.PdfObjectDictionary{}
// PDF Version. Can be changed if using more advanced features in PDF.
// By default it is set to 1.3.
w.majorVersion = 1
w.minorVersion = 3
// Creation info.
infoDict := core.MakeDict()
infoDict.Set("Producer", core.MakeString(""))
infoDict.Set("Creator", core.MakeString(getPdfCreator()))
infoObj := core.PdfIndirectObject{}
infoObj.PdfObject = infoDict
w.infoObj = &infoObj
w.addObject(&infoObj)
// Root catalog.
catalog := core.PdfIndirectObject{}
catalogDict := core.MakeDict()
catalogDict.Set("Type", core.MakeName("Catalog"))
catalog.PdfObject = catalogDict
w.root = &catalog
w.addObject(&catalog)
// Pages.
pages := core.PdfIndirectObject{}
pagedict := core.MakeDict()
pagedict.Set("Type", core.MakeName("Pages"))
kids := core.PdfObjectArray{}
pagedict.Set("Kids", &kids)
pagedict.Set("Count", core.MakeInteger(0))
pages.PdfObject = pagedict
w.pages = &pages
w.addObject(&pages)
catalogDict.Set("Pages", &pages)
w.catalog = catalogDict
common.Log.Trace("Catalog %s", catalog)
return w
}
// Set the PDF version of the output file.
func (pw *PdfWriter) SetVersion(majorVersion, minorVersion int) {
pw.majorVersion = majorVersion
pw.minorVersion = minorVersion
}
// Set the optional content properties.
func (pw *PdfWriter) SetOCProperties(ocProperties core.PdfObject) error {
dict := pw.catalog
if ocProperties != nil {
common.Log.Trace("Setting OC Properties...")
dict.Set("OCProperties", ocProperties)
// Any risk of infinite loops?
pw.addObjects(ocProperties)
}
return nil
}
func (pw *PdfWriter) hasObject(obj core.PdfObject) bool {
// Check if already added.
for _, o := range pw.objects {
// GH: May perform better to use a hash map to check if added?
if o == obj {
return true
}
}
return false
}
// Adds the object to list of objects and returns true if the obj was
// not already added.
// Returns false if the object was previously added.
func (pw *PdfWriter) addObject(obj core.PdfObject) bool {
hasObj := pw.hasObject(obj)
if !hasObj {
pw.objects = append(pw.objects, obj)
return true
}
return false
}
func (pw *PdfWriter) addObjects(obj core.PdfObject) error {
common.Log.Trace("Adding objects!")
if io, isIndirectObj := obj.(*core.PdfIndirectObject); isIndirectObj {
common.Log.Trace("Indirect")
common.Log.Trace("- %s (%p)", obj, io)
common.Log.Trace("- %s", io.PdfObject)
if pw.addObject(io) {
err := pw.addObjects(io.PdfObject)
if err != nil {
return err
}
}
return nil
}
if so, isStreamObj := obj.(*core.PdfObjectStream); isStreamObj {
common.Log.Trace("Stream")
common.Log.Trace("- %s %p", obj, obj)
if pw.addObject(so) {
err := pw.addObjects(so.PdfObjectDictionary)
if err != nil {
return err
}
}
return nil
}
if dict, isDict := obj.(*core.PdfObjectDictionary); isDict {
common.Log.Trace("Dict")
common.Log.Trace("- %s", obj)
for _, k := range dict.Keys() {
v := dict.Get(k)
common.Log.Trace("Key %s", k)
if k != "Parent" {
err := pw.addObjects(v)
if err != nil {
return err
}
} else {
if _, parentIsNull := dict.Get("Parent").(*core.PdfObjectNull); parentIsNull {
// Parent is null. We can ignore it.
continue
}
if hasObj := pw.hasObject(v); !hasObj {
common.Log.Debug("Parent obj is missing!! %T %p %v", v, v, v)
pw.pendingObjects[v] = dict
// Although it is missing at this point, it could be added later...
}
// How to handle the parent? Make sure it is present?
if parentObj, parentIsRef := dict.Get("Parent").(*core.PdfObjectReference); parentIsRef {
// Parent is a reference. Means we can drop it?
// Could refer to somewhere outside of the scope of the output doc.
// Should be done by the reader already.
// -> ERROR.
common.Log.Debug("error: Parent is a reference object - Cannot be in writer (needs to be resolved)")
return fmt.Errorf("parent is a reference object - Cannot be in writer (needs to be resolved) - %s", parentObj)
}
}
}
return nil
}
if arr, isArray := obj.(*core.PdfObjectArray); isArray {
common.Log.Trace("Array")
common.Log.Trace("- %s", obj)
if arr == nil {
return errors.New("array is nil")
}
for _, v := range *arr {
err := pw.addObjects(v)
if err != nil {
return err
}
}
return nil
}
if _, isReference := obj.(*core.PdfObjectReference); isReference {
// Should never be a reference, should already be resolved.
common.Log.Debug("error: Cannot be a reference!")
return errors.New("reference not allowed")
}
return nil
}
// Add a page to the PDF file. The new page should be an indirect
// object.
func (pw *PdfWriter) AddPage(page *PdfPage) error {
obj := page.ToPdfObject()
common.Log.Trace("==========")
common.Log.Trace("Appending to page list %T", obj)
pageObj, ok := obj.(*core.PdfIndirectObject)
if !ok {
return errors.New("page should be an indirect object")
}
common.Log.Trace("%s", pageObj)
common.Log.Trace("%s", pageObj.PdfObject)
pDict, ok := pageObj.PdfObject.(*core.PdfObjectDictionary)
if !ok {
return errors.New("page object should be a dictionary")
}
otype, ok := pDict.Get("Type").(*core.PdfObjectName)
if !ok {
return fmt.Errorf("page should have a Type key with a value of type name (%T)", pDict.Get("Type"))
}
if *otype != "Page" {
return errors.New("type != Page (Required)")
}
// Copy inherited fields if missing.
inheritedFields := []core.PdfObjectName{"Resources", "MediaBox", "CropBox", "Rotate"}
parent, hasParent := pDict.Get("Parent").(*core.PdfIndirectObject)
common.Log.Trace("Page Parent: %T (%v)", pDict.Get("Parent"), hasParent)
for hasParent {
common.Log.Trace("Page Parent: %T", parent)
parentDict, ok := parent.PdfObject.(*core.PdfObjectDictionary)
if !ok {
return errors.New("invalid Parent object")
}
for _, field := range inheritedFields {
common.Log.Trace("Field %s", field)
if pDict.Get(field) != nil {
common.Log.Trace("- page has already")
continue
}
if obj := parentDict.Get(field); obj != nil {
// Parent has the field. Inherit, pass to the new page.
common.Log.Trace("Inheriting field %s", field)
pDict.Set(field, obj)
}
}
parent, hasParent = parentDict.Get("Parent").(*core.PdfIndirectObject)
common.Log.Trace("Next parent: %T", parentDict.Get("Parent"))
}
common.Log.Trace("Traversal done")
// Update the dictionary.
// Reuses the input object, updating the fields.
pDict.Set("Parent", pw.pages)
pageObj.PdfObject = pDict
// Add to Pages.
pagesDict, ok := pw.pages.PdfObject.(*core.PdfObjectDictionary)
if !ok {
return errors.New("invalid Pages obj (not a dict)")
}
kids, ok := pagesDict.Get("Kids").(*core.PdfObjectArray)
if !ok {
return errors.New("invalid Pages Kids obj (not an array)")
}
*kids = append(*kids, pageObj)
pageCount, ok := pagesDict.Get("Count").(*core.PdfObjectInteger)
if !ok {
return errors.New("invalid Pages Count object (not an integer)")
}
// Update the count.
*pageCount = *pageCount + 1
pw.addObject(pageObj)
// Traverse the page and record all object references.
err := pw.addObjects(pDict)
if err != nil {
return err
}
return nil
}
// Add outlines to a PDF file.
func (pw *PdfWriter) AddOutlineTree(outlineTree *PdfOutlineTreeNode) {
pw.outlineTree = outlineTree
}
// Add Acroforms to a PDF file. Sets the specified form for writing.
func (pw *PdfWriter) SetForms(form *PdfAcroForm) error {
pw.acroForm = form
return nil
}
// Write out an indirect / stream object.
func (pw *PdfWriter) writeObject(num int, obj core.PdfObject) {
common.Log.Trace("Write obj #%d\n", num)
if pobj, isIndirect := obj.(*core.PdfIndirectObject); isIndirect {
outStr := fmt.Sprintf("%d 0 obj\n", num)
outStr += pobj.PdfObject.DefaultWriteString()
outStr += "\nendobj\n"
pw.writer.WriteString(outStr)
return
}
// XXX/TODO: Add a default encoder if Filter not specified?
// Still need to make sure is encrypted.
if pobj, isStream := obj.(*core.PdfObjectStream); isStream {
outStr := fmt.Sprintf("%d 0 obj\n", num)
outStr += pobj.PdfObjectDictionary.DefaultWriteString()
outStr += "\nstream\n"
pw.writer.WriteString(outStr)
pw.writer.Write(pobj.Stream)
pw.writer.WriteString("\nendstream\nendobj\n")
return
}
pw.writer.WriteString(obj.DefaultWriteString())
}
// Update all the object numbers prior to writing.
func (pw *PdfWriter) updateObjectNumbers() {
// Update numbers
for idx, obj := range pw.objects {
if io, isIndirect := obj.(*core.PdfIndirectObject); isIndirect {
io.ObjectNumber = int64(idx + 1)
io.GenerationNumber = 0
}
if so, isStream := obj.(*core.PdfObjectStream); isStream {
so.ObjectNumber = int64(idx + 1)
so.GenerationNumber = 0
}
}
}
type EncryptOptions struct {
Permissions core.AccessPermissions
Algorithm EncryptionAlgorithm
}
// EncryptionAlgorithm is used in EncryptOptions to change the default algorithm used to encrypt the document.
type EncryptionAlgorithm int
const (
// RC4_128bit uses RC4 encryption (128 bit)
RC4_128bit = EncryptionAlgorithm(iota)
// AES_128bit uses AES encryption (128 bit, PDF 1.6)
AES_128bit
// AES_256bit uses AES encryption (256 bit, PDF 2.0)
AES_256bit
)
// Encrypt the output file with a specified user/owner password.
func (pw *PdfWriter) Encrypt(userPass, ownerPass []byte, options *EncryptOptions) error {
crypter := core.PdfCrypt{}
pw.crypter = &crypter
crypter.EncryptedObjects = map[core.PdfObject]bool{}
crypter.CryptFilters = core.CryptFilters{}
algo := RC4_128bit
if options != nil {
algo = options.Algorithm
}
var cf core.CryptFilter
switch algo {
case RC4_128bit:
crypter.V = 2
crypter.R = 3
cf = core.NewCryptFilterV2(16)
case AES_128bit:
pw.SetVersion(1, 5)
crypter.V = 4
crypter.R = 4
cf = core.NewCryptFilterAESV2()
case AES_256bit:
pw.SetVersion(2, 0)
crypter.V = 5
crypter.R = 6 // TODO(dennwc): a way to set R=5?
cf = core.NewCryptFilterAESV3()
default:
return fmt.Errorf("unsupported algorithm: %v", options.Algorithm)
}
crypter.Length = cf.Length * 8
const (
defaultFilter = core.StandardCryptFilter
)
crypter.CryptFilters[defaultFilter] = cf
if crypter.V >= 4 {
crypter.StreamFilter = defaultFilter
crypter.StringFilter = defaultFilter
}
// Set
crypter.P = math.MaxUint32
crypter.EncryptMetadata = true
if options != nil {
crypter.P = int(options.Permissions.GetP())
}
// Generate the encryption dictionary.
ed := core.MakeDict()
ed.Set("Filter", core.MakeName("Standard"))
ed.Set("P", core.MakeInteger(int64(crypter.P)))
ed.Set("V", core.MakeInteger(int64(crypter.V)))
ed.Set("R", core.MakeInteger(int64(crypter.R)))
ed.Set("Length", core.MakeInteger(int64(crypter.Length)))
pw.encryptDict = ed
// Prepare the ID object for the trailer.
hashcode := md5.Sum([]byte(time.Now().Format(time.RFC850)))
id0 := core.PdfObjectString(hashcode[:])
b := make([]byte, 100)
rand.Read(b)
hashcode = md5.Sum(b)
id1 := core.PdfObjectString(hashcode[:])
common.Log.Trace("Random b: % x", b)
pw.ids = &core.PdfObjectArray{&id0, &id1}
common.Log.Trace("Gen Id 0: % x", id0)
// Generate encryption parameters
if crypter.R < 5 {
crypter.Id0 = string(id0)
// Make the O and U objects.
O, err := crypter.Alg3(userPass, ownerPass)
if err != nil {
common.Log.Debug("error: Error generating O for encryption (%s)", err)
return err
}
crypter.O = []byte(O)
common.Log.Trace("gen O: % x", O)
U, key, err := crypter.Alg5(userPass)
if err != nil {
common.Log.Debug("error: Error generating O for encryption (%s)", err)
return err
}
common.Log.Trace("gen U: % x", U)
crypter.U = []byte(U)
crypter.EncryptionKey = key
ed.Set("O", &O)
ed.Set("U", &U)
} else { // R >= 5
err := crypter.GenerateParams(userPass, ownerPass)
if err != nil {
return err
}
ed.Set("O", core.MakeString(string(crypter.O)))
ed.Set("U", core.MakeString(string(crypter.U)))
ed.Set("OE", core.MakeString(string(crypter.OE)))
ed.Set("UE", core.MakeString(string(crypter.UE)))
ed.Set("EncryptMetadata", core.MakeBool(crypter.EncryptMetadata))
if crypter.R > 5 {
ed.Set("Perms", core.MakeString(string(crypter.Perms)))
}
}
if crypter.V >= 4 {
if err := crypter.SaveCryptFilters(ed); err != nil {
return err
}
}
// Make an object to contain the encryption dictionary.
io := core.MakeIndirectObject(ed)
pw.encryptObj = io
pw.addObject(io)
return nil
}
// Write the pdf out.
func (pw *PdfWriter) Write(ws io.WriteSeeker) error {
// Outlines.
if pw.outlineTree != nil {
common.Log.Trace("OutlineTree: %+v", pw.outlineTree)
outlines := pw.outlineTree.ToPdfObject()
common.Log.Trace("Outlines: %+v (%T, p:%p)", outlines, outlines, outlines)
pw.catalog.Set("Outlines", outlines)
err := pw.addObjects(outlines)
if err != nil {
return err
}
}
// Form fields.
if pw.acroForm != nil {
common.Log.Trace("Writing acro forms")
indObj := pw.acroForm.ToPdfObject()
common.Log.Trace("AcroForm: %+v", indObj)
pw.catalog.Set("AcroForm", indObj)
err := pw.addObjects(indObj)
if err != nil {
return err
}
}
// Check pending objects prior to write.
for pendingObj, pendingObjDict := range pw.pendingObjects {
if !pw.hasObject(pendingObj) {
common.Log.Debug("error Pending object %+v %T (%p) never added for writing", pendingObj, pendingObj, pendingObj)
for _, key := range pendingObjDict.Keys() {
val := pendingObjDict.Get(key)
if val == pendingObj {
common.Log.Debug("Pending object found! and replaced with null")
pendingObjDict.Set(key, core.MakeNull())
break
}
}
}
}
// Set version in the catalog.
pw.catalog.Set("Version", core.MakeName(fmt.Sprintf("%d.%d", pw.majorVersion, pw.minorVersion)))
w := bufio.NewWriter(ws)
pw.writer = w
w.WriteString(fmt.Sprintf("%%PDF-%d.%d\n", pw.majorVersion, pw.minorVersion))
w.WriteString("%âãÏÓ\n")
w.Flush()
pw.updateObjectNumbers()
offsets := []int64{}
// Write objects
common.Log.Trace("Writing %d obj", len(pw.objects))
for idx, obj := range pw.objects {
common.Log.Trace("Writing %d", idx)
pw.writer.Flush()
offset, _ := ws.Seek(0, os.SEEK_CUR)
offsets = append(offsets, offset)
// Encrypt prior to writing.
// Encrypt dictionary should not be encrypted.
if pw.crypter != nil && obj != pw.encryptObj {
err := pw.crypter.Encrypt(obj, int64(idx+1), 0)
if err != nil {
common.Log.Debug("error: Failed encrypting (%s)", err)
return err
}
}
pw.writeObject(idx+1, obj)
}
w.Flush()
xrefOffset, _ := ws.Seek(0, os.SEEK_CUR)
// Write xref table.
pw.writer.WriteString("xref\r\n")
outStr := fmt.Sprintf("%d %d\r\n", 0, len(pw.objects)+1)
pw.writer.WriteString(outStr)
outStr = fmt.Sprintf("%.10d %.5d f\r\n", 0, 65535)
pw.writer.WriteString(outStr)
for _, offset := range offsets {
outStr = fmt.Sprintf("%.10d %.5d n\r\n", offset, 0)
pw.writer.WriteString(outStr)
}
// Generate & write trailer
trailer := core.MakeDict()
trailer.Set("Info", pw.infoObj)
trailer.Set("Root", pw.root)
trailer.Set("Size", core.MakeInteger(int64(len(pw.objects)+1)))
// If encrypted!
if pw.crypter != nil {
trailer.Set("Encrypt", pw.encryptObj)
trailer.Set("ID", pw.ids)
common.Log.Trace("Ids: %s", pw.ids)
}
pw.writer.WriteString("trailer\n")
pw.writer.WriteString(trailer.DefaultWriteString())
pw.writer.WriteString("\n")
// Make offset reference.
outStr = fmt.Sprintf("startxref\n%d\n", xrefOffset)
pw.writer.WriteString(outStr)
pw.writer.WriteString("%%EOF\n")
w.Flush()
return nil
}

View File

@@ -0,0 +1,588 @@
package model
import (
"errors"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/common"
"gitea.tecamino.com/paadi/pdfmerge/internal/pdf/core"
)
// XObjectForm (Table 95 in 8.10.2).
type XObjectForm struct {
Filter core.StreamEncoder
FormType core.PdfObject
BBox core.PdfObject
Matrix core.PdfObject
Resources *PdfPageResources
Group core.PdfObject
Ref core.PdfObject
MetaData core.PdfObject
PieceInfo core.PdfObject
LastModified core.PdfObject
StructParent core.PdfObject
StructParents core.PdfObject
OPI core.PdfObject
OC core.PdfObject
Name core.PdfObject
// Stream data.
Stream []byte
// Primitive
primitive *core.PdfObjectStream
}
var ErrTypeCheck = errors.New("type check error")
// Create a brand new XObject Form. Creates a new underlying PDF object stream primitive.
func NewXObjectForm() *XObjectForm {
xobj := &XObjectForm{}
stream := &core.PdfObjectStream{}
stream.PdfObjectDictionary = core.MakeDict()
xobj.primitive = stream
return xobj
}
// Build the Form XObject from a stream object.
// XXX: Should this be exposed? Consider different access points.
func NewXObjectFormFromStream(stream *core.PdfObjectStream) (*XObjectForm, error) {
form := &XObjectForm{}
form.primitive = stream
dict := *(stream.PdfObjectDictionary)
encoder, err := core.NewEncoderFromStream(stream)
if err != nil {
return nil, err
}
form.Filter = encoder
if obj := dict.Get("Subtype"); obj != nil {
name, ok := obj.(*core.PdfObjectName)
if !ok {
return nil, errors.New("type error")
}
if *name != "Form" {
common.Log.Debug("invalid form subtype")
return nil, errors.New("invalid form subtype")
}
}
if obj := dict.Get("FormType"); obj != nil {
form.FormType = obj
}
if obj := dict.Get("BBox"); obj != nil {
form.BBox = obj
}
if obj := dict.Get("Matrix"); obj != nil {
form.Matrix = obj
}
if obj := dict.Get("Resources"); obj != nil {
obj = core.TraceToDirectObject(obj)
d, ok := obj.(*core.PdfObjectDictionary)
if !ok {
common.Log.Debug("invalid XObject Form Resources object, pointing to non-dictionary")
return nil, errors.New("type check error")
}
res, err := NewPdfPageResourcesFromDict(d)
if err != nil {
common.Log.Debug("Failed getting form resources")
return nil, err
}
form.Resources = res
common.Log.Trace("Form resources: %#v", form.Resources)
}
form.Group = dict.Get("Group")
form.Ref = dict.Get("Ref")
form.MetaData = dict.Get("MetaData")
form.PieceInfo = dict.Get("PieceInfo")
form.LastModified = dict.Get("LastModified")
form.StructParent = dict.Get("StructParent")
form.StructParents = dict.Get("StructParents")
form.OPI = dict.Get("OPI")
form.OC = dict.Get("OC")
form.Name = dict.Get("Name")
form.Stream = stream.Stream
return form, nil
}
func (xform *XObjectForm) GetContainingPdfObject() core.PdfObject {
return xform.primitive
}
func (xform *XObjectForm) GetContentStream() ([]byte, error) {
decoded, err := core.DecodeStream(xform.primitive)
if err != nil {
return nil, err
}
return decoded, nil
}
// Update the content stream with specified encoding. If encoding is null, will use the xform.Filter object
// or Raw encoding if not set.
func (xform *XObjectForm) SetContentStream(content []byte, encoder core.StreamEncoder) error {
encoded := content
if encoder == nil {
if xform.Filter != nil {
encoder = xform.Filter
} else {
encoder = core.NewRawEncoder()
}
}
enc, err := encoder.EncodeBytes(encoded)
if err != nil {
return err
}
encoded = enc
xform.Stream = encoded
return nil
}
// Return a stream object.
func (xform *XObjectForm) ToPdfObject() core.PdfObject {
stream := xform.primitive
dict := stream.PdfObjectDictionary
if xform.Filter != nil {
// Pre-populate the stream dictionary with the encoding related fields.
dict = xform.Filter.MakeStreamDict()
stream.PdfObjectDictionary = dict
}
dict.Set("Type", core.MakeName("XObject"))
dict.Set("Subtype", core.MakeName("Form"))
dict.SetIfNotNil("FormType", xform.FormType)
dict.SetIfNotNil("BBox", xform.BBox)
dict.SetIfNotNil("Matrix", xform.Matrix)
if xform.Resources != nil {
dict.SetIfNotNil("Resources", xform.Resources.ToPdfObject())
}
dict.SetIfNotNil("Group", xform.Group)
dict.SetIfNotNil("Ref", xform.Ref)
dict.SetIfNotNil("MetaData", xform.MetaData)
dict.SetIfNotNil("PieceInfo", xform.PieceInfo)
dict.SetIfNotNil("LastModified", xform.LastModified)
dict.SetIfNotNil("StructParent", xform.StructParent)
dict.SetIfNotNil("StructParents", xform.StructParents)
dict.SetIfNotNil("OPI", xform.OPI)
dict.SetIfNotNil("OC", xform.OC)
dict.SetIfNotNil("Name", xform.Name)
dict.Set("Length", core.MakeInteger(int64(len(xform.Stream))))
stream.Stream = xform.Stream
return stream
}
// XObjectImage (Table 89 in 8.9.5.1).
// Implements PdfModel interface.
type XObjectImage struct {
//ColorSpace PdfObject
Width *int64
Height *int64
ColorSpace PdfColorspace
BitsPerComponent *int64
Filter core.StreamEncoder
Intent core.PdfObject
ImageMask core.PdfObject
Mask core.PdfObject
Matte core.PdfObject
Decode core.PdfObject
Interpolate core.PdfObject
Alternatives core.PdfObject
SMask core.PdfObject
SMaskInData core.PdfObject
Name core.PdfObject // Obsolete. Currently read if available and write if available. Not setting on new created files.
StructParent core.PdfObject
ID core.PdfObject
OPI core.PdfObject
Metadata core.PdfObject
OC core.PdfObject
Stream []byte
// Primitive
primitive *core.PdfObjectStream
}
func NewXObjectImage() *XObjectImage {
xobj := &XObjectImage{}
stream := &core.PdfObjectStream{}
stream.PdfObjectDictionary = core.MakeDict()
xobj.primitive = stream
return xobj
}
// Creates a new XObject Image from an image object with default options.
// If encoder is nil, uses raw encoding (none).
func NewXObjectImageFromImage(img *Image, cs PdfColorspace, encoder core.StreamEncoder) (*XObjectImage, error) {
xobj := NewXObjectImage()
return UpdateXObjectImageFromImage(xobj, img, cs, encoder)
}
// UpdateXObjectImageFromImage creates a new XObject Image from an Image object `img` and default
//
// masks from xobjIn.
//
// The default masks are overriden if img.hasAlpha
// If `encoder` is nil, uses raw encoding (none).
func UpdateXObjectImageFromImage(xobjIn *XObjectImage, img *Image, cs PdfColorspace,
encoder core.StreamEncoder) (*XObjectImage, error) {
xobj := NewXObjectImage()
if encoder == nil {
encoder = core.NewRawEncoder()
}
encoded, err := encoder.EncodeBytes(img.Data)
if err != nil {
common.Log.Debug("error with encoding: %v", err)
return nil, err
}
xobj.Filter = encoder
xobj.Stream = encoded
// Width and height.
imWidth := img.Width
imHeight := img.Height
xobj.Width = &imWidth
xobj.Height = &imHeight
// Bits.
xobj.BitsPerComponent = &img.BitsPerComponent
// Guess colorspace if not explicitly set.
if cs == nil {
switch img.ColorComponents {
case 1:
xobj.ColorSpace = NewPdfColorspaceDeviceGray()
case 3:
xobj.ColorSpace = NewPdfColorspaceDeviceRGB()
case 4:
xobj.ColorSpace = NewPdfColorspaceDeviceCMYK()
default:
return nil, errors.New("colorspace undefined")
}
} else {
xobj.ColorSpace = cs
}
if img.hasAlpha {
// Add the alpha channel information as a stencil mask (SMask).
// Has same width and height as original and stored in same
// bits per component (1 component, hence the DeviceGray channel).
smask := NewXObjectImage()
smask.Filter = encoder
encoded, err := encoder.EncodeBytes(img.alphaData)
if err != nil {
common.Log.Debug("error with encoding: %v", err)
return nil, err
}
smask.Stream = encoded
smask.BitsPerComponent = &img.BitsPerComponent
smask.Width = &img.Width
smask.Height = &img.Height
smask.ColorSpace = NewPdfColorspaceDeviceGray()
xobj.SMask = smask.ToPdfObject()
} else {
xobj.SMask = xobjIn.SMask
xobj.ImageMask = xobjIn.ImageMask
if xobj.ColorSpace.GetNumComponents() == 1 {
smaskMatteToGray(xobj)
}
}
return xobj, nil
}
// smaskMatteToGray converts to gray the Matte value in the SMask image referenced by `xobj` (if
// there is one)
func smaskMatteToGray(xobj *XObjectImage) error {
if xobj.SMask == nil {
return nil
}
stream, ok := xobj.SMask.(*core.PdfObjectStream)
if !ok {
common.Log.Debug("SMask is not *PdfObjectStream")
return ErrTypeCheck
}
dict := stream.PdfObjectDictionary
matte := dict.Get("Matte")
if matte == nil {
return nil
}
gray, err := toGray(matte.(*core.PdfObjectArray))
if err != nil {
return err
}
grayMatte := core.MakeArrayFromFloats([]float64{gray})
dict.SetIfNotNil("Matte", grayMatte)
return nil
}
// toGray converts a 1, 3 or 4 dimensional color `matte` to gray
// If `matte` is not a 1, 3 or 4 dimensional color then an error is returned
func toGray(matte *core.PdfObjectArray) (float64, error) {
colors, err := matte.ToFloat64Array()
if err != nil {
common.Log.Debug("Bad Matte array: matte=%s err=%v", matte, err)
}
switch len(colors) {
case 1:
return colors[0], nil
case 3:
cs := PdfColorspaceDeviceRGB{}
rgbColor, err := cs.ColorFromFloats(colors)
if err != nil {
return 0.0, err
}
return rgbColor.(*PdfColorDeviceRGB).ToGray().Val(), nil
case 4:
cs := PdfColorspaceDeviceCMYK{}
cmykColor, err := cs.ColorFromFloats(colors)
if err != nil {
return 0.0, err
}
rgbColor, err := cs.ColorToRGB(cmykColor.(*PdfColorDeviceCMYK))
if err != nil {
return 0.0, err
}
return rgbColor.(*PdfColorDeviceRGB).ToGray().Val(), nil
}
err = errors.New("bad Matte color")
common.Log.Error("toGray: matte=%s err=%v", matte, err)
return 0.0, err
}
// Build the image xobject from a stream object.
// An image dictionary is the dictionary portion of a stream object representing an image XObject.
func NewXObjectImageFromStream(stream *core.PdfObjectStream) (*XObjectImage, error) {
img := &XObjectImage{}
img.primitive = stream
dict := *(stream.PdfObjectDictionary)
encoder, err := core.NewEncoderFromStream(stream)
if err != nil {
return nil, err
}
img.Filter = encoder
if obj := core.TraceToDirectObject(dict.Get("Width")); obj != nil {
iObj, ok := obj.(*core.PdfObjectInteger)
if !ok {
return nil, errors.New("invalid image width object")
}
iVal := int64(*iObj)
img.Width = &iVal
} else {
return nil, errors.New("width missing")
}
if obj := core.TraceToDirectObject(dict.Get("Height")); obj != nil {
iObj, ok := obj.(*core.PdfObjectInteger)
if !ok {
return nil, errors.New("invalid image height object")
}
iVal := int64(*iObj)
img.Height = &iVal
} else {
return nil, errors.New("height missing")
}
if obj := core.TraceToDirectObject(dict.Get("ColorSpace")); obj != nil {
cs, err := NewPdfColorspaceFromPdfObject(obj)
if err != nil {
return nil, err
}
img.ColorSpace = cs
} else {
// If not specified, assume gray..
common.Log.Debug("XObject Image colorspace not specified - assuming 1 color component")
img.ColorSpace = NewPdfColorspaceDeviceGray()
}
if obj := core.TraceToDirectObject(dict.Get("BitsPerComponent")); obj != nil {
iObj, ok := obj.(*core.PdfObjectInteger)
if !ok {
return nil, errors.New("invalid image height object")
}
iVal := int64(*iObj)
img.BitsPerComponent = &iVal
}
img.Intent = dict.Get("Intent")
img.ImageMask = dict.Get("ImageMask")
img.Mask = dict.Get("Mask")
img.Decode = dict.Get("Decode")
img.Interpolate = dict.Get("Interpolate")
img.Alternatives = dict.Get("Alternatives")
img.SMask = dict.Get("SMask")
img.SMaskInData = dict.Get("SMaskInData")
img.Matte = dict.Get("Matte")
img.Name = dict.Get("Name")
img.StructParent = dict.Get("StructParent")
img.ID = dict.Get("ID")
img.OPI = dict.Get("OPI")
img.Metadata = dict.Get("Metadata")
img.OC = dict.Get("OC")
img.Stream = stream.Stream
return img, nil
}
// Update XObject Image with new image data.
func (ximg *XObjectImage) SetImage(img *Image, cs PdfColorspace) error {
encoded, err := ximg.Filter.EncodeBytes(img.Data)
if err != nil {
return err
}
ximg.Stream = encoded
// Width, height and bits.
ximg.Width = &img.Width
ximg.Height = &img.Height
ximg.BitsPerComponent = &img.BitsPerComponent
// Guess colorspace if not explicitly set.
if cs == nil {
switch img.ColorComponents {
case 1:
ximg.ColorSpace = NewPdfColorspaceDeviceGray()
case 3:
ximg.ColorSpace = NewPdfColorspaceDeviceRGB()
case 4:
ximg.ColorSpace = NewPdfColorspaceDeviceCMYK()
default:
return errors.New("colorspace undefined")
}
} else {
ximg.ColorSpace = cs
}
return nil
}
// Set compression filter. Decodes with current filter sets and encodes the data with the new filter.
func (ximg *XObjectImage) SetFilter(encoder core.StreamEncoder) error {
encoded := ximg.Stream
decoded, err := ximg.Filter.DecodeBytes(encoded)
if err != nil {
return err
}
ximg.Filter = encoder
encoded, err = encoder.EncodeBytes(decoded)
if err != nil {
return err
}
ximg.Stream = encoded
return nil
}
// This will convert to an Image which can be transformed or saved out.
// The image data is decoded and the Image returned.
func (ximg *XObjectImage) ToImage() (*Image, error) {
image := &Image{}
if ximg.Height == nil {
return nil, errors.New("height attribute missing")
}
image.Height = *ximg.Height
if ximg.Width == nil {
return nil, errors.New("width attribute missing")
}
image.Width = *ximg.Width
if ximg.BitsPerComponent == nil {
return nil, errors.New("bits per component missing")
}
image.BitsPerComponent = *ximg.BitsPerComponent
image.ColorComponents = ximg.ColorSpace.GetNumComponents()
decoded, err := core.DecodeStream(ximg.primitive)
if err != nil {
return nil, err
}
image.Data = decoded
if ximg.Decode != nil {
darr, ok := ximg.Decode.(*core.PdfObjectArray)
if !ok {
common.Log.Debug("invalid Decode object")
return nil, errors.New("invalid type")
}
decode, err := darr.ToFloat64Array()
if err != nil {
return nil, err
}
image.decode = decode
}
return image, nil
}
func (ximg *XObjectImage) GetContainingPdfObject() core.PdfObject {
return ximg.primitive
}
// Return a stream object.
func (ximg *XObjectImage) ToPdfObject() core.PdfObject {
stream := ximg.primitive
dict := stream.PdfObjectDictionary
if ximg.Filter != nil {
//dict.Set("Filter", ximg.Filter)
// Pre-populate the stream dictionary with the
// encoding related fields.
dict = ximg.Filter.MakeStreamDict()
stream.PdfObjectDictionary = dict
}
dict.Set("Type", core.MakeName("XObject"))
dict.Set("Subtype", core.MakeName("Image"))
dict.Set("Width", core.MakeInteger(*(ximg.Width)))
dict.Set("Height", core.MakeInteger(*(ximg.Height)))
if ximg.BitsPerComponent != nil {
dict.Set("BitsPerComponent", core.MakeInteger(*(ximg.BitsPerComponent)))
}
if ximg.ColorSpace != nil {
dict.SetIfNotNil("ColorSpace", ximg.ColorSpace.ToPdfObject())
}
dict.SetIfNotNil("Intent", ximg.Intent)
dict.SetIfNotNil("ImageMask", ximg.ImageMask)
dict.SetIfNotNil("Mask", ximg.Mask)
dict.SetIfNotNil("Decode", ximg.Decode)
dict.SetIfNotNil("Interpolate", ximg.Interpolate)
dict.SetIfNotNil("Alternatives", ximg.Alternatives)
dict.SetIfNotNil("SMask", ximg.SMask)
dict.SetIfNotNil("SMaskInData", ximg.SMaskInData)
dict.SetIfNotNil("Matte", ximg.Matte)
dict.SetIfNotNil("Name", ximg.Name)
dict.SetIfNotNil("StructParent", ximg.StructParent)
dict.SetIfNotNil("ID", ximg.ID)
dict.SetIfNotNil("OPI", ximg.OPI)
dict.SetIfNotNil("Metadata", ximg.Metadata)
dict.SetIfNotNil("OC", ximg.OC)
dict.Set("Length", core.MakeInteger(int64(len(ximg.Stream))))
stream.Stream = ximg.Stream
return stream
}