From 7751c17f106d9d7d4c6c290b969ece1c8dab4371 Mon Sep 17 00:00:00 2001 From: Kurt Date: Sun, 12 Nov 2017 14:04:27 -0500 Subject: Add partial support for spot colors. This does not yet include gradients, etc --- spotcolor.go | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 spotcolor.go (limited to 'spotcolor.go') diff --git a/spotcolor.go b/spotcolor.go new file mode 100644 index 0000000..33aca82 --- /dev/null +++ b/spotcolor.go @@ -0,0 +1,184 @@ +// 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(">>") +} -- cgit v1.2.1-24-ge1ad