func glyphDiffs(cp1, cp2 codepage.CodepageIndex, first, last int) (diffs array) { map1, map2 := cp1.Map(), cp2.Map() same := true for i := first; i <= last; i++ { if same { if map1[i] != map2[i] { same = false r := afm.RuneGlyphs[map2[i]] if r == "" { r = "question" } diffs = append(diffs, integer(i), name(r)) } } else { if map1[i] == map2[i] { same = true } else { r := afm.RuneGlyphs[map2[i]] if r == "" { r = "question" } diffs = append(diffs, name(r)) } } } return }
func (dw *DocWriter) widthsForFontCodepage(f *font.Font, cpi codepage.CodepageIndex) *indirectObject { var widths [256]int upm := f.UnitsPerEm() // Avoid divide by zero error for unusual fonts. if upm > 0 { for i, r := range cpi.Map() { designWidth, _ := f.AdvanceWidth(r) widths[i] = designWidth * 1000 / upm } } pdfWidths := arrayFromInts(widths[32:]) ioWidths := &indirectObject{dw.nextSeq(), 0, &pdfWidths} return ioWidths }
func (dw *DocWriter) fontKey(f *font.Font, cpi codepage.CodepageIndex) string { if f == nil { panic("fontKey: No font specified.") } if !f.HasMetrics() { panic("fontKey: font missing metrics.") } name := fmt.Sprintf("%s/%s-%s", f.PostScriptName(), cpi, f.SubType()) if key, ok := dw.fontKeys[name]; ok { return key } descriptor := newFontDescriptor( dw.nextSeq(), 0, f.PostScriptName(), f.Family(), f.Flags(), f.BoundingBox(), 0, // missingWidth f.StemV(), 0, // stemH f.ItalicAngle(), f.CapHeight(), f.XHeight(), f.Ascent(), f.Descent(), f.Leading(), 0, 0) // maxWidth, avgWidth dw.file.body.add(descriptor) key := fmt.Sprintf("F%d", len(dw.fontKeys)) dw.fontKeys[name] = key widths := dw.widthsForFontCodepage(f, cpi) dw.file.body.add(widths) var font *simpleFont switch f.SubType() { case "Type1": if useStandardEncoding(f.Family()) { font = newType1Font( dw.nextSeq(), 0, f.PostScriptName(), 32, 255, widths, descriptor, nil) } else { encoding, ok := dw.fontEncodings[cpi.String()] if !ok { differences := glyphDiffs(codepage.Idx_CP1252, cpi, 32, 255) encoding = newFontEncoding(dw.nextSeq(), 0, "WinAnsiEncoding", differences) dw.file.body.add(encoding) dw.fontEncodings[cpi.String()] = encoding } font = newType1Font( dw.nextSeq(), 0, f.PostScriptName(), 32, 255, widths, descriptor, &indirectObjectRef{encoding}) } case "TrueType": font = newTrueTypeFont( dw.nextSeq(), 0, f.PostScriptName(), 32, 255, widths, descriptor) } dw.file.body.add(font) dw.resources.fonts[key] = &indirectObjectRef{font} return key }