Skip to content

PDF Layer (Optional Content Groups)

Foxit PDF SDK fully supports PDF layers, also known as Optional Content Groups (OCG). This feature lets users selectively show or hide content in different layers of a multi-layer PDF document. Multi-layer technology is widely used in CAD drafting, mapping, layered artwork, multilingual document management, and other fields.

Layer Tree and Layer Nodes

In Foxit PDF SDK, PDF layers are organized and managed through layer nodes. To access layer information, developers first construct a PDF LayerTree object. Then call LayerTree.getRootNode() (Java example) to obtain the root layer node that represents the entire layer tree. From that root node, developers can traverse and enumerate all child nodes in the layer tree to access every layer in the document.

API Capabilities

Foxit PDF SDK provides rich APIs for the following PDF layer operations:

  • Get and set layer data
  • Control visibility of content in different layers (show or hide)
  • Set and modify layer names
  • Add and remove layers
  • Edit existing layer properties

Create a PDF Layer

c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/common/fs_render.h"
#include "include/pdf/fs_pdflayer.h"

using namespace foxit;
using namespace pdf;
...
// Assuming PDFDoc doc has been loaded.

LayerTree layertree(doc);
LayerNode root = layertree.GetRootNode();
if (root.IsEmpty()) {
	printf("No layer information!\r\n");
	return ;
}	
...
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_render_c.h"
#include "include/fs_pdflayer_c.h"

 ...
// Assuming FS_PDFDOC_HANDLE doc has been loaded.

FS_LAYERTREE_HANDLE layertree;
FSDK_LayerTree_Create(doc, &layertree);
FS_LAYERNODE_HANDLE root;
FSDK_LayerTree_GetRootNode(layertree, &root);
FS_BOOL return_value;
FSDK_LayerTree_IsEmpty(layertree, &return_value);
if (return_value) {
printf("No layer information!\r\n");
return ;
}	
...
java
import static com.foxit.sdk.pdf.LayerTree;
import static com.foxit.sdk.pdf.LayerNode;
...	

LayerTree layertree = new LayerTree(doc);
LayerNode root = layertree.getRootNode();
py
import sys
import site

if sys.version_info.major == 2:
    _PYTHON2_ = True
else:
    _PYTHON2_ = False

if _PYTHON2_:
    #replace with the python2 lib path
    site.addsitedir('../../../')
    from FoxitPDFSDKPython2 import *
else:
    from FoxitPDFSDKPython3 import *
...
# Assuming PDFDoc doc has been loaded.

layertree = LayerTree(doc)
root = layertree.GetRootNode()
if root.IsEmpty():
    print("No layer information!\r\n")
    return
...
objc
 #include "FSPDFObjC.h"
...

// Assuming FSPDFDoc doc has been loaded.
...

FSLayerTree* layertree = [[FSLayerTree alloc] initWithDocument:doc];
FSLayerNode* root = [layertree getRootNode];
if ([root isEmpty]) {
    return -1;
}
...
js
const FSDK = require("@fuxinsoft/foxit-pdf-sdk-node");
...
// Assuming PDFDoc doc has been loaded.

let layertree = new FSDK.LayerTree(doc);
let root = layertree.GetRootNode();
if (root.IsEmpty()) {
  console.log("No layer information!\r\n");
  return;
}
...
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
 ...
// Assuming PDFDoc doc has been loaded.

LayerTree layertree = new LayerTree(doc);
LayerNode root = layertree.GetRootNode();
...
go
import (
. “foxit.com/fsdk”
“fmt”
)
...
# Assuming PDFDoc doc has been loaded.

layertree := NewLayerTree(doc)
root := layertree.GetRootNode()
if root.IsEmpty(){
    fmt.Printf("No layer information!\r\n")
return
}
...

Set Information for All Layer Nodes

c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/common/fs_render.h"
#include "include/pdf/fs_pdflayer.h"

using namespace foxit;
using namespace foxit::common;
using foxit::common::Library;
using namespace pdf;
 ...
// Assuming PDFDoc doc has been loaded.

