Skip to content

Commit 6e1af9e

Browse files
committed
Fix stamp transform calc
1 parent be6b07a commit 6e1af9e

File tree

7 files changed

+149
-24
lines changed

7 files changed

+149
-24
lines changed

pkg/pdfcpu/context.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ import (
3030
type Context struct {
3131
*Configuration
3232
*XRefTable
33-
Read *ReadContext
34-
Optimize *OptimizationContext
35-
Write *WriteContext
33+
Read *ReadContext
34+
Optimize *OptimizationContext
35+
Write *WriteContext
36+
writingPages bool // true, when writing page dicts.
37+
dest bool // true when writing a destination within a page.
3638
}
3739

3840
// NewContext initializes a new Context.
@@ -48,6 +50,8 @@ func NewContext(rs io.ReadSeeker, fileName string, fileSize int64, config *Confi
4850
newReadContext(rs, fileName, fileSize),
4951
newOptimizationContext(),
5052
NewWriteContext(config.Eol),
53+
false,
54+
false,
5155
}
5256

5357
return ctx, nil
@@ -572,7 +576,7 @@ func (wc *WriteContext) HasWriteOffset(objNumber int) bool {
572576
return found
573577
}
574578

575-
// ReducedFeatureSet returns true for Split,Trim,Merge,ExtractPages.
579+
// ReducedFeatureSet returns true for some operations.
576580
// Don't confuse with pdfcpu commands, these are internal triggers.
577581
func (wc *WriteContext) ReducedFeatureSet() bool {
578582
switch wc.Command {

pkg/pdfcpu/crypto.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ func validateOwnerPassword(ctx *Context) (ok bool, k []byte, err error) {
340340
ownerpw := ctx.OwnerPW
341341
userpw := ctx.UserPW
342342

343-
//fmt.Printf("ValidateOwnerPassword: ownerpw=ctx.OwnerPW=%s userpw=ctx.UserPW=%s\n", ownerpw, userpw)
343+
//fmt.Printf("ValidateOwnerPassword: ownerpw=ctx.OwnerPW:<%s> userpw=ctx.UserPW:<%s>\n", ownerpw, userpw)
344344

345345
e := ctx.E
346346

pkg/pdfcpu/read.go

Lines changed: 98 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package pdfcpu
1919
import (
2020
"bufio"
2121
"bytes"
22+
"fmt"
2223
"io"
2324
"os"
2425
"sort"
@@ -780,6 +781,98 @@ func scanLine(s *bufio.Scanner) (string, error) {
780781
return s.Text(), nil
781782
}
782783

784+
func scanTrailer(s *bufio.Scanner, line string) (string, error) {
785+
786+
var buf bytes.Buffer
787+
var err error
788+
var i, j, k int
789+
790+
log.Read.Printf("line: <%s>\n", line)
791+
792+
// Scan for dict start tag "<<".
793+
for {
794+
i = strings.Index(line, "<<")
795+
if i >= 0 {
796+
break
797+
}
798+
line, err = scanLine(s)
799+
log.Read.Printf("line: <%s>\n", line)
800+
if err != nil {
801+
return "", err
802+
}
803+
}
804+
805+
line = line[i:]
806+
buf.WriteString(line)
807+
buf.WriteString(" ")
808+
log.Read.Printf("scanTrailer dictBuf after start tag: <%s>\n", line)
809+
810+
// Scan for dict end tag ">>" but account for inner dicts.
811+
line = line[2:]
812+
813+
for {
814+
815+
if len(line) == 0 {
816+
line, err = scanLine(s)
817+
if err != nil {
818+
return "", err
819+
}
820+
buf.WriteString(line)
821+
buf.WriteString(" ")
822+
log.Read.Printf("scanTrailer dictBuf next line: <%s>\n", line)
823+
}
824+
825+
i = strings.Index(line, "<<")
826+
if i < 0 {
827+
// No <<
828+
j = strings.Index(line, ">>")
829+
if j >= 0 {
830+
// Yes >>
831+
if k == 0 {
832+
return buf.String(), nil
833+
}
834+
k--
835+
println(k)
836+
line = line[j+2:]
837+
continue
838+
}
839+
// No >>
840+
line, err = scanLine(s)
841+
if err != nil {
842+
return "", err
843+
}
844+
buf.WriteString(line)
845+
buf.WriteString(" ")
846+
log.Read.Printf("scanTrailer dictBuf next line: <%s>\n", line)
847+
} else {
848+
// Yes <<
849+
j = strings.Index(line, ">>")
850+
if j < 0 {
851+
// No >>
852+
k++
853+
println(k)
854+
line = line[i+2:]
855+
} else {
856+
// Yes >>
857+
if i < j {
858+
// handle <<
859+
k++
860+
println(k)
861+
line = line[i+2:]
862+
} else {
863+
// handle >>
864+
if k == 0 {
865+
return buf.String(), nil
866+
}
867+
k--
868+
println(k)
869+
line = line[j+2:]
870+
}
871+
}
872+
}
873+
}
874+
}
875+
783876
func scanTrailerDict(s *bufio.Scanner, startTag bool) (string, error) {
784877

785878
var buf bytes.Buffer
@@ -864,16 +957,9 @@ func parseXRefSection(s *bufio.Scanner, ctx *Context) (*int64, error) {
864957
log.Read.Printf("line (len %d) <%s>\n", len(line), line)
865958
}
866959

867-
// Unless trailerDict already scanned into trailerString
868-
if strings.Index(trailerString, ">>") == -1 {
869-
870-
// scan lines until we have the complete trailer dict: << ... >>
871-
trailerDictString, err := scanTrailerDict(s, strings.Index(trailerString, "<<") > 0)
872-
if err != nil {
873-
return nil, err
874-
}
875-
876-
trailerString += trailerDictString
960+
trailerString, err = scanTrailer(s, trailerString)
961+
if err != nil {
962+
return nil, err
877963
}
878964

879965
log.Read.Printf("parseXRefSection: trailerString: (len:%d) <%s>\n", len(trailerString), trailerString)
@@ -2179,6 +2265,7 @@ func setupEncryptionKey(ctx *Context, encryptDictObjNr int) error {
21792265
if err != nil {
21802266
return err
21812267
}
2268+
fmt.Printf("read: id = %0X\n", enc.ID)
21822269

21832270
var ok bool
21842271

@@ -2189,7 +2276,7 @@ func setupEncryptionKey(ctx *Context, encryptDictObjNr int) error {
21892276
}
21902277

21912278
// If the owner password does not match we generally move on if the user password is correct
2192-
// unless we need to insist on a correct owner password.
2279+
// unless we need to insist on a correct owner password due to the specific command in progress.
21932280
if !ok && needsOwnerAndUserPassword(ctx.Mode) {
21942281
return errors.New("owner password authentication error")
21952282
}

pkg/pdfcpu/stamp.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,16 @@ func (wm Watermark) String() string {
150150
sc = "absolute"
151151
}
152152

153+
bbox := ""
154+
if wm.bb != nil {
155+
bbox = (*wm.bb).String()
156+
}
157+
158+
vp := ""
159+
if wm.vp != nil {
160+
vp = (*wm.vp).String()
161+
}
162+
153163
return fmt.Sprintf("Watermark: <%s> is %son top, typ:%s\n"+
154164
"%s %d points\n"+
155165
"PDFpage#: %d\n"+
@@ -171,8 +181,8 @@ func (wm Watermark) String() string {
171181
wm.diagonal,
172182
wm.opacity,
173183
wm.renderMode,
174-
*wm.bb,
175-
*wm.vp,
184+
bbox,
185+
vp,
176186
wm.pageRot,
177187
)
178188
}
@@ -287,8 +297,8 @@ func (wm *Watermark) calcTransformMatrix() *matrix {
287297
dy = wm.bb.LL.Y
288298
}
289299

290-
m2[2][0] = wm.vp.Width()/2 + sin*(wm.bb.Height()/2+dy) - cos*wm.bb.Width()/2
291-
m2[2][1] = wm.vp.Height()/2 - cos*(wm.bb.Height()/2+dy) - sin*wm.bb.Width()/2
300+
m2[2][0] = wm.vp.LL.X + wm.vp.Width()/2 + sin*(wm.bb.Height()/2+dy) - cos*wm.bb.Width()/2
301+
m2[2][1] = wm.vp.LL.Y + wm.vp.Height()/2 - cos*(wm.bb.Height()/2+dy) - sin*wm.bb.Width()/2
292302

293303
m := m1.multiply(m2)
294304
return &m

pkg/pdfcpu/validate/info.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ func validateDocumentInfoDict(xRefTable *pdf.XRefTable, obj pdf.Object) (hasModD
9393
// name, optional, since V1.3
9494
case "Trapped":
9595
validate := func(s string) bool { return pdf.MemberOf(s, []string{"True", "False", "Unknown"}) }
96+
if xRefTable.ValidationMode == pdf.ValidationRelaxed {
97+
validate = func(s string) bool {
98+
return pdf.MemberOf(s, []string{"True", "False", "Unknown", "true", "false", "unknown"})
99+
}
100+
}
96101
_, err = xRefTable.DereferenceName(v, pdf.V13, validate)
97102

98103
// text string, optional

pkg/pdfcpu/writeObjects.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -523,16 +523,23 @@ func writeDirectObject(ctx *Context, o Object) error {
523523
switch o := o.(type) {
524524

525525
case Dict:
526-
for _, v := range o {
526+
for k, v := range o {
527+
if ctx.writingPages && (k == "Dest" || k == "D") {
528+
ctx.dest = true
529+
}
527530
_, _, err := writeDeepObject(ctx, v)
528531
if err != nil {
529532
return err
530533
}
534+
ctx.dest = false
531535
}
532536
log.Write.Printf("writeDirectObject: end offset=%d\n", ctx.Write.Offset)
533537

534538
case Array:
535-
for _, v := range o {
539+
for i, v := range o {
540+
if ctx.dest && i == 0 {
541+
continue
542+
}
536543
_, _, err := writeDeepObject(ctx, v)
537544
if err != nil {
538545
return err
@@ -568,11 +575,15 @@ func writeDeepDict(ctx *Context, d Dict, objNr, genNr int) error {
568575
return err
569576
}
570577

571-
for _, v := range d {
578+
for k, v := range d {
579+
if ctx.writingPages && (k == "Dest" || k == "D") {
580+
ctx.dest = true
581+
}
572582
_, _, err = writeDeepObject(ctx, v)
573583
if err != nil {
574584
return err
575585
}
586+
ctx.dest = false
576587
}
577588

578589
return nil
@@ -609,7 +620,10 @@ func writeDeepArray(ctx *Context, a Array, objNr, genNr int) error {
609620
return err
610621
}
611622

612-
for _, v := range a {
623+
for i, v := range a {
624+
if ctx.dest && i == 0 {
625+
continue
626+
}
613627
_, _, err = writeDeepObject(ctx, v)
614628
if err != nil {
615629
return err

pkg/pdfcpu/writePages.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ func writePageDict(ctx *Context, ir *IndirectRef, pageDict Dict, pageNr int) err
6161
return errors.New("writePageDict: missing parent")
6262
}
6363

64+
ctx.writingPages = true
65+
6466
for _, e := range []struct {
6567
entryName string
6668
statsAttr int
@@ -100,6 +102,8 @@ func writePageDict(ctx *Context, ir *IndirectRef, pageDict Dict, pageNr int) err
100102
}
101103
}
102104

105+
ctx.writingPages = false
106+
103107
log.Write.Printf("*** writePageDict end: obj#%d offset=%d ***\n", objNr, ctx.Write.Offset)
104108

105109
return nil
@@ -253,6 +257,7 @@ func writePagesDict(ctx *Context, ir *IndirectRef, pageNr *int) (skip bool, writ
253257
d.Update("Kids", kidsNew)
254258
d.Update("Count", Integer(countNew))
255259
log.Write.Printf("writePagesDict: writing pageDict for obj=%d page=%d\n%s", objNr, *pageNr, d)
260+
256261
err = writeDictObject(ctx, objNr, genNr, d)
257262
if err != nil {
258263
return false, 0, err

0 commit comments

Comments
 (0)