mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 08:46:55 +08:00
1 parent
c8a163a077
commit
0351dd54f5
31 files changed
+993
-311
No files matched your search
+61
-28
@@ -56,8 +56,11 @@ type pdfCompositor struct {
|
||||
meshes map[pdfMeshKey][]pdfShadingPixel
|
||||
gradients map[pdfGradientKey][]pdfShadingPixel
|
||||
transfers []*pdfgo.TransferFunction
|
||||
channels []uint8
|
||||
transferModel pdfgo.Name
|
||||
transferBlocked bool
|
||||
shadingSource bool
|
||||
softMask bool
|
||||
}
|
||||
|
||||
// pdfCompositeKey 区分图元的填充与描边几何
|
||||
@@ -89,10 +92,18 @@ type pdfCompositeColorSampler struct {
|
||||
values map[float64][4]float64
|
||||
position pdfgo.GradientPosition
|
||||
converter pdfgo.ColorConverter
|
||||
colorants *pdfShadingColorants
|
||||
prepared bool
|
||||
converted bool
|
||||
}
|
||||
|
||||
// pdfImageProcessKey 隔离图像的组空间及软蒙版采样,不复用错误的原生映射
|
||||
type pdfImageProcessKey struct {
|
||||
image *pdfgo.Image
|
||||
space *pdfgo.ColorSpace
|
||||
softMask bool
|
||||
}
|
||||
|
||||
// pdfCompositeCache 在单页内复用几何、图像分量及蒙版内容
|
||||
type pdfCompositeCache struct {
|
||||
geometry *renderCache[pdfCompositeSceneKey, pdfCompositeGeometry]
|
||||
@@ -100,6 +111,7 @@ type pdfCompositeCache struct {
|
||||
bounds map[pdfCompositeKey]Box
|
||||
images map[*pdfgo.Image]*pdfgo.ImageComponents
|
||||
imageMatrix map[*pdfgo.ImageMark]pdfgo.Matrix
|
||||
imageProcesses map[pdfImageProcessKey]*pdfgo.ImageProcess
|
||||
masks map[*pdfgo.SoftMask][]pdfCompositeNode
|
||||
meshes map[*pdfgo.MeshGradient][]pdfMeshTriangle
|
||||
patterns map[pdfgo.Paint]*pdfCompositePattern
|
||||
@@ -346,9 +358,6 @@ func (p *pdfImporter) collectCompositeNodes(walk func(pdfgo.Visitor) error) ([]p
|
||||
if err := p.halftone(mark.Style); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.resolveTransfer(&mark.Style); err != nil {
|
||||
return err
|
||||
}
|
||||
nodes = append(nodes, pdfCompositeNode{path: &mark})
|
||||
return nil
|
||||
}
|
||||
@@ -386,9 +395,6 @@ func (p *pdfImporter) collectCompositeNodes(walk func(pdfgo.Visitor) error) ([]p
|
||||
if err := p.halftone(mark.Style); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.resolveTransfer(&mark.Style); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(mark.Glyphs) > 1 && (mark.Object != nil && !mark.Object.Knockout || mark.Style.AlphaIsShape || mark.Style.Fill.Alpha != 1 || mark.Style.Stroke.Alpha != 1 || mark.Style.SoftMask != nil || !pdfNormalBlend(mark.Style.BlendMode) || mark.Mode%4 == 1 || mark.Mode%4 == 2) {
|
||||
for i := range mark.Glyphs {
|
||||
glyph := mark
|
||||
@@ -426,9 +432,6 @@ func (p *pdfImporter) collectCompositeNodes(walk func(pdfgo.Visitor) error) ([]p
|
||||
if err := p.halftone(mark.Style); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.resolveTransfer(&mark.Style); err != nil {
|
||||
return err
|
||||
}
|
||||
nodes = append(nodes, pdfCompositeNode{image: &mark})
|
||||
return nil
|
||||
}
|
||||
@@ -499,15 +502,19 @@ func (p *pdfImporter) compositePage(space *pdfgo.ColorSpace, walk func(pdfgo.Vis
|
||||
p.compositeNodes = nil
|
||||
p.transferBackdrop = false
|
||||
p.compositeSpace = space
|
||||
if pdfCompositeHasTransfer(nodes) {
|
||||
device, err := p.transferDevice(space, nodes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.transferModel = device
|
||||
hasTransfer, err := p.compositeHasTransfer(nodes, device)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if hasTransfer {
|
||||
if p.warning == nil {
|
||||
return &pdfgo.UnsupportedError{Feature: "device transfer function rasterization"}
|
||||
}
|
||||
if overprint, err := p.processOverprint(nodes); err != nil {
|
||||
return err
|
||||
} else if overprint {
|
||||
return &pdfgo.UnsupportedError{Feature: "per-colorant transfer function overprinting"}
|
||||
}
|
||||
if err := p.compositeRegion(nil, pdfCompositeNode{group: &pdfgo.GroupMark{Alpha: 1, ColorSpace: space}, children: nodes}, space, true); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -540,16 +547,16 @@ func (p *pdfImporter) compositeObjects(nodes []pdfCompositeNode) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("inspect graphic %d: %w", i+1, err)
|
||||
}
|
||||
transfer := pdfCompositeHasTransfer([]pdfCompositeNode{node})
|
||||
device := p.transferModel
|
||||
if device == "" {
|
||||
device = "DeviceRGB"
|
||||
}
|
||||
transfer, err := p.compositeHasTransfer([]pdfCompositeNode{node}, device)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p.transferBackdrop || transfer {
|
||||
direct = false
|
||||
for _, source := range [][]pdfCompositeNode{p.compositeNodes, {node}} {
|
||||
if overprint, err := p.processOverprint(source); err != nil {
|
||||
return err
|
||||
} else if overprint {
|
||||
return &pdfgo.UnsupportedError{Feature: "per-colorant transfer function overprinting"}
|
||||
}
|
||||
}
|
||||
}
|
||||
if direct {
|
||||
if err := node.emit(p.visitor()); err != nil {
|
||||
@@ -785,7 +792,19 @@ func (p *pdfImporter) compositeRegion(backdrop []pdfCompositeNode, node pdfCompo
|
||||
scratch := &pdfCompositeScratch{}
|
||||
var transfers []*pdfgo.TransferFunction
|
||||
var previousTransfers []*pdfgo.TransferFunction
|
||||
if pdfCompositeHasTransfer(backdrop) || pdfCompositeHasTransfer([]pdfCompositeNode{node}) {
|
||||
device := p.transferModel
|
||||
if device == "" {
|
||||
device = "DeviceRGB"
|
||||
}
|
||||
hasTransfer := false
|
||||
for _, nodes := range [][]pdfCompositeNode{backdrop, {node}} {
|
||||
found, err := p.compositeHasTransfer(nodes, device)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hasTransfer = hasTransfer || found
|
||||
}
|
||||
if hasTransfer {
|
||||
transfers = make([]*pdfgo.TransferFunction, len(buffer))
|
||||
previousTransfers = make([]*pdfgo.TransferFunction, len(buffer))
|
||||
}
|
||||
@@ -799,6 +818,7 @@ func (p *pdfImporter) compositeRegion(backdrop []pdfCompositeNode, node pdfCompo
|
||||
c := pdfCompositor{importer: p, box: Box{X: box.X + float64(x)*step, Y: box.Y + float64(y)*step, W: float64(width) * step, H: float64(height) * step}, width: width, height: height, inverse: inverse, cache: cache, scratch: scratch, masks: map[*pdfgo.SoftMask][]float64{}}
|
||||
if transfers != nil {
|
||||
c.transfers = transfers[:width*height]
|
||||
c.transferModel = device
|
||||
clear(c.transfers)
|
||||
}
|
||||
pixels := buffer[:width*height]
|
||||
@@ -824,7 +844,18 @@ func (p *pdfImporter) compositeRegion(backdrop []pdfCompositeNode, node pdfCompo
|
||||
}
|
||||
var rgb [3]float64
|
||||
var err error
|
||||
if c.transfers != nil {
|
||||
if c.transfers != nil && device == "DeviceCMYK" {
|
||||
values := pixel.values
|
||||
if flatten {
|
||||
for j := range values {
|
||||
values[j] *= pixel.alpha
|
||||
}
|
||||
}
|
||||
values, err = c.transfers[i].Apply(values[:], device, "")
|
||||
if err == nil {
|
||||
rgb, err = pdfCompositeOutputColor(space, values)
|
||||
}
|
||||
} else if c.transfers != nil {
|
||||
rgb, err = space.RGB(pixel.values[:space.Components()], "RelativeColorimetric")
|
||||
} else {
|
||||
rgb, err = pdfCompositeOutputColor(space, pixel.values)
|
||||
@@ -834,12 +865,14 @@ func (p *pdfImporter) compositeRegion(backdrop []pdfCompositeNode, node pdfCompo
|
||||
}
|
||||
alpha := pixel.alpha
|
||||
if flatten {
|
||||
for j := range rgb {
|
||||
rgb[j] = pixel.alpha*rgb[j] + 1 - pixel.alpha
|
||||
if c.transfers == nil || device != "DeviceCMYK" {
|
||||
for j := range rgb {
|
||||
rgb[j] = pixel.alpha*rgb[j] + 1 - pixel.alpha
|
||||
}
|
||||
}
|
||||
alpha = 1
|
||||
}
|
||||
if c.transfers != nil && c.transfers[i] != nil {
|
||||
if c.transfers != nil && device != "DeviceCMYK" && c.transfers[i] != nil {
|
||||
values, err := c.transfers[i].Apply(rgb[:], "DeviceRGB", "")
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in new issue
Block a user