mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 13:56:32 +08:00
1 parent
aa1fcd4cd6
commit
54995fb60e
10 files changed
+62
-22
No files matched your search
@@ -10,7 +10,7 @@ require (
|
||||
github.com/tdewolff/canvas v0.0.0-20260923214215-09804640d00c
|
||||
github.com/tdewolff/font v0.0.0-20260913163313-54f98bb59ee6
|
||||
github.com/xiaoqidun/jbig2 v1.1.1
|
||||
github.com/xiaoqidun/pdfgo v0.0.0-20261003042717-ffb073d5634d
|
||||
github.com/xiaoqidun/pdfgo v0.0.0-20261003103143-2420f94d9b97
|
||||
golang.org/x/crypto v0.57.0
|
||||
golang.org/x/image v0.46.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/xiaoqidun/jbig2 v1.1.1 h1:SjliS9ZO0e9HX5oYUfBuXrfFsXhWricrSz+XY4zORDI=
|
||||
github.com/xiaoqidun/jbig2 v1.1.1/go.mod h1:8QonVWtENmh2kc6l+leqeGl7psb79DWlHDkCpdChjfQ=
|
||||
github.com/xiaoqidun/pdfgo v0.0.0-20261003042717-ffb073d5634d h1:WiG6LgYU1hZBAELi72qP6UnCyA8cPe7Ap6nto0ofGnA=
|
||||
github.com/xiaoqidun/pdfgo v0.0.0-20261003042717-ffb073d5634d/go.mod h1:4Pf0JO0BEf1uzRY+uZjlMjN/OPn3PYa0YMi6cqPPTLQ=
|
||||
github.com/xiaoqidun/pdfgo v0.0.0-20261003103143-2420f94d9b97 h1:1YHWQ3BBFJd4RlWAEGhHHQ6D+OI/nriU91YIUzxZo8o=
|
||||
github.com/xiaoqidun/pdfgo v0.0.0-20261003103143-2420f94d9b97/go.mod h1:4Pf0JO0BEf1uzRY+uZjlMjN/OPn3PYa0YMi6cqPPTLQ=
|
||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
github.com/yuin/goldmark v1.8.5 h1:r6N5afV5qj/5S4UTch8agZHJ8UxNCMwX7WjkkJam2NA=
|
||||
|
||||
@@ -330,7 +330,14 @@ func (e *Editor) documentRoot() string {
|
||||
// 返回: bool 是否为同一文档
|
||||
func (e *Editor) sameDocument(other *Editor) bool {
|
||||
if e.source == nil || other.source == nil {
|
||||
return e.source == nil && other.source == nil
|
||||
if e.source == nil && other.source == nil {
|
||||
return true
|
||||
}
|
||||
fresh, packaged := e, other
|
||||
if fresh.source != nil {
|
||||
fresh, packaged = other, e
|
||||
}
|
||||
return len(packaged.source.reader.OFD.DocBody) == 1 && (packaged.source.fromNew || fresh.Info.DocID != "" && fresh.Info.DocID == packaged.source.info.DocID)
|
||||
}
|
||||
return e.documentRoot() == other.documentRoot() && e.source.info.DocID == other.source.info.DocID
|
||||
}
|
||||
|
||||
@@ -684,6 +684,7 @@ func (e *Editor) importBase() (*editorSource, error) {
|
||||
return nil, err
|
||||
}
|
||||
editor.source.idsReady = true
|
||||
editor.source.fromNew = true
|
||||
return editor.source, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ type editorSource struct {
|
||||
info DocInfo
|
||||
fallbackDocID string
|
||||
directory string
|
||||
fromNew bool
|
||||
pages map[string]*editorSourcePage
|
||||
origins map[string]*editorObjectOrigin
|
||||
idsReady bool
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ type pdfImporter struct {
|
||||
pages map[pdfgo.Reference]*pdfgo.Page
|
||||
pageIDs map[pdfgo.Reference]string
|
||||
pageIndexes map[pdfgo.Reference]int
|
||||
imageIDs map[pdfImageKey]string
|
||||
imageIDs map[pdfImageKey][]pdfImageResource
|
||||
attachmentIDs map[pdfAttachmentKey]string
|
||||
maskClips map[*pdfgo.SoftMask]pdfgo.Path
|
||||
pageBox pdfgo.Rectangle
|
||||
|
||||
+17
-5
@@ -20,6 +20,7 @@ import (
|
||||
"image"
|
||||
"image/color"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"unicode/utf8"
|
||||
|
||||
@@ -32,6 +33,12 @@ type pdfImageKey struct {
|
||||
intent pdfgo.Name
|
||||
}
|
||||
|
||||
// pdfImageResource 保存图像的有效颜色空间及对应资源,避免跨资源重映射复用
|
||||
type pdfImageResource struct {
|
||||
space pdfgo.Object
|
||||
id string
|
||||
}
|
||||
|
||||
// pdfStencilImage 按当前填充色读取模板图像,不分配整幅彩色样本
|
||||
type pdfStencilImage struct {
|
||||
source image.Image
|
||||
@@ -103,9 +110,14 @@ func (p *pdfImporter) image(mark pdfgo.ImageMark) error {
|
||||
}
|
||||
source := mark.Image
|
||||
key := pdfImageKey{stream: source.Stream, intent: source.Intent}
|
||||
id := p.imageIDs[key]
|
||||
if source.ImageMask {
|
||||
id = ""
|
||||
id := ""
|
||||
if !source.ImageMask {
|
||||
for _, resource := range p.imageIDs[key] {
|
||||
if reflect.DeepEqual(resource.space, source.ColorSpace) {
|
||||
id = resource.id
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if id == "" {
|
||||
jbig2Original, err := source.JBIG2File()
|
||||
@@ -155,9 +167,9 @@ func (p *pdfImporter) image(mark pdfgo.ImageMark) error {
|
||||
}
|
||||
if !source.ImageMask {
|
||||
if p.imageIDs == nil {
|
||||
p.imageIDs = map[pdfImageKey]string{}
|
||||
p.imageIDs = map[pdfImageKey][]pdfImageResource{}
|
||||
}
|
||||
p.imageIDs[key] = id
|
||||
p.imageIDs[key] = append(p.imageIDs[key], pdfImageResource{space: source.ColorSpace, id: id})
|
||||
}
|
||||
}
|
||||
return p.appendImage(mark, id)
|
||||
|
||||
@@ -160,11 +160,23 @@ func intersectClipPath(parent, current *canvas.Path) *canvas.Path {
|
||||
if parent.Empty() || current.Empty() {
|
||||
return &canvas.Path{}
|
||||
}
|
||||
if parentOK && parentRect.Contains(current.FastBounds()) {
|
||||
return current
|
||||
if parentOK {
|
||||
bounds := current.Bounds()
|
||||
if parentRect.Contains(bounds) {
|
||||
return current
|
||||
}
|
||||
if !parentRect.Overlaps(bounds) {
|
||||
return &canvas.Path{}
|
||||
}
|
||||
}
|
||||
if currentOK && currentRect.Contains(parent.FastBounds()) {
|
||||
return parent
|
||||
if currentOK {
|
||||
bounds := parent.Bounds()
|
||||
if currentRect.Contains(bounds) {
|
||||
return parent
|
||||
}
|
||||
if !currentRect.Overlaps(bounds) {
|
||||
return &canvas.Path{}
|
||||
}
|
||||
}
|
||||
if result, ok := intersectConvexCanvasPaths(parent, current); ok {
|
||||
return result
|
||||
@@ -199,7 +211,7 @@ func applyClipPath(path, clip *canvas.Path) *canvas.Path {
|
||||
return &canvas.Path{}
|
||||
}
|
||||
if rect, ok := rectangularPath(clip); ok {
|
||||
bounds := path.FastBounds()
|
||||
bounds := path.Bounds()
|
||||
if rect.Contains(bounds) {
|
||||
return path
|
||||
}
|
||||
@@ -224,18 +236,25 @@ func rectangularPath(path *canvas.Path) (canvas.Rect, bool) {
|
||||
return canvas.Rect{}, false
|
||||
}
|
||||
data := path.Data()
|
||||
if len(data) != 20 {
|
||||
return canvas.Rect{}, false
|
||||
}
|
||||
for i := 0; i < len(data); i += 4 {
|
||||
if i+4 > len(data) || (data[i] != canvas.MoveToCmd && data[i] != canvas.LineToCmd && data[i] != canvas.CloseCmd) {
|
||||
if data[i] != canvas.MoveToCmd && data[i] != canvas.LineToCmd && data[i] != canvas.CloseCmd {
|
||||
return canvas.Rect{}, false
|
||||
}
|
||||
}
|
||||
points := path.Coords()
|
||||
if len(points) != 5 || !points[0].Equals(points[4]) {
|
||||
if !(canvas.Point{X: data[1], Y: data[2]}).Equals(canvas.Point{X: data[17], Y: data[18]}) {
|
||||
return canvas.Rect{}, false
|
||||
}
|
||||
rect := path.FastBounds()
|
||||
corners := 0
|
||||
for _, point := range points[:4] {
|
||||
for i := 0; i < 16; i += 4 {
|
||||
point := canvas.Point{X: data[i+1], Y: data[i+2]}
|
||||
next := (i + 4) % 16
|
||||
if !canvas.Equal(point.X, data[next+1]) && !canvas.Equal(point.Y, data[next+2]) {
|
||||
return canvas.Rect{}, false
|
||||
}
|
||||
corner := 0
|
||||
switch {
|
||||
case canvas.Equal(point.X, rect.X0) && canvas.Equal(point.Y, rect.Y0):
|
||||
|
||||
@@ -368,7 +368,7 @@ func (r *Renderer) renderPattern(ctx *canvas.Context, pattern *PatternPaint, pag
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
bounds := clip.FastBounds()
|
||||
bounds := clip.Bounds()
|
||||
points := [][2]float64{
|
||||
{bounds.X0, pageH - bounds.Y0},
|
||||
{bounds.X1, pageH - bounds.Y0},
|
||||
|
||||
@@ -60,7 +60,7 @@ func (r *Renderer) drawSampledShading(ctx *canvas.Context, path *canvas.Path, vi
|
||||
if path.Empty() {
|
||||
return
|
||||
}
|
||||
bounds := path.FastBounds().And(shdCanvasBounds(ctx))
|
||||
bounds := path.Bounds().And(shdCanvasBounds(ctx))
|
||||
if bounds.W() <= 0 || bounds.H() <= 0 {
|
||||
return
|
||||
}
|
||||
@@ -243,7 +243,7 @@ func drawRepeatAxialPath(ctx *canvas.Context, path *canvas.Path, gradient *repea
|
||||
p = p.Transform(view.Inv())
|
||||
d := gradient.End.Sub(gradient.Start).Mul(gradient.period)
|
||||
axis := canvas.Matrix{{d.X, -d.Y, gradient.Start.X}, {d.Y, d.X, gradient.Start.Y}}
|
||||
bounds := p.FastBounds().And(shdCanvasBounds(ctx).Transform(view.Inv()))
|
||||
bounds := p.Bounds().And(shdCanvasBounds(ctx).Transform(view.Inv()))
|
||||
area := bounds.Transform(axis.Inv())
|
||||
origin := ctx.CoordView().Dot(canvas.Point{})
|
||||
m := ctx.CoordSystemView().Mul(ctx.View()).Translate(origin.X, origin.Y).Mul(view)
|
||||
|
||||
Reference in new issue
Block a user