void SetAllLayerNodesInformation(LayerNode layer_node) {
  if (layer_node.HasLayer()) {
    layer_node.SetDefaultVisible(true);
    layer_node.SetExportUsage(LayerTree::e_StateUndefined);
    layer_node.SetViewUsage(LayerTree::e_StateOFF);
    LayerPrintData print_data("subtype_print", LayerTree::e_StateON);
    layer_node.SetPrintUsage(print_data);
    LayerZoomData zoom_data(1, 10);
    layer_node.SetZoomUsage(zoom_data);
    WString new_name = WString(L"[View_OFF_Print_ON_Export_Undefined]") + layer_node.GetName();
    layer_node.SetName(new_name);
  }
  int count = layer_node.GetChildrenCount();
  for (int i = 0; i < count; i++) {
    LayerNode child = layer_node.GetChild(i);
    SetAllLayerNodesInformation(child);
  }
}

LayerTree layertree(doc);
LayerNode root = layertree.GetRootNode();
SetAllLayerNodesInformation(root);
...
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_render_c.h"
#include "include/fs_pdflayer_c.h"
 ...

// Assuming FS_PDFDOC_HANDLE doc has been loaded.

void SetAllLayerNodesInformation(LayerNode layer_node) {
  FS_BOOL return_HasLayer;
  FSDK_LayerNode_HasLayer(layer_node, &return_HasLayer);
  if (return_HasLayer) {
    FS_BOOL return_value;
    FSDK_LayerNode_SetDefaultVisible(layer_node, true, &return_value);
    FSDK_LayerNode_SetExportUsage(layer_node, e_FSStateUndefined, &return_value);;
    FSDK_LayerNode_SetViewUsage(layer_node, e_FSStateOFF, &return_value);
    FSLayerPrintData print_data;
    print_data.print_state = e_FSStateON;
    print_data.subtype.str = "subtype_print";
    print_data.subtype.len = strlen("subtype_print");
    FSDK_LayerNode_SetPrintUsage(layer_node, print_data, &return_value);
    FSLayerZoomData zoom_data;
    zoom_data.max_factor = 10;
    zoom_data.min_factor = 1;
    FSDK_LayerNode_SetZoomUsage(layer_node, zoom_data, &return_value);
    FS_WSTR return_GetName;
    FSDK_LayerNode_GetName(layer_node, &return_GetName);
wchar_t new_name[255];
swprintf_s(new_name, 255, L” [View_OFF_Print_ON_Export_Undefined]%ls”, return_GetName.str)
    FSDK_LayerNode_SetName(layer_node, new_name, &return_value);
  }
  int count = 0;
  FSDK_LayerNode_GetChildrenCount(layer_node, &count);
  for (int i = 0; i < count; i++) {
    FS_LAYERNODE_HANDLE child;
    FSDK_LayerNode_GetChild(layer_node, i, &child);
    SetAllLayerNodesInformation(child);
  }
}

FS_LAYERTREE_HANDLE layertree;
FSDK_LayerTree_Create(doc, &layertree);
FS_LAYERNODE_HANDLE root;
FSDK_LayerTree_GetRootNode(layertree, &root);
SetAllLayerNodesInformation(root);
...
java
import com.foxit.sdk.pdf.*;
...	

static void setAllLayerNodesInformation(LayerNode layer_node) throws PDFException {
    if (layer_node.hasLayer()) {
        layer_node.setDefaultVisible(true);
        layer_node.setExportUsage(e_StateUndefined);
        layer_node.setViewUsage(e_StateOFF);
        LayerPrintData print_data = new LayerPrintData("subtype_print", e_StateON);
        layer_node.setPrintUsage(print_data);
        LayerZoomData zoom_data = new LayerZoomData(1, 10);
        layer_node.setZoomUsage(zoom_data);
        String new_name = String.format("[View_OFF_Print_ON_Export_Undefined]") +  layer_node.getName();
        layer_node.setName(new_name);
    }
    int count = layer_node.getChildrenCount();
    for (int i = 0; i < count; i++) {
        LayerNode child = layer_node.getChild(i);
        setAllLayerNodesInformation(child);
    }
}
...
py
import sys
import site

