mirror of
https://github.com/unidoc/unipdf.git
synced 2025-05-02 22:17:06 +08:00
Fixed some issues in creator code
Stopped double converting from Go strings to PDF encoded strings Added TTF parse table format 12
This commit is contained in:
parent
fefff56603
commit
c2feafdfdc
@ -20,9 +20,9 @@ type VectorDrawable interface {
|
||||
Height() float64
|
||||
}
|
||||
|
||||
// DrawContext defines the drawing context. The DrawContext is continuously used and updated when drawing the page
|
||||
// contents in relative mode. Keeps track of current X, Y position, available height as well as other page parameters
|
||||
// such as margins and dimensions.
|
||||
// DrawContext defines the drawing context. The DrawContext is continuously used and updated when
|
||||
// drawing the page contents in relative mode. Keeps track of current X, Y position, available
|
||||
// height as well as other page parameters such as margins and dimensions.
|
||||
type DrawContext struct {
|
||||
// Current page number.
|
||||
Page int
|
||||
|
@ -125,7 +125,7 @@ func (p *Paragraph) SetEnableWrap(enableWrap bool) {
|
||||
p.enableWrap = enableWrap
|
||||
}
|
||||
|
||||
// SetColor set the color of the Paragraph text.
|
||||
// SetColor sets the color of the Paragraph text.
|
||||
//
|
||||
// Example:
|
||||
// 1. p := NewParagraph("Red paragraph")
|
||||
@ -219,7 +219,7 @@ func (p *Paragraph) getTextWidth() float64 {
|
||||
// XXX/TODO: Consider the Knuth/Plass algorithm or an alternative.
|
||||
func (p *Paragraph) wrapText() error {
|
||||
if !p.enableWrap {
|
||||
p.textLines = []string{p.textFont.Encoder().Encode(p.text)}
|
||||
p.textLines = []string{p.text}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -240,8 +240,8 @@ func (p *Paragraph) wrapText() error {
|
||||
|
||||
metrics, found := p.textFont.GetGlyphCharMetrics(glyph)
|
||||
if !found {
|
||||
common.Log.Debug("ERROR: Glyph char metrics not found! %q rune=0x%04x=%c font=%s",
|
||||
glyph, val, val, p.textFont.BaseFont())
|
||||
common.Log.Debug("ERROR: Glyph char metrics not found! %q rune=0x%04x=%c font=%s %#q",
|
||||
glyph, val, val, p.textFont.BaseFont(), p.textFont.Subtype())
|
||||
common.Log.Trace("Font: %#v", p.textFont)
|
||||
common.Log.Trace("Encoder: %#v", p.textFont.Encoder())
|
||||
return errors.New("Glyph char metrics missing")
|
||||
@ -306,7 +306,7 @@ func (p *Paragraph) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext,
|
||||
|
||||
blk := NewBlock(ctx.PageWidth, ctx.PageHeight)
|
||||
if p.positioning.isRelative() {
|
||||
// Account for Paragraph Margins.
|
||||
// Account for Paragraph margins.
|
||||
ctx.X += p.margins.left
|
||||
ctx.Y += p.margins.top
|
||||
ctx.Width -= p.margins.left + p.margins.right
|
||||
@ -408,7 +408,7 @@ func drawParagraphOnBlock(blk *Block, p *Paragraph, ctx DrawContext) (DrawContex
|
||||
// Get width of the line (excluding spaces).
|
||||
w := 0.0
|
||||
spaces := 0
|
||||
for _, runeVal := range runes {
|
||||
for i, runeVal := range runes {
|
||||
glyph, found := p.textFont.Encoder().RuneToGlyph(runeVal)
|
||||
if !found {
|
||||
common.Log.Debug("Rune 0x%x not supported by text encoder", runeVal)
|
||||
@ -420,7 +420,9 @@ func drawParagraphOnBlock(blk *Block, p *Paragraph, ctx DrawContext) (DrawContex
|
||||
}
|
||||
metrics, found := p.textFont.GetGlyphCharMetrics(glyph)
|
||||
if !found {
|
||||
common.Log.Debug("Unsupported glyph %s in font", glyph)
|
||||
common.Log.Debug("Unsupported glyph %q i=%d rune=0x%04x=%c in font %s %s",
|
||||
glyph, i, runeVal, runeVal,
|
||||
p.textFont.BaseFont(), p.textFont.Subtype())
|
||||
return ctx, errors.New("Unsupported text glyph")
|
||||
}
|
||||
|
||||
@ -451,19 +453,13 @@ func drawParagraphOnBlock(blk *Block, p *Paragraph, ctx DrawContext) (DrawContex
|
||||
|
||||
encStr := ""
|
||||
for _, runeVal := range runes {
|
||||
//creator.Add_Tj(core.PdfObjectString(tb.Encoder.Encode(line)))
|
||||
glyph, found := p.textFont.Encoder().RuneToGlyph(runeVal)
|
||||
if !found {
|
||||
common.Log.Debug("Rune 0x%x not supported by text encoder", runeVal)
|
||||
return ctx, errors.New("Unsupported rune in text encoding")
|
||||
}
|
||||
|
||||
if glyph == "space" {
|
||||
if !found {
|
||||
common.Log.Debug("Unsupported glyph %s in font", glyph)
|
||||
return ctx, errors.New("Unsupported text glyph")
|
||||
}
|
||||
|
||||
if glyph == "space" { // XXX: What about \t and other spaces.
|
||||
if len(encStr) > 0 {
|
||||
objs = append(objs, core.MakeString(encStr))
|
||||
encStr = ""
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"errors"
|
||||
|
||||
"github.com/unidoc/unidoc/common"
|
||||
"github.com/unidoc/unidoc/pdf/core"
|
||||
"github.com/unidoc/unidoc/pdf/model"
|
||||
)
|
||||
|
||||
@ -130,7 +131,8 @@ func (table *Table) CurCol() int {
|
||||
return curCol
|
||||
}
|
||||
|
||||
// SetPos sets the Table's positioning to absolute mode and specifies the upper-left corner coordinates as (x,y).
|
||||
// SetPos sets the Table's positioning to absolute mode and specifies the upper-left corner
|
||||
// coordinates as (x,y).
|
||||
// Note that this is only sensible to use when the table does not wrap over multiple pages.
|
||||
// TODO: Should be able to set width too (not just based on context/relative positioning mode).
|
||||
func (table *Table) SetPos(x, y float64) {
|
||||
@ -139,7 +141,8 @@ func (table *Table) SetPos(x, y float64) {
|
||||
table.yPos = y
|
||||
}
|
||||
|
||||
// GeneratePageBlocks generate the page blocks. Multiple blocks are generated if the contents wrap over multiple pages.
|
||||
// GeneratePageBlocks generate the page blocks. Multiple blocks are generated if the contents wrap
|
||||
// over multiple pages.
|
||||
// Implements the Drawable interface.
|
||||
func (table *Table) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) {
|
||||
blocks := []*Block{}
|
||||
@ -232,7 +235,7 @@ func (table *Table) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext,
|
||||
}
|
||||
err := block.Draw(rect)
|
||||
if err != nil {
|
||||
common.Log.Debug("Error: %v\n", err)
|
||||
common.Log.Debug("ERROR: %v\n", err)
|
||||
}
|
||||
} else if cell.borderStyle != CellBorderStyleNone {
|
||||
// Draw border (no fill).
|
||||
@ -244,7 +247,7 @@ func (table *Table) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext,
|
||||
rect.SetBorderColor(ColorRGBFromArithmetic(r, g, b))
|
||||
err := block.Draw(rect)
|
||||
if err != nil {
|
||||
common.Log.Debug("Error: %v\n", err)
|
||||
common.Log.Debug("ERROR: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,7 +293,7 @@ func (table *Table) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext,
|
||||
|
||||
err := block.DrawWithContext(cell.content, ctx)
|
||||
if err != nil {
|
||||
common.Log.Debug("Error: %v\n", err)
|
||||
common.Log.Debug("ERROR: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -515,8 +518,8 @@ func (cell *TableCell) SetContent(vd VectorDrawable) error {
|
||||
}
|
||||
cell.content = vd
|
||||
default:
|
||||
common.Log.Debug("Error: unsupported cell content type %T\n", vd)
|
||||
return errors.New("Type check error")
|
||||
common.Log.Debug("ERROR: unsupported cell content type %T", vd)
|
||||
return core.ErrTypeError
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -146,7 +146,8 @@ func (t *ttfParser) Parse() (TtfType, error) {
|
||||
return TtfType{}, errors.New("fonts based on PostScript outlines are not supported")
|
||||
}
|
||||
if version != "\x00\x01\x00\x00" {
|
||||
common.Log.Debug("ERROR: Unrecognized TrueType file format. version=%q", version)
|
||||
// This is not an error. In the font_test.go example axes.txt we see version "true".
|
||||
common.Log.Debug("Unrecognized TrueType file format. version=%q", version)
|
||||
}
|
||||
numTables := int(t.ReadUShort())
|
||||
t.Skip(3 * 2) // searchRange, entrySelector, rangeShift
|
||||
@ -460,6 +461,8 @@ func (t *ttfParser) parseCmapVersion(offset int64) error {
|
||||
return t.parseCmapFormat0()
|
||||
case 6:
|
||||
return t.parseCmapFormat6()
|
||||
case 12:
|
||||
return t.parseCmapFormat12()
|
||||
default:
|
||||
common.Log.Debug("ERROR: Unsupported cmap format=%d", format)
|
||||
return nil // XXX: Can't return an error here if creator_test.go is to pass.
|
||||
@ -496,6 +499,43 @@ func (t *ttfParser) parseCmapFormat6() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *ttfParser) parseCmapFormat12() error {
|
||||
|
||||
numGroups := t.ReadULong()
|
||||
|
||||
common.Log.Trace("parseCmapFormat12: %s numGroups=%d", t.rec.String(), numGroups)
|
||||
|
||||
for i := uint32(0); i < numGroups; i++ {
|
||||
firstCode := t.ReadULong()
|
||||
endCode := t.ReadULong()
|
||||
startGlyph := t.ReadULong()
|
||||
|
||||
if firstCode > 0x0010FFFF || (0xD800 <= firstCode && firstCode <= 0xDFFF) {
|
||||
return errors.New("Invalid characters codes")
|
||||
}
|
||||
|
||||
if endCode < firstCode || endCode > 0x0010FFFF || (0xD800 <= endCode && endCode <= 0xDFFF) {
|
||||
return errors.New("Invalid characters codes")
|
||||
}
|
||||
|
||||
for j := uint32(0); j <= endCode-firstCode; j++ {
|
||||
glyphId := startGlyph + j
|
||||
// if glyphId >= numGlyphs {
|
||||
// common.Log.Debug("ERROR: Format 12 cmap contains an invalid glyph index")
|
||||
// break
|
||||
// }
|
||||
if firstCode+j > 0x10FFFF {
|
||||
common.Log.Debug("Format 12 cmap contains character beyond UCS-4")
|
||||
}
|
||||
|
||||
t.rec.Chars[uint16(i+firstCode)] = uint16(glyphId)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *ttfParser) ParseName() error {
|
||||
if err := t.Seek("name"); err != nil {
|
||||
return err
|
||||
|
@ -55,7 +55,7 @@ func doEncode(enc TextEncoder, raw string) string {
|
||||
for _, r := range raw {
|
||||
code, found := enc.RuneToCharcode(r)
|
||||
if !found {
|
||||
common.Log.Debug("Failed to map rune to charcode for rune 0x%X", r)
|
||||
common.Log.Debug("Failed to map rune to charcode for rune 0x%04x", r)
|
||||
continue
|
||||
}
|
||||
encoded = append(encoded, byte(code))
|
||||
|
@ -191,7 +191,8 @@ func (se *SimpleEncoder) computeTables() {
|
||||
for code, glyph := range se.differences {
|
||||
r, ok := GlyphToRune(glyph)
|
||||
if !ok {
|
||||
common.Log.Debug("ERROR: No match for glyph=%q differences=%+v", glyph, se.differences)
|
||||
common.Log.Debug("ERROR: No match for glyph=%q differences=%+v", glyph,
|
||||
se.differences)
|
||||
}
|
||||
codeToRune[uint16(code)] = r
|
||||
}
|
||||
@ -208,28 +209,6 @@ func (se *SimpleEncoder) computeTables() {
|
||||
se.codeToGlyph = codeToGlyph
|
||||
se.glyphToCode = glyphToCode
|
||||
se.codeToRune = codeToRune
|
||||
|
||||
if se.baseName == "SymbolEncoding" {
|
||||
fmt.Printf("differences=%+v\n", se.differences)
|
||||
r, ok := se.baseEncoding[0xc6]
|
||||
if !ok {
|
||||
panic("`0")
|
||||
}
|
||||
fmt.Printf("r=0x%04x=%c\n", r, r)
|
||||
r, ok = codeToRune[0xc6]
|
||||
if !ok {
|
||||
panic("`2")
|
||||
}
|
||||
fmt.Printf("r=0x%04x=%c\n", r, r)
|
||||
g, ok := codeToGlyph[0xc6]
|
||||
if !ok {
|
||||
panic("`3")
|
||||
}
|
||||
fmt.Printf("g=%q\n", g)
|
||||
if _, ok := glyphToCode["Delta"]; !ok {
|
||||
panic("`1")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FromFontDifferences converts `diffList`, a /Differences array from an /Encoding object to a map
|
||||
|
Loading…
x
Reference in New Issue
Block a user