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 (
"errors"
"fmt"
"github.com/unidoc/unidoc/pdf/contentstream"
"github.com/unidoc/unidoc/pdf/core"
"github.com/unidoc/unidoc/pdf/model"
@ -348,6 +350,7 @@ func mergeContents(contents *contentstream.ContentStreamOperations, resources *m
xobjectMap := map[core.PdfObjectName]core.PdfObjectName{}
fontMap := map[core.PdfObjectName]core.PdfObjectName{}
csMap := map[core.PdfObjectName]core.PdfObjectName{}
gstateMap := map[core.PdfObjectName]core.PdfObjectName{}
for _, op := range *contentsToAdd {
switch op.Operand {
@ -432,6 +435,35 @@ func mergeContents(contents *contentstream.ContentStreamOperations, resources *m
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)

View File

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