if sys.version_info.major == 2:
    _PYTHON2_ = True
else:
    _PYTHON2_ = False

if _PYTHON2_:
    #replace with the python2 lib path
    site.addsitedir('../../../')
    from FoxitPDFSDKPython2 import *
else:
from FoxitPDFSDKPython3 import *

...
# Assuming PDFDoc doc has been loaded.

def SetAllLayerNodesInformation(layer_node):
    if layer_node.HasLayer():
        layer_node.SetDefaultVisible(True)
        layer_node.SetExportUsage(LayerTree.e_StateUndefined)
        layer_node.SetViewUsage(LayerTree.e_StateOFF)
        print_data = LayerPrintData("subtype_print", LayerTree.e_StateON)
        layer_node.SetPrintUsage(print_data)
        zoom_data = LayerZoomData(1, 10)
        layer_node.SetZoomUsage(zoom_data)
        new_name = "[View_OFF_Print_ON_Export_Undefined]" + layer_node.GetName()
        layer_node.SetName(new_name)
    
    count = layer_node.GetChildrenCount()
    for i in range(0, count):
        child = layer_node.GetChild(i)
        SetAllLayerNodesInformation(child)

layertree = LayerTree(doc)
root = layertree.GetRootNode()
SetAllLayerNodesInformation(root)
...
objc
#include "FSPDFObjC.h"
...

// Assuming FSPDFDoc doc has been loaded.
...

FSLayerTree* layertree = [[FSLayerTree alloc] initWithDocument:doc];
FSLayerNode* root = [layertree getRootNode];
if ([root isEmpty]) {
    return -1;
}
setAllLayerNodesInformation(root);

void setAllLayerNodesInformation(FSLayerNode* layer_node) {
    if ([layer_node hasLayer]) {
        [layer_node setDefaultVisible:YES];
        [layer_node setExportUsage:FSLayerTreeStateUndefined];
        [layer_node setViewUsage:FSLayerTreeStateOFF];
        FSLayerPrintData* print_data = [[FSLayerPrintData alloc] initWithSubtype:@"subtype_print" print_state:FSLayerTreeStateON];
        [layer_node setPrintUsage:print_data];
        FSLayerZoomData* zoom_data = [[FSLayerZoomData alloc] initWithMin_factor:1 max_factor:10];
        [layer_node setZoomUsage:zoom_data];
        NSString* new_name = [NSString stringWithFormat:@"%@%@",@"[View_OFF_Print_ON_Export_Undefined]", [layer_node getName]];
        [layer_node setName:new_name];
    }
    int count = [layer_node getChildrenCount];
    for (int i = 0; i < count; i++) {
        FSLayerNode* child = [layer_node getChild:i];
        setAllLayerNodesInformation(child);
    }
}
...
js
const FSDK = require("@fuxinsoft/foxit-pdf-sdk-node");

...
// Assuming PDFDoc doc has been loaded.

function SetAllLayerNodesInformation(layer_node) {
  if (layer_node.HasLayer()) {
    layer_node.SetDefaultVisible(true);
    layer_node.SetExportUsage(FSDK.LayerTree.e_StateUndefined);
    layer_node.SetViewUsage(FSDK.LayerTree.e_StateOFF);
    let print_data = new FSDK.LayerPrintData("subtype_print", FSDK.LayerTree.e_StateON);
    layer_node.SetPrintUsage(print_data);
    let zoom_data = new FSDK.LayerZoomData(1, 10);
    layer_node.SetZoomUsage(zoom_data);
    let new_name = "[View_OFF_Print_ON_Export_Undefined]" + layer_node.GetName();
    layer_node.SetName(new_name);
  }
  let count = layer_node.GetChildrenCount();
  for (let i = 0; i < count; i++) {
    let child = layer_node.GetChild(i);
    SetAllLayerNodesInformation(child);
  }
}

let layertree = new FSDK.LayerTree(doc);
let root = layertree.GetRootNode();
SetAllLayerNodesInformation(root);
...
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
...
// Assuming PDFDoc doc has been loaded.

