summaryrefslogtreecommitdiff
path: root/src/devices
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/grodvi/Makefile.sub2
-rw-r--r--src/devices/grohtml/Makefile.sub2
-rw-r--r--src/devices/grohtml/html-text.cpp9
-rw-r--r--src/devices/grohtml/post-html.cpp13
-rw-r--r--src/devices/grolbp/Makefile.sub2
-rw-r--r--src/devices/grolj4/Makefile.sub2
-rw-r--r--src/devices/gropdf/Makefile.sub54
-rw-r--r--src/devices/gropdf/TODO31
-rw-r--r--src/devices/gropdf/gropdf.man1064
-rw-r--r--src/devices/gropdf/gropdf.pl3019
-rw-r--r--src/devices/grops/Makefile.sub2
-rw-r--r--src/devices/grops/grops.man4
-rw-r--r--src/devices/grotty/tty.cpp15
13 files changed, 35 insertions, 4184 deletions
diff --git a/src/devices/grodvi/Makefile.sub b/src/devices/grodvi/Makefile.sub
index a939dbf0..16dc24ce 100644
--- a/src/devices/grodvi/Makefile.sub
+++ b/src/devices/grodvi/Makefile.sub
@@ -1,6 +1,6 @@
PROG=grodvi$(EXEEXT)
MAN1=grodvi.n
-XLIBS=$(LIBDRIVER) $(LIBGROFF) $(LIBGNU)
+XLIBS=$(LIBDRIVER) $(LIBGROFF)
MLIB=$(LIBM)
OBJS=dvi.$(OBJEXT)
CCSRCS=$(srcdir)/dvi.cpp
diff --git a/src/devices/grohtml/Makefile.sub b/src/devices/grohtml/Makefile.sub
index 48203b42..ad673cf5 100644
--- a/src/devices/grohtml/Makefile.sub
+++ b/src/devices/grohtml/Makefile.sub
@@ -1,6 +1,6 @@
PROG=post-grohtml$(EXEEXT)
MAN1=grohtml.n
-XLIBS=$(LIBDRIVER) $(LIBGROFF) $(LIBGNU)
+XLIBS=$(LIBDRIVER) $(LIBGROFF)
MLIB=$(LIBM)
OBJS=\
post-html.$(OBJEXT) \
diff --git a/src/devices/grohtml/html-text.cpp b/src/devices/grohtml/html-text.cpp
index 1b27ab3a..cae579b6 100644
--- a/src/devices/grohtml/html-text.cpp
+++ b/src/devices/grohtml/html-text.cpp
@@ -1,5 +1,5 @@
// -*- C++ -*-
-/* Copyright (C) 2000-2005, 2007, 2009, 2011
+/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009
* Free Software Foundation, Inc.
*
* Gaius Mulley (gaius@glam.ac.uk) wrote html-text.cpp
@@ -873,8 +873,9 @@ void html_text::emit_space (void)
void html_text::remove_def (tag_definition *t)
{
- tag_definition *p = stackptr;
- tag_definition *l = 0;
+ tag_definition *p = stackptr;
+ tag_definition *l = 0;
+ tag_definition *q = 0;
while ((p != 0) && (p != t)) {
l = p;
@@ -885,10 +886,12 @@ void html_text::remove_def (tag_definition *t)
stackptr = stackptr->next;
if (stackptr == NULL)
lastptr = NULL;
+ q = stackptr;
} else if (l == 0) {
error("stack list pointers are wrong");
} else {
l->next = p->next;
+ q = p->next;
if (l->next == NULL)
lastptr = l;
}
diff --git a/src/devices/grohtml/post-html.cpp b/src/devices/grohtml/post-html.cpp
index f4656a0d..a6acc691 100644
--- a/src/devices/grohtml/post-html.cpp
+++ b/src/devices/grohtml/post-html.cpp
@@ -1,5 +1,6 @@
// -*- C++ -*-
-/* Copyright (C) 2000-2007, 2009-2011
+/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009,
+ * 2010
* Free Software Foundation, Inc.
*
* Gaius Mulley (gaius@glam.ac.uk) wrote post-html.cpp
@@ -3613,7 +3614,9 @@ void html_printer::lookahead_for_tables (void)
text_glob *start_of_table = NULL;
text_glob *last = NULL;
colType type_of_col = none;
+ int left = 0;
int found_col = FALSE;
+ int seen_text = FALSE;
int ncol = 0;
int colmin = 0; // pacify compiler
int colmax = 0; // pacify compiler
@@ -3643,7 +3646,9 @@ void html_printer::lookahead_for_tables (void)
}
start_of_line = g;
+ seen_text = FALSE;
ncol = 0;
+ left = next_horiz_pos(g, nf);
if (found_col)
last = g;
found_col = FALSE;
@@ -3708,10 +3713,14 @@ void html_printer::lookahead_for_tables (void)
} else if (! g->is_a_tag())
update_min_max(type_of_col, &colmin, &colmax, g);
+ if ((! g->is_a_tag()) || g->is_tab())
+ seen_text = TRUE;
+
if ((g->is_col() || g->is_tab() || g->is_tab0())
&& (start_of_line != NULL) && (start_of_table == NULL)) {
start_of_table = insert_tab_ts(start_of_line);
start_of_line = NULL;
+ seen_text = FALSE;
} else if (g->is_ce() && (start_of_table != NULL)) {
add_table_end("*** CE ***");
start_of_table->remember_table(tbl);
@@ -3773,7 +3782,9 @@ void html_printer::lookahead_for_tables (void)
nf = calc_nf(g, nf);
} while ((g != NULL) && (g->is_br() || (nf && g->is_eol())));
start_of_line = g;
+ seen_text = FALSE;
ncol = 0;
+ left = next_horiz_pos(g, nf);
if (found_col)
last = g;
found_col = FALSE;
diff --git a/src/devices/grolbp/Makefile.sub b/src/devices/grolbp/Makefile.sub
index c9aef240..a2372933 100644
--- a/src/devices/grolbp/Makefile.sub
+++ b/src/devices/grolbp/Makefile.sub
@@ -1,6 +1,6 @@
PROG=grolbp$(EXEEXT)
MAN1=grolbp.n
-XLIBS=$(LIBDRIVER) $(LIBGROFF) $(LIBGNU)
+XLIBS=$(LIBDRIVER) $(LIBGROFF)
MLIB=$(LIBM)
OBJS=lbp.$(OBJEXT)
CCSRCS=$(srcdir)/lbp.cpp
diff --git a/src/devices/grolj4/Makefile.sub b/src/devices/grolj4/Makefile.sub
index 9d1d2bba..1216a49a 100644
--- a/src/devices/grolj4/Makefile.sub
+++ b/src/devices/grolj4/Makefile.sub
@@ -1,7 +1,7 @@
PROG=grolj4$(EXEEXT)
MAN1=grolj4.n
MAN5=lj4_font.n
-XLIBS=$(LIBDRIVER) $(LIBGROFF) $(LIBGNU)
+XLIBS=$(LIBDRIVER) $(LIBGROFF)
MLIB=$(LIBM)
OBJS=lj4.$(OBJEXT)
CCSRCS=$(srcdir)/lj4.cpp
diff --git a/src/devices/gropdf/Makefile.sub b/src/devices/gropdf/Makefile.sub
deleted file mode 100644
index c876c925..00000000
--- a/src/devices/gropdf/Makefile.sub
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (C) 2011 Free Software Foundation, Inc.
-# Written by Deri James <deri@chuzzlewit.demon.co.uk>
-#
-# This file is part of groff.
-#
-# groff is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# groff is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-MAN1=\
- gropdf.n
-
-CMDFILES=\
- gropdf
-
-MOSTLYCLEANADD=\
- gropdf \
- $(MAN1)
-
-# Some `makes' don't predefine RM...
-RM=rm -f
-
-
-all: gropdf
-
-
-gropdf: gropdf.pl $(SH_DEPS_SED_SCRIPT)
- $(RM) $@
- sed -f $(SH_DEPS_SED_SCRIPT) \
- -e "s|@VERSION@|$(version)$(revision)|" \
- -e "s|@PERLPATH@|$(PERLPATH)|" \
- -e "s|@GROFF_FONT_DIR@|$(fontdir)|" $(srcdir)/gropdf.pl >$@
- chmod +x $@
-
-install_data:
- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir)
- for f in $(CMDFILES); do \
- $(RM) $(DESTDIR)$(bindir)/$$f; \
- $(INSTALL_SCRIPT) $$f $(DESTDIR)$(bindir)/$$f; \
- done
-
-uninstall_sub:
- for f in $(CMDFILES); do \
- $(RM) $(DESTDIR)$(bindir)/$$f; \
- done
diff --git a/src/devices/gropdf/TODO b/src/devices/gropdf/TODO
deleted file mode 100644
index 4d6fca18..00000000
--- a/src/devices/gropdf/TODO
+++ /dev/null
@@ -1,31 +0,0 @@
-pspic.tmac
-----------
-
-Equiv for gropdf is pdfpic (which is dependant on a program
-pdfbb (to extract MediaBox (etc.) from the pdf) which is not written yet!
-Meanwhile you could use \X'pdf: pdfpic filename -L|R|C wid (hgt) (linelen)'
-(-R and -C require a linelen) Wid or hgt may be zero (in which case the same
-scaling as the other axis is used). The disadvantage of this call (over
-pdfpic macro) is that it is transparent to groff, after placing the image
-the current X/Y position remains what it was, so you need to do your own
-'motion control' (like a .sp) to "step over" the image you just placed.
-
-psfig.tmac
-----------
-
-No equiv for gropdf.
-
-psatk.tmac
-----------
-
-No equiv for gropdf.
-
--I : search -I directory for included files
-
--w : set line width
-
-Another \X : \X'ps: exec 0 setlinejoin'\X'ps: exec 0 setlinecap' for mom
-
-Cater for fonts with >255 glyphs (currently accessing a glyph above 255
-(i.e. \N[260]) causes a fail). This will be fixed when font subsetting is
-implemented.
diff --git a/src/devices/gropdf/gropdf.man b/src/devices/gropdf/gropdf.man
deleted file mode 100644
index a26a314b..00000000
--- a/src/devices/gropdf/gropdf.man
+++ /dev/null
@@ -1,1064 +0,0 @@
-.ig
-Copyright (C) 2011
- Free Software Foundation, Inc.
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided that the
-entire resulting derived work is distributed under the terms of a
-permission notice identical to this one.
-
-Permission is granted to copy and distribute translations of this
-manual into another language, under the above conditions for modified
-versions, except that this permission notice may be included in
-translations approved by the Free Software Foundation instead of in
-the original English.
-..
-.
-.
-.\" Like TP, but if specified indent is more than half
-.\" the current line-length - indent, use the default indent.
-.de Tp
-. ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
-. el .TP "\\$1"
-..
-.
-.de FT
-. if '\\*(.T'ps' .ft \\$1
-. if '\\*(.T'pdf' .ft \\$1
-..
-.
-.
-.TH GROPDF @MAN1EXT@ "@MDATE@" "Groff Version @VERSION@"
-.
-.
-.SH NAME
-.
-gropdf \- PDF driver for groff
-.
-.
-.SH SYNOPSIS
-.
-.SY gropdf
-.OP \-delv
-.OP \-F dir
-\#.OP \-I dir
-.OP \-p papersize
-\#.OP \-w n
-.OP \-y foundry
-.RI [ files
-.IR .\|.\|. ]
-.YS
-.
-.LP
-It is possible to have whitespace between a command line option and its
-parameter.
-.
-.
-.SH DESCRIPTION
-.
-.B gropdf
-translates the output of GNU
-.B troff
-to PDF.
-.
-Normally
-.B gropdf
-should be invoked by using the groff command
-with a
-.B \-Tpdf
-option.
-.
-If no files are given,
-.B gropdf
-reads the standard input.
-.
-A filename of
-.B \-
-also causes
-.B gropdf
-to read the standard input.
-.
-PDF output is written to the standard output.
-.
-When
-.B gropdf
-is run by
-.B groff
-options can be passed to
-.B gropdf
-using
-.BR groff 's
-.B \-P
-option.
-.
-.LP
-See section
-.B FONT INSTALLATION
-below for a guide how to install fonts for
-.BR gropdf .
-.
-.
-.SH OPTIONS
-.
-.TP
-.B \-d
-Include debug information as comments within the PDF.
-Also produces an uncompressed PDF.
-.
-.TP
-.B \-e
-Force all fonts to be embedded in the PDF.
-.
-.TP
-.BI \-F dir
-Prepend directory
-.IB dir /dev name
-to the search path for font, and device description files;
-.I name
-is the name of the device, usually
-.BR pdf .
-.
-.\" .TP
-.\" .BI \-I dir
-.\" This option may be used to add a directory to the search path for
-.\" files on the command line and files named in
-.\" .B \[rs]X'ps: import'
-.\" and
-.\" .B \[rs]X'ps: file'
-.\" escapes.
-.\" .
-.\" The search path is initialized with the current directory.
-.\" .
-.\" This option may be specified more than once; the directories are then
-.\" searched in the order specified (but before the current directory).
-.\" .
-.\" If you want to make the current directory be read before other directories,
-.\" add
-.\" .B \-I.\&
-.\" at the appropriate place.
-.\" .
-.\" .IP
-.\" No directory search is performed for files with an absolute file name.
-.\" .
-.\" .TP
-.
-.TP
-.B \-l
-Print the document in landscape format.
-.
-.TP
-.BI \-p paper-size
-Set physical dimension of output medium.
-.
-This overrides the
-.BR papersize ,
-.BR paperlength ,
-and
-.B paperwidth
-commands in the
-.B DESC
-file; it accepts the same arguments as the
-.B papersize
-command.
-.
-See
-.B groff_font (@MAN5EXT@)
-for details.
-.
-.\" .TP
-.\" .BI \-w n
-.\" Lines should be drawn using a thickness of
-.\" .IR n \~\c
-.\" thousandths of an em.
-.\" .
-.\" If this option is not given, the line thickness defaults to 0.04\~em.
-.\" .
-.
-.TP
-.B \-v
-Print the version number.
-.
-.TP
-.BI \-y foundry
-Set the foundry to use for selecting fonts of the same name.
-.
-.TP
-.B \-e
-Forces gropdf to embed ALL fonts (even the 14 base PDF fonts).
-.
-.
-.SH USAGE
-.
-The input to
-.B gropdf
-must be in the format output by
-.BR @g@troff (@MAN1EXT@).
-.
-This is described in
-.BR groff_out (@MAN5EXT@).
-.
-.LP
-In addition, the device and font description files for the device used
-must meet certain requirements:
-.
-The resolution must be an integer multiple of\~72 times the
-.BR sizescale .
-.
-The
-.B pdf
-device uses a resolution of 72000 and a sizescale of 1000.
-.
-.LP
-The device description file must contain a valid paper size; see
-.BR groff_font (@MAN5EXT@)
-for more information.
-.
-.B gropdf
-uses the same Type\~1 Adobe postscript fonts as the
-.B grops
-device driver.
-.
-Although the PDF Standard allows the use of other font types (like TrueType)
-this implementation only accepts the Type\~1 postscript font.
-.
-Fewer Type\~1 fonts are supported natively in PDF documents than
-the standard 35 fonts supported by
-.B grops
-and all postscript printers, but all the fonts are available since any
-which aren't supported natively are automatically embedded in the PDF.
-.
-.LP
-.B gropdf
-supports the concept of foundries, that is different versions of basically
-the same font.
-.
-During install a
-.B Foundry
-file controls where fonts are found and builds
-.B groff
-fonts from the files it discovers on your system.
-.
-.LP
-Each font description file must contain a command
-.
-.IP
-.BI internalname\ psname
-.
-.LP
-which says that the PostScript name of the font is
-.IR psname .
-.
-Lines starting with
-.B #
-and blank lines are ignored.
-.
-The code for each character given in the font file must correspond
-to the code in the default encoding for the font.
-.
-This code can be used with the
-.B \[rs]N
-escape sequence in
-.B troff
-to select the character,
-even if the character does not have a groff name.
-.
-Every character in the font file must exist in the PostScript font, and
-the widths given in the font file must match the widths used
-in the PostScript font.
-.
-.LP
-Note that
-.B gropdf
-is currently only able to display the first 256 glyphs in any font.
-This restriction will be lifted in a later version.
-.
-.\" .LP
-.\" Note that
-.\" .B grops
-.\" is able to display all glyphs in a PostScript font, not only 256.
-.\" .I enc_file
-.\" (or the default encoding if no encoding file specified) just defines the
-.\" order of glyphs for the first 256 characters; all other glyphs are
-.\" accessed with additional encoding vectors which
-.\" .B grops
-.\" produces on the fly.
-.
-.LP
-.B gropdf
-can automatically include the downloadable fonts necessary
-to print the document.
-.
-Fonts may be in PFA or PFB format.
-.LP
-.
-Any downloadable fonts which should, when required, be included by
-.B gropdf
-must be listed in the file
-.BR @FONTDIR@/devpdf/download ;
-this should consist of lines of the form
-.
-.IP
-.I
-foundry font filename
-.
-.LP
-where
-.I foundry
-is the foundry name or blank for the default foundry.
-.
-.I font
-is the PostScript name of the font,
-and
-.I filename
-is the name of the file containing the font;
-lines beginning with
-.B #
-and blank lines are ignored;
-fields must be separated by tabs;
-.I filename
-is searched for using the same mechanism that is used
-for groff font metric files.
-.
-The
-.B download
-file itself is also searched for using this mechanism;
-currently, only the first found file in the font path is used.
-.
-Foundry names are usually a single character (such as `U' for the URW
-Foundry) or blank for the default foundry.
-.
-This default uses the same fonts as
-.B ghostscript
-uses when it embeds fonts in a PDF file.
-.
-.LP
-In the default setup there are styles called
-.BR R ,
-.BR I ,
-.BR B ,
-and
-.B BI
-mounted at font positions 1 to\~4.
-.
-The fonts are grouped into families
-.BR A ,
-.BR BM ,
-.BR C ,
-.BR H ,
-.BR HN ,
-.BR N ,
-.BR P ,
-and\~\c
-.B T
-having members in each of these styles:
-.
-.RS
-.TP
-.B AR
-.FT AR
-AvantGarde-Book
-.FT
-.
-.TQ
-.B AI
-.FT AI
-AvantGarde-BookOblique
-.FT
-.
-.TQ
-.B AB
-.FT AB
-AvantGarde-Demi
-.FT
-.
-.TQ
-.B ABI
-.FT ABI
-AvantGarde-DemiOblique
-.FT
-.
-.TQ
-.B BMR
-.FT BMR
-Bookman-Light
-.FT
-.
-.TQ
-.B BMI
-.FT BMI
-Bookman-LightItalic
-.FT
-.
-.TQ
-.B BMB
-.FT BMB
-Bookman-Demi
-.FT
-.
-.TQ
-.B BMBI
-.FT BMBI
-Bookman-DemiItalic
-.FT
-.
-.TQ
-.B CR
-.FT CR
-Courier
-.FT
-.
-.TQ
-.B CI
-.FT CI
-Courier-Oblique
-.FT
-.
-.TQ
-.B CB
-.FT CB
-Courier-Bold
-.FT
-.
-.TQ
-.B CBI
-.FT CBI
-Courier-BoldOblique
-.FT
-.
-.TQ
-.B HR
-.FT HR
-Helvetica
-.FT
-.
-.TQ
-.B HI
-.FT HI
-Helvetica-Oblique
-.FT
-.
-.TQ
-.B HB
-.FT HB
-Helvetica-Bold
-.FT
-.
-.TQ
-.B HBI
-.FT HBI
-Helvetica-BoldOblique
-.FT
-.
-.TQ
-.B HNR
-.FT HNR
-Helvetica-Narrow
-.FT
-.
-.TQ
-.B HNI
-.FT HNI
-Helvetica-Narrow-Oblique
-.FT
-.
-.TQ
-.B HNB
-.FT HNB
-Helvetica-Narrow-Bold
-.FT
-.
-.TQ
-.B HNBI
-.FT HNBI
-Helvetica-Narrow-BoldOblique
-.FT
-.
-.TQ
-.B NR
-.FT NR
-NewCenturySchlbk-Roman
-.FT
-.
-.TQ
-.B NI
-.FT NI
-NewCenturySchlbk-Italic
-.FT
-.
-.TQ
-.B NB
-.FT NB
-NewCenturySchlbk-Bold
-.FT
-.
-.TQ
-.B NBI
-.FT NBI
-NewCenturySchlbk-BoldItalic
-.FT
-.
-.TQ
-.B PR
-.FT PR
-Palatino-Roman
-.FT
-.
-.TQ
-.B PI
-.FT PI
-Palatino-Italic
-.FT
-.
-.TQ
-.B PB
-.FT PB
-Palatino-Bold
-.FT
-.
-.TQ
-.B PBI
-.FT PBI
-Palatino-BoldItalic
-.FT
-.
-.TQ
-.B TR
-.FT TR
-Times-Roman
-.FT
-.
-.TQ
-.B TI
-.FT TI
-Times-Italic
-.FT
-.
-.TQ
-.B TB
-.FT TB
-Times-Bold
-.FT
-.
-.TQ
-.B TBI
-.FT TBI
-Times-BoldItalic
-.FT
-.RE
-.
-.LP
-There is also the following font which is not a member of a family:
-.
-.RS
-.TP
-.B ZCMI
-.FT ZCMI
-ZapfChancery-MediumItalic
-.FT
-.RE
-.
-.LP
-There are also some special fonts called
-.B S
-for the PS Symbol font. The lower case greek characters are automatically
-slanted (to match the SymbolSlanted font (SS) available to postscript).
-.
-Zapf Dingbats is available as
-.BR ZD ,
-the "hand pointing left" glyph (\[rs]lh) is available since it
-has been defined using the \[rs]X'pdf: xrev' extension which reverses the
-direction of letters within words.
-.
-.LP
-The default color for
-.B \[rs]m
-and
-.B \[rs]M
-is black; for colors defined in the `rgb' color space
-.B setrgbcolor
-is used, for `cmy' and `cmyk'
-.BR setcmykcolor ,
-and for `gray'
-.BR setgray .
-.
-Note that
-.B setcmykcolor
-is a PostScript LanguageLevel\~2 command and thus not available on some
-older printers.
-.
-.LP
-.B gropdf
-understands some of the X\~commands produced using the
-.B \[rs]X
-escape sequences supported by
-.B grops.
-Specifically it supports:-
-.
-.TP
-.B "\[rs]X'ps: invis'"
-Suppress output.
-.
-.TP
-.B "\[rs]X'ps: endinvis'"
-Stop suppressing output.
-.
-.TP
-.B "\[rs]X'ps: exec gsave currentpoint 2 copy translate \fIn\fP rotate neg exch neg exch translate'"
-where
-.I n
-is the angle of rotation.
-This is to support the
-.I align
-command in
-.BR gpic .
-.
-.TP
-.B "\[rs]X'ps: exec grestore'"
-Again used by
-.B gpic
-to restore after rotation.
-.
-.TP
-.BI "\[rs]X'ps: ... pdfmark'"
-All the
-.I pdfmark
-macros installed by using
-.I -m pdfmark
-or
-.I -m mspdf
-(see documentation in `pdfmark.pdf').
-A subset of these macros are installed automatically when you use
-.B -Tpdf
-so you should not need to use `-m pdfmark' for using most of the PDF
-functionality.
-.
-.LP
-All other
-.B ps:
-tags are silently ignored.
-.
-.LP
-One
-.B \[rs]X
-special used by the DVI driver is also recognised:
-.
-.TP
-.BI \[rs]X'papersize= paper-size '
-where the
-.I paper-size
-parameter is the same as the
-.B papersize
-command.
-.
-See
-.BR groff_font (@MAN5EXT@)
-for details.
-This means that you can alter the page size at will within the PDF file
-being created by
-.BR gropdf .
-.
-If you do want to change the paper size, it must be done before you start
-creating the page.
-.
-.LP
-In addition,
-.B gropdf
-supports its own suite of
-.B pdf:
-tags.
-.
-The following tags are supported:
-.
-.TP
-.BI "\[rs]X'pdf: pdfpic " "file alignment width height line-length" '
-Place an image of the specified
-.I width
-containing the PDF drawing from file
-.I file
-of desired
-.I width
-and
-.I height
-(if
-.I height
-is missing or zero then it is scaled proportionally).
-.
-If
-.I alignment
-is
-.B \-L
-the drawing is left aligned.
-.
-If it is
-.B \-C
-or
-.B \-R
-a
-.I linelength
-greater than the width of the drawing is required as well.
-.
-If
-.I width
-is specified as zero then the width is scaled in proportion to the height.
-.
-.\" .IP
-.\" See
-.\" .BR groff_tmac (@MAN5EXT@)
-.\" for a description of the
-.\" .B PSPIC
-.\" macro which provides a convenient high-level interface for inclusion of
-.\" PostScript graphics.
-.
-.TP
-.B \[rs]X'pdf: xrev'
-This toggles a flag which reverses the direction of printing
-.IR "letter by letter" ,
-i.e., each separate letter is reversed, not the entire word.
-.
-This is useful for reversing the direction of glyphs in the Dingbats font.
-.
-To return to normal printing repeat the command again.
-.
-.TP
-.BI "\[rs]X'pdf: markstart " "/ANN definition" '
-The macros which support PDF Bookmarks use this call internally to start the
-definition of bookmark hotspot (user will have called
-`.pdfhref\~L' with the text which will become the `hot spot' region).
-.
-Normally this is never used except from within the pdfmark macros.
-.
-.TP
-.B \[rs]X'pdf: markend'
-The macros which support PDF Bookmarks use this call internally to stop the
-definition of bookmark hotspot (user will have called
-`.pdfhref\~L' with the text which will become the `hot spot' region).
-.
-Normally this is never used except from within the pdfmark macros.
-.
-.TP
-.B \[rs]X'pdf: marksuspend'
-.TQ
-.B \[rs]X'pdf: markrestart'
-If you are using page traps to produce headings, footings, etc., you need to
-use these in case a `hot spot' crosses a page boundary, otherwise any text
-output by the heading or footing macro will be marked as part of the `hot
-spot'.
-.
-To stop this happening just place
-`.pdfmarksuspend' and `.pdfmarkrestart' at the start and end of the page trap macro,
-respectively.
-.
-(These are just convenience macros which emit the \[rs]X code.
-.
-These macros must only be used within page traps.)
-.
-.SS Importing graphics
-.
-.B gropdf
-only supports importing other PDF files as graphics.
-.
-But that PDF file may contain any of the graphic formats supported by the PDF
-standard (such as JPEG, PNG, GIF, etc.).
-.
-So any application which outputs PDF can be used as an embedded file in
-.BR gropdf .
-.
-The PDF file you wish to insert must be a single page and the drawing must
-just fit inside the media size of the PDF file.
-.
-So, in
-.BR inkscape (1)
-or
-.BR gimp (1)
-(for example) make sure the canvas size just fits the image.
-.
-.LP
-The PDF parser used in
-.B gropdf
-has not been rigorously tested with all possible applications which produce
-PDFs.
-.
-If you find a single page PDF which fails to import properly, it is worth
-running it through the
-.
-.BR pdftk (1)
-program by issuing the command:
-.
-.RS
-.LP
-.B pdftk
-.I oldfile.pdf
-.B output
-.I newfile.pdf
-.RE
-.
-.LP
-You may find that
-.I newfile.pdf
-will now load successfully.
-.
-.SS TrueType and other font formats
-.
-.B gropdf
-does not support TrueType fonts natively within the PDF files it generates
-(but does support any fonts if they are in an imported PDF).
-.
-However, TrueType fonts can be used with
-.B gropdf
-if converted first to
-.B Type\~42
-format, a special PostScript wrapper equivalent to the PFA format mentioned
-in
-.BR \%pfbtops (@MAN1EXT@).
-.
-There are several different methods to generate a Type\~42
-wrapper and most of them involve the use of a PostScript
-interpreter such as Ghostscript \[en] see
-.BR gs (1).
-.
-.LP
-Yet, the easiest method involves the use of the application
-.BR ttftot42 (1).
-.
-This program uses
-.BR freetype (3)
-(version 1.3.1) to generate Type\~42
-font wrappers and well-formed AFM files that can be fed to the
-.BR \%afmtodit (@MAN1EXT@)
-script to create appropriate metric files.
-.
-The resulting font wrappers should be added to groff's
-.B download
-file.
-.
-.B ttftot42
-source code can be downloaded from
-.UR ftp://\:www.giga.or.at/\:pub/\:nih/\:ttftot42/
-ftp://\:www.giga.or.at/\:pub/\:nih/\:ttftot42/
-.UE .
-.
-.LP
-Another solution for creating Type\~42 wrappers is to use FontForge,
-available from
-.UR http://\:fontforge.sf.net
-http://\:fontforge.sf.net
-.UE .
-.
-This font editor can convert most outline font formats.
-.
-.
-.SH FONT INSTALLATION
-.
-This section gives a summary of the above explanations; it can serve
-as a step-by-step font installation guide for
-.BR gropdf .
-.
-.ds BU \[bu]\ \ \"
-.de LI
-.IP "" 4
-\h'-\w'\*[BU]'u'\*[BU]\c
-..
-.LI
-Convert your font to something groff understands.
-.
-This is either a PostScript Type\~1 font in either PFA or PFB format or a
-PostScript Type\~42 font, together with an AFM file.
-.
-.IP
-The very first line in a PFA/PFB file contains this:
-.
-.RS
-.IP
-.B %!PS-AdobeFont-1.0:
-.RE
-.
-.IP
-A PFB file has this also in the first line, but the string is
-preceded with some binary bytes.
-.
-.IP
-The very first characters in a Type\~42 font file look like this:
-.
-.RS
-.IP
-.B %!PS-TrueTypeFont
-.RE
-.
-.IP
-This is a wrapper format for TrueType fonts.
-.
-Old PS printers might not support it (this is, they don't have a
-built-in TrueType font interpreter).
-.
-.IP
-For TrueType fonts, try
-.B ttftot42
-or
-.BR fontforge .
-For all other font formats use
-.B fontforge
-which can convert most outline font formats.
-.
-.LI
-Convert the AFM file to a groff font description file with the
-.BR \%afmtodit (@MAN1EXT@)
-program.
-.
-An example call is
-.
-.RS
-.IP
-afmtodit Foo-Bar-Bold.afm map/textmap FBB
-.RE
-.
-.IP
-which converts the metric file `Foo-Bar-Bold.afm' to the groff
-font `FBB'.
-.
-If you have a font family which comes with normal, bold, italic,
-and bold italic faces, it is recommended to use the letters
-.BR R ,
-.BR B ,
-.BR I ,
-and
-.BR BI ,
-respectively, as postfixes in the groff font names to make groff's
-`.fam' request work.
-.
-An example is groff's built-in Times-Roman font: The font family name
-is
-.BR T ,
-and the groff font names are
-.BR TR ,
-.BR TB ,
-.BR TI ,
-and
-.BR TBI .
-.
-.LI
-Install both the groff font description files and the fonts in a
-`devpdf' subdirectory of the font path which groff finds.
-.
-See the
-.B ENVIRONMENT
-section in the
-.BR troff (@MAN1EXT@)
-man page which lists the actual value of the font path.
-.
-Note that groff doesn't use the AFM files (but it is a good idea to
-store them anyway).
-.
-.LI
-Register all fonts which must be downloaded to the printer in the
-`devpdf/download' file.
-.
-Only the first occurrence of this file in the font path is read.
-.
-This means that you should copy the default `download' file to the
-first directory in your font path and add your fonts there.
-.
-To continue the above example we assume that the PS font name for
-Foo-Bar-Bold.pfa is `XY-Foo-Bar-Bold' (the PS font name is stored in the
-.B internalname
-field in the `FBB' file) and belongs to foundry `F', thus the following
-line should be added to `download':
-.
-.RS
-.IP
-.B F XY-Foo-Bar-Bold Foo-Bar-Bold.pfa
-.
-.LP
-Use a tab character to separate the fields, and the
-`foundry' field should be null for the default foundry.
-.RE
-.
-.
-.SH ENVIRONMENT
-.
-.TP
-.SM
-.B GROFF_FONT_PATH
-A list of directories in which to search for the
-.BI dev name
-directory in addition to the default ones.
-.
-If, in the `download' file, the
-font file has been specified with a full path, no directories are searched.
-.
-See
-.BR @g@troff (@MAN1EXT@)
-and
-.BR \%groff_font (@MAN5EXT@)
-for more details.
-.
-.
-.SH FILES
-.
-.Tp \w'\fB@FONTDIR@/devpdf/download'u+2n
-.B @FONTDIR@/devpdf/DESC
-Device description file.
-.
-.TP
-.BI @FONTDIR@/devpdf/ F
-Font description file for font\~\c
-.IR F .
-.
-.TP
-.BI @FONTDIR@/devpdf/ U-F
-Font description file for font\~\c
-.I F
-(using foundry\~\c
-.I U
-rather than the default foundry).
-.
-.TP
-.B @FONTDIR@/devpdf/download
-List of downloadable fonts.
-.
-.TP
-.B @FONTDIR@/devpdf/Foundry
-A Perl script used during install to locate suitable fonts.
-.
-.TP
-.B @FONTDIR@/devpdf/enc/text.enc
-Encoding used for text fonts.
-.
-.TP
-.B @MACRODIR@/pdf.tmac
-Macros for use with
-.BR gropdf ;
-automatically loaded by
-.BR troffrc .
-.
-.\" .TP
-.\" .B @MACRODIR@/pspic.tmac
-.\" Definition of
-.\" .B PSPIC
-.\" macro,
-.\" automatically loaded by
-.\" .BR ps.tmac .
-.\" .
-.
-.
-.SH "SEE ALSO"
-.
-.BR \%afmtodit (@MAN1EXT@),
-.BR groff (@MAN1EXT@),
-.BR grops (@MAN1EXT@),
-.BR @g@troff (@MAN1EXT@),
-.BR grops (@MAN1EXT@),
-.BR \%pfbtops (@MAN1EXT@),
-.BR \%groff_out (@MAN5EXT@),
-.BR \%groff_font (@MAN5EXT@),
-.BR \%groff_char (@MAN7EXT@),
-.BR \%groff_tmac (@MAN5EXT@)
-.
-.
-.
-.\" Local Variables:
-.\" mode: nroff
-.\" End:
diff --git a/src/devices/gropdf/gropdf.pl b/src/devices/gropdf/gropdf.pl
deleted file mode 100644
index 31b92d0f..00000000
--- a/src/devices/gropdf/gropdf.pl
+++ /dev/null
@@ -1,3019 +0,0 @@
-#!@PERLPATH@ -w
-#
-# gropdf : PDF post processor for groff
-# Deri James : 4th May 2009
-#
-
-# Copyright (C) 2011 Free Software Foundation, Inc.
-# Written by Deri James <deri@chuzzlewit.demon.co.uk>
-#
-# This file is part of groff.
-#
-# groff is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# groff is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-use strict;
-use Getopt::Long;
-use Compress::Zlib;
-
-my %cfg;
-
-$cfg{GROFF_VERSION}='@VERSION@';
-$cfg{GROFF_FONT_PATH}='@GROFF_FONT_DIR@';
-binmode(STDOUT);
-
-my @obj; # Array of PDF objects
-my $objct=0; # Count of Objects
-my $fct=0; # Output count
-my %fnt; # Used fonts
-my $lct=0; # Input Line Count
-my $src_name='';
-my %env; # Current environment
-my %fontlst; # Fonts Loaded
-my $rot=0; # Portrait
-my %desc; # Contents of DESC
-my %download; # Contents of downlopad file
-my $pages; # Pointer to /Pages object
-my $devnm='devpdf';
-my $cpage; # Pointer to current pages
-my $cpageno=0; # Object no of current page
-my $cat; # Pointer to catalogue
-my $dests; # Pointer to Dests
-my @mediabox=(0,0,595,842);
-my @defaultmb=(0,0,595,842);
-my $stream=''; # Current Text/Graphics stream
-my $cftsz=10; # Current font sz
-my $cft; # Current Font
-my $lwidth=1; # current linewidth
-my $textcol=''; # Current groff text
-my $fillcol=''; # Current groff fill
-my $curfill=''; # Current PDF fill
-my $strkcol='';
-my $curstrk='';
-my @lin=(); # Array holding current line of text
-my @ahead=(); # Buffer used to hol the next line
-my $mode='g'; # Graphic (g) or Text (t) mode;
-my $xpos=0; # Current X position
-my $ypos=0; # Current Y position
-my $tmxpos=0;
-my $widtbl; # Pointer to width table for current font size
-my $origwidtbl; # Pointer to width table
-my $krntbl; # Pointer to kern table
-my $matrix="1 0 0 1";
-my $whtsz; # Current width of a space
-my $poschg=0; # V/H pending
-my $fontchg=0; # font change pending
-my $tnum=2; # flatness of B-Spline curve
-my $tden=3; # flatness of B-Spline curve
-my $linewidth=40;
-my $w_flg=0;
-my $nomove=0;
-my $pendmv=0;
-my $gotT=0;
-my $suppress=0; # Suppress processing?
-my %incfil; # Included Files
-my @outlev=([0,undef,0,0]); # Structure pdfmark /OUT entries
-my $curoutlev=\@outlev;
-my $Foundry='';
-my $xrev=0; # Reverse x direction of font
-my $matrixchg=0;
-my $wt=-1;
-my $thislev=1;
-my $mark=undef;
-my $suspendmark=undef;
-my $n_flg=1;
-my $pginsert=-1; # Growth point for kids array
-my %pgnames; # 'names' of pages for switchtopage
-
-my %ppsz=( 'ledger'=>[1224,792],
- 'legal'=>[612,1008],
- 'letter'=>[612,792],
- 'a0'=>[2384,3370],
- 'a1'=>[1684,2384],
- 'a2'=>[1191,1684],
- 'a3'=>[842,1191],
- 'a4'=>[595,842],
- 'a5'=>[420,595],
- 'a6'=>[297,420],
- 'a7'=>[210,297],
- 'a8'=>[148,210],
- 'a9'=>[105,148],
- 'a10'=>[73,105],
- 'isob0'=>[2835,4008],
- 'isob1'=>[2004,2835],
- 'isob2'=>[1417,2004],
- 'isob3'=>[1001,1417],
- 'isob4'=>[709,1001],
- 'isob5'=>[499,709],
- 'isob6'=>[354,499],
- 'c0'=>[2599,3677],
- 'c1'=>[1837,2599],
- 'c2'=>[1298,1837],
- 'c3'=>[918,1298],
- 'c4'=>[649,918],
- 'c5'=>[459,649],
- 'c6'=>[323,459] );
-
-
-my $fd;
-my $frot;
-my $fpsz;
-my $embedall=0;
-my $debug=0;
-my $version=0;
-
-#Load_Config();
-
-GetOptions("F=s" => \$fd, 'l' => \$frot, 'p=s' => \$fpsz, 'd!' => \$debug, 'v' => \$version, 'e' => \$embedall, 'y=s' => \$Foundry);
-
-if ($version)
-{
- print "GNU gropdf (groff) version $cfg{GROFF_VERSION}\n";
- exit;
-}
-
-# Search for 'font directory': paths in -f opt, shell var GROFF_FONT_PATH, default paths
-
-my $fontdir=$cfg{GROFF_FONT_PATH};
-$fontdir=$ENV{GROFF_FONT_PATH}.':'.$fontdir if exists($ENV{GROFF_FONT_PATH});
-$fontdir=$fd.':'.$fontdir if defined($fd);
-
-$rot=90 if $frot;
-$matrix="0 1 -1 0" if $frot;
-
-LoadDownload();
-LoadDesc();
-
-my $unitwidth=$desc{unitwidth};
-my $papersz=$desc{papersize};
-$papersz=$fpsz if $fpsz;
-
-$env{FontHT}=0;
-$env{FontSlant}=0;
-MakeMatrix();
-
-if (substr($papersz,0,1) eq '/' and -r $papersz)
-{
- if (open(P,"<$papersz"))
- {
- while (<P>)
- {
- chomp;
- s/# .*//;
- next if $_ eq '';
- $papersz=$_;
- last
- }
-
- close(P);
- }
-}
-
-if ($papersz=~m/([\d.]+)([cipP]),([\d.]+)([cipP])/)
-{
- @defaultmb=@mediabox=(0,0,ToPoints($1,$2),ToPoints($3,$4));
-}
-elsif (exists($ppsz{$papersz}))
-{
- @defaultmb=@mediabox=(0,0,$ppsz{$papersz}->[0],$ppsz{$papersz}->[1]);
-}
-
-my (@dt)=localtime(time);
-my $dt=PDFDate(\@dt);
-
-my %info=('Creator' => "(groff version $cfg{GROFF_VERSION})",
- 'Producer' => "(gropdf version $cfg{GROFF_VERSION})",
- 'ModDate' => "($dt)",
- 'CreationDate' => "($dt)");
-while (<>)
-{
- chomp;
- s/\r$//;
- $lct++;
-
- do # The ahead buffer behaves like 'ungetc'
- {{
- if (scalar(@ahead))
- {
- $_=shift(@ahead);
- }
-
-
- my $cmd=substr($_,0,1);
- next if $cmd eq '#'; # just a comment
- my $lin=substr($_,1);
-
- while ($cmd eq 'w')
- {
- $cmd=substr($lin,0,1);
- $lin=substr($lin,1);
- $w_flg=1 if $gotT;
- }
-
- $lin=~s/^\s+//;
-# $lin=~s/\s#.*?$//; # remove comment
- $stream.="\% $_\n" if $debug;
-
- do_x($lin),next if ($cmd eq 'x');
- next if $suppress;
- do_p($lin),next if ($cmd eq 'p');
- do_f($lin),next if ($cmd eq 'f');
- do_s($lin),next if ($cmd eq 's');
- do_m($lin),next if ($cmd eq 'm');
- do_D($lin),next if ($cmd eq 'D');
- do_V($lin),next if ($cmd eq 'V');
- do_v($lin),next if ($cmd eq 'v');
- do_t($lin),next if ($cmd eq 't');
- do_C($lin),next if ($cmd eq 'C');
- do_c($lin),next if ($cmd eq 'c');
- do_N($lin),next if ($cmd eq 'N');
- do_h($lin),next if ($cmd eq 'h');
- do_H($lin),next if ($cmd eq 'H');
- do_n($lin),next if ($cmd eq 'n');
-
- my $tmp=scalar(@ahead);
- }} until scalar(@ahead) == 0;
-
-}
-
-
-if ($cpageno > 0)
-{
- PutObj($cpageno);
- OutStream($cpageno+1);
-}
-
-
-PutOutlines(\@outlev);
-
-PutObj(1);
-
-my $info=BuildObj(++$objct,\%info);
-
-PutObj($objct);
-
-foreach my $o (3..$objct)
-{
- PutObj($o) if (!exists($obj[$o]->{XREF}));
-}
-
-#my $encrypt=BuildObj(++$objct,{'Filter' => '/Standard', 'V' => 1, 'R' => 2, 'P' => 252});
-#PutObj($objct);
-PutObj(2);
-
-my $xrefct=$fct;
-
-$objct+=1;
-print "xref\n0 $objct\n0000000000 65535 f \n";
-
-foreach my $xr (@obj)
-{
- next if !defined($xr);
- printf("%010d 00000 n \n",$xr->{XREF});
-}
-
-print "trailer\n<<\n/Info $info\n/Root 1 0 R\n/Size $objct\n>>\nstartxref\n$fct\n\%\%EOF\n\% Pages=$pages->{Count}\n";
-
-
-sub MakeMatrix
-{
- my $fontxrev=shift||0;
- my @mat=($frot)?(0,1,-1,0):(1,0,0,1);
-
- if (!$frot)
- {
- if ($env{FontHT} != 0)
- {
- $mat[3]=sprintf('%.3f',$env{FontHT}/$cftsz);
- }
-
- if ($env{FontSlant} != 0)
- {
- my $slant=$env{FontSlant};
- $slant*=$env{FontHT}/$cftsz if $env{FontHT} != 0;
- my $ang=rad($slant);
-
- $mat[2]=sprintf('%.3f',sin($ang)/cos($ang));
- }
-
- if ($fontxrev)
- {
- $mat[0]=-$mat[0];
- }
- }
-
- $matrix=join(' ',@mat);
- $matrixchg=1;
-}
-
-sub PutOutlines
-{
- my $o=shift;
- my $outlines;
-
- if ($#{$o} > 0)
- {
- # We've got Outlines to deal with
- my $openct=$curoutlev->[0]->[2];
-
- while ($thislev-- > 1)
- {
- my $nxtoutlev=$curoutlev->[0]->[1];
- $nxtoutlev->[0]->[2]+=$openct if $curoutlev->[0]->[3]==1;
- $openct=0 if $nxtoutlev->[0]->[3]==-1;
- $curoutlev=$nxtoutlev;
- }
-
- $cat->{Outlines}=BuildObj(++$objct,{'Count' => abs($o->[0]->[0])+$o->[0]->[2]});
- $outlines=$obj[$objct]->{DATA};
- }
- else
- {
- return;
- }
-
- SetOutObj($o);
-
- $outlines->{First}=$o->[1]->[2];
- $outlines->{Last}=$o->[$#{$o}]->[2];
-
- LinkOutObj($o,$cat->{Outlines});
-}
-
-sub SetOutObj
-{
- my $o=shift;
-
- for my $j (1..$#{$o})
- {
- my $ono=BuildObj(++$objct,$o->[$j]->[0]);
- $o->[$j]->[2]=$ono;
-
- SetOutObj($o->[$j]->[1]) if $#{$o->[$j]->[1]} > -1;
- }
-}
-
-sub LinkOutObj
-{
- my $o=shift;
- my $parent=shift;
-
- for my $j (1..$#{$o})
- {
- my $op=GetObj($o->[$j]->[2]);
-
- $op->{Next}=$o->[$j+1]->[2] if ($j < $#{$o});
- $op->{Prev}=$o->[$j-1]->[2] if ($j > 1);
- $op->{Parent}=$parent;
-
- if ($#{$o->[$j]->[1]} > -1)
- {
- $op->{Count}=$o->[$j]->[1]->[0]->[2]*$o->[$j]->[1]->[0]->[3];# if exists($op->{Count}) and $op->{Count} > 0;
- $op->{First}=$o->[$j]->[1]->[1]->[2];
- $op->{Last}=$o->[$j]->[1]->[$#{$o->[$j]->[1]}]->[2];
- LinkOutObj($o->[$j]->[1],$o->[$j]->[2]);
- }
- }
-}
-
-sub GetObj
-{
- my $ono=shift;
- ($ono)=split(' ',$ono);
- return($obj[$ono]->{DATA});
-}
-
-
-
-sub PDFDate
-{
- my $dt=shift;
- return(sprintf("D:%04d%02d%02d%02d%02d%02d% +02d'00'",$dt->[5]+1900,$dt->[4]+1,$dt->[3],$dt->[2],$dt->[1],$dt->[0],( localtime time() + 3600*( 12 - (gmtime)[2] ) )[2] - 12));
-}
-
-sub ToPoints
-{
- my $num=shift;
- my $unit=shift;
-
- if ($unit eq 'i')
- {
- return($num*72);
- }
- elsif ($unit eq 'c')
- {
- return int($num*72/2.54);
- }
- elsif ($unit eq 'm') # millimetres
- {
- return int($num*72/25.4);
- }
- elsif ($unit eq 'p')
- {
- return($num);
- }
- elsif ($unit eq 'P')
- {
- return($num*6);
- }
- else
- {
- Msg(1,"Unknown scaling factor '$unit'");
- }
-}
-
-sub Load_Config
-{
- open(CFG,"<gropdf_config") or die "Can't open config file: $!";
-
- while (<CFG>)
- {
- chomp;
- my ($key,$val)=split(/ ?= ?/);
-
- $cfg{$key}=$val;
- }
-
- close(CFG);
-}
-
-sub LoadDownload
-{
- my $f;
-
- OpenFile(\$f,$fontdir,"download");
- Msg(1,"Failed to open 'download'") if !defined($f);
-
- while (<$f>)
- {
- chomp;
- s/#.*$//;
- next if $_ eq '';
- my ($foundry,$name,$file)=split(/\t+/);
- if (substr($file,0,1) eq '*')
- {
- next if !$embedall;
- $file=substr($file,1);
- }
-
- $download{"$foundry $name"}=$file;
- }
-
- close($f);
-}
-
-sub OpenFile
-{
- my $f=shift;
- my $dirs=shift;
- my $fnm=shift;
-
- if (substr($fnm,0,1) eq '/' or substr($fnm,1,1) eq ':') # dos
- {
- return if -r "$fnm" and open($$f,"<$fnm");
- }
-
- my (@dirs)=split(':',$dirs);
-
- foreach my $dir (@dirs)
- {
- last if -r "$dir/$devnm/$fnm" and open($$f,"<$dir/$devnm/$fnm");
- }
-}
-
-sub LoadDesc
-{
- my $f;
-
- OpenFile(\$f,$fontdir,"DESC");
- Msg(1,"Failed to open 'DESC'") if !defined($f);
-
- while (<$f>)
- {
- chomp;
- s/#.*$//;
- next if $_ eq '';
- my ($name,$prms)=split(' ',$_,2);
- $desc{lc($name)}=$prms;
- }
-
- close($f);
-}
-
-sub rad { $_[0]*3.14159/180 }
-
-my $InPicRotate=0;
-
-sub do_x
-{
- my $l=shift;
- my ($xcmd,@xprm)=split(' ',$l);
- $xcmd=substr($xcmd,0,1);
-
- if ($xcmd eq 'T')
- {
- Msg(0,"Expecting a pdf pipe (got $xprm[0])") if $xprm[0] ne substr($devnm,3);
- }
- elsif ($xcmd eq 'f') # Register Font
- {
- $xprm[1]="${Foundry}-$xprm[1]" if $Foundry ne '';
- LoadFont($xprm[0],$xprm[1]);
- }
- elsif ($xcmd eq 'F') # Source File (for errors)
- {
- $env{SourceFile}=$xprm[0];
- }
- elsif ($xcmd eq 'H') # FontHT
- {
- $xprm[0]/=$unitwidth;
- $xprm[0]=0 if $xprm[0] == $cftsz;
- $env{FontHT}=$xprm[0];
- MakeMatrix();
- }
- elsif ($xcmd eq 'S') # FontSlant
- {
- $env{FontSlant}=$xprm[0];
- MakeMatrix();
- }
- elsif ($xcmd eq 'i') # Initialise
- {
- $objct++;
- @defaultmb=@mediabox;
- BuildObj($objct,{'Pages' => BuildObj($objct+1,
- {'Kids' => [],
- 'Count' => 0,
- 'Type' => '/Pages',
- 'Rotate' => $rot,
- 'MediaBox' => \@defaultmb,
- 'Resources' =>
- {'Font' => {},
- 'ProcSet' => ['/PDF', '/Text', '/ImageB', '/ImageC', '/ImageI']}
- }
- ),
- 'Type' => '/Catalog'});
-
- $cat=$obj[$objct]->{DATA};
- $objct++;
- $pages=$obj[2]->{DATA};
- Put("%PDF-1.4\n\x25\xe2\xe3\xcf\xd3\n");
- }
- elsif ($xcmd eq 'X')
- {
- # There could be extended args
- do
- {{
- LoadAhead(1);
- if (substr($ahead[0],0,1) eq '+')
- {
- $l.="\n".substr($ahead[0],1);
- shift(@ahead);
- }
- }} until $#ahead==0;
-
- ($xcmd,@xprm)=split(' ',$l);
- $xcmd=substr($xcmd,0,1);
-
- if ($xprm[0]=~m/^(.+:)(.+)/)
- {
- splice(@xprm,1,0,$2);
- $xprm[0]=$1;
- }
-
- my $par=join(' ',@xprm[1..$#xprm]);
-
- if ($xprm[0] eq 'ps:')
- {
- if ($xprm[1] eq 'invis')
- {
- $suppress=1;
- }
- elsif ($xprm[1] eq 'endinvis')
- {
- $suppress=0;
- }
- elsif ($par=~m/exec gsave currentpoint 2 copy translate (.+) rotate neg exch neg exch translate/)
- {
- # This is added by gpic to rotate a single object
-
- my $theta=-rad($1);
-
- IsGraphic();
- my ($curangle,$hyp)=RtoP($xpos,GraphY($ypos));
- my ($x,$y)=PtoR($theta+$curangle,$hyp);
- $stream.="q\n".sprintf("%.3f %.3f %.3f %.3f %.3f %.3f cm",cos($theta),sin($theta),-sin($theta),cos($theta),$xpos-$x,GraphY($ypos)-$y)."\n";
- $InPicRotate=1;
- }
- elsif ($par=~m/exec grestore/ and $InPicRotate)
- {
- IsGraphic();
- $stream.="Q\n";
- $InPicRotate=0;
- }
- elsif ($par=~m/\[(.+) pdfmark/)
- {
- my $pdfmark=$1;
- $pdfmark=~s((\d{4,6}) u)(sprintf("%.1f",$1/$desc{sizescale}))eg;
-
- if ($pdfmark=~m/(.+) \/DOCINFO/)
- {
- my @xwds=split(' ',"<< $1 >>");
- my $docinfo=ParsePDFValue(\@xwds);
-
- foreach my $k (keys %{$docinfo})
- {
- $info{$k}=$docinfo->{$k} if $k ne 'Producer';
- }
- }
- elsif ($pdfmark=~m/(.+) \/DOCVIEW/)
- {
- my @xwds=split(' ',"<< $1 >>");
- my $docview=ParsePDFValue(\@xwds);
-
- foreach my $k (keys %{$docview})
- {
- $cat->{$k}=$docview->{$k} if !exists($cat->{$k});
- }
- }
- elsif ($pdfmark=~m/(.+) \/DEST/)
- {
- my @xwds=split(' ',"<< $1 >>");
- my $dest=ParsePDFValue(\@xwds);
- foreach my $v (@{$dest->{View}})
- {
- $v=GraphY(abs($v)) if substr($v,0,1) eq '-';
- }
- unshift(@{$dest->{View}},"$cpageno 0 R");
-
- if (!defined($dests))
- {
- $cat->{Dests}=BuildObj(++$objct,{});
- $dests=$obj[$objct]->{DATA};
- }
-
- my $k=substr($dest->{Dest},1);
- $dests->{$k}=$dest->{View};
- }
- elsif ($pdfmark=~m/(.+) \/ANN/)
- {
- my $l=$1;
- $l=~s/Color/C/;
- $l=~s/Action/A/;
- $l=~s/Title/T/;
- $l=~s'/Subtype /URI'/S /URI';
- my @xwds=split(' ',"<< $l >>");
- my $annotno=BuildObj(++$objct,ParsePDFValue(\@xwds));
- my $annot=$obj[$objct];
- $annot->{DATA}->{Type}='/Annot';
- FixRect($annot->{DATA}->{Rect}); # Y origin to ll
- push(@{$cpage->{Annots}},$annotno);
- }
- elsif ($pdfmark=~m/(.+) \/OUT/)
- {
- my @xwds=split(' ',"<< $1 >>");
- my $out=ParsePDFValue(\@xwds);
-
- my $this=[$out,[]];
-
- if (exists($out->{Level}))
- {
- my $lev=abs($out->{Level});
- my $levsgn=sgn($out->{Level});
- delete($out->{Level});
-
- if ($lev > $thislev)
- {
- my $thisoutlev=$curoutlev->[$#{$curoutlev}]->[1];
- $thisoutlev->[0]=[0,$curoutlev,0,$levsgn];
- $curoutlev=$thisoutlev;
- $thislev++;
- }
- elsif ($lev < $thislev)
- {
- my $openct=$curoutlev->[0]->[2];
-
- while ($thislev > $lev)
- {
- my $nxtoutlev=$curoutlev->[0]->[1];
- $nxtoutlev->[0]->[2]+=$openct if $curoutlev->[0]->[3]==1;
- $openct=0 if $nxtoutlev->[0]->[3]==-1;
- $curoutlev=$nxtoutlev;
- $thislev--;
- }
- }
-
- push(@{$curoutlev},$this);
- $curoutlev->[0]->[2]++;
- }
- else
- {
- while ($curoutlev->[0]->[0] == 0 and defined($curoutlev->[0]->[1]))
- {
- $curoutlev=$curoutlev->[0]->[1];
- }
-
- $curoutlev->[0]->[0]--;
- $curoutlev->[0]->[2]++;
- push(@{$curoutlev},$this);
-
-
- if (exists($out->{Count}) and $out->{Count} != 0)
- {
- push(@{$this->[1]},[abs($out->{Count}),$curoutlev,0,sgn($out->{Count})]);
- $curoutlev=$this->[1];
-
- if ($out->{Count} > 0)
- {
- my $p=$curoutlev;
-
- while (defined($p))
- {
- $p->[0]->[2]+=$out->{Count};
- $p=$p->[0]->[1];
- }
- }
- }
- }
- }
- }
- }
- elsif (lc($xprm[0]) eq 'pdf:')
- {
- if (lc($xprm[1]) eq 'import')
- {
- my $fil=$xprm[2];
- my $llx=$xprm[3];
- my $lly=$xprm[4];
- my $urx=$xprm[5];
- my $ury=$xprm[6];
- my $wid=$xprm[7];
- my $hgt=$xprm[8]||-1;
- my $mat=[1,0,0,1,0,0];
-
- if (!exists($incfil{$fil}))
- {
- if ($fil=~m/\.pdf$/)
- {
- $incfil{$fil}=LoadPDF($fil,$mat,$wid,$hgt,"import");
- }
- elsif ($fil=~m/\.swf$/)
- {
- my $xscale=$wid/($urx-$llx+1);
- my $yscale=($hgt<=0)?$xscale:($hgt/($ury-$lly+1));
- $hgt=($ury-$lly+1)*$yscale;
-
- if ($rot)
- {
- $mat->[3]=$xscale;
- $mat->[0]=$yscale;
- }
- else
- {
- $mat->[0]=$xscale;
- $mat->[3]=$yscale;
- }
-
- $incfil{$fil}=LoadSWF($fil,[$llx,$lly,$urx,$ury],$mat);
- }
- else
- {
- Msg(0,"Unknown filetype '$fil'");
- return undef;
- }
- }
-
- if (defined($incfil{$fil}))
- {
- IsGraphic();
- if ($fil=~m/\.pdf$/)
- {
- my $bbox=$incfil{$fil}->[1];
- my $xscale=$wid/($bbox->[2]-$bbox->[0]+1);
- my $yscale=($hgt<=0)?$xscale:($hgt/($bbox->[3]-$bbox->[1]+1));
- $stream.="q $xscale 0 0 $yscale ".PutXY($xpos,$ypos)." cm";
- $stream.=" 0 1 -1 0 0 0 cm" if $rot;
- $stream.=" /$incfil{$fil}->[0] Do Q\n";
- }
- elsif ($fil=~m/\.swf$/)
- {
- $stream.=PutXY($xpos,$ypos)." m /$incfil{$fil} Do\n";
- }
- }
- }
- elsif (lc($xprm[1]) eq 'pdfpic')
- {
- my $fil=$xprm[2];
- my $flag=uc($xprm[3]);
- my $wid=GetPoints($xprm[4]);
- my $hgt=GetPoints($xprm[5]||-1);
- my $ll=GetPoints($xprm[6]||0);
- my $mat=[1,0,0,1,0,0];
-
- if (!exists($incfil{$fil}))
- {
- $incfil{$fil}=LoadPDF($fil,$mat,$wid,$hgt,"pdfpic");
- }
-
- if (defined($incfil{$fil}))
- {
- IsGraphic();
- my $bbox=$incfil{$fil}->[1];
- my $xscale=$wid/($bbox->[2]-$bbox->[0]+1);
- my $yscale=($hgt<=0)?$xscale:($hgt/($bbox->[3]-$bbox->[1]+1));
- $xscale=($wid<=0)?$yscale:$xscale;
- $xscale=$yscale if $yscale < $xscale;
- $yscale=$xscale if $xscale < $yscale;
- $wid=($bbox->[2]-$bbox->[0]+1)*$xscale;
- $hgt=($bbox->[3]-$bbox->[1]+1)*$yscale;
-
- if ($flag eq '-C' and $ll > $wid)
- {
- $xpos+=int(($ll-$wid)/2);
- }
- elsif ($flag eq '-R' and $ll > $wid)
- {
- $xpos+=$ll-$wid;
- }
-
- $ypos+=$hgt;
- $stream.="q $xscale 0 0 $yscale ".PutXY($xpos,$ypos)." cm";
- $stream.=" 0 1 -1 0 0 0 cm" if $rot;
- $stream.=" /$incfil{$fil}->[0] Do Q\n";
- }
- }
- elsif (lc($xprm[1]) eq 'xrev')
- {
- $xrev=!$xrev;
- }
- elsif (lc($xprm[1]) eq 'markstart')
- {
- $mark={'rst' => $xprm[2]/$unitwidth, 'rsb' => $xprm[3]/$unitwidth, 'xpos' => $xpos,
- 'ypos' => $ypos, 'pdfmark' => join(' ',@xprm[4..$#xprm])};
- }
- elsif (lc($xprm[1]) eq 'markend')
- {
- PutHotSpot($xpos) if defined($mark);
- $mark=undef;
- }
- elsif (lc($xprm[1]) eq 'marksuspend')
- {
- $suspendmark=$mark;
- $mark=undef;
- }
- elsif (lc($xprm[1]) eq 'markrestart')
- {
- $mark=$suspendmark;
- $suspendmark=undef;
- }
- elsif (lc($xprm[1]) eq 'pagename')
- {
- if ($pginsert > -1)
- {
- $pgnames{$xprm[2]}=$pages->{Kids}->[$pginsert];
- }
- else
- {
- $pgnames{$xprm[2]}='top';
- }
- }
- elsif (lc($xprm[1]) eq 'switchtopage')
- {
- my $ba=$xprm[2];
- my $want=$xprm[3];
-
- if ($pginsert > -1)
- {
- if (!defined($want) or $want eq '')
- {
- # no before/after
- $want=$ba;
- $ba='before';
- }
-
- if (!defined($ba) or $ba eq '' or $ba eq 'bottom')
- {
- $pginsert=$#{$pages->{Kids}};
- }
- elsif ($ba eq 'top')
- {
- $pginsert=-1;
- }
- else
- {
- if (exists($pgnames{$want}))
- {
- my $ref=$pgnames{$want};
-
- if ($ref eq 'top')
- {
- $pginsert=-1;
- }
- else
- {
-
- foreach my $j (0..$#{$pages->{Kids}})
- {
- if ($ref eq $pages->{Kids}->[$j])
- {
- if ($ba eq 'before')
- {
- $pginsert=$j-1;
- return;
- }
- elsif ($ba eq 'after')
- {
- $pginsert=$j;
- return;
- }
- else
- {
- Msg(0,"Parameter must be top|bottom|before|after not '$ba'");
- return;
- }
- }
- }
-
- Msg(0,"Can't find page ref '$ref'");
- }
- }
- else
- {
- Msg(0,"Can't find page named '$want'");
- }
- }
-
- }
- }
- }
- elsif (lc(substr($xprm[0],0,9)) eq 'papersize')
- {
- my ($px,$py)=split(',',substr($xprm[0],10));
- $px=GetPoints($px);
- $py=GetPoints($py);
- @mediabox=(0,0,$px,$py);
- my @mb=@mediabox;
- $matrixchg=1;
- $cpage->{MediaBox}=\@mb;
- }
- }
-}
-
-sub PutHotSpot
-{
- my $endx=shift;
- my $l=$mark->{pdfmark};
- $l=~s/Color/C/;
- $l=~s/Action/A/;
- $l=~s'/Subtype /URI'/S /URI';
- my @xwds=split(' ',"<< $l >>");
- my $annotno=BuildObj(++$objct,ParsePDFValue(\@xwds));
- my $annot=$obj[$objct];
- $annot->{DATA}->{Type}='/Annot';
- $annot->{DATA}->{Rect}=[$mark->{xpos},$mark->{ypos}-$mark->{rsb},$endx,$mark->{ypos}-$mark->{rst}];
- FixRect($annot->{DATA}->{Rect}); # Y origin to ll
- push(@{$cpage->{Annots}},$annotno);
-}
-
-sub sgn
-{
- return(1) if $_[0] > 0;
- return(-1) if $_[0] < 0;
- return(0);
-}
-
-sub FixRect
-{
- my $rect=shift;
-
- return if !defined($rect);
- $rect->[1]=GraphY($rect->[1]);
- $rect->[3]=GraphY($rect->[3]);
-}
-
-sub GetPoints
-{
- my $val=shift;
-
- $val=ToPoints($1,$2) if ($val=~m/(-?[\d.]+)([cipn])/);
-
- return $val;
-}
-
-# Although the PDF reference mentions XObject/Form as a way of incorporating an external PDF page into
-# the current PDF, it seems not to work with any current PDF reader (although I am told (by Leonard Rosenthol,
-# who helped author the PDF ISO standard) that Acroread 9 does support it, empiorical observation shows otherwise!!).
-# So... do it the hard way - full PDF parser and merge required objects!!!
-
-# sub BuildRef
-# {
-# my $fil=shift;
-# my $bbox=shift;
-# my $mat=shift;
-# my $wid=($bbox->[2]-$bbox->[0])*$mat->[0];
-# my $hgt=($bbox->[3]-$bbox->[1])*$mat->[3];
-#
-# if (!open(PDF,"<$fil"))
-# {
-# Msg(0,"Failed to open '$fil'");
-# return(undef);
-# }
-#
-# my (@f)=(<PDF>);
-#
-# close(PDF);
-#
-# $objct++;
-# my $xonm="XO$objct";
-#
-# $pages->{'Resources'}->{'XObject'}->{$xonm}=BuildObj($objct,{'Type' => '/XObject',
-# 'Subtype' => '/Form',
-# 'BBox' => $bbox,
-# 'Matrix' => $mat,
-# 'Resources' => $pages->{'Resources'},
-# 'Ref' => {'Page' => '1',
-# 'F' => BuildObj($objct+1,{'Type' => '/Filespec',
-# 'F' => "($fil)",
-# 'EF' => {'F' => BuildObj($objct+2,{'Type' => '/EmbeddedFile'})}
-# })
-# }
-# });
-#
-# $obj[$objct]->{STREAM}="q 1 0 0 1 0 0 cm
-# q BT
-# 1 0 0 1 0 0 Tm
-# .5 g .5 G
-# /F5 20 Tf
-# (Proxy) Tj
-# ET Q
-# 0 0 m 72 0 l s
-# Q\n";
-#
-# # $obj[$objct]->{STREAM}=PutXY($xpos,$ypos)." m ".PutXY($xpos+$wid,$ypos)." l ".PutXY($xpos+$wid,$ypos+$hgt)." l ".PutXY($xpos,$ypos+$hgt)." l f\n";
-# $obj[$objct+2]->{STREAM}=join('',@f);
-# PutObj($objct);
-# PutObj($objct+1);
-# PutObj($objct+2);
-# $objct+=2;
-# return($xonm);
-# }
-
-sub LoadSWF
-{
- my $fil=shift;
- my $bbox=shift;
- my $mat=shift;
- my $wid=($bbox->[2]-$bbox->[0])*$mat->[0];
- my $hgt=($bbox->[3]-$bbox->[1])*$mat->[3];
- my (@path)=split('/',$fil);
- my $node=pop(@path);
-
- if (!open(PDF,"<$fil"))
- {
- Msg(0,"Failed to open '$fil'");
- return(undef);
- }
-
- my (@f)=(<PDF>);
-
- close(PDF);
-
- $objct++;
- my $xonm="XO$objct";
-
- $pages->{'Resources'}->{'XObject'}->{$xonm}=BuildObj($objct,{'Type' => '/XObject', 'BBox' => $bbox, 'Matrix' => $mat, 'FormType' => 1, 'Subtype' => '/Form', 'Length' => 0, 'Type' => "/XObject"});
- $obj[$objct]->{STREAM}='';
- PutObj($objct);
- $objct++;
- my $asset=BuildObj($objct,{'EF' => {'F' => BuildObj($objct+1,{})},
- 'F' => "($node)",
- 'Type' => '/Filespec',
- 'UF' => "($node)"});
-
- PutObj($objct);
- $objct++;
- $obj[$objct]->{STREAM}=join('',@f);
- PutObj($objct);
- $objct++;
- my $config=BuildObj($objct,{'Instances' => [BuildObj($objct+1,{'Params' => { 'Binding' => '/Background'}, 'Asset' => $asset})],
- 'Subtype' => '/Flash'});
-
- PutObj($objct);
- $objct++;
- PutObj($objct);
- $objct++;
-
- my ($x,$y)=split(' ',PutXY($xpos,$ypos));
-
- push(@{$cpage->{Annots}},BuildObj($objct,{'RichMediaContent' => {'Subtype' => '/Flash', 'Configurations' => [$config], 'Assets' => {'Names' => [ "($node)", $asset ] }},
- 'P' => "$cpageno 0 R",
- 'RichMediaSettings' => { 'Deactivation' => { 'Condition' => '/PI',
- 'Type' => '/RichMediaDeactivation'},
- 'Activation' => { 'Condition' => '/PV',
- 'Type' => '/RichMediaActivation'}},
- 'F' => 68,
- 'Subtype' => '/RichMedia',
- 'Type' => '/Annot',
- 'Rect' => "[ $x $y ".($x+$wid)." ".($y+$hgt)." ]",
- 'Border' => [0,0,0]}));
-
- PutObj($objct);
-
- return $xonm;
-}
-
-sub LoadPDF
-{
- my $pdfnm=shift;
- my $wid=shift;
- my $hgt=shift;
- my $type=shift;
- my $mat=[1,0,0,1,0,0];
- my $pdf;
- my $pdftxt='';
- my $strmlen=0;
- my $curobj=-1;
- my $instream=0;
- my $cont;
-
- if (!open(PD,"<$pdfnm"))
- {
- Msg(0,"Failed to open PDF '$pdfnm'");
- return undef;
- }
-
- my $hdr=<PD>;
-
- $/="\r" if (length($hdr) > 10);
-
- while (<PD>)
- {
- chomp;
-
- s/\n//;
-
- if (m/endstream(\s+.*)?$/)
- {
- $instream=0;
- $_="endstream";
- $_.=$1 if defined($1)
- }
-
- next if $instream;
-
- if (m'/Length\s+(\d+)(\s+\d+\s+R)?')
- {
- if (!defined($2))
- {
- $strmlen=$1;
- }
- else
- {
- $strmlen=0;
- }
- }
-
- if (m'^(\d+) \d+ obj')
- {
- $curobj=$1;
- $pdf->[$curobj]->{OBJ}=undef;
- }
-
- if (m'stream\s*$' and ! m/^endstream/)
- {
- if ($curobj > -1)
- {
- $pdf->[$curobj]->{STREAMPOS}=[tell(PD),$strmlen];
- seek(PD,$strmlen,1);
- $instream=1;
- }
- else
- {
- Msg(0,"Parsing PDF '$pdfnm' failed");
- return undef;
- }
- }
-
- $pdftxt.=$_.' ';
- }
-
- close(PD);
-
- open(PD,"<$pdfnm");
-# $pdftxt=~s/\]/ \]/g;
- my (@pdfwds)=split(' ',$pdftxt);
- my $wd;
-
- while ($wd=nextwd(\@pdfwds),length($wd))
- {
- if ($wd=~m/\d+/ and defined($pdfwds[1]) and $pdfwds[1]=~m/^obj(.*)/)
- {
- $curobj=$wd;
- shift(@pdfwds); shift(@pdfwds);
- unshift(@pdfwds,$1) if defined($1) and length($1);
- $pdf->[$curobj]->{OBJ}=ParsePDFObj(\@pdfwds);
- }
- elsif ($wd eq 'trailer' and !exists($pdf->[0]->{OBJ}))
- {
- $pdf->[0]->{OBJ}=ParsePDFObj(\@pdfwds);
- }
- else
- {
-# print "Skip '$wd'\n";
- }
- }
-
- my $catalog=${$pdf->[0]->{OBJ}->{Root}};
- my $page=FindPage(1,$pdf);
- my $xobj=++$objct;
-
- # Load the streamas
-
- foreach my $o (@{$pdf})
- {
- if (exists($o->{STREAMPOS}))
- {
- my $l;
-
- $l=$o->{OBJ}->{Length} if exists($o->{OBJ}->{Length});
-
- $l=$pdf->[$$l]->{OBJ} if (defined($l) && ref($l) eq 'OBJREF');
-
- Msg(1,"Unable to determine length of stream \@$o->{STREAMPOS}->[0]") if !defined($l);
-
- sysseek(PD,$o->{STREAMPOS}->[0],0);
- Msg(0,'Failed to read all the stream') if $l != sysread(PD,$o->{STREAM},$l);
-
- if (exists($o->{OBJ}->{'Filter'}) and $o->{OBJ}->{'Filter'} eq '/FlateDecode')
- {
- $o->{STREAM}=Compress::Zlib::uncompress($o->{STREAM});
- delete($o->{OBJ }->{'Filter'});
- }
- }
- }
-
- close(PD);
-
- # Find BBox
- my $BBox;
- my $insmap={};
-
- foreach my $k (qw( MediaBox ArtBox TrimBox BleedBox CropBox ))
- {
- $BBox=FindKey($pdf,$page,$k);
- last if $BBox;
- }
-
- $BBox=[0,0,595,842] if !defined($BBox);
-
- my $xscale=$wid/($BBox->[2]-$BBox->[0]+1);
- my $yscale=($hgt<=0)?$xscale:($hgt/($BBox->[3]-$BBox->[1]+1));
- $hgt=($BBox->[3]-$BBox->[1]+1)*$yscale;
-
- if ($type eq "import")
- {
- $mat->[0]=$xscale;
- $mat->[3]=$yscale;
- }
-
- # Find Resource
-
- my $res=FindKey($pdf,$page,'Resources');
- my $xonm="XO$xobj";
-
- # Map inserted objects to current PDF
-
- MapInsValue($pdf,$page,'',$insmap,$xobj,$pdf->[$page]->{OBJ});
-#
-# Many PDFs include 'Resources' at the 'Page' level but if 'Resources' is held at a higher level (i.e 'Pages')
-# then we need to include its objects as well.
-#
- MapInsValue($pdf,$page,'',$insmap,$xobj,$res) if !exists($pdf->[$page]->{OBJ}->{Resources});
-
- # Copy Resources
-
- my %incres=%{$res};
-
- $incres{ProcSet}=['/PDF', '/Text', '/ImageB', '/ImageC', '/ImageI'];
-
- ($mat->[4],$mat->[5])=split(' ',PutXY($xpos,$ypos));
- $pages->{'Resources'}->{'XObject'}->{$xonm}=BuildObj($xobj,{'Type' => '/XObject', 'BBox' => $BBox, 'Name' => "/$xonm", 'FormType' => 1, 'Subtype' => '/Form', 'Length' => 0, 'Type' => "/XObject", 'Resources' => \%incres});
-
- BuildStream($xobj,$pdf,$pdf->[$page]->{OBJ}->{Contents});
-
- return([$xonm,$BBox] );
-}
-
-sub BuildStream
-{
- my $xobj=shift;
- my $pdf=shift;
- my $val=shift;
- my $strm='';
- my $objs;
- my $refval=ref($val);
-
- if ($refval eq 'OBJREF')
- {
- push(@{$objs}, $val);
- }
- elsif ($refval eq 'ARRAY')
- {
- $objs=$val;
- }
- else
- {
- Msg(0,"unexpected 'Contents'");
- }
-
- foreach my $o (@{$objs})
- {
- $strm.="\n" if $strm;
- $strm.=$pdf->[$$o]->{STREAM} if exists($pdf->[$$o]->{STREAM});
- }
-
- $obj[$xobj]->{STREAM}=$strm;
-}
-
-
-sub MapInsHash
-{
- my $pdf=shift;
- my $o=shift;
- my $insmap=shift;
- my $parent=shift;
- my $val=shift;
-
-
- foreach my $k (keys(%{$val}))
- {
- MapInsValue($pdf,$o,$k,$insmap,$parent,$val->{$k}) if $k ne 'Contents';
- }
-}
-
-sub MapInsValue
-{
- my $pdf=shift;
- my $o=shift;
- my $k=shift;
- my $insmap=shift;
- my $parent=shift;
- my $val=shift;
- my $refval=ref($val);
-
- if ($refval eq 'OBJREF')
- {
- if ($k ne 'Parent')
- {
- if (!exists($insmap->{IMP}->{$$val}))
- {
- $objct++;
- $insmap->{CUR}->{$objct}=$$val;
- $insmap->{IMP}->{$$val}=$objct;
- $obj[$objct]->{DATA}=$pdf->[$$val]->{OBJ};
- $obj[$objct]->{STREAM}=$pdf->[$$val]->{STREAM} if exists($pdf->[$$val]->{STREAM});
- MapInsValue($pdf,$$val,'',$insmap,$o,$pdf->[$$val]->{OBJ});
- }
-
- $$val=$insmap->{IMP}->{$$val};
- }
- else
- {
- $$val=$parent;
- }
- }
- elsif ($refval eq 'ARRAY')
- {
- foreach my $v (@{$val})
- {
- MapInsValue($pdf,$o,'',$insmap,$parent,$v)
- }
- }
- elsif ($refval eq 'HASH')
- {
- MapInsHash($pdf,$o,$insmap,$parent,$val);
- }
-
-}
-
-sub FindKey
-{
- my $pdf=shift;
- my $page=shift;
- my $k=shift;
-
- if (exists($pdf->[$page]->{OBJ}->{$k}))
- {
- my $val=$pdf->[$page]->{OBJ}->{$k};
- $val=$pdf->[$$val]->{OBJ} if ref($val) eq 'OBJREF';
- return($val);
- }
- else
- {
- if (exists($pdf->[$page]->{OBJ}->{Parent}))
- {
- return(FindKey($pdf,${$pdf->[$page]->{OBJ}->{Parent}},$k));
- }
- }
-
- return(undef);
-}
-
-sub FindPage
-{
- my $wantpg=shift;
- my $pdf=shift;
- my $catalog=${$pdf->[0]->{OBJ}->{Root}};
- my $pages=${$pdf->[$catalog]->{OBJ}->{Pages}};
-
- return(NextPage($pdf,$pages,\$wantpg));
-}
-
-sub NextPage
-{
- my $pdf=shift;
- my $pages=shift;
- my $wantpg=shift;
- my $ret;
-
- if ($pdf->[$pages]->{OBJ}->{Type} eq '/Pages')
- {
- foreach my $kid (@{$pdf->[$pages]->{OBJ}->{Kids}})
- {
- $ret=NextPage($pdf,$$kid,$wantpg);
- last if $$wantpg<=0;
- }
- }
- elsif ($pdf->[$pages]->{OBJ}->{Type} eq '/Page')
- {
- $$wantpg--;
- $ret=$pages;
- }
-
- return($ret);
-}
-
-sub nextwd
-{
- my $pdfwds=shift;
-
- my $wd=shift(@{$pdfwds});
-
- return('') if !defined($wd);
-
- if ($wd=~m/^(.*?)(<<|>>|\[|\])(.*)/)
- {
- if (defined($1) and length($1))
- {
- unshift(@{$pdfwds},$3) if defined($3) and length($3);
- unshift(@{$pdfwds},$2);
- $wd=$1;
- }
- else
- {
- unshift(@{$pdfwds},$3) if defined($3) and length($3);
- $wd=$2;
- }
- }
-
- return($wd);
-}
-
-sub ParsePDFObj
-{
-
- my $pdfwds=shift;
- my $rtn;
- my $wd;
-
- while ($wd=nextwd($pdfwds),length($wd))
- {
- if ($wd eq 'stream' or $wd eq 'endstream')
- {
- next;
- }
- elsif ($wd eq 'endobj' or $wd eq 'startxref')
- {
- last;
- }
- else
- {
- unshift(@{$pdfwds},$wd);
- $rtn=ParsePDFValue($pdfwds);
- }
- }
-
- return($rtn);
-}
-
-sub ParsePDFHash
-{
- my $pdfwds=shift;
- my $rtn={};
- my $wd;
-
- while ($wd=nextwd($pdfwds),length($wd))
- {
- if ($wd eq '>>')
- {
- last;
- }
-
- my (@w)=split('/',$wd,3);
-
- if ($w[0])
- {
- Msg(0,"PDF Dict Key '$wd' does not start with '/'");
- exit 1;
- }
- else
- {
- unshift(@{$pdfwds},"/$w[2]") if $w[2];
- $wd=$w[1];
- (@w)=split('\(',$wd,2);
- $wd=$w[0];
- unshift(@{$pdfwds},"($w[1]") if defined($w[1]);
- (@w)=split('\<',$wd,2);
- $wd=$w[0];
- unshift(@{$pdfwds},"<$w[1]") if defined($w[1]);
-
- $rtn->{$wd}=ParsePDFValue($pdfwds);
- }
- }
-
- return($rtn);
-}
-
-sub ParsePDFValue
-{
- my $pdfwds=shift;
- my $rtn;
- my $wd=nextwd($pdfwds);
-
- if ($wd=~m/^\d+$/ and $pdfwds->[0]=~m/^\d+$/ and $pdfwds->[1]=~m/^R(\]|\>|\/)?/)
- {
- shift(@{$pdfwds});
- if (defined($1) and length($1))
- {
- $pdfwds->[0]=substr($pdfwds->[0],1);
- }
- else
- {
- shift(@{$pdfwds});
- }
- return(bless(\$wd,'OBJREF'));
- }
-
- if ($wd eq '<<')
- {
- return(ParsePDFHash($pdfwds));
- }
-
- if ($wd eq '[')
- {
- return(ParsePDFArray($pdfwds));
- }
-
- if ($wd=~m/(.*?)(\(.*)$/)
- {
- if (defined($1) and length($1))
- {
- unshift(@{$pdfwds},$2);
- $wd=$1;
- }
- else
- {
- return(ParsePDFString($wd,$pdfwds));
- }
- }
-
- if ($wd=~m/(.*?)(\<.*)$/)
- {
- if (defined($1) and length($1))
- {
- unshift(@{$pdfwds},$2);
- $wd=$1;
- }
- else
- {
- return(ParsePDFHexString($wd,$pdfwds));
- }
- }
-
- if ($wd=~m/(.+?)(\/.*)$/)
- {
- if (defined($2) and length($2))
- {
- unshift(@{$pdfwds},$2);
- $wd=$1;
- }
- }
-
- return($wd);
-}
-
-sub ParsePDFString
-{
- my $wd=shift;
- my $rtn='';
- my $pdfwds=shift;
- my $lev=0;
-
- while (length($wd))
- {
- $rtn.=' ' if length($rtn);
-
- while ($wd=~m/(?<!\\)\(/g) {$lev++;}
- while ($wd=~m/(?<!\\)\)/g) {$lev--;}
-
-
- if ($lev<=0 and $wd=~m/^(.*?\))([^)]+)$/)
- {
- unshift(@{$pdfwds},$2) if defined($2) and length($2);
- $wd=$1;
- }
-
- $rtn.=$wd;
-
- last if $lev <= 0;
-
- $wd=nextwd($pdfwds);
- }
-
- return($rtn);
-}
-
-sub ParsePDFHexString
-{
- my $wd=shift;
- my $rtn='';
- my $pdfwds=shift;
- my $lev=0;
-
- if ($wd=~m/^(<.+?>)(.*)/)
- {
- unshift(@{$pdfwds},$2) if defined($2) and length($2);
- $rtn=$1;
- }
-
- return($rtn);
-}
-
-sub ParsePDFArray
-{
- my $pdfwds=shift;
- my $rtn=[];
- my $wd;
-
- while (1)
- {
- $wd=ParsePDFValue($pdfwds);
- last if $wd eq ']' or length($wd)==0;
- push(@{$rtn},$wd);
- }
-
- return($rtn);
-}
-
-sub Msg
-{
- my ($lev,$msg)=@_;
-
- print STDERR "$env{SourceFile}: " if exists($env{SourceFile});
- print STDERR "$msg\n";
- exit 1 if $lev;
-}
-
-sub PutXY
-{
- my ($x,$y)=(@_);
-
- if ($frot)
- {
- return("$y $x");
- }
- else
- {
- $y=$mediabox[3]-$y;
- return("$x $y");
- }
-}
-
-sub GraphY
-{
- my $y=shift;
-
- if ($frot)
- {
- return($y);
- }
- else
- {
- return($mediabox[3]-$y);
- }
-}
-
-sub Put
-{
- my $msg=shift;
-
- print $msg;
- $fct+=length($msg);
-}
-
-sub PutObj
-{
- my $ono=shift;
- my $msg="$ono 0 obj ";
- $obj[$ono]->{XREF}=$fct;
- if (exists($obj[$ono]->{STREAM}))
- {
- if (!$debug)
- {
- $obj[$ono]->{STREAM}=Compress::Zlib::compress($obj[$ono]->{STREAM});
- $obj[$ono]->{DATA}->{'Filter'}=['/FlateDecode'];
- }
-
- $obj[$ono]->{DATA}->{'Length'}=length($obj[$ono]->{STREAM});
- }
- PutField(\$msg,$obj[$ono]->{DATA});
- PutStream(\$msg,$ono) if exists($obj[$ono]->{STREAM});
- Put($msg."endobj\n");
-}
-
-sub PutStream
-{
- my $msg=shift;
- my $ono=shift;
-
- # We could 'flate' here
- $$msg.="stream\n$obj[$ono]->{STREAM}endstream\n";
-}
-
-sub PutField
-{
- my $pmsg=shift;
- my $fld=shift;
- my $term=shift||"\n";
- my $typ=ref($fld);
-
- if ($typ eq '')
- {
- $$pmsg.="$fld$term";
- }
- elsif ($typ eq 'ARRAY')
- {
- $$pmsg.='[';
- foreach my $cell (@{$fld})
- {
- PutField($pmsg,$cell,' ');
- }
- $$pmsg.="]$term";
- }
- elsif ($typ eq 'HASH')
- {
- $$pmsg.='<< ';
- foreach my $key (sort keys %{$fld})
- {
- $$pmsg.="/$key ";
- PutField($pmsg,$fld->{$key});
- }
- $$pmsg.=">>$term";
- }
- elsif ($typ eq 'OBJREF')
- {
- $$pmsg.="$$fld 0 R$term";
- }
-}
-
-sub BuildObj
-{
- my $ono=shift;
- my $val=shift;
-
- $obj[$ono]->{DATA}=$val;
-
- return("$ono 0 R ");
-}
-
-sub LoadFont
-{
- my $fontno=shift;
- my $fontnm=shift;
- my $ofontnm=$fontnm;
-
- return $fontlst{$fontno}->{OBJ} if (exists($fontlst{$fontno}));
-
- my $f;
- OpenFile(\$f,$fontdir,"$fontnm");
-
- if (!defined($f) and $Foundry)
- {
- # Try with no foundry
- $fontnm=~s/.*?-//;
- OpenFile(\$f,$fontdir,$fontnm);
- }
-
- Msg(1,"Failed to open font '$ofontnm'") if !defined($f);
-
- my $foundry='';
- $foundry=$1 if $fontnm=~m/^(.*?)-/;
- my $stg=1;
- my %fnt;
- my @fntbbox=(0,0,0,0);
- my $capheight=0;
- my $lastchr=0;
- my $t1flags=0;
- my $fixwid=-1;
- my $ascent=0;
- my $charset='';
-
- while (<$f>)
- {
- chomp;
-
- s/^ +//;
- s/^#.*// if $stg == 1;
- next if $_ eq '';
-
- if ($stg == 1)
- {
- my ($key,$val)=split(' ',$_,2);
-
- $key=lc($key);
- $stg=2,next if $key eq 'kernpairs';
- $stg=3,next if lc($_) eq 'charset';
-
- $fnt{$key}=$val
- }
- elsif ($stg == 2)
- {
- $stg=3,next if lc($_) eq 'charset';
-
- my ($ch1,$ch2,$k)=split;
- $fnt{KERN}->{$ch1}->{$ch2}=$k;
- }
- else
- {
- my (@r)=split;
- my (@p)=split(',',$r[1]);
-
- if ($r[1] eq '"')
- {
- $fnt{GNM}->{$r[0]}=$lastchr;
- next;
- }
-
- $r[0]='u0020' if $r[3] == 32;
- next if $r[3] >255;
- $fnt{GNM}->{$r[0]}=$r[3];
- $fnt{GNO}->[$r[3]]='/'.$r[4];
- $fnt{WID}->[$r[3]]=$p[0];
- $lastchr=$r[3] if $r[3] > $lastchr;
- $fixwid=$p[0] if $fixwid == -1;
- $fixwid=-2 if $fixwid > 0 and $p[0] != $fixwid;
-
- $fntbbox[1]=-$p[2] if defined($p[2]) and -$p[2] < $fntbbox[1];
- $fntbbox[2]=$p[0] if $p[0] > $fntbbox[2];
- $fntbbox[3]=$p[1] if defined($p[1]) and $p[1] > $fntbbox[3];
- $ascent=$p[1] if defined($p[1]) and $p[1] > $ascent and $r[3] >= 32 and $r[3] < 128;
- $charset.='/'.$r[4] if defined($r[4]);
- $capheight=$p[1] if length($r[4]) == 1 and $r[4] ge 'A' and $r[4] le 'Z' and $p[1] > $capheight;
- }
- }
-
- close($f);
-
- unshift(@{$fnt{GNO}},0);
-
- foreach my $glyph (@{$fnt{GNO}})
- {
- $glyph='/.notdef' if !defined($glyph);
- }
-
- foreach my $w (@{$fnt{WID}})
- {
- $w=0 if !defined($w);
- }
-
- my $fno=0;
- my $slant=0;
- $slant=-$fnt{'slant'} if exists($fnt{'slant'});
- $fnt{'spacewidth'}=700 if !exists($fnt{'spacewidth'});
-
- $t1flags|=2**0 if $fixwid > -1;
- $t1flags|=(exists($fnt{'special'}))?2**2:2**5;
- $t1flags|=2**6 if $slant != 0;
- my $fontkey="$foundry $fnt{internalname}";
-
- if (exists($download{$fontkey}))
- {
- # Not a Base Font
- my ($l1,$l2,$l3,$t1stream)=GetType1($download{$fontkey});
- Msg(0,"Incorrect font format for '$fontkey' ($l1)") if !defined($t1stream);
- $fno=++$objct;
- $fontlst{$fontno}->{OBJ}=BuildObj($objct,
- {'Type' => '/Font',
- 'Subtype' => '/Type1',
- 'BaseFont' => '/'.$fnt{internalname},
- 'Widths' => $fnt{WID},
- 'FirstChar' => 0,
- 'LastChar' => $lastchr,
- 'Encoding' => BuildObj($objct+1,
- {'Type' => '/Encoding',
- 'Differences' => $fnt{GNO}
- }
- ),
- 'FontDescriptor' => BuildObj($objct+2,
- {'Type' => '/FontDescriptor',
- 'FontName' => '/'.$fnt{internalname},
- 'Flags' => $t1flags,
- 'FontBBox' => \@fntbbox,
- 'ItalicAngle' => $slant,
- 'Ascent' => $ascent,
- 'Descent' => $fntbbox[1],
- 'CapHeight' => $capheight,
- 'StemV' => 0,
- 'CharSet' => "($charset)",
- 'FontFile' => BuildObj($objct+3,
- {'Length1' => $l1,
- 'Length2' => $l2,
- 'Length3' => $l3
- }
- )
- }
- )
- }
- );
-
- $objct+=3;
- $fontlst{$fontno}->{NM}='/F'.$fontno;
- $pages->{'Resources'}->{'Font'}->{'F'.$fontno}=$fontlst{$fontno}->{OBJ};
- $fontlst{$fontno}->{FNT}=\%fnt;
- $obj[$objct]->{STREAM}=$t1stream;
-
- }
- else
- {
- $fno=++$objct;
- $fontlst{$fontno}->{OBJ}=BuildObj($objct,
- {'Type' => '/Font',
- 'Subtype' => '/Type1',
- 'BaseFont' => '/'.$fnt{internalname},
- 'Encoding' => BuildObj($objct+1,
- {'Type' => '/Encoding',
- 'Differences' => $fnt{GNO}
- }
- )
- }
- );
- $objct+=1;
- $fontlst{$fontno}->{NM}='/F'.$fontno;
- $pages->{'Resources'}->{'Font'}->{'F'.$fontno}=$fontlst{$fontno}->{OBJ};
- $fontlst{$fontno}->{FNT}=\%fnt;
- }
-
- PutObj($fno);
- PutObj($fno+1);
- PutObj($fno+2) if defined($obj[$fno+2]);
- PutObj($fno+3) if defined($obj[$fno+3]);
-}
-
-sub GetType1
-{
- my $file=shift;
- my ($l1,$l2,$l3); # Return lengths
- my ($head,$body,$tail); # Font contents
- my $f;
-
- OpenFile(\$f,$fontdir,"$file");
- Msg(1,"Failed to open '$file'") if !defined($f);
- binmode($f);
-
- my $l=<$f>;
-
- if (substr($l,0,1) eq "\x80")
- {
- # PFB file
- sysseek($f,0,0);
- my $hdr='';
- $l1=$l2=$l3=0;
- my $typ=0;
- my $data='';
- my $sl=0;
-
- while ($typ != 3)
- {
- my $chk=sysread($f,$hdr,6);
-
- if ($chk < 2)
- {
- # eof($f) uses buffered i/o (since file was open not sysopen)
- # which screws up next sysread. So this will terminate loop if font
- # has no terminating section type 3.
- last if $l3;
- return(5,$l2,$l3,undef);
- }
-
- $typ=ord(substr($hdr,1,1));
-
- if ($chk == 6)
- {
- $sl=unpack('L',substr($hdr,2,4));
- $chk=sysread($f,$data,$sl);
- return(1,$l2,$l3,undef) if $chk != $sl;
- }
-
- if ($typ == 1)
- {
- if ($l2 == 0)
- {
- # First text bit(s) must be head
- $head.=$data;
- $l1+=$sl;
- }
- else
- {
- # A text bit after the binary sections must be tail
- $tail.=$data;
- $l3+=$sl;
- }
- }
- elsif ($typ == 2)
- {
- return(2,$l2,$l3,undef) if $l3; # Found a binary bit after the tail
- $body.=$data;
- $l2+=$sl;
- }
- elsif ($typ != 3)
- {
- # What segment type is this!
- return(3,$l2,$l3,undef);
- }
- }
-
- close($f);
- return($l1,$l2,$l3,"$head$body$tail");
- }
-
- my (@lines)=(<$f>);
- unshift(@lines,$l);
-
- close($f);
-
- Msg(1,"Font file '$file' must be an Adobe type 1 font file") if $lines[0]!~m/\%\!PS.Adobe/i;
- $head=$body=$tail='';
-
- foreach my $line (@lines)
- {
- if (!defined($l1))
- {
- if (length($line) > 19 and $line=~s/^(currentfile eexec)//)
- {
- $head.=$1;
- $l1=length($head);
- redo;
- }
-
- $head.=$line;
-
- if ($line=~m/eexec$/)
- {
- # chomp($head);
- # $head.="\x0d";
- $l1=length($head);
- }
- }
- elsif (!defined($l2))
- {
- #$line=~s/(\0\0)0+$/&1/;
- if ($line=~m/^0+$/)
- {
- $l2=length($body);
- $tail=$line;
- }
- else
- {
- chomp($line);
- $body.=pack('H*',$line);
- }
- }
- else
- {
- $tail.=$line;
- }
- }
-
- $l1=length($head);
- $l2=length($body);
- $l3=length($tail);
-
- return($l1,$l2,$l3,"$head$body$tail");
-}
-
-
-sub OutStream
-{
- my $ono=shift;
-
- IsGraphic();
- $stream.="Q\n";
- $obj[$ono]->{STREAM}=$stream;
- $obj[$ono]->{DATA}->{Length}=length($stream);
- $stream='';
- PutObj($ono);
-}
-
-sub do_p
-{
- # Start of pages
-
- if ($cpageno > 0)
- {
- PutObj($cpageno);
- OutStream($cpageno+1);
- }
-
- $cpageno=++$objct;
-
- my $thispg=BuildObj($objct,
- {'Type' => '/Page',
- 'Group' => {'CS' => '/DeviceRGB', 'S' => '/Transparency'},
- 'Parent' => '2 0 R',
- 'Contents' => [ BuildObj($objct+1,
- {'Length' => 0}
- ) ],
- }
- );
-
- splice(@{$pages->{Kids}},++$pginsert,0,$thispg);
-
- $objct+=1;
- $cpage=$obj[$cpageno]->{DATA};
- $pages->{'Count'}++;
- $stream="q 1 0 0 1 0 0 cm\n";
- $mode='g';
- $curfill='';
- @mediabox=@defaultmb;
-}
-
-sub do_f
-{
- my $par=shift;
-
-# IsText();
- $cft="$par";
- $fontchg=1;
-# $stream.="/F$cft $cftsz Tf\n" if $cftsz;
- $widtbl=CacheWid($par);
- $origwidtbl=$fontlst{$par}->{FNT}->{WID};
- $krntbl=$fontlst{$par}->{FNT}->{KERN};
-}
-
-sub CacheWid
-{
- my $par=shift;
-
- if (!defined($fontlst{$par}->{CACHE}->{$cftsz}))
- {
- $fontlst{$par}->{CACHE}->{$cftsz}=BuildCache($fontlst{$par}->{FNT}->{WID});
- }
-
- return($fontlst{$par}->{CACHE}->{$cftsz});
-}
-
-sub BuildCache
-{
- my $wid=shift;
- return([]);
- my @cwid;
-
- foreach my $w (@{$wid})
- {
- push(@cwid,$w*$cftsz);
- }
-
- return(\@cwid);
-}
-
-sub IsText
-{
- if ($mode eq 'g')
- {
- $xpos+=$pendmv/$unitwidth;
- $stream.="q BT\n$matrix ".PutXY($xpos,$ypos)." Tm\n";
- $poschg=0;
- $fontchg=0;
- $pendmv=0;
- $matrixchg=0;
- $tmxpos=$xpos;
- $stream.=$textcol."\n", $curfill=$textcol if $textcol ne $curfill;
- if (defined($cft))
- {
- $whtsz=$fontlst{$cft}->{FNT}->{spacewidth}*$cftsz;
- $stream.="/F$cft $cftsz Tf\n";
- }
- }
-
- if ($poschg or $matrixchg)
- {
- PutLine(0) if $matrixchg;
- $stream.="$matrix ".PutXY($xpos,$ypos)." Tm\n", $poschg=0;
- $tmxpos=$xpos;
- $matrixchg=0;
- }
-
- if ($fontchg)
- {
- PutLine(0);
- $whtsz=$fontlst{$cft}->{FNT}->{spacewidth}*$cftsz;
- $stream.="/F$cft $cftsz Tf\n" if $cftsz and defined($cft);
- $fontchg=0;
- }
-
- $mode='t';
-}
-
-sub IsGraphic
-{
- if ($mode eq 't')
- {
- PutLine();
- $stream.="ET Q\n";
- $xpos+=($pendmv-$nomove)/$unitwidth;
- $pendmv=0;
- $nomove=0;
- $stream.=$strkcol."\n", $curstrk=$strkcol if $strkcol ne $curstrk;
- $curfill=$fillcol;
- }
- $mode='g';
-}
-
-sub do_s
-{
- my $par=shift;
- $par/=$unitwidth;
-
- if ($par != $cftsz and defined($cft))
- {
- PutLine();
- $cftsz=$par;
-# $stream.="/F$cft $cftsz Tf\n";
- $fontchg=1;
- $widtbl=CacheWid($cft);
- }
-}
-
-sub do_m
-{
- # Groff uses /m[] for text & graphic stroke, and /M[] (DF?) for graphic fill.
- # PDF uses G/RG/K for graphic stroke, and g/rg/k for text & graphic fill.
- #
- # This means that we must maintain g/rg/k state separately for text colour & graphic fill (this is
- # probably why 'gs' maintains seperate graphic states for text & graphics when distilling PS -> PDF).
- #
- # To facilitate this:-
- #
- # $textcol = current groff stroke colour
- # $fillcol = current groff fill colour
- # $curfill = current PDF fill colour
-
- my $par=shift;
- my $mcmd=substr($par,0,1);
-
- $par=substr($par,1);
- $par=~s/^ +//;
-
-# IsGraphic();
-
- $textcol=set_col($mcmd,$par,0);
- $strkcol=set_col($mcmd,$par,1);
-
- if ($mode eq 't')
- {
- PutLine();
- $stream.=$textcol."\n";
- $curfill=$textcol;
- }
- else
- {
- $stream.="$strkcol\n";
- $curstrk=$strkcol;
- }
-}
-
-sub set_col
-{
- my $mcmd=shift;
- my $par=shift;
- my $upper=shift;
- my @oper=('g','k','rg');
-
- @oper=('G','K','RG') if $upper;
-
- if ($mcmd eq 'd')
- {
- # default colour
- return("0 $oper[0]");
- }
-
- my (@c)=split(' ',$par);
-
- if ($mcmd eq 'c')
- {
- # Text CMY
- return(($c[0]/65535).' '.($c[1]/65535).' '.($c[2]/65535)." 0 $oper[1]");
- }
- elsif ($mcmd eq 'k')
- {
- # Text CMYK
- return(($c[0]/65535).' '.($c[1]/65535).' '.($c[2]/65535).' '.($c[3]/65535)." $oper[1]");
- }
- elsif ($mcmd eq 'g')
- {
- # Text Grey
- return(($c[0]/65535)." $oper[0]");
- }
- elsif ($mcmd eq 'r')
- {
- # Text RGB0
- return(($c[0]/65535).' '.($c[1]/65535).' '.($c[2]/65535)." $oper[2]");
- }
-}
-
-sub do_D
-{
- my $par=shift;
- my $Dcmd=substr($par,0,1);
-
- $par=substr($par,1);
- $xpos+=$pendmv/$unitwidth;
- $pendmv=0;
-
- IsGraphic();
-
- if ($Dcmd eq 'F')
- {
- my $mcmd=substr($par,0,1);
-
- $par=substr($par,1);
- $par=~s/^ +//;
-
- $fillcol=set_col($mcmd,$par,0);
- $stream.="$fillcol\n";
- $curfill=$fillcol;
- }
- elsif ($Dcmd eq 'f')
- {
- my $mcmd=substr($par,0,1);
-
- $par=substr($par,1);
- $par=~s/^ +//;
- ($par)=split(' ',$par);
-
- if ($par >= 0 and $par <= 1000)
- {
- $fillcol=set_col('g',int((1000-$par)*65535/1000),0);
- }
- else
- {
- $fillcol=lc($textcol);
- }
-
- $stream.="$fillcol\n";
- $curfill=$fillcol;
- }
- elsif ($Dcmd eq '~')
- {
- # B-Spline
- my (@p)=split(' ',$par);
- my ($nxpos,$nypos);
-
- foreach my $p (@p) { $p/=$unitwidth; }
- $stream.=PutXY($xpos,$ypos)." m\n";
- $xpos+=($p[0]/2);
- $ypos+=($p[1]/2);
- $stream.=PutXY($xpos,$ypos)." l\n";
-
- for (my $i=0; $i < $#p-1; $i+=2)
- {
- $nxpos=(($p[$i]*$tnum)/(2*$tden));
- $nypos=(($p[$i+1]*$tnum)/(2*$tden));
- $stream.=PutXY(($xpos+$nxpos),($ypos+$nypos))." ";
- $nxpos=($p[$i]/2 + ($p[$i+2]*($tden-$tnum))/(2*$tden));
- $nypos=($p[$i+1]/2 + ($p[$i+3]*($tden-$tnum))/(2*$tden));
- $stream.=PutXY(($xpos+$nxpos),($ypos+$nypos))." ";
- $nxpos=(($p[$i]-$p[$i]/2) + $p[$i+2]/2);
- $nypos=(($p[$i+1]-$p[$i+1]/2) + $p[$i+3]/2);
- $stream.=PutXY(($xpos+$nxpos),($ypos+$nypos))." c\n";
- $xpos+=$nxpos;
- $ypos+=$nypos;
- }
-
- $xpos+=($p[$#p-1]-$p[$#p-1]/2);
- $ypos+=($p[$#p]-$p[$#p]/2);
- $stream.=PutXY($xpos,$ypos)." l\nS\n";
- $poschg=1;
- }
- elsif ($Dcmd eq 'p' or $Dcmd eq 'P')
- {
- # B-Spline
- my (@p)=split(' ',$par);
- my ($nxpos,$nypos);
-
- foreach my $p (@p) { $p/=$unitwidth; }
- $stream.=PutXY($xpos,$ypos)." m\n";
-
- for (my $i=0; $i < $#p; $i+=2)
- {
- $xpos+=($p[$i]);
- $ypos+=($p[$i+1]);
- $stream.=PutXY($xpos,$ypos)." l\n";
- }
-
- if ($Dcmd eq 'p')
- {
- $stream.="s\n";
- }
- else
- {
- $stream.="f\n";
- }
- $poschg=1;
- }
- elsif ($Dcmd eq 'c')
- {
- # Stroke circle
- $par=substr($par,1);
- my (@p)=split(' ',$par);
-
- DrawCircle($p[0],$p[0]);
- $stream.="s\n";
- $poschg=1;
- }
- elsif ($Dcmd eq 'C')
- {
- # Fill circle
- $par=substr($par,1);
- my (@p)=split(' ',$par);
-
- DrawCircle($p[0],$p[0]);
- $stream.="f\n";
- $poschg=1;
- }
- elsif ($Dcmd eq 'e')
- {
- # Stroke ellipse
- $par=substr($par,1);
- my (@p)=split(' ',$par);
-
- DrawCircle($p[0],$p[1]);
- $stream.="s\n";
- $poschg=1;
- }
- elsif ($Dcmd eq 'E')
- {
- # Fill ellipse
- $par=substr($par,1);
- my (@p)=split(' ',$par);
-
- DrawCircle($p[0],$p[1]);
- $stream.="f\n";
- $poschg=1;
- }
- elsif ($Dcmd eq 'l')
- {
- # Line To
- $par=substr($par,1);
- my (@p)=split(' ',$par);
-
- foreach my $p (@p) { $p/=$unitwidth; }
- $stream.=PutXY($xpos,$ypos)." m\n";
- $xpos+=$p[0];
- $ypos+=$p[1];
- $stream.=PutXY($xpos,$ypos)." l\n";
-
- $stream.="s\n";
- $poschg=1;
- }
- elsif ($Dcmd eq 't')
- {
- # Line Thickness
- $par=substr($par,1);
- my (@p)=split(' ',$par);
-
- foreach my $p (@p) { $p/=$unitwidth; }
- # $xpos+=$p[0]*100; # WTF!!!
- #int lw = ((font::res/(72*font::sizescale))*linewidth*env->size)/1000;
- $p[0]=(($desc{res}/(72*$desc{sizescale}))*$linewidth*$cftsz)/1000 if $p[0] < 0;
- $lwidth=$p[0];
- $stream.="$p[0] w\n";
- $poschg=1;
- }
- elsif ($Dcmd eq 'a')
- {
- # Arc
- $par=substr($par,1);
- my (@p)=split(' ',$par);
- my $rad180=3.14159;
- my $rad360=$rad180*2;
- my $rad90=$rad180/2;
-
- foreach my $p (@p) { $p/=$unitwidth; }
-
- # Documentation is wrong. Groff does not use Dh1,Dv1 as centre of the circle!
-
- my $centre=adjust_arc_centre(\@p);
-
- # Using formula here : http://www.tinaja.com/glib/bezcirc2.pdf
- # First calculate angle between start and end point
-
- my ($startang,$r)=RtoP(-$centre->[0],$centre->[1]);
- my ($endang,$r2)=RtoP(($p[0]+$p[2])-$centre->[0],-($p[1]+$p[3]-$centre->[1]));
- $endang+=$rad360 if $endang < $startang;
- my $totang=($endang-$startang)/4; # do it in 4 pieces
-
- # Now 1 piece
-
- my $x0=cos($totang/2);
- my $y0=sin($totang/2);
- my $x3=$x0;
- my $y3=-$y0;
- my $x1=(4-$x0)/3;
- my $y1=((1-$x0)*(3-$x0))/(3*$y0);
- my $x2=$x1;
- my $y2=-$y1;
-
- # Rotate to start position and draw 4 pieces
-
- foreach my $j (0..3)
- {
- PlotArcSegment($totang/2+$startang+$j*$totang,$r,$xpos+$centre->[0],GraphY($ypos+$centre->[1]),$x0,$y0,$x1,$y1,$x2,$y2,$x3,$y3);
- }
-
- $xpos+=$p[0]+$p[2];
- $ypos+=$p[1]+$p[3];
-
- $poschg=1;
- }
-}
-
-sub deg
-{
- return int($_[0]*180/3.14159);
-}
-
-sub adjust_arc_centre
-{
- # Taken from geometry.cpp
-
- # We move the center along a line parallel to the line between
- # the specified start point and end point so that the center
- # is equidistant between the start and end point.
- # It can be proved (using Lagrange multipliers) that this will
- # give the point nearest to the specified center that is equidistant
- # between the start and end point.
-
- my $p=shift;
- my @c;
- my $x = $p->[0] + $p->[2]; # (x, y) is the end point
- my $y = $p->[1] + $p->[3];
- my $n = $x*$x + $y*$y;
- if ($n != 0)
- {
- $c[0]= $p->[0];
- $c[1] = $p->[1];
- my $k = .5 - ($c[0]*$x + $c[1]*$y)/$n;
- $c[0] += $k*$x;
- $c[1] += $k*$y;
- return(\@c);
- }
- else
- {
- return(undef);
- }
-}
-
-
-sub PlotArcSegment
-{
- my ($ang,$r,$transx,$transy,$x0,$y0,$x1,$y1,$x2,$y2,$x3,$y3)=@_;
- my $cos=cos($ang);
- my $sin=sin($ang);
- my @mat=($cos,$sin,-$sin,$cos,0,0);
- my $lw=$lwidth/$r;
-
- $stream.="q $r 0 0 $r $transx $transy cm ".join(' ',@mat)." cm $lw w $x0 $y0 m $x1 $y1 $x2 $y2 $x3 $y3 c S Q\n";
-}
-
-sub DrawCircle
-{
- my $hd=shift;
- my $vd=shift;
- my $hr=$hd/2/$unitwidth;
- my $vr=$vd/2/$unitwidth;
- my $kappa=0.5522847498;
- $hd/=$unitwidth;
- $vd/=$unitwidth;
-
-
- $stream.=PutXY(($xpos+$hd),$ypos)." m\n";
- $stream.=PutXY(($xpos+$hd),($ypos+$vr*$kappa))." ".PutXY(($xpos+$hr+$hr*$kappa),($ypos+$vr))." ".PutXY(($xpos+$hr),($ypos+$vr))." c\n";
- $stream.=PutXY(($xpos+$hr-$hr*$kappa),($ypos+$vr))." ".PutXY(($xpos),($ypos+$vr*$kappa))." ".PutXY(($xpos),($ypos))." c\n";
- $stream.=PutXY(($xpos),($ypos-$vr*$kappa))." ".PutXY(($xpos+$hr-$hr*$kappa),($ypos-$vr))." ".PutXY(($xpos+$hr),($ypos-$vr))." c\n";
- $stream.=PutXY(($xpos+$hr+$hr*$kappa),($ypos-$vr))." ".PutXY(($xpos+$hd),($ypos-$vr*$kappa))." ".PutXY(($xpos+$hd),($ypos))." c\n";
- $xpos+=$hd;
-
- $poschg=1;
-}
-
-sub FindCircle
-{
- my ($x1,$y1,$x2,$y2,$x3,$y3)=@_;
- my ($Xo, $Yo);
-
- my $x=$x2+$x3;
- my $y=$y2+$y3;
- my $n=$x**2+$y**2;
-
- if ($n)
- {
- my $k=.5-($x2*$x + $y2*$y)/$n;
- return(sqrt($n),$x2+$k*$x,$y2+$k*$y);
- }
- else
- {
- return(-1);
- }
-
-}
-
-sub PtoR
-{
- my ($theta,$r)=@_;
-
- return($r*cos($theta),$r*sin($theta));
-}
-
-sub RtoP
-{
- my ($x,$y)=@_;
-
- return(atan2($y,$x),sqrt($x**2+$y**2));
-}
-
-sub PutLine
-{
-
- my $f=shift;
-
- IsText() if !defined($f);
-
- return if (scalar(@lin) == 0) or (!defined($lin[0]->[0]) and $#lin == 0);
-
-# $stream.="% --- wht=$whtsz, pend=$pendmv, nomv=$nomove\n" if $debug;
- $pendmv-=$nomove;
- $lin[$#lin]->[1]=-$pendmv/$cftsz if ($pendmv != 0);
-
- if (0)
- {
- if (scalar(@lin) == 1 and (!defined($lin[0]->[1]) or $lin[0]->[1] == 0))
- {
- $stream.="($lin[0]->[0]) Tj\n";
- }
- else
- {
- $stream.="[";
-
- foreach my $wd (@lin)
- {
- $stream.="($wd->[0]) " if defined($wd->[0]);
- $stream.="$wd->[1] " if defined($wd->[1]) and $wd->[1] != 0;
- }
-
- $stream.="] TJ\n";
- }
- }
- else
- {
- if (scalar(@lin) == 1 and (!defined($lin[0]->[1]) or $lin[0]->[1] == 0))
- {
- $stream.="0 Tw ($lin[0]->[0]) Tj\n";
- }
- else
- {
- if ($wt>=-1 or $#lin == 0 or $lin[0]->[1]>=0)
- {
- $stream.="0 Tw [";
-
- foreach my $wd (@lin)
- {
- $stream.="($wd->[0]) " if defined($wd->[0]);
- $stream.="$wd->[1] " if defined($wd->[1]) and $wd->[1] != 0;
- }
-
- $stream.="] TJ\n";
- }
- else
- {
- # $stream.="\%dg 0 Tw [";
- #
- # foreach my $wd (@lin)
- # {
- # $stream.="($wd->[0]) " if defined($wd->[0]);
- # $stream.="$wd->[1] " if defined($wd->[1]) and $wd->[1] != 0;
- # }
- #
- # $stream.="] TJ\n";
- #
- # my $wt=$lin[0]->[1]||0;
-
- # while ($wt < -$whtsz/$cftsz)
- # {
- # $wt+=$whtsz/$cftsz;
- # }
-
- $stream.=sprintf( "%.3f Tw ",-($whtsz+$wt*$cftsz)/$unitwidth );
- $stream.="[(";
-
- foreach my $wd (@lin)
- {
- my $wwt=$wd->[1]||0;
-
- while ($wwt <= $wt+.1)
- {
- $wwt-=$wt;
- $wd->[0].=' ';
- }
-
- if (abs($wwt) < .1 or $wwt == 0)
- {
- $stream.="$wd->[0]" if defined($wd->[0]);
- }
- else
- {
- $stream.="$wd->[0]) $wwt (" if defined($wd->[0]);
- }
- }
- $stream.=")] TJ\n";
- }
- }
- }
-
- @lin=();
- $xpos+=$pendmv/$unitwidth;
- $pendmv=0;
- $nomove=0;
- $wt=-1;
-}
-
-sub LoadAhead
-{
- my $no=shift;
-
- foreach my $j (1..$no)
- {
- my $lin=<>;
- chomp($lin);
- $lin=~s/\r$//;
- $lct++;
-
- push(@ahead,$lin);
- $stream.="%% $lin\n" if $debug;
- }
-}
-
-sub do_V
-{
- my $par=shift;
-
- if ($mode eq 't')
- {
- PutLine();
- }
- else
- {
- $xpos+=$pendmv/$unitwidth;
- $pendmv=0;
- }
-
- $ypos=$par/$unitwidth;
-
- LoadAhead(1);
-
- if (substr($ahead[0],0,1) eq 'H')
- {
- $xpos=substr($ahead[0],1)/$unitwidth;
-
- @ahead=();
-
- }
-
- $nomove=$pendmv=0;
- $poschg=1;
-}
-
-sub do_v
-{
- my $par=shift;
-
- PutLine();
-
- $ypos+=$par/$unitwidth;
-
- $poschg=1;
-}
-
-sub TextWid
-{
- my $txt=shift;
- my $w=0;
-
- foreach my $c (split('',$txt))
- {
- my $cn=ord($c);
- $widtbl->[$cn]=$origwidtbl->[$cn]*$cftsz if !defined($widtbl->[$cn]);
- $w+=$widtbl->[$cn];
- }
-
- return($w/$unitwidth);
-}
-
-sub do_t
-{
- my $par=shift;
- my $wid=TextWid($par);
-
- $par=reverse(split('',$par)) if $xrev;
- if ($n_flg and defined($mark))
- {
- $mark->{ypos}=$ypos;
- $mark->{xpos}=$xpos;
- }
-
- $n_flg=0;
- IsText();
-
- $xpos+=$wid;
- $xpos+=($pendmv-$nomove)/$unitwidth;
-
- $stream.="% == '$par'=$wid 'xpos=$xpos\n" if $debug;
- $par=~s/\\/\\\\/g;
- $par=~s/\)/\\)/g;
- $par=~s/\(/\\(/g;
-
- # $pendmv = 'h' move since last 't'
- # $nomove = width of char(s) added by 'C', 'N' or 'c'
- # $w-flg = 'w' seen since last t
-
- if ($fontchg)
- {
- PutLine();
- $whtsz=$fontlst{$cft}->{FNT}->{spacewidth}*$cftsz;
- $stream.="/F$cft $cftsz Tf\n", $fontchg=0 if $fontchg && defined($cft);
- }
-
- $gotT=1;
-
- $stream.="% --- wht=$whtsz, pend=$pendmv, nomv=$nomove\n" if $debug;
-
-# if ($w_flg && $#lin > -1)
-# {
-# $lin[$#lin]->[0].=' ';
-# $pendmv-=$whtsz;
-# $dontglue=1 if $pendmv==0;
-# }
-
- $wt=-$pendmv/$cftsz if $w_flg and $wt==-1;
- $pendmv-=$nomove;
- $nomove=0;
- $w_flg=0;
-
- if ($xrev)
- {
- PutLine(0) if $#lin > -1;
- MakeMatrix(1);
- $stream.="$matrix ".PutXY($xpos,$ypos)." Tm\n", $poschg=0;
- $stream.="0 Tw ";
- $stream.="($par) Tj\n";
- MakeMatrix();
- $stream.="$matrix ".PutXY($xpos,$ypos)." Tm\n", $poschg=0;
- $matrixchg=0;
- return;
- }
-
- if ($pendmv)
- {
- if ($#lin == -1)
- {
- push(@lin,[undef,-$pendmv/$cftsz]);
- }
- else
- {
- $lin[$#lin]->[1]=-$pendmv/$cftsz;
- }
-
- push(@lin,[$par,undef]);
-# $xpos+=$pendmv/$unitwidth;
- $pendmv=0
- }
- else
- {
- if ($#lin == -1)
- {
- push(@lin,[$par,undef]);
- }
- else
- {
- $lin[$#lin]->[0].=$par;
- }
- }
-}
-
-sub do_h
-{
- $pendmv+=shift;
-}
-
-sub do_H
-{
- my $par=shift;
-
- if ($mode eq 't')
- {
- PutLine();
- }
- else
- {
- $xpos+=$pendmv/$unitwidth;
- $pendmv=0;
- }
-
- my $newx=$par/$unitwidth;
- $stream.=sprintf("%.3f",$newx-$tmxpos)." 0 Td\n" if $mode eq 't';
- $tmxpos=$xpos=$newx;
- $pendmv=$nomove=0;
-}
-
-sub do_C
-{
- my $par=shift;
- my $nm;
-
- ($par,$nm)=FindChar($par);
-
- do_t($par);
- $nomove=$nm;
-}
-
-sub FindChar
-{
- my $chnm=shift;
-
- if (exists($fontlst{$cft}->{FNT}->{GNM}->{$chnm}))
- {
- my $ch=$fontlst{$cft}->{FNT}->{GNM}->{$chnm};
- return(chr($ch),$fontlst{$cft}->{FNT}->{WID}->[$ch]*$cftsz);
- }
- else
- {
- return(' ');
- }
-}
-
-sub do_c
-{
- my $par=shift;
-
- push(@ahead,substr($par,1));
- $par=substr($par,0,1);
- my $ch=ord($par);
- do_t($ch);
- $nomove=$fontlst{$cft}->{FNT}->{WID}->[$ch]*$cftsz;
-}
-
-sub do_N
-{
- my $par=shift;
-
- do_t(chr($par));
- $nomove=$fontlst{$cft}->{FNT}->{WID}->[$par]*$cftsz;
-}
-
-sub do_n
-{
- $gotT=0;
- PutLine();
- $pendmv=$nomove=0;
- $n_flg=1;
- @lin=();
- PutHotSpot($xpos) if defined($mark);
-}
diff --git a/src/devices/grops/Makefile.sub b/src/devices/grops/Makefile.sub
index 95ebd27a..e1595cb5 100644
--- a/src/devices/grops/Makefile.sub
+++ b/src/devices/grops/Makefile.sub
@@ -1,6 +1,6 @@
PROG=grops$(EXEEXT)
MAN1=grops.n
-XLIBS=$(LIBDRIVER) $(LIBGROFF) $(LIBGNU)
+XLIBS=$(LIBDRIVER) $(LIBGROFF)
MLIB=$(LIBM)
OBJS=\
ps.$(OBJEXT) \
diff --git a/src/devices/grops/grops.man b/src/devices/grops/grops.man
index 5c59ffb2..2d4ee4af 100644
--- a/src/devices/grops/grops.man
+++ b/src/devices/grops/grops.man
@@ -1,5 +1,6 @@
.ig
-Copyright (C) 1989-2006, 2008-2011
+Copyright (C) 1989-2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008,
+ 2009, 2010
Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
@@ -28,7 +29,6 @@ the original English.
.
.de FT
. if '\\*(.T'ps' .ft \\$1
-. if '\\*(.T'pdf' .ft \\$1
..
.
.
diff --git a/src/devices/grotty/tty.cpp b/src/devices/grotty/tty.cpp
index e25f934d..87654107 100644
--- a/src/devices/grotty/tty.cpp
+++ b/src/devices/grotty/tty.cpp
@@ -1,6 +1,6 @@
// -*- C++ -*-
-/* Copyright (C) 1989-2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2009-2011
+/* Copyright (C) 1989-2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
+ 2010
Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
@@ -311,8 +311,11 @@ void tty_printer::make_underline(int w)
if (!w)
warning("can't underline zero-width character");
else {
- putchar('_');
- putchar('\b');
+ int n = w / font::hor;
+ for (int i = 0; i < n; i++)
+ putchar('_');
+ for (int j = 0; j < n; j++)
+ putchar('\b');
}
}
else {
@@ -334,8 +337,10 @@ void tty_printer::make_bold(output_character c, int w)
if (!w)
warning("can't print zero-width character in bold");
else {
+ int n = w / font::hor;
put_char(c);
- putchar('\b');
+ for (int i = 0; i < n; i++)
+ putchar('\b');
}
}
else {