.\" Define the PDFPIC macro.
.\"
.\" When used with output devices other than `pdf`, convert image to
.\" encapsulated PostScript and process it with PSPIC.
.\"
.\" Usage:
.\"
.\"   .PDFPIC [-L|-R|-C|-I <indentation>] <file> [<width> [<height>]]
.\"
.\" Requires the poppler-utils package (for pdfinfo(1) and pdftops(1)).
.\" Requires running troff(1) in unsafe mode.
.
.do if d PDFPIC .nx
.
.do nr *groff_pdfpic_tmac_C \n[.cp]
.cp 0
.
.\" Locate a directory to house temporary files.  Check each argument
.\" in turn, confirming its existence, writability, and searchability.
.\"
.\" `pdfpic*temporary-directory` contains its name if one is found, and
.\" is empty otherwise.
.de pdfpic@get-temporary-directory
.  ds pdfpic*temporary-directory \" empty
.  while !'\\$1'' \{\
.    sy test -d \\$1 && test -w \\$1 && test -x \\$1
.    if \\n[systat]=0 .ds pdfpic*temporary-directory \\$1
.    ie '\\*[pdfpic*temporary-directory]'' .shift
.    el                                    .break
.  \}
..
.
.\" A user may wish to append an 'ab' to this macro using 'am'.  That
.\" is why we don't 'return X' from here to return from two scopes.
.de pdfpic@error
.  tm pdfpic.tmac:\\n[.F]:\\n[.c]: error: \\$*
..
.
.de pdfpic@cleanup
.  rm pdfpic*pspic-args
.  rm pdfpic*file-extension
.  rm pdfpic*file-name-base
.  rm pdfpic*temporary-directory
.  rm pdfpic*temporary-file
.  rr pdfpic*do-conversion
.  rr pdfpic*offset-mode
.  rr pdfpic*indentation
.  rr pdfpic*width
.  rr pdfpic*height
.  rr pdfpic*did-pdfinfo-work
.  rr pdfpic*desired-width
.  rr pdfpic*desired-height
..
.
.de PDFPIC
.  if !\\n[.U] \{\
.    pdfpic@error use of \\$0 requires GNU troff's unsafe mode \
(-U option)
.    return
.  \}
.
.  \" Dispose of junk from any previous early return.
.  pdfpic@cleanup
.
.  nr pdfpic*do-conversion 0
.  if !'\\*[.T]'pdf' .nr pdfpic*do-conversion 1
.
.  nr pdfpic*offset-mode 0
.
.  \" Preserve the trailing space in definitions of pdfpic*pspic-args.
.
.  \" left-aligned?
.  ie '\\$1'-L' \{\
.    nr pdfpic*offset-mode 1
.    if \\n[pdfpic*do-conversion] .ds pdfpic*pspic-args \\$1 \"
.    shift
.  \}
.  el \{\
.    \" right-aligned?
.    ie '\\$1'-R' \{\
.      nr pdfpic*offset-mode 2
.      if \\n[pdfpic*do-conversion] .ds pdfpic*pspic-args \\$1 \"
.      shift
.    \}
.    el \{\
.      \" indented?
.      ie '\\$1'-I' \{\
.        nr pdfpic*offset-mode 3
.        nr pdfpic*indentation (m;\\$2)
.        if \\n[pdfpic*do-conversion] .ds pdfpic*pspic-args \\$1 \\$2 \"
.        shift 2
.      \}
.      el \{\
.        \" centered is the default
.        ie '\\$1'-C' \{\
.          if \\n[pdfpic*do-conversion] .ds pdfpic*pspic-args \\$1 \"
.          shift
.        \}
.        el .nr pdfpic*offset-mode 0
.      \}
.    \}
.  \}
.  br
.
.  ds pdfpic*file-extension \\$1\"
.  substring pdfpic*file-extension -4
.  stringdown pdfpic*file-extension
.  if !'\\*[pdfpic*file-extension]'.pdf' \{\
.    pdfpic@error '\\$1' lacks a '.pdf' extension; skipping
.    return
.  \}
.
.  \" Ensure the file exists and is readable.
.  \"
.  \" This test is subject to a time-of-check-to-time-of-use (TOCTTOU)
.  \" attack (or a simple race with a concurrent `rm` command, for
.  \" instance).
.  sy test -r \\$1
.  if \\n[systat]!=0 \{\
.    pdfpic@error '\\$1' does not exist or is not readable; skipping
.    return
.  \}
.
.  \" if driver is not gropdf, convert image to .eps
.  if \\n[pdfpic*do-conversion] \{\
.    ds pdfpic*file-name-base \\$1
.    substring pdfpic*file-name-base 0 -5
.
.    sy pdftops -eps \\$1
.    shift
.
.    as pdfpic*pspic-args \\*[pdfpic*file-name-base].eps \\$*
.
.    PSPIC \\*[pdfpic*pspic-args]
.    return
.  \}
.
.  pdfpic@get-temporary-directory \\V[GROFF_TMPDIR] \\V[TMPDIR]
.
.  if 'pdfpic*temporary-directory'' \{\
.    \" Figure out if we're on a Windows system (with a Unix shell).
.    nr pdfpic*is-on-windows 0
.
.    sy expr $(uname -s) : "CYGWIN.*" > /dev/null
.    if \\n[systat]=0 .nr pdfpic*is-on-windows 1
.    sy expr $(uname -s) : "MINGW.*" > /dev/null
.    if \\n[systat]=0 .nr pdfpic*is-on-windows 1
.
.    if \\n[pdfpic*is-on-windows] \
.      pdfpic@get-temporary-directory \\V[TEMP] \\V[TMP]
.
.    rr pdfpic*is-on-windows
.  \}
.
.  if '\\*[pdfpic*temporary-directory]'' \
.    pdfpic@get-temporary-directory /tmp
.
.  if '\\*[pdfpic*temporary-directory]'' \{\
.    pdfpic@error cannot locate a usable temporary directory; \
skipping '\\$1'
.    return
.  \}
.  ds pdfpic*temporary-file \\*[pdfpic*temporary-directory]/pdfpic\n[$$]
.
.  \" Get image dimensions.  The `tr` command to strip null bytes is
.  \" distasteful, but its necessity is imposed on us.  See
.  \" <https://gitlab.freedesktop.org/poppler/poppler/-/issues/776>.
.  ec @
.  sy pdfinfo @$1 | \
tr -d '\000' | \
grep "Page *size" | \
sed -e 's/Page *size: *\\([[:digit:].]*\\) *x *\\([[:digit:].]*\\).*$/\
.nr pdfpic*width (p;\\1)\\n\
.nr pdfpic*height  (p;\\2)/' \
> @*[pdfpic*temporary-file]
.  ec
.  if \\n[systat] \{\
.    pdfpic@error retrieval of '\\$1' image dimensions failed with \
exit status \\n[systat]; skipping
.    return
.  \}
.  so \\*[pdfpic*temporary-file]
.  sy rm \\*[pdfpic*temporary-file]
.
.  nr pdfpic*did-pdfinfo-work 1
.  if !r pdfpic*width .nr pdfpic*did-pdfinfo-work 0
.  if !r pdfpic*height .nr pdfpic*did-pdfinfo-work 0
.  if !\\n[pdfpic*did-pdfinfo-work] \{\
.    pdfpic@error retrieval of '\\$1' image dimensions failed; skipping
.    return
.  \}
.  rr pdfpic*did-pdfinfo-work
.
.  \" reject nonsense dimensions <= 0 (and avoid zero divide later)
.  if !\\n[pdfpic*width] \{\
.    pdfpic@error '\\$1' reports image width of \\n[pdfpic*width]u; \
skipping
.    return
.  \}
.  if !\\n[pdfpic*height] \{\
.    pdfpic@error '\\$1' reports image height of \\n[pdfpic*height]u; \
skipping
.    return
.  \}
.
.  \" if we have a <width> parameter, use it as the final
.  \" image width; otherwise we use the image's natural width
.  \" or the current line length, whatever is smaller
.  ie (\\n[.$] >= 2) \{\
.    nr pdfpic*desired-width (i;\\$2)
.    if !\\n[pdfpic*desired-width] \{\
.      pdfpic@error rejecting desired image width of \
\\n[pdfpic*desired-width]u; skipping '\\$1'
.      return
.    \}
.  \}
.  el \
.    nr pdfpic*desired-width ((\\n[.l] - \\n[.i]) <? \\n[pdfpic*width])
.
.  if (\\n[.$] >= 3) \{\
.    nr pdfpic*desired-height (i;\\$3)
.    if !\\n[pdfpic*desired-height] \{\
.      pdfpic@error rejecting desired image height of \
\\n[pdfpic*desired-height]u; skipping '\\$1'
.      return
.    \}
.  \}
.  \" We have no else clause; pdfpic*desired-height will get clobbered
.  \" anyway.
.
.  \" compute the final image height (with proper rounding),
.  \" based on the image's aspect ratio
.  nr pdfpic*desired-height (\\n[pdfpic*desired-width] * 1000 \
                             + (\\n[pdfpic*width] / 2) \
                             / \\n[pdfpic*width] * \\n[pdfpic*height] \
                             + 500 / 1000)
