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