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  }