1/*
2 * Copyright (c) 2014 Kurt Jung (Gmail: kurt.w.jung)
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17package gofpdf
18
19// Routines in this file are translated from
20// http://www.fpdf.org/en/script/script97.php
21
22type layerType struct {
23	name    string
24	visible bool
25	objNum  int // object number
26}
27
28type layerRecType struct {
29	list          []layerType
30	currentLayer  int
31	openLayerPane bool
32}
33
34func (f *Fpdf) layerInit() {
35	f.layer.list = make([]layerType, 0)
36	f.layer.currentLayer = -1
37	f.layer.openLayerPane = false
38}
39
40// AddLayer defines a layer that can be shown or hidden when the document is
41// displayed. name specifies the layer name that the document reader will
42// display in the layer list. visible specifies whether the layer will be
43// initially visible. The return value is an integer ID that is used in a call
44// to BeginLayer().
45func (f *Fpdf) AddLayer(name string, visible bool) (layerID int) {
46	layerID = len(f.layer.list)
47	f.layer.list = append(f.layer.list, layerType{name: name, visible: visible})
48	return
49}
50
51// BeginLayer is called to begin adding content to the specified layer. All
52// content added to the page between a call to BeginLayer and a call to
53// EndLayer is added to the layer specified by id. See AddLayer for more
54// details.
55func (f *Fpdf) BeginLayer(id int) {
56	f.EndLayer()
57	if id >= 0 && id < len(f.layer.list) {
58		f.outf("/OC /OC%d BDC", id)
59		f.layer.currentLayer = id
60	}
61}
62
63// EndLayer is called to stop adding content to the currently active layer. See
64// BeginLayer for more details.
65func (f *Fpdf) EndLayer() {
66	if f.layer.currentLayer >= 0 {
67		f.out("EMC")
68		f.layer.currentLayer = -1
69	}
70}
71
72// OpenLayerPane advises the document reader to open the layer pane when the
73// document is initially displayed.
74func (f *Fpdf) OpenLayerPane() {
75	f.layer.openLayerPane = true
76}
77
78func (f *Fpdf) layerEndDoc() {
79	if len(f.layer.list) > 0 {
80		if f.pdfVersion < "1.5" {
81			f.pdfVersion = "1.5"
82		}
83	}
84}
85
86func (f *Fpdf) layerPutLayers() {
87	for j, l := range f.layer.list {
88		f.newobj()
89		f.layer.list[j].objNum = f.n
90		f.outf("<</Type /OCG /Name %s>>", f.textstring(utf8toutf16(l.name)))
91		f.out("endobj")
92	}
93}
94
95func (f *Fpdf) layerPutResourceDict() {
96	if len(f.layer.list) > 0 {
97		f.out("/Properties <<")
98		for j, layer := range f.layer.list {
99			f.outf("/OC%d %d 0 R", j, layer.objNum)
100		}
101		f.out(">>")
102	}
103
104}
105
106func (f *Fpdf) layerPutCatalog() {
107	if len(f.layer.list) > 0 {
108		onStr := ""
109		offStr := ""
110		for _, layer := range f.layer.list {
111			onStr += sprintf("%d 0 R ", layer.objNum)
112			if !layer.visible {
113				offStr += sprintf("%d 0 R ", layer.objNum)
114			}
115		}
116		f.outf("/OCProperties <</OCGs [%s] /D <</OFF [%s] /Order [%s]>>>>", onStr, offStr, onStr)
117		if f.layer.openLayerPane {
118			f.out("/PageMode /UseOC")
119		}
120	}
121}
122