public static void SetAllLayerNodesInformation(LayerNode layer_node) 
{
     if (layer_node.HasLayer()) 
     {
        layer_node.SetDefaultVisible(true);
        layer_node.SetExportUsage(LayerTree.UsageState.e_StateUndefined);
        layer_node.SetViewUsage(LayerTree.UsageState.e_StateOFF);
        LayerPrintData print_data = new LayerPrintData("subtype_print", LayerTree.UsageState.e_StateON);
        layer_node.SetPrintUsage (print_data);
        LayerZoomData zoom_data = new LayerZoomData(1, 10);
        layer_node.SetZoomUsage(zoom_data);
        string new_name = "[View_OFF_Print_ON_Export_Undefined]" + layer_node.GetName();
        layer_node.SetName(new_name);
     }
     int count = layer_node.GetChildrenCount();
     for (int i = 0; i < count; i++) 
     {
        using (LayerNode child = layer_node.GetChild(i))
        {
              SetAllLayerNodesInformation(child);
        }
     }
}

LayerTree layertree = new LayerTree(doc);
LayerNode root = layertree.GetRootNode();
if (root.IsEmpty())
{
    return;
}
SetAllLayerNodesInformation(root);
...
go
import (
. “foxit.com/fsdk”
)

...
# Assuming PDFDoc doc has been loaded.

func SetAllLayerNodesInformation(layer_node LayerNode){
    if layer_node.HasLayer(){
        layer_node.SetDefaultVisible(true)
        layer_node.SetExportUsage(LayerTreeE_StateUndefined)
        layer_node.SetViewUsage(LayerTreeE_StateOFF)
        print_data = LayerPrintData("subtype_print", LayerTreeE_StateON)
        layer_node.SetPrintUsage(print_data)
        zoom_data := LayerZoomData(1, 10)
        layer_node.SetZoomUsage(zoom_data)
        new_name := "[View_OFF_Print_ON_Export_Undefined]" + layer_node.GetName()
        layer_node.SetName(new_name)
    }
    count := layer_node.GetChildrenCount()
    for i:=0;i< count;i++{
        child := layer_node.GetChild(i)
        SetAllLayerNodesInformation(child)
}
}
layertree := NewLayerTree(doc)
root := layertree.GetRootNode()
SetAllLayerNodesInformation(root)
...

Edit the Layer Tree

c++
#include "include/common/fs_common.h"
#include "include/pdf/fs_pdfdoc.h"
#include "include/common/fs_render.h"
#include "include/pdf/fs_pdflayer.h"

using namespace foxit;
using namespace foxit::common;
using namespace pdf;
 ...
// Assuming PDFDoc doc has been loaded.

// edit layer tree
PDFDoc doc(input_file);
error_code = doc.Load();
layertree = LayerTree(doc);
root = layertree.GetRootNode();
int children_count = root.GetChildrenCount();
root.RemoveChild(children_count -1);
LayerNode child = root.GetChild(children_count - 2);
LayerNode child0 = root.GetChild(0);
child.MoveTo(child0, 0);
child.AddChild(0, L"AddedLayerNode", true);
child.AddChild(0, L"AddedNode", false);
C
#include "include/fs_basictypes_c.h"
#include "include/fs_common_c.h"
#include "include/fs_pdfdoc_c.h"
#include "include/fs_render_c.h"
#include "include/fs_pdflayer_c.h"
 ...	

// Assuming FS_PDFDOC_HANDLE doc has been loaded.

// edit layer tree
FS_PDFDOC_HANDLE doc;
FSDK_PDFDoc_Create0(input_file, &doc);
FSErrorCode code = FSDK_PDFDoc_Load(doc, NULL);
FSDK_LayerTree_Create(doc, &layertree);
FSDK_LayerTree_GetRootNode(layertree, &root);
int children_count = 0;
FSDK_LayerNode_GetChildrenCount(root, &children_count);
FS_BOOL return_value;
FSDK_LayerNode_RemoveChild(root, children_count - 1, &return_value);
FS_LAYERNODE_HANDLE child;
FSDK_LayerNode_GetChild(root, children_count - 2, &child);
FS_LAYERNODE_HANDLE child0;
FSDK_LayerNode_GetChild(root, 0, &child0);
FSDK_LayerNode_MoveTo(child, child0, 0, &return_value);
FS_LAYERNODE_HANDLE return_AddChild;
FSDK_LayerNode_AddChild(root, 0, L"AddedLayerNode", true, &return_AddChild);
FSDK_LayerNode_AddChild(root, 0, L"AddedNode", false, &return_AddChild);
java
import com.foxit.sdk.pdf.*;
...

