mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 14:53:44 +08:00
1 parent
3b9f88cbba
commit
052e34a4e6
6 files changed
+119
-27
No files matched your search
@@ -9,7 +9,7 @@ require (
|
|||||||
github.com/tdewolff/canvas v0.0.0-20260923214215-09804640d00c
|
github.com/tdewolff/canvas v0.0.0-20260923214215-09804640d00c
|
||||||
github.com/tdewolff/font v0.0.0-20260913163313-54f98bb59ee6
|
github.com/tdewolff/font v0.0.0-20260913163313-54f98bb59ee6
|
||||||
github.com/xiaoqidun/jbig2 v1.1.1
|
github.com/xiaoqidun/jbig2 v1.1.1
|
||||||
github.com/xiaoqidun/pdfgo v0.0.0-20260927070002-9eedb7bf8e13
|
github.com/xiaoqidun/pdfgo v0.0.0-20260927082417-6c78229518ef
|
||||||
golang.org/x/crypto v0.57.0
|
golang.org/x/crypto v0.57.0
|
||||||
golang.org/x/image v0.46.0
|
golang.org/x/image v0.46.0
|
||||||
golang.org/x/text v0.42.0
|
golang.org/x/text v0.42.0
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ github.com/tdewolff/test v1.0.12 h1:7F21DqIajswxuche0geHdrUZRCWE4oko4b7bcmkkrxk=
|
|||||||
github.com/tdewolff/test v1.0.12/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
|
github.com/tdewolff/test v1.0.12/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
|
||||||
github.com/xiaoqidun/jbig2 v1.1.1 h1:SjliS9ZO0e9HX5oYUfBuXrfFsXhWricrSz+XY4zORDI=
|
github.com/xiaoqidun/jbig2 v1.1.1 h1:SjliS9ZO0e9HX5oYUfBuXrfFsXhWricrSz+XY4zORDI=
|
||||||
github.com/xiaoqidun/jbig2 v1.1.1/go.mod h1:8QonVWtENmh2kc6l+leqeGl7psb79DWlHDkCpdChjfQ=
|
github.com/xiaoqidun/jbig2 v1.1.1/go.mod h1:8QonVWtENmh2kc6l+leqeGl7psb79DWlHDkCpdChjfQ=
|
||||||
github.com/xiaoqidun/pdfgo v0.0.0-20260927070002-9eedb7bf8e13 h1:P3UEKffubpK6Cqh1ulQysufcw3c+zhEsUv4z+EhqCDA=
|
github.com/xiaoqidun/pdfgo v0.0.0-20260927082417-6c78229518ef h1:GW25sDMcACPksCOx58dKcbV2qWhbhClj6m7nuu+rZbo=
|
||||||
github.com/xiaoqidun/pdfgo v0.0.0-20260927070002-9eedb7bf8e13/go.mod h1:4Pf0JO0BEf1uzRY+uZjlMjN/OPn3PYa0YMi6cqPPTLQ=
|
github.com/xiaoqidun/pdfgo v0.0.0-20260927082417-6c78229518ef/go.mod h1:4Pf0JO0BEf1uzRY+uZjlMjN/OPn3PYa0YMi6cqPPTLQ=
|
||||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||||
github.com/yuin/goldmark v1.8.5 h1:r6N5afV5qj/5S4UTch8agZHJ8UxNCMwX7WjkkJam2NA=
|
github.com/yuin/goldmark v1.8.5 h1:r6N5afV5qj/5S4UTch8agZHJ8UxNCMwX7WjkkJam2NA=
|
||||||
|
|||||||
+41
-4
@@ -608,15 +608,16 @@ func (p *pdfImporter) tilingPattern(source *pdfgo.TilingPattern, base pdfgo.Pain
|
|||||||
const unit = 25.4 / 72
|
const unit = 25.4 / 72
|
||||||
box := source.BBox
|
box := source.BBox
|
||||||
width, height := box.XMax-box.XMin, box.YMax-box.YMin
|
width, height := box.XMax-box.XMin, box.YMax-box.YMin
|
||||||
if width <= 0 || height <= 0 || source.XStep < width || source.YStep < height {
|
xstep, ystep := math.Abs(source.XStep), math.Abs(source.YStep)
|
||||||
return nil, &pdfgo.UnsupportedError{Feature: "overlapping or empty tiling pattern cell"}
|
if width <= 0 || height <= 0 || !finite(xstep) || !finite(ystep) || xstep == 0 || ystep == 0 {
|
||||||
|
return nil, fmt.Errorf("invalid PDF tiling pattern dimensions")
|
||||||
}
|
}
|
||||||
localToPDF := pdfgo.Matrix{1 / unit, 0, 0, -1 / unit, box.XMin, box.YMax}
|
localToPDF := pdfgo.Matrix{1 / unit, 0, 0, -1 / unit, box.XMin, box.YMax}
|
||||||
m := p.matrix.Mul(source.Matrix).Mul(localToPDF)
|
m := p.matrix.Mul(source.Matrix).Mul(localToPDF)
|
||||||
pattern := &Pattern{Width: width * unit, Height: height * unit, XStep: source.XStep * unit, YStep: source.YStep * unit, RelativeTo: "Page", CTM: pdfNumbers(m[:]...)}
|
pattern := &Pattern{Width: math.Min(width, xstep) * unit, Height: math.Min(height, ystep) * unit, XStep: xstep * unit, YStep: ystep * unit, RelativeTo: "Page", CTM: pdfNumbers(m[:]...)}
|
||||||
cell := *p
|
cell := *p
|
||||||
cell.matrix = pdfgo.Matrix{unit, 0, 0, -unit, -box.XMin * unit, box.YMax * unit}
|
cell.matrix = pdfgo.Matrix{unit, 0, 0, -unit, -box.XMin * unit, box.YMax * unit}
|
||||||
cell.pageWidth, cell.pageHeight = pattern.Width, pattern.Height
|
cell.pageWidth, cell.pageHeight = width*unit, height*unit
|
||||||
cell.objects, cell.pendingPath = nil, nil
|
cell.objects, cell.pendingPath = nil, nil
|
||||||
visitor := pdfgo.Visitor{Path: cell.path, Text: cell.text, Image: cell.image}
|
visitor := pdfgo.Visitor{Path: cell.path, Text: cell.text, Image: cell.image}
|
||||||
visitor.Group = func(mark pdfgo.GroupMark, walk func(pdfgo.Visitor) error) error {
|
visitor.Group = func(mark pdfgo.GroupMark, walk func(pdfgo.Visitor) error) error {
|
||||||
@@ -629,6 +630,42 @@ func (p *pdfImporter) tilingPattern(source *pdfgo.TilingPattern, base pdfgo.Pain
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pattern.CellContent.Objects = cell.objects
|
pattern.CellContent.Objects = cell.objects
|
||||||
|
if width > xstep || height > ystep {
|
||||||
|
columns, rows := math.Ceil(width/xstep), math.Ceil(height/ystep)
|
||||||
|
if !finite(columns*rows) || columns*rows > float64(int(^uint(0)>>1)) {
|
||||||
|
return nil, fmt.Errorf("PDF tiling pattern instance count overflow")
|
||||||
|
}
|
||||||
|
bounds := make([]Box, len(cell.objects))
|
||||||
|
for index, object := range cell.objects {
|
||||||
|
if object.Type == "PathObject" && object.PathObject.Stroke != nil && !*object.PathObject.Stroke {
|
||||||
|
var err error
|
||||||
|
bounds[index], err = ParseBox(object.PathObject.Boundary)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pattern.CellContent.Objects = nil
|
||||||
|
for row := 1 - int(rows); row <= 0; row++ {
|
||||||
|
for column := 1 - int(columns); column <= 0; column++ {
|
||||||
|
if err := p.ctx.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dx, dy := float64(column)*xstep*unit, float64(row)*ystep*unit
|
||||||
|
for index, object := range cell.objects {
|
||||||
|
b := bounds[index]
|
||||||
|
if b.W > 0 && b.H > 0 && (b.X+dx+b.W < 0 || b.Y+dy+b.H < 0 || b.X+dx > pattern.Width || b.Y+dy > pattern.Height) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
translated, err := transformEditorObject(object, dx, dy, 1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pattern.CellContent.Objects = append(pattern.CellContent.Objects, translated)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return pattern, nil
|
return pattern, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+53
-16
@@ -29,10 +29,15 @@ import (
|
|||||||
"github.com/xiaoqidun/pdfgo"
|
"github.com/xiaoqidun/pdfgo"
|
||||||
)
|
)
|
||||||
|
|
||||||
// stampAnnotation 将PDF印章外观转换为OFD注解
|
// appearanceAnnotation 将PDF静态外观转换为对应类型的OFD注解
|
||||||
// 入参: ctx取消上下文, page PDF页面, annotation PDF印章
|
// 入参: ctx取消上下文, page PDF页面, annotation PDF注解
|
||||||
// 返回: error 外观或转换错误
|
// 返回: error 外观或转换错误
|
||||||
func (p *pdfImporter) stampAnnotation(ctx context.Context, page *pdfgo.Page, annotation pdfgo.Annotation) error {
|
func (p *pdfImporter) appearanceAnnotation(ctx context.Context, page *pdfgo.Page, annotation pdfgo.Annotation) error {
|
||||||
|
for _, key := range []pdfgo.Name{"AA", "OC"} {
|
||||||
|
if annotation.Dictionary[key] != nil {
|
||||||
|
return &pdfgo.UnsupportedError{Feature: fmt.Sprintf("annotation field %q", key)}
|
||||||
|
}
|
||||||
|
}
|
||||||
flags := int64(0)
|
flags := int64(0)
|
||||||
if value := annotation.Dictionary["F"]; value != nil {
|
if value := annotation.Dictionary["F"]; value != nil {
|
||||||
resolved, err := p.reader.Resolve(value)
|
resolved, err := p.reader.Resolve(value)
|
||||||
@@ -45,6 +50,9 @@ func (p *pdfImporter) stampAnnotation(ctx context.Context, page *pdfgo.Page, ann
|
|||||||
}
|
}
|
||||||
flags = int64(number)
|
flags = int64(number)
|
||||||
}
|
}
|
||||||
|
if flags&256 != 0 {
|
||||||
|
return &pdfgo.UnsupportedError{Feature: "annotation ToggleNoView flag"}
|
||||||
|
}
|
||||||
box := pdfBounds([]pdfgo.Point{
|
box := pdfBounds([]pdfgo.Point{
|
||||||
p.matrix.Apply(pdfgo.Point{X: annotation.Rect.XMin, Y: annotation.Rect.YMin}),
|
p.matrix.Apply(pdfgo.Point{X: annotation.Rect.XMin, Y: annotation.Rect.YMin}),
|
||||||
p.matrix.Apply(pdfgo.Point{X: annotation.Rect.XMax, Y: annotation.Rect.YMin}),
|
p.matrix.Apply(pdfgo.Point{X: annotation.Rect.XMax, Y: annotation.Rect.YMin}),
|
||||||
@@ -69,7 +77,7 @@ func (p *pdfImporter) stampAnnotation(ctx context.Context, page *pdfgo.Page, ann
|
|||||||
return &pdfgo.UnsupportedError{Feature: "darken stamp text"}
|
return &pdfgo.UnsupportedError{Feature: "darken stamp text"}
|
||||||
}
|
}
|
||||||
if err := stamp.text(mark); err != nil {
|
if err := stamp.text(mark); err != nil {
|
||||||
return fmt.Errorf("stamp text: %w", err)
|
return fmt.Errorf("annotation text: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
@@ -99,8 +107,20 @@ func (p *pdfImporter) stampAnnotation(ctx context.Context, page *pdfgo.Page, ann
|
|||||||
}
|
}
|
||||||
p.report.Warnings = append(p.report.Warnings, pdfgo.Diagnostic{Page: p.page + 1, Message: "PDF darken stamp appearance flattened over page content"})
|
p.report.Warnings = append(p.report.Warnings, pdfgo.Diagnostic{Page: p.page + 1, Message: "PDF darken stamp appearance flattened over page content"})
|
||||||
}
|
}
|
||||||
converted := Annotation{Type: "Stamp", Appearance: Appearance{Boundary: pdfBoundary(box), Objects: stamp.objects}}
|
converted := Annotation{Type: pdfAnnotationType(annotation.Subtype), Subtype: string(annotation.Subtype), Appearance: Appearance{Boundary: pdfBoundary(box), Objects: stamp.objects}}
|
||||||
if flags&(1|2|32) != 0 {
|
if value, err := p.reader.Resolve(annotation.Dictionary["Contents"]); err != nil {
|
||||||
|
return err
|
||||||
|
} else if value != nil {
|
||||||
|
contents, ok := value.(pdfgo.String)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("invalid PDF annotation contents")
|
||||||
|
}
|
||||||
|
converted.Remark, err = pdfgo.DecodeTextString(contents)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if flags&(2|32) != 0 {
|
||||||
visible := false
|
visible := false
|
||||||
converted.Visible = &visible
|
converted.Visible = &visible
|
||||||
}
|
}
|
||||||
@@ -113,7 +133,7 @@ func (p *pdfImporter) stampAnnotation(ctx context.Context, page *pdfgo.Page, ann
|
|||||||
}
|
}
|
||||||
creator, ok := resolved.(pdfgo.String)
|
creator, ok := resolved.(pdfgo.String)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("invalid PDF stamp creator")
|
return fmt.Errorf("invalid PDF annotation creator")
|
||||||
}
|
}
|
||||||
converted.Creator, err = pdfgo.DecodeTextString(creator)
|
converted.Creator, err = pdfgo.DecodeTextString(creator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -127,7 +147,7 @@ func (p *pdfImporter) stampAnnotation(ctx context.Context, page *pdfgo.Page, ann
|
|||||||
}
|
}
|
||||||
encoded, ok := resolved.(pdfgo.String)
|
encoded, ok := resolved.(pdfgo.String)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("invalid PDF stamp modification date")
|
return fmt.Errorf("invalid PDF annotation modification date")
|
||||||
}
|
}
|
||||||
date, err := pdfgo.DecodeTextString(encoded)
|
date, err := pdfgo.DecodeTextString(encoded)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -135,46 +155,63 @@ func (p *pdfImporter) stampAnnotation(ctx context.Context, page *pdfgo.Page, ann
|
|||||||
}
|
}
|
||||||
date = strings.TrimPrefix(date, "D:")
|
date = strings.TrimPrefix(date, "D:")
|
||||||
if len(date) < 4 {
|
if len(date) < 4 {
|
||||||
return fmt.Errorf("invalid PDF stamp modification date")
|
return fmt.Errorf("invalid PDF annotation modification date")
|
||||||
}
|
}
|
||||||
year, err := strconv.Atoi(date[:4])
|
year, err := strconv.Atoi(date[:4])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid PDF stamp modification date: %w", err)
|
return fmt.Errorf("invalid PDF annotation modification date: %w", err)
|
||||||
}
|
}
|
||||||
month, day := 1, 1
|
month, day := 1, 1
|
||||||
if len(date) >= 6 {
|
if len(date) >= 6 {
|
||||||
month, err = strconv.Atoi(date[4:6])
|
month, err = strconv.Atoi(date[4:6])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid PDF stamp modification month: %w", err)
|
return fmt.Errorf("invalid PDF annotation modification month: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(date) >= 8 {
|
if len(date) >= 8 {
|
||||||
day, err = strconv.Atoi(date[6:8])
|
day, err = strconv.Atoi(date[6:8])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid PDF stamp modification day: %w", err)
|
return fmt.Errorf("invalid PDF annotation modification day: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parsed := time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC)
|
parsed := time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC)
|
||||||
if parsed.Year() != year || int(parsed.Month()) != month || parsed.Day() != day {
|
if parsed.Year() != year || int(parsed.Month()) != month || parsed.Day() != day {
|
||||||
return fmt.Errorf("invalid PDF stamp modification date")
|
return fmt.Errorf("invalid PDF annotation modification date")
|
||||||
}
|
}
|
||||||
converted.LastModDate = parsed.Format("2006-01-02")
|
converted.LastModDate = parsed.Format("2006-01-02")
|
||||||
if len(date) > 8 {
|
if len(date) > 8 {
|
||||||
p.report.Warnings = append(p.report.Warnings, pdfgo.Diagnostic{Page: p.page + 1, Message: "PDF stamp modification time cannot fit OFD annotation date"})
|
p.report.Warnings = append(p.report.Warnings, pdfgo.Diagnostic{Page: p.page + 1, Message: "PDF annotation modification time cannot fit OFD annotation date"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _, err := p.editor.AddAnnotation(p.page, converted); err != nil {
|
if _, err := p.editor.AddAnnotation(p.page, converted); err != nil {
|
||||||
return fmt.Errorf("stamp annotation: %w", err)
|
return fmt.Errorf("PDF annotation: %w", err)
|
||||||
}
|
}
|
||||||
p.report.TextObjects += stamp.report.TextObjects
|
p.report.TextObjects += stamp.report.TextObjects
|
||||||
p.report.PathObjects += stamp.report.PathObjects
|
p.report.PathObjects += stamp.report.PathObjects
|
||||||
p.report.ImageObjects += stamp.report.ImageObjects
|
p.report.ImageObjects += stamp.report.ImageObjects
|
||||||
if flags&64 != 0 {
|
if flags&64 != 0 {
|
||||||
p.report.Warnings = append(p.report.Warnings, pdfgo.Diagnostic{Page: p.page + 1, Message: "PDF stamp read-only flag not transferred"})
|
p.report.Warnings = append(p.report.Warnings, pdfgo.Diagnostic{Page: p.page + 1, Message: "PDF annotation read-only flag not transferred"})
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pdfAnnotationType 将具有静态外观的PDF注解类别对应到OFD注解类别
|
||||||
|
// 入参: subtype PDF注解类别
|
||||||
|
// 返回: string OFD注解类别,空字符串表示需单独处理
|
||||||
|
func pdfAnnotationType(subtype pdfgo.Name) string {
|
||||||
|
switch subtype {
|
||||||
|
case "Stamp":
|
||||||
|
return "Stamp"
|
||||||
|
case "Watermark":
|
||||||
|
return "Watermark"
|
||||||
|
case "Highlight", "Underline", "Squiggly", "StrikeOut":
|
||||||
|
return "Highlight"
|
||||||
|
case "Text", "FreeText", "Line", "Square", "Circle", "Polygon", "PolyLine", "Caret", "Ink":
|
||||||
|
return "Path"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// darkenStampAppearance 按PDF的Darken公式合成印章范围
|
// darkenStampAppearance 按PDF的Darken公式合成印章范围
|
||||||
// 入参: page PDF页面, box印章范围, mark图像, stamp局部转换器
|
// 入参: page PDF页面, box印章范围, mark图像, stamp局部转换器
|
||||||
// 返回: error 转换错误
|
// 返回: error 转换错误
|
||||||
|
|||||||
+21
-3
@@ -22,7 +22,7 @@ import (
|
|||||||
"github.com/xiaoqidun/pdfgo"
|
"github.com/xiaoqidun/pdfgo"
|
||||||
)
|
)
|
||||||
|
|
||||||
// annotations 将链接、印章和表单外观按页面顺序转换为OFD对象
|
// annotations 将链接、静态注解和表单外观按页面顺序转换为OFD对象
|
||||||
// 入参: ctx 取消上下文, page PDF页面, strict 严格检查开关
|
// 入参: ctx 取消上下文, page PDF页面, strict 严格检查开关
|
||||||
// 返回: error 错误信息
|
// 返回: error 错误信息
|
||||||
func (p *pdfImporter) annotations(ctx context.Context, page *pdfgo.Page, strict bool) error {
|
func (p *pdfImporter) annotations(ctx context.Context, page *pdfgo.Page, strict bool) error {
|
||||||
@@ -48,8 +48,8 @@ func (p *pdfImporter) annotations(ctx context.Context, page *pdfgo.Page, strict
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if annotation.Subtype == "Stamp" {
|
if pdfAnnotationType(annotation.Subtype) != "" {
|
||||||
if err := p.stampAnnotation(ctx, page, annotation); err != nil {
|
if err := p.appearanceAnnotation(ctx, page, annotation); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@@ -196,6 +196,24 @@ func (p *pdfImporter) annotations(ctx context.Context, page *pdfgo.Page, strict
|
|||||||
dest.OmitLeft, dest.OmitTop = retained[1], retained[0]
|
dest.OmitLeft, dest.OmitTop = retained[1], retained[0]
|
||||||
}
|
}
|
||||||
dest.OmitZoom = retained[2] || values[2] == 0
|
dest.OmitZoom = retained[2] || values[2] == 0
|
||||||
|
} else if destination.Mode == "FitR" {
|
||||||
|
values := [4]float64{}
|
||||||
|
for n, v := range destination.Parameters {
|
||||||
|
switch v := v.(type) {
|
||||||
|
case pdfgo.Integer:
|
||||||
|
values[n] = float64(v)
|
||||||
|
case pdfgo.Real:
|
||||||
|
values[n] = float64(v)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid PDF FitR destination coordinate")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bounds := pdfBounds([]pdfgo.Point{
|
||||||
|
matrix.Apply(pdfgo.Point{X: values[0], Y: values[1]}),
|
||||||
|
matrix.Apply(pdfgo.Point{X: values[2], Y: values[3]}),
|
||||||
|
})
|
||||||
|
dest.Left, dest.Top = bounds.X, bounds.Y
|
||||||
|
dest.Right, dest.Bottom = bounds.X+bounds.W, bounds.Y+bounds.H
|
||||||
} else if destination.Mode != "Fit" {
|
} else if destination.Mode != "Fit" {
|
||||||
return &pdfgo.UnsupportedError{Feature: "destination mode " + string(destination.Mode)}
|
return &pdfgo.UnsupportedError{Feature: "destination mode " + string(destination.Mode)}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ func (r *Renderer) walkAnnotation(annotation Annotation, visitor PageVisitor) er
|
|||||||
}
|
}
|
||||||
box, _ := ParseBox(annotation.Appearance.Boundary)
|
box, _ := ParseBox(annotation.Appearance.Boundary)
|
||||||
matrix := TranslationMatrix(box.X, box.Y)
|
matrix := TranslationMatrix(box.X, box.Y)
|
||||||
state := RenderState{Parent: &matrix}
|
state := RenderState{Parent: &matrix, BoundaryInCTM: true}
|
||||||
for i := range annotation.Appearance.Objects {
|
for i := range annotation.Appearance.Objects {
|
||||||
if err := r.WalkObject(&annotation.Appearance.Objects[i], state, visitor); err != nil {
|
if err := r.WalkObject(&annotation.Appearance.Objects[i], state, visitor); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
Reference in new issue
Block a user