From 5142daa13e19b32afa064863e039da3afaf06e83 Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Wed, 27 Nov 2019 03:01:12 +0000
Subject: CTAN sync 201911270301

---
 .../latex/contrib/l3backend/l3backend-header.dtx   | 574 +++++++++++++++++++++
 1 file changed, 574 insertions(+)
 create mode 100644 macros/latex/contrib/l3backend/l3backend-header.dtx

(limited to 'macros/latex/contrib/l3backend/l3backend-header.dtx')

diff --git a/macros/latex/contrib/l3backend/l3backend-header.dtx b/macros/latex/contrib/l3backend/l3backend-header.dtx
new file mode 100644
index 0000000000..b1f2495c79
--- /dev/null
+++ b/macros/latex/contrib/l3backend/l3backend-header.dtx
@@ -0,0 +1,574 @@
+% \iffalse meta-comment
+%
+%% File: l3backend-header.dtx
+%
+% Copyright (C) 2019 The LaTeX3 Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file
+%
+%    https://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3backend bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+%    https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\documentclass[full,kernel]{l3doc}
+\begin{document}
+  \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+%   The \textsf{l3backend-header} package\\ Backend graphics support^^A
+% }
+%
+% \author{^^A
+%  The \LaTeX3 Project\thanks
+%    {^^A
+%      E-mail:
+%        \href{mailto:latex-team@latex-project.org}
+%          {latex-team@latex-project.org}^^A
+%    }^^A
+% }
+%
+% \date{Released 2019-11-25}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3backend-header} Implementation}
+%
+%    \begin{macrocode}
+%<*dvips&header>
+%    \end{macrocode}
+%
+% \begin{macro}{pdf.globaldict}
+%   A small global dictionary for backend use.
+%    \begin{macrocode}
+true setglobal
+/pdf.globaldict 4 dict def
+false setglobal
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     pdf.cvs     ,
+%     pdf.dvi.pt  ,
+%     pdf.pt.dvi  ,
+%     pdf.rect.ht
+%   }
+%   Small utilities for PostScript manipulations. Conversion to DVI dimensions
+%   is done here to allow for |Resolution|. The total height of a rectangle
+%   (an array) needs a little maths, in contrast to simply extracting a value.
+%    \begin{macrocode}
+
+/pdf.cvs { 65534 string cvs } def
+/pdf.dvi.pt { 72.27 mul Resolution div } def
+/pdf.pt.dvi { 72.27 div Resolution mul } def
+/pdf.rect.ht { dup 1 get neg exch 3 get add } def
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{pdf.linkmargin, pdf.linkdp.pad, pdf.linkht.pad}
+%   Settings which are defined up-front in |SDict|.
+%    \begin{macrocode}
+/pdf.linkmargin { 1 pdf.pt.dvi } def
+/pdf.linkdp.pad { 0 } def
+/pdf.linkht.pad { 0 } def
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     pdf.rect        ,
+%     pdf.save.ll     ,
+%     pdf.save.ur     ,
+%     pdf.save.linkll ,
+%     pdf.save.linkur ,
+%     pdf.llx         ,
+%     pdf.lly         ,
+%     pdf.urx         ,
+%     pdf.ury
+%   }
+%   Functions for marking the limits of an annotation/link, plus drawing the
+%   border. We separate links for generic annotations to support adding a
+%   margin and setting a minimal size.
+%    \begin{macrocode}
+/pdf.rect
+  { /Rect [ pdf.llx pdf.lly pdf.urx pdf.ury ] } def
+/pdf.save.ll
+  {
+    currentpoint
+    /pdf.lly exch def
+    /pdf.llx exch def
+  }
+    def
+/pdf.save.ur
+  {
+    currentpoint
+    /pdf.ury exch def
+    /pdf.urx exch def
+  }
+    def
+/pdf.save.linkll
+  {
+    currentpoint
+    pdf.linkmargin add
+    pdf.linkdp.pad add
+    /pdf.lly exch def
+    pdf.linkmargin sub
+    /pdf.llx exch def
+  }
+    def
+/pdf.save.linkur
+  {
+    currentpoint
+    pdf.linkmargin sub
+    pdf.linkht.pad sub
+    /pdf.ury exch def
+    pdf.linkmargin add
+    /pdf.urx exch def
+  }
+    def
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     pdf.dest.anchor ,
+%     pdf.dest.x      ,
+%     pdf.dest.y      ,
+%     pdf.dest.point  ,
+%     pdf.dest2device ,
+%     pdf.dev.x       ,
+%     pdf.dev.y       ,
+%     pdf.tmpa        ,
+%     pdf.tmpb        ,
+%     pdf.tmpc        ,
+%     pdf.tmpd
+%   }
+%   For finding the anchor point of a destination link. We make the use case
+%   a separate function as it comes up a lot, and as this makes it easier to
+%   adjust if we need additional effects. We also need a more complex approach
+%   to convert a co-ordinate pair correctly when defining a rectangle: this
+%   can otherwise be out when using a landscape page. (Thanks to Alexander
+%   Grahn for the approach here.)
+%    \begin{macrocode}
+/pdf.dest.anchor
+  {
+    currentpoint exch
+    pdf.dvi.pt 72 add
+    /pdf.dest.x exch def
+    pdf.dvi.pt
+    vsize 72 sub exch sub
+    /pdf.dest.y exch def
+  }
+    def
+/pdf.dest.point
+  { pdf.dest.x pdf.dest.y } def
+/pdf.dest2device
+  {
+    /pdf.dest.y exch def
+    /pdf.dest.x exch def
+    matrix currentmatrix
+    matrix defaultmatrix
+    matrix invertmatrix
+    matrix concatmatrix
+    cvx exec
+    /pdf.dev.y exch def
+    /pdf.dev.x exch def
+    /pdf.tmpd exch def
+    /pdf.tmpc exch def
+    /pdf.tmpb exch def
+    /pdf.tmpa exch def
+    pdf.dest.x pdf.tmpa mul
+      pdf.dest.y pdf.tmpc mul add
+      pdf.dev.x add
+    pdf.dest.x pdf.tmpb mul
+     pdf.dest.y pdf.tmpd mul add
+     pdf.dev.y add
+  }
+    def
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     pdf.bordertracking          ,
+%     pdf.bordertracking.begin    ,
+%     pdf.bordertracking.end      ,
+%     pdf.leftboundary            ,
+%     pdf.rightboundary           ,
+%     pdf.brokenlink.rect         ,
+%     pdf.brokenlink.skip         ,
+%     pdf.brokenlink.dict         ,
+%     pdf.bordertracking.endpage  ,
+%     pdf.bordertracking.continue ,
+%     pdf.originx                 ,
+%     pdf.originy
+%   }
+%    To know where a breakable link can go, we need to track the boundary
+%    rectangle. That can be done by hooking into |a| and |x| operations:
+%    those names have to be retained. The boundary is stored at the end of
+%    the operation. Special effort is needed at the start and end of pages
+%    (or rather galleys), such that everything works properly.
+%    \begin{macrocode}
+/pdf.bordertracking false def
+/pdf.bordertracking.begin
+  {
+    SDict /pdf.bordertracking true put
+    SDict /pdf.leftboundary undef
+    SDict /pdf.rightboundary undef
+    /a where
+      {
+        /a
+          {
+            currentpoint pop
+            SDict /pdf.rightboundary known dup
+              {
+                SDict /pdf.rightboundary get 2 index lt
+                  { not }
+                if
+              }
+            if
+              { pop }
+              { SDict exch /pdf.rightboundary exch put }
+            ifelse
+            moveto
+            currentpoint pop
+            SDict /pdf.leftboundary known dup
+              {
+                SDict /pdf.leftboundary get 2 index gt
+                  { not }
+                if
+              }
+            if
+              { pop }
+              { SDict exch /pdf.leftboundary exch put }
+            ifelse
+          }
+        put
+      }
+    if
+  }
+    def
+/pdf.bordertracking.end
+  {
+    /a where { /a { moveto } put } if
+    /x where { /x { 0 exch rmoveto } put } if
+    SDict /pdf.leftboundary known
+      { pdf.outerbox 0 pdf.leftboundary put }
+    if
+    SDict /pdf.rightboundary known
+      { pdf.outerbox 2 pdf.rightboundary put }
+    if
+    SDict /pdf.bordertracking false put
+  }
+    def
+  /pdf.bordertracking.endpage
+{
+  pdf.bordertracking
+    {
+      pdf.bordertracking.end
+      true setglobal
+      pdf.globaldict
+        /pdf.brokenlink.rect [ pdf.outerbox aload pop ] put
+      pdf.globaldict
+        /pdf.brokenlink.skip pdf.baselineskip put
+      pdf.globaldict
+        /pdf.brokenlink.dict
+          pdf.link.dict pdf.cvs put
+      false setglobal
+      mark pdf.link.dict cvx exec /Rect
+        [
+          pdf.llx
+          pdf.lly
+          pdf.outerbox 2 get pdf.linkmargin add
+          currentpoint exch pop
+          pdf.outerbox pdf.rect.ht sub pdf.linkmargin sub
+        ]
+      /ANN pdf.pdfmark
+    }
+  if
+}
+  def
+/pdf.bordertracking.continue
+  {
+    /pdf.link.dict pdf.globaldict
+      /pdf.brokenlink.dict get def
+    /pdf.outerbox pdf.globaldict
+      /pdf.brokenlink.rect get def
+    /pdf.baselineskip pdf.globaldict
+      /pdf.brokenlink.skip get def
+    pdf.globaldict dup dup
+    /pdf.brokenlink.dict undef
+    /pdf.brokenlink.skip undef
+    /pdf.brokenlink.rect undef
+    currentpoint
+    /pdf.originy exch def
+    /pdf.originx exch def
+    /a where
+      {
+        /a
+          {
+            moveto
+            SDict
+            begin
+            currentpoint pdf.originy ne exch
+              pdf.originx ne or
+              {
+                pdf.save.linkll
+                /pdf.lly
+                  pdf.lly pdf.outerbox 1 get sub def
+                pdf.bordertracking.begin
+              }
+            if
+            end
+          }
+        put
+      }
+    if
+    /x where
+      {
+        /x
+          {
+            0 exch rmoveto
+            SDict~
+            begin
+            currentpoint
+            pdf.originy ne exch pdf.originx ne or
+              {
+                pdf.save.linkll
+                /pdf.lly
+                  pdf.lly pdf.outerbox 1 get sub def
+                pdf.bordertracking.begin
+              }
+            if
+            end
+          }
+        put
+      }
+    if
+  }
+    def
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     pdf.breaklink       ,
+%     pdf.breaklink.write ,
+%     pdf.count           ,
+%     pdf.currentrect
+%   }
+%   Dealing with link breaking itself has multiple stage. The first step is to
+%   find the |Rect| entry in the dictionary, looping over key--value pairs.
+%   The first line is handled first, adjusting the rectangle to stay inside the
+%   text area. The second phase is a loop over the height of the bulk of the
+%   link area, done on the basis of a number of baselines. Finally, the end of
+%   the link area is tidied up, again from the boundary of the text area.
+%    \begin{macrocode}
+/pdf.breaklink
+  {
+    pop
+    counttomark 2 mod 0 eq
+      {
+        counttomark /pdf.count exch def
+          {
+           pdf.count 0 eq { exit } if
+           counttomark 2 roll
+           1 index /Rect eq
+             {
+               dup 4 array copy
+               dup dup
+                 1 get
+                 pdf.outerbox pdf.rect.ht
+                 pdf.linkmargin 2 mul add sub
+                 3 exch put
+               dup
+                 pdf.outerbox 2 get
+                 pdf.linkmargin add
+                 2 exch put
+               dup dup
+                 3 get
+                 pdf.outerbox pdf.rect.ht
+                 pdf.linkmargin 2 mul add add
+                 1 exch put
+               /pdf.currentrect exch  def
+               pdf.breaklink.write
+                 {
+                   pdf.currentrect
+                   dup
+                     pdf.outerbox 0 get
+                     pdf.linkmargin sub
+                     0 exch put
+                   dup
+                     pdf.outerbox 2 get
+                     pdf.linkmargin add
+                     2 exch put
+                   dup dup
+                     1 get
+                     pdf.baselineskip add
+                     1 exch put
+                   dup dup
+                     3 get
+                     pdf.baselineskip add
+                     3 exch put
+                   /pdf.currentrect exch def
+                   pdf.breaklink.write
+                  }
+                1 index 3 get
+                pdf.linkmargin 2 mul add
+                pdf.outerbox pdf.rect.ht add
+                2 index 1 get sub
+                pdf.baselineskip div round cvi 1 sub
+                exch
+              repeat
+              pdf.currentrect
+              dup
+                pdf.outerbox 0 get
+                pdf.linkmargin sub
+                0 exch put
+              dup dup
+                1 get
+                pdf.baselineskip add
+                1 exch put
+              dup dup
+                3 get
+                pdf.baselineskip add
+                3 exch put
+              dup 2 index 2 get  2 exch put
+              /pdf.currentrect exch def
+              pdf.breaklink.write
+              SDict /pdf.pdfmark.good false put
+              exit
+            }
+            { pdf.count 2 sub /pdf.count exch def }
+          ifelse
+        }
+      loop
+    }
+  if
+  /ANN
+}
+  def
+/pdf.breaklink.write
+  {
+    counttomark 1 sub
+    index /_objdef eq
+      {
+        counttomark -2 roll
+        dup wcheck
+          {
+            readonly
+            counttomark 2 roll
+          }
+          { pop pop }
+        ifelse
+      }
+    if
+    counttomark 1 add copy
+    pop pdf.currentrect
+    /ANN pdfmark
+  }
+    def
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     pdf.pdfmark      ,
+%     pdf.pdfmark.good ,
+%     pdf.outerbox     ,
+%     pdf.baselineskip ,
+%     pdf.pdfmark.dict
+%   }
+%   The business end of breaking links starts by hooking into |pdfmarks|.
+%   Unlike \pkg{hypdvips}, we avoid altering any links we have not created
+%   by using a copy of the core |pdfmarks| function. Only mark types which
+%   are known are altered. At present, this is purely |ANN| marks, which are
+%   measured relative to the size of the baseline skip. If they are
+%   more than one apparent line high, breaking is applied.
+%    \begin{macrocode}
+/pdf.pdfmark
+  {
+    SDict /pdf.pdfmark.good true put
+    dup /ANN eq
+      {
+        pdf.pdfmark.store
+        pdf.pdfmark.dict
+          begin
+            Subtype /Link eq
+            currentdict /Rect known and
+            SDict /pdf.outerbox known and
+            SDict /pdf.baselineskip known and
+              {
+                Rect 3 get
+                pdf.linkmargin 2 mul add
+                pdf.outerbox pdf.rect.ht add
+                Rect 1 get sub
+                pdf.baselineskip div round cvi 0 gt
+                  { pdf.breaklink }
+                if
+              }
+            if
+          end
+        SDict /pdf.outerbox undef
+        SDict /pdf.baselineskip undef
+        currentdict /pdf.pdfmark.dict undef
+      }
+    if
+    pdf.pdfmark.good
+      { pdfmark }
+      { cleartomark }
+    ifelse
+  }
+    def
+/pdf.pdfmark.store
+  {
+    /pdf.pdfmark.dict 65534 dict def
+    counttomark 1 add copy
+    pop
+      {
+        dup mark eq
+          {
+            pop
+            exit
+          }
+          {
+            pdf.pdfmark.dict
+            begin def end
+          }
+        ifelse
+      }
+    loop
+}
+  def
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+%</dvips&header>
+%    \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
-- 
cgit v1.2.3

