Skip to content

Commit 47ae7e2

Browse files
authored
Merge pull request #165 from unidoc/release/v3.2.0
Release unipdf v3.2.0
2 parents 4187510 + 681e4c2 commit 47ae7e2

Some content is hidden

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

49 files changed

+3144
-452
lines changed

.travis.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
language: go
2+
sudo: required
3+
go:
4+
- 1.12.x
5+
env:
6+
global:
7+
- CGO_ENABLED="0"
8+
- GO111MODULE="on"
9+
- TMPDIR="$(echo -n $HOME/tmp)"
10+
- UNIDOC_GS_BIN_PATH="/usr/bin/gs"
11+
- UNIDOC_EXTRACT_FORCETEST="0"
12+
- UNIDOC_E2E_FORCE_TESTS="0"
13+
- UNIDOC_EXTRACT_TESTDATA=""
14+
- UNIDOC_RENDERTEST_BASELINE_PATH=""
15+
- UNIDOC_PASSTHROUGH_TESTDATA=""
16+
- UNIDOC_ALLOBJECTS_TESTDATA=""
17+
- UNIDOC_SPLIT_TESTDATA=""
18+
- UNIDOC_EXTRACT_IMAGES_TESTDATA=""
19+
- UNIDOC_JBIG2_TESTDATA=""
20+
- UNIDOC_FDFMERGE_TESTDATA=""
21+
before_install:
22+
- sudo apt-get update
23+
- sudo apt-get install -y git ghostscript
24+
- go get golang.org/x/lint/golint
25+
- go get -t ./...
26+
- mkdir -p $TMPDIR
27+
script:
28+
- go vet ./...
29+
- golint ./...
30+
- go test -v ./...
31+
- find $TMPDIR -maxdepth 1 -name "*.pdf" -print0 | xargs -t -n 1 -0 gs -dNOPAUSE -dBATCH -sDEVICE=nullpage -sPDFPassword=password -dPDFSTOPONERROR -dPDFSTOPONWARNING
32+
- go test -coverprofile=coverage.out -covermode=atomic -coverpkg=./... ./...
33+
- ./.travis/build_examples.sh
34+
after_success:
35+
- bash <(curl -s https://codecov.io/bash)

.travis/build_examples.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env bash
2+
repo_path="$HOME/projects/unipdf-examples"
3+
git clone https://github.com/unidoc/unipdf-examples.git $repo_path
4+
cd $repo_path
5+
6+
build_branch="$TRAVIS_BRANCH"
7+
if [[ -n "$TRAVIS_PULL_REQUEST_BRANCH" ]]; then
8+
build_branch="$TRAVIS_PULL_REQUEST_BRANCH"
9+
fi
10+
if [[ -z "$build_branch" ]]; then
11+
build_branch="development"
12+
fi
13+
14+
target_branch="development"
15+
if [[ `git ls-remote origin "$build_branch"` ]]; then
16+
target_branch="$build_branch"
17+
fi
18+
19+
git checkout $target_branch
20+
echo "replace github.com/unidoc/unipdf/v3 => $TRAVIS_BUILD_DIR" >> go.mod
21+
./build_examples.sh

Jenkinsfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ node {
1515
env.UNIDOC_PASSTHROUGH_TESTDATA="/home/jenkins/corpus/unidoc-e2e-testdata"
1616
env.UNIDOC_ALLOBJECTS_TESTDATA="/home/jenkins/corpus/unidoc-e2e-testdata"
1717
env.UNIDOC_SPLIT_TESTDATA="/home/jenkins/corpus/unidoc-e2e-split-testdata"
18+
env.UNIDOC_EXTRACT_IMAGES_TESTDATA="/home/jenkins/corpus/unidoc-e2e-extract-images-testdata"
1819
env.UNIDOC_JBIG2_TESTDATA="/home/jenkins/corpus/jbig2-testdata"
1920
env.UNIDOC_FDFMERGE_TESTDATA="/home/jenkins/corpus/fdfmerge-testdata"
2021
env.UNIDOC_GS_BIN_PATH="/usr/bin/gs"
@@ -85,7 +86,7 @@ node {
8586
sh("printenv")
8687

8788
// Pull unipdf-examples from connected branch, or master otherwise.
88-
def examplesBranch = "v3"
89+
def examplesBranch = "development"
8990

9091
// Check if connected branch is defined explicitly.
9192
def safeName = env.BRANCH_NAME.replaceAll(/[\/\.]/, '')

common/version.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import (
1111
)
1212

1313
const releaseYear = 2019
14-
const releaseMonth = 8
15-
const releaseDay = 4
16-
const releaseHour = 11
17-
const releaseMin = 40
14+
const releaseMonth = 9
15+
const releaseDay = 7
16+
const releaseHour = 13
17+
const releaseMin = 10
1818

1919
// Version holds version information, when bumping this make sure to bump the released at stamp also.
20-
const Version = "3.1.1"
20+
const Version = "3.2.0"
2121

2222
var ReleasedAt = time.Date(releaseYear, releaseMonth, releaseDay, releaseHour, releaseMin, 0, 0, time.UTC)

core/encoding.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2138,9 +2138,7 @@ func (enc *JBIG2Encoder) DecodeBytes(encoded []byte) ([]byte, error) {
21382138
if err != nil {
21392139
return nil, err
21402140
}
2141-
2142-
// Inverse the data representation if the decoder is marked as 'isChocolateData'.
2143-
bm.InverseData(enc.IsChocolateData)
2141+
bm.GetVanillaData()
21442142

21452143
// By default the bitmap data contains the rowstride padding.
21462144
// In order to get rid of the rowstride padding use the bitmap.GetUnpaddedData method.

creator/creator.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,11 @@ func (c *Creator) initContext() {
291291
}
292292

293293
// NewPage adds a new Page to the Creator and sets as the active Page.
294-
func (c *Creator) NewPage() {
294+
func (c *Creator) NewPage() *model.PdfPage {
295295
page := c.newPage()
296296
c.pages = append(c.pages, page)
297297
c.context.Page++
298+
return page
298299
}
299300

300301
// AddPage adds the specified page to the creator.
@@ -482,6 +483,8 @@ func (c *Creator) finalize() error {
482483

483484
for idx, page := range c.pages {
484485
c.setActivePage(page)
486+
487+
// Draw page header.
485488
if c.drawHeaderFunc != nil {
486489
// Prepare a block to draw on.
487490
// Header is drawn on the top of the page. Has width of the page, but height limited to
@@ -493,12 +496,14 @@ func (c *Creator) finalize() error {
493496
}
494497
c.drawHeaderFunc(headerBlock, args)
495498
headerBlock.SetPos(0, 0)
496-
err := c.Draw(headerBlock)
497-
if err != nil {
499+
500+
if err := c.Draw(headerBlock); err != nil {
498501
common.Log.Debug("ERROR: drawing header: %v", err)
499502
return err
500503
}
501504
}
505+
506+
// Draw page footer.
502507
if c.drawFooterFunc != nil {
503508
// Prepare a block to draw on.
504509
// Footer is drawn on the bottom of the page. Has width of the page, but height limited
@@ -510,25 +515,25 @@ func (c *Creator) finalize() error {
510515
}
511516
c.drawFooterFunc(footerBlock, args)
512517
footerBlock.SetPos(0, c.pageHeight-footerBlock.height)
513-
err := c.Draw(footerBlock)
514-
if err != nil {
518+
519+
if err := c.Draw(footerBlock); err != nil {
515520
common.Log.Debug("ERROR: drawing footer: %v", err)
516521
return err
517522
}
518523
}
519524

520-
// Draw blocks to pages.
525+
// Draw page blocks.
521526
block, ok := c.pageBlocks[page]
522527
if !ok {
523-
return errors.New("could not find page block")
528+
continue
524529
}
525530
if err := block.drawToPage(page); err != nil {
531+
common.Log.Debug("ERROR: drawing page %d blocks: %v", idx+1, err)
526532
return err
527533
}
528534
}
529535

530536
c.finalized = true
531-
532537
return nil
533538
}
534539

@@ -600,7 +605,9 @@ func (c *Creator) Draw(d Drawable) error {
600605
// Write output of creator to io.Writer interface.
601606
func (c *Creator) Write(ws io.Writer) error {
602607
if !c.finalized {
603-
c.finalize()
608+
if err := c.finalize(); err != nil {
609+
return err
610+
}
604611
}
605612

606613
pdfWriter := model.NewPdfWriter()

creator/paragraph.go

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package creator
77

88
import (
99
"errors"
10-
"fmt"
1110
"strconv"
1211

1312
"github.com/unidoc/unipdf/v3/common"
@@ -489,7 +488,6 @@ func drawParagraphOnBlock(blk *Block, p *Paragraph, ctx DrawContext) (DrawContex
489488
enc := p.textFont.Encoder()
490489

491490
var encoded []byte
492-
isCID := p.textFont.IsCID()
493491
for _, r := range runes {
494492
if r == ' ' { // TODO: What about \t and other spaces.
495493
if len(encoded) > 0 {
@@ -498,19 +496,11 @@ func drawParagraphOnBlock(blk *Block, p *Paragraph, ctx DrawContext) (DrawContex
498496
}
499497
objs = append(objs, core.MakeFloat(-spaceWidth))
500498
} else {
501-
code, ok := enc.RuneToCharcode(r)
502-
if !ok {
503-
err := fmt.Errorf("unsupported rune in text encoding: %#x (%c)", r, r)
504-
common.Log.Debug("%s", err)
505-
return ctx, err
506-
}
507-
// TODO(dennwc): this should not be done manually; encoder should do this
508-
if isCID {
509-
hi, lo := code>>8, code&0xff
510-
encoded = append(encoded, byte(hi), byte(lo))
511-
} else {
512-
encoded = append(encoded, byte(code))
499+
if _, ok := enc.RuneToCharcode(r); !ok {
500+
common.Log.Debug("unsupported rune in text encoding: %#x (%c)", r, r)
501+
continue
513502
}
503+
encoded = append(encoded, enc.Encode(string(r))...)
514504
}
515505
}
516506
if len(encoded) > 0 {

creator/styled_paragraph.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,10 @@ func drawStyledParagraphOnBlock(blk *Block, p *StyledParagraph, ctx DrawContext)
761761

762762
chunkWidths[k] += spaceWidth * fontSize
763763
} else {
764+
if _, ok := enc.RuneToCharcode(rn); !ok {
765+
common.Log.Debug("unsupported rune in text encoding: %#x (%c)", rn, rn)
766+
continue
767+
}
764768
encStr = append(encStr, enc.Encode(string(rn))...)
765769
}
766770
}

creator/text_chunk.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,9 @@ func newExternalLinkAnnotation(url string) *model.PdfAnnotation {
4444
annotation.BS = bs.ToPdfObject()
4545

4646
// Set link destination.
47-
action := core.MakeDict()
48-
action.Set(core.PdfObjectName("S"), core.MakeName("URI"))
49-
action.Set(core.PdfObjectName("URI"), core.MakeString(url))
50-
annotation.A = action
47+
action := model.NewPdfActionURI()
48+
action.URI = core.MakeString(url)
49+
annotation.SetAction(action.PdfAction)
5150

5251
return annotation.PdfAnnotation
5352
}

extractor/text.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,14 +1180,46 @@ var (
11801180
// sortPosition sorts a text list by its elements' positions on a page.
11811181
// Sorting is by orientation then top to bottom, left to right when page is orientated so that text
11821182
// is horizontal.
1183+
// Text is considered to be on different lines if the lines' orientedStart.Y differs by more than `tol`.
11831184
func (pt *PageText) sortPosition(tol float64) {
1185+
if len(pt.marks) == 0 {
1186+
return
1187+
}
1188+
1189+
// For grouping data vertically into lines, it is necessary to have the data presorted by
1190+
// descending y position.
1191+
sort.SliceStable(pt.marks, func(i, j int) bool {
1192+
ti, tj := pt.marks[i], pt.marks[j]
1193+
if ti.orient != tj.orient {
1194+
return ti.orient < tj.orient
1195+
}
1196+
return ti.orientedStart.Y >= tj.orientedStart.Y
1197+
})
1198+
1199+
// Cluster the marks into y-clusters by relative y proximity. Each cluster is our guess of what
1200+
// makes up a line of text.
1201+
clusters := make([]int, len(pt.marks))
1202+
cluster := 0
1203+
clusters[0] = cluster
1204+
for i := 1; i < len(pt.marks); i++ {
1205+
if pt.marks[i-1].orient != pt.marks[i].orient {
1206+
cluster++
1207+
} else {
1208+
if pt.marks[i-1].orientedStart.Y - pt.marks[i].orientedStart.Y > tol {
1209+
cluster++
1210+
}
1211+
}
1212+
clusters[i] = cluster
1213+
}
1214+
1215+
// Sort by y-cluster and x.
11841216
sort.SliceStable(pt.marks, func(i, j int) bool {
11851217
ti, tj := pt.marks[i], pt.marks[j]
11861218
if ti.orient != tj.orient {
11871219
return ti.orient < tj.orient
11881220
}
1189-
if math.Abs(ti.orientedStart.Y-tj.orientedStart.Y) > tol {
1190-
return ti.orientedStart.Y > tj.orientedStart.Y
1221+
if clusters[i] != clusters[j] {
1222+
return clusters[i] < clusters[j]
11911223
}
11921224
return ti.orientedStart.X < tj.orientedStart.X
11931225
})

0 commit comments

Comments
 (0)