5

I want to generate a ps file with layers. Ocg.sty does not support ps, so I want to write a simple example by myself to see if its possible. I took a pdf version from here and tried to change the commands to generate a ps version (code is appended here).

Well, the ps file is generated, but it seems to be corrupt. When I use ps2pdf there are errors reported. If the part with "AddToShipoutPicture" is removed ps2pdf reports no errors, so it seems the error is there to find. But maybe more is wrong. Maybe someone can help to make a simple working solution.

\documentclass{article}
\RequirePackage{eso-pic}
\RequirePackage{ifpdf}

\newcommand{\setupOCG}{
  \special{ps: mark /_objdef {@ocg1} /type/dict /OBJ pdfmark}
  \special{ps: mark {@ocg1} <</Type/OCG /Name (My first layer)>> /PUT pdfmark}
  \special{ps: mark /_objdef {@ocg2} /type/dict /OBJ pdfmark}
  \special{ps: mark {@ocg2} <</Type/OCG /Name (My second layer)>> /PUT pdfmark}

  %register it and configure its default behaviour
  %\special{ps: mark /_objdef {{@ocg1} {@ocg2}} /type/array /OBJ pdfmark}
  \special{ps:mark {Catalog} <<
    /OCProperties <<
      /OCGs [{@ocg1} {@ocg2}]
      /D <</BaseState/ON /Order [{@ocg1} {@ocg2}]  /OFF [{@ocg1}]  >> %first layer invisible
    >>
  >> /PUT pdfmark}

  %add the OCG to the resources of the current page object
  \AddToShipoutPicture{%
    \special{ps:mark {Resources} <<
      /Properties <<
        %this maps the name to the OCG object
        /oc1 {@ocg1} /oc2 {@ocg2}
      >>
    >> /PUT pdfmark}
  }
}

\newcommand{\myocg}[2]{%    
\special{ps: mark /OC /#1 /BDC pdfmark}#2\special{ps: mark /EMC pdfmark}% ok
    %\special{ps: mark {ocgname\the\ocnum} <</OC {/@oc\the\ocnum}>> /PUT pdfmark}
}

\setupOCG

\begin{document}
  \myocg{oc1}{I am NOT visible on the first layer.}
  \myocg{oc2}{I am visible on the second layer.}
\end{document}
2
  • 1
    The /OC ... BDC-EMC bracket around page content to be made optional must be inserted directly into the page stream. Ghostscript implements only a subset of pdfmarks, /BMC and /EMC not being amongst these (according to gdevpdfm.c in the Ghostscript sources).
    – AlexG
    Nov 26, 2012 at 13:42
  • @AlexG: Please convert this comment into an answer. Feb 2, 2013 at 21:27

1 Answer 1

3

2nd Update

Package ocgx2, and Ghostscript releases >=9.15 allow for creating PDF layers (OCGs) with latex+dvips+ps2pdf.

\documentclass{article}

\usepackage{ocgx2}

\begin{document}
\switchocg{a b}{\fbox{Swap visibility}}\\[1ex]

\begin{ocg}{A}{a}{1}
  Some text, initially visible.
\end{ocg}

\begin{ocg}{B}{b}{0}
  Some text, initially \emph{in}visible.
\end{ocg}

\begin{ocg}{A}{a}{0} %initial visibility of re-opened OCG cannot be changed
  Some more text, initially visible.
\end{ocg}

\end{document}

1st Update (obsolete)

The package combination ocgx+fixocgx, together with the recent Ghostscript release 9.15 allows for creating PDF layers (OCGs) with latex+dvips+ps2pdf.

\documentclass{article}

\usepackage{ocgx}
\usepackage{fixocgx}[2015/01/26]

\begin{document}
\switchocg{a b}{\fbox{Swap visibility}}\\[1ex]

\begin{ocg}{A}{a}{1}
  Some text, initially visible.
\end{ocg}

\begin{ocg}{B}{b}{0}
  Some text, initially \emph{in}visible.
\end{ocg}

\begin{ocg}{A}{a}{0} %initial visibility of re-opened OCG cannot be changed
  Some more text, initially visible.
\end{ocg}

\end{document}

In order to create layers in PDFs using OCGs (optional content groups), the content in the page stream that is to be made optional must be enclosed in a /OC ... BDC-EMC bracket.

Unfortunately, the /BDC and /EMC pdfmarks, which serve this purpose, are not supported by Ghostscript's ps2pdf (according to gdevpdfm.c in the Ghostscript sources).

Currently, only Adobe Distiller supports them.

As of Ghostscript-9.15, /BDC and /EMC pdfmarks and thus OCGs are fully supported.

The corrected code example from the original posting using the low-level pdfmark implementation, to be run through latex->dvips-> ps2pdf or Distiller, reads:

\documentclass{article}

\newcommand{\setupOCG}{
  \special{ps: mark /_objdef {ocg1} /type/dict /OBJ pdfmark}
  \special{ps: mark {ocg1} <</Type/OCG /Name (My first layer)>> /PUT pdfmark}
  \special{ps: mark /_objdef {ocg2} /type/dict /OBJ pdfmark}
  \special{ps: mark {ocg2} <</Type/OCG /Name (My second layer)>> /PUT pdfmark}

  %register it and configure its default behaviour
  \special{ps:mark {Catalog} <<
    /OCProperties <<
      /OCGs [{ocg1} {ocg2}]
      /D <</BaseState/ON /Order [{ocg1} {ocg2}]  /OFF [{ocg1}]  >> %first layer invisible
    >>
  >> /PUT pdfmark}
}

\newcommand{\myocg}[2]{%    
  \special{ps: mark /OC {#1} /BDC pdfmark}#2\special{ps: mark /EMC pdfmark}%
}

\setupOCG

\begin{document}
  \myocg{ocg1}{I am NOT visible on the first layer.}
  \myocg{ocg2}{I am visible on the second layer.}
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .