Allow specifying image opacity via graphics state. Support ExtGState when merging content streams (in blocks).

This commit is contained in:
Gunnsteinn Hall 2017-07-13 14:20:02 +00:00
parent 9e755691ff
commit 2e70c34829
2 changed files with 47 additions and 1 deletions

View File

@ -8,6 +8,8 @@ package creator
import ( import (
"errors" "errors"
"fmt"
"github.com/unidoc/unidoc/pdf/contentstream" "github.com/unidoc/unidoc/pdf/contentstream"
"github.com/unidoc/unidoc/pdf/core" "github.com/unidoc/unidoc/pdf/core"
"github.com/unidoc/unidoc/pdf/model" "github.com/unidoc/unidoc/pdf/model"
@ -348,6 +350,7 @@ func mergeContents(contents *contentstream.ContentStreamOperations, resources *m
xobjectMap := map[core.PdfObjectName]core.PdfObjectName{} xobjectMap := map[core.PdfObjectName]core.PdfObjectName{}
fontMap := map[core.PdfObjectName]core.PdfObjectName{} fontMap := map[core.PdfObjectName]core.PdfObjectName{}
csMap := map[core.PdfObjectName]core.PdfObjectName{} csMap := map[core.PdfObjectName]core.PdfObjectName{}
gstateMap := map[core.PdfObjectName]core.PdfObjectName{}
for _, op := range *contentsToAdd { for _, op := range *contentsToAdd {
switch op.Operand { switch op.Operand {
@ -432,6 +435,35 @@ func mergeContents(contents *contentstream.ContentStreamOperations, resources *m
op.Params[0] = &useName op.Params[0] = &useName
} }
} }
case "gs":
// ExtGState.
if len(op.Params) == 1 {
if name, ok := op.Params[0].(*core.PdfObjectName); ok {
if _, processed := gstateMap[*name]; !processed {
var useName core.PdfObjectName
// Process if not already processed.
gs, found := resourcesToAdd.GetExtGState(*name)
if found {
useName = *name
i := 1
for {
gs2, found := resources.GetExtGState(useName)
if !found || gs == gs2 {
break
}
useName = core.PdfObjectName(fmt.Sprintf("GS%d", i))
i++
}
}
resources.AddExtGState(useName, gs)
gstateMap[*name] = useName
}
useName := gstateMap[*name]
op.Params[0] = &useName
}
}
} }
*contents = append(*contents, op) *contents = append(*contents, op)

View File

@ -38,6 +38,9 @@ type image struct {
xPos float64 xPos float64
yPos float64 yPos float64
// Opacity (alpha value).
opacity float64
// Margins to be applied around the block when drawing on Page. // Margins to be applied around the block when drawing on Page.
margins margins margins margins
@ -71,6 +74,7 @@ func NewImage(data []byte) (*image, error) {
image.width = image.origWidth image.width = image.origWidth
image.height = image.origHeight image.height = image.origHeight
image.angle = 0 image.angle = 0
image.opacity = 1.0
image.positioning = positionRelative image.positioning = positionRelative
@ -131,6 +135,11 @@ func (img *image) Width() float64 {
return img.width return img.width
} }
// Set opacity
func (img *image) SetOpacity(opacity float64) {
img.opacity = opacity
}
// Set the image Margins. // Set the image Margins.
func (img *image) SetMargins(left, right, top, bottom float64) { func (img *image) SetMargins(left, right, top, bottom float64) {
img.margins.left = left img.margins.left = left
@ -263,7 +272,12 @@ func drawImageOnBlock(blk *Block, img *image, ctx DrawContext) (DrawContext, err
// Graphics state with normal blend mode. // Graphics state with normal blend mode.
gs0 := core.MakeDict() gs0 := core.MakeDict()
gs0.Set("BM", core.MakeName("Normal")) gs0.Set("BM", core.MakeName("Normal"))
err = blk.resources.AddExtGState(gsName, gs0) if img.opacity < 1.0 {
gs0.Set("CA", core.MakeFloat(img.opacity))
gs0.Set("ca", core.MakeFloat(img.opacity))
}
err = blk.resources.AddExtGState(gsName, core.MakeIndirectObject(gs0))
if err != nil { if err != nil {
return ctx, err return ctx, err
} }