LayerTree layertree = new LayerTree(doc);
LayerNode root = layertree.getRootNode();
int children_count = root.getChildrenCount();
root.removeChild(children_count -1);
LayerNode child = root.getChild(children_count - 2);
LayerNode child0 = root.getChild(0);
child.moveTo(child0, 0);
child.addChild(0, "AddedLayerNode", true);
child.addChild(0, "AddedNode", false);
...
py
import sys
import site

if sys.version_info.major == 2:
    _PYTHON2_ = True
else:
    _PYTHON2_ = False

if _PYTHON2_:
    #replace with the python2 lib path
    site.addsitedir('../../../')
    from FoxitPDFSDKPython2 import *
else:
from FoxitPDFSDKPython3 import *

# Assuming PDFDoc doc has been loaded.

# edit layer tree
doc = PDFDoc(input_file)
error_code = doc.Load("")
layertree = LayerTree(doc)
root = layertree.GetRootNode()
children_count = root.GetChildrenCount()
root.RemoveChild(children_count -1)
child = root.GetChild(children_count - 2)
child0 = root.GetChild(0)
child.MoveTo(child0, 0)
child.AddChild(0, "AddedLayerNode", True)
child.AddChild(0, "AddedNode", False)
objc
#include "FSPDFObjC.h"
...

FSLayerTree* layertree = [[FSLayerTree alloc] initWithDocument:doc];
FSLayerNode* root = [layertree getRootNode];
if ([root isEmpty]) {
    return -1;
}
int children_count = [root getChildrenCount];
[root removeChild:children_count-1];
FSLayerNode* child = [root getChild:children_count-2];
FSLayerNode* child0 = [root getChild:0];
[child moveTo:child0 index:0];
[child addChild:0 name:@"AddedLayerNode" has_Layer:YES];
[child addChild:0 name:@"AddedNode" has_Layer:NO];
...
js
const FSDK = require("@fuxinsoft/foxit-pdf-sdk-node");

// Assuming PDFDoc doc has been loaded.

// edit layer tree.
let doc = new FSDK.PDFDoc(input_file);
let error_code = doc.Load("");
let layertree = new FSDK.LayerTree(doc);
let root = layertree.GetRootNode();
let children_count = root.GetChildrenCount();
root.RemoveChild(children_count - 1);
let child = root.GetChild(children_count - 2);
let child0 = root.GetChild(0);
child.MoveTo(child0, 0);
child.AddChild(0, "AddedLayerNode", true);
child.AddChild(0, "AddedNode", false);
csharp
using foxit;
using foxit.common;
using foxit.common.fxcrt;
using foxit.pdf;
 ...
// Assuming PDFDoc doc has been loaded.

LayerTree layertree = new LayerTree(doc);
LayerNode root = layertree.GetRootNode();
int children_count = root.GetChildrenCount();
root.RemoveChild(children_count - 1);
LayerNode child = root.GetChild(children_count - 2);
LayerNode child0 = root.GetChild(0);
child.MoveTo(child0, 0);
child.AddChild(0, "AddedLayerNode", true);
child.AddChild(0, "AddedNode", false);
go
import (
. “foxit.com/fsdk”
)

# Assuming PDFDoc doc has been loaded.

# edit layer tree
doc := NewPDFDoc(input_file)
error_code := doc.Load("")
layertree := NewLayerTree(doc)
root := layertree.GetRootNode()
children_count := root.GetChildrenCount()
root.RemoveChild(children_count -1)
child := root.GetChild(children_count - 2)
child0 := root.GetChild(0)
child.MoveTo(child0, 0)
child.AddChild(0, "AddedLayerNode", true)
child.AddChild(0, "AddedNode", false)