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(">>")
 | |
| }
 |