Skip to content

Commit 60bb696

Browse files
authored
Merge pull request #393 from gunnsth/release/v3.9.0
Prepare unipdf release v3.9.0
2 parents 8ab0b6f + c7febe5 commit 60bb696

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+4703
-1279
lines changed

Jenkinsfile

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
node {
22
// Install the desired Go version
3-
def root = tool name: 'go 1.11.5', type: 'go'
3+
def root = tool name: 'go 1.14.3', type: 'go'
44

55
env.GOROOT="${root}"
6-
env.GOPATH="${WORKSPACE}/gopath"
7-
// Hack for 1.11.5 testing work.
8-
env.CGO_ENABLED="0"
9-
env.PATH="${root}/bin:${env.GOPATH}/bin:${env.PATH}"
10-
env.GOCACHE="off"
6+
env.GOBIN="${WORKSPACE}/bin"
7+
env.PATH="${root}/bin:${env.GOBIN}:${env.PATH}"
118
env.UNIDOC_EXTRACT_FORCETEST="1"
129
env.UNIDOC_E2E_FORCE_TESTS="1"
10+
env.UNIDOC_RENDERTEST_FORMFILL_FORCETEST="1"
1311
env.UNIDOC_EXTRACT_TESTDATA="/home/jenkins/corpus/unidoc-extractor-testdata"
1412
env.UNIDOC_RENDERTEST_BASELINE_PATH="/home/jenkins/corpus/unidoc-creator-render-testdata-upd2"
1513
env.UNIDOC_PASSTHROUGH_TESTDATA="/home/jenkins/corpus/unidoc-e2e-testdata"
@@ -18,14 +16,16 @@ node {
1816
env.UNIDOC_EXTRACT_IMAGES_TESTDATA="/home/jenkins/corpus/unidoc-e2e-extract-images-testdata"
1917
env.UNIDOC_JBIG2_TESTDATA="/home/jenkins/corpus/jbig2-testdata"
2018
env.UNIDOC_FDFMERGE_TESTDATA="/home/jenkins/corpus/fdfmerge-testdata"
19+
env.UNIDOC_RENDERTEST_FORMFILL_TESTDATA="/home/jenkins/corpus/unidoc-form-fill-render-testdata"
20+
env.UNIDOC_RENDERTEST_FORMFILL_BASELINE="/home/jenkins/corpus/unidoc-form-fill-render-baseline"
2121
env.UNIDOC_GS_BIN_PATH="/usr/bin/gs"
22-
// Hack for 1.11.5 testing work.
2322
env.CGO_ENABLED="0"
2423

2524
env.TMPDIR="${WORKSPACE}/temp"
25+
sh "mkdir -p ${env.GOBIN}"
2626
sh "mkdir -p ${env.TMPDIR}"
2727

28-
dir("${GOPATH}/src/github.com/unidoc/unipdf") {
28+
dir("${WORKSPACE}/unipdf") {
2929
sh 'go version'
3030

3131
stage('Checkout') {
@@ -35,11 +35,9 @@ node {
3535

3636
stage('Prepare') {
3737
// Get linter and other build tools.
38-
sh 'go get -u golang.org/x/lint/golint'
38+
sh 'go get golang.org/x/lint/golint'
3939
sh 'go get github.com/tebeka/go2xunit'
4040
sh 'go get github.com/t-yuki/gocover-cobertura'
41-
// Get all dependencies (for tests also).
42-
sh 'go get -t ./...'
4341
}
4442

4543
stage('Linting') {
@@ -53,7 +51,7 @@ node {
5351
stage('Testing') {
5452
// Go test - No tolerance.
5553
sh "rm -f ${env.TMPDIR}/*.pdf"
56-
sh '2>&1 go test -v ./... | tee gotest.txt'
54+
sh '2>&1 go test -count=1 -v ./... | tee gotest.txt'
5755
}
5856

5957
stage('Check generated PDFs') {
@@ -62,7 +60,7 @@ node {
6260
}
6361

6462
stage('Test coverage') {
65-
sh 'go test -coverprofile=coverage.out -covermode=atomic -coverpkg=./... ./...'
63+
sh 'go test -count=1 -coverprofile=coverage.out -covermode=atomic -coverpkg=./... ./...'
6664
sh '/home/jenkins/codecov.sh'
6765
sh 'gocover-cobertura < coverage.out > coverage.xml'
6866
step([$class: 'CoberturaPublisher', coberturaReportFile: 'coverage.xml'])
@@ -80,7 +78,7 @@ node {
8078
}
8179
}
8280

83-
dir("${GOPATH}/src/github.com/unidoc/unipdf-examples") {
81+
dir("${WORKSPACE}/unipdf-examples") {
8482
stage('Build examples') {
8583
// Output environment variables (useful for debugging).
8684
sh("printenv")
@@ -97,7 +95,10 @@ node {
9795

9896
echo "Pulling unipdf-examples on branch ${examplesBranch}"
9997
git url: 'https://github.com/unidoc/unidoc-examples.git', branch: examplesBranch
100-
98+
99+
// Use replace directive to use disk version of unipdf.
100+
sh 'echo "replace github.com/unidoc/unipdf/v3 => ../unipdf" >>go.mod'
101+
101102
// Dependencies for examples.
102103
sh './build_examples.sh'
103104
}

annotator/field_appearance.go

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -219,15 +219,15 @@ func genFieldTextAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFieldT
219219
return nil, err
220220
}
221221
width, height := rect.Width(), rect.Height()
222+
bboxWidth, bboxHeight := width, height
222223

223-
var rotation float64
224-
if mkDict, has := core.GetDict(wa.MK); has {
224+
mkDict, has := core.GetDict(wa.MK)
225+
if has {
225226
bsDict, _ := core.GetDict(wa.BS)
226227
err := style.applyAppearanceCharacteristics(mkDict, bsDict, nil)
227228
if err != nil {
228229
return nil, err
229230
}
230-
rotation, _ = core.GetNumberAsFloat(mkDict.Get("R"))
231231
}
232232

233233
// Get and process the default appearance string (DA) operands.
@@ -252,26 +252,10 @@ func genFieldTextAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFieldT
252252
cc.Add_BMC("Tx")
253253
cc.Add_q()
254254

255-
bboxWidth, bboxHeight := width, height
256-
if rotation != 0 {
257-
// Calculate bounding box before rotation.
258-
revRotation := -rotation
259-
bbox := draw.Path{Points: []draw.Point{
260-
draw.NewPoint(0, 0).Rotate(revRotation),
261-
draw.NewPoint(width, 0).Rotate(revRotation),
262-
draw.NewPoint(0, height).Rotate(revRotation),
263-
draw.NewPoint(width, height).Rotate(revRotation),
264-
}}.GetBoundingBox()
265-
266-
// Update width and height, as the appearance is generated based on
267-
// the bounding of the annotation with no rotation.
268-
width = bbox.Width
269-
height = bbox.Height
270-
271-
// Apply rotation.
272-
cc.RotateDeg(rotation)
273-
cc.Translate(bbox.X, bbox.Y)
274-
}
255+
// Apply rotation if present.
256+
// Update width and height, as the appearance is generated based on
257+
// the bounding of the annotation with no rotation.
258+
width, height = style.applyRotation(mkDict, width, height, cc)
275259

276260
// Graphic state changes.
277261
cc.Add_BT()
@@ -513,8 +497,10 @@ func genFieldTextCombAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFi
513497
return nil, err
514498
}
515499
width, height := rect.Width(), rect.Height()
500+
bboxWidth, bboxHeight := width, height
516501

517-
if mkDict, has := core.GetDict(wa.MK); has {
502+
mkDict, has := core.GetDict(wa.MK)
503+
if has {
518504
bsDict, _ := core.GetDict(wa.BS)
519505
err := style.applyAppearanceCharacteristics(mkDict, bsDict, nil)
520506
if err != nil {
@@ -551,6 +537,11 @@ func genFieldTextCombAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFi
551537
cc.Add_BMC("Tx")
552538
cc.Add_q()
553539

540+
// Apply rotation if present.
541+
// Update width and height, as the appearance is generated based on
542+
// the bounding of the annotation with no rotation.
543+
width, height = style.applyRotation(mkDict, width, height, cc)
544+
554545
// Graphic state changes.
555546
cc.Add_BT()
556547

@@ -680,7 +671,7 @@ func genFieldTextCombAppearance(wa *model.PdfAnnotationWidget, ftxt *model.PdfFi
680671

681672
xform := model.NewXObjectForm()
682673
xform.Resources = resources
683-
xform.BBox = core.MakeArrayFromFloats([]float64{0, 0, width, height})
674+
xform.BBox = core.MakeArrayFromFloats([]float64{0, 0, bboxWidth, bboxHeight})
684675
xform.SetContentStream(cc.Bytes(), defStreamEncoder())
685676

686677
apDict := core.MakeDict()
@@ -702,6 +693,7 @@ func genFieldCheckboxAppearance(wa *model.PdfAnnotationWidget, fbtn *model.PdfFi
702693
return nil, err
703694
}
704695
width, height := rect.Width(), rect.Height()
696+
bboxWidth, bboxHeight := width, height
705697

706698
common.Log.Debug("Checkbox, wa BS: %v", wa.BS)
707699

@@ -710,7 +702,8 @@ func genFieldCheckboxAppearance(wa *model.PdfAnnotationWidget, fbtn *model.PdfFi
710702
return nil, err
711703
}
712704

713-
if mkDict, has := core.GetDict(wa.MK); has {
705+
mkDict, has := core.GetDict(wa.MK)
706+
if has {
714707
bsDict, _ := core.GetDict(wa.BS)
715708
err := style.applyAppearanceCharacteristics(mkDict, bsDict, zapfdb)
716709
if err != nil {
@@ -732,6 +725,11 @@ func genFieldCheckboxAppearance(wa *model.PdfAnnotationWidget, fbtn *model.PdfFi
732725
drawAlignmentReticle(cc, style2, width, height)
733726
}
734727

728+
// Apply rotation if present.
729+
// Update width and height, as the appearance is generated based on
730+
// the bounding of the annotation with no rotation.
731+
width, height = style.applyRotation(mkDict, width, height, cc)
732+
735733
fontsize := style.AutoFontSizeFraction * height
736734

737735
checkmetrics, ok := zapfdb.GetRuneMetrics(style.CheckmarkRune)
@@ -767,7 +765,7 @@ func genFieldCheckboxAppearance(wa *model.PdfAnnotationWidget, fbtn *model.PdfFi
767765

768766
xformOn.Resources = model.NewPdfPageResources()
769767
xformOn.Resources.SetFontByName("ZaDb", zapfdb.ToPdfObject())
770-
xformOn.BBox = core.MakeArrayFromFloats([]float64{0, 0, width, height})
768+
xformOn.BBox = core.MakeArrayFromFloats([]float64{0, 0, bboxWidth, bboxHeight})
771769
xformOn.SetContentStream(cc.Bytes(), defStreamEncoder())
772770
}
773771

@@ -777,7 +775,7 @@ func genFieldCheckboxAppearance(wa *model.PdfAnnotationWidget, fbtn *model.PdfFi
777775
if style.BorderSize > 0 {
778776
drawRect(cc, style, width, height)
779777
}
780-
xformOff.BBox = core.MakeArrayFromFloats([]float64{0, 0, width, height})
778+
xformOff.BBox = core.MakeArrayFromFloats([]float64{0, 0, bboxWidth, bboxHeight})
781779
xformOff.SetContentStream(cc.Bytes(), defStreamEncoder())
782780
}
783781

@@ -813,7 +811,8 @@ func genFieldComboboxAppearance(form *model.PdfAcroForm, wa *model.PdfAnnotation
813811
return nil, err
814812
}
815813

816-
if mkDict, has := core.GetDict(wa.MK); has {
814+
mkDict, has := core.GetDict(wa.MK)
815+
if has {
817816
bsDict, _ := core.GetDict(wa.BS)
818817
err := style.applyAppearanceCharacteristics(mkDict, bsDict, nil)
819818
if err != nil {
@@ -839,7 +838,7 @@ func genFieldComboboxAppearance(form *model.PdfAcroForm, wa *model.PdfAnnotation
839838
}
840839

841840
if len(optstr) > 0 {
842-
xform, err := makeComboboxTextXObjForm(fch.PdfField, width, height, optstr, style, daOps, form.DR)
841+
xform, err := makeComboboxTextXObjForm(fch.PdfField, width, height, optstr, style, daOps, form.DR, mkDict)
843842
if err != nil {
844843
return nil, err
845844
}
@@ -857,8 +856,9 @@ func genFieldComboboxAppearance(form *model.PdfAcroForm, wa *model.PdfAnnotation
857856
// Make a text-based XObj Form.
858857
func makeComboboxTextXObjForm(field *model.PdfField, width, height float64,
859858
text string, style AppearanceStyle, daOps *contentstream.ContentStreamOperations,
860-
dr *model.PdfPageResources) (*model.XObjectForm, error) {
859+
dr *model.PdfPageResources, mkDict *core.PdfObjectDictionary) (*model.XObjectForm, error) {
861860
resources := model.NewPdfPageResources()
861+
bboxWidth, bboxHeight := width, height
862862

863863
cc := contentstream.NewContentCreator()
864864
if style.BorderSize > 0 {
@@ -875,6 +875,11 @@ func makeComboboxTextXObjForm(field *model.PdfField, width, height float64,
875875
// Graphic state changes.
876876
cc.Add_BT()
877877

878+
// Apply rotation if present.
879+
// Update width and height, as the appearance is generated based on
880+
// the bounding of the annotation with no rotation.
881+
width, height = style.applyRotation(mkDict, width, height, cc)
882+
878883
// Process DA operands.
879884
apFont, hasTf, err := style.processDA(field, daOps, dr, resources, cc)
880885
if err != nil {
@@ -950,7 +955,7 @@ func makeComboboxTextXObjForm(field *model.PdfField, width, height float64,
950955

951956
xform := model.NewXObjectForm()
952957
xform.Resources = resources
953-
xform.BBox = core.MakeArrayFromFloats([]float64{0, 0, width, height})
958+
xform.BBox = core.MakeArrayFromFloats([]float64{0, 0, bboxWidth, bboxHeight})
954959
xform.SetContentStream(cc.Bytes(), defStreamEncoder())
955960

956961
return xform, nil
@@ -1067,6 +1072,40 @@ func (style *AppearanceStyle) applyAppearanceCharacteristics(mkDict *core.PdfObj
10671072
return nil
10681073
}
10691074

1075+
// applyRotation applies the rotation specified by the MK dictionary,
1076+
// if present. The method returns the width and height of the annotation
1077+
// rectangle with no rotation.
1078+
func (style *AppearanceStyle) applyRotation(mkDict *core.PdfObjectDictionary,
1079+
width, height float64, cc *contentstream.ContentCreator) (float64, float64) {
1080+
if !style.AllowMK {
1081+
return width, height
1082+
}
1083+
if mkDict == nil {
1084+
return width, height
1085+
}
1086+
1087+
// Extract rotation from the MK dictionary.
1088+
rotation, _ := core.GetNumberAsFloat(mkDict.Get("R"))
1089+
if rotation == 0 {
1090+
return width, height
1091+
}
1092+
1093+
// Calculate bounding box before rotation.
1094+
revRotation := -rotation
1095+
bbox := draw.Path{Points: []draw.Point{
1096+
draw.NewPoint(0, 0).Rotate(revRotation),
1097+
draw.NewPoint(width, 0).Rotate(revRotation),
1098+
draw.NewPoint(0, height).Rotate(revRotation),
1099+
draw.NewPoint(width, height).Rotate(revRotation),
1100+
}}.GetBoundingBox()
1101+
1102+
// Apply rotation.
1103+
cc.RotateDeg(rotation)
1104+
cc.Translate(bbox.X, bbox.Y)
1105+
1106+
return bbox.Width, bbox.Height
1107+
}
1108+
10701109
// processDA adds the operands found in the field default appearance stream to
10711110
// the provided content stream creator. It also provides a fallback font, based
10721111
// on the configuration of the AppearanceStyle, if no valid font is specified

0 commit comments

Comments
 (0)