Skip to content

Commit

Permalink
document: add footer image support
Browse files Browse the repository at this point in the history
Add support for adding images to footers.
  • Loading branch information
im-kulikov authored and tbaliance committed Jul 16, 2018
1 parent 675d117 commit 1f94b99
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 21 deletions.
21 changes: 9 additions & 12 deletions common/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ import (
_ "image/gif"
_ "image/jpeg"
_ "image/png"

"baliance.com/gooxml"
)

// Image is a container for image information. It's used as we need format and
Expand All @@ -31,9 +29,10 @@ type Image struct {

// ImageRef is a reference to an image within a document.
type ImageRef struct {
d *DocBase
rels Relationships
img Image
d *DocBase
rels Relationships
img Image
relID string
}

// MakeImageRef constructs an image reference which is a reference to a
Expand All @@ -43,15 +42,13 @@ func MakeImageRef(img Image, d *DocBase, rels Relationships) ImageRef {
return ImageRef{img: img, d: d, rels: rels}
}

func (i *ImageRef) SetRelID(id string) {
i.relID = id
}

// RelID returns the relationship ID.
func (i ImageRef) RelID() string {
for imgIdx, ir := range i.d.Images {
if ir.img == i.img {
imgID := i.rels.FindRIDForN(imgIdx, gooxml.ImageType)
return imgID
}
}
return ""
return i.relID
}

// Format returns the format of the underlying image
Expand Down
16 changes: 15 additions & 1 deletion document/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type Document struct {
hdrRels []common.Relationships

footers []*wml.Ftr
ftrRels []common.Relationships

docRels common.Relationships
themes []*dml.Theme
Expand Down Expand Up @@ -132,7 +133,10 @@ func (d *Document) AddFooter() Footer {
d.footers = append(d.footers, ftr)
path := fmt.Sprintf("footer%d.xml", len(d.footers))
d.docRels.AddRelationship(path, gooxml.FooterType)

d.ContentTypes.AddOverride("/word/"+path, "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml")
d.ftrRels = append(d.ftrRels, common.NewRelationships())

return Footer{d, ftr}
}

Expand Down Expand Up @@ -228,9 +232,13 @@ func (d *Document) Save(w io.Writer) error {
}
}
for i, ftr := range d.footers {
fn := gooxml.AbsoluteFilename(dt, gooxml.FooterType, i+1)
if err := zippkg.MarshalXMLByTypeIndex(z, dt, gooxml.FooterType, i+1, ftr); err != nil {
return err
}
if !d.ftrRels[i].IsEmpty() {
zippkg.MarshalXML(z, zippkg.RelationsPathFor(fn), d.ftrRels[i].X())
}
}

for i, img := range d.Images {
Expand Down Expand Up @@ -570,12 +578,13 @@ func (d *Document) AddImage(i common.Image) (common.ImageRef, error) {

d.Images = append(d.Images, r)
fn := fmt.Sprintf("media/image%d.%s", len(d.Images), i.Format)
d.docRels.AddRelationship(fn, gooxml.ImageType)
rel := d.docRels.AddRelationship(fn, gooxml.ImageType)
d.ContentTypes.EnsureDefault("png", "image/png")
d.ContentTypes.EnsureDefault("jpeg", "image/jpeg")
d.ContentTypes.EnsureDefault("jpg", "image/jpeg")
d.ContentTypes.EnsureDefault("wmf", "image/x-wmf")
d.ContentTypes.EnsureDefault(i.Format, "image/"+i.Format)
r.SetRelID(rel.X().IdAttr)
return r, nil
}

Expand Down Expand Up @@ -711,6 +720,11 @@ func (d *Document) onNewRelationship(decMap *zippkg.DecodeMap, target, typ strin
d.footers = append(d.footers, ftr)
rel.TargetAttr = gooxml.RelativeFilename(dt, src.Typ, typ, len(d.footers))

// look for footer rels
ftrRel := common.NewRelationships()
decMap.AddTarget(zippkg.RelationsPathFor(target), ftrRel.X(), typ, 0)
d.ftrRels = append(d.ftrRels, ftrRel)

case gooxml.ThemeType:
thm := dml.NewTheme()
decMap.AddTarget(target, thm, typ, uint32(len(d.themes)))
Expand Down
20 changes: 14 additions & 6 deletions document/document_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func TestDuplicateBookmarks(t *testing.T) {
}
}

func TestHeaderImages(t *testing.T) {
func TestHeaderAndFooterImages(t *testing.T) {
doc := document.New()
img1, err := common.ImageFromFile("testdata/gopher.png")
if err != nil {
Expand All @@ -226,20 +226,28 @@ func TestHeaderImages(t *testing.T) {
}

if dir1.RelID() != "rId4" {
t.Errorf("expected rId4")
t.Errorf("expected rId4 != %s", dir1.RelID())
}
if dir2.RelID() != "rId5" {
t.Errorf("expected rId5")
t.Errorf("expected rId5 != %s", dir2.RelID())
}

hdr := doc.AddHeader()
ftr := doc.AddFooter()
hir1, err := hdr.AddImage(img1)
fir1, err := ftr.AddImage(img1)
hir2, err := hdr.AddImage(img2)
fir2, err := ftr.AddImage(img2)
if hir1.RelID() != "rId1" {
t.Errorf("expected rId1")
t.Errorf("expected rId1 != %s", hir1.RelID())
}
if hir2.RelID() != "rId2" {
t.Errorf("expected rId1")
t.Errorf("expected rId2 != %s", hir2.RelID())
}
if fir1.RelID() != "rId1" {
t.Errorf("expected rId1 != %s", hir1.RelID())
}
if fir2.RelID() != "rId2" {
t.Errorf("expected rId2 != %s", hir2.RelID())
}

}
38 changes: 37 additions & 1 deletion document/footer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@

package document

import "baliance.com/gooxml/schema/soo/wml"
import (
"errors"
"fmt"

"baliance.com/gooxml"
"baliance.com/gooxml/common"
"baliance.com/gooxml/schema/soo/wml"
)

// Footer is a footer for a document section.
type Footer struct {
Expand Down Expand Up @@ -70,3 +77,32 @@ func (f Footer) RemoveParagraph(p Paragraph) {
func (f Footer) Clear() {
f.x.EG_ContentBlockContent = nil
}

// AddImage adds an image to the document package, returning a reference that
// can be used to add the image to a run and place it in the document contents.
func (f Footer) AddImage(i common.Image) (common.ImageRef, error) {
var ftrRels common.Relationships
for i, ftr := range f.d.footers {
if ftr == f.x {
ftrRels = f.d.ftrRels[i]
}
}

r := common.MakeImageRef(i, &f.d.DocBase, ftrRels)
if i.Path == "" {
return r, errors.New("image must have a path")
}

if i.Format == "" {
return r, errors.New("image must have a valid format")
}
if i.Size.X == 0 || i.Size.Y == 0 {
return r, errors.New("image must have a valid size")
}

f.d.Images = append(f.d.Images, r)
fn := fmt.Sprintf("media/image%d.%s", len(f.d.Images), i.Format)
rel := ftrRels.AddRelationship(fn, gooxml.ImageType)
r.SetRelID(rel.X().IdAttr)
return r, nil
}
3 changes: 2 additions & 1 deletion document/header.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func (h Header) AddImage(i common.Image) (common.ImageRef, error) {

h.d.Images = append(h.d.Images, r)
fn := fmt.Sprintf("media/image%d.%s", len(h.d.Images), i.Format)
hdrRels.AddRelationship(fn, gooxml.ImageType)
rel := hdrRels.AddRelationship(fn, gooxml.ImageType)
r.SetRelID(rel.X().IdAttr)
return r, nil
}

0 comments on commit 1f94b99

Please sign in to comment.