.
.  \" if we have a <height> parameter, use it as the final
.  \" image height in case it is smaller than the height
.  \" value we have just computed
.  if ((\\n[.$] >= 3) & (\\n[pdfpic*desired-height] > (i;0\\$3))) \{\
.    nr pdfpic*desired-height (i;\\$3)
.    \" recompute the final image width since we always
.    \" keep the correct image aspect
.    nr pdfpic*desired-width (\\n[pdfpic*desired-height] * 1000 \
                              + (\\n[pdfpic*height] / 2) \
                              / \\n[pdfpic*height] * \\n[pdfpic*width] \
                              + 500 / 1000)
.  \}
.
.  \" reserve vertical space for image
.  ne (\\n[pdfpic*desired-height]u + 1v)
.
.  \" compute image offset w.r.t. the current left margin
.  if (\\n[pdfpic*offset-mode] == 0) \
.    nr pdfpic*indentation \
       (\\n[.l] - \\n[.i] - \\n[pdfpic*desired-width] / 2)
.  if (\\n[pdfpic*offset-mode] == 1) \
.    nr pdfpic*indentation 0
.  if (\\n[pdfpic*offset-mode] == 2) \
.    nr pdfpic*indentation \
       (\\n[.l] - \\n[.i] - \\n[pdfpic*desired-width])
.
\h'\\n[pdfpic*indentation]u'\
\X'pdf: pdfpic \\$1 -L \\n[pdfpic*desired-width]z \
\\n[pdfpic*desired-height]z'
.  if !r PDFPIC_NOSPACE \{\
.    nr PDFPIC_NOSPACE 0
.    if \B'\\V[GROFF_PDFPIC_NOSPACE]' \
.      nr PDFPIC_NOSPACE \\V[GROFF_PDFPIC_NOSPACE]
.  \}
.  if \\n[PDFPIC_NOSPACE]=0 \{\
.    br
.    sp \\n[pdfpic*desired-height]u
.  \}
.
.  pdfpic@cleanup
..
.
.cp \n[*groff_pdfpic_tmac_C]
.do rr *groff_pdfpic_tmac_C
.
.\" Local Variables:
.\" mode: nroff
.\" fill-column: 72
.\" End:
.\" vim: set expandtab filetype=groff tabstop=2 textwidth=72:
