mirror of
https://github.com/unidoc/unipdf.git
synced 2025-05-09 19:29:34 +08:00
Merge pull request #225 from a5i/v3-fix-combine-objects
Fix combine objects optimizations
This commit is contained in:
commit
8477b05897
@ -2415,37 +2415,40 @@ func TestCombineDuplicateDirectObjects(t *testing.T) {
|
||||
"mollit anim id est laborum.")
|
||||
p.SetTextAlignment(TextAlignmentJustify)
|
||||
p.SetMargins(0, 0, 5, 0)
|
||||
for j := 0; j < 7; j++ {
|
||||
|
||||
for j := 0; j < 2; j++ {
|
||||
subchap1.Add(p)
|
||||
}
|
||||
|
||||
subchap2 := c.NewSubchapter(ch1, "Mechanism")
|
||||
subchap2.SetMargins(0, 0, 5, 0)
|
||||
for j := 0; j < 15; j++ {
|
||||
for j := 0; j < 3; j++ {
|
||||
subchap2.Add(p)
|
||||
}
|
||||
|
||||
subchap3 := c.NewSubchapter(ch1, "Discussion")
|
||||
subchap3.SetMargins(0, 0, 5, 0)
|
||||
for j := 0; j < 19; j++ {
|
||||
for j := 0; j < 4; j++ {
|
||||
subchap3.Add(p)
|
||||
}
|
||||
|
||||
subchap4 := c.NewSubchapter(ch1, "Conclusion")
|
||||
subchap4.SetMargins(0, 0, 5, 0)
|
||||
for j := 0; j < 23; j++ {
|
||||
for j := 0; j < 3; j++ {
|
||||
subchap4.Add(p)
|
||||
}
|
||||
|
||||
c.Draw(ch1)
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
for i := 0; i < 5; i++ {
|
||||
ch2 := c.NewChapter("References")
|
||||
ch2.SetMargins(1, 1, 1, 1)
|
||||
for j := 0; j < 13; j++ {
|
||||
ch2.Add(p)
|
||||
}
|
||||
|
||||
metadata := core.MakeDict()
|
||||
metadata.Set(core.PdfObjectName("TEST"), core.MakeString("---------------- ## ----------------"))
|
||||
c.Draw(ch2)
|
||||
c.getActivePage().Metadata = metadata
|
||||
}
|
||||
|
||||
// Set a function to create the front Page.
|
||||
|
@ -18,17 +18,16 @@ type CombineDuplicateDirectObjects struct {
|
||||
|
||||
// Optimize optimizes PDF objects to decrease PDF size.
|
||||
func (dup *CombineDuplicateDirectObjects) Optimize(objects []core.PdfObject) (optimizedObjects []core.PdfObject, err error) {
|
||||
|
||||
updateObjectNumbers(objects)
|
||||
dictsByHash := make(map[string][]*core.PdfObjectDictionary)
|
||||
var processDict func(pDict *core.PdfObjectDictionary)
|
||||
processDict = func(pDict *core.PdfObjectDictionary) {
|
||||
|
||||
processDict = func(pDict *core.PdfObjectDictionary) {
|
||||
for _, key := range pDict.Keys() {
|
||||
obj := pDict.Get(key)
|
||||
if dict, isDictObj := obj.(*core.PdfObjectDictionary); isDictObj {
|
||||
hasher := md5.New()
|
||||
hasher.Write([]byte(dict.DefaultWriteString()))
|
||||
|
||||
hash := string(hasher.Sum(nil))
|
||||
dictsByHash[hash] = append(dictsByHash[hash], dict)
|
||||
processDict(dict)
|
||||
|
@ -18,6 +18,7 @@ type CombineIdenticalIndirectObjects struct {
|
||||
|
||||
// Optimize optimizes PDF objects to decrease PDF size.
|
||||
func (c *CombineIdenticalIndirectObjects) Optimize(objects []core.PdfObject) (optimizedObjects []core.PdfObject, err error) {
|
||||
updateObjectNumbers(objects)
|
||||
replaceTable := make(map[core.PdfObject]core.PdfObject)
|
||||
toDelete := make(map[core.PdfObject]struct{})
|
||||
|
||||
|
@ -82,3 +82,21 @@ func replaceObjectsInPlace(objects []core.PdfObject, objTo map[core.PdfObject]co
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update all the object numbers prior to get hash of objects.
|
||||
func updateObjectNumbers(objects []core.PdfObject) {
|
||||
// Update numbers
|
||||
for idx, obj := range objects {
|
||||
switch o := obj.(type) {
|
||||
case *core.PdfIndirectObject:
|
||||
o.ObjectNumber = int64(idx + 1)
|
||||
o.GenerationNumber = 0
|
||||
case *core.PdfObjectStream:
|
||||
o.ObjectNumber = int64(idx + 1)
|
||||
o.GenerationNumber = 0
|
||||
case *core.PdfObjectStreams:
|
||||
o.ObjectNumber = int64(idx + 1)
|
||||
o.GenerationNumber = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -636,17 +636,16 @@ func (this *PdfWriter) writeObject(num int, obj PdfObject) {
|
||||
func (this *PdfWriter) updateObjectNumbers() {
|
||||
// Update numbers
|
||||
for idx, obj := range this.objects {
|
||||
if io, isIndirect := obj.(*PdfIndirectObject); isIndirect {
|
||||
io.ObjectNumber = int64(idx + 1)
|
||||
io.GenerationNumber = 0
|
||||
}
|
||||
if so, isStream := obj.(*PdfObjectStream); isStream {
|
||||
so.ObjectNumber = int64(idx + 1)
|
||||
so.GenerationNumber = 0
|
||||
}
|
||||
if so, isObjectStreams := obj.(*PdfObjectStreams); isObjectStreams {
|
||||
so.ObjectNumber = int64(idx + 1)
|
||||
so.GenerationNumber = 0
|
||||
switch o := obj.(type) {
|
||||
case *PdfIndirectObject:
|
||||
o.ObjectNumber = int64(idx + 1)
|
||||
o.GenerationNumber = 0
|
||||
case *PdfObjectStream:
|
||||
o.ObjectNumber = int64(idx + 1)
|
||||
o.GenerationNumber = 0
|
||||
case *PdfObjectStreams:
|
||||
o.ObjectNumber = int64(idx + 1)
|
||||
o.GenerationNumber = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user