185 lines
5.8 KiB
Go
185 lines
5.8 KiB
Go
// Copyright (c) Kurt Jung (Gmail: kurt.w.jung)
|
|
//
|
|
// Permission to use, copy, modify, and distribute this software for any
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
// copyright notice and this permission notice appear in all copies.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
// Adapted from http://www.fpdf.org/en/script/script89.php by Olivier PLATHEY
|
|
|
|
package gofpdf
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
func byteBound(v byte) byte {
|
|
if v > 100 {
|
|
return 100
|
|
}
|
|
return v
|
|
}
|
|
|
|
// AddSpotColor adds an ink-based CMYK color to the gofpdf instance and
|
|
// associates it with the specified name. The individual components specify
|
|
// percentages ranging from 0 to 100. Values above this are quietly capped to
|
|
// 100. An error occurs if the specified name is already associated with a
|
|
// color.
|
|
func (f *Fpdf) AddSpotColor(nameStr string, c, m, y, k byte) {
|
|
if f.err == nil {
|
|
_, ok := f.spotColorMap[nameStr]
|
|
if !ok {
|
|
id := len(f.spotColorMap) + 1
|
|
f.spotColorMap[nameStr] = spotColorType{
|
|
id: id,
|
|
val: cmykColorType{
|
|
c: byteBound(c),
|
|
m: byteBound(m),
|
|
y: byteBound(y),
|
|
k: byteBound(k),
|
|
},
|
|
}
|
|
} else {
|
|
f.err = fmt.Errorf("name \"%s\" is already associated with a spot color", nameStr)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (f *Fpdf) getSpotColor(nameStr string) (clr spotColorType, ok bool) {
|
|
if f.err == nil {
|
|
clr, ok = f.spotColorMap[nameStr]
|
|
if !ok {
|
|
f.err = fmt.Errorf("spot color name \"%s\" is not registered", nameStr)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// SetDrawSpotColor sets the current draw color to the spot color associated
|
|
// with nameStr. An error occurs if the name is not associated with a color.
|
|
// The value for tint ranges from 0 (no intensity) to 100 (full intensity). It
|
|
// is quietly bounded to this range.
|
|
func (f *Fpdf) SetDrawSpotColor(nameStr string, tint byte) {
|
|
var clr spotColorType
|
|
var ok bool
|
|
|
|
clr, ok = f.getSpotColor(nameStr)
|
|
if ok {
|
|
f.color.draw.mode = colorModeSpot
|
|
f.color.draw.spotStr = nameStr
|
|
f.color.draw.str = sprintf("/CS%d CS %.3f SCN", clr.id, float64(byteBound(tint))/100)
|
|
if f.page > 0 {
|
|
f.out(f.color.draw.str)
|
|
}
|
|
}
|
|
}
|
|
|
|
// SetFillSpotColor sets the current fill color to the spot color associated
|
|
// with nameStr. An error occurs if the name is not associated with a color.
|
|
// The value for tint ranges from 0 (no intensity) to 100 (full intensity). It
|
|
// is quietly bounded to this range.
|
|
func (f *Fpdf) SetFillSpotColor(nameStr string, tint byte) {
|
|
var clr spotColorType
|
|
var ok bool
|
|
|
|
clr, ok = f.getSpotColor(nameStr)
|
|
if ok {
|
|
f.color.fill.mode = colorModeSpot
|
|
f.color.fill.spotStr = nameStr
|
|
f.color.fill.str = sprintf("/CS%d cs %.3f scn", clr.id, float64(byteBound(tint))/100)
|
|
f.colorFlag = f.color.fill.str != f.color.text.str
|
|
if f.page > 0 {
|
|
f.out(f.color.fill.str)
|
|
}
|
|
}
|
|
}
|
|
|
|
// SetTextSpotColor sets the current text color to the spot color associated
|
|
// with nameStr. An error occurs if the name is not associated with a color.
|
|
// The value for tint ranges from 0 (no intensity) to 100 (full intensity). It
|
|
// is quietly bounded to this range.
|
|
func (f *Fpdf) SetTextSpotColor(nameStr string, tint byte) {
|
|
var clr spotColorType
|
|
var ok bool
|
|
|
|
clr, ok = f.getSpotColor(nameStr)
|
|
if ok {
|
|
f.color.text.mode = colorModeSpot
|
|
f.color.text.spotStr = nameStr
|
|
f.color.text.str = sprintf("/CS%d cs %.3f scn", clr.id, float64(byteBound(tint))/100)
|
|
f.colorFlag = f.color.text.str != f.color.text.str
|
|
}
|
|
}
|
|
|
|
func (f *Fpdf) returnSpotColor(clr colorType) (name string, c, m, y, k byte) {
|
|
var spotClr spotColorType
|
|
var ok bool
|
|
|
|
name = clr.spotStr
|
|
if name != "" {
|
|
spotClr, ok = f.getSpotColor(name)
|
|
if ok {
|
|
c = spotClr.val.c
|
|
m = spotClr.val.m
|
|
y = spotClr.val.y
|
|
k = spotClr.val.k
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// GetDrawSpotColor returns the most recently used spot color information for
|
|
// drawing. This will not be the current drawing color if some other color type
|
|
// such as RGB is active. If no spot color has been set for drawing, zero
|
|
// values are returned.
|
|
func (f *Fpdf) GetDrawSpotColor() (name string, c, m, y, k byte) {
|
|
return f.returnSpotColor(f.color.draw)
|
|
}
|
|
|
|
// GetTextSpotColor returns the most recently used spot color information for
|
|
// text output. This will not be the current text color if some other color
|
|
// type such as RGB is active. If no spot color has been set for text, zero
|
|
// values are returned.
|
|
func (f *Fpdf) GetTextSpotColor() (name string, c, m, y, k byte) {
|
|
return f.returnSpotColor(f.color.text)
|
|
}
|
|
|
|
// GetFillSpotColor returns the most recently used spot color information for
|
|
// fill output. This will not be the current fill color if some other color
|
|
// type such as RGB is active. If no fill spot color has been set, zero values
|
|
// are returned.
|
|
func (f *Fpdf) GetFillSpotColor() (name string, c, m, y, k byte) {
|
|
return f.returnSpotColor(f.color.fill)
|
|
}
|
|
|
|
func (f *Fpdf) putSpotColors() {
|
|
for k, v := range f.spotColorMap {
|
|
f.newobj()
|
|
f.outf("[/Separation /%s", strings.Replace(k, " ", "#20", -1))
|
|
f.out("/DeviceCMYK <<")
|
|
f.out("/Range [0 1 0 1 0 1 0 1] /C0 [0 0 0 0] ")
|
|
f.outf("/C1 [%.3f %.3f %.3f %.3f] ", float64(v.val.c)/100, float64(v.val.m)/100,
|
|
float64(v.val.y)/100, float64(v.val.k)/100)
|
|
f.out("/FunctionType 2 /Domain [0 1] /N 1>>]")
|
|
f.out("endobj")
|
|
v.objID = f.n
|
|
f.spotColorMap[k] = v
|
|
}
|
|
}
|
|
|
|
func (f *Fpdf) spotColorPutResourceDict() {
|
|
f.out("/ColorSpace <<")
|
|
for _, clr := range f.spotColorMap {
|
|
f.outf("/CS%d %d 0 R", clr.id, clr.objID)
|
|
}
|
|
f.out(">>")
|
|
}
|