texlive/source-luatex.dif

9937 lines
359 KiB
Plaintext

--- texk/web2c/luatexdir/ChangeLog
+++ texk/web2c/luatexdir/ChangeLog 2011-10-13 07:39:33.000000000 +0000
@@ -1,4 +1,34 @@
+2011-10-04 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * am/libluatex.am: Avoid to `clean' ../mplibdir/lmplib.c.
+
+ * am/txt2zlib.am (noinst_PROGRAMS): Conditionally add txt2zlib,
+ such that txt2zlib$(EXEEXT) gets cleaned.
+
+2011-09-30 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * tex/printing.w (print_file_line): Bug fix: avoid uninitialized
+ lineno - from ../tex.ch.
+ * tex/inputstack.w: Slightly reformulate printing of current
+ line - from ../etexdir/etex.ch.
+
+2011-08-04 Magnus Granberg <zorry@gentoo.org>
+
+ * luatex.c: Do not #include empty file <kpathsea/recorder.h>.
+
+2011-06-17 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Reduce memory leaks.
+ * lua/lkpselib.c (do_lua_kpathsea_lookup): Free string no longer
+ used.
+
+2011-06-16 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ lua/lkpselib.c (find_dpi): Allow find_suffix() to return a
+ const string.
+
2011-05-19 Taco Hoekwater <taco@luatex.org>
+
* lua/ltexlib.c: fix a bug on negative catcode table arguments.
* luatex.c, NEWS: luatex is now version 0.70.1
* luatex_svnversion.h: updated to reflect latest luatex revision (4277)
--- texk/web2c/luatexdir/Makefile.in
+++ texk/web2c/luatexdir/Makefile.in 2011-10-13 07:39:33.000000000 +0000
@@ -0,0 +1,149 @@
+# Makefile for luatex.
+# Public domain.
+# $Id: Makefile.in 4214 2011-04-27 21:53:38Z hhenkel $
+
+kpse_include ../make/common.mk
+kpse_include ../make/programs.mk
+kpse_include ../make/library.mk
+
+kpathsea_srcdir_parent = $(srcdir)/../..
+kpathsea_dir_parent = ../..
+
+ALL_CXXFLAGS = @CXXFLAGS@ @DEFS@ $(XXCFLAGS) \
+ -I. -I$(srcdir) \
+ -I$(kpathsea_dir_parent) -I$(kpathsea_srcdir_parent) \
+ @LIBXPDFCPPFLAGS@ \
+ -I$(LIBOBSDCOMPATDIR) -I$(LIBOBSDCOMPATDIR)/.. \
+ -I$(LIBOBSDCOMPATFSRCDIR) -I$(LIBOBSDCOMPATFSRCDIR)/.. \
+ -I$(LIBPNGSRCDIR) -I$(ZLIBSRCDIR) \
+ -DPDF_PARSER_ONLY -DDISABLE_OUTLINE -I../../../../src/libs/obsdcompat
+CXX = @CXX@
+
+CTANGLE = ../ctangle
+
+.SUFFIXES: .cc .o
+.cc.o:
+ $(CXX) $(ALL_CXXFLAGS) -c $< -o $@
+
+# XCFLAGS=-Wstrict-prototypes -Wmissing-prototypes
+
+LIBPNGDIR=../../../libs/libpng
+LIBPNGSRCDIR=$(srcdir)/$(LIBPNGDIR)
+
+ZLIBDIR=../../../libs/zlib
+ZLIBSRCDIR=$(srcdir)/$(ZLIBDIR)
+
+LIBXPDFDIR=../../../libs/xpdf
+LIBXPDFSRCDIR=$(srcdir)/$(LIBXPDFDIR)
+
+LIBMD5DIR=../../../libs/md5
+LIBMD5SRCDIR=$(srcdir)/$(LIBMD5DIR)
+
+LIBOBSDCOMPATDIR=../../../libs/obsdcompat
+LIBOBSDCOMPATSRCDIR=$(srcdir)/$(LIBOBSDCOMPATDIR)
+
+XCPPFLAGS=-I.. -I$(srcdir)/.. -I../.. -I$(srcdir)/../.. -I$(LIBMD5DIR) \
+ -I$(LIBMD5SRCDIR) @LIBPNGCPPFLAGS@ @ZLIBCPPFLAGS@ \
+ -I$(LIBXPDFDIR) -I$(LIBXPDFDIR)/.. -I$(LIBXPDFSRCDIR) -I$(LIBXPDFSRCDIR)/.. \
+ -I$(LIBOBSDCOMPATDIR) -I$(LIBOBSDCOMPATDIR)/.. -I$(LIBOBSDCOMPATSRCDIR) \
+ -I$(LIBOBSDCOMPATSRCDIR)/.. -DpdfTeX
+
+
+OBJS = \
+font/mapfile.o \
+font/pkin.o \
+font/subfont.o \
+font/tounicode.o \
+font/vfpacket.o \
+font/writeenc.o \
+font/writefont.o \
+font/writet1.o \
+font/writet3.o \
+font/writettf.o \
+font/writetype0.o \
+font/writetype2.o \
+font/writecff.o \
+font/tt_glyf.o \
+font/tt_table.o \
+font/sfnt.o \
+font/texfont.o \
+font/tfmofm.o \
+font/vfovf.o \
+font/luafont.o \
+font/dofont.o \
+image/pdftoepdf.o \
+image/writeimg.o \
+image/writejbig2.o \
+image/writejpg.o \
+image/writepng.o \
+lua/loslibext.o \
+lua/lcallbacklib.o \
+lua/lkpselib.o \
+lua/llualib.o \
+lua/lnodelib.o \
+lua/lpdflib.o \
+lua/lstatslib.o \
+lua/ltexiolib.o \
+lua/ltexlib.o \
+lua/ltokenlib.o \
+lua/lfontlib.o \
+lua/texluac.o \
+lua/luainit.o \
+lua/luastuff.o \
+lua/luatex.o \
+lua/luatoken.o \
+lua/luanode.o \
+lua/llanglib.o \
+lua/limglib.o \
+lua/luagen.o \
+lang/hnjalloc.o \
+lang/hyphen.o \
+lang/texlang.o \
+ocp/readocp.o \
+pdf/pdfpage.o \
+pdf/pdfpagetree.o \
+tex/linebreak.o \
+tex/postlinebreak.o \
+tex/texnodes.o \
+tex/textoken.o \
+tex/texpdf.o \
+tex/math.o \
+tex/mlist.o \
+tex/primitive.o \
+tex/texdeffont.o \
+tex/filename.o \
+managed-sa.o \
+mathcodes.o \
+textcodes.o \
+utils/avl.o \
+utils/avlstuff.o \
+utils/utils.o \
+utils/writezip.o \
+utils/synctex.o
+
+all: libpdf.a makecpool
+
+libpdf.a: $(OBJS)
+ rm -f $@
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+ $(RANLIB) $@
+
+makecpool: makecpool.o
+ $(link_command) makecpool.o
+
+kpse_include ../make/clean.mk
+
+clean::
+ rm -f libpdf.a
+
+depend:
+ rm -f $(OBJS) $(srcdir)/depend.mk
+ for a in $(OBJS); do \
+ env XXCFLAGS="-MM -MT \$$@" XCFLAGS="-MM -MT \$$@" $(MAKE) -k $$a; \
+ touch $$a; \
+ grep -a -v "^$(CC)\|$(CXX)\|$(AR)\|make" $$a | \
+ sed 's: [^ ]*/\.\./libs/[^ ]*::g' >> $(srcdir)/depend.mk; \
+ done; \
+ rm -f $(OBJS)
+
+kpse_include luatexdir/depend.mk
--- texk/web2c/luatexdir/luatex.c
+++ texk/web2c/luatexdir/luatex.c 2011-10-13 07:39:33.000000000 +0000
@@ -15,16 +15,16 @@
#include "luatex_svnversion.h"
static const char _svn_version[] =
- "$Id: luatex.c 4276 2011-05-19 05:11:57Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.70.1/source/texk/web2c/luatexdir/luatex.c $";
+ "$Id: luatex.c 4356 2011-10-05 21:59:13Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/luatex.c $";
#define TeX
int luatex_svn = luatex_svn_revision;
-int luatex_version = 70; /* \.{\\luatexversion} */
-int luatex_revision = '1'; /* \.{\\luatexrevision} */
+int luatex_version = 71; /* \.{\\luatexversion} */
+int luatex_revision = '0'; /* \.{\\luatexrevision} */
int luatex_date_info = -extra_version_info; /* the compile date is negated */
-const char *luatex_version_string = "beta-0.70.1";
+const char *luatex_version_string = "beta-0.71.0";
const char *engine_name = "luatex"; /* the name of this engine */
#include <kpathsea/c-ctype.h>
@@ -32,7 +32,6 @@ const char *engine_name = "luatex";
#include <kpathsea/readable.h>
#include <kpathsea/variable.h>
#include <kpathsea/absolute.h>
-#include <kpathsea/recorder.h>
#ifdef WIN32
#include <kpathsea/concatn.h>
#endif
--- texk/web2c/luatexdir/ptexlib.h
+++ texk/web2c/luatexdir/ptexlib.h 2011-10-13 07:39:33.000000000 +0000
@@ -1,7 +1,7 @@
/* ptexlib.h
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -37,7 +37,6 @@ extern double rint(double x);
extern char **suffixlist; /* in luainit.w */
# endif
-
/* Replicate these here. They are hardcoded anyway */
# define eTeX_version_string "2.2" /* current \eTeX\ version */
@@ -47,7 +46,7 @@ extern char **suffixlist; /* in lu
# define Omega_version_string "1.15" /* \.{\\OmegaVersion} */
# define Omega_version 1 /* \.{\\Omegaversion} */
-# define Omega_minor_version 15 /* \.{\\Omegaminorversion} */
+# define Omega_minor_version 15/* \.{\\Omegaminorversion} */
# define Omega_revision ".15" /* \.{\\Omegarevision} */
# define Aleph_version_string "0.0" /* \.{\\AlephVersion} */
@@ -67,7 +66,8 @@ extern char **suffixlist; /* in lu
/* Not all systems define it. */
# ifndef M_PI
-# define M_PI 3.14159265358979323846 /* pi */
+# define M_PI 3.14159265358979323846
+ /* pi */
# endif
# ifdef WIN32
@@ -174,7 +174,7 @@ size_t T##_limit
# include "image/writeimg.h"
# include "openbsd-compat.h"
# include "dvi/dvigen.h"
-# include "pdf/pagetree.h"
+# include "pdf/pdfpagetree.h"
# include "pdf/pdfgen.h"
# include "pdf/pdfpage.h"
# include "pdf/pdftables.h"
@@ -333,6 +333,7 @@ typedef enum {
find_pk_file_callback, read_pk_file_callback,
show_error_hook_callback,
process_input_buffer_callback, process_output_buffer_callback,
+ process_jobname_callback,
start_page_number_callback, stop_page_number_callback,
start_run_callback, stop_run_callback,
define_font_callback,
@@ -420,7 +421,7 @@ extern void topenin(void);
extern str_number getjobname(str_number);
extern str_number makefullnamestring(void);
-#include <kpathsea/version.h>
+# include <kpathsea/version.h>
extern PDF static_pdf;
--- texk/web2c/luatexdir/am/libluatex.am
+++ texk/web2c/luatexdir/am/libluatex.am 2011-10-13 07:39:28.000000000 +0000
@@ -1,6 +1,6 @@
## texk/web2c/luatexdir/am/libluatex.am: Makefile fragment for libluatex.
##
-## Copyright (C) 2009 - 2011 Peter Breitenlohner <tex-live@tug.org>
+## Copyright (C) 2009-2011 Peter Breitenlohner <tex-live@tug.org>
## You may freely use, modify and/or distribute this file.
## libluatex
@@ -210,8 +210,8 @@ libluatex_a_SOURCES += \
##
luatex_pdf_ctangle = CWEBINPUTS=$(srcdir)/luatexdir/pdf $(ctangle)
-pagetree.c: ctangle$(EXEEXT) luatexdir/pdf/pagetree.w
- $(luatex_pdf_ctangle) pagetree.w
+pdfpagetree.c: ctangle$(EXEEXT) luatexdir/pdf/pdfpagetree.w
+ $(luatex_pdf_ctangle) pdfpagetree.w
pdfaction.c: ctangle$(EXEEXT) luatexdir/pdf/pdfaction.w
$(luatex_pdf_ctangle) pdfaction.w
pdfannot.c: ctangle$(EXEEXT) luatexdir/pdf/pdfannot.w
@@ -257,7 +257,7 @@ pdfthread.c: ctangle$(EXEEXT) luatexdir/
pdfxform.c: ctangle$(EXEEXT) luatexdir/pdf/pdfxform.w
$(luatex_pdf_ctangle) pdfxform.w
-libluatex_web += luatexdir/pdf/pagetree.w luatexdir/pdf/pdfaction.w luatexdir/pdf/pdfannot.w
+libluatex_web += luatexdir/pdf/pdfpagetree.w luatexdir/pdf/pdfaction.w luatexdir/pdf/pdfannot.w
libluatex_web += luatexdir/pdf/pdfcolorstack.w luatexdir/pdf/pdfdest.w
libluatex_web += luatexdir/pdf/pdffont.w luatexdir/pdf/pdfgen.w luatexdir/pdf/pdfglyph.w
libluatex_web += luatexdir/pdf/pdfimage.w luatexdir/pdf/pdflink.w luatexdir/pdf/pdflistout.w
@@ -267,13 +267,13 @@ libluatex_web += luatexdir/pdf/pdfsavere
libluatex_web += luatexdir/pdf/pdfshipout.w luatexdir/pdf/pdftables.w
libluatex_web += luatexdir/pdf/pdfthread.w luatexdir/pdf/pdfxform.w
-nodist_libluatex_a_SOURCES += pagetree.c pdfaction.c pdfannot.c pdfcolorstack.c pdfdest.c pdffont.c
+nodist_libluatex_a_SOURCES += pdfpagetree.c pdfaction.c pdfannot.c pdfcolorstack.c pdfdest.c pdffont.c
nodist_libluatex_a_SOURCES += pdfgen.c pdfglyph.c pdfimage.c pdflink.c pdflistout.c pdfliteral.c
nodist_libluatex_a_SOURCES += pdfluaapi.c pdfobj.c pdfoutline.c pdfpage.c pdfrule.c pdfsaverestore.c
nodist_libluatex_a_SOURCES += pdfsetmatrix.c pdfshipout.c pdftables.c pdfthread.c pdfxform.c
libluatex_a_SOURCES += \
- luatexdir/pdf/pagetree.h \
+ luatexdir/pdf/pdfpagetree.h \
luatexdir/pdf/pdfaction.h \
luatexdir/pdf/pdfannot.h \
luatexdir/pdf/pdfcolorstack.h \
@@ -481,9 +481,9 @@ libluatex_a_SOURCES += \
synctexdir/synctex.c \
synctexdir/synctex.h
-## from mplibdir
+## from ../mplibdir
##
-nodist_libluatex_a_SOURCES += \
+libluatex_a_SOURCES += \
mplibdir/lmplib.c
$(libluatex_a_OBJECTS): libff.a libmplib.a
--- texk/web2c/luatexdir/am/txt2zlib.am
+++ texk/web2c/luatexdir/am/txt2zlib.am 2011-10-13 07:39:28.000000000 +0000
@@ -3,6 +3,11 @@
## Copyright (C) 2010, 2011 Hartmut Henkel <hartmut@luatex.org>
## You may freely use, modify and/or distribute this file.
+if LUATEX
+if !cross
+noinst_PROGRAMS += txt2zlib
+endif !cross
+endif LUATEX
EXTRA_PROGRAMS += txt2zlib
nodist_txt2zlib_SOURCES = txt2zlib.c
--- texk/web2c/luatexdir/dvi/dvigen.h
+++ texk/web2c/luatexdir/dvi/dvigen.h 2011-10-13 07:39:27.000000000 +0000
@@ -175,7 +175,6 @@ this is essentially the depth of |push|
extern scaled_whd rule;
extern scaledpos dvi;
-extern scaledpos cur_page_size; /* width and height of page being shipped */
extern void expand_macros_in_tokenlist(halfword p);
extern void write_out(halfword p);
--- texk/web2c/luatexdir/dvi/dvigen.w
+++ texk/web2c/luatexdir/dvi/dvigen.w 2011-10-13 07:39:27.000000000 +0000
@@ -1040,8 +1040,6 @@ void prune_movements(int l)
scaledpos dvi; /* a \.{DVI} position in page coordinates, in sync with DVI file */
-scaledpos cur_page_size;
-
@ When |hlist_out| is called, its duty is to output the box represented
by the |hlist_node| pointed to by |temp_ptr|. The reference point of that
box has coordinates |(cur.h,cur.v)|.
--- texk/web2c/luatexdir/font/luafont.w
+++ texk/web2c/luatexdir/font/luafont.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% luafont.w
%
-% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
%
% This file is part of LuaTeX.
%
@@ -570,16 +570,29 @@ static int count_hash_items(lua_State *
@ @c
#define streq(a,b) (strcmp(a,b)==0)
-#define append_packet(k) { cpackets[np++] = (eight_bits)(k); }
+#define append_packet(k) { *(cp++) = (eight_bits) (k); }
-#define do_store_four(l) { \
- append_packet((l&0xFF000000)>>24); \
- append_packet((l&0x00FF0000)>>16); \
- append_packet((l&0x0000FF00)>>8); \
- append_packet((l&0x000000FF)); }
+#define do_store_four(l) { \
+ append_packet((l & 0xFF000000) >> 24); \
+ append_packet((l & 0x00FF0000) >> 16); \
+ append_packet((l & 0x0000FF00) >> 8); \
+ append_packet((l & 0x000000FF)); \
+}
-/*
-*/
+@ @c
+static void append_float(eight_bits ** cpp, float a)
+{
+ unsigned int i;
+ eight_bits *cp = *cpp;
+ union U {
+ float a;
+ eight_bits b[sizeof(float)];
+ } u;
+ u.a = a;
+ for (i = 0; i < sizeof(float); i++)
+ append_packet(u.b[i]);
+ *cpp = cp;
+}
#define lua_roundnumber(a,b) (int)floor((double)lua_tonumber(L,-1)+0.5)
@@ -757,6 +770,8 @@ make_luaS_index(horiz_variants);
make_luaS_index(vert_variants);
make_luaS_index(mathkern);
make_luaS_index(commands);
+make_luaS_index(scale);
+make_luaS_index(lua);
static void init_font_string_pointers(lua_State * L)
{
@@ -817,7 +832,8 @@ static void init_font_string_pointers(lu
init_luaS_index(vert_variants);
init_luaS_index(mathkern);
init_luaS_index(commands);
-
+ init_luaS_index(scale);
+ init_luaS_index(lua);
}
static int count_char_packet_bytes(lua_State * L)
@@ -849,10 +865,12 @@ static int count_char_packet_bytes(lua_S
l++;
} else if (luaS_ptr_eq(s, rule)) {
l += 9;
- } else if (luaS_ptr_eq(s, right) ||
- luaS_ptr_eq(s, node) || luaS_ptr_eq(s, down)) {
+ } else if (luaS_ptr_eq(s, right) || luaS_ptr_eq(s, node)
+ || luaS_ptr_eq(s, down) || luaS_ptr_eq(s, image)) {
l += 5;
- } else if (luaS_ptr_eq(s, special)) {
+ } else if (luaS_ptr_eq(s, scale)) {
+ l += sizeof(float) + 1;
+ } else if (luaS_ptr_eq(s, special) || luaS_ptr_eq(s, lua)) {
size_t len;
lua_rawgeti(L, -2, 2);
if (lua_isstring(L, -1)) {
@@ -860,13 +878,11 @@ static int count_char_packet_bytes(lua_S
lua_pop(L, 1);
if (len > 0) {
l = (int) (l + 5 + (int) len);
- }
+ }
} else {
lua_pop(L, 1);
fprintf(stdout, "invalid packet special!\n");
}
- } else if (luaS_ptr_eq(s, image)) {
- l += 5;
} else {
fprintf(stdout, "unknown packet command %s!\n", s);
}
@@ -880,8 +896,6 @@ static int count_char_packet_bytes(lua_S
return l;
}
-
-
static scaled sp_to_dvi(halfword sp, halfword atsize)
{
double result, mult;
@@ -898,9 +912,8 @@ read_char_packets(lua_State * L, int *l_
size_t l;
int cmd;
const char *s;
- eight_bits *cpackets;
+ eight_bits *cpackets, *cp;
int ff = 0;
- int np = 0;
int max_f = 0;
int pc = count_char_packet_bytes(L);
if (pc <= 0)
@@ -910,7 +923,7 @@ read_char_packets(lua_State * L, int *l_
while (l_fonts[(max_f + 1)] != 0)
max_f++;
- cpackets = xmalloc((unsigned) (pc + 1));
+ cp = cpackets = xmalloc((unsigned) (pc + 1));
for (i = 1; i <= (int) lua_objlen(L, -1); i++) {
lua_rawgeti(L, -1, i);
if (lua_istable(L, -1)) {
@@ -958,6 +971,10 @@ read_char_packets(lua_State * L, int *l_
cmd = packet_special_code;
} else if (luaS_ptr_eq(s, image)) {
cmd = packet_image_code;
+ } else if (luaS_ptr_eq(s, scale)) {
+ cmd = packet_scale_code;
+ } else if (luaS_ptr_eq(s, lua)) {
+ cmd = packet_lua_code;
}
switch (cmd) {
@@ -1006,6 +1023,7 @@ read_char_packets(lua_State * L, int *l_
lua_pop(L, 2);
break;
case packet_special_code:
+ case packet_lua_code:
append_packet(cmd);
lua_rawgeti(L, -2, 2);
s = luaL_checklstring(L, -1, &l);
@@ -1037,6 +1055,12 @@ read_char_packets(lua_State * L, int *l_
break;
case packet_nop_code:
break;
+ case packet_scale_code:
+ append_packet(cmd);
+ lua_rawgeti(L, -2, 2);
+ append_float(&cp, (float) luaL_checknumber(L, -1));
+ lua_pop(L, 1);
+ break;
default:
fprintf(stdout,
"Unknown char packet code %s (char %d in font %s)\n",
@@ -1056,7 +1080,6 @@ read_char_packets(lua_State * L, int *l_
return;
}
-
@ @c
static void read_lua_cidinfo(lua_State * L, int f)
{
@@ -1478,7 +1501,7 @@ font_char_from_lua(lua_State * L, intern
-@ The caller has to fix the state of the lua stack when there is an error!
+@ The caller has to fix the state of the lua stack when there is an error!
@c
int font_from_lua(lua_State * L, int f)
@@ -2194,7 +2217,7 @@ static halfword handle_lig_word(halfword
return cur;
}
-@ Return value is the new tail, head should be a dummy
+@ Return value is the new tail, head should be a dummy
@c
halfword handle_ligaturing(halfword head, halfword tail)
--- texk/web2c/luatexdir/font/luatexfont.h
+++ texk/web2c/luatexdir/font/luatexfont.h 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
/* luatexfont.h --- General font definitions
- Copyright 2008-2010 Taco Hoekwater <taco@luatex.org>
+ Copyright 2008-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -150,6 +150,10 @@ void replace_packet_fonts(internal_font_
int *new_fontid, int count);
int *packet_local_fonts(internal_font_number f, int *num);
+int packet_cur_s; /* current |do_vf_packet()| recursion level */
+int packet_stack_ptr; /* pointer into |packet_stack| */
+vf_struct *new_vfstruct(void);
+
/* writecff.c */
void writetype1w(PDF pdf, fd_entry * fd);
--- texk/web2c/luatexdir/font/texfont.h
+++ texk/web2c/luatexdir/font/texfont.h 2011-10-13 07:39:33.000000000 +0000
@@ -599,7 +599,9 @@ typedef enum { packet_char_code,
packet_rule_code,
packet_node_code,
packet_nop_code,
- packet_end_code
+ packet_end_code,
+ packet_scale_code,
+ packet_lua_code,
} packet_command_codes;
extern scaled store_scaled_f(scaled sq, int fw);
--- texk/web2c/luatexdir/font/tounicode.w
+++ texk/web2c/luatexdir/font/tounicode.w 2011-10-13 07:39:33.000000000 +0000
@@ -343,8 +343,11 @@ int write_tounicode(PDF pdf, char **glyp
else
strcat(buf, builtin_suffix); /* ".enc" not present, this is a builtin
encoding so the name is eg "cmr10-builtin" */
- objnum = pdf_new_objnum(pdf);
- pdf_begin_dict(pdf, objnum, 0);
+ objnum = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, objnum, OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
pdf_printf(pdf, "%%!PS-Adobe-3.0 Resource-CMap\n"@/
"%%%%DocumentNeededResources: ProcSet (CIDInit)\n"@/
@@ -467,6 +470,7 @@ int write_tounicode(PDF pdf, char **glyp
"CMapName currentdict /CMap defineresource pop\n"
"end\n" "end\n" "%%%%EndResource\n" "%%%%EOF\n");
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
return objnum;
}
@@ -487,8 +491,11 @@ int write_cid_tounicode(PDF pdf, fo_entr
(fo->fd->subset_tag != NULL ? fo->fd->subset_tag : "UCS"),
fo->fd->fontname);
- objnum = pdf_new_objnum(pdf);
- pdf_begin_dict(pdf, objnum, 0);
+ objnum = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, objnum, OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
pdf_printf(pdf, "%%!PS-Adobe-3.0 Resource-CMap\n"@/
"%%%%DocumentNeededResources: ProcSet (CIDInit)\n"@/
@@ -624,5 +631,6 @@ int write_cid_tounicode(PDF pdf, fo_entr
"CMapName currentdict /CMap defineresource pop\n"
"end\n" "end\n" "%%%%EndResource\n" "%%%%EOF\n");
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
return objnum;
}
--- texk/web2c/luatexdir/font/vfpacket.w
+++ texk/web2c/luatexdir/font/vfpacket.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,224 +1,254 @@
% vfpacket.w
-
+%
% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
-
+%
% This file is part of LuaTeX.
-
+%
% LuaTeX 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 2 of the License, or (at your
% option) any later version.
-
+%
% LuaTeX 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 Lesser General Public
% License for more details.
-
+%
% You should have received a copy of the GNU General Public License along
% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
@ @c
-#include "ptexlib.h"
-
static const char _svn_version[] =
- "$Id: vfpacket.w 4098 2011-04-07 21:01:11Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/font/vfpacket.w $";
-
-
-@ The |do_vf_packet| procedure is called in order to interpret the
- character packet for a virtual character. Such a packet may contain
- the instruction to typeset a character from the same or an other
- virtual font; in such cases |do_vf_packet| calls itself
- recursively. The recursion level, i.e., the number of times this has
- happened, is kept in the global variable |packet_cur_s| and should
- not exceed |packet_max_recursion|.
-
-@c
-#define packet_max_recursion 100
-
-typedef unsigned char packet_stack_index; /* an index into the stack */
-
-typedef struct packet_stack_record {
- scaled stack_h;
- scaled stack_v;
-} packet_stack_record;
-
-
-static packet_stack_index packet_cur_s = 0; /* current recursion level */
-static packet_stack_record packet_stack[packet_max_recursion];
-static packet_stack_index packet_stack_ptr = 0; /* pointer into |packet_stack| */
+ "$Id: vfpacket.w 4341 2011-07-28 21:24:31Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/vfpacket.w $";
+#include "ptexlib.h"
-@ Some macros for processing character packets.
+@ Some macros for processing character packets.
@c
-#define do_packet_byte() vf_packets[cur_packet_byte++]
+#define packet_number(fw) { \
+ fw = *(vfp++); \
+ fw = fw * 256 + *(vfp++); \
+ fw = fw * 256 + *(vfp++); \
+ fw = fw * 256 + *(vfp++); \
+}
-#define packet_number(fw) { \
- fw = do_packet_byte(); \
- fw = fw*256 + do_packet_byte(); \
- fw = fw*256 + do_packet_byte(); \
- fw = fw*256 + do_packet_byte(); }
-
-#define packet_scaled(a,fs) { int fw; \
- fw = do_packet_byte(); \
- if (fw>127) fw = fw - 256; \
- fw = fw*256 + do_packet_byte(); \
- fw = fw*256 + do_packet_byte(); \
- fw = fw*256 + do_packet_byte(); \
- a = store_scaled_f(fw, fs); }
+#define packet_scaled(a, fs) { \
+ int fw; \
+ fw = *(vfp++); \
+ if (fw > 127) \
+ fw = fw - 256; \
+ fw = fw * 256 + *(vfp++); \
+ fw = fw * 256 + *(vfp++); \
+ fw = fw * 256 + *(vfp++); \
+ a = store_scaled_f(fw, fs); \
+}
+@ @c
+vf_struct *new_vfstruct(void)
+{
+ vf_struct *vp = (vf_struct *) xmalloc(sizeof(vf_struct));
+ vp->packet_stack_level = vp->packet_stack_minlevel = 0;
+ vp->packet_stack =
+ (packet_stack_record *) xmalloc(packet_stack_size *
+ sizeof(packet_stack_record));
+ vp->lf = 0;
+ vp->fs_f = 0;
+ vp->packet_cur_s = 0;
+ vp->refpos = NULL;
+ vp->vflua = false;
+ return vp;
+}
-@ count the number of bytes in a command packet
+@ Count the number of bytes in a command packet.
@c
int vf_packet_bytes(charinfo * co)
{
- eight_bits *vf_packets;
- int cur_packet_byte;
+ eight_bits *vf_packets, *vfp;
unsigned k;
int cmd;
- vf_packets = get_charinfo_packets(co);
+ vfp = vf_packets = get_charinfo_packets(co);
if (vf_packets == NULL) {
return 0;
}
- cur_packet_byte = 0;
- while ((cmd = vf_packets[cur_packet_byte]) != packet_end_code) {
- cur_packet_byte++;
+ while ((cmd = *(vfp++)) != packet_end_code) {
switch (cmd) {
+ case packet_nop_code:
+ case packet_pop_code:
+ case packet_push_code:
+ break;
case packet_char_code:
- case packet_font_code:
- case packet_right_code:
case packet_down_code:
+ case packet_font_code:
+ case packet_image_code:
case packet_node_code:
- cur_packet_byte += 4;
- break;
- case packet_push_code:
- case packet_pop_code:
+ case packet_right_code:
+ vfp += 4;
break;
case packet_rule_code:
- cur_packet_byte += 8;
+ vfp += 8;
break;
case packet_special_code:
packet_number(k); /* +4 */
- cur_packet_byte = (cur_packet_byte + (int) k);
- break;
- case packet_image_code:
- cur_packet_byte += 4;
- break;
- case packet_nop_code:
+ vfp += (int) k;
break;
default:
pdf_error("vf", "invalid DVI command (1)");
}
};
- return (cur_packet_byte + 1);
+ return (vfp - vf_packets);
}
-
-@ typeset the \.{DVI} commands in the
- character packet for character |c| in current font |f|
+@ Typeset the \.{DVI} commands in the character packet
+ for character |c| in current font |f|.
@c
const char *packet_command_names[] = {
"char", "font", "pop", "push", "special", "image",
- "right", "down", "rule", "node", "nop", "end", NULL
+ "right", "down", "rule", "node", "nop", "end", "scale", "lua", NULL
};
+@ @c
+static float packet_float(eight_bits ** vfpp)
+{
+ unsigned int i;
+ union U {
+ float a;
+ eight_bits b[sizeof(float)];
+ } u;
+ eight_bits *vfp = *vfpp;
+ for (i = 0; i < sizeof(float); i++)
+ u.b[i] = *(vfp++);
+ *vfpp = vfp;
+ return u.a;
+}
+@ The |do_vf_packet| procedure is called in order to interpret the
+ character packet for a virtual character. Such a packet may contain
+ the instruction to typeset a character from the same or an other
+ virtual font; in such cases |do_vf_packet| calls itself
+ recursively. The recursion level, i.e., the number of times this has
+ happened, is kept in the global variable |packet_cur_s| and should
+ not exceed |packet_max_recursion|.
+@c
void do_vf_packet(PDF pdf, internal_font_number vf_f, int c)
{
- internal_font_number lf;
- charinfo *co;
- scaledpos cur = { 0, 0 }, size;
- eight_bits *vf_packets;
- int cur_packet_byte;
- int cmd, fs_f;
- scaled i;
+ eight_bits *vfp;
+ posstructure *save_posstruct, localpos;
+ vf_struct *save_vfstruct, localvfstruct, *vp;
+ int cmd;
unsigned k;
+ scaledpos size;
+ scaled i;
str_number s;
+ float f;
+ packet_stack_record *mat_p;
- posstructure localpos; /* the position structure local within this function */
- posstructure *refpos; /* the list origin pos. on the page, provided by the caller */
-
- lf = 0; /* for -Wall */
- packet_cur_s++;
- if (packet_cur_s >= packet_max_recursion)
- overflow("max level recursion of virtual fonts", packet_max_recursion);
- co = get_charinfo(vf_f, c);
- vf_packets = get_charinfo_packets(co);
- if (vf_packets == NULL) {
- packet_cur_s--;
- return;
- }
+ vfp = get_charinfo_packets(get_charinfo(vf_f, c));
+ assert(vfp != NULL);
- refpos = pdf->posstruct;
+ save_posstruct = pdf->posstruct;
pdf->posstruct = &localpos; /* use local structure for recursion */
- localpos.pos = refpos->pos;
+ localpos.pos = save_posstruct->pos;
localpos.dir = dir_TLT; /* invariably for vf */
- cur_packet_byte = 0;
- fs_f = font_size(vf_f);
- while ((cmd = vf_packets[cur_packet_byte]) != packet_end_code) {
- cur_packet_byte++;
+ save_vfstruct = pdf->vfstruct;
+ vp = pdf->vfstruct = &localvfstruct;
+ localvfstruct = *save_vfstruct;
+
+ vp->packet_stack_minlevel = ++(vp->packet_stack_level);
+ vp->lf = 0;
+ vp->fs_f = font_size(vf_f);
+ vp->packet_cur_s++;
+ if (vp->packet_cur_s == packet_max_recursion)
+ overflow("max level recursion of virtual fonts", packet_max_recursion);
+ vp->refpos = save_posstruct;
+ vp->vflua = false;
+
+ mat_p = &(vp->packet_stack[vp->packet_stack_level]);
+ mat_p->c0 = 1.0;
+ mat_p->c1 = 0.0;
+ mat_p->c2 = 0.0;
+ mat_p->c3 = 1.0;
+ mat_p->pos.h = 0;
+ mat_p->pos.v = 0;
+
+ while ((cmd = *(vfp++)) != packet_end_code) {
#ifdef DEBUG
- if (cmd>packet_end_code) {
- fprintf(stdout, "do_vf_packet(%i,%i) command code = illegal \n", vf_f,c);
- } else {
- fprintf(stdout, "do_vf_packet(%i,%i) command code = %s\n",vf_f, c, packet_command_names[cmd]);
- }
+ if (cmd > packet_end_code) {
+ fprintf(stdout, "do_vf_packet(%i,%i) command code = illegal \n",
+ vf_f, c);
+ } else {
+ fprintf(stdout, "do_vf_packet(%i,%i) command code = %s\n", vf_f, c,
+ packet_command_names[cmd]);
+ }
#endif
switch (cmd) {
case packet_font_code:
- packet_number(lf);
+ packet_number(vp->lf);
break;
case packet_push_code:
- packet_stack[packet_stack_ptr].stack_h = cur.h;
- packet_stack[packet_stack_ptr].stack_v = cur.v;
- packet_stack_ptr++;
+ vp->packet_stack_level++;
+ if (vp->packet_stack_level == packet_stack_size)
+ pdf_error("vf", "packet_stack_level overflow");
+ vp->packet_stack[vp->packet_stack_level] = *mat_p;
+ mat_p = &(vp->packet_stack[vp->packet_stack_level]);
break;
case packet_pop_code:
- packet_stack_ptr--;
- cur.h = packet_stack[packet_stack_ptr].stack_h;
- cur.v = packet_stack[packet_stack_ptr].stack_v;
+ if (vp->packet_stack_level == vp->packet_stack_minlevel)
+ pdf_error("vf", "packet_stack_level underflow");
+ vp->packet_stack_level--;
+ mat_p = &(vp->packet_stack[vp->packet_stack_level]);
break;
case packet_char_code:
packet_number(k);
- if (!char_exists(lf, (int) k)) {
- char_warning(lf, (int) k);
- } else {
- if (has_packet(lf, (int) k))
- do_vf_packet(pdf, lf, (int) k);
+ if (!char_exists(vp->lf, (int) k))
+ char_warning(vp->lf, (int) k);
+ else {
+ if (has_packet(vp->lf, (int) k))
+ do_vf_packet(pdf, vp->lf, (int) k);
else
- backend_out[glyph_node] (pdf, lf, (int) k);
+ backend_out[glyph_node] (pdf, vp->lf, (int) k);
}
- cur.h = cur.h + char_width(lf, (int) k);
+ mat_p->pos.h += char_width(vp->lf, (int) k);
break;
case packet_rule_code:
- packet_scaled(size.v, fs_f); /* height (where is depth?) */
- packet_scaled(size.h, fs_f);
+ packet_scaled(size.v, vp->fs_f); /* height (where is depth?) */
+ packet_scaled(size.h, vp->fs_f);
if (size.h > 0 && size.v > 0)
pdf_place_rule(pdf, 0, size); /* the 0 is unused */
- cur.h = cur.h + size.h;
+ mat_p->pos.h += size.h;
break;
case packet_right_code:
- packet_scaled(i, fs_f);
- cur.h = cur.h + i;
+ packet_scaled(i, vp->fs_f);
+ mat_p->pos.h += i;
break;
case packet_down_code:
- packet_scaled(i, fs_f);
- cur.v = cur.v + i;
+ packet_scaled(i, vp->fs_f);
+ mat_p->pos.v += i;
break;
case packet_special_code:
packet_number(k);
- str_room((unsigned) k);
+ str_room(k);
while (k > 0) {
k--;
- append_char(do_packet_byte());
+ append_char(*(vfp++));
}
s = make_string();
pdf_literal(pdf, s, scan_special, false);
flush_str(s);
break;
+ case packet_lua_code:
+ packet_number(k);
+ vp->vflua = true;
+ if (luaL_loadbuffer
+ (Luas, (const char *) vfp, (size_t) k, "packet_lua_code")
+ || lua_pcall(Luas, 0, LUA_MULTRET, 0))
+ lua_error(Luas);
+ vp->vflua = false;
+ vfp += k;
+ break;
case packet_image_code:
packet_number(k);
vf_out_image(pdf, k);
@@ -229,34 +259,40 @@ void do_vf_packet(PDF pdf, internal_font
break;
case packet_nop_code:
break;
+ case packet_scale_code:
+ f = packet_float(&vfp);
+ mat_p->c0 = mat_p->c0 * f;
+ mat_p->c3 = mat_p->c3 * f;
+ /* pdf->pstruct->scale = f; *//* scale is still NOP */
+ pdf->pstruct->need_tm = true;
+ pdf->pstruct->need_tf = true;
+ break;
default:
pdf_error("vf", "invalid DVI command (2)");
}
- synch_pos_with_cur(&localpos, refpos, cur); /* trivial case, always TLT */
+ synch_pos_with_cur(&localpos, save_posstruct, mat_p->pos); /* trivial case, always TLT */
}
- packet_cur_s--;
- pdf->posstruct = refpos;
+ pdf->posstruct = save_posstruct;
+ pdf->vfstruct = save_vfstruct;
}
@ @c
int *packet_local_fonts(internal_font_number f, int *num)
{
- int c, cmd, cur_packet_byte, lf, k, l, i;
+ int c, cmd, lf, k, l, i;
int localfonts[256] = { 0 };
int *lfs;
charinfo *co;
- eight_bits *vf_packets;
+ eight_bits *vf_packets, *vfp;
k = 0;
for (c = font_bc(f); c <= font_ec(f); c++) {
if (quick_char_exists(f, c)) {
co = get_charinfo(f, c);
- vf_packets = get_charinfo_packets(co);
+ vfp = vf_packets = get_charinfo_packets(co);
if (vf_packets == NULL)
continue;
- cur_packet_byte = 0;
- while ((cmd = vf_packets[cur_packet_byte]) != packet_end_code) {
- cur_packet_byte++;
+ while ((cmd = *(vfp++)) != packet_end_code) {
switch (cmd) {
case packet_font_code:
packet_number(lf);
@@ -269,26 +305,23 @@ int *packet_local_fonts(internal_font_nu
localfonts[k++] = lf;
}
break;
- case packet_push_code:
- case packet_pop_code:
case packet_nop_code:
+ case packet_pop_code:
+ case packet_push_code:
break;
case packet_char_code:
- case packet_right_code:
case packet_down_code:
+ case packet_image_code:
case packet_node_code:
- cur_packet_byte += 4;
+ case packet_right_code:
+ vfp += 4;
break;
case packet_rule_code:
- cur_packet_byte += 8;
+ vfp += 8;
break;
case packet_special_code:
packet_number(i);
- while (i-- > 0)
- (void) do_packet_byte();
- break;
- case packet_image_code:
- cur_packet_byte += 4;
+ vfp += i;
break;
default:
pdf_error("vf", "invalid DVI command (3)");
@@ -305,26 +338,22 @@ int *packet_local_fonts(internal_font_nu
return NULL;
}
-
@ @c
void
replace_packet_fonts(internal_font_number f, int *old_fontid,
int *new_fontid, int count)
{
- int c, cmd, cur_packet_byte, lf, k, l;
+ int c, cmd, lf, k, l;
charinfo *co;
- eight_bits *vf_packets;
+ eight_bits *vf_packets, *vfp;
- k = 0;
for (c = font_bc(f); c <= font_ec(f); c++) {
if (quick_char_exists(f, c)) {
co = get_charinfo(f, c);
- vf_packets = get_charinfo_packets(co);
+ vfp = vf_packets = get_charinfo_packets(co);
if (vf_packets == NULL)
continue;
- cur_packet_byte = 0;
- while ((cmd = vf_packets[cur_packet_byte]) != packet_end_code) {
- cur_packet_byte++;
+ while ((cmd = *(vfp++)) != packet_end_code) {
switch (cmd) {
case packet_font_code:
packet_number(lf);
@@ -335,36 +364,32 @@ replace_packet_fonts(internal_font_numbe
}
if (l < count) {
k = new_fontid[l];
- vf_packets[(cur_packet_byte - 4)] = (eight_bits)
+ *(vfp - 4) = (eight_bits)
((k & 0xFF000000) >> 24);
- vf_packets[(cur_packet_byte - 3)] = (eight_bits)
+ *(vfp - 3) = (eight_bits)
((k & 0x00FF0000) >> 16);
- vf_packets[(cur_packet_byte - 2)] = (eight_bits)
+ *(vfp - 2) = (eight_bits)
((k & 0x0000FF00) >> 8);
- vf_packets[(cur_packet_byte - 1)] =
- (eight_bits) (k & 0x000000FF);
+ *(vfp - 1) = (eight_bits) (k & 0x000000FF);
}
break;
- case packet_push_code:
- case packet_pop_code:
case packet_nop_code:
+ case packet_pop_code:
+ case packet_push_code:
break;
case packet_char_code:
- case packet_right_code:
case packet_down_code:
+ case packet_image_code:
case packet_node_code:
- cur_packet_byte += 4;
+ case packet_right_code:
+ vfp += 4;
break;
case packet_rule_code:
- cur_packet_byte += 8;
+ vfp += 8;
break;
case packet_special_code:
packet_number(k);
- while (k-- > 0)
- (void) do_packet_byte();
- break;
- case packet_image_code:
- cur_packet_byte += 4;
+ vfp += k;
break;
default:
pdf_error("vf", "invalid DVI command (4)");
--- texk/web2c/luatexdir/font/writecff.w
+++ texk/web2c/luatexdir/font/writecff.w 2011-10-13 07:39:33.000000000 +0000
@@ -2990,7 +2990,7 @@ static void write_fontfile(PDF pdf, cff_
cff_release_index(topdict);
for (i = 0; i < offset; i++)
- fb_putchar(pdf, dest[i]);
+ strbuf_putchar(pdf->fb, dest[i]);
xfree(dest);
return;
@@ -3168,7 +3168,7 @@ void write_cff(PDF pdf, cff_font * cffon
each (set) bit is a (present) CID. */
if (1) {
int cid;
- cidset = pdf_new_objnum(pdf);
+ cidset = pdf_create_obj(pdf, obj_type_others, 0);
if (cidset != 0) {
size_t l = (last_cid/8)+1;
char *stream = xmalloc(l);
@@ -3179,10 +3179,14 @@ void write_cff(PDF pdf, cff_font * cffon
stream[(cid / 8)] |= (1 << (7 - (cid % 8)));
}
}
- pdf_begin_dict(pdf, cidset, 0);
+ pdf_begin_obj(pdf, cidset, OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
pdf_out_block(pdf, stream, l);
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
}
}
@@ -3372,23 +3376,25 @@ void write_cid_cff(PDF pdf, cff_font * c
}
/* CIDSet: a table of bits indexed by cid, bytes with high order bit first,
- each (set) bit is a (present) CID. */
+ each (set) bit is a (present) CID. */
if (1) {
- cidset = pdf_new_objnum(pdf);
- if (cidset != 0) {
- size_t l = (last_cid/8)+1;
- char *stream = xmalloc(l);
- memset(stream, 0, l);
- for (cid = 1; cid <= (long) last_cid; cid++) {
- if (CIDToGIDMap[2 * cid] || CIDToGIDMap[2 * cid + 1]) {
- stream[(cid / 8)] |= (1 << (7 - (cid % 8)));
- }
- }
- pdf_begin_dict(pdf, cidset, 0);
- pdf_begin_stream(pdf);
- pdf_out_block(pdf, stream, l);
- pdf_end_stream(pdf);
- }
+ cidset = pdf_create_obj(pdf, obj_type_others, 0);
+ if (cidset != 0) {
+ size_t l = (last_cid / 8) + 1;
+ char *stream = xmalloc(l);
+ memset(stream, 0, l);
+ for (cid = 1; cid <= (long) last_cid; cid++) {
+ if (CIDToGIDMap[2 * cid] || CIDToGIDMap[2 * cid + 1]) {
+ stream[(cid / 8)] |= (1 << (7 - (cid % 8)));
+ }
+ }
+ pdf_begin_obj(pdf, cidset, OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_begin_stream(pdf);
+ pdf_out_block(pdf, stream, l);
+ pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
+ }
}
@@ -3551,7 +3557,7 @@ void writetype1w(PDF pdf, fd_entry * fd)
write_cff(pdf, cff, fd);
} else {
for (i = 0; i < tfm_size; i++)
- fb_putchar(pdf, tfm_buffer[i]);
+ strbuf_putchar(pdf->fb, tfm_buffer[i]);
}
fd->ff_found = 1;
} else {
--- texk/web2c/luatexdir/font/writeenc.w
+++ texk/web2c/luatexdir/font/writeenc.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,7 +1,7 @@
% writeenc.w
-%
+
% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
-% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -89,31 +89,32 @@ fe_entry *get_fe_entry(char *s)
@ @c
static void write_enc(PDF pdf, char **glyph_names, struct avl_table *tx_tree,
- int fe_objnum)
+ int fe_objnum)
{
int i_old, *p;
struct avl_traverser t;
assert(glyph_names != NULL);
assert(tx_tree != NULL);
assert(fe_objnum != 0);
- pdf_begin_dict(pdf, fe_objnum, 1);
- pdf_puts(pdf, "/Type /Encoding\n");
- pdf_puts(pdf, "/Differences [");
+ pdf_begin_obj(pdf, fe_objnum, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Encoding");
+ pdf_add_name(pdf, "Differences");
+ pdf_begin_array(pdf);
avl_t_init(&t, tx_tree);
for (i_old = -2, p = (int *) avl_t_first(&t, tx_tree); p != NULL;
p = (int *) avl_t_next(&t)) {
- if (*p == i_old + 1) /* no gap */
- pdf_printf(pdf, "/%s", glyph_names[*p]);
+ if (*p == i_old + 1) /* consecutive */
+ pdf_add_name(pdf, glyph_names[*p]);
else {
- if (i_old == -2)
- pdf_printf(pdf, "%i/%s", *p, glyph_names[*p]);
- else
- pdf_printf(pdf, " %i/%s", *p, glyph_names[*p]);
+ pdf_add_int(pdf, *p);
+ pdf_add_name(pdf, glyph_names[*p]);
}
i_old = *p;
}
- pdf_puts(pdf, "]\n");
+ pdf_end_array(pdf);
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
}
static void write_fontencoding(PDF pdf, fe_entry * fe)
@@ -135,7 +136,7 @@ void write_fontencodings(PDF pdf)
write_fontencoding(pdf, fe);
}
-@ cleaning up...
+@ cleaning up...
@c
static void destroy_fe_entry(void *pa, void *pb)
--- texk/web2c/luatexdir/font/writefont.w
+++ texk/web2c/luatexdir/font/writefont.w 2011-10-13 07:39:33.000000000 +0000
@@ -177,15 +177,16 @@ static void write_fontmetrics(PDF pdf, f
{
int i;
fix_fontmetrics(fd);
- pdf_printf(pdf, "/%s [%i %i %i %i]\n", font_key[FONTBBOX1_CODE].pdfname,
- (int) fd->font_dim[FONTBBOX1_CODE].val,
+ pdf_add_name(pdf, font_key[FONTBBOX1_CODE].pdfname);
+ pdf_begin_array(pdf);
+ pdf_printf(pdf, "%i %i %i %i", (int) fd->font_dim[FONTBBOX1_CODE].val,
(int) fd->font_dim[FONTBBOX2_CODE].val,
(int) fd->font_dim[FONTBBOX3_CODE].val,
(int) fd->font_dim[FONTBBOX4_CODE].val);
+ pdf_end_array(pdf);
for (i = 0; i < GEN_KEY_NUM; i++)
if (fd->font_dim[i].set)
- pdf_printf(pdf, "/%s %i\n", font_key[i].pdfname,
- fd->font_dim[i].val);
+ pdf_dict_add_int(pdf, font_key[i].pdfname, fd->font_dim[i].val);
}
@
@@ -200,15 +201,22 @@ static void preset_fontname(fo_entry * f
fo->fd->fontname = xstrdup(fo->fm->tfm_name);
}
-static void write_fontname(PDF pdf, fd_entry * fd, const char *key)
+static void pdf_dict_add_fontname(PDF pdf, const char *key, fd_entry * fd)
{
+ char *s;
+ size_t l1 = 0, l2;
assert(fd->fontname != NULL);
- pdf_puts(pdf, "/");
- if (key != NULL)
- pdf_printf(pdf, "%s /", key);
+ assert(key != NULL);
if (fd->subset_tag != NULL)
- pdf_printf(pdf, "%s+", fd->subset_tag);
- pdf_printf(pdf, "%s\n", fd->fontname);
+ l1 = strlen(fd->subset_tag);
+ l2 = strlen(fd->fontname);
+ s = xmalloc(l1 + l2 + 2);
+ if (l1 > 0)
+ snprintf(s, l1 + l2 + 2, "%s+%s", fd->subset_tag, fd->fontname);
+ else
+ snprintf(s, l2 + 1, "%s", fd->fontname);
+ pdf_dict_add_name(pdf, key, s);
+ xfree(s);
}
@
@@ -360,15 +368,15 @@ static void write_charwidth_array(PDF pd
struct avl_traverser t;
assert(fo->tx_tree != NULL);
assert(fo->cw_objnum == 0);
- fo->cw_objnum = pdf_new_objnum(pdf);
- pdf_begin_obj(pdf, fo->cw_objnum, 1);
+ fo->cw_objnum = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, fo->cw_objnum, OBJSTM_ALWAYS);
avl_t_init(&t, fo->tx_tree);
fip = (int *) avl_t_first(&t, fo->tx_tree);
assert(fip != NULL);
- pdf_puts(pdf, "[");
+ pdf_begin_array(pdf);
for (ip = fip, j = *ip; ip != NULL; ip = (int *) avl_t_next(&t)) {
if (ip != fip)
- pdf_puts(pdf, " ");
+ pdf_out(pdf, ' ');
i = *ip;
while (j < i - 1) {
pdf_puts(pdf, "0 ");
@@ -377,7 +385,7 @@ static void write_charwidth_array(PDF pd
j = i;
pdf_print_charwidth(pdf, f, i);
}
- pdf_puts(pdf, "]\n");
+ pdf_end_array(pdf);
pdf_end_obj(pdf);
}
@@ -440,30 +448,35 @@ static void write_fontfile(PDF pdf, fd_e
if (!fd->ff_found)
return;
assert(fd->ff_objnum == 0);
- fd->ff_objnum = pdf_new_objnum(pdf);
- pdf_begin_dict(pdf, fd->ff_objnum, 0); /* font file stream */
+ fd->ff_objnum = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, fd->ff_objnum, OBJSTM_NEVER); /* font file stream */
+ pdf_begin_dict(pdf);
if (is_cidkeyed(fd->fm)) {
/* No subtype is used for TrueType-based OpenType fonts */
if (is_opentype(fd->fm) || is_type1(fd->fm))
- pdf_puts(pdf, "/Subtype /CIDFontType0C\n");
+ pdf_dict_add_name(pdf, "Subtype", "CIDFontType0C");
#if 0
- else
- pdf_puts(pdf,"/Subtype /OpenType\n");
+ else
+ pdf_dict_add_name(pdf, "Subtype", "OpenType");
#endif
} else {
- if (is_type1(fd->fm))
- pdf_printf(pdf, "/Length1 %i\n/Length2 %i\n/Length3 %i\n",
- (int) t1_length1, (int) t1_length2, (int) t1_length3);
- else if (is_truetype(fd->fm))
- pdf_printf(pdf, "/Length1 %i\n", (int) ttf_length);
+ if (is_type1(fd->fm)) {
+ pdf_dict_add_int(pdf, "Length1", (int) t1_length1);
+ pdf_dict_add_int(pdf, "Length2", (int) t1_length2);
+ pdf_dict_add_int(pdf, "Length3", (int) t1_length3);
+ } else if (is_truetype(fd->fm))
+ pdf_dict_add_int(pdf, "Length1", (int) ttf_length);
else if (is_opentype(fd->fm))
- pdf_puts(pdf, "/Subtype /Type1C\n");
+ pdf_dict_add_name(pdf, "Subtype", "Type1C");
else
assert(0);
}
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
- fb_flush(pdf);
+ strbuf_flush(pdf, pdf->fb);
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
}
@
@@ -495,14 +508,15 @@ static void write_fontdescriptor(PDF pdf
struct avl_traverser t;
int fd_flags;
assert(fd != NULL && fd->fm != NULL);
- cidset = 0; /* possibly updated by |write_fontfile| */
+ cidset = 0; /* possibly updated by |write_fontfile| */
if (is_fontfile(fd->fm) && is_included(fd->fm))
write_fontfile(pdf, fd); /* this will set |fd->ff_found| if font file is found */
if (fd->fd_objnum == 0)
- fd->fd_objnum = pdf_new_objnum(pdf);
- pdf_begin_dict(pdf, fd->fd_objnum, 1);
- pdf_puts(pdf, "/Type /FontDescriptor\n");
- write_fontname(pdf, fd, "FontName");
+ fd->fd_objnum = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, fd->fd_objnum, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "FontDescriptor");
+ pdf_dict_add_fontname(pdf, "FontName", fd);
if (fd->fm->fd_flags != FD_FLAGS_NOT_SET_IN_MAPLINE)
fd_flags = (int) fd->fm->fd_flags;
else if (fd->ff_found)
@@ -517,16 +531,16 @@ static void write_fontdescriptor(PDF pdf
fd->fm->ps_name != NULL ? fd->fm->ps_name : "No name given",
fd->fm->tfm_name, fd_flags);
}
- pdf_printf(pdf, "/Flags %i\n", fd_flags);
+ pdf_dict_add_int(pdf, "Flags", fd_flags);
write_fontmetrics(pdf, fd);
if (fd->ff_found) {
if (is_cidkeyed(fd->fm)) {
if (is_type1(fd->fm))
- pdf_printf(pdf, "/FontFile3 %i 0 R\n", (int) fd->ff_objnum);
+ pdf_dict_add_ref(pdf, "FontFile3", (int) fd->ff_objnum);
else if (is_truetype(fd->fm))
- pdf_printf(pdf, "/FontFile2 %i 0 R\n", (int) fd->ff_objnum);
+ pdf_dict_add_ref(pdf, "FontFile2", (int) fd->ff_objnum);
else if (is_opentype(fd->fm))
- pdf_printf(pdf, "/FontFile3 %i 0 R\n", (int) fd->ff_objnum);
+ pdf_dict_add_ref(pdf, "FontFile3", (int) fd->ff_objnum);
else
assert(0);
} else {
@@ -534,29 +548,32 @@ static void write_fontdescriptor(PDF pdf
/* /CharSet is optional; names may appear in any order */
assert(fd->gl_tree != NULL);
avl_t_init(&t, fd->gl_tree);
- pdf_puts(pdf, "/CharSet (");
+ pdf_add_name(pdf, "CharSet");
+ pdf_out(pdf, '(');
for (glyph = (char *) avl_t_first(&t, fd->gl_tree);
glyph != NULL; glyph = (char *) avl_t_next(&t))
- pdf_printf(pdf, "/%s", glyph);
- pdf_puts(pdf, ")\n");
+ pdf_add_name(pdf, glyph);
+ pdf_out(pdf, ')');
+ pdf->cave = 0;
}
if (is_type1(fd->fm))
- pdf_printf(pdf, "/FontFile %i 0 R\n", (int) fd->ff_objnum);
+ pdf_dict_add_ref(pdf, "FontFile", (int) fd->ff_objnum);
else if (is_truetype(fd->fm))
- pdf_printf(pdf, "/FontFile2 %i 0 R\n", (int) fd->ff_objnum);
+ pdf_dict_add_ref(pdf, "FontFile2", (int) fd->ff_objnum);
else if (is_opentype(fd->fm))
- pdf_printf(pdf, "/FontFile3 %i 0 R\n", (int) fd->ff_objnum);
+ pdf_dict_add_ref(pdf, "FontFile3", (int) fd->ff_objnum);
else
assert(0);
}
}
- if (cidset !=0)
- pdf_printf(pdf, "/CIDSet %i 0 R\n", cidset);
+ if (cidset != 0)
+ pdf_dict_add_ref(pdf, "CIDSet", cidset);
/* TODO: Other optional keys for CID fonts.
The most interesting one is
\.{/Style << /Panose <12-byte string>>>}
*/
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
}
static void write_fontdescriptors(PDF pdf)
@@ -591,34 +608,36 @@ static void write_fontdictionary(PDF pdf
fo->fm->tfm_name);
}
}
- pdf_begin_dict(pdf, fo->fo_objnum, 1);
- pdf_puts(pdf, "/Type /Font\n");
- pdf_puts(pdf, "/Subtype /");
+ pdf_begin_obj(pdf, fo->fo_objnum, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Font");
if (is_type1(fo->fm))
- pdf_printf(pdf, "%s\n", "Type1");
+ pdf_dict_add_name(pdf, "Subtype", "Type1");
else if (is_truetype(fo->fm))
- pdf_printf(pdf, "%s\n", "TrueType");
+ pdf_dict_add_name(pdf, "Subtype", "TrueType");
else if (is_opentype(fo->fm))
- pdf_printf(pdf, "%s\n", "Type1");
+ pdf_dict_add_name(pdf, "Subtype", "Type1");
else
assert(0);
assert(fo->fd != NULL && fo->fd->fd_objnum != 0);
- write_fontname(pdf, fo->fd, "BaseFont");
- pdf_printf(pdf, "/FontDescriptor %i 0 R\n", (int) fo->fd->fd_objnum);
+ pdf_dict_add_fontname(pdf, "BaseFont", fo->fd);
+ pdf_dict_add_ref(pdf, "FontDescriptor", (int) fo->fd->fd_objnum);
assert(fo->cw_objnum != 0);
- pdf_printf(pdf, "/FirstChar %i\n/LastChar %i\n/Widths %i 0 R\n",
- (int) fo->first_char, (int) fo->last_char, (int) fo->cw_objnum);
+ pdf_dict_add_int(pdf, "FirstChar", (int) fo->first_char);
+ pdf_dict_add_int(pdf, "LastChar", (int) fo->last_char);
+ pdf_dict_add_ref(pdf, "Widths", (int) fo->cw_objnum);
if ((is_type1(fo->fm) || is_opentype(fo->fm)) && fo->fe != NULL
&& fo->fe->fe_objnum != 0)
- pdf_printf(pdf, "/Encoding %i 0 R\n", (int) fo->fe->fe_objnum);
+ pdf_dict_add_ref(pdf, "Encoding", (int) fo->fe->fe_objnum);
if (fo->tounicode_objnum != 0)
- pdf_printf(pdf, "/ToUnicode %i 0 R\n", (int) fo->tounicode_objnum);
+ pdf_dict_add_ref(pdf, "ToUnicode", (int) fo->tounicode_objnum);
if (pdf_font_attr(fo->tex_font) != get_nullstr() &&
pdf_font_attr(fo->tex_font) != 0) {
pdf_print(pdf, pdf_font_attr(fo->tex_font));
- pdf_puts(pdf, "\n");
+ pdf_out(pdf, '\n');
}
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
}
static void write_fontdictionaries(PDF pdf)
@@ -661,7 +680,7 @@ static void create_fontdictionary(PDF pd
fo->fe = get_fe_entry(fo->fm->encname); /* returns |NULL| if .enc file couldn't be opened */
if (fo->fe != NULL && (is_type1(fo->fm) || is_opentype(fo->fm))) {
if (fo->fe->fe_objnum == 0)
- fo->fe->fe_objnum = pdf_new_objnum(pdf); /* then it will be written out */
+ fo->fe->fe_objnum = pdf_create_obj(pdf, obj_type_others, 0); /* then it will be written out */
/* mark encoding pairs used by TeX to optimize encoding vector */
fo->fe->tx_tree = mark_chars(fo, fo->fe->tx_tree, f);
}
@@ -901,24 +920,28 @@ static void write_cid_charwidth_array(PD
struct avl_traverser t;
assert(fo->cw_objnum == 0);
- fo->cw_objnum = pdf_new_objnum(pdf);
- pdf_begin_obj(pdf, fo->cw_objnum, 1);
+ fo->cw_objnum = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, fo->cw_objnum, OBJSTM_ALWAYS);
avl_t_init(&t, fo->fd->gl_tree);
glyph = (glw_entry *) avl_t_first(&t, fo->fd->gl_tree);
assert(glyph != NULL);
i = (int) glyph->id;
- pdf_printf(pdf, "[ %i [", i);
+ pdf_begin_array(pdf);
+ pdf_add_int(pdf, i);
+ pdf_begin_array(pdf);
for (; glyph != NULL; glyph = (glw_entry *) avl_t_next(&t)) {
j = glyph->wd;
if (glyph->id > (unsigned) (i + 1)) {
- pdf_printf(pdf, "] %i [", glyph->id);
+ pdf_end_array(pdf);
+ pdf_add_int(pdf, glyph->id);
+ pdf_begin_array(pdf);
j = glyph->wd;
}
if (glyph->id == (unsigned) (i + 1))
- pdf_puts(pdf, " ");
+ pdf_out(pdf, ' ');
if (j < 0) {
- pdf_puts(pdf, "-");
+ pdf_out(pdf, '-');
j = -j;
}
@@ -928,7 +951,8 @@ static void write_cid_charwidth_array(PD
i = (int) glyph->id;
}
- pdf_puts(pdf, "]]\n");
+ pdf_end_array(pdf);
+ pdf_end_array(pdf);
pdf_end_obj(pdf);
}
@@ -965,44 +989,53 @@ void write_cid_fontdictionary(PDF pdf, f
fo->tounicode_objnum = write_cid_tounicode(pdf, fo, f);
- pdf_begin_dict(pdf, fo->fo_objnum, 1);
- pdf_puts(pdf, "/Type /Font\n");
- pdf_puts(pdf, "/Subtype /Type0\n");
- pdf_puts(pdf, "/Encoding /Identity-H\n");
- write_fontname(pdf, fo->fd, "BaseFont");
- i = pdf_new_objnum(pdf);
- pdf_printf(pdf, "/DescendantFonts [%i 0 R]\n", i);
+ pdf_begin_obj(pdf, fo->fo_objnum, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Font");
+ pdf_dict_add_name(pdf, "Subtype", "Type0");
+ pdf_dict_add_name(pdf, "Encoding", "Identity-H");
+ pdf_dict_add_fontname(pdf, "BaseFont", fo->fd);
+ i = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_add_name(pdf, "DescendantFonts");
+ pdf_begin_array(pdf);
+ pdf_add_ref(pdf, i);
+ pdf_end_array(pdf);
/* todo: the ToUnicode CMap */
if (fo->tounicode_objnum != 0)
- pdf_printf(pdf, "/ToUnicode %i 0 R\n", (int) fo->tounicode_objnum);
-
+ pdf_dict_add_ref(pdf, "ToUnicode", (int) fo->tounicode_objnum);
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
- pdf_begin_dict(pdf, i, 1);
- pdf_puts(pdf, "/Type /Font\n");
+ pdf_begin_obj(pdf, i, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Font");
if (is_opentype(fo->fm) || is_type1(fo->fm)) {
- pdf_puts(pdf, "/Subtype /CIDFontType0\n");
+ pdf_dict_add_name(pdf, "Subtype", "CIDFontType0");
} else {
- pdf_puts(pdf, "/Subtype /CIDFontType2\n");
- pdf_printf(pdf, "/CIDToGIDMap /Identity\n");
+ pdf_dict_add_name(pdf, "Subtype", "CIDFontType2");
+ pdf_dict_add_name(pdf, "CIDToGIDMap", "Identity");
}
- write_fontname(pdf, fo->fd, "BaseFont");
- pdf_printf(pdf, "/FontDescriptor %i 0 R\n", (int) fo->fd->fd_objnum);
- pdf_printf(pdf, "/W %i 0 R\n", (int) fo->cw_objnum);
- pdf_printf(pdf, "/CIDSystemInfo <<\n");
- pdf_printf(pdf, "/Registry (%s)\n",
- (font_cidregistry(f) ? font_cidregistry(f) : "Adobe"));
- pdf_printf(pdf, "/Ordering (%s)\n",
- (font_cidordering(f) ? font_cidordering(f) : "Identity"));
- pdf_printf(pdf, "/Supplement %u\n", (unsigned int) font_cidsupplement(f));
- pdf_printf(pdf, ">>\n");
+ pdf_dict_add_fontname(pdf, "BaseFont", fo->fd);
+ pdf_dict_add_ref(pdf, "FontDescriptor", (int) fo->fd->fd_objnum);
+ pdf_dict_add_ref(pdf, "W", (int) fo->cw_objnum);
+ pdf_add_name(pdf, "CIDSystemInfo");
+ pdf_begin_dict(pdf);
+ pdf_dict_add_string(pdf, "Registry",
+ (font_cidregistry(f) ? font_cidregistry(f) : "Adobe"));
+ pdf_dict_add_string(pdf, "Ordering",
+ (font_cidordering(f) ? font_cidordering(f) :
+ "Identity"));
+ pdf_dict_add_int(pdf, "Supplement", (int) font_cidsupplement(f));
+ pdf_end_dict(pdf);
/* I doubt there is anything useful that could be written here */
#if 0
- if (pdf_font_attr(fo->tex_font) != get_nullstr()) {
- pdf_print(pdf_font_attr(fo->tex_font));
- pdf_puts(pdf,"\n");
- }
+ if (pdf_font_attr(fo->tex_font) != get_nullstr()) {
+ pdf_out(pdf, '\n');
+ pdf_print(pdf_font_attr(fo->tex_font));
+ pdf_out(pdf, '\n');
+ }
#endif
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
}
--- texk/web2c/luatexdir/font/writet1.w
+++ texk/web2c/luatexdir/font/writet1.w 2011-10-13 07:39:33.000000000 +0000
@@ -32,8 +32,8 @@ static const char _svn_version[] =
#define get_length3() t1_length3 = fixedcontent? t1_offset() - t1_save_offset : 0
#define save_offset() t1_save_offset = t1_offset()
-#define t1_putchar(A) fb_putchar(pdf,(A))
-#define t1_offset() fb_offset(pdf)
+#define t1_putchar(A) strbuf_putchar(pdf->fb, (A))
+#define t1_offset() strbuf_offset(pdf->fb)
#define out_eexec_char t1_putchar
#define end_last_eexec_line() \
@@ -41,8 +41,6 @@ static const char _svn_version[] =
#define t1_char(c) c
#define embed_all_glyphs(tex_font) fm_cur->all_glyphs
#define extra_charset() fm_cur->charset
-#define update_subset_tag() \
- strncpy(pdf->fb_array + t1_fontname_offset, fm_cur->subset_tag, 6)
#define fixedcontent false
int t1_length1, t1_length2, t1_length3;
@@ -52,7 +50,6 @@ static int t1_fontname_offset;
static unsigned char *t1_buffer = NULL;
static int t1_size = 0;
static int t1_curbyte = 0;
-
@ @c
#define t1_read_file() \
readbinfile(t1_file,&t1_buffer,&t1_size)
@@ -1364,7 +1361,8 @@ static void t1_subset_ascii_part(PDF pdf
}
make_subset_tag(fd_cur);
assert(t1_fontname_offset != 0);
- strncpy(pdf->fb_array + t1_fontname_offset, fd_cur->subset_tag, 6);
+ strncpy((char *) pdf->fb->data + t1_fontname_offset, fd_cur->subset_tag,
+ 6);
}
/* now really all glyphs needed from this font are in the |fd_cur->gl_tree| */
if (t1_encoding == ENC_STANDARD)
@@ -1387,7 +1385,7 @@ static void t1_subset_ascii_part(PDF pdf
destroy_t1_glyph_tree(gl_tree);
if (j == 0)
/* We didn't mark anything for the Encoding array.
- We add \.{dup 0 /.notdef put} for compatibility with Acrobat 5.0. */
+ We add \.{dup 0 /.notdef put} for compatibility with Acrobat 5.0. */
t1_puts(pdf, "dup 0 /.notdef put\n");
t1_puts(pdf, "readonly def\n");
}
--- texk/web2c/luatexdir/font/writet3.w
+++ texk/web2c/luatexdir/font/writet3.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,7 +1,7 @@
% writet3.w
% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
-% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -98,6 +98,7 @@ static boolean writepk(PDF pdf, internal
kpse_glyph_file_type font_ret;
int llx, lly, urx, ury;
int cw, rw, i, j;
+ pdffloat pf;
halfword *row;
char *name;
char *ftemp = NULL;
@@ -187,9 +188,14 @@ static boolean writepk(PDF pdf, internal
ury = cd.cheight + lly;
update_bbox(llx, lly, urx, ury, t3_glyph_num == 0);
t3_glyph_num++;
- t3_char_procs[cd.charcode] = pdf_new_dict(pdf, obj_type_others, 0, 0);
+ t3_char_procs[cd.charcode] = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, t3_char_procs[cd.charcode], OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
- pdf_print_real(pdf, (int) t3_char_widths[cd.charcode], 2);
+ setpdffloat(pf, (int) t3_char_widths[cd.charcode], 2);
+ print_pdffloat(pdf, pf);
pdf_printf(pdf, " 0 %i %i %i %i d1\n",
(int) llx, (int) lly, (int) urx, (int) ury);
if (is_null_glyph)
@@ -215,6 +221,7 @@ static boolean writepk(PDF pdf, internal
pdf_puts(pdf, "\nEI\nQ\n");
end_stream:
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
}
xfree(cd.raster);
cur_file_name = NULL;
@@ -225,11 +232,12 @@ static boolean writepk(PDF pdf, internal
@c
void writet3(PDF pdf, internal_font_number f)
{
-
int i;
+ char s[32];
int wptr, eptr, cptr;
int first_char, last_char;
int pk_font_scale;
+ pdffloat pf;
boolean is_notdef;
t3_glyph_num = 0;
@@ -253,77 +261,123 @@ void writet3(PDF pdf, internal_font_numb
if (pdf_char_marked(f, i))
break;
last_char = i;
- pdf_begin_dict(pdf, pdf_font_num(f), 1); /* Type 3 font dictionary */
- pdf_puts(pdf, "/Type /Font\n/Subtype /Type3\n");
- pdf_printf(pdf, "/Name /F%i\n", (int) f);
+
+ /* Type 3 font dictionary */
+ pdf_begin_obj(pdf, pdf_font_num(f), OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Font");
+ pdf_dict_add_name(pdf, "Subtype", "Type3");
+ snprintf(s, 31, "F%i", (int) f);
+ pdf_dict_add_name(pdf, "Name", s);
if (pdf_font_attr(f) != get_nullstr() && pdf_font_attr(f) != 0) {
+ pdf_out(pdf, '\n');
pdf_print(pdf, pdf_font_attr(f));
- pdf_puts(pdf, "\n");
+ pdf_out(pdf, '\n');
}
if (is_pk_font) {
pk_font_scale =
get_pk_font_scale(f, pdf->decimal_digits, pdf->pk_scale_factor);
- pdf_puts(pdf, "/FontMatrix [");
- pdf_print_real(pdf, pk_font_scale, 5);
+ pdf_add_name(pdf, "FontMatrix");
+ pdf_begin_array(pdf);
+ setpdffloat(pf, pk_font_scale, 5);
+ print_pdffloat(pdf, pf);
pdf_puts(pdf, " 0 0 ");
- pdf_print_real(pdf, pk_font_scale, 5);
- pdf_puts(pdf, " 0 0]\n");
- } else
- pdf_printf(pdf, "/FontMatrix [%g 0 0 %g 0 0]\n",
+ print_pdffloat(pdf, pf);
+ pdf_puts(pdf, " 0 0");
+ pdf_end_array(pdf);
+ } else {
+ pdf_add_name(pdf, "FontMatrix");
+ pdf_begin_array(pdf);
+ pdf_printf(pdf, "%g 0 0 %g 0 0",
(double) t3_font_scale, (double) t3_font_scale);
- pdf_printf(pdf, "/%s [ %i %i %i %i ]\n",
- font_key[FONTBBOX1_CODE].pdfname,
- (int) t3_b0, (int) t3_b1, (int) t3_b2, (int) t3_b3);
- pdf_printf(pdf, "/Resources << /ProcSet [ /PDF %s] >>\n",
- t3_image_used ? "/ImageB " : "");
- pdf_printf(pdf, "/FirstChar %i\n/LastChar %i\n", first_char, last_char);
- wptr = pdf_new_objnum(pdf);
- eptr = pdf_new_objnum(pdf);
- cptr = pdf_new_objnum(pdf);
- pdf_printf(pdf, "/Widths %i 0 R\n/Encoding %i 0 R\n/CharProcs %i 0 R\n",
- (int) wptr, (int) eptr, (int) cptr);
+ pdf_end_array(pdf);
+ }
+ pdf_add_name(pdf, font_key[FONTBBOX1_CODE].pdfname);
+ pdf_begin_array(pdf);
+ pdf_add_int(pdf, (int) t3_b0);
+ pdf_add_int(pdf, (int) t3_b1);
+ pdf_add_int(pdf, (int) t3_b2);
+ pdf_add_int(pdf, (int) t3_b3);
+ pdf_end_array(pdf);
+ pdf_add_name(pdf, "Resources");
+ pdf_begin_dict(pdf);
+ pdf_add_name(pdf, "ProcSet");
+ pdf_begin_array(pdf);
+ pdf_add_name(pdf, "PDF");
+ if (t3_image_used)
+ pdf_add_name(pdf, "ImageB");
+ pdf_end_array(pdf);
+ pdf_end_dict(pdf);
+ pdf_dict_add_int(pdf, "FirstChar", first_char);
+ pdf_dict_add_int(pdf, "LastChar", last_char);
+ wptr = pdf_create_obj(pdf, obj_type_others, 0);
+ eptr = pdf_create_obj(pdf, obj_type_others, 0);
+ cptr = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_dict_add_ref(pdf, "Widths", (int) wptr);
+ pdf_dict_add_ref(pdf, "Encoding", (int) eptr);
+ pdf_dict_add_ref(pdf, "CharProcs", (int) cptr);
pdf_end_dict(pdf);
- pdf_begin_obj(pdf, wptr, 1); /* chars width array */
- pdf_puts(pdf, "[");
+ pdf_end_obj(pdf);
+
+ /* chars width array */
+ pdf_begin_obj(pdf, wptr, OBJSTM_ALWAYS);
+ pdf_begin_array(pdf);
if (is_pk_font)
for (i = first_char; i <= last_char; i++) {
- pdf_print_real(pdf, (int) t3_char_widths[i], 2);
- pdf_puts(pdf, " ");
+ setpdffloat(pf, (int) t3_char_widths[i], 2);
+ print_pdffloat(pdf, pf);
+ pdf_out(pdf, ' ');
} else
for (i = first_char; i <= last_char; i++)
- pdf_printf(pdf, "%i ", (int) t3_char_widths[i]);
- pdf_puts(pdf, "]\n");
+ pdf_add_int(pdf, (int) t3_char_widths[i]);
+ pdf_end_array(pdf);
pdf_end_obj(pdf);
- pdf_begin_dict(pdf, eptr, 1); /* encoding dictionary */
- pdf_printf(pdf, "/Type /Encoding\n/Differences [%i", first_char);
+
+ /* encoding dictionary */
+ pdf_begin_obj(pdf, eptr, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Encoding");
+ pdf_add_name(pdf, "Differences");
+ pdf_begin_array(pdf);
+ pdf_add_int(pdf, first_char);
if (t3_char_procs[first_char] == 0) {
- pdf_printf(pdf, "/%s", notdef);
+ pdf_add_name(pdf, notdef);
is_notdef = true;
} else {
- pdf_printf(pdf, "/a%i", first_char);
+ snprintf(s, 31, "a%i", first_char);
+ pdf_add_name(pdf, s);
is_notdef = false;
}
for (i = first_char + 1; i <= last_char; i++) {
if (t3_char_procs[i] == 0) {
if (!is_notdef) {
- pdf_printf(pdf, " %i/%s", i, notdef);
+ pdf_add_int(pdf, i);
+ pdf_add_name(pdf, notdef);
is_notdef = true;
}
} else {
if (is_notdef) {
- pdf_printf(pdf, " %i", i);
+ pdf_add_int(pdf, i);
is_notdef = false;
}
- pdf_printf(pdf, "/a%i", i);
+ snprintf(s, 31, "a%i", i);
+ pdf_add_name(pdf, s);
}
}
- pdf_puts(pdf, "]\n");
+ pdf_end_array(pdf);
pdf_end_dict(pdf);
- pdf_begin_dict(pdf, cptr, 1); /* CharProcs dictionary */
+ pdf_end_obj(pdf);
+
+ /* CharProcs dictionary */
+ pdf_begin_obj(pdf, cptr, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
for (i = first_char; i <= last_char; i++)
- if (t3_char_procs[i] != 0)
- pdf_printf(pdf, "/a%i %i 0 R\n", (int) i, (int) t3_char_procs[i]);
+ if (t3_char_procs[i] != 0) {
+ snprintf(s, 31, "a%i", (int) i);
+ pdf_dict_add_ref(pdf, s, (int) t3_char_procs[i]);
+ }
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
if (tracefilenames)
tex_printf(">");
cur_file_name = NULL;
--- texk/web2c/luatexdir/font/writettf.w
+++ texk/web2c/luatexdir/font/writettf.w 2011-10-13 07:39:33.000000000 +0000
@@ -24,15 +24,15 @@
#include <string.h>
static const char _svn_version[] =
- "$Id: writettf.w 3789 2010-08-02 19:59:49Z oneiros $ "
-"$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/font/writettf.w $";
+ "$Id: writettf.w 4296 2011-06-15 18:33:05Z hhenkel $ "
+"$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/font/writettf.w $";
#define DEFAULT_NTABS 14
#define NEW_CMAP_SIZE 2
-#define ttf_putchar(A) fb_putchar(pdf,(A))
-#define ttf_offset() fb_offset(pdf)
-#define ttf_seek_outbuf(A) fb_seek(pdf,(A))
+#define ttf_putchar(A) strbuf_putchar(pdf->fb, (A))
+#define ttf_offset() strbuf_offset(pdf->fb)
+#define ttf_seek_outbuf(A) strbuf_seek(pdf->fb, (A))
unsigned char *ttf_buffer = NULL;
int ttf_size = 0;
@@ -1260,7 +1260,7 @@ static void ttf_write_dirtab(PDF pdf)
/* adjust checkSumAdjustment */
tmp_ulong = 0;
checksum = 0;
- for (p = pdf->fb_array, i = 0; i < (unsigned) save_offset;) {
+ for (p = (char *) pdf->fb->data, i = 0; i < (unsigned) save_offset;) {
tmp_ulong = (tmp_ulong << 8) + (TTF_ULONG) * p++;
i++;
if (i % 4 == 0) {
--- texk/web2c/luatexdir/font/writetype0.w
+++ texk/web2c/luatexdir/font/writetype0.w 2011-10-13 07:39:33.000000000 +0000
@@ -48,7 +48,8 @@ void writetype0(PDF pdf, fd_entry * fd)
cur_file_name =
luatex_find_file(fd_cur->fm->ff_name, find_opentype_file_callback);
if (cur_file_name == NULL) {
- pdftex_fail("cannot find OpenType font file for reading (%s)", fd_cur->fm->ff_name);
+ pdftex_fail("cannot find OpenType font file for reading (%s)",
+ fd_cur->fm->ff_name);
}
callback_id = callback_defined(read_opentype_file_callback);
if (callback_id > 0) {
@@ -56,11 +57,13 @@ void writetype0(PDF pdf, fd_entry * fd)
&file_opened, &ttf_buffer, &ttf_size) &&
file_opened && ttf_size > 0) {
} else {
- pdftex_fail("cannot open OpenType font file for reading (%s)", cur_file_name);
+ pdftex_fail("cannot open OpenType font file for reading (%s)",
+ cur_file_name);
}
} else {
if (!otf_open(cur_file_name)) {
- pdftex_fail("cannot open OpenType font file for reading (%s)", cur_file_name);
+ pdftex_fail("cannot open OpenType font file for reading (%s)",
+ cur_file_name);
}
ttf_read_file();
ttf_close();
@@ -93,14 +96,14 @@ void writetype0(PDF pdf, fd_entry * fd)
if (!is_subsetted(fd_cur->fm)) {
/* not subsetted, just do a copy */
for (i = (long) tab->length; i > 0; i--)
- fb_putchar(pdf, (eight_bits) ttf_getnum(1));
+ strbuf_putchar(pdf->fb, (unsigned char) ttf_getnum(1));
} else {
if (cff != NULL) {
if (cff_is_cidfont(cff)) {
write_cid_cff(pdf, cff, fd_cur);
#if 0
- for (i = tab->length; i > 0; i--)
- fb_putchar (ttf_getnum(1));
+ for (i = tab->length; i > 0; i--)
+ strbuf_putchar(pdf->fb, (unsigned char) ttf_getnum(1));
#endif
} else {
write_cff(pdf, cff, fd_cur);
@@ -108,7 +111,7 @@ void writetype0(PDF pdf, fd_entry * fd)
} else {
/* not understood, just do a copy */
for (i = (long) tab->length; i > 0; i--)
- fb_putchar(pdf, (eight_bits) ttf_getnum(1));
+ strbuf_putchar(pdf->fb, (unsigned char) ttf_getnum(1));
}
}
xfree(dir_tab);
--- texk/web2c/luatexdir/font/writetype2.w
+++ texk/web2c/luatexdir/font/writetype2.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
-% writetype0.w
+% writetype2.w
%
-% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
%
% This file is part of LuaTeX.
%
@@ -38,11 +38,11 @@ unsigned long cidtogid_obj = 0;
@ low-level helpers
@c
-#define test_loc(l) \
- if ((f->loc+l)>f->buflen) { \
- fprintf (stderr,"File ended prematurely\n"); \
- uexit(1); \
- }
+#define test_loc(l) \
+ if ((f->loc + l) > f->buflen) { \
+ fprintf(stderr, "File ended prematurely\n"); \
+ uexit(1); \
+ }
BYTE get_unsigned_byte(sfnt * f)
@@ -378,56 +378,65 @@ void make_tt_subset(PDF pdf, fd_entry *
/* squeeze in the cidgidmap */
if (cidtogidmap != NULL) {
- cidtogid_obj = (unsigned long) pdf_new_objnum(pdf);
- pdf_begin_dict(pdf, (int) cidtogid_obj, 0);
- pdf_printf(pdf, "/Length %i\n", ((last_cid + 1) * 2));
+ cidtogid_obj = (unsigned long) pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, (int) cidtogid_obj, OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_int(pdf, "Length", ((last_cid + 1) * 2));
pdf_end_dict(pdf);
- pdf_printf(pdf, "stream\n");
+ assert(0); /* code unused */
+ pdf_begin_stream(pdf);
pdf_room(pdf, (int) ((last_cid + 1) * 2));
for (i = 0; i < ((int) (last_cid + 1) * 2); i++) {
pdf_quick_out(pdf, cidtogidmap[i]);
}
- pdf_printf(pdf, "\nendstream\n");
+ pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
}
/* the tff subset */
for (i = 0; i < (int) (fontfile->length); i++)
- fb_putchar(pdf, fontfile->data[i]);
+ strbuf_putchar(pdf->fb, fontfile->data[i]);
pdf_release_obj(fontfile);
/* CIDSet: a table of bits indexed by cid, bytes with high order bit first,
- each (set) bit is a (present) CID. */
+ each (set) bit is a (present) CID. */
if (is_subsetted(fd->fm)) {
- cidset = pdf_new_objnum(pdf);
- if (cidset != 0) {
- size_t l = (last_cid/8)+1;
- char *stream = xmalloc(l);
- memset(stream, 0, l);
- for (cid = 1; cid <= (long) last_cid; cid++) {
- if (used_chars[cid]) {
- stream[(cid / 8)] |= (1 << (7 - (cid % 8)));
- }
- }
- pdf_begin_dict(pdf, cidset, 0);
- pdf_begin_stream(pdf);
- pdf_out_block(pdf, stream, l);
- pdf_end_stream(pdf);
- }
+ cidset = pdf_create_obj(pdf, obj_type_others, 0);
+ if (cidset != 0) {
+ size_t l = (last_cid / 8) + 1;
+ char *stream = xmalloc(l);
+ memset(stream, 0, l);
+ for (cid = 1; cid <= (long) last_cid; cid++) {
+ if (used_chars[cid]) {
+ stream[(cid / 8)] |= (1 << (7 - (cid % 8)));
+ }
+ }
+ pdf_begin_obj(pdf, cidset, OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
+ pdf_begin_stream(pdf);
+ pdf_out_block(pdf, stream, l);
+ pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
+ }
}
/* TODO other stuff that needs fixing: */
/* DW, W, DW2, and W2 */
#if 0
- if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) {
- pdf_add_dict(font->fontdict,
- pdf_new_name("DW"), pdf_new_number(1000.0));
- } else {
- add_TTCIDHMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid);
- if (v_used_chars)
- add_TTCIDVMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid);
- }
+ if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) {
+ pdf_add_dict(font->fontdict,
+ pdf_new_name("DW"), pdf_new_number(1000.0));
+ } else {
+ add_TTCIDHMetrics(font->fontdict, glyphs, used_chars, cidtogidmap,
+ last_cid);
+ if (v_used_chars)
+ add_TTCIDVMetrics(font->fontdict, glyphs, used_chars, cidtogidmap,
+ last_cid);
+ }
#endif
xfree(used_chars);
--- texk/web2c/luatexdir/image/epdf.h
+++ texk/web2c/luatexdir/image/epdf.h 2011-10-13 07:39:27.000000000 +0000
@@ -1,7 +1,7 @@
/* epdf.h
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
LuaTeX is free software; you can redistribute it and/or modify it under
@@ -33,6 +33,7 @@
# include <sys/stat.h>
# include <dirent.h>
# include <poppler-config.h>
+# include <cpp/poppler-version.h>
# include <goo/GooString.h>
# include <goo/gmem.h>
# include <goo/gfile.h>
@@ -80,39 +81,62 @@ extern "C" {
# include "lua51/lua.h"
# include "lua51/lauxlib.h"
- /* pdfgen.c */
+ /* pdfgen.w */
+ extern int ten_pow[10];
__attribute__ ((format(printf, 2, 3)))
extern void pdf_printf(PDF, const char *fmt, ...);
- extern void pdf_begin_obj(PDF, int, bool);
+ extern void pdf_begin_obj(PDF, int, int);
extern void pdf_end_obj(PDF);
+ extern void pdf_begin_dict(PDF);
+ extern void pdf_end_dict(PDF);
+ extern void pdf_begin_array(PDF);
+ extern void pdf_end_array(PDF);
+ extern void pdf_add_null(PDF);
+ extern void pdf_add_bool(PDF, int i);
+ extern void pdf_add_int(PDF, int i);
+ extern void pdf_add_ref(PDF, int num);
+ extern void pdf_add_name(PDF, const char *name);
+ extern void pdf_dict_add_streaminfo(PDF);
extern void pdf_begin_stream(PDF);
extern void pdf_end_stream(PDF);
extern void pdf_room(PDF, int);
extern void pdf_out_block(PDF pdf, const char *s, size_t n);
-# define pdf_out(B, A) do { pdf_room(B, 1); B->buf[B->ptr++] = A; } while (0)
+ extern void pdf_dict_add_int(PDF, const char *key, int i);
+ extern void pdf_dict_add_ref(PDF, const char *key, int num);
+ extern void pdf_dict_add_name(PDF, const char *key, const char *val);
+ extern void pdf_dict_add_streaminfo(PDF);
+
+# define pdf_out(pdf, A) do { pdf_room(pdf, 1); *(pdf->buf->p++) = A; } while (0)
+# define pdf_quick_out(pdf,A) *(pdf->buf->p++)=(unsigned char)(A)
# define pdf_puts(pdf, s) pdf_out_block((pdf), (s), strlen(s))
- /* pdftables.c */
- extern int pdf_new_objnum(PDF);
+ /* pdfpage.w */
+ extern void print_pdffloat(PDF pdf, pdffloat f);
+
+ /* pdftables.w */
+ extern int pdf_create_obj(PDF pdf, int t, int i);
/* pdftoepdf.cc */
extern void read_pdf_info(image_dict *, int, int, img_readtype_e);
extern void write_epdf(PDF, image_dict *);
extern void unrefPdfDocument(char *);
extern void epdf_free(void);
+ extern void copyReal(PDF pdf, double d);
- /* utils.c */
+ extern int poppler_version_major(void);
+ extern int poppler_version_minor(void);
+ extern int poppler_version_micro(void);
+
+ /* utils.w */
__attribute__ ((format(printf, 1, 2)))
extern void pdftex_warn(const char *fmt, ...);
__attribute__ ((noreturn, format(printf, 1, 2)))
extern void pdftex_fail(const char *fmt, ...);
extern char *convertStringToPDFString(char *in, int len);
- extern char *stripzeros(char *a);
- /* lepdflib.c */
+ /* lepdflib.w */
int luaopen_epdf(lua_State * L);
-
};
/**********************************************************************/
--- texk/web2c/luatexdir/image/image.h
+++ texk/web2c/luatexdir/image/image.h 2011-10-13 07:39:27.000000000 +0000
@@ -32,8 +32,8 @@
extern int do_zround(double r); /* from utils.w */
extern scaled one_hundred_bp; /* from pdfgen.w */
-# define bp2int(p) do_zround(p * (one_hundred_bp / 100.0))
-# define int2bp(i) (i * 100.0 / one_hundred_bp)
+# define bp2sp(p) do_zround(p * (one_hundred_bp / 100.0))
+# define sp2bp(i) (i * 100.0 / one_hundred_bp)
# define TYPE_IMG "image"
# define TYPE_IMG_DICT "image-dict"
--- texk/web2c/luatexdir/image/pdftoepdf.cc
+++ texk/web2c/luatexdir/image/pdftoepdf.cc 2011-10-13 07:39:27.000000000 +0000
@@ -1,7 +1,7 @@
/* pdftoepdf.cc
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -29,11 +29,6 @@ static const char _svn_version[] =
// This file is mostly C and not very much C++; it's just used to interface
// the functions of xpdf, which happens to be written in C++.
-// The prefix "PTEX" for the PDF keys is special to pdfTeX;
-// this has been registered with Adobe by Hans Hagen.
-
-#define pdfkeyprefix "PTEX"
-
static GBool isInit = gFalse;
//**********************************************************************
@@ -253,7 +248,7 @@ static int addInObj(PDF pdf, PdfDocument
n = new InObj;
n->ref = ref;
n->next = NULL;
- n->num = pdf_new_objnum(pdf);
+ n->num = pdf_create_obj(pdf, obj_type_others, 0);
addObjMap(pdf_doc, ref, n->num);
if (pdf_doc->inObjList == NULL)
pdf_doc->inObjList = n;
@@ -269,7 +264,7 @@ static int addInObj(PDF pdf, PdfDocument
}
//**********************************************************************
-// Function converts double to string; very small and very large numbers
+// Function converts double to pdffloat; very small and very large numbers
// are NOT converted to scientific notation.
// n must be a number or real conforming to the implementation limits
// of PDF as specified in appendix C.1 of the PDF Ref.
@@ -278,57 +273,24 @@ static int addInObj(PDF pdf, PdfDocument
// maximum value of reals is +2^15
// smalles values of reals is 1/(2^16)
-static char *convertNumToPDF(double n)
+static pdffloat conv_double_to_pdffloat(double n)
{
- static const int precision = 6;
- static const int fact = (int) 1E6; // must be 10^precision
- static const double epsilon = 0.5E-6; // 2epsilon must be 10^-precision
- static char buf[64];
- // handle very small values: return 0
- if (fabs(n) < epsilon) {
- buf[0] = '0';
- buf[1] = '\0';
- } else {
- char ints[64];
- int bindex = 0, sindex = 0;
- int ival, fval;
- // handle the sign part if n is negative
- if (n < 0) {
- buf[bindex++] = '-';
- n = -n;
- }
- n += epsilon; // for rounding
- // handle the integer part, simply with sprintf
- ival = (int) floor(n);
- n -= ival;
- sprintf(ints, "%d", ival);
- while (ints[sindex] != 0)
- buf[bindex++] = ints[sindex++];
- // handle the fractional part up to 'precision' digits
- fval = (int) floor(n * fact);
- if (fval) {
- // set a dot
- buf[bindex++] = '.';
- sindex = bindex + precision;
- buf[sindex--] = '\0';
- // fill up trailing zeros with the string terminator NULL
- while (((fval % 10) == 0) && (sindex >= bindex)) {
- buf[sindex--] = '\0';
- fval /= 10;
- }
- // fill up the fractional part back to front
- while (sindex >= bindex) {
- buf[sindex--] = (fval % 10) + '0';
- fval /= 10;
- }
- } else
- buf[bindex++] = '\0';
- }
- return (char *) buf;
+ pdffloat a;
+ a.e = 6;
+ a.m = lround(n * ten_pow[a.e]);
+ return a;
}
static void copyObject(PDF, PdfDocument *, Object *);
+void copyReal(PDF pdf, double d)
+{
+ if (pdf->cave)
+ pdf_out(pdf, ' ');
+ print_pdffloat(pdf, conv_double_to_pdffloat(d));
+ pdf->cave = true;
+}
+
static void copyString(PDF pdf, GooString * string)
{
char *p;
@@ -336,8 +298,10 @@ static void copyString(PDF pdf, GooStrin
size_t i, l;
p = string->getCString();
l = (size_t) string->getLength();
+ if (pdf->cave)
+ pdf_out(pdf, ' ');
if (strlen(p) == l) {
- pdf_puts(pdf, "(");
+ pdf_out(pdf, '(');
for (; *p != 0; p++) {
c = (unsigned char) *p;
if (c == '(' || c == ')' || c == '\\')
@@ -347,20 +311,21 @@ static void copyString(PDF pdf, GooStrin
else
pdf_out(pdf, c);
}
- pdf_puts(pdf, ")");
+ pdf_out(pdf, ')');
} else {
- pdf_puts(pdf, "<");
+ pdf_out(pdf, '<');
for (i = 0; i < l; i++) {
c = (unsigned char) string->getChar(i);
pdf_printf(pdf, "%.2x", (int) c);
}
- pdf_puts(pdf, ">");
+ pdf_out(pdf, '>');
}
+ pdf->cave = true;
}
static void copyName(PDF pdf, char *s)
{
- pdf_puts(pdf, "/");
+ pdf_out(pdf, '/');
for (; *s != 0; s++) {
if (isdigit(*s) || isupper(*s) || islower(*s) || *s == '_' ||
*s == '.' || *s == '-' || *s == '+')
@@ -368,72 +333,74 @@ static void copyName(PDF pdf, char *s)
else
pdf_printf(pdf, "#%.2X", *s & 0xFF);
}
+ pdf->cave = true;
}
static void copyArray(PDF pdf, PdfDocument * pdf_doc, Array * array)
{
int i, l;
Object obj1;
- pdf_puts(pdf, "[");
+ pdf_begin_array(pdf);
for (i = 0, l = array->getLength(); i < l; ++i) {
array->getNF(i, &obj1);
- if (!obj1.isName())
- pdf_puts(pdf, " ");
copyObject(pdf, pdf_doc, &obj1);
obj1.free();
}
- pdf_puts(pdf, "]");
+ pdf_end_array(pdf);
}
static void copyDict(PDF pdf, PdfDocument * pdf_doc, Dict * dict)
{
int i, l;
Object obj1;
- pdf_puts(pdf, "<<");
+ pdf_begin_dict(pdf);
for (i = 0, l = dict->getLength(); i < l; ++i) {
copyName(pdf, dict->getKey(i));
- pdf_puts(pdf, " ");
dict->getValNF(i, &obj1);
copyObject(pdf, pdf_doc, &obj1);
obj1.free();
- pdf_puts(pdf, "\n");
}
- pdf_puts(pdf, ">>");
+ pdf_end_dict(pdf);
}
static void copyStreamStream(PDF pdf, Stream * str)
{
- int c;
+ int c, i, len = 1024;
str->reset();
+ i = len;
while ((c = str->getChar()) != EOF) {
- pdf_out(pdf, c);
- pdf->last_byte = c;
+ if (i == len) {
+ pdf_room(pdf, len);
+ i = 0;
+ }
+ pdf_quick_out(pdf, c);
+ i++;
}
}
static void copyStream(PDF pdf, PdfDocument * pdf_doc, Stream * stream)
{
copyDict(pdf, pdf_doc, stream->getDict());
- pdf_puts(pdf, "stream\n");
+ pdf_begin_stream(pdf);
+ assert(pdf->zip_write_state == NO_ZIP);
copyStreamStream(pdf, stream->getUndecodedStream());
- if (pdf->last_byte != '\n')
- pdf_puts(pdf, "\n");
- pdf_puts(pdf, "endstream"); // can't simply write pdf_end_stream()
+ pdf_end_stream(pdf);
}
static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj)
{
switch (obj->getType()) {
case objBool:
- pdf_printf(pdf, "%s", obj->getBool()? "true" : "false");
+ pdf_add_bool(pdf, (int) obj->getBool());
break;
case objInt:
- pdf_printf(pdf, "%i", obj->getInt());
+ pdf_add_int(pdf, obj->getInt());
break;
case objReal:
- pdf_printf(pdf, "%s", convertNumToPDF(obj->getReal()));
+ copyReal(pdf, obj->getReal());
break;
// not needed:
+ // case objNum:
// GBool isNum() { return type == objInt || type == objReal; }
case objString:
copyString(pdf, obj->getString());
@@ -442,7 +409,7 @@ static void copyObject(PDF pdf, PdfDocum
copyName(pdf, obj->getName());
break;
case objNull:
- pdf_puts(pdf, "null");
+ pdf_add_null(pdf);
break;
case objArray:
copyArray(pdf, pdf_doc, obj->getArray());
@@ -454,7 +421,7 @@ static void copyObject(PDF pdf, PdfDocum
copyStream(pdf, pdf_doc, obj->getStream());
break;
case objRef:
- pdf_printf(pdf, "%d 0 R", addInObj(pdf, pdf_doc, obj->getRef()));
+ pdf_add_ref(pdf, addInObj(pdf, pdf_doc, obj->getRef()));
break;
case objCmd:
case objError:
@@ -473,18 +440,18 @@ static void copyObject(PDF pdf, PdfDocum
static void writeRefs(PDF pdf, PdfDocument * pdf_doc)
{
InObj *r, *n;
- XRef *xref;
Object obj1;
- xref = pdf_doc->doc->getXRef();
+ XRef *xref;
+ PDFDoc *doc = pdf_doc->doc;
+ xref = doc->getXRef();
for (r = pdf_doc->inObjList; r != NULL;) {
xref->fetch(r->ref.num, r->ref.gen, &obj1);
if (obj1.isStream())
- pdf_begin_obj(pdf, r->num, 0);
+ pdf_begin_obj(pdf, r->num, OBJSTM_NEVER);
else
pdf_begin_obj(pdf, r->num, 2); // \pdfobjcompresslevel = 2 is for this
copyObject(pdf, pdf_doc, &obj1);
obj1.free();
- pdf_puts(pdf, "\n");
pdf_end_obj(pdf);
n = r->next;
delete r;
@@ -530,6 +497,7 @@ read_pdf_info(image_dict * idict, int mi
int pdf_inclusion_errorlevel, img_readtype_e readtype)
{
PdfDocument *pdf_doc;
+ PDFDoc *doc;
Page *page;
int rotate;
PDFRectangle *pagebox;
@@ -546,12 +514,13 @@ read_pdf_info(image_dict * idict, int mi
}
// open PDF file
pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL);
+ doc = pdf_doc->doc;
// check PDF version
// this works only for PDF 1.x -- but since any versions of PDF newer
// than 1.x will not be backwards compatible to PDF 1.x, pdfTeX will
// then have to changed drastically anyway.
- pdf_major_version_found = pdf_doc->doc->getPDFMajorVersion();
- pdf_minor_version_found = pdf_doc->doc->getPDFMinorVersion();
+ pdf_major_version_found = doc->getPDFMajorVersion();
+ pdf_minor_version_found = doc->getPDFMinorVersion();
if ((pdf_major_version_found > 1)
|| (pdf_minor_version_found > minor_pdf_version_wanted)) {
const char *msg =
@@ -564,17 +533,16 @@ read_pdf_info(image_dict * idict, int mi
minor_pdf_version_wanted);
}
}
- img_totalpages(idict) = pdf_doc->doc->getCatalog()->getNumPages();
+ img_totalpages(idict) = doc->getCatalog()->getNumPages();
if (img_pagename(idict)) {
// get page by name
GooString name(img_pagename(idict));
- LinkDest *link = pdf_doc->doc->findDest(&name);
+ LinkDest *link = doc->findDest(&name);
if (link == NULL || !link->isOk())
pdftex_fail("PDF inclusion: invalid destination <%s>",
img_pagename(idict));
Ref ref = link->getPageRef();
- img_pagenum(idict) =
- pdf_doc->doc->getCatalog()->findPage(ref.num, ref.gen);
+ img_pagenum(idict) = doc->getCatalog()->findPage(ref.num, ref.gen);
if (img_pagenum(idict) == 0)
pdftex_fail("PDF inclusion: destination is not a page <%s>",
img_pagename(idict));
@@ -587,7 +555,7 @@ read_pdf_info(image_dict * idict, int mi
(int) img_pagenum(idict));
}
// get the required page
- page = pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict));
+ page = doc->getCatalog()->getPage(img_pagenum(idict));
// get the pagebox coordinates (media, crop,...) to use.
pagebox = get_pagebox(page, img_pagebox(idict));
@@ -606,10 +574,10 @@ read_pdf_info(image_dict * idict, int mi
ysize = pagebox->y1 - pagebox->y2;
}
// The following 4 parameters are raw. Do _not_ modify by /Rotate!
- img_xsize(idict) = bp2int(xsize);
- img_ysize(idict) = bp2int(ysize);
- img_xorig(idict) = bp2int(xorig);
- img_yorig(idict) = bp2int(yorig);
+ img_xsize(idict) = bp2sp(xsize);
+ img_ysize(idict) = bp2sp(ysize);
+ img_xorig(idict) = bp2sp(xorig);
+ img_yorig(idict) = bp2sp(yorig);
// Handle /Rotate parameter. Only multiples of 90 deg. are allowed
// (PDF Ref. v1.3, p. 78).
@@ -649,13 +617,14 @@ read_pdf_info(image_dict * idict, int mi
void write_epdf(PDF pdf, image_dict * idict)
{
PdfDocument *pdf_doc;
+ PDFDoc *doc;
Page *page;
Ref *pageref;
Dict *pageDict;
Object obj1, contents, pageobj, pagesobj1, pagesobj2, *op1, *op2, *optmp;
PDFRectangle *pagebox;
int i, l;
- float bbox[4];
+ double bbox[4];
char s[256];
const char *pagedictkeys[] =
{ "Group", "LastModified", "Metadata", "PieceInfo", "Resources",
@@ -665,36 +634,43 @@ void write_epdf(PDF pdf, image_dict * id
// open PDF file
pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL);
- page = pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict));
- pageref = pdf_doc->doc->getCatalog()->getPageRef(img_pagenum(idict));
+ doc = pdf_doc->doc;
+ page = doc->getCatalog()->getPage(img_pagenum(idict));
+ pageref = doc->getCatalog()->getPageRef(img_pagenum(idict));
assert(pageref != NULL); // was checked already in read_pdf_info()
- pdf_doc->doc->getXRef()->fetch(pageref->num, pageref->gen, &pageobj);
+ doc->getXRef()->fetch(pageref->num, pageref->gen, &pageobj);
pageDict = pageobj.getDict();
// write the Page header
- pdf_puts(pdf, "/Type /XObject\n/Subtype /Form\n");
+ pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "XObject");
+ pdf_dict_add_name(pdf, "Subtype", "Form");
+
if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
- pdf_printf(pdf, "%s\n", img_attr(idict));
- pdf_puts(pdf, "/FormType 1\n");
+ pdf_printf(pdf, "\n%s\n", img_attr(idict));
+ pdf_dict_add_int(pdf, "FormType", 1);
// write additional information
- pdf_printf(pdf, "/%s.FileName (%s)\n", pdfkeyprefix,
+ snprintf(s, 30, "%s.FileName", pdfkeyprefix);
+ pdf_add_name(pdf, s);
+ pdf_printf(pdf, " (%s)",
convertStringToPDFString(pdf_doc->file_path,
strlen(pdf_doc->file_path)));
- pdf_printf(pdf, "/%s.PageNumber %i\n", pdfkeyprefix,
- (int) img_pagenum(idict));
- pdf_doc->doc->getDocInfoNF(&obj1);
+ snprintf(s, 30, "%s.PageNumber", pdfkeyprefix);
+ pdf_dict_add_int(pdf, s, (int) img_pagenum(idict));
+ doc->getDocInfoNF(&obj1);
if (obj1.isRef()) {
// the info dict must be indirect (PDF Ref p. 61)
- pdf_printf(pdf, "/%s.InfoDict ", pdfkeyprefix);
- pdf_printf(pdf, "%d 0 R\n", addInObj(pdf, pdf_doc, obj1.getRef()));
+ snprintf(s, 30, "%s.InfoDict", pdfkeyprefix);
+ pdf_dict_add_ref(pdf, s, addInObj(pdf, pdf_doc, obj1.getRef()));
}
obj1.free();
if (img_is_bbox(idict)) {
- bbox[0] = int2bp(img_bbox(idict)[0]);
- bbox[1] = int2bp(img_bbox(idict)[1]);
- bbox[2] = int2bp(img_bbox(idict)[2]);
- bbox[3] = int2bp(img_bbox(idict)[3]);
+ bbox[0] = sp2bp(img_bbox(idict)[0]);
+ bbox[1] = sp2bp(img_bbox(idict)[1]);
+ bbox[2] = sp2bp(img_bbox(idict)[2]);
+ bbox[3] = sp2bp(img_bbox(idict)[3]);
} else {
// get the pagebox coordinates (media, crop,...) to use.
pagebox = get_pagebox(page, img_pagebox(idict));
@@ -703,9 +679,13 @@ void write_epdf(PDF pdf, image_dict * id
bbox[2] = pagebox->x2;
bbox[3] = pagebox->y2;
}
- sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", bbox[0], bbox[1], bbox[2],
- bbox[3]);
- pdf_puts(pdf, stripzeros(s));
+ pdf_add_name(pdf, "BBox");
+ pdf_begin_array(pdf);
+ copyReal(pdf, bbox[0]);
+ copyReal(pdf, bbox[1]);
+ copyReal(pdf, bbox[2]);
+ copyReal(pdf, bbox[3]);
+ pdf_end_array(pdf);
// The /Matrix calculation is replaced by transforms in out_img().
// Now all relevant parts of the Page dictionary are copied:
@@ -720,7 +700,7 @@ void write_epdf(PDF pdf, image_dict * id
for (i = 0; pagedictkeys[i] != NULL; i++) {
pageDict->lookupNF((char *) pagedictkeys[i], &obj1);
if (!obj1.isNull()) {
- pdf_printf(pdf, "/%s ", pagedictkeys[i]);
+ pdf_add_name(pdf, pagedictkeys[i]);
copyObject(pdf, pdf_doc, &obj1); // preserves indirection
}
obj1.free();
@@ -739,7 +719,7 @@ void write_epdf(PDF pdf, image_dict * id
obj1.free();
op1->dictLookupNF((char *) "Resources", &obj1);
if (!obj1.isNull()) {
- pdf_puts(pdf, "/Resources ");
+ pdf_add_name(pdf, (const char *) "Resources");
copyObject(pdf, pdf_doc, &obj1);
break;
}
@@ -761,9 +741,9 @@ void write_epdf(PDF pdf, image_dict * id
// Variant A: get stream and recompress under control
// of \pdfcompresslevel
//
- // pdfbeginstream();
+ // pdf_begin_stream();
// copyStreamStream(contents->getStream());
- // pdfendstream();
+ // pdf_end_stream();
// Variant B: copy stream without recompressing
//
@@ -774,28 +754,29 @@ void write_epdf(PDF pdf, image_dict * id
obj1.free();
contents.streamGetDict()->lookup((char *) "Length", &obj1);
assert(!obj1.isNull());
- pdf_puts(pdf, "/Length ");
+ pdf_add_name(pdf, (const char *) "Length");
copyObject(pdf, pdf_doc, &obj1);
obj1.free();
- pdf_puts(pdf, "\n");
contents.streamGetDict()->lookup((char *) "Filter", &obj1);
if (!obj1.isNull()) {
- pdf_puts(pdf, "/Filter ");
+ pdf_add_name(pdf, (const char *) "Filter");
copyObject(pdf, pdf_doc, &obj1);
obj1.free();
- pdf_puts(pdf, "\n");
contents.streamGetDict()->lookup((char *) "DecodeParms", &obj1);
if (!obj1.isNull()) {
- pdf_puts(pdf, "/DecodeParms ");
+ pdf_add_name(pdf, (const char *) "DecodeParms");
copyObject(pdf, pdf_doc, &obj1);
- pdf_puts(pdf, "\n");
}
}
obj1.free();
- pdf_puts(pdf, ">>\nstream\n");
+ pdf_end_dict(pdf);
+ pdf_begin_stream(pdf);
copyStreamStream(pdf, contents.getStream()->getBaseStream());
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
} else if (contents.isArray()) {
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
for (i = 0, l = contents.arrayGetLength(); i < l; ++i) {
copyStreamStream(pdf, (contents.arrayGet(i, &obj1))->getStream());
@@ -803,13 +784,17 @@ void write_epdf(PDF pdf, image_dict * id
if (i < (l - 1)) {
// put a space between streams to be on the safe side (streams
// should have a trailing space here, but one never knows)
- pdf_puts(pdf, " ");
+ pdf_out(pdf, ' ');
}
}
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
} else { // the contents are optional, but we need to include an empty stream
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
}
// write out all indirect objects
writeRefs(pdf, pdf_doc);
@@ -880,3 +865,20 @@ void epdf_free()
delete globalParams;
isInit = gFalse;
}
+
+//**********************************************************************
+
+int poppler_version_major(void)
+{
+ return (POPPLER_VERSION_MAJOR);
+}
+
+int poppler_version_minor(void)
+{
+ return (POPPLER_VERSION_MINOR);
+}
+
+int poppler_version_micro(void)
+{
+ return (POPPLER_VERSION_MICRO);
+}
--- texk/web2c/luatexdir/image/pdftoepdf.h
+++ texk/web2c/luatexdir/image/pdftoepdf.h 2011-10-13 07:39:27.000000000 +0000
@@ -1,7 +1,7 @@
/* pdftoepdf.h
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -29,6 +29,11 @@ void read_pdf_info(image_dict *, int, in
void unrefPdfDocument(char *);
void write_epdf(PDF, image_dict *);
void epdf_check_mem(void);
+void copyReal(PDF pdf, double d);
+
+int poppler_version_major(void);
+int poppler_version_minor(void);
+int poppler_version_micro(void);
/* epdf.c --- this should go in an own header file */
--- texk/web2c/luatexdir/image/writeimg.h
+++ texk/web2c/luatexdir/image/writeimg.h 2011-10-13 07:39:27.000000000 +0000
@@ -1,7 +1,7 @@
/* writeimg.h
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -48,5 +48,6 @@ void idict_to_array(image_dict *);
void dumpimagemeta(void);
void undumpimagemeta(PDF, int, int);
scaled_whd scan_alt_rule(void);
+size_t read_file_to_buf(PDF pdf, FILE * f, size_t len);
#endif /* WRITEIMG_H */
--- texk/web2c/luatexdir/image/writeimg.w
+++ texk/web2c/luatexdir/image/writeimg.w 2011-10-13 07:39:27.000000000 +0000
@@ -1,7 +1,7 @@
% writeimg.w
% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
-% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -66,10 +66,10 @@ static const char _svn_version[] =
(http://www.libpng.org/pub/png):
3.1. PNG file signature
-
+
The first eight bytes of a PNG file always contain the following
(decimal) values:
-
+
137 80 78 71 13 10 26 10
Translation to C: |"\x89PNG\r\n\x1A\n"|
@@ -92,7 +92,7 @@ static const char _svn_version[] =
Status: Final Committee Draft
D.4.1, ID string
-
+
This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A
0x1A 0x0A.
@@ -318,7 +318,7 @@ void read_img(PDF pdf,
IMG_CLOSEINBETWEEN);
break;
case IMG_TYPE_PNG:
- read_png_info(pdf, idict, IMG_CLOSEINBETWEEN);
+ read_png_info(idict, IMG_CLOSEINBETWEEN);
break;
case IMG_TYPE_JPG:
read_jpg_info(pdf, idict, IMG_CLOSEINBETWEEN);
@@ -366,7 +366,7 @@ static image_dict *read_image(PDF pdf, c
return idict;
}
-@ scans PDF pagebox specification
+@ scans PDF pagebox specification
@c
static pdfboxspec_e scan_pdf_box_spec(void)
{
@@ -617,7 +617,6 @@ void write_img(PDF pdf, image_dict * idi
@c
void pdf_write_image(PDF pdf, int n)
{
- pdf_begin_dict(pdf, n, 0);
if (pdf->draftmode == 0)
write_img(pdf, idict_array[obj_data_ptr(pdf, n)]);
}
@@ -634,21 +633,29 @@ void check_pdfstream_dict(image_dict * i
@ @c
void write_pdfstream(PDF pdf, image_dict * idict)
{
- char s[256];
assert(img_pdfstream_ptr(idict) != NULL);
assert(img_is_bbox(idict));
- pdf_puts(pdf, "/Type /XObject\n/Subtype /Form\n");
+ pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "XObject");
+ pdf_dict_add_name(pdf, "Subtype", "Form");
if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
- pdf_printf(pdf, "%s\n", img_attr(idict));
- pdf_puts(pdf, "/FormType 1\n");
- sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", int2bp(img_bbox(idict)[0]),
- int2bp(img_bbox(idict)[1]), int2bp(img_bbox(idict)[2]),
- int2bp(img_bbox(idict)[3]));
- pdf_printf(pdf, stripzeros(s));
+ pdf_printf(pdf, "\n%s\n", img_attr(idict));
+ pdf_dict_add_int(pdf, "FormType", 1);
+ pdf_add_name(pdf, "BBox");
+ pdf_begin_array(pdf);
+ copyReal(pdf, sp2bp(img_bbox(idict)[0]));
+ copyReal(pdf, sp2bp(img_bbox(idict)[1]));
+ copyReal(pdf, sp2bp(img_bbox(idict)[2]));
+ copyReal(pdf, sp2bp(img_bbox(idict)[3]));
+ pdf_end_array(pdf);
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
if (img_pdfstream_stream(idict) != NULL)
pdf_puts(pdf, img_pdfstream_stream(idict));
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
}
@ @c
@@ -809,7 +816,7 @@ void undumpimagemeta(PDF pdf, int pdfver
}
}
-@ scans rule spec to |alt_rule|
+@ scans rule spec to |alt_rule|
@c
scaled_whd scan_alt_rule(void)
{
@@ -835,3 +842,21 @@ scaled_whd scan_alt_rule(void)
}
return alt_rule;
}
+
+@ copy file of arbitrary size to PDF buffer and flush as needed
+@c
+size_t read_file_to_buf(PDF pdf, FILE * f, size_t len)
+{
+ size_t i, j, k = 0;
+ while (len > 0) {
+ i = (size_t) (len > pdf->buf->size) ? (size_t) pdf->buf->size : len;
+ pdf_room(pdf, (int) i);
+ j = fread(pdf->buf->p, 1, i, f);
+ pdf->buf->p += j;
+ k += j;
+ len -= j;
+ if (i != j)
+ break;
+ }
+ return k;
+}
--- texk/web2c/luatexdir/image/writejbig2.w
+++ texk/web2c/luatexdir/image/writejbig2.w 2011-10-13 07:39:27.000000000 +0000
@@ -714,40 +714,52 @@ static void rd_jbig2_info(FILEINFO * fip
}
@ @c
-static void wr_jbig2(PDF pdf, FILEINFO * fip, unsigned long page)
+static void wr_jbig2(PDF pdf, image_dict * idict, FILEINFO * fip,
+ unsigned long page)
{
LITEM *slip;
PAGEINFO *pip;
SEGINFO *sip;
unsigned long i;
if (page > 0) {
+ assert(idict != NULL);
pip = find_pageinfo(&(fip->pages), page);
assert(pip != NULL);
- pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
- pdf_printf(pdf, "/Width %i\n", pip->width);
- pdf_printf(pdf, "/Height %i\n", pip->height);
- pdf_puts(pdf, "/ColorSpace /DeviceGray\n");
- pdf_puts(pdf, "/BitsPerComponent 1\n");
- pdf_printf(pdf, "/Length %lu\n",
- getstreamlen(pip->segments.first, true));
- pdf_puts(pdf, "/Filter [/JBIG2Decode]\n");
+ pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "XObject");
+ pdf_dict_add_name(pdf, "Subtype", "Image");
+ pdf_dict_add_int(pdf, "Width", pip->width);
+ pdf_dict_add_int(pdf, "Height", pip->height);
+ pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray");
+ pdf_dict_add_int(pdf, "BitsPerComponent", 1);
+ pdf_dict_add_int(pdf, "Length",
+ getstreamlen(pip->segments.first, true));
+ pdf_dict_add_name(pdf, "Filter", "JBIG2Decode");
if (fip->page0.last != NULL) {
if (fip->pdfpage0objnum == 0) {
fip->pdfpage0objnum =
(unsigned long) pdf_create_obj(pdf, obj_type_others, 0);
}
- pdf_printf(pdf, "/DecodeParms [<< /JBIG2Globals %lu 0 R >>]\n",
- fip->pdfpage0objnum);
+ pdf_add_name(pdf, "DecodeParms");
+ pdf_begin_array(pdf);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_ref(pdf, "JBIG2Globals", fip->pdfpage0objnum);
+ pdf_end_dict(pdf);
+ pdf_end_array(pdf);
}
+ pdf_end_dict(pdf);
} else {
+ assert(idict == NULL);
pip = find_pageinfo(&(fip->page0), page);
assert(pip != NULL);
- pdf_begin_dict(pdf, (int) fip->pdfpage0objnum, 0);
- pdf_printf(pdf, "/Length %lu\n",
- getstreamlen(pip->segments.first, false));
+ pdf_begin_obj(pdf, (int) fip->pdfpage0objnum, OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_int(pdf, "Length",
+ getstreamlen(pip->segments.first, false));
+ pdf_end_dict(pdf);
}
- pdf_puts(pdf, ">>\n");
- pdf_puts(pdf, "stream\n");
+ pdf_begin_stream(pdf);
fip->file = xfopen(fip->filepath, FOPEN_RBIN_MODE);
for (slip = pip->segments.first; slip != NULL; slip = slip->next) { /* loop over page segments */
sip = slip->d;
@@ -761,6 +773,7 @@ static void wr_jbig2(PDF pdf, FILEINFO *
}
}
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
xfclose(fip->file, fip->filepath);
}
@@ -822,7 +835,7 @@ void write_jbig2(PDF pdf, image_dict * i
assert(fip->phase == HAVEINFO); /* don't write before |rd_jbig2_info()| call */
pip = find_pageinfo(&(fip->pages), (unsigned long) img_pagenum(idict));
assert(pip != NULL);
- wr_jbig2(pdf, fip, pip->pagenum);
+ wr_jbig2(pdf, idict, fip, pip->pagenum);
img_file(idict) = NULL;
}
@@ -836,7 +849,7 @@ void flush_jbig2_page0_objects(PDF pdf)
for (fip = avl_t_first(&t, file_tree); fip != NULL;
fip = avl_t_next(&t)) {
if (fip->page0.last != NULL)
- wr_jbig2(pdf, fip, 0);
+ wr_jbig2(pdf, NULL, fip, 0); /* NULL: page0 */
}
}
}
--- texk/web2c/luatexdir/image/writejp2.w
+++ texk/web2c/luatexdir/image/writejp2.w 2011-10-13 07:39:27.000000000 +0000
@@ -261,22 +261,27 @@ static void reopen_jp2(image_dict * idic
void write_jp2(PDF pdf, image_dict * idict)
{
long unsigned l;
- FILE *f;
assert(idict != NULL);
if (img_file(idict) == NULL)
reopen_jp2(idict);
- xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
assert(img_jp2_ptr(idict) != NULL);
- pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
+ pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "XObject");
+ pdf_dict_add_name(pdf, "Subtype", "Image");
if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
- pdf_printf(pdf, "%s\n", img_attr(idict));
- pdf_printf(pdf, "/Width %i\n/Height %i\n/Length %i\n",
- (int) img_xsize(idict),
- (int) img_ysize(idict), (int) img_jp2_ptr(idict)->length);
- pdf_puts(pdf, "/Filter /JPXDecode\n>>\nstream\n");
- for (l = (long unsigned int) img_jp2_ptr(idict)->length, f =
- img_file(idict); l > 0; l--)
- pdf_out(pdf, xgetc(f));
+ pdf_printf(pdf, "\n%s\n", img_attr(idict));
+ pdf_dict_add_int(pdf, "Width", (int) img_xsize(idict));
+ pdf_dict_add_int(pdf, "Height", (int) img_ysize(idict));
+ pdf_dict_add_int(pdf, "Length", (int) img_jp2_ptr(idict)->length);
+ pdf_dict_add_name(pdf, "Filter", "JPXDecode");
+ pdf_end_dict(pdf);
+ pdf_begin_stream(pdf);
+ l = (long unsigned int) img_jp2_ptr(idict)->length;
+ xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
+ if (read_file_to_buf(pdf, img_file(idict), l) != l)
+ pdftex_fail("writejp2: fread failed");
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
close_and_cleanup_jp2(idict);
}
--- texk/web2c/luatexdir/image/writejpg.w
+++ texk/web2c/luatexdir/image/writejpg.w 2011-10-13 07:39:27.000000000 +0000
@@ -1,7 +1,7 @@
% writejpg.w
% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
-% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -249,41 +249,59 @@ static void reopen_jpg(PDF pdf, image_di
@ @c
void write_jpg(PDF pdf, image_dict * idict)
{
- long unsigned l;
- FILE *f;
+ size_t l;
assert(idict != NULL);
if (img_file(idict) == NULL)
reopen_jpg(pdf, idict);
assert(img_jpg_ptr(idict) != NULL);
- pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
+ pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "XObject");
+ pdf_dict_add_name(pdf, "Subtype", "Image");
if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
- pdf_printf(pdf, "%s\n", img_attr(idict));
- pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n/Length %i\n",
- (int) img_xsize(idict),
- (int) img_ysize(idict),
- (int) img_colordepth(idict), (int) img_jpg_ptr(idict)->length);
- pdf_puts(pdf, "/ColorSpace ");
+ pdf_printf(pdf, "\n%s\n", img_attr(idict));
+ pdf_dict_add_int(pdf, "Width", (int) img_xsize(idict));
+ pdf_dict_add_int(pdf, "Height", (int) img_ysize(idict));
+ pdf_dict_add_int(pdf, "BitsPerComponent", (int) img_colordepth(idict));
+ pdf_dict_add_int(pdf, "Length", (int) img_jpg_ptr(idict)->length);
if (img_colorspace(idict) != 0) {
- pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
+ pdf_dict_add_ref(pdf, "ColorSpace", (int) img_colorspace(idict));
} else {
switch (img_jpg_color(idict)) {
case JPG_GRAY:
- pdf_puts(pdf, "/DeviceGray\n");
+ pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray");
break;
case JPG_RGB:
- pdf_puts(pdf, "/DeviceRGB\n");
+ pdf_dict_add_name(pdf, "ColorSpace", "DeviceRGB");
break;
case JPG_CMYK:
- pdf_puts(pdf, "/DeviceCMYK\n/Decode [1 0 1 0 1 0 1 0]\n");
+ pdf_dict_add_name(pdf, "ColorSpace", "DeviceCMYK");
+ pdf_add_name(pdf, "Decode");
+ pdf_begin_array(pdf);
+ pdf_add_int(pdf, 1);
+ pdf_add_int(pdf, 0);
+ pdf_add_int(pdf, 1);
+ pdf_add_int(pdf, 0);
+ pdf_add_int(pdf, 1);
+ pdf_add_int(pdf, 0);
+ pdf_add_int(pdf, 1);
+ pdf_add_int(pdf, 0);
+ pdf_end_array(pdf);
break;
default:
pdftex_fail("Unsupported color space %i",
(int) img_jpg_color(idict));
}
}
- pdf_puts(pdf, "/Filter /DCTDecode\n>>\nstream\n");
- for (l = img_jpg_ptr(idict)->length, f = img_file(idict); l > 0; l--)
- pdf_out(pdf, xgetc(f));
+ pdf_dict_add_name(pdf, "Filter", "DCTDecode");
+ pdf_end_dict(pdf);
+ pdf_begin_stream(pdf);
+ assert(pdf->zip_write_state == NO_ZIP);
+ l = (size_t) img_jpg_ptr(idict)->length;
+ xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
+ if (read_file_to_buf(pdf, img_file(idict), l) != l)
+ pdftex_fail("writejpg: fread failed");
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
close_and_cleanup_jpg(idict);
}
--- texk/web2c/luatexdir/image/writepng.h
+++ texk/web2c/luatexdir/image/writepng.h 2011-10-13 07:39:27.000000000 +0000
@@ -1,7 +1,7 @@
/* writepng.h
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -18,14 +18,14 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: writepng.h 2580 2009-06-23 15:55:52Z taco $ */
+/* $Id: writepng.h 4227 2011-04-30 07:11:25Z oneiros $ */
#ifndef WRITEPNG_H
# define WRITEPNG_H
# include "image.h"
-void read_png_info(PDF, image_dict *, img_readtype_e);
+void read_png_info(image_dict *, img_readtype_e);
void write_additional_png_objects(PDF);
void write_png(PDF, image_dict *);
--- texk/web2c/luatexdir/image/writepng.w
+++ texk/web2c/luatexdir/image/writepng.w 2011-10-13 07:39:27.000000000 +0000
@@ -1,7 +1,7 @@
% writepng.w
% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
-% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -45,7 +45,7 @@ static void close_and_cleanup_png(image_
}
@ @c
-void read_png_info(PDF pdf, image_dict * idict, img_readtype_e readtype)
+void read_png_info(image_dict * idict, img_readtype_e readtype)
{
png_structp png_p;
png_infop info_p;
@@ -100,139 +100,153 @@ void read_png_info(PDF pdf, image_dict *
}
@ @c
-#define write_gray_pixel_16(r) \
- if (j % 4 == 0||j % 4 == 1) pdf_quick_out(pdf,*r++); \
- else smask[smask_ptr++] = *r++
-
-#define write_gray_pixel_8(r) \
- if (j % 2 == 0) pdf_quick_out(pdf,*r++); \
- else smask[smask_ptr++] = *r++
-
-#define write_rgb_pixel_16(r) \
- if (!(j % 8 == 6||j % 8 == 7)) pdf_quick_out(pdf,*r++); \
- else smask[smask_ptr++] = *r++
-
-#define write_rgb_pixel_8(r) \
- if (j % 4 != 3) pdf_quick_out(pdf,*r++); \
- else smask[smask_ptr++] = *r++
+#define write_gray_pixel_16(r) \
+ if (j % 4 == 0 || j % 4 == 1) \
+ pdf_quick_out(pdf, *r++); \
+ else \
+ smask[smask_ptr++] = *r++ \
+
+#define write_gray_pixel_8(r) \
+ if (j % 2 == 0) \
+ pdf_quick_out(pdf, *r++); \
+ else \
+ smask[smask_ptr++] = *r++
+
+#define write_rgb_pixel_16(r) \
+ if (!(j % 8 == 6 || j % 8 == 7)) \
+ pdf_quick_out(pdf, *r++); \
+ else \
+ smask[smask_ptr++] = *r++
+
+#define write_rgb_pixel_8(r) \
+ if (j % 4 != 3) \
+ pdf_quick_out(pdf, *r++); \
+ else \
+ smask[smask_ptr++] = *r++
#define write_simple_pixel(r) pdf_quick_out(pdf,*r++)
-#define write_noninterlaced(outmac) \
- for (i = 0; i < (int)png_get_image_height (png_p, info_p); i++) { \
- png_read_row(png_p, row, NULL); \
- r = row; \
- k = (int)png_get_rowbytes(png_p, info_p); \
- while(k > 0) { \
- l = (k > pdf->buf_size)? pdf->buf_size : k; \
- pdf_room(pdf,l); \
- for (j = 0; j < l; j++) { \
- outmac; \
- } \
- k -= l; \
- } \
- }
+#define write_noninterlaced(outmac) \
+ for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) { \
+ png_read_row(png_p, row, NULL); \
+ r = row; \
+ k = (size_t) png_get_rowbytes(png_p, info_p); \
+ while (k > 0) { \
+ l = (k > pdf->buf->size) ? pdf->buf->size : k; \
+ pdf_room(pdf, l); \
+ for (j = 0; j < l; j++) { \
+ outmac; \
+ } \
+ k -= l; \
+ } \
+ }
+
+#define write_interlaced(outmac) \
+ for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) { \
+ row = rows[i]; \
+ k = (size_t) png_get_rowbytes(png_p, info_p); \
+ while (k > 0) { \
+ l = (k > pdf->buf->size) ? pdf->buf->size : k; \
+ pdf_room(pdf, l); \
+ for (j = 0; j < l; j++) { \
+ outmac; \
+ } \
+ k -= l; \
+ } \
+ xfree(rows[i]); \
+ }
-#define write_interlaced(outmac) \
- for (i = 0; i < (int)png_get_image_height (png_p, info_p); i++) { \
- row = rows[i]; \
- k = (int)png_get_rowbytes(png_p, info_p); \
- while(k > 0) { \
- l = (k > pdf->buf_size)?pdf->buf_size: k;\
- pdf_room(pdf,l); \
- for (j = 0; j < l; j++) { \
- outmac; \
- } \
- k -= l; \
- } \
- xfree(rows[i]); \
- }
+@ @c
+static void write_palette_streamobj(PDF pdf, int palette_objnum,
+ png_colorp palette, int num_palette)
+{
+ int i;
+ if (palette_objnum == 0)
+ return;
+ assert(palette != NULL);
+ pdf_begin_obj(pdf, palette_objnum, OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
+ pdf_begin_stream(pdf);
+ for (i = 0; i < num_palette; i++) {
+ pdf_room(pdf, 3);
+ pdf_quick_out(pdf, palette[i].red);
+ pdf_quick_out(pdf, palette[i].green);
+ pdf_quick_out(pdf, palette[i].blue);
+ }
+ pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
+}
@ @c
-static void write_png_palette(PDF pdf, image_dict * idict)
+static void write_smask_streamobj(PDF pdf, image_dict * idict, int smask_objnum,
+ png_bytep smask, int smask_size)
{
- int i, j, k, l;
+ int i;
png_structp png_p = img_png_png_ptr(idict);
png_infop info_p = img_png_info_ptr(idict);
- png_bytep row, r, *rows;
- int palette_objnum = 0;
- png_colorp palette;
- int num_palette;
-
- png_get_PLTE(png_p, info_p, &palette, &num_palette);
-
- if (img_colorspace(idict) != 0) {
- pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
- } else {
- palette_objnum = pdf_create_obj(pdf, obj_type_others, 0);
- pdf_printf(pdf, "[/Indexed /DeviceRGB %i %i 0 R]\n",
- (int) (num_palette - 1), (int) palette_objnum);
- }
+ png_byte bitdepth = png_get_bit_depth(png_p, info_p);
+ pdf_begin_obj(pdf, smask_objnum, OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "XObject");
+ pdf_dict_add_name(pdf, "Subtype", "Image");
+ if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
+ pdf_printf(pdf, "\n%s\n", img_attr(idict));
+ pdf_dict_add_int(pdf, "Width", (int) png_get_image_width(png_p, info_p));
+ pdf_dict_add_int(pdf, "Height", (int) png_get_image_height(png_p, info_p));
+ pdf_dict_add_int(pdf, "BitsPerComponent", (bitdepth == 16 ? 8 : bitdepth));
+ pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray");
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
- if (png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE) {
- row = xtalloc(png_get_rowbytes(png_p, info_p), png_byte);
- write_noninterlaced(write_simple_pixel(r));
- xfree(row);
- } else {
- if (png_get_image_height (png_p, info_p) * png_get_rowbytes(png_p, info_p) >= 10240000L)
- pdftex_warn
- ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)");
- rows = xtalloc(png_get_image_height (png_p, info_p), png_bytep);
- for (i = 0; (unsigned) i < png_get_image_height (png_p, info_p); i++)
- rows[i] = xtalloc(png_get_rowbytes(png_p, info_p), png_byte);
- png_read_image(png_p, rows);
- write_interlaced(write_simple_pixel(row));
- xfree(rows);
+ for (i = 0; i < smask_size; i++) {
+ if (i % 8 == 0)
+ pdf_room(pdf, 8);
+ pdf_quick_out(pdf, smask[i]);
+ if (bitdepth == 16)
+ i++;
}
pdf_end_stream(pdf);
- if (palette_objnum > 0) {
- pdf_begin_dict(pdf, palette_objnum, 0);
- pdf_begin_stream(pdf);
- for (i = 0; i < num_palette; i++) {
- pdf_room(pdf, 3);
- pdf_quick_out(pdf, palette[i].red);
- pdf_quick_out(pdf, palette[i].green);
- pdf_quick_out(pdf, palette[i].blue);
- }
- pdf_end_stream(pdf);
- }
+ pdf_end_obj(pdf);
}
@ @c
static void write_png_gray(PDF pdf, image_dict * idict)
{
- int i, j, k, l;
+ int i;
+ size_t j, k, l;
png_structp png_p = img_png_png_ptr(idict);
png_infop info_p = img_png_info_ptr(idict);
png_bytep row, r, *rows;
- if (img_colorspace(idict) != 0) {
- pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
- } else {
- pdf_puts(pdf, "/DeviceGray\n");
- }
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
if (png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE) {
row = xtalloc(png_get_rowbytes(png_p, info_p), png_byte);
write_noninterlaced(write_simple_pixel(r));
xfree(row);
} else {
- if (png_get_image_height (png_p, info_p) * png_get_rowbytes(png_p, info_p) >= 10240000L)
+ if (png_get_image_height(png_p, info_p) *
+ png_get_rowbytes(png_p, info_p) >= 10240000L)
pdftex_warn
("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)");
- rows = xtalloc(png_get_image_height (png_p, info_p), png_bytep);
- for (i = 0; (unsigned) i < png_get_image_height (png_p, info_p); i++)
+ rows = xtalloc(png_get_image_height(png_p, info_p), png_bytep);
+ for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++)
rows[i] = xtalloc(png_get_rowbytes(png_p, info_p), png_byte);
png_read_image(png_p, rows);
write_interlaced(write_simple_pixel(row));
xfree(rows);
}
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
}
@ @c
static void write_png_gray_alpha(PDF pdf, image_dict * idict)
{
- int i, j, k, l;
+ int i;
+ size_t j, k, l;
png_structp png_p = img_png_png_ptr(idict);
png_infop info_p = img_png_info_ptr(idict);
png_bytep row, r, *rows;
@@ -240,34 +254,35 @@ static void write_png_gray_alpha(PDF pdf
png_bytep smask;
int smask_ptr = 0;
int smask_size = 0;
- png_byte bitdepth;
- if (img_colorspace(idict) != 0) {
- pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
- } else {
- pdf_puts(pdf, "/DeviceGray\n");
- }
smask_objnum = pdf_create_obj(pdf, obj_type_others, 0);
- pdf_printf(pdf, "/SMask %i 0 R\n", (int) smask_objnum);
- smask_size = (int) ((png_get_rowbytes(png_p, info_p) / 2) * png_get_image_height (png_p, info_p));
+ pdf_dict_add_ref(pdf, "SMask", (int) smask_objnum);
+ smask_size =
+ (int) ((png_get_rowbytes(png_p, info_p) / 2) *
+ png_get_image_height(png_p, info_p));
smask = xtalloc((unsigned) smask_size, png_byte);
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
if (png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE) {
row = xtalloc(png_get_rowbytes(png_p, info_p), png_byte);
- if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor != 0)) {
+ if ((png_get_bit_depth(png_p, info_p) == 16)
+ && (pdf->image_hicolor != 0)) {
write_noninterlaced(write_gray_pixel_16(r));
} else {
write_noninterlaced(write_gray_pixel_8(r));
}
xfree(row);
} else {
- if (png_get_image_height (png_p, info_p) * png_get_rowbytes(png_p, info_p) >= 10240000L)
+ if (png_get_image_height(png_p, info_p) *
+ png_get_rowbytes(png_p, info_p) >= 10240000L)
pdftex_warn
("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)");
- rows = xtalloc(png_get_image_height (png_p, info_p), png_bytep);
- for (i = 0; (unsigned) i < png_get_image_height (png_p, info_p); i++)
+ rows = xtalloc(png_get_image_height(png_p, info_p), png_bytep);
+ for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++)
rows[i] = xtalloc(png_get_rowbytes(png_p, info_p), png_byte);
png_read_image(png_p, rows);
- if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor != 0)) {
+ if ((png_get_bit_depth(png_p, info_p) == 16)
+ && (pdf->image_hicolor != 0)) {
write_interlaced(write_gray_pixel_16(row));
} else {
write_interlaced(write_gray_pixel_8(row));
@@ -275,65 +290,16 @@ static void write_png_gray_alpha(PDF pdf
xfree(rows);
}
pdf_end_stream(pdf);
- pdf_flush(pdf);
- /* now write the Smask object */
- bitdepth = png_get_bit_depth (png_p, info_p);
- pdf_begin_dict(pdf, smask_objnum, 0);
- pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
- if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
- pdf_printf(pdf, "%s\n", img_attr(idict));
- pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n",
- (int) png_get_image_width (png_p, info_p),
- (int) png_get_image_height (png_p, info_p),
- (bitdepth == 16 ? 8 : bitdepth));
- pdf_puts(pdf, "/ColorSpace /DeviceGray\n");
- pdf_begin_stream(pdf);
- for (i = 0; i < smask_size; i++) {
- if (i % 8 == 0)
- pdf_room(pdf, 8);
- pdf_quick_out(pdf, smask[i]);
- if (bitdepth == 16)
- i++;
- }
- pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
+ write_smask_streamobj(pdf, idict, smask_objnum, smask, smask_size);
xfree(smask);
}
@ @c
-static void write_png_rgb(PDF pdf, image_dict * idict)
-{
- int i, j, k, l;
- png_structp png_p = img_png_png_ptr(idict);
- png_infop info_p = img_png_info_ptr(idict);
- png_bytep row, r, *rows;
- if (img_colorspace(idict) != 0) {
- pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
- } else {
- pdf_puts(pdf, "/DeviceRGB\n");
- }
- pdf_begin_stream(pdf);
- if (png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE) {
- row = xtalloc(png_get_rowbytes(png_p, info_p), png_byte);
- write_noninterlaced(write_simple_pixel(r));
- xfree(row);
- } else {
- if (png_get_image_height (png_p, info_p) * png_get_rowbytes(png_p, info_p) >= 10240000L)
- pdftex_warn
- ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)");
- rows = xtalloc(png_get_image_height (png_p, info_p), png_bytep);
- for (i = 0; (unsigned) i < png_get_image_height (png_p, info_p); i++)
- rows[i] = xtalloc(png_get_rowbytes(png_p, info_p), png_byte);
- png_read_image(png_p, rows);
- write_interlaced(write_simple_pixel(row));
- xfree(rows);
- }
- pdf_end_stream(pdf);
-}
-
-@ @c
static void write_png_rgb_alpha(PDF pdf, image_dict * idict)
{
- int i, j, k, l;
+ int i;
+ size_t j, k, l;
png_structp png_p = img_png_png_ptr(idict);
png_infop info_p = img_png_info_ptr(idict);
png_bytep row, r, *rows;
@@ -341,34 +307,35 @@ static void write_png_rgb_alpha(PDF pdf,
png_bytep smask;
int smask_ptr = 0;
int smask_size = 0;
- png_byte bitdepth;
- if (img_colorspace(idict) != 0) {
- pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
- } else {
- pdf_puts(pdf, "/DeviceRGB\n");
- }
smask_objnum = pdf_create_obj(pdf, obj_type_others, 0);
- pdf_printf(pdf, "/SMask %i 0 R\n", (int) smask_objnum);
- smask_size = (int) ((png_get_rowbytes (png_p, info_p) / 4) * png_get_image_height (png_p, info_p));
+ pdf_dict_add_ref(pdf, "SMask", (int) smask_objnum);
+ smask_size =
+ (int) ((png_get_rowbytes(png_p, info_p) / 4) *
+ png_get_image_height(png_p, info_p));
smask = xtalloc((unsigned) smask_size, png_byte);
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
if (png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE) {
row = xtalloc(png_get_rowbytes(png_p, info_p), png_byte);
- if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor != 0)) {
+ if ((png_get_bit_depth(png_p, info_p) == 16)
+ && (pdf->image_hicolor != 0)) {
write_noninterlaced(write_rgb_pixel_16(r));
} else {
write_noninterlaced(write_rgb_pixel_8(r));
}
xfree(row);
} else {
- if (png_get_image_height (png_p, info_p) * png_get_rowbytes(png_p, info_p) >= 10240000L)
+ if (png_get_image_height(png_p, info_p) *
+ png_get_rowbytes(png_p, info_p) >= 10240000L)
pdftex_warn
("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)");
- rows = xtalloc(png_get_image_height (png_p, info_p), png_bytep);
- for (i = 0; (unsigned) i < png_get_image_height (png_p, info_p); i++)
+ rows = xtalloc(png_get_image_height(png_p, info_p), png_bytep);
+ for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++)
rows[i] = xtalloc(png_get_rowbytes(png_p, info_p), png_byte);
png_read_image(png_p, rows);
- if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor != 0)) {
+ if ((png_get_bit_depth(png_p, info_p) == 16)
+ && (pdf->image_hicolor != 0)) {
write_interlaced(write_rgb_pixel_16(row));
} else {
write_interlaced(write_rgb_pixel_8(row));
@@ -376,47 +343,29 @@ static void write_png_rgb_alpha(PDF pdf,
xfree(rows);
}
pdf_end_stream(pdf);
- pdf_flush(pdf);
- /* now write the Smask object */
- if (smask_objnum > 0) {
- bitdepth = png_get_bit_depth (png_p, info_p);
- pdf_begin_dict(pdf, smask_objnum, 0);
- pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
- if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
- pdf_printf(pdf, "%s\n", img_attr(idict));
- pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n",
- (int) png_get_image_width (png_p, info_p),
- (int) png_get_image_height (png_p, info_p),
- (bitdepth == 16 ? 8 : bitdepth));
- pdf_puts(pdf, "/ColorSpace /DeviceGray\n");
- pdf_begin_stream(pdf);
- for (i = 0; i < smask_size; i++) {
- if (i % 8 == 0)
- pdf_room(pdf, 8);
- pdf_quick_out(pdf, smask[i]);
- if (bitdepth == 16)
- i++;
- }
- xfree(smask);
- pdf_end_stream(pdf);
- }
+ pdf_end_obj(pdf);
+ write_smask_streamobj(pdf, idict, smask_objnum, smask, smask_size);
+ xfree(smask);
}
-@ The |copy_png| function is from Hartmut Henkel. The goal is to use
-pdf's native FlateDecode support if that is possible.
-
-Only a subset of the png files allows this, but when possible it
-greatly improves inclusion speed.
-
-Code cheerfully gleaned from Thomas Merz' PDFlib,
-file |p_png.c| "SPNG - Simple PNG"
-
+@ The |copy_png| code is cheerfully gleaned from Thomas Merz' PDFlib,
+file |p_png.c| ``SPNG - Simple PNG''.
+The goal is to use pdf's native FlateDecode support, if that is possible.
+Only a subset of the png files allows this, but for these it greatly
+improves inclusion speed.
+
+In the ``PNG Copy'' mode only the IDAT chunks are copied;
+all other chunks from the PNG file are discarded.
+If there are any other chunks in the PNG file,
+which might influence the visual appearance of the image,
+or if image processing like gamma change is requested,
+the ``PNG Copy'' function must be skipped; therefore the lengthy tests.
@c
-static int spng_getint(FILE * fp)
+static int spng_getint(FILE * f)
{
unsigned char buf[4];
- if (fread(buf, 1, 4, fp) != 4)
+ if (fread(buf, 1, 4, f) != 4)
pdftex_fail("writepng: reading chunk type failed");
return ((((((int) buf[0] << 8) + buf[1]) << 8) + buf[2]) << 8) + buf[3];
}
@@ -426,22 +375,22 @@ static int spng_getint(FILE * fp)
static void copy_png(PDF pdf, image_dict * idict)
{
+ int type, streamlength = 0, idat = 0;
+ size_t len;
+ boolean endflag = false;
+ FILE *f;
png_structp png_p;
png_infop info_p;
- FILE *fp;
- int i, len, type, streamlength = 0;
- boolean endflag = false;
- int idat = 0; /* flag to check continuous IDAT chunks sequence */
assert(idict != NULL);
png_p = img_png_png_ptr(idict);
info_p = img_png_info_ptr(idict);
- fp = (FILE *) png_get_io_ptr(png_p);
+ f = (FILE *) png_get_io_ptr(png_p);
/* 1st pass to find overall stream /Length */
- if (fseek(fp, 8, SEEK_SET) != 0)
- pdftex_fail("writepng: fseek in PNG file failed");
+ if (fseek(f, 8, SEEK_SET) != 0)
+ pdftex_fail("writepng: fseek in PNG file failed (1)");
do {
- len = spng_getint(fp);
- type = spng_getint(fp);
+ len = spng_getint(f);
+ type = spng_getint(f);
switch (type) {
case SPNG_CHUNK_IEND:
endflag = true;
@@ -449,64 +398,64 @@ static void copy_png(PDF pdf, image_dict
case SPNG_CHUNK_IDAT:
streamlength += len;
default:
- if (fseek(fp, len + 4, SEEK_CUR) != 0)
- pdftex_fail("writepng: fseek in PNG file failed");
+ if (fseek(f, len + 4, SEEK_CUR) != 0)
+ pdftex_fail("writepng: fseek in PNG file failed (2)");
}
} while (endflag == false);
- pdf_printf(pdf, "/Length %d\n"
- "/Filter/FlateDecode\n"
- "/DecodeParms<<"
- "/Colors %d"
- "/Columns %u"
- "/BitsPerComponent %i"
- "/Predictor 10>>\n>>\nstream\n", streamlength,
- png_get_color_type (png_p, info_p) == 2 ? 3 : 1,
- png_get_image_width (png_p, info_p),
- png_get_bit_depth (png_p, info_p));
+ pdf_dict_add_int(pdf, "Length", streamlength);
+ pdf_dict_add_name(pdf, "Filter", "FlateDecode");
+ pdf_add_name(pdf, "DecodeParms");
+ pdf_begin_dict(pdf);
+ pdf_dict_add_int(pdf, "Colors",
+ png_get_color_type(png_p,
+ info_p) == PNG_COLOR_TYPE_RGB ? 3 : 1);
+ pdf_dict_add_int(pdf, "Columns", png_get_image_width(png_p, info_p));
+ pdf_dict_add_int(pdf, "BitsPerComponent", png_get_bit_depth(png_p, info_p));
+ pdf_dict_add_int(pdf, "Predictor", 10);
+ pdf_end_dict(pdf);
+ pdf_end_dict(pdf);
+ pdf_begin_stream(pdf);
+ assert(pdf->zip_write_state == NO_ZIP); /* the PNG stream is already compressed */
/* 2nd pass to copy data */
endflag = false;
- if (fseek(fp, 8, SEEK_SET) != 0)
- pdftex_fail("writepng: fseek in PNG file failed");
+ if (fseek(f, 8, SEEK_SET) != 0)
+ pdftex_fail("writepng: fseek in PNG file failed (3)");
do {
- len = spng_getint(fp);
- type = spng_getint(fp);
+ len = spng_getint(f);
+ type = spng_getint(f);
switch (type) {
case SPNG_CHUNK_IDAT: /* do copy */
if (idat == 2)
pdftex_fail("writepng: IDAT chunk sequence broken");
idat = 1;
- while (len > 0) {
- i = (len > pdf->buf_size) ? pdf->buf_size : len;
- pdf_room(pdf, i);
- fread(&pdf->buf[pdf->ptr], 1, (size_t) i, fp);
- pdf->ptr += i;
- len -= i;
- }
- if (fseek(fp, 4, SEEK_CUR) != 0)
- pdftex_fail("writepng: fseek in PNG file failed");
+ if (read_file_to_buf(pdf, f, len) != len)
+ pdftex_fail("writepng: fread failed");
+ if (fseek(f, 4, SEEK_CUR) != 0)
+ pdftex_fail("writepng: fseek in PNG file failed (4)");
break;
case SPNG_CHUNK_IEND: /* done */
- pdf_end_stream(pdf);
endflag = true;
break;
default:
if (idat == 1)
idat = 2;
- if (fseek(fp, len + 4, SEEK_CUR) != 0)
- pdftex_fail("writepng: fseek in PNG file failed");
+ if (fseek(f, len + 4, SEEK_CUR) != 0)
+ pdftex_fail("writepng: fseek in PNG file failed (5)");
}
} while (endflag == false);
+ pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
}
@ @c
-static void reopen_png(PDF pdf, image_dict * idict)
+static void reopen_png(image_dict * idict)
{
int width, height, xres, yres;
width = img_xsize(idict); /* do consistency check */
height = img_ysize(idict);
xres = img_xres(idict);
yres = img_yres(idict);
- read_png_info(pdf, idict, IMG_KEEPOPEN);
+ read_png_info(idict, IMG_KEEPOPEN);
if (width != img_xsize(idict) || height != img_ysize(idict)
|| xres != img_xres(idict) || yres != img_yres(idict))
pdftex_fail("writepng: image dimensions have changed");
@@ -517,29 +466,24 @@ static boolean last_png_needs_page_group
void write_png(PDF pdf, image_dict * idict)
{
+#ifndef PNG_FP_1
+ /* for libpng < 1.5.0 */
+# define PNG_FP_1 100000
+#endif
+ int num_palette, palette_objnum = 0;
boolean png_copy = true;
double gamma = 0.0;
png_fixed_point int_file_gamma = 0;
-#ifndef PNG_FP_1
- /* for libpng < 1.5.0 */
-#define PNG_FP_1 100000
-#endif
- int i;
- int palette_objnum = 0;
png_structp png_p;
png_infop info_p;
+ png_colorp palette;
assert(idict != NULL);
last_png_needs_page_group = false;
if (img_file(idict) == NULL)
- reopen_png(pdf, idict);
+ reopen_png(idict);
assert(img_png_ptr(idict) != NULL);
png_p = img_png_png_ptr(idict);
info_p = img_png_info_ptr(idict);
- if (pdf->minor_version < 5)
- pdf->image_hicolor = 0;
- pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
- if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
- pdf_printf(pdf, "%s\n", img_attr(idict));
/* simple transparency support */
if (png_get_valid(png_p, info_p, PNG_INFO_tRNS)) {
png_set_tRNS_to_alpha(png_p);
@@ -575,11 +519,44 @@ void write_png(PDF pdf, image_dict * idi
(void) png_set_interlace_handling(png_p);
png_read_update_info(png_p, info_p);
- pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n",
- (int) png_get_image_width(png_p, info_p),
- (int) png_get_image_height(png_p, info_p),
- (int) png_get_bit_depth(png_p, info_p));
- pdf_puts(pdf, "/ColorSpace ");
+ pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "XObject");
+ pdf_dict_add_name(pdf, "Subtype", "Image");
+ if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
+ pdf_printf(pdf, "\n%s\n", img_attr(idict));
+ pdf_dict_add_int(pdf, "Width", (int) png_get_image_width(png_p, info_p));
+ pdf_dict_add_int(pdf, "Height", (int) png_get_image_height(png_p, info_p));
+ pdf_dict_add_int(pdf, "BitsPerComponent",
+ (int) png_get_bit_depth(png_p, info_p));
+ if (img_colorspace(idict) != 0) {
+ pdf_dict_add_ref(pdf, "ColorSpace", (int) img_colorspace(idict));
+ } else {
+ switch (png_get_color_type(png_p, info_p)) {
+ case PNG_COLOR_TYPE_PALETTE:
+ png_get_PLTE(png_p, info_p, &palette, &num_palette);
+ palette_objnum = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_add_name(pdf, "ColorSpace");
+ pdf_begin_array(pdf);
+ pdf_add_name(pdf, "Indexed");
+ pdf_add_name(pdf, "DeviceRGB"); /* base; PDFRef. 4.5.5 */
+ pdf_add_int(pdf, (int) (num_palette - 1)); /* hival */
+ pdf_add_ref(pdf, (int) palette_objnum); /* lookup */
+ pdf_end_array(pdf);
+ break;
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray");
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ pdf_dict_add_name(pdf, "ColorSpace", "DeviceRGB");
+ break;
+ default:
+ pdftex_fail("unsupported type of color_type <%i>",
+ png_get_color_type(png_p, info_p));
+ }
+ }
if (png_copy && pdf->minor_version > 1
&& png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE
&& (png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_GRAY
@@ -594,43 +571,11 @@ void write_png(PDF pdf, image_dict * idi
&& !png_get_valid(png_p, info_p, PNG_INFO_bKGD)
&& !png_get_valid(png_p, info_p, PNG_INFO_hIST)
&& !png_get_valid(png_p, info_p, PNG_INFO_tRNS)
- && !png_get_valid(png_p, info_p, PNG_INFO_sPLT)
- ) {
- /* Copy PNG */
- png_colorp palette;
- int num_palette;
-
- png_get_PLTE(png_p, info_p, &palette, &num_palette);
- if (img_colorspace(idict) != 0) {
- pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
- } else {
- switch (png_get_color_type(png_p, info_p)) {
- case PNG_COLOR_TYPE_PALETTE:
- palette_objnum = pdf_create_obj(pdf, obj_type_others, 0);
- pdf_printf(pdf, "[/Indexed /DeviceRGB %i %i 0 R]\n",
- num_palette - 1, (int) palette_objnum);
- break;
- case PNG_COLOR_TYPE_GRAY:
- pdf_puts(pdf, "/DeviceGray\n");
- break;
- default: /* RGB */
- pdf_puts(pdf, "/DeviceRGB\n");
- };
- }
+ && !png_get_valid(png_p, info_p, PNG_INFO_sPLT)) {
+ /* PNG copy */
if (tracefilenames)
tex_printf(" (PNG copy)");
copy_png(pdf, idict);
- if (palette_objnum > 0) {
- pdf_begin_dict(pdf, palette_objnum, 0);
- pdf_begin_stream(pdf);
- for (i = 0; i < num_palette; i++) {
- pdf_room(pdf, 3);
- pdf_quick_out(pdf, palette[i].red);
- pdf_quick_out(pdf, palette[i].green);
- pdf_quick_out(pdf, palette[i].blue);
- }
- pdf_end_stream(pdf);
- }
} else {
if (0) {
tex_printf(" *** PNG copy skipped because: ");
@@ -667,9 +612,8 @@ void write_png(PDF pdf, image_dict * idi
}
switch (png_get_color_type(png_p, info_p)) {
case PNG_COLOR_TYPE_PALETTE:
- write_png_palette(pdf, idict);
- break;
case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_RGB:
write_png_gray(pdf, idict);
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
@@ -679,22 +623,18 @@ void write_png(PDF pdf, image_dict * idi
} else
write_png_gray(pdf, idict);
break;
- case PNG_COLOR_TYPE_RGB:
- write_png_rgb(pdf, idict);
- break;
case PNG_COLOR_TYPE_RGB_ALPHA:
if (pdf->minor_version >= 4) {
write_png_rgb_alpha(pdf, idict);
last_png_needs_page_group = true;
} else
- write_png_rgb(pdf, idict);
+ write_png_gray(pdf, idict);
break;
default:
- pdftex_fail("unsupported type of color_type <%i>",
- png_get_color_type(png_p, info_p));
+ assert(0);
}
}
- pdf_flush(pdf);
+ write_palette_streamobj(pdf, palette_objnum, palette, num_palette);
close_and_cleanup_png(idict);
}
@@ -709,7 +649,7 @@ void write_additional_png_objects(PDF pd
(void) pdf;
(void) transparent_page_group;
(void) transparent_page_group_was_written;
- return; /* this interferes with current macro-based usage and cannot be configured */
+ return; /* this interferes with current macro-based usage and cannot be configured */
#if 0
if (last_png_needs_page_group) {
if (!transparent_page_group_was_written && transparent_page_group > 1) {
@@ -719,9 +659,13 @@ void write_additional_png_objects(PDF pd
if (pdf->compress_level == 0) {
pdf_puts(pdf, "%PTEX Group needed for transparent pngs\n");
}
- pdf_puts
- (pdf,
- "<</Type/Group /S/Transparency /CS/DeviceRGB /I true /K true>>\n");
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Group");
+ pdf_dict_add_name(pdf, "S", "Transparency");
+ pdf_dict_add_name(pdf, "CS", "DeviceRGB");
+ pdf_dict_add_bool(pdf, "I", 1);
+ pdf_dict_add_bool(pdf, "K", 1);
+ pdf_end_dict(pdf);
pdf_end_obj(pdf);
}
}
--- texk/web2c/luatexdir/lua/lcallbacklib.c
+++ texk/web2c/luatexdir/lua/lcallbacklib.c 2011-10-13 07:39:27.000000000 +0000
@@ -47,6 +47,7 @@ static const char *const callbacknames[]
"find_pk_file", "read_pk_file",
"show_error_hook",
"process_input_buffer", "process_output_buffer",
+ "process_jobname",
"start_page_number", "stop_page_number",
"start_run", "stop_run",
"define_font",
--- texk/web2c/luatexdir/lua/lepdflib.cc
+++ texk/web2c/luatexdir/lua/lepdflib.cc 2011-10-13 07:39:27.000000000 +0000
@@ -54,10 +54,11 @@ static const char *ErrorCodeNames[] = {
#define M_Annots "Annots"
#define M_Array "Array"
#define M_Catalog "Catalog"
-#define M_EmbFile "EmbFile"
#define M_Dict "Dict"
+#define M_EmbFile "EmbFile"
#define M_GooString "GooString"
#define M_LinkDest "LinkDest"
+#define M_Link "Link"
#define M_Links "Links"
#define M_Object "Object"
#define M_Page "Page"
@@ -65,8 +66,8 @@ static const char *ErrorCodeNames[] = {
#define M_PDFRectangle "PDFRectangle"
#define M_Ref "Ref"
#define M_Stream "Stream"
-#define M_XRef "XRef"
#define M_XRefEntry "XRefEntry"
+#define M_XRef "XRef"
//**********************************************************************
@@ -89,9 +90,13 @@ new_poppler_userdata(AnnotBorder);
new_poppler_userdata(Annots);
new_poppler_userdata(Array);
new_poppler_userdata(Catalog);
-new_poppler_userdata(EmbFile);
new_poppler_userdata(Dict);
+#if POPPLER_VERSION_MAJOR == 0 && (POPPLER_VERSION_MINOR < 17 || \
+ ( POPPLER_VERSION_MINOR == 17 && POPPLER_VERSION_MICRO < 2))
+new_poppler_userdata(EmbFile);
+#endif
//new_poppler_userdata(GooString);
+new_poppler_userdata(Link);
new_poppler_userdata(LinkDest);
new_poppler_userdata(Links);
new_poppler_userdata(Object);
@@ -100,7 +105,7 @@ new_poppler_userdata(PDFRectangle);
new_poppler_userdata(Ref);
new_poppler_userdata(Stream);
new_poppler_userdata(XRef);
-//new_poppler_userdata(XRefEntry);
+new_poppler_userdata(XRefEntry);
//**********************************************************************
@@ -393,7 +398,11 @@ static int m_Annot__gc(lua_State * L)
printf("\n===== Annot GC ===== uin=<%p>\n", uin);
#endif
if (uin->atype == ALLOC_LEPDF)
+#if POPPLER_VERSION_MAJOR == 0 && POPPLER_VERSION_MINOR < 17
delete(Annot *) uin->d;
+#else
+ ((Annot *) uin->d)->decRefCnt();
+#endif
return 0;
}
@@ -410,6 +419,8 @@ static const struct luaL_Reg Annot_m[] =
//**********************************************************************
// AnnotBorderStyle
+#if POPPLER_VERSION_MAJOR == 0 && POPPLER_VERSION_MINOR < 17
+
m_poppler_get_DOUBLE(AnnotBorderStyle, getWidth);
m_poppler__tostring(AnnotBorderStyle);
@@ -420,9 +431,9 @@ static int m_Annots__gc(lua_State * L)
uin = (udstruct *) luaL_checkudata(L, 1, M_Annots);
if (uin->pd != NULL && uin->pd->pc != uin->pc)
pdfdoc_changed_error(L);
-#ifdef DEBUG
+# ifdef DEBUG
printf("\n===== Annots GC ===== uin=<%p>\n", uin);
-#endif
+# endif
if (uin->atype == ALLOC_LEPDF)
delete(Annots *) uin->d;
return 0;
@@ -435,6 +446,8 @@ static const struct luaL_Reg AnnotBorder
{NULL, NULL} // sentinel
};
+#endif
+
//**********************************************************************
// Annots
@@ -684,6 +697,8 @@ static int m_Catalog_findDest(lua_State
m_poppler_get_poppler(Catalog, Object, getDests);
m_poppler_get_INT(Catalog, numEmbeddedFiles);
+#if POPPLER_VERSION_MAJOR == 0 && (POPPLER_VERSION_MINOR < 17 || \
+ ( POPPLER_VERSION_MINOR == 17 && POPPLER_VERSION_MICRO < 2))
static int m_Catalog_embeddedFile(lua_State * L)
{
EmbFile *ef;
@@ -707,6 +722,7 @@ static int m_Catalog_embeddedFile(lua_St
lua_pushnil(L);
return 1;
}
+#endif
m_poppler_get_INT(Catalog, numJS);
@@ -749,7 +765,9 @@ static const struct luaL_Reg Catalog_m[]
{"findDest", m_Catalog_findDest},
{"getDests", m_Catalog_getDests},
{"numEmbeddedFiles", m_Catalog_numEmbeddedFiles},
+#if POPPLER_VERSION_MAJOR == 0 && POPPLER_VERSION_MINOR < 17
{"embeddedFile", m_Catalog_embeddedFile},
+#endif
{"numJS", m_Catalog_numJS},
{"getJS", m_Catalog_getJS},
{"getOutline", m_Catalog_getOutline},
@@ -761,6 +779,9 @@ static const struct luaL_Reg Catalog_m[]
//**********************************************************************
// EmbFile
+#if POPPLER_VERSION_MAJOR == 0 && (POPPLER_VERSION_MINOR < 17 || \
+ ( POPPLER_VERSION_MINOR == 17 && POPPLER_VERSION_MICRO < 2))
+
m_poppler_get_GOOSTRING(EmbFile, name);
m_poppler_get_GOOSTRING(EmbFile, description);
m_poppler_get_INT(EmbFile, size);
@@ -778,6 +799,7 @@ static int m_EmbFile_streamObject(lua_St
uout = new_Object_userdata(L);
uout->d = new Object(); // automatic init to type "none"
((EmbFile *) uin->d)->streamObject().copy((Object *) uout->d);
+ uout->atype = ALLOC_LEPDF;
uout->pc = uin->pc;
uout->pd = uin->pd;
return 1;
@@ -801,6 +823,8 @@ static const struct luaL_Reg EmbFile_m[]
{NULL, NULL} // sentinel
};
+#endif
+
//**********************************************************************
// Dict
@@ -1032,6 +1056,38 @@ static const struct luaL_Reg GooString_m
};
//**********************************************************************
+// Link
+
+#if 0
+m_poppler_get_BOOL(Link, isOk);
+
+static int m_Link_inRect(lua_State * L)
+{
+ udstruct *uin;
+ double x, y;
+ uin = (udstruct *) luaL_checkudata(L, 1, M_Link);
+ if (uin->pd != NULL && uin->pd->pc != uin->pc)
+ pdfdoc_changed_error(L);
+ x = luaL_checknumber(L, 2);
+ y = luaL_checknumber(L, 3);
+ if (((Link *) uin->d)->inRect(x, y))
+ lua_pushboolean(L, 1);
+ else
+ lua_pushboolean(L, 0);
+ return 1;
+}
+
+m_poppler__tostring(Link);
+
+static const struct luaL_Reg Link_m[] = {
+ {"isOk", m_Link_isOk},
+ {"inRect", m_Link_inRect},
+ {"__tostring", m_Link__tostring},
+ {NULL, NULL} // sentinel
+};
+#endif
+
+//**********************************************************************
// LinkDest
static const char *LinkDestKindNames[] =
@@ -1115,9 +1171,39 @@ static const struct luaL_Reg LinkDest_m[
//**********************************************************************
// Links
+m_poppler_get_INT(Links, getNumLinks);
+
+#if 0
+static int m_Links_getLink(lua_State * L)
+{
+ Link *link;
+ int i, len;
+ udstruct *uin, *uout;
+ uin = (udstruct *) luaL_checkudata(L, 1, M_Links);
+ if (uin->pd != NULL && uin->pd->pc != uin->pc)
+ pdfdoc_changed_error(L);
+ i = luaL_checkint(L, 2);
+ len = ((Links *) uin->d)->getNumLinks();
+ if (i > 0 && i <= len) {
+ link = ((Links *) uin->d)->getLink(i - 1);
+ if (link != NULL) {
+ uout = new_Link_userdata(L);
+ uout->d = link;
+ uout->pc = uin->pc;
+ uout->pd = uin->pd;
+ } else
+ lua_pushnil(L);
+ } else
+ lua_pushnil(L);
+ return 1;
+}
+#endif
+
m_poppler__tostring(Links);
static const struct luaL_Reg Links_m[] = {
+ {"getNumLinks", m_Links_getNumLinks},
+ //{"getLink", m_Links_getLink},
{"__tostring", m_Links__tostring},
{NULL, NULL} // sentinel
};
@@ -2256,19 +2342,23 @@ static int m_PDFDoc_findPage(lua_State *
static int m_PDFDoc_getLinks(lua_State * L)
{
- int i;
+ int i, pages;
Links *links;
udstruct *uin, *uout;
uin = (udstruct *) luaL_checkudata(L, 1, M_PDFDoc);
if (uin->pd != NULL && uin->pd->pc != uin->pc)
pdfdoc_changed_error(L);
i = luaL_checkint(L, 2);
- links = ((PdfDocument *) uin->d)->doc->getLinks(i);
- if (links != NULL) {
- uout = new_Links_userdata(L);
- uout->d = links;
- uout->pc = uin->pc;
- uout->pd = uin->pd;
+ pages = ((PdfDocument *) uin->d)->doc->getNumPages();
+ if (i > 0 && i <= pages) {
+ links = ((PdfDocument *) uin->d)->doc->getLinks(i);
+ if (links != NULL) {
+ uout = new_Links_userdata(L);
+ uout->d = links;
+ uout->pc = uin->pc;
+ uout->pd = uin->pd;
+ } else
+ lua_pushnil(L);
} else
lua_pushnil(L);
return 1;
@@ -2347,6 +2437,8 @@ static int m_PDFDoc_getDocInfoNF(lua_Sta
m_PDFDoc_INT(getPDFMajorVersion);
m_PDFDoc_INT(getPDFMinorVersion);
+m_poppler__tostring(PDFDoc);
+
static int m_PDFDoc__gc(lua_State * L)
{
udstruct *uin;
@@ -2390,6 +2482,7 @@ static const struct luaL_Reg PDFDoc_m[]
{"getDocInfoNF", m_PDFDoc_getDocInfoNF},
{"getPDFMajorVersion", m_PDFDoc_getPDFMajorVersion},
{"getPDFMinorVersion", m_PDFDoc_getPDFMinorVersion},
+ {"__tostring", m_PDFDoc__tostring},
{"__gc", m_PDFDoc__gc}, // finalizer
{NULL, NULL} // sentinel
};
@@ -2625,12 +2718,47 @@ static int m_XRef_fetch(lua_State * L)
m_poppler_get_OBJECT(XRef, getDocInfo);
m_poppler_get_OBJECT(XRef, getDocInfoNF);
m_poppler_get_INT(XRef, getNumObjects);
-// getLastXRefPos
m_poppler_get_INT(XRef, getRootNum);
m_poppler_get_INT(XRef, getRootGen);
// getStreamEnd
+
+static int m_XRef_getNumEntry(lua_State * L)
+{
+ int i, offset;
+ udstruct *uin;
+ uin = (udstruct *) luaL_checkudata(L, 1, M_XRef);
+ if (uin->pd != NULL && uin->pd->pc != uin->pc)
+ pdfdoc_changed_error(L);
+ offset = luaL_checkint(L, 2);
+ i = ((XRef *) uin->d)->getNumEntry(offset);
+ if (i >= 0)
+ lua_pushinteger(L, i);
+ else
+ lua_pushnil(L);
+ return 1;
+}
+
m_poppler_get_INT(XRef, getSize);
-// getEntry
+
+static int m_XRef_getEntry(lua_State * L)
+{
+ int i, size;
+ udstruct *uin, *uout;
+ uin = (udstruct *) luaL_checkudata(L, 1, M_XRef);
+ if (uin->pd != NULL && uin->pd->pc != uin->pc)
+ pdfdoc_changed_error(L);
+ i = luaL_checkint(L, 2);
+ size = ((XRef *) uin->d)->getSize();
+ if (i > 0 && i <= size) {
+ uout = new_XRefEntry_userdata(L);
+ uout->d = ((XRef *) uin->d)->getEntry(i);
+ uout->pc = uin->pc;
+ uout->pd = uin->pd;
+ } else
+ lua_pushnil(L);
+ return 1;
+}
+
m_poppler_get_poppler(XRef, Object, getTrailerDict);
m_poppler__tostring(XRef);
@@ -2652,11 +2780,12 @@ static const struct luaL_Reg XRef_m[] =
{"getDocInfo", m_XRef_getDocInfo},
{"getDocInfoNF", m_XRef_getDocInfoNF},
{"getNumObjects", m_XRef_getNumObjects},
- //
{"getRootNum", m_XRef_getRootNum},
{"getRootGen", m_XRef_getRootGen},
- //
+ // {"getStreamEnd", m_XRef_getStreamEnd},
+ {"getNumEntry", m_XRef_getNumEntry},
{"getSize", m_XRef_getSize},
+ {"getEntry", m_XRef_getEntry},
{"getTrailerDict", m_XRef_getTrailerDict},
{"__tostring", m_XRef__tostring},
{NULL, NULL} // sentinel
@@ -2665,7 +2794,10 @@ static const struct luaL_Reg XRef_m[] =
//**********************************************************************
// XRefEntry
+m_poppler__tostring(XRefEntry);
+
static const struct luaL_Reg XRefEntry_m[] = {
+ {"__tostring", m_XRefEntry__tostring},
{NULL, NULL} // sentinel
};
@@ -2683,13 +2815,20 @@ int luaopen_epdf(lua_State * L)
{
register_meta(Annot);
// TODO register_meta(AnnotBorder);
+#if POPPLER_VERSION_MAJOR == 0 && POPPLER_VERSION_MINOR < 17
register_meta(AnnotBorderStyle);
+#endif
register_meta(Annots);
register_meta(Array);
register_meta(Catalog);
- register_meta(EmbFile);
register_meta(Dict);
+#if POPPLER_VERSION_MAJOR == 0 && (POPPLER_VERSION_MINOR < 17 || \
+ ( POPPLER_VERSION_MINOR == 17 && POPPLER_VERSION_MICRO < 2))
+ register_meta(EmbFile);
+#endif
+
register_meta(GooString);
+ //register_meta(Link);
register_meta(LinkDest);
register_meta(Links);
register_meta(Object);
--- texk/web2c/luatexdir/lua/lfontlib.c
+++ texk/web2c/luatexdir/lua/lfontlib.c 2011-10-13 07:39:27.000000000 +0000
@@ -1,6 +1,6 @@
/* lfontlib.c
-
- Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
+
+ Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -17,20 +17,19 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
+static const char _svn_version[] =
+ "$Id: lfontlib.c 4341 2011-07-28 21:24:31Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/lua/lfontlib.c $";
+
#include "lua/luatex-api.h"
#include "ptexlib.h"
-
-static const char _svn_version[] =
- "$Id: lfontlib.c 3551 2010-03-26 14:43:50Z taco $ $URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/lua/lfontlib.c $";
-
#define TIMERS 0
#if TIMERS
# include <sys/time.h>
#endif
-
static int get_fontid(void)
{
if (font_tables == NULL || font_tables[0] == NULL) {
@@ -83,8 +82,7 @@ static int font_read_vf(lua_State * L)
lua_number2int(i, lua_tonumber(L, 2));
return make_vf_table(L, cnom, (scaled) i);
} else {
- luaL_error(L,
- "expected an integer size as second argument");
+ luaL_error(L, "expected an integer size as second argument");
return 2;
}
}
@@ -178,7 +176,7 @@ static int setfont(lua_State * L)
font_from_lua(L, i);
} else {
luaL_error(L,
- "that font has been accessed already, changing it is forbidden");
+ "that font has been accessed already, changing it is forbidden");
}
} else {
luaL_error(L, "that integer id is not a valid font");
@@ -288,3 +286,184 @@ int luaopen_font(lua_State * L)
make_table(L, "fonts", "getfont", "setfont");
return 1;
}
+
+/**********************************************************************/
+/* "vf" library: Lua functions within virtual fonts */
+
+static int l_vf_char(lua_State * L)
+{
+ int k;
+ vf_struct *vsp = static_pdf->vfstruct;
+ packet_stack_record *mat_p;
+ if (!vsp->vflua)
+ pdf_error("vf", "vf.char() outside virtual font");
+ k = (int) luaL_checkinteger(L, 1);
+ if (!char_exists(vsp->lf, (int) k)) {
+ char_warning(vsp->lf, (int) k);
+ } else {
+ if (has_packet(vsp->lf, (int) k))
+ do_vf_packet(static_pdf, vsp->lf, (int) k);
+ else
+ backend_out[glyph_node] (static_pdf, vsp->lf, (int) k);
+ }
+ mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
+ mat_p->pos.h += char_width(vsp->lf, (int) k);
+ synch_pos_with_cur(static_pdf->posstruct, vsp->refpos, mat_p->pos);
+ return 0;
+}
+
+static int l_vf_down(lua_State * L)
+{
+ scaled i;
+ vf_struct *vsp = static_pdf->vfstruct;
+ packet_stack_record *mat_p;
+ if (!vsp->vflua)
+ pdf_error("vf", "vf.down() outside virtual font");
+ i = (scaled) luaL_checkinteger(L, 1);
+ i = store_scaled_f(i, vsp->fs_f);
+ mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
+ mat_p->pos.v += i;
+ synch_pos_with_cur(static_pdf->posstruct, vsp->refpos, mat_p->pos);
+ return 0;
+}
+
+static int l_vf_fontid(lua_State * L)
+{
+ vf_struct *vsp = static_pdf->vfstruct;
+ if (!vsp->vflua)
+ pdf_error("vf", "vf.fontid() outside virtual font");
+ vsp->lf = (int) luaL_checkinteger(L, 1);
+ return 0;
+}
+
+static int l_vf_image(lua_State * L)
+{
+ int k;
+ vf_struct *vsp = static_pdf->vfstruct;
+ if (!vsp->vflua)
+ pdf_error("vf", "vf.image() outside virtual font");
+ k = (int) luaL_checkinteger(L, 1);
+ vf_out_image(static_pdf, k);
+ return 0;
+}
+
+static int l_vf_node(lua_State * L)
+{
+ int k;
+ vf_struct *vsp = static_pdf->vfstruct;
+ if (!vsp->vflua)
+ pdf_error("vf", "vf.node() outside virtual font");
+ k = (int) luaL_checkinteger(L, 1);
+ hlist_out(static_pdf, (halfword) k);
+ return 0;
+}
+
+static int l_vf_nop(lua_State * L)
+{
+ vf_struct *vsp = static_pdf->vfstruct;
+ if (!vsp->vflua)
+ pdf_error("vf", "vf.nop() outside virtual font");
+ return 0;
+}
+
+static int l_vf_pop(lua_State * L)
+{
+ vf_struct *vsp = static_pdf->vfstruct;
+ packet_stack_record *mat_p;
+ if (!vsp->vflua)
+ pdf_error("vf", "vf.pop() outside virtual font");
+ if (vsp->packet_stack_level == vsp->packet_stack_minlevel)
+ pdf_error("vf", "packet_stack_level underflow");
+ vsp->packet_stack_level--;
+ mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
+ synch_pos_with_cur(static_pdf->posstruct, vsp->refpos, mat_p->pos);
+ return 0;
+}
+
+static int l_vf_push(lua_State * L)
+{
+ vf_struct *vsp = static_pdf->vfstruct;
+ packet_stack_record *mat_p;
+ if (!vsp->vflua)
+ pdf_error("vf", "vf.push() outside virtual font");
+ mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
+ vsp->packet_stack_level++;
+ if (vsp->packet_stack_level == packet_stack_size)
+ pdf_error("vf", "packet_stack_level overflow");
+ vsp->packet_stack[vsp->packet_stack_level] = *mat_p;
+ mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
+ return 0;
+}
+
+static int l_vf_right(lua_State * L)
+{
+ scaled i;
+ vf_struct *vsp = static_pdf->vfstruct;
+ packet_stack_record *mat_p;
+ if (!vsp->vflua)
+ pdf_error("vf", "vf.right() outside virtual font");
+ mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
+ i = (scaled) luaL_checkinteger(L, 1);
+ i = store_scaled_f(i, vsp->fs_f);
+ mat_p->pos.h += i;
+ synch_pos_with_cur(static_pdf->posstruct, vsp->refpos, mat_p->pos);
+ return 0;
+}
+
+static int l_vf_rule(lua_State * L)
+{
+ scaledpos size;
+ vf_struct *vsp = static_pdf->vfstruct;
+ packet_stack_record *mat_p;
+ if (!vsp->vflua)
+ pdf_error("vf", "vf.rule() outside virtual font");
+ size.h = (scaled) luaL_checkinteger(L, 1);
+ size.v = (scaled) luaL_checkinteger(L, 2);
+ size.h = store_scaled_f(size.h, vsp->fs_f);
+ size.v = store_scaled_f(size.v, vsp->fs_f);
+ if (size.h > 0 && size.v > 0)
+ pdf_place_rule(static_pdf, 0, size); /* the 0 is unused */
+ mat_p = &(vsp->packet_stack[vsp->packet_stack_level]);
+ mat_p->pos.h += size.h;
+ synch_pos_with_cur(static_pdf->posstruct, vsp->refpos, mat_p->pos);
+ return 0;
+}
+
+static int l_vf_special(lua_State * L)
+{
+ const_lstring st;
+ int texstr;
+ vf_struct *vsp = static_pdf->vfstruct;
+ if (!vsp->vflua)
+ pdf_error("vf", "vf.special() outside virtual font");
+ st.s = lua_tolstring(L, 1, &(st.l));
+ texstr = maketexlstring(st.s, st.l);
+ pdf_literal(static_pdf, texstr, scan_special, false);
+ flush_str(texstr);
+ return 0;
+}
+
+static const struct luaL_reg vflib[] = {
+ {"char", l_vf_char},
+ {"down", l_vf_down},
+ /* {"font", l_vf_font}, */
+ {"fontid", l_vf_fontid},
+ {"image", l_vf_image},
+ /* {"lua", l_vf_lua}, */
+ {"node", l_vf_node},
+ {"nop", l_vf_nop},
+ {"pop", l_vf_pop},
+ {"push", l_vf_push},
+ {"right", l_vf_right},
+ {"rule", l_vf_rule},
+ /* {"scale", l_vf_scale}, */
+ /* {"slot", l_vf_slot}, */
+ {"special", l_vf_special},
+ {NULL, NULL} /* sentinel */
+};
+
+int luaopen_vf(lua_State * L)
+{
+ luaL_register(L, "vf", vflib);
+ return 1;
+}
--- texk/web2c/luatexdir/lua/limglib.c
+++ texk/web2c/luatexdir/lua/limglib.c 2011-10-13 07:39:27.000000000 +0000
@@ -585,7 +585,6 @@ static void write_image_or_node(lua_Stat
tail_append(n);
break; /* image */
case WR_IMMEDIATEWRITE:
- pdf_begin_dict(static_pdf, img_objnum(ad), 0);
write_img(static_pdf, ad);
break; /* image */
case WR_NODE: /* image */
--- texk/web2c/luatexdir/lua/lkpselib.c
+++ texk/web2c/luatexdir/lua/lkpselib.c 2011-10-13 07:39:27.000000000 +0000
@@ -331,7 +331,7 @@ static int lua_kpathsea_var_value(lua_St
static unsigned find_dpi(const_string s)
{
unsigned dpi_number = 0;
- string extension = find_suffix(s);
+ const_string extension = find_suffix(s);
if (extension != NULL)
sscanf(extension, "%u", &dpi_number);
@@ -622,13 +622,16 @@ static int do_lua_kpathsea_lookup(lua_St
case kpse_any_glyph_format:
{
kpse_glyph_file_type glyph_ret;
+ string temp = remove_suffix (name);
/* Try to extract the resolution from the name. */
unsigned local_dpi = find_dpi(name);
if (!local_dpi)
local_dpi = (unsigned) dpi;
ret =
- kpathsea_find_glyph(kpse, remove_suffix(name), local_dpi,
+ kpathsea_find_glyph(kpse, temp, local_dpi,
fmt, &glyph_ret);
+ if (temp != name)
+ free (temp);
}
break;
--- texk/web2c/luatexdir/lua/lnodelib.c
+++ texk/web2c/luatexdir/lua/lnodelib.c 2011-10-13 07:39:27.000000000 +0000
@@ -2781,7 +2781,7 @@ static int lua_nodelib_setfield(lua_Stat
height(n) = (halfword) lua_tointeger(L, 3);
break;
case 7:
- box_dir(n) = (halfword) lua_tointeger(L, 3);
+ box_dir(n) = nodelib_getdir(L, 3);
break;
case 8:
glue_shrink(n) = (halfword) lua_tointeger(L, 3);
--- texk/web2c/luatexdir/lua/lpdflib.c
+++ texk/web2c/luatexdir/lua/lpdflib.c 2011-10-13 07:39:27.000000000 +0000
@@ -1,6 +1,6 @@
/* lpdflib.c
- Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -119,11 +119,11 @@ static int l_immediateobj(lua_State * L)
case 1:
if (!lua_isstring(L, first_arg))
luaL_error(L, "pdf.immediateobj() 1st argument must be string");
- pdf_begin_obj(static_pdf, k, 1);
+ pdf_begin_obj(static_pdf, k, OBJSTM_ALWAYS);
st1.s = lua_tolstring(L, first_arg, &st1.l);
pdf_out_block(static_pdf, st1.s, st1.l);
if (st1.s[st1.l - 1] != '\n')
- pdf_puts(static_pdf, "\n");
+ pdf_out(static_pdf, '\n');
pdf_end_obj(static_pdf);
break;
case 2:
@@ -138,15 +138,16 @@ static int l_immediateobj(lua_State * L)
if (n == first_arg + 2)
luaL_error(L,
"pdf.immediateobj() 3rd argument forbidden in file mode");
- pdf_begin_obj(static_pdf, k, 1);
+ pdf_begin_obj(static_pdf, k, OBJSTM_ALWAYS);
buf.s = fread_to_buf(L, st2.s, &buf.l);
pdf_out_block(static_pdf, (const char *) buf.s, buf.l);
if (buf.s[buf.l - 1] != '\n')
- pdf_puts(static_pdf, "\n");
+ pdf_out(static_pdf, '\n');
xfree(buf.s);
pdf_end_obj(static_pdf);
} else {
- pdf_begin_dict(static_pdf, k, 0); /* 0 = not an object stream candidate! */
+ pdf_begin_obj(static_pdf, k, OBJSTM_NEVER); /* not an object stream candidate! */
+ pdf_begin_dict(static_pdf);
if (n == first_arg + 2) { /* write attr text */
if (!lua_isstring(L, first_arg + 2))
luaL_error(L,
@@ -154,8 +155,10 @@ static int l_immediateobj(lua_State * L)
st3.s = lua_tolstring(L, first_arg + 2, &st3.l);
pdf_out_block(static_pdf, st3.s, st3.l);
if (st3.s[st3.l - 1] != '\n')
- pdf_puts(static_pdf, "\n");
+ pdf_out(static_pdf, '\n');
}
+ pdf_dict_add_streaminfo(static_pdf);
+ pdf_end_dict(static_pdf);
pdf_begin_stream(static_pdf);
if (st1.l == 6 && strncmp((const char *) st1.s, "stream", 6) == 0) {
pdf_out_block(static_pdf, st2.s, st2.l);
@@ -168,6 +171,7 @@ static int l_immediateobj(lua_State * L)
} else
luaL_error(L, "pdf.immediateobj() invalid argument");
pdf_end_stream(static_pdf);
+ pdf_end_obj(static_pdf);
}
break;
default:
@@ -217,9 +221,9 @@ static const parm_struct pdf_parms[] = {
static int table_obj(lua_State * L)
{
- int k, type;
+ int k, type, obj_compression;
int compress_level = -1; /* unset */
- int os_level = 1; /* default: put non-stream objects into object streams */
+ int os_threshold = OBJSTM_ALWAYS; /* default: put non-stream objects into object streams */
int saved_compress_level = static_pdf->compress_level;
const_lstring attr, st;
lstring buf;
@@ -332,10 +336,14 @@ static int table_obj(lua_State * L)
"pdf.obj(): \"objcompression\" key not allowed for stream object");
if (!lua_isboolean(L, -1)) /* !b t */
luaL_error(L, "pdf.obj(): \"objcompression\" must be boolean");
- os_level = lua_toboolean(L, -1); /* 0 or 1 */
- /* 0: never compress; 1: depends then on \pdfobjcompresslevel */
+ obj_compression = lua_toboolean(L, -1); /* 0 or 1 */
+ /* OBJSTM_NEVER: never into object stream; OBJSTM_ALWAYS: depends then on \pdfobjcompresslevel */
+ if (obj_compression > 0)
+ os_threshold = OBJSTM_ALWAYS;
+ else
+ os_threshold = OBJSTM_NEVER;
if (immediate == 0)
- obj_obj_pdfoslevel(static_pdf, k) = os_level;
+ obj_obj_objstm_threshold(static_pdf, k) = os_threshold;
}
lua_pop(L, 1); /* t */
@@ -354,7 +362,7 @@ static int table_obj(lua_State * L)
switch (type) {
case P_RAW:
if (immediate == 1)
- pdf_begin_obj(static_pdf, k, os_level);
+ pdf_begin_obj(static_pdf, k, os_threshold);
if (!lua_isnil(L, -2)) { /* file-s? string-s? t */
/* from string */
lua_pop(L, 1); /* string-s? t */
@@ -365,7 +373,7 @@ static int table_obj(lua_State * L)
st.s = lua_tolstring(L, -1, &st.l);
pdf_out_block(static_pdf, st.s, st.l);
if (st.s[st.l - 1] != '\n')
- pdf_puts(static_pdf, "\n");
+ pdf_out(static_pdf, '\n');
} else
obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* t */
} else {
@@ -378,7 +386,7 @@ static int table_obj(lua_State * L)
buf.s = fread_to_buf(L, st.s, &buf.l);
pdf_out_block(static_pdf, (const char *) buf.s, buf.l);
if (buf.s[buf.l - 1] != '\n')
- pdf_puts(static_pdf, "\n");
+ pdf_out(static_pdf, '\n');
xfree(buf.s);
} else {
set_obj_obj_is_file(static_pdf, k);
@@ -390,14 +398,17 @@ static int table_obj(lua_State * L)
break;
case P_STREAM:
if (immediate == 1) {
- pdf_begin_dict(static_pdf, k, 0); /* 0 = not an object stream candidate! */
+ pdf_begin_obj(static_pdf, k, OBJSTM_NEVER); /* 0 = not an object stream candidate! */
+ pdf_begin_dict(static_pdf);
if (attr.s != NULL) {
pdf_out_block(static_pdf, attr.s, attr.l);
if (attr.s[attr.l - 1] != '\n')
- pdf_puts(static_pdf, "\n");
+ pdf_out(static_pdf, '\n');
}
if (compress_level > -1)
static_pdf->compress_level = compress_level;
+ pdf_dict_add_streaminfo(static_pdf);
+ pdf_end_dict(static_pdf);
pdf_begin_stream(static_pdf);
} else {
set_obj_obj_is_stream(static_pdf, k);
@@ -430,8 +441,10 @@ static int table_obj(lua_State * L)
obj_obj_data(static_pdf, k) = luaL_ref(L, LUA_REGISTRYINDEX); /* nil t */
}
}
- if (immediate == 1)
+ if (immediate == 1) {
pdf_end_stream(static_pdf);
+ pdf_end_obj(static_pdf);
+ }
break;
default:
assert(0);
@@ -738,7 +751,7 @@ static int l_pageref(lua_State * L)
n = (int) luaL_checkinteger(L, 1);
if (n <= 0)
luaL_error(L, "pdf.pageref() needs page number > 0");
- n = get_obj(static_pdf, obj_type_page, n, false);
+ n = pdf_get_obj(static_pdf, obj_type_page, n, false);
lua_pushnumber(L, n);
return 1;
}
--- texk/web2c/luatexdir/lua/lstatslib.c
+++ texk/web2c/luatexdir/lua/lstatslib.c 2011-10-13 07:39:27.000000000 +0000
@@ -1,6 +1,6 @@
/* lstatslib.c
-
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+
+ Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -88,21 +88,21 @@ static lua_Number get_pdf_gone(void)
static lua_Number get_pdf_ptr(void)
{
if (static_pdf != NULL)
- return (lua_Number) static_pdf->ptr;
+ return (lua_Number) (static_pdf->buf->p - static_pdf->buf->data);
return (lua_Number) 0;
}
static lua_Number get_pdf_os_cntr(void)
{
if (static_pdf != NULL)
- return (lua_Number) static_pdf->os_cntr;
+ return (lua_Number) static_pdf->os->ostm_ctr;
return (lua_Number) 0;
}
static lua_Number get_pdf_os_objidx(void)
{
if (static_pdf != NULL)
- return (lua_Number) static_pdf->os_idx;
+ return (lua_Number) static_pdf->os->idx;
return (lua_Number) 0;
}
@@ -174,12 +174,12 @@ static struct statistic stats[] = {
{"luatex_revision", 'S', (void *) &luatexrevision},
{"ini_version", 'b', &ini_version},
/*
- * mem stat
+ * mem stat
*/
{"var_used", 'g', &var_used},
{"dyn_used", 'g', &dyn_used},
- /*
- * traditional tex stats
+ /*
+ * traditional tex stats
*/
{"str_ptr", 'g', &str_ptr},
{"init_str_ptr", 'g', &init_str_ptr},
--- texk/web2c/luatexdir/lua/luastuff.w
+++ texk/web2c/luatexdir/lua/luastuff.w 2011-10-13 07:39:27.000000000 +0000
@@ -236,6 +236,7 @@ void luainterpreter(void)
luaopen_font(L);
luaopen_lang(L);
luaopen_mplib(L);
+ luaopen_vf(L);
/* |luaopen_pdf(L);| */
/* environment table at |LUA_ENVIRONINDEX| needs to load this way: */
--- texk/web2c/luatexdir/lua/luatex-api.h
+++ texk/web2c/luatexdir/lua/luatex-api.h 2011-10-13 07:39:27.000000000 +0000
@@ -94,6 +94,7 @@ extern int luaopen_lua(lua_State * L, ch
extern int luaopen_stats(lua_State * L);
extern int luaopen_font(lua_State * L);
+extern int luaopen_vf(lua_State * L);
extern int font_to_lua(lua_State * L, int f);
extern int font_from_lua(lua_State * L, int f); /* return is boolean */
--- texk/web2c/luatexdir/luascripts/pdflua.c
+++ texk/web2c/luatexdir/luascripts/pdflua.c 2011-10-13 07:39:28.000000000 +0000
@@ -20,26 +20,25 @@
#include "ptexlib.h"
-static const Byte compr[259] = {
- 0x78, 0x9c, 0xad, 0x51, 0xc1, 0x4a, 0xc4, 0x30, 0x10, 0xbd, 0xe7, 0x2b, 0xe6, 0xd0, 0x83, 0xc2,
- 0x36, 0x49, 0x57, 0x59, 0x69, 0xc1, 0x0f, 0x10, 0x3c, 0x09, 0x5e, 0xbc, 0xa5, 0xe9, 0xb4, 0x0d,
- 0x0d, 0x49, 0x98, 0x24, 0xae, 0x8b, 0xf8, 0xef, 0xa6, 0x50, 0x74, 0x55, 0xbc, 0x6d, 0x98, 0x84,
- 0xc7, 0xbc, 0x97, 0x79, 0x0f, 0xa6, 0xae, 0xa1, 0x7a, 0x18, 0x3a, 0x08, 0xc3, 0x68, 0xb3, 0xe2,
- 0xe5, 0xc2, 0x4d, 0x7b, 0xdb, 0xc2, 0x5e, 0x36, 0xb2, 0x6e, 0x9a, 0x5a, 0xde, 0x81, 0x94, 0x9d,
- 0x6c, 0xbb, 0xa6, 0x7d, 0x81, 0x79, 0x46, 0xb7, 0xa0, 0x85, 0x8a, 0xd5, 0xe5, 0xdb, 0xf3, 0xd3,
- 0x63, 0x07, 0x73, 0x4a, 0xa1, 0x13, 0x62, 0xf4, 0xd9, 0x0d, 0x74, 0xe2, 0x31, 0x07, 0xb4, 0xa8,
- 0xf9, 0x48, 0x22, 0xbe, 0x3a, 0x51, 0xc6, 0x25, 0x7c, 0x13, 0x49, 0x4d, 0x51, 0xf4, 0x98, 0x54,
- 0x2d, 0xf9, 0xe1, 0xc0, 0xa5, 0x88, 0x3e, 0x93, 0x46, 0x51, 0xb8, 0x45, 0x1c, 0xb1, 0xdf, 0xeb,
- 0x4d, 0x39, 0x18, 0x5a, 0x51, 0xd4, 0x64, 0x42, 0x8a, 0xe2, 0x2c, 0x54, 0xc5, 0x56, 0xcf, 0x34,
- 0x9b, 0x08, 0xa5, 0x50, 0x91, 0x3d, 0xc1, 0xd1, 0xd3, 0x02, 0xc6, 0x41, 0x20, 0x3f, 0x11, 0xc6,
- 0xc8, 0x39, 0x5f, 0x55, 0x97, 0x39, 0x8c, 0xf5, 0x38, 0x19, 0x17, 0xd4, 0x84, 0x70, 0x0f, 0x63,
- 0x76, 0x3a, 0x19, 0xef, 0xae, 0xd4, 0x35, 0x43, 0x37, 0xb0, 0xf5, 0xf9, 0x8f, 0xf2, 0x39, 0x85,
- 0x52, 0x85, 0x8d, 0x89, 0xf0, 0x87, 0x64, 0x53, 0x5c, 0x2e, 0xa3, 0xf5, 0x5a, 0xd9, 0x6d, 0x79,
- 0xc5, 0xe8, 0x9d, 0x01, 0x9c, 0xc7, 0xfe, 0xc2, 0xbb, 0x42, 0x7c, 0x47, 0xde, 0xd0, 0xda, 0xfc,
- 0x1b, 0xf6, 0x57, 0x67, 0xc7, 0x3e, 0x18, 0x23, 0x4c, 0x99, 0xdc, 0xe6, 0xc3, 0x3e, 0x01, 0x6c,
- 0x2e, 0xa2, 0xa9
+static const Byte compr[250] = {
+ 0x78, 0x9c, 0xad, 0x51, 0xc1, 0x4a, 0xc4, 0x30, 0x14, 0xbc, 0xbf, 0xaf, 0x78, 0x87, 0x1e, 0x14,
+ 0xb6, 0x49, 0xba, 0x0a, 0xd2, 0x82, 0x1f, 0x20, 0x78, 0x12, 0xbc, 0x78, 0xeb, 0xa6, 0xaf, 0x6d,
+ 0x68, 0x48, 0xc2, 0x4b, 0xe2, 0xba, 0x88, 0xff, 0x6e, 0x0a, 0x45, 0x57, 0xc5, 0xdb, 0x86, 0x97,
+ 0x30, 0xcc, 0x4c, 0x32, 0x03, 0xa9, 0x6b, 0xac, 0x1e, 0x86, 0x0e, 0xc3, 0x30, 0xda, 0xdc, 0x8b,
+ 0xb2, 0xf1, 0xa6, 0xbd, 0x6d, 0x71, 0xaf, 0x1a, 0x55, 0x37, 0x4d, 0xad, 0xee, 0x50, 0xa9, 0x4e,
+ 0xb5, 0x5d, 0xd3, 0xbe, 0xe0, 0x3c, 0x93, 0x5b, 0xc8, 0x62, 0x05, 0x75, 0xb9, 0xf6, 0xfc, 0xf4,
+ 0xd8, 0xe1, 0x9c, 0x52, 0xe8, 0xa4, 0x1c, 0x7d, 0x76, 0x03, 0x9f, 0x44, 0xcc, 0x81, 0x2c, 0x69,
+ 0x31, 0xb2, 0x8c, 0xaf, 0x4e, 0x96, 0xe7, 0x12, 0xbd, 0xc9, 0xc4, 0xd9, 0x2d, 0x32, 0xfa, 0xcc,
+ 0x9a, 0x64, 0x21, 0x16, 0x79, 0xa4, 0xc3, 0x5e, 0x6f, 0xf2, 0x60, 0x78, 0x45, 0x51, 0xb3, 0x09,
+ 0x29, 0xca, 0xb3, 0x26, 0x15, 0xac, 0x41, 0x69, 0x36, 0x11, 0xcb, 0x50, 0xcf, 0xf6, 0x84, 0x47,
+ 0xcf, 0x0b, 0x1a, 0x87, 0x81, 0xfd, 0xc4, 0x14, 0xa3, 0x10, 0x62, 0x75, 0x5d, 0x66, 0x01, 0x1c,
+ 0x68, 0x32, 0x2e, 0xf4, 0x13, 0xe1, 0x3d, 0x8e, 0xd9, 0xe9, 0x64, 0xbc, 0xbb, 0xea, 0xaf, 0x81,
+ 0xdc, 0x00, 0xeb, 0xf1, 0x9f, 0xe4, 0x73, 0x0a, 0x65, 0x8a, 0x1a, 0x13, 0xd3, 0x0f, 0xcb, 0xe6,
+ 0xb8, 0x5c, 0x47, 0xeb, 0x75, 0x6f, 0xb7, 0x1f, 0x2b, 0x41, 0xef, 0x80, 0x78, 0x5e, 0xfb, 0x0b,
+ 0xef, 0x8a, 0xf0, 0x5d, 0x79, 0x43, 0x2b, 0xf9, 0xb7, 0xec, 0x2f, 0x66, 0x07, 0x1f, 0x00, 0x4c,
+ 0x29, 0xb3, 0xdb, 0x72, 0xe0, 0x13, 0x6d, 0xe3, 0xa0, 0x0e
};
-static const zlib_struct compr_struct = { 564, 259, compr };
+static const zlib_struct compr_struct = { 553, 250, compr };
const zlib_struct *pdflua_zlib_struct_ptr = &compr_struct;
--- texk/web2c/luatexdir/pdf/pdfaction.w
+++ texk/web2c/luatexdir/pdf/pdfaction.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% pdfaction.w
-%
-% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
+
+% Copyright 2009-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -47,7 +47,7 @@ void delete_action_node(halfword a)
free_node(a, pdf_action_size);
}
-@ read an action specification
+@ read an action specification
@c
halfword scan_action(PDF pdf)
{
@@ -130,78 +130,83 @@ void write_action(PDF pdf, halfword p)
char *s;
int d = 0;
if (pdf_action_type(p) == pdf_action_user) {
- pdf_print_toks_ln(pdf, pdf_action_tokens(p));
+ pdf_out(pdf, '\n');
+ pdf_print_toks(pdf, pdf_action_tokens(p));
+ pdf_out(pdf, '\n');
return;
}
- pdf_printf(pdf, "<< ");
+ pdf_begin_dict(pdf);
if (pdf_action_file(p) != null) {
- pdf_printf(pdf, "/F ");
+ pdf_add_name(pdf, "F");
+ pdf_out(pdf, ' ');
s = tokenlist_to_cstring(pdf_action_file(p), true, NULL);
pdf_print_str(pdf, s);
xfree(s);
- pdf_printf(pdf, " ");
+ pdf_out(pdf, ' ');
if (pdf_action_new_window(p) > pdf_window_notset) {
- pdf_printf(pdf, "/NewWindow ");
if (pdf_action_new_window(p) == pdf_window_new)
- pdf_printf(pdf, "true ");
+ pdf_dict_add_bool(pdf, "NewWindow", 1);
else
- pdf_printf(pdf, "false ");
+ pdf_dict_add_bool(pdf, "NewWindow", 0);
}
}
switch (pdf_action_type(p)) {
case pdf_action_page:
+ pdf_dict_add_name(pdf, "S", "GoTo");
if (pdf_action_file(p) == null) {
- pdf_printf(pdf, "/S /GoTo /D [");
- pdf_print_int(pdf,
- get_obj(pdf, obj_type_page, pdf_action_id(p), false));
- pdf_printf(pdf, " 0 R");
+ pdf_add_name(pdf, "D");
+ pdf_begin_array(pdf);
+ pdf_add_ref(pdf,
+ pdf_get_obj(pdf, obj_type_page, pdf_action_id(p),
+ false));
} else {
- pdf_printf(pdf, "/S /GoToR /D [");
+ pdf_add_name(pdf, "D");
+ pdf_begin_array(pdf);
pdf_print_int(pdf, pdf_action_id(p) - 1);
}
{
char *tokstr =
tokenlist_to_cstring(pdf_action_tokens(p), true, NULL);
- pdf_printf(pdf, " %s]", tokstr);
+ pdf_printf(pdf, " %s", tokstr);
+ pdf_end_array(pdf);
xfree(tokstr);
}
break;
case pdf_action_goto:
if (pdf_action_file(p) == null) {
- pdf_printf(pdf, "/S /GoTo ");
- d = get_obj(pdf, obj_type_dest, pdf_action_id(p),
- pdf_action_named_id(p));
- } else {
- pdf_printf(pdf, "/S /GoToR ");
- }
+ pdf_dict_add_name(pdf, "S", "GoTo");
+ d = pdf_get_obj(pdf, obj_type_dest, pdf_action_id(p),
+ pdf_action_named_id(p));
+ } else
+ pdf_dict_add_name(pdf, "S", "GoToR");
if (pdf_action_named_id(p) > 0) {
char *tokstr = tokenlist_to_cstring(pdf_action_id(p), true, NULL);
- pdf_str_entry(pdf, "D", tokstr);
+ pdf_dict_add_string(pdf, "D", tokstr);
xfree(tokstr);
} else if (pdf_action_file(p) == null) {
- pdf_indirect(pdf, "D", d);
+ pdf_dict_add_ref(pdf, "D", d);
} else {
pdf_error("ext4",
"`goto' option cannot be used with both `file' and `num'");
}
break;
case pdf_action_thread:
- pdf_printf(pdf, "/S /Thread ");
+ pdf_dict_add_name(pdf, "S", "Thread");
if (pdf_action_file(p) == null) {
- d = get_obj(pdf, obj_type_thread, pdf_action_id(p),
- pdf_action_named_id(p));
+ d = pdf_get_obj(pdf, obj_type_thread, pdf_action_id(p),
+ pdf_action_named_id(p));
if (pdf_action_named_id(p) > 0) {
char *tokstr =
tokenlist_to_cstring(pdf_action_id(p), true, NULL);
- pdf_str_entry(pdf, "D", tokstr);
+ pdf_dict_add_string(pdf, "D", tokstr);
xfree(tokstr);
} else if (pdf_action_file(p) == null) {
- pdf_indirect(pdf, "D", d);
+ pdf_dict_add_ref(pdf, "D", d);
} else {
- pdf_int_entry(pdf, "D", pdf_action_id(p));
+ pdf_dict_add_int(pdf, "D", pdf_action_id(p));
}
}
break;
}
- pdf_printf(pdf, " >>\n");
+ pdf_end_dict(pdf);
}
--- texk/web2c/luatexdir/pdf/pdfannot.w
+++ texk/web2c/luatexdir/pdf/pdfannot.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% pdfannot.w
-% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2009-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -36,7 +36,7 @@ void do_annot(PDF pdf, halfword p, halfw
if (doing_leaders)
return;
if (is_obj_scheduled(pdf, pdf_annot_objnum(p))) {
- k = pdf_create_obj(pdf, obj_type_annot, pdf->obj_ptr + 1);
+ k = pdf_create_obj(pdf, obj_type_annot, 0);
obj_annot_ptr(pdf, pdf_annot_objnum(p)) = p;
pdf_annot_objnum(p) = k;
}
@@ -73,7 +73,7 @@ void scan_annot(PDF pdf)
{
int k;
if (scan_keyword("reserveobjnum")) {
- k = pdf_create_obj(pdf, obj_type_annot, pdf->obj_ptr + 1);
+ k = pdf_create_obj(pdf, obj_type_annot, 0);
/* Scan an optional space */
get_x_token();
if (cur_cmd != spacer_cmd)
@@ -86,7 +86,7 @@ void scan_annot(PDF pdf)
if (obj_annot_ptr(pdf, k) != 0)
pdf_error("ext1", "annot object in use");
} else {
- k = pdf_create_obj(pdf, obj_type_annot, pdf->obj_ptr + 1);
+ k = pdf_create_obj(pdf, obj_type_annot, 0);
}
new_annot_whatsit(pdf_annot_node);
obj_annot_ptr(pdf, k) = tail;
--- texk/web2c/luatexdir/pdf/pdfcolorstack.w
+++ texk/web2c/luatexdir/pdf/pdfcolorstack.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% pdfcolorstack.w
%
-% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2009-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -204,9 +204,8 @@ static int colorstackpush(int colstack_n
if (global_shipping_mode == SHIPPING_PAGE) {
if (colstack->page_used == colstack->page_size) {
colstack->page_size += STACK_INCREMENT;
- colstack->page_stack = xretalloc(colstack->page_stack,
- (unsigned) colstack->page_size,
- char *);
+ xretalloc(colstack->page_stack, (unsigned) colstack->page_size,
+ char *);
}
colstack->page_stack[colstack->page_used++] = colstack->page_current;
str = makecstring(s);
@@ -219,9 +218,8 @@ static int colorstackpush(int colstack_n
} else {
if (colstack->form_used == colstack->form_size) {
colstack->form_size += STACK_INCREMENT;
- colstack->form_stack = xretalloc(colstack->form_stack,
- (unsigned) colstack->form_size,
- char *);
+ xretalloc(colstack->form_stack, (unsigned) colstack->form_size,
+ char *);
}
colstack->form_stack[colstack->form_used++] = colstack->form_current;
str = makecstring(s);
--- texk/web2c/luatexdir/pdf/pdfdest.w
+++ texk/web2c/luatexdir/pdf/pdfdest.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% pdfdest.w
-% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2009-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -92,7 +92,7 @@ void do_dest(PDF pdf, halfword p, halfwo
pdf_error("ext4", "destinations cannot be inside an XForm");
if (doing_leaders)
return;
- k = get_obj(pdf, obj_type_dest, pdf_dest_id(p), pdf_dest_named_id(p));
+ k = pdf_get_obj(pdf, obj_type_dest, pdf_dest_id(p), pdf_dest_named_id(p));
if (obj_dest_ptr(pdf, k) != null) {
warn_dest_dup(pdf_dest_id(p), (small_number) pdf_dest_named_id(p),
"ext4", "has been already used, duplicate ignored");
@@ -146,65 +146,63 @@ void write_out_pdf_mark_destinations(PDF
} else {
int i;
i = obj_dest_ptr(pdf, k->info);
+ pdf_begin_obj(pdf, k->info, OBJSTM_ALWAYS);
if (pdf_dest_named_id(i) > 0) {
- pdf_begin_dict(pdf, k->info, 1);
- pdf_printf(pdf, "/D ");
- } else {
- pdf_begin_obj(pdf, k->info, 1);
+ pdf_begin_dict(pdf);
+ pdf_add_name(pdf, "D");
}
- pdf_out(pdf, '[');
- pdf_print_int(pdf, pdf->last_page);
- pdf_printf(pdf, " 0 R ");
+ pdf_begin_array(pdf);
+ pdf_add_ref(pdf, pdf->last_page);
switch (pdf_dest_type(i)) {
case pdf_dest_xyz:
- pdf_printf(pdf, "/XYZ ");
- pdf_print_mag_bp(pdf, pdf_ann_left(i));
- pdf_out(pdf, ' ');
- pdf_print_mag_bp(pdf, pdf_ann_top(i));
- pdf_out(pdf, ' ');
+ pdf_add_name(pdf, "XYZ");
+ pdf_add_mag_bp(pdf, pdf_ann_left(i));
+ pdf_add_mag_bp(pdf, pdf_ann_top(i));
if (pdf_dest_xyz_zoom(i) == null) {
- pdf_printf(pdf, "null");
+ pdf_add_null(pdf);
} else {
+ if (pdf->cave == 1)
+ pdf_out(pdf, ' ');
pdf_print_int(pdf, pdf_dest_xyz_zoom(i) / 1000);
pdf_out(pdf, '.');
pdf_print_int(pdf, (pdf_dest_xyz_zoom(i) % 1000));
+ pdf->cave = 1;
}
break;
case pdf_dest_fit:
- pdf_printf(pdf, "/Fit");
+ pdf_add_name(pdf, "Fit");
break;
case pdf_dest_fith:
- pdf_printf(pdf, "/FitH ");
- pdf_print_mag_bp(pdf, pdf_ann_top(i));
+ pdf_add_name(pdf, "FitH");
+ pdf_add_mag_bp(pdf, pdf_ann_top(i));
break;
case pdf_dest_fitv:
- pdf_printf(pdf, "/FitV ");
- pdf_print_mag_bp(pdf, pdf_ann_left(i));
+ pdf_add_name(pdf, "FitV");
+ pdf_add_mag_bp(pdf, pdf_ann_left(i));
break;
case pdf_dest_fitb:
- pdf_printf(pdf, "/FitB");
+ pdf_add_name(pdf, "FitB");
break;
case pdf_dest_fitbh:
- pdf_printf(pdf, "/FitBH ");
- pdf_print_mag_bp(pdf, pdf_ann_top(i));
+ pdf_add_name(pdf, "FitBH");
+ pdf_add_mag_bp(pdf, pdf_ann_top(i));
break;
case pdf_dest_fitbv:
- pdf_printf(pdf, "/FitBV ");
- pdf_print_mag_bp(pdf, pdf_ann_left(i));
+ pdf_add_name(pdf, "FitBV");
+ pdf_add_mag_bp(pdf, pdf_ann_left(i));
break;
case pdf_dest_fitr:
- pdf_printf(pdf, "/FitR ");
- pdf_print_rect_spec(pdf, i);
+ pdf_add_name(pdf, "FitR");
+ pdf_add_rect_spec(pdf, i);
break;
default:
pdf_error("ext5", "unknown dest type");
break;
}
- pdf_printf(pdf, "]\n");
+ pdf_end_array(pdf);
if (pdf_dest_named_id(i) > 0)
pdf_end_dict(pdf);
- else
- pdf_end_obj(pdf);
+ pdf_end_obj(pdf);
}
k = k->link;
}
@@ -307,7 +305,6 @@ void sort_dest_names(PDF pdf)
sizeof(dest_name_entry), dest_cmp);
}
-
@ Output the name tree. The tree nature of the destination list forces the
storing of intermediate data in |obj_info| and |obj_aux| fields, which
is further uglified by the fact that |obj_tab| entries do not accept char
@@ -343,21 +340,20 @@ int output_name_tree(PDF pdf)
}
set_obj_link(pdf, names_tail, 0);
/* Output the current node in this level */
- pdf_begin_dict(pdf, l, 1);
+ pdf_begin_obj(pdf, l, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
j = 0;
if (is_names) {
set_obj_start(pdf, l, pdf->dest_names[k].objname);
- pdf_printf(pdf, "/Names [");
+ pdf_add_name(pdf, "Names");
+ pdf_begin_array(pdf);
do {
- pdf_print_str(pdf, pdf->dest_names[k].objname);
- pdf_out(pdf, ' ');
- pdf_print_int(pdf, pdf->dest_names[k].objnum);
- pdf_printf(pdf, " 0 R ");
+ pdf_add_string(pdf, pdf->dest_names[k].objname);
+ pdf_add_ref(pdf, pdf->dest_names[k].objnum);
j++;
k++;
} while (j != name_tree_kids_max && k != pdf->dest_names_ptr);
- pdf_remove_last_space(pdf);
- pdf_printf(pdf, "]\n");
+ pdf_end_array(pdf);
set_obj_stop(pdf, l, pdf->dest_names[k - 1].objname); /* for later */
if (k == pdf->dest_names_ptr) {
is_names = false;
@@ -367,48 +363,48 @@ int output_name_tree(PDF pdf)
} else {
set_obj_start(pdf, l, obj_start(pdf, k));
- pdf_printf(pdf, "/Kids [");
+ pdf_add_name(pdf, "Kids");
+ pdf_begin_array(pdf);
do {
- pdf_print_int(pdf, k);
- pdf_printf(pdf, " 0 R ");
+ pdf_add_ref(pdf, k);
set_obj_stop(pdf, l, obj_stop(pdf, k));
k = obj_link(pdf, k);
j++;
} while (j != name_tree_kids_max && k != b
&& obj_link(pdf, k) != 0);
- pdf_remove_last_space(pdf);
- pdf_printf(pdf, "]\n");
+ pdf_end_array(pdf);
if (k == b)
b = 0;
}
- pdf_printf(pdf, "/Limits [");
- pdf_print_str(pdf, obj_start(pdf, l));
- pdf_out(pdf, ' ');
- pdf_print_str(pdf, obj_stop(pdf, l));
- pdf_printf(pdf, "]\n");
+ pdf_add_name(pdf, "Limits");
+ pdf_begin_array(pdf);
+ pdf_add_string(pdf, obj_start(pdf, l));
+ pdf_add_string(pdf, obj_stop(pdf, l));
+ pdf_end_array(pdf);
pdf_end_dict(pdf);
-
-
+ pdf_end_obj(pdf);
} while (b != 0);
if (k == l) {
dests = l;
goto DONE;
}
-
}
DONE:
if ((dests != 0) || (pdf_names_toks != null)) {
- m = pdf_new_dict(pdf, obj_type_others, 0, 1);
+ m = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, m, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
if (dests != 0)
- pdf_indirect_ln(pdf, "Dests", dests);
+ pdf_dict_add_ref(pdf, "Dests", dests);
if (pdf_names_toks != null) {
- pdf_print_toks_ln(pdf, pdf_names_toks);
+ pdf_print_toks(pdf, pdf_names_toks);
delete_token_ref(pdf_names_toks);
pdf_names_toks = null;
}
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
return m;
} else {
return 0;
--- texk/web2c/luatexdir/pdf/pdffont.w
+++ texk/web2c/luatexdir/pdf/pdffont.w 2011-10-13 07:39:33.000000000 +0000
@@ -37,7 +37,7 @@ fonts too. Information about virtual fon
\.{DVI}-related programs.
Whenever we want to write out a character in a font to PDF output, we
-should check whether the used character is a virtual or read character.
+should check whether the used character is a virtual or real character.
The |has_packet()| C macro checks for this condition.
--- texk/web2c/luatexdir/pdf/pdfgen.h
+++ texk/web2c/luatexdir/pdf/pdfgen.h 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
/* pdfgen.h
- Copyright 2009-2010 Taco Hoekwater <taco@luatex.org>
+ Copyright 2009-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -28,7 +28,7 @@
# define PROCSET_IMAGE_C (1 << 3)
# define PROCSET_IMAGE_I (1 << 4)
-# define inf_pdf_mem_size 10000 /* min size of the |mem| array */
+# define inf_pdf_mem_size 10000/* min size of the |mem| array */
# define sup_pdf_mem_size 10000000 /* max size of the |mem| array */
extern PDF static_pdf;
@@ -43,25 +43,22 @@ output file in initialization to ensure
written bytes.
*/
-# define inf_pdf_op_buf_size 16384 /* size of the PDF output buffer */
-# define sup_pdf_op_buf_size 16384 /* size of the PDF output buffer */
-# define inf_pdf_os_buf_size 1 /* initial value of |pdf_os_buf_size| */
-# define sup_pdf_os_buf_size 5000000 /* arbitrary upper hard limit of |pdf_os_buf_size| */
-# define max_single_pdf_print 8192 /* Max size that can be get from pdf_room() at once.
- the value is on the conservative side, but should be
- large enough to cover most uses */
-# define pdf_os_max_objs 100 /* maximum number of objects in object stream */
+# define inf_pdfout_buf_size 16384 /* initial value of |pdf->buf| size */
+# define sup_pdfout_buf_size 16384 /* arbitrary upper hard limit of |pdf->buf| size */
+# define inf_objstm_buf_size 1 /* initial value of |os->buf[OBJSTM_BUF]| size */
+# define sup_objstm_buf_size 5000000 /* arbitrary upper hard limit of |os->buf[OBJSTM_BUF]| size */
+
+# define PDF_OS_MAX_OBJS 100 /* maximum number of objects in object stream */
# define inf_obj_tab_size 1000 /* min size of the cross-reference table for PDF output */
# define sup_obj_tab_size 8388607 /* max size of the cross-reference table for PDF output */
/* The following macros are similar as for \.{DVI} buffer handling */
-# define pdf_offset(pdf) (pdf->gone + pdf->ptr)
+# define pdf_offset(pdf) (pdf->gone + pdf->buf->p - pdf->buf->data)
/* the file offset of last byte in PDF
buffer that |pdf_ptr| points to */
-# define pdf_save_offset(pdf) pdf->save_offset=(pdf->gone + pdf->ptr)
-# define pdf_saved_offset(pdf) pdf->save_offset
+# define pdf_save_offset(pdf) pdf->save_offset = (pdf->gone + pdf->buf->p - pdf->buf->data)
# define set_ff(A) do { \
if (pdf_font_num(A) < 0) \
@@ -70,12 +67,6 @@ written bytes.
ff = A; \
} while (0)
-typedef enum {
- no_zip = 0, /* no \.{ZIP} compression */
- zip_writing = 1, /* \.{ZIP} compression being used */
- zip_finish = 2 /* finish \.{ZIP} compression */
-} zip_write_states;
-
typedef enum { NOT_SHIPPING, SHIPPING_PAGE, SHIPPING_FORM } shipping_mode_e;
extern int pdf_output_option;
@@ -96,19 +87,10 @@ extern void pdf_room(PDF, int);
extern void fix_pdf_minorversion(PDF);
/* output a byte to PDF buffer without checking of overflow */
-# define pdf_quick_out(pdf,A) pdf->buf[pdf->ptr++]=(unsigned char)A
+# define pdf_quick_out(pdf,A) * (pdf->buf->p++) = (unsigned char) (A)
/* do the same as |pdf_quick_out| and flush the PDF buffer if necessary */
-# define pdf_out(pdf,A) do { pdf_room(pdf,1); pdf_quick_out(pdf,A); } while (0)
-
-# if 0
-/* see function pdf_out_block() */
-# define pdf_out_block_macro(pdf,A,n) do { \
- pdf_room(pdf,(int)(n)); \
- (void)memcpy((pdf->buf+pdf->ptr),(A),(size_t)(n)); \
- pdf->ptr+=(int)(n); \
- } while (0)
-# endif
+# define pdf_out(pdf,A) do { pdf_room(pdf, 1); pdf_quick_out(pdf, A); } while (0)
/*
Basic printing procedures for PDF output are very similiar to \TeX\ basic
@@ -116,39 +98,52 @@ printing ones but the output is going to
suffix |_ln| append a new-line character to the PDF output.
*/
-# define pdf_newline_char 10 /* new-line character '\n' for UNIX platforms */
-
-/* output a new-line character to PDF buffer */
-# define pdf_print_nl(pdf) pdf_out(pdf,pdf_newline_char)
-
/* print out a string to PDF buffer followed by a new-line character */
# define pdf_print_ln(pdf,A) do { \
pdf_print(pdf,A); \
- pdf_print_nl(pdf); \
+ pdf_out(pdf, '\n'); \
} while (0)
/* print out an integer to PDF buffer followed by a new-line character */
-# define pdf_print_int_ln(pdf,A) do { \
- pdf_print_int(pdf,A); \
- pdf_print_nl(pdf); \
+# define pdf_print_int_ln(pdf,A) do { \
+ pdf_print_int(pdf,A); \
+ pdf_out(pdf, '\n'); \
} while (0)
extern __attribute__ ((format(printf, 2, 3)))
void pdf_printf(PDF, const char *, ...);
-extern void pdf_print_char(PDF, int);
-extern void pdf_print_wide_char(PDF, int);
extern void pdf_print(PDF, str_number);
extern void pdf_print_int(PDF, longinteger);
-extern void pdf_print_real(PDF, int, int);
+extern void print_pdffloat(PDF pdf, pdffloat f);
extern void pdf_print_str(PDF, const char *);
+extern void pdf_add_null(PDF);
+extern void pdf_add_bool(PDF, int i);
+extern void pdf_add_int(PDF, int i);
+extern void pdf_add_ref(PDF, int num);
+extern void pdf_add_string(PDF, const char *s);
+extern void pdf_add_name(PDF, const char *name);
+
+extern void pdf_dict_add_bool(PDF, const char *key, int i);
+extern void pdf_dict_add_int(PDF, const char *key, int i);
+extern void pdf_dict_add_ref(PDF, const char *key, int num);
+extern void pdf_dict_add_name(PDF, const char *key, const char *val);
+extern void pdf_dict_add_string(PDF pdf, const char *key, const char *val);
+extern void pdf_dict_add_streaminfo(PDF);
+
extern void pdf_begin_stream(PDF);
extern void pdf_end_stream(PDF);
-extern void pdf_remove_last_space(PDF);
-extern void pdf_print_bp(PDF, scaled);
-extern void pdf_print_mag_bp(PDF, scaled);
+extern void pdf_add_bp(PDF, scaled);
+extern void pdf_add_mag_bp(PDF, scaled);
+
+extern strbuf_s *new_strbuf(size_t size, size_t limit);
+extern void strbuf_seek(strbuf_s * b, off_t offset);
+extern size_t strbuf_offset(strbuf_s * b);
+extern void strbuf_putchar(strbuf_s * b, unsigned char c);
+extern void strbuf_flush(PDF pdf, strbuf_s * b);
+extern void strbuf_free(strbuf_s * b);
/* This is for the resource lists */
@@ -164,36 +159,23 @@ extern void pdf_out_block(PDF pdf, const
pdf_puts(pdf, pdf->resname_prefix); \
} while (0)
-extern void pdf_int_entry(PDF, const char *, int);
-extern void pdf_int_entry_ln(PDF, const char *, int);
-extern void pdf_indirect(PDF, const char *, int);
-extern void pdf_indirect_ln(PDF, const char *, int);
extern void pdf_print_str_ln(PDF, const char *);
-extern void pdf_str_entry(PDF, const char *, const char *);
-extern void pdf_str_entry_ln(PDF, const char *, const char *);
extern void pdf_print_toks(PDF, halfword);
-extern void pdf_print_toks_ln(PDF, halfword);
-extern void pdf_print_rect_spec(PDF, halfword);
+extern void pdf_add_rect_spec(PDF, halfword);
extern void pdf_rectangle(PDF, halfword);
extern void pdf_begin_obj(PDF, int, int);
-extern int pdf_new_obj(PDF, int, int, int);
extern void pdf_end_obj(PDF);
-extern void pdf_begin_dict(PDF, int, int);
-extern int pdf_new_dict(PDF, int, int, int);
+extern void pdf_begin_dict(PDF);
extern void pdf_end_dict(PDF);
+extern void pdf_begin_array(PDF);
+extern void pdf_end_array(PDF);
extern void remove_pdffile(PDF);
-extern int fb_offset(PDF);
-extern void fb_flush(PDF);
-extern void fb_putchar(PDF, eight_bits);
-extern void fb_seek(PDF, int);
-extern void fb_free(PDF);
-
extern void zip_free(PDF);
/* functions that do not output stuff */
@@ -213,6 +195,7 @@ extern char *get_resname_prefix(PDF);
extern void pdf_begin_page(PDF pdf);
extern void pdf_end_page(PDF pdf);
extern void print_pdf_table_string(PDF pdf, const char *s);
+extern int get_pdf_table_bool(PDF, const char *, int);
extern void fix_o_mode(PDF pdf);
extern void ensure_output_state(PDF pdf, output_state s);
--- texk/web2c/luatexdir/pdf/pdfgen.w
+++ texk/web2c/luatexdir/pdf/pdfgen.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% pdfgen.w
-% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2009-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -38,8 +38,6 @@ static const char _svn_version[] =
PDF static_pdf = NULL;
-static char *jobname_cstr = NULL;
-
@ commandline interface
@c
int pdf_output_option;
@@ -54,26 +52,113 @@ halfword pdf_names_toks; /* addit
halfword pdf_trailer_toks; /* additional keys of Trailer dictionary */
shipping_mode_e global_shipping_mode = NOT_SHIPPING; /* set to |shipping_mode| when |ship_out| starts */
-@ |init_pdf_struct()| is called early, only once, from maincontrol.w
+@ Create a new buffer |strbuf_s| of size |size| and maximum allowed size |limit|.
+Initialize it and set |p| to begin of data.
+@c
+strbuf_s *new_strbuf(size_t size, size_t limit)
+{
+ strbuf_s *b;
+ assert(limit >= size);
+ b = xtalloc(1, strbuf_s);
+ b->size = size;
+ b->limit = limit;
+ if (size > 0)
+ b->p = b->data = xtalloc(b->size, unsigned char);
+ else
+ b->p = b->data = NULL; /* for other alloc */
+ return b;
+}
+@ Check that |n| bytes more fit into buffer; increase it if required.
+@c
+static void strbuf_room(strbuf_s * b, size_t n)
+{
+ unsigned int a;
+ size_t l = (size_t) (b->p - b->data);
+ if (n > b->limit - l)
+ overflow("PDF buffer", (unsigned) b->size);
+ if (n + l > b->size) {
+ a = (unsigned int) (b->size >> 2);
+ if (n + l > b->size + a)
+ b->size = n + l;
+ else if (b->size < b->limit - a)
+ b->size = b->size + a;
+ else
+ b->size = b->limit;
+ b->data = xreallocarray(b->data, unsigned char, (unsigned) b->size);
+ b->p = b->data + l;
+ }
+}
+
+@ Seek to position |offset| within buffer. Position must be valid.
+@c
+void strbuf_seek(strbuf_s * b, off_t offset)
+{
+ assert(offset >= 0 && offset < (off_t) b->size);
+ b->p = b->data + offset;
+}
+
+@ Get the current buffer fill level, the number of characters.
+@c
+size_t strbuf_offset(strbuf_s * b)
+{
+ return (size_t) (b->p - b->data);
+}
+
+@ Put one character into buffer. Make room before if needed.
+@c
+void strbuf_putchar(strbuf_s * b, unsigned char c)
+{
+ if ((size_t) (b->p - b->data + 1) > b->size)
+ strbuf_room(b, 1);
+ *b->p++ = c;
+}
+
+@ Dump filled buffer part to PDF.
+@c
+void strbuf_flush(PDF pdf, strbuf_s * b)
+{
+ pdf_out_block(pdf, (const char *) b->data, strbuf_offset(b));
+ strbuf_seek(b, 0);
+}
+
+@ Free all dynamically allocated buffer structures.
+@c
+void strbuf_free(strbuf_s * b)
+{
+ xfree(b->data);
+ xfree(b);
+}
+
+@ |init_pdf_struct()| is called early, only once, from maincontrol.w
@c
PDF init_pdf_struct(PDF pdf)
{
+ os_struct *os;
assert(pdf == NULL);
pdf = xtalloc(1, pdf_output_file);
memset(pdf, 0, sizeof(pdf_output_file));
+ pdf->job_name = makecstring(job_name);
pdf->o_mode = OMODE_NONE; /* will be set by |fix_o_mode()| */
pdf->o_state = ST_INITIAL;
- pdf->os_obj = xtalloc(pdf_os_max_objs, os_obj_data);
- pdf->os_buf_size = inf_pdf_os_buf_size;
- pdf->os_buf = xtalloc(pdf->os_buf_size, unsigned char);
- pdf->op_buf_size = inf_pdf_op_buf_size;
- pdf->op_buf = xtalloc(pdf->op_buf_size, unsigned char);
+ /* init PDF and object stream writing */
+ pdf->os = os = xtalloc(1, os_struct);
+ os->buf[PDFOUT_BUF] = new_strbuf(inf_pdfout_buf_size, sup_pdfout_buf_size);
+ os->buf[OBJSTM_BUF] = new_strbuf(inf_objstm_buf_size, sup_objstm_buf_size);
+ os->buf[LUASTM_BUF] = new_strbuf(0, 0);
+ os->obj = xtalloc(PDF_OS_MAX_OBJS, os_obj_data);
+ os->cur_objstm = 0;
+ os->trigger_luastm = false;
+
+ os->curbuf = PDFOUT_BUF;
+ pdf->buf = os->buf[os->curbuf];
- pdf->buf_size = pdf->op_buf_size;
- pdf->buf = pdf->op_buf;
+ pdf->fb = new_strbuf(1, 100000000);
+
+ pdf->stream_deflate = false;
+ pdf->stream_writing = false;
/* Sometimes it is neccesary to allocate memory for PDF output that cannot
be deallocated then, so we use |mem| for this purpose. */
@@ -112,26 +197,9 @@ PDF init_pdf_struct(PDF pdf)
init_pdf_pagecalculations(pdf);
pdf->pdflua_ref = new_pdflua();
- return pdf;
-}
-
-@ @c
-static void pdf_shipout_begin(void)
-{
- pos_stack_used = 0; /* start with empty stack */
-
- if (global_shipping_mode == SHIPPING_PAGE) {
- colorstackpagestart();
- }
-}
+ pdf->vfstruct = new_vfstruct();
-static void pdf_shipout_end(void)
-{
- if (pos_stack_used > 0) {
- pdftex_fail("%u unmatched \\pdfsave after %s shipout",
- (unsigned int) pos_stack_used,
- ((global_shipping_mode == SHIPPING_PAGE) ? "page" : "form"));
- }
+ return pdf;
}
@ We use |pdf_get_mem| to allocate memory in |mem|.
@@ -144,7 +212,7 @@ int pdf_get_mem(PDF pdf, int s)
if (s > sup_pdf_mem_size - pdf->mem_ptr)
overflow("PDF memory size (pdf_mem_size)", (unsigned) pdf->mem_size);
if (pdf->mem_ptr + s > pdf->mem_size) {
- a = pdf->mem_size / 5;
+ a = pdf->mem_size >> 2;
if (pdf->mem_ptr + s > pdf->mem_size + a) {
pdf->mem_size = pdf->mem_ptr + s;
} else if (pdf->mem_size < sup_pdf_mem_size - a) {
@@ -238,8 +306,9 @@ static void write_zip(PDF pdf)
{
int flush, err = Z_OK;
uInt zip_len;
+ strbuf_s *buf = pdf->buf;
z_stream *s = pdf->c_stream;
- boolean finish = pdf->zip_write_state == zip_finish;
+ boolean finish = pdf->zip_write_state == ZIP_FINISH;
assert(pdf->compress_level > 0);
/* This was just to suppress the filename report in |pdftex_fail|
but zlib errors are rare enough (especially now that the
@@ -265,8 +334,8 @@ static void write_zip(PDF pdf)
}
assert(s != NULL);
assert(pdf->zipbuf != NULL);
- s->next_in = pdf->buf;
- s->avail_in = (uInt) pdf->ptr;
+ s->next_in = buf->data;
+ s->avail_in = (uInt) (buf->p - buf->data);
while (true) {
if (s->avail_out == 0 || (finish && s->avail_out < ZIP_BUF_SIZE)) {
zip_len = ZIP_BUF_SIZE - s->avail_out;
@@ -280,6 +349,7 @@ static void write_zip(PDF pdf)
assert(s->avail_in == 0);
assert(s->avail_out == ZIP_BUF_SIZE);
xfflush(pdf->file);
+ pdf->zip_write_state = NO_ZIP;
break;
}
flush = Z_FINISH;
@@ -305,6 +375,19 @@ void zip_free(PDF pdf)
xfree(pdf->c_stream);
}
+@ @c
+static void write_nozip(PDF pdf)
+{
+ strbuf_s *buf = pdf->buf;
+ size_t l = strbuf_offset(buf);
+ if (l == 0)
+ return;
+ pdf->stream_length = pdf_offset(pdf) - pdf->save_offset;
+ pdf->gone +=
+ (off_t) xfwrite((char *) buf->data, sizeof(char), l, pdf->file);
+ pdf->last_byte = *(buf->p - 1);
+}
+
@ The PDF buffer is flushed by calling |pdf_flush|, which checks the
variable |zip_write_state| and will compress the buffer before flushing if
neccesary. We call |pdf_begin_stream| to begin a stream and |pdf_end_stream|
@@ -312,173 +395,142 @@ to finish it. The stream contents will b
@c
void pdf_flush(PDF pdf)
-{ /* flush out the |pdf_buf| */
-
- off_t saved_pdf_gone;
- if (!pdf->os_mode) {
- saved_pdf_gone = pdf->gone;
- switch (pdf->zip_write_state) {
- case no_zip:
- if (pdf->ptr > 0) {
- if (pdf->draftmode == 0)
- (void) xfwrite((char *) pdf->buf, sizeof(char),
- (size_t) pdf->ptr, pdf->file);
- pdf->gone += pdf->ptr;
- pdf->last_byte = pdf->buf[pdf->ptr - 1];
- }
- break;
- case zip_writing:
- if (pdf->draftmode == 0)
- write_zip(pdf);
- break;
- case zip_finish:
- if (pdf->draftmode == 0)
+{ /* flush out the |pdf->buf| */
+ os_struct *os = pdf->os;
+ off_t saved_pdf_gone = pdf->gone;
+ assert(pdf->buf == os->buf[os->curbuf]);
+ switch (os->curbuf) {
+ case PDFOUT_BUF:
+ if (pdf->draftmode == 0) {
+ switch (pdf->zip_write_state) {
+ case NO_ZIP:
+ write_nozip(pdf);
+ break;
+ case ZIP_WRITING:
+ case ZIP_FINISH:
write_zip(pdf);
- pdf->zip_write_state = no_zip;
- break;
+ break;
+ default:
+ assert(0);
+ }
}
- pdf->ptr = 0;
+ strbuf_seek(pdf->buf, 0);
if (saved_pdf_gone > pdf->gone)
pdf_error("file size",
"File size exceeds architectural limits (pdf_gone wraps around)");
+ break;
+ case LUASTM_BUF:
+ luaL_addsize(&(os->b), strbuf_offset(pdf->buf));
+ pdf->buf->p = pdf->buf->data = (unsigned char *) luaL_prepbuffer(&(os->b)); /* for next stream piece */
+ break;
+ case OBJSTM_BUF:
+ break;
+ default:
+ assert(0);
}
}
-@ switch between PDF stream and object stream mode
-
-@c
-static void pdf_os_switch(PDF pdf, boolean pdf_os)
+@ @c
+static void pdf_buffer_select(PDF pdf, boolean do_os)
{
- if (pdf_os && pdf->os_enable) {
- if (!pdf->os_mode) { /* back up PDF stream variables */
- pdf->op_ptr = pdf->ptr;
- pdf->ptr = pdf->os_ptr;
- pdf->buf = pdf->os_buf;
- pdf->buf_size = pdf->os_buf_size;
- pdf->os_mode = true; /* switch to object stream */
- }
+ os_struct *os = pdf->os;
+ if (pdf->os_enable && do_os) {
+ os->curbuf = OBJSTM_BUF; /* switch to object stream */
} else {
- if (pdf->os_mode) { /* back up object stream variables */
- pdf->os_ptr = pdf->ptr;
- pdf->ptr = pdf->op_ptr;
- pdf->buf = pdf->op_buf;
- pdf->buf_size = pdf->op_buf_size;
- pdf->os_mode = false; /* switch to PDF stream */
- }
+ os->curbuf = PDFOUT_BUF; /* switch to PDF stream */
}
+ pdf->buf = os->buf[pdf->os->curbuf];
}
-@ create new \.{/ObjStm} object if required, and set up cross reference info
+@ create new \.{/ObjStm} object if required, and set up cross reference info
@c
-static void pdf_os_prepare_obj(PDF pdf, int i, int pdf_os_level)
-{
- pdf_os_switch(pdf, ((pdf_os_level > 0)
- && (pdf->objcompresslevel >= pdf_os_level)));
- if (pdf->os_mode) {
- if (pdf->os_cur_objnum == 0) {
- pdf->os_cur_objnum =
- pdf_create_obj(pdf, obj_type_objstm, pdf->obj_ptr + 1);
- pdf->os_cntr++; /* only for statistics */
- pdf->os_idx = 0;
- pdf->ptr = 0; /* start fresh object stream */
- } else {
- pdf->os_idx++;
- }
- obj_os_idx(pdf, i) = pdf->os_idx;
- obj_offset(pdf, i) = pdf->os_cur_objnum;
- pdf->os_obj[pdf->os_idx].num = i;
- pdf->os_obj[pdf->os_idx].off = pdf->ptr;
- } else {
- obj_offset(pdf, i) = pdf_offset(pdf);
- obj_os_idx(pdf, i) = -1; /* mark it as not included in object stream */
+static void pdf_prepare_obj(PDF pdf, int k, int pdf_os_threshold)
+{
+ os_struct *os = pdf->os;
+ strbuf_s *obuf = os->buf[OBJSTM_BUF];
+ assert(os->curbuf != LUASTM_BUF);
+ assert(pdf_os_threshold >= OBJSTM_ALWAYS);
+ pdf_buffer_select(pdf, (pdf->objcompresslevel >= pdf_os_threshold));
+ assert(pdf->buf == os->buf[os->curbuf]);
+ switch (os->curbuf) {
+ case PDFOUT_BUF:
+ obj_offset(pdf, k) = pdf_offset(pdf);
+ obj_os_idx(pdf, k) = PDF_OS_MAX_OBJS; /* mark it as not included in any ObjStm */
+ break;
+ case LUASTM_BUF:
+ assert(0);
+ break;
+ case OBJSTM_BUF:
+ if (os->cur_objstm == 0) {
+ os->cur_objstm = (unsigned int) pdf_create_obj(pdf, obj_type_objstm, 0);
+ os->idx = 0;
+ obuf->p = obuf->data; /* start fresh object stream */
+ os->ostm_ctr++; /* only for statistics */
+ }
+ assert(os->idx < PDF_OS_MAX_OBJS); /* for marking below */
+ obj_os_idx(pdf, k) = (int) os->idx;
+ obj_os_objnum(pdf, k) = (int) os->cur_objstm;
+ os->obj[os->idx].num = k;
+ os->obj[os->idx].off = obuf->p - obuf->data;
+ break;
+ default:
+ assert(0);
}
}
-@* low-level buffer checkers.
-
-@ check that |s| bytes more fit into |pdf_os_buf|; increase it if required
-@c
-static void pdf_os_get_os_buf(PDF pdf, int s)
-{
- int a;
- if (s > sup_pdf_os_buf_size - pdf->ptr)
- overflow("PDF object stream buffer", (unsigned) pdf->os_buf_size);
- if (pdf->ptr + s > pdf->os_buf_size) {
- a = pdf->os_buf_size / 5;
- if (pdf->ptr + s > pdf->os_buf_size + a)
- pdf->os_buf_size = pdf->ptr + s;
- else if (pdf->os_buf_size < sup_pdf_os_buf_size - a)
- pdf->os_buf_size = pdf->os_buf_size + a;
- else
- pdf->os_buf_size = sup_pdf_os_buf_size;
- pdf->os_buf =
- xreallocarray(pdf->os_buf, unsigned char,
- (unsigned) pdf->os_buf_size);
- pdf->buf = pdf->os_buf;
- pdf->buf_size = pdf->os_buf_size;
- }
-}
-
-@ make sure that there are at least |n| bytes free in PDF buffer
+@* Low-level buffer checkers.
+
+@ Set the active buffer pointer.
+Make sure that there are at least |n| bytes free in that buffer,
+flush if needed.
@c
void pdf_room(PDF pdf, int n)
{
- if (pdf->os_mode && (n + pdf->ptr > pdf->buf_size))
- pdf_os_get_os_buf(pdf, n);
- else if ((!pdf->os_mode) && (n > pdf->buf_size))
- overflow("PDF output buffer", (unsigned) pdf->op_buf_size);
- else if ((!pdf->os_mode) && (n + pdf->ptr > pdf->buf_size))
- pdf_flush(pdf);
-}
-
-
-@ print out a character to PDF buffer; the character will be printed in octal
- form in the following cases: chars <= 32, backslash (92), left parenthesis
- (40) and right parenthesis (41)
-
-@c
-#define pdf_print_escaped(c) \
- if ((c)<=32||(c)=='\\'||(c)=='('||(c)==')'||(c)>127) { \
- pdf_room(pdf,4); \
- pdf_quick_out(pdf,'\\'); \
- pdf_quick_out(pdf,(unsigned char)('0' + (((c)>>6) & 0x3))); \
- pdf_quick_out(pdf,(unsigned char)('0' + (((c)>>3) & 0x7))); \
- pdf_quick_out(pdf,(unsigned char)('0' + ( (c) & 0x7))); \
- } else { \
- pdf_out(pdf,(c)); \
- }
-
-void pdf_print_char(PDF pdf, int c)
-{
- if (c > 255)
+ os_struct *os = pdf->os;
+ strbuf_s *buf = pdf->buf;
+ if ((size_t) (n + buf->p - buf->data) <= buf->size)
return;
- pdf_print_escaped(c);
+ assert(buf == os->buf[os->curbuf]);
+ switch (os->curbuf) {
+ case PDFOUT_BUF:
+ if ((size_t) n > buf->size)
+ overflow("PDF output buffer", (unsigned) buf->size);
+ if ((size_t) (n + buf->p - buf->data) < buf->limit)
+ strbuf_room(buf, (size_t) n); /* grow it if possible */
+ else
+ pdf_flush(pdf);
+ break;
+ case LUASTM_BUF:
+ if ((size_t) n > buf->size)
+ overflow("PDF output buffer", (unsigned) buf->size);
+ pdf_flush(pdf);
+ break;
+ case OBJSTM_BUF:
+ strbuf_room(buf, (size_t) n); /* just grow it */
+ break;
+ default:
+ assert(0);
+ }
}
@ @c
void pdf_out_block(PDF pdf, const char *s, size_t n)
{
size_t l;
+ strbuf_s *buf = pdf->buf;
do {
l = n;
- if ((int) l > pdf->buf_size)
- l = (size_t) pdf->buf_size;
+ if (l > buf->size)
+ l = buf->size;
pdf_room(pdf, (int) l);
- (void) memcpy(pdf->buf + pdf->ptr, s, l);
- pdf->ptr += (int) l;
+ (void) memcpy(buf->p, s, l);
+ buf->p += l;
s += l;
n -= l;
} while (n > 0);
}
-void pdf_print_wide_char(PDF pdf, int c)
-{
- char hex[5];
- snprintf(hex, 5, "%04X", c);
- pdf_out_block(pdf, (const char *) hex, 4);
-}
-
@ @c
__attribute__ ((format(printf, 2, 3)))
void pdf_printf(PDF pdf, const char *fmt, ...)
@@ -513,60 +565,40 @@ void pdf_print(PDF pdf, str_number s)
@c
void pdf_print_int(PDF pdf, longinteger n)
{
- register int k = 0; /* current digit; we assume that $|n|<10^{23}$ */
- int dig[24];
- if (n < 0) {
- pdf_out(pdf, '-');
- if (n < -0x7FFFFFFF) { /* need to negate |n| more carefully */
- register longinteger m;
- k++;
- m = -1 - n;
- n = m / 10;
- m = (m % 10) + 1;
- if (m < 10) {
- dig[0] = (int) m;
- } else {
- dig[0] = 0;
- n++;
- }
- } else {
- n = -n;
- }
- }
- do {
- dig[k++] = (int) (n % 10);
- n /= 10;
- } while (n != 0);
- pdf_room(pdf, k);
- while (k-- > 0) {
- pdf_quick_out(pdf, (unsigned char) ('0' + dig[k]));
- }
+ char s[24];
+ int w;
+ w = snprintf(s, 23, "%ld", n);
+ check_nprintf(w, 23);
+ pdf_out_block(pdf, (const char *) s, (size_t) w);
}
-@ print $m/10^d$ as real
-@c
-void pdf_print_real(PDF pdf, int m, int d)
+@ @c
+void print_pdffloat(PDF pdf, pdffloat f)
{
+ char a[24];
+ int e = f.e, i, j;
+ long l, m = f.m;
if (m < 0) {
pdf_out(pdf, '-');
- m = -m;
- };
- pdf_print_int(pdf, m / ten_pow[d]);
- m = m % ten_pow[d];
- if (m > 0) {
+ m *= -1;
+ }
+ l = m / ten_pow[e];
+ pdf_print_int(pdf, l);
+ l = m % ten_pow[e];
+ if (l != 0) {
pdf_out(pdf, '.');
- d--;
- while (m < ten_pow[d]) {
- pdf_out(pdf, '0');
- d--;
+ j = snprintf(a, 23, "%ld", l + ten_pow[e]);
+ assert(j < 23);
+ for (i = e; i > 0; i--) {
+ if (a[i] != '0')
+ break;
+ a[i] = '\0';
}
- while (m % 10 == 0)
- m /= 10;
- pdf_print_int(pdf, m);
+ pdf_puts(pdf, (a + 1));
}
}
-@ print out |s| as string in PDF output
+@ print out |s| as string in PDF output
@c
void pdf_print_str(PDF pdf, const char *s)
{
@@ -599,64 +631,93 @@ void pdf_print_str(PDF pdf, const char *
pdf_puts(pdf, orig); /* it was a hex string after all */
}
-@ begin a stream
+@ begin a stream (needs to have a stream dictionary also)
@c
void pdf_begin_stream(PDF pdf)
{
- assert(pdf->os_mode == false);
- pdf_puts(pdf, "/Length \n");
- pdf->seek_write_length = true; /* fill in length at |pdf_end_stream| call */
- pdf->stream_length_offset = pdf_offset(pdf) - 11;
+ os_struct *os = pdf->os;
+ strbuf_s *lbuf = os->buf[LUASTM_BUF];
+ assert(os->curbuf == PDFOUT_BUF);
+ assert(pdf->buf == os->buf[os->curbuf]);
+ assert(pdf->zip_write_state == NO_ZIP);
+ pdf_puts(pdf, "\nstream\n");
+ pdf_save_offset(pdf);
+ pdf_flush(pdf);
+ if (os->trigger_luastm) {
+ os->trigger_luastm = false; /* this was just a trigger */
+ luaL_buffinit(Luas, &(os->b));
+ lbuf->p = lbuf->data = (unsigned char *) luaL_prepbuffer(&(os->b));
+ lbuf->size = lbuf->limit = LUAL_BUFFERSIZE;
+ os->curbuf = LUASTM_BUF;
+ pdf->buf = os->buf[os->curbuf];
+ }
+ if (pdf->stream_deflate) {
+ assert(pdf->compress_level > 0);
+ pdf->zip_write_state = ZIP_WRITING;
+ }
+ pdf->stream_writing = true;
pdf->stream_length = 0;
pdf->last_byte = 0;
- if (pdf->compress_level > 0) {
- pdf_puts(pdf, "/Filter /FlateDecode\n");
- pdf_puts(pdf, ">>\n");
- pdf_puts(pdf, "stream\n");
- pdf_flush(pdf);
- pdf->zip_write_state = zip_writing;
- } else {
- pdf_puts(pdf, ">>\n");
- pdf_puts(pdf, "stream\n");
- pdf_save_offset(pdf);
- }
}
-@ @c
-static void write_stream_length(PDF pdf, int length, longinteger offset)
-{
- if (jobname_cstr == NULL)
- jobname_cstr = makecstring(job_name);
- if (pdf->draftmode == 0) {
- xfseeko(pdf->file, (off_t) offset, SEEK_SET, jobname_cstr);
- fprintf(pdf->file, "%li", (long int) length);
- xfseeko(pdf->file, pdf_offset(pdf), SEEK_SET, jobname_cstr);
- }
-}
-
-@ end a stream
+@ end a stream
@c
void pdf_end_stream(PDF pdf)
{
- if (pdf->zip_write_state == zip_writing)
- pdf->zip_write_state = zip_finish;
- else
- pdf->stream_length = pdf_offset(pdf) - pdf_saved_offset(pdf);
- pdf_flush(pdf);
- if (pdf->seek_write_length)
- write_stream_length(pdf, (int) pdf->stream_length,
- pdf->stream_length_offset);
+ os_struct *os = pdf->os;
+ strbuf_s *lbuf = os->buf[LUASTM_BUF];
+ lstring ls;
+ assert(pdf->buf == os->buf[os->curbuf]);
+ switch (os->curbuf) {
+ case PDFOUT_BUF:
+ if (pdf->zip_write_state == ZIP_WRITING)
+ pdf->zip_write_state = ZIP_FINISH;
+ pdf_flush(pdf); /* sets pdf->last_byte */
+ break;
+ case LUASTM_BUF:
+ luaL_addsize(&(os->b), strbuf_offset(os->buf[LUASTM_BUF]));
+ luaL_pushresult(&(os->b));
+
+ /* now the complete page stream is on the Lua stack */
+ /* TODO: pagestream filter callback here */
+
+ ls.s = lua_tolstring(Luas, -1, &ls.l);
+ lbuf->data = (unsigned char *) ls.s;
+ lbuf->p = lbuf->data + ls.l;
+ os->curbuf = LUASTM_BUF;
+ pdf->buf = os->buf[os->curbuf];
+ if (pdf->zip_write_state == ZIP_WRITING) {
+ pdf->zip_write_state = ZIP_FINISH;
+ write_zip(pdf);
+ } else
+ write_nozip(pdf);
+ lua_pop(Luas, 1);
+ os->curbuf = PDFOUT_BUF;
+ pdf->buf = os->buf[os->curbuf];
+ assert(pdf->buf->data == pdf->buf->p);
+ break;
+ case OBJSTM_BUF:
+ assert(0);
+ break;
+ default:
+ assert(0);
+ }
+ assert(pdf->zip_write_state == NO_ZIP);
+ assert(os->curbuf == PDFOUT_BUF);
+ assert(pdf->buf == os->buf[os->curbuf]);
+ pdf->stream_deflate = false;
+ pdf->stream_writing = false;
+ if (pdf->last_byte != '\n')
+ pdf_out(pdf, '\n'); /* doesn't really belong to the stream */
+ pdf_puts(pdf, "endstream");
+ /* write stream /Length */
+ if (pdf->seek_write_length && pdf->draftmode == 0) {
+ xfseeko(pdf->file, (off_t) pdf->stream_length_offset, SEEK_SET,
+ pdf->job_name);
+ fprintf(pdf->file, "%li", (long int) pdf->stream_length);
+ xfseeko(pdf->file, 0, SEEK_END, pdf->job_name);
+ }
pdf->seek_write_length = false;
- if (pdf->last_byte != pdf_newline_char)
- pdf_out(pdf, pdf_newline_char);
- pdf_puts(pdf, "endstream\n");
- pdf_end_obj(pdf);
-}
-
-void pdf_remove_last_space(PDF pdf)
-{
- if ((pdf->ptr > 0) && (pdf->buf[pdf->ptr - 1] == ' '))
- pdf->ptr--;
}
@ To print |scaled| value to PDF output we need some subroutines to ensure
@@ -720,19 +781,20 @@ scaled round_xn_over_d(scaled x, int n,
}
@ @c
-#define lround(a) (long) floor((a) + 0.5)
-
-void pdf_print_bp(PDF pdf, scaled s)
+void pdf_add_bp(PDF pdf, scaled s)
{ /* print scaled as |bp| */
pdffloat a;
pdfstructure *p = pdf->pstruct;
assert(p != NULL);
a.m = lround(s * p->k1);
a.e = pdf->decimal_digits;
+ if (pdf->cave > 0)
+ pdf_out(pdf, ' ');
print_pdffloat(pdf, a);
+ pdf->cave = 1;
}
-void pdf_print_mag_bp(PDF pdf, scaled s)
+void pdf_add_mag_bp(PDF pdf, scaled s)
{ /* take |mag| into account */
pdffloat a;
pdfstructure *p = pdf->pstruct;
@@ -742,18 +804,12 @@ void pdf_print_mag_bp(PDF pdf, scaled s)
else
a.m = lround(s * p->k1);
a.e = pdf->decimal_digits;
+ if (pdf->cave > 0)
+ pdf_out(pdf, ' ');
print_pdffloat(pdf, a);
+ pdf->cave = 1;
}
-#define set_p_or_return(a) do { \
- p = a; \
- if (p==NULL) { \
- a = item; \
- return; \
- } \
- } while (0)
-
-
@* handling page resources.
@c
@@ -879,7 +935,7 @@ static void destroy_page_resources_tree(
@* Subroutines to print out various PDF objects.
-@ print out an integer |n| with fixed width |w|; used for outputting cross-reference table
+@ print out an integer |n| with fixed width |w|; used for outputting cross-reference table
@c
static void pdf_print_fw_int(PDF pdf, longinteger n, size_t w)
{
@@ -894,7 +950,7 @@ static void pdf_print_fw_int(PDF pdf, lo
pdf_out_block(pdf, (const char *) digits, w);
}
-@ print out an integer |n| as a fixed number |w| of bytes; used for outputting \.{/XRef} cross-reference stream
+@ print out an integer |n| as a fixed number |w| of bytes; used for outputting \.{/XRef} cross-reference stream
@c
static void pdf_out_bytes(PDF pdf, longinteger n, size_t w)
{
@@ -909,59 +965,12 @@ static void pdf_out_bytes(PDF pdf, longi
pdf_out_block(pdf, (const char *) bytes, w);
}
-@ print out an entry in dictionary with integer value to PDF buffer
-@c
-void pdf_int_entry(PDF pdf, const char *s, int v)
-{
- pdf_printf(pdf, "/%s ", s);
- pdf_print_int(pdf, v);
-}
-
-void pdf_int_entry_ln(PDF pdf, const char *s, int v)
-{
-
- pdf_int_entry(pdf, s, v);
- pdf_print_nl(pdf);
-}
-
-@ print out an indirect entry in dictionary
-@c
-void pdf_indirect(PDF pdf, const char *s, int o)
-{
- pdf_printf(pdf, "/%s %d 0 R", s, (int) o);
-}
-
-void pdf_indirect_ln(PDF pdf, const char *s, int o)
-{
-
- pdf_indirect(pdf, s, o);
- pdf_print_nl(pdf);
-}
-
-@ print out |s| as string in PDF output
+@ print out |s| as string in PDF output
@c
void pdf_print_str_ln(PDF pdf, const char *s)
{
pdf_print_str(pdf, s);
- pdf_print_nl(pdf);
-}
-
-@ print out an entry in dictionary with string value to PDF buffer
-@c
-void pdf_str_entry(PDF pdf, const char *s, const char *v)
-{
- if (v == 0)
- return;
- pdf_printf(pdf, "/%s ", s);
- pdf_print_str(pdf, v);
-}
-
-void pdf_str_entry_ln(PDF pdf, const char *s, const char *v)
-{
- if (v == 0)
- return;
- pdf_str_entry(pdf, s, v);
- pdf_print_nl(pdf);
+ pdf_out(pdf, '\n');
}
@ @c
@@ -969,43 +978,34 @@ void pdf_print_toks(PDF pdf, halfword p)
{
int len = 0;
char *s = tokenlist_to_cstring(p, true, &len);
- if (len > 0)
- pdf_puts(pdf, s);
- xfree(s);
-}
-
-void pdf_print_toks_ln(PDF pdf, halfword p)
-{
- int len = 0;
- char *s = tokenlist_to_cstring(p, true, &len);
if (len > 0) {
+ if (pdf->cave > 0)
+ pdf_out(pdf, ' ');
pdf_puts(pdf, s);
- pdf_print_nl(pdf);
+ pdf->cave = 1;
}
xfree(s);
}
-@ prints a rect spec
+@ prints a rect spec
@c
-void pdf_print_rect_spec(PDF pdf, halfword r)
+void pdf_add_rect_spec(PDF pdf, halfword r)
{
- pdf_print_mag_bp(pdf, pdf_ann_left(r));
- pdf_out(pdf, ' ');
- pdf_print_mag_bp(pdf, pdf_ann_bottom(r));
- pdf_out(pdf, ' ');
- pdf_print_mag_bp(pdf, pdf_ann_right(r));
- pdf_out(pdf, ' ');
- pdf_print_mag_bp(pdf, pdf_ann_top(r));
+ pdf_add_mag_bp(pdf, pdf_ann_left(r));
+ pdf_add_mag_bp(pdf, pdf_ann_bottom(r));
+ pdf_add_mag_bp(pdf, pdf_ann_right(r));
+ pdf_add_mag_bp(pdf, pdf_ann_top(r));
}
-@ output a rectangle specification to PDF file
+@ output a rectangle specification to PDF file
@c
void pdf_rectangle(PDF pdf, halfword r)
{
prepare_mag();
- pdf_puts(pdf, "/Rect [");
- pdf_print_rect_spec(pdf, r);
- pdf_puts(pdf, "]\n");
+ pdf_add_name(pdf, "Rect");
+ pdf_begin_array(pdf);
+ pdf_add_rect_spec(pdf, r);
+ pdf_end_array(pdf);
}
@ @c
@@ -1019,7 +1019,7 @@ static void init_pdf_outputparameters(PD
pdf->image_gamma = fix_int(pdf_image_gamma, 0, 1000000);
pdf->image_hicolor = fix_int(pdf_image_hicolor, 0, 1);
pdf->image_apply_gamma = fix_int(pdf_image_apply_gamma, 0, 1);
- pdf->objcompresslevel = fix_int(pdf_objcompresslevel, 0, 3);
+ pdf->objcompresslevel = fix_int(pdf_objcompresslevel, 0, MAX_OBJ_COMPRESS_LEVEL);
pdf->inclusion_copy_font = fix_int(pdf_inclusion_copy_font, 0, 1);
pdf->replace_font = fix_int(pdf_replace_font, 0, 1);
pdf->pk_resolution = fix_int(pdf_pk_resolution, 72, 8000);
@@ -1055,7 +1055,7 @@ static void init_pdf_outputparameters(PD
pdf->resname_prefix = get_resname_prefix(pdf);
}
-@ Checks that we have a name for the generated PDF file and that it's open.
+@ Checks that we have a name for the generated PDF file and that it's open.
@c
static void ensure_output_file_open(PDF pdf, const char *ext)
@@ -1088,7 +1088,7 @@ static void ensure_pdf_header_written(PD
pdf_out(pdf, 'T' + 128);
pdf_out(pdf, 'E' + 128);
pdf_out(pdf, 'X' + 128);
- pdf_print_nl(pdf);
+ pdf_out(pdf, '\n');
}
@ @c
@@ -1152,117 +1152,242 @@ When calling this procedure, |pdf_os_mod
@c
static void pdf_os_write_objstream(PDF pdf)
{
- halfword i, j, p, q;
- if (pdf->os_cur_objnum == 0) /* no object stream started */
+ os_struct *os = pdf->os;
+ unsigned int i, j, n1, n2; /* n1, n2: ObjStm buffer may be reallocated! */
+ strbuf_s *obuf = os->buf[OBJSTM_BUF];
+ if (os->cur_objstm == 0) /* no object stream started */
return;
- p = pdf->ptr;
- i = 0;
- j = 0;
- while (i <= pdf->os_idx) { /* assemble object number and byte offset pairs */
- pdf_printf(pdf, "%d %d", (int) pdf->os_obj[i].num,
- (int) pdf->os_obj[i].off);
- if (j == 9) { /* print out in groups of ten for better readability */
- pdf_out(pdf, pdf_newline_char);
+ assert(pdf->buf == obuf); /* yes, pdf_out() still goes into ObjStm */
+ assert(os->idx > 0); /* yes, there are objects for the ObjStm */
+ n1 = (unsigned int) strbuf_offset(obuf); /* remember end of collected object stream contents */
+ /* this is needed here to calculate /First for the ObjStm dict */
+ for (i = 0, j = 0; i < os->idx; i++) { /* add object-number/byte-offset list to buffer */
+ pdf_print_int(pdf, (int) os->obj[i].num);
+ pdf_out(pdf, ' ');
+ pdf_print_int(pdf, (int) os->obj[i].off);
+ if (j == 9 || i == os->idx - 1) { /* print out in groups of ten for better readability */
+ pdf_out(pdf, '\n');
j = 0;
} else {
pdf_out(pdf, ' ');
j++;
}
- i++;
}
- pdf->buf[pdf->ptr - 1] = pdf_newline_char; /* no risk of flush, as we are in |pdf_os_mode| */
- q = pdf->ptr;
- pdf_begin_dict(pdf, pdf->os_cur_objnum, 0); /* switch to PDF stream writing */
- pdf_puts(pdf, "/Type /ObjStm\n");
- pdf_printf(pdf, "/N %d\n", (int) (pdf->os_idx + 1));
- pdf_printf(pdf, "/First %d\n", (int) (q - p));
+ n2 = (unsigned int) strbuf_offset(obuf); /* remember current buffer end */
+ pdf_begin_obj(pdf, (int) os->cur_objstm, OBJSTM_NEVER); /* switch to PDF stream writing */
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "ObjStm");
+ pdf_dict_add_int(pdf, "N", (int) os->idx); /* number of objects in ObjStm */
+ pdf_dict_add_int(pdf, "First", (int) (n2 - n1));
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
- /* write object number and byte offset pairs;
- |q - p| should always fit into the PDF output buffer */
- pdf_out_block(pdf, (const char *) (pdf->os_buf + p), (size_t) (q - p));
- i = 0;
- while (i < p) {
- q = i + pdf->buf_size;
- if (q > p)
- q = p;
- pdf_room(pdf, q - i);
- while (i < q) { /* write the buffered objects */
- pdf_quick_out(pdf, pdf->os_buf[i]);
- i++;
- }
- }
+ /* write object-number/byte-offset list */
+ pdf_out_block(pdf, (const char *) (obuf->data + n1), (size_t) (n2 - n1));
+ /* write collected object stream contents */
+ pdf_out_block(pdf, (const char *) obuf->data, (size_t) n1);
pdf_end_stream(pdf);
- pdf->os_cur_objnum = 0; /* to force object stream generation next time */
+ pdf_end_obj(pdf);
+ os->cur_objstm = 0; /* to force object stream generation next time */
}
-@ begin a PDF dictionary object
+@ begin a PDF dictionary
@c
-void pdf_begin_dict(PDF pdf, int i, int pdf_os_level)
+void pdf_begin_dict(PDF pdf)
{
- ensure_output_state(pdf, ST_HEADER_WRITTEN);
- pdf_os_prepare_obj(pdf, i, pdf_os_level);
- if (!pdf->os_mode) {
- pdf_printf(pdf, "%d 0 obj\n<<\n", (int) i);
- } else {
- if (pdf->compress_level == 0)
- pdf_printf(pdf, "%% %d 0 obj\n", (int) i); /* debugging help */
- pdf_puts(pdf, "<<\n");
- }
+ pdf_puts(pdf, "<<");
+ pdf->cave = 0;
}
-@ begin a new PDF dictionary object
+@ end a PDF dictionary
@c
-int pdf_new_dict(PDF pdf, int t, int i, int pdf_os_level)
+void pdf_end_dict(PDF pdf)
{
- int k = pdf_create_obj(pdf, t, i);
- pdf_begin_dict(pdf, k, pdf_os_level);
- return k;
+ pdf_puts(pdf, ">>");
+ pdf->cave = 0;
}
-@ end a PDF dictionary object
+@ add integer object to dict
@c
-void pdf_end_dict(PDF pdf)
+void pdf_dict_add_bool(PDF pdf, const char *key, int i)
{
- if (pdf->os_mode) {
- pdf_puts(pdf, ">>\n");
- if (pdf->os_idx == pdf_os_max_objs - 1)
- pdf_os_write_objstream(pdf);
- } else {
- pdf_puts(pdf, ">>\nendobj\n");
- }
+ pdf_add_name(pdf, key);
+ pdf_add_bool(pdf, i);
}
-@ begin a PDF object
+@ add integer object to dict
@c
-void pdf_begin_obj(PDF pdf, int i, int pdf_os_level)
+void pdf_dict_add_int(PDF pdf, const char *key, int i)
{
- ensure_output_state(pdf, ST_HEADER_WRITTEN);
- pdf_os_prepare_obj(pdf, i, pdf_os_level);
- if (!pdf->os_mode) {
- pdf_printf(pdf, "%d 0 obj\n", (int) i);
- } else if (pdf->compress_level == 0) {
- pdf_printf(pdf, "%% %d 0 obj\n", (int) i); /* debugging help */
+ pdf_add_name(pdf, key);
+ pdf_add_int(pdf, i);
+}
+
+@ add name object to dict
+@c
+void pdf_dict_add_name(PDF pdf, const char *key, const char *val)
+{
+ pdf_add_name(pdf, key);
+ pdf_add_name(pdf, val);
+}
+
+@ add string object to dict
+@c
+void pdf_dict_add_string(PDF pdf, const char *key, const char *val)
+{
+ if (val == NULL)
+ return;
+ pdf_add_name(pdf, key);
+ if (pdf->cave > 0)
+ pdf_out(pdf, ' ');
+ pdf->cave = 0;
+ pdf_print_str(pdf, val);
+}
+
+@ add name reference to dict
+@c
+void pdf_dict_add_ref(PDF pdf, const char *key, int num)
+{
+ pdf_add_name(pdf, key);
+ pdf_add_ref(pdf, num);
+}
+
+@ add objects of different types
+@c
+void pdf_add_null(PDF pdf)
+{
+ if (pdf->cave > 0)
+ pdf_out(pdf, ' ');
+ pdf_puts(pdf, "null");
+ pdf->cave = 1;
+}
+
+void pdf_add_bool(PDF pdf, int i)
+{
+ if (pdf->cave > 0)
+ pdf_out(pdf, ' ');
+ if (i == 0)
+ pdf_puts(pdf, "false");
+ else
+ pdf_puts(pdf, "true");
+ pdf->cave = 1;
+}
+
+void pdf_add_int(PDF pdf, int i)
+{
+ if (pdf->cave > 0)
+ pdf_out(pdf, ' ');
+ pdf_print_int(pdf, i);
+ pdf->cave = 1;
+}
+
+void pdf_add_string(PDF pdf, const char *s)
+{
+ if (pdf->cave > 0)
+ pdf_out(pdf, ' ');
+ pdf_print_str(pdf, s);
+ pdf->cave = 1;
+}
+
+void pdf_add_name(PDF pdf, const char *name)
+{
+ pdf_out(pdf, '/');
+ pdf_puts(pdf, name);
+ pdf->cave = 1;
+}
+
+void pdf_add_ref(PDF pdf, int num)
+{
+ if (pdf->cave > 0)
+ pdf_out(pdf, ' ');
+ pdf_print_int(pdf, num);
+ pdf_puts(pdf, " 0 R");
+ pdf->cave = 1;
+}
+
+@ add stream length and filter entries to a stream dictionary,
+remember file position for seek
+@c
+void pdf_dict_add_streaminfo(PDF pdf)
+{
+ assert(pdf->buf == pdf->os->buf[PDFOUT_BUF]);
+ pdf_add_name(pdf, "Length");
+ pdf->stream_length_offset = pdf_offset(pdf) + 1;
+ pdf->seek_write_length = true; /* fill in length at |pdf_end_stream| call */
+ pdf_puts(pdf, " x "); /* space for 10 decimal digits */
+ pdf->cave = 1;
+ if (pdf->compress_level > 0) {
+ pdf_dict_add_name(pdf, "Filter", "FlateDecode");
+ pdf->stream_deflate = true;
}
}
-@ begin a new PDF object
+@ begin a PDF array
@c
-int pdf_new_obj(PDF pdf, int t, int i, int pdf_os_level)
+void pdf_begin_array(PDF pdf)
{
- int k = pdf_create_obj(pdf, t, i);
- pdf_begin_obj(pdf, k, pdf_os_level);
- return k;
+ pdf_out(pdf, '[');
+ pdf->cave = 0;
+}
+
+@ end a PDF array
+@c
+void pdf_end_array(PDF pdf)
+{
+ pdf_out(pdf, ']');
+ pdf->cave = 0;
}
-@ end a PDF object
+@ begin a PDF object
+@c
+void pdf_begin_obj(PDF pdf, int i, int pdf_os_threshold)
+{
+ os_struct *os = pdf->os;
+ strbuf_s *buf;
+ ensure_output_state(pdf, ST_HEADER_WRITTEN);
+ pdf_prepare_obj(pdf, i, pdf_os_threshold);
+ assert(pdf->buf == os->buf[os->curbuf]);
+ buf = pdf->buf;
+ switch (os->curbuf) {
+ case PDFOUT_BUF:
+ pdf_printf(pdf, "%d 0 obj\n", (int) i);
+ break;
+ case LUASTM_BUF:
+ assert(0);
+ break;
+ case OBJSTM_BUF:
+ if (pdf->compress_level == 0)
+ pdf_printf(pdf, "%% %d 0 obj\n", (int) i); /* debugging help */
+ break;
+ default:
+ assert(0);
+ }
+ pdf->cave = 0;
+}
+
+@ end a PDF object
@c
void pdf_end_obj(PDF pdf)
{
- if (pdf->os_mode) {
- if (pdf->os_idx == pdf_os_max_objs - 1)
+ os_struct *os = pdf->os;
+ assert(pdf->buf == os->buf[os->curbuf]);
+ switch (os->curbuf) {
+ case PDFOUT_BUF:
+ pdf_puts(pdf, "\nendobj\n"); /* end a PDF object */
+ break;
+ case LUASTM_BUF:
+ assert(0);
+ break;
+ case OBJSTM_BUF:
+ os->idx++; /* = number of objects collected so far in ObjStm */
+ os->o_ctr++; /* only for statistics */
+ if (os->idx == PDF_OS_MAX_OBJS)
pdf_os_write_objstream(pdf);
- } else {
- pdf_puts(pdf, "endobj\n"); /* end a PDF object */
+ else
+ pdf_out(pdf, ' '); /* Adobe Reader seems to need this */
+ break;
+ default:
+ assert(0);
}
}
@@ -1271,7 +1396,7 @@ void pdf_end_obj(PDF pdf)
control characters are octal encoded.
This assumes that the string does not contain any already escaped
characters!
-
+
@c
char *convertStringToPDFString(const char *in, int len)
{
@@ -1311,7 +1436,7 @@ char *convertStringToPDFString(const cha
@ Converts any string given in in in an allowed PDF string which is
hexadecimal encoded;
|sizeof(out)| should be at least $|lin|*2+1$.
-
+
@c
static void convertStringToHexString(const char *in, char *out, int lin)
{
@@ -1387,7 +1512,10 @@ static void print_ID(PDF pdf, const char
md5_finish(&state, digest);
/* write the IDs */
convertStringToHexString((char *) digest, id, 16);
- pdf_printf(pdf, "/ID [<%s> <%s>]", id, id);
+ pdf_add_name(pdf, "ID");
+ pdf_begin_array(pdf);
+ pdf_printf(pdf, "<%s> <%s>", id, id);
+ pdf_end_array(pdf);
}
@ Print the /CreationDate entry.
@@ -1505,20 +1633,6 @@ void init_start_time(PDF pdf)
}
@ @c
-static void print_creation_date(PDF pdf)
-{
- init_start_time(pdf);
- pdf_printf(pdf, "/CreationDate (%s)\n", pdf->start_time_str);
-}
-
-@ @c
-static void print_mod_date(PDF pdf)
-{
- init_start_time(pdf);
- pdf_printf(pdf, "/ModDate (%s)\n", pdf->start_time_str);
-}
-
-@ @c
char *getcreationdate(PDF pdf)
{
assert(pdf);
@@ -1538,67 +1652,6 @@ void remove_pdffile(PDF pdf)
}
@ @c
-static void realloc_fb(PDF pdf)
-{
- if (pdf->fb_array == NULL) {
- pdf->fb_limit = SMALL_ARRAY_SIZE;
- pdf->fb_array = xtalloc(pdf->fb_limit, char);
- pdf->fb_ptr = pdf->fb_array;
- } else if ((size_t) (pdf->fb_ptr - pdf->fb_array + 1) > pdf->fb_limit) {
- size_t last_ptr_index = (size_t) (pdf->fb_ptr - pdf->fb_array);
- pdf->fb_limit *= 2;
- if ((size_t) (pdf->fb_ptr - pdf->fb_array + 1) > pdf->fb_limit)
- pdf->fb_limit = (size_t) (pdf->fb_ptr - pdf->fb_array + 1);
- xretalloc(pdf->fb_array, pdf->fb_limit, char);
- pdf->fb_ptr = pdf->fb_array + last_ptr_index;
- }
-}
-
-@ @c
-int fb_offset(PDF pdf)
-{
- return (int) (pdf->fb_ptr - pdf->fb_array);
-}
-
-@ @c
-void fb_seek(PDF pdf, int offset)
-{
- pdf->fb_ptr = pdf->fb_array + offset;
-}
-
-@ @c
-void fb_putchar(PDF pdf, eight_bits b)
-{
- if ((size_t) (pdf->fb_ptr - pdf->fb_array + 1) > pdf->fb_limit)
- realloc_fb(pdf);
- *(pdf->fb_ptr)++ = (char) b;
-}
-
-@ @c
-void fb_flush(PDF pdf)
-{
- char *p;
- int n;
- for (p = pdf->fb_array; p < pdf->fb_ptr;) {
- n = pdf->buf_size - pdf->ptr;
- if (pdf->fb_ptr - p < n)
- n = (int) (pdf->fb_ptr - p);
- memcpy(pdf->buf + pdf->ptr, p, (unsigned) n);
- pdf->ptr += n;
- if (pdf->ptr == pdf->buf_size)
- pdf_flush(pdf);
- p += n;
- }
- pdf->fb_ptr = pdf->fb_array;
-}
-
-@ @c
-void fb_free(PDF pdf)
-{
- xfree(pdf->fb_array);
-}
-
-@ @c
void pdf_error(const char *t, const char *p)
{
normalize_selector();
@@ -1635,7 +1688,7 @@ void pdf_warning(const char *t, const ch
history = warning_issued;
}
-@ Use |check_o_mode()| in the backend-specific "Implement..." chunks
+@ Use |check_o_mode()| in the backend-specific "Implement..." chunks
@c
void check_o_mode(PDF pdf, const char *s, int o_mode_bitpattern, boolean strict)
@@ -1735,64 +1788,81 @@ char *get_resname_prefix(PDF pdf)
void pdf_begin_page(PDF pdf)
{
+ pdffloat f;
scaled form_margin = 0; /* was one_bp until SVN4066 */
ensure_output_state(pdf, ST_HEADER_WRITTEN);
init_pdf_pagecalculations(pdf);
-
if (pdf->page_resources == NULL) {
pdf->page_resources = xtalloc(1, pdf_resource_struct);
pdf->page_resources->resources_tree = NULL;
}
- pdf->page_resources->last_resources = pdf_new_objnum(pdf);
+ pdf->page_resources->last_resources =
+ pdf_create_obj(pdf, obj_type_others, 0);
reset_page_resources(pdf);
if (global_shipping_mode == SHIPPING_PAGE) {
- pdf->last_page = get_obj(pdf, obj_type_page, total_pages + 1, 0);
+ pdf->last_page = pdf_get_obj(pdf, obj_type_page, total_pages + 1, 0);
set_obj_aux(pdf, pdf->last_page, 1); /* mark that this page has been created */
- pdf->last_stream = pdf_new_dict(pdf, obj_type_pagestream, 0, 0);
+ pdf->last_stream = pdf_create_obj(pdf, obj_type_pagestream, 0);
+ pdf_begin_obj(pdf, pdf->last_stream, OBJSTM_NEVER);
pdf->last_thread = null;
+ pdf_begin_dict(pdf);
pdflua_begin_page(pdf);
} else {
assert(global_shipping_mode == SHIPPING_FORM);
- pdf_begin_dict(pdf, pdf_cur_form, 0);
+ pdf_begin_obj(pdf, pdf_cur_form, OBJSTM_NEVER);
pdf->last_stream = pdf_cur_form;
/* Write out Form stream header */
- pdf_puts(pdf, "/Type /XObject\n");
- pdf_puts(pdf, "/Subtype /Form\n");
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "XObject");
+ pdf_dict_add_name(pdf, "Subtype", "Form");
if (pdf_xform_attr != null)
- pdf_print_toks_ln(pdf, pdf_xform_attr);
+ pdf_print_toks(pdf, pdf_xform_attr);
if (obj_xform_attr(pdf, pdf_cur_form) != null) {
- pdf_print_toks_ln(pdf, obj_xform_attr(pdf, pdf_cur_form));
+ pdf_print_toks(pdf, obj_xform_attr(pdf, pdf_cur_form));
delete_token_ref(obj_xform_attr(pdf, pdf_cur_form));
set_obj_xform_attr(pdf, pdf_cur_form, null);
}
- pdf_puts(pdf, "/BBox [");
- pdf_print_bp(pdf, -form_margin);
- pdf_out(pdf, ' ');
- pdf_print_bp(pdf, -form_margin);
- pdf_out(pdf, ' ');
- pdf_print_bp(pdf, cur_page_size.h + form_margin);
- pdf_out(pdf, ' ');
- pdf_print_bp(pdf, cur_page_size.v + form_margin);
- pdf_puts(pdf, "]\n");
- pdf_puts(pdf, "/FormType 1\n");
- pdf_puts(pdf, "/Matrix [1 0 0 1 0 0]\n");
- pdf_indirect_ln(pdf, "Resources", pdf->page_resources->last_resources);
+ pdf_add_name(pdf, "BBox");
+ pdf_begin_array(pdf);
+ pdf_add_bp(pdf, -form_margin);
+ pdf_add_bp(pdf, -form_margin);
+ pdf_add_bp(pdf, pdf->page_size.h + form_margin);
+ pdf_add_bp(pdf, pdf->page_size.v + form_margin);
+ pdf_end_array(pdf);
+ pdf_dict_add_int(pdf, "FormType", 1);
+ pdf_add_name(pdf, "Matrix");
+ pdf_begin_array(pdf);
+ pdf_add_int(pdf, 1);
+ pdf_add_int(pdf, 0);
+ pdf_add_int(pdf, 0);
+ pdf_add_int(pdf, 1);
+ pdf_add_int(pdf, 0);
+ pdf_add_int(pdf, 0);
+ pdf_end_array(pdf);
+ pdf_dict_add_ref(pdf, "Resources", pdf->page_resources->last_resources);
}
/* Start stream of page/form contents */
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
+ pdf->os->trigger_luastm = false; /* if it's true, the page stream goes through Lua */
pdf_begin_stream(pdf);
if (global_shipping_mode == SHIPPING_PAGE) {
/* Adjust transformation matrix for the magnification ratio */
if (mag != 1000) {
- pdf_print_real(pdf, mag, 3);
+ setpdffloat(f, mag, 3);
+ print_pdffloat(pdf, f);
pdf_puts(pdf, " 0 0 ");
- pdf_print_real(pdf, mag, 3);
+ print_pdffloat(pdf, f);
pdf_puts(pdf, " 0 0 cm\n");
}
}
- pdf_shipout_begin();
+ pos_stack_used = 0; /* start with empty stack */
+ if (global_shipping_mode == SHIPPING_PAGE) {
+ colorstackpagestart();
+ }
if (global_shipping_mode == SHIPPING_PAGE)
pdf_out_colorstack_startpage(pdf);
}
@@ -1802,13 +1872,17 @@ void print_pdf_table_string(PDF pdf, con
{
size_t len;
const char *ls;
- lua_getglobal(Luas, "pdf"); /* t ... */
+ lua_getglobal(Luas, "pdf"); /* t ... */
lua_pushstring(Luas, s); /* s t ... */
lua_gettable(Luas, -2); /* s? t ... */
if (lua_isstring(Luas, -1)) { /* s t ... */
ls = lua_tolstring(Luas, -1, &len);
- pdf_out_block(pdf, ls, len);
- pdf_out(pdf, '\n');
+ if (len > 0) {
+ if (pdf->cave == 1)
+ pdf_out(pdf, ' ');
+ pdf_out_block(pdf, ls, len);
+ pdf->cave = 1;
+ }
}
lua_pop(Luas, 2); /* ... */
}
@@ -1819,84 +1893,92 @@ void print_pdf_table_string(PDF pdf, con
void pdf_end_page(PDF pdf)
{
+ char s[64], *p;
int j, annots = 0, beads = 0;
pdf_resource_struct *res_p = pdf->page_resources;
pdf_resource_struct local_page_resources;
pdf_object_list *annot_list, *bead_list, *link_list, *ol, *ol1;
- scaledpos save_cur_page_size; /* to save |cur_page_size| during flushing pending forms */
+ scaledpos save_cur_page_size; /* to save |pdf->page_size| during flushing pending forms */
shipping_mode_e save_shipping_mode;
int procset = PROCSET_PDF;
/* Finish stream of page/form contents */
pdf_goto_pagemode(pdf);
- pdf_shipout_end();
+ if (pos_stack_used > 0) {
+ pdftex_fail("%u unmatched \\pdfsave after %s shipout",
+ (unsigned int) pos_stack_used,
+ ((global_shipping_mode ==
+ SHIPPING_PAGE) ? "page" : "form"));
+ }
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
if (global_shipping_mode == SHIPPING_PAGE) {
pdf->last_pages = pdf_do_page_divert(pdf, pdf->last_page, 0);
/* Write out /Page object */
- pdf_begin_dict(pdf, pdf->last_page, 1);
- pdf_puts(pdf, "/Type /Page\n");
- pdf_indirect_ln(pdf, "Contents", pdf->last_stream);
- pdf_indirect_ln(pdf, "Resources", res_p->last_resources);
- pdf_puts(pdf, "/MediaBox [0 0 ");
- pdf_print_mag_bp(pdf, cur_page_size.h);
- pdf_out(pdf, ' ');
- pdf_print_mag_bp(pdf, cur_page_size.v);
- pdf_puts(pdf, "]\n");
+ pdf_begin_obj(pdf, pdf->last_page, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Page");
+ pdf_dict_add_ref(pdf, "Contents", pdf->last_stream);
+ pdf_dict_add_ref(pdf, "Resources", res_p->last_resources);
+ pdf_add_name(pdf, "MediaBox");
+ pdf_begin_array(pdf);
+ pdf_add_int(pdf, 0);
+ pdf_add_int(pdf, 0);
+ pdf_add_mag_bp(pdf, pdf->page_size.h);
+ pdf_add_mag_bp(pdf, pdf->page_size.v);
+ pdf_end_array(pdf);
if (pdf_page_attr != null)
- pdf_print_toks_ln(pdf, pdf_page_attr);
+ pdf_print_toks(pdf, pdf_page_attr);
print_pdf_table_string(pdf, "pageattributes");
- pdf_indirect_ln(pdf, "Parent", pdf->last_pages);
+ pdf_dict_add_ref(pdf, "Parent", pdf->last_pages);
if (pdf->img_page_group_val != 0) {
assert(pdf->img_page_group_val > 0);
- pdf_printf(pdf, "/Group %d 0 R\n", pdf->img_page_group_val);
+ pdf_dict_add_ref(pdf, "Group", pdf->img_page_group_val);
}
annot_list = get_page_resources_list(pdf, obj_type_annot);
link_list = get_page_resources_list(pdf, obj_type_link);
if (annot_list != NULL || link_list != NULL) {
annots = pdf_create_obj(pdf, obj_type_annots, 0);
- pdf_indirect_ln(pdf, "Annots", annots);
+ pdf_dict_add_ref(pdf, "Annots", annots);
}
bead_list = get_page_resources_list(pdf, obj_type_bead);
if (bead_list != NULL) {
beads = pdf_create_obj(pdf, obj_type_beads, 0);
- pdf_indirect_ln(pdf, "B", beads);
+ pdf_dict_add_ref(pdf, "B", beads);
}
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
pdflua_end_page(pdf, annots, beads);
pdf->img_page_group_val = 0;
/* Generate array of annotations or beads in page */
if (annot_list != NULL || link_list != NULL) {
- pdf_begin_obj(pdf, annots, 1);
- pdf_puts(pdf, "[");
+ pdf_begin_obj(pdf, annots, OBJSTM_ALWAYS);
+ pdf_begin_array(pdf);
while (annot_list != NULL) {
assert(annot_list->info > 0);
- pdf_print_int(pdf, annot_list->info);
- pdf_puts(pdf, " 0 R ");
+ pdf_add_ref(pdf, annot_list->info);
annot_list = annot_list->link;
}
while (link_list != NULL) {
- pdf_print_int(pdf, link_list->info);
- pdf_puts(pdf, " 0 R ");
+ pdf_add_ref(pdf, link_list->info);
link_list = link_list->link;
}
- pdf_puts(pdf, "]\n");
+ pdf_end_array(pdf);
pdf_end_obj(pdf);
}
if (bead_list != NULL) {
- pdf_begin_dict(pdf, beads, 1);
- pdf_puts(pdf, "[");
+ pdf_begin_obj(pdf, beads, OBJSTM_ALWAYS);
+ pdf_begin_array(pdf);
while (bead_list != NULL) {
- pdf_print_int(pdf, bead_list->info);
- pdf_printf(pdf, " 0 R ");
+ pdf_add_ref(pdf, bead_list->info);
bead_list = bead_list->link;
}
- pdf_printf(pdf, "]\n");
- pdf_end_dict(pdf);
+ pdf_end_array(pdf);
+ pdf_end_obj(pdf);
}
}
@@ -1912,19 +1994,19 @@ void pdf_end_page(PDF pdf)
/* Write out pending forms */
/* When flushing pending forms we need to save and restore resource lists
which are also used by page shipping.
- Saving and restoring |cur_page_size| is needed for proper
+ Saving and restoring |pdf->page_size| is needed for proper
writing out pending PDF marks. */
ol = get_page_resources_list(pdf, obj_type_xform);
while (ol != NULL) {
if (!is_obj_written(pdf, ol->info)) {
pdf_cur_form = ol->info;
- save_cur_page_size = cur_page_size;
+ save_cur_page_size = pdf->page_size;
save_shipping_mode = global_shipping_mode;
pdf->page_resources = &local_page_resources;
local_page_resources.resources_tree = NULL;
ship_out(pdf, obj_xform_box(pdf, pdf_cur_form), SHIPPING_FORM);
/* Restore page size and page resources */
- cur_page_size = save_cur_page_size;
+ pdf->page_size = save_cur_page_size;
global_shipping_mode = save_shipping_mode;
destroy_page_resources_tree(pdf);
pdf->page_resources = res_p;
@@ -1947,11 +2029,13 @@ void pdf_end_page(PDF pdf)
while (ol != NULL) {
if (ol->info > 0 && obj_type(pdf, ol->info) == obj_type_annot) {
j = obj_annot_ptr(pdf, ol->info); /* |j| points to |pdf_annot_node| */
- pdf_begin_dict(pdf, ol->info, 1);
- pdf_puts(pdf, "/Type /Annot\n");
- pdf_print_toks_ln(pdf, pdf_annot_data(j));
+ pdf_begin_obj(pdf, ol->info, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Annot");
+ pdf_print_toks(pdf, pdf_annot_data(j));
pdf_rectangle(pdf, j);
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
}
ol = ol->link;
}
@@ -1960,17 +2044,19 @@ void pdf_end_page(PDF pdf)
if ((ol = get_page_resources_list(pdf, obj_type_link)) != NULL) {
while (ol != NULL) {
j = obj_annot_ptr(pdf, ol->info);
- pdf_begin_dict(pdf, ol->info, 1);
- pdf_puts(pdf, "/Type /Annot\n");
+ pdf_begin_obj(pdf, ol->info, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Annot");
if (pdf_action_type(pdf_link_action(j)) != pdf_action_user)
- pdf_puts(pdf, "/Subtype /Link\n");
+ pdf_dict_add_name(pdf, "Subtype", "Link");
if (pdf_link_attr(j) != null)
- pdf_print_toks_ln(pdf, pdf_link_attr(j));
+ pdf_print_toks(pdf, pdf_link_attr(j));
pdf_rectangle(pdf, j);
if (pdf_action_type(pdf_link_action(j)) != pdf_action_user)
pdf_puts(pdf, "/A ");
write_action(pdf, pdf_link_action(j));
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
ol = ol->link;
}
/* Flush |pdf_start_link_node|'s created by |append_link| */
@@ -1992,17 +2078,18 @@ void pdf_end_page(PDF pdf)
}
/* Write out resources dictionary */
- pdf_begin_dict(pdf, res_p->last_resources, 1);
+ pdf_begin_obj(pdf, res_p->last_resources, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
/* Print additional resources */
if (global_shipping_mode == SHIPPING_PAGE) {
if (pdf_page_resources != null)
- pdf_print_toks_ln(pdf, pdf_page_resources);
+ pdf_print_toks(pdf, pdf_page_resources);
print_pdf_table_string(pdf, "pageresources");
} else {
if (pdf_xform_resources != null)
- pdf_print_toks_ln(pdf, pdf_xform_resources);
+ pdf_print_toks(pdf, pdf_xform_resources);
if (obj_xform_resources(pdf, pdf_cur_form) != null) {
- pdf_print_toks_ln(pdf, obj_xform_resources(pdf, pdf_cur_form));
+ pdf_print_toks(pdf, obj_xform_resources(pdf, pdf_cur_form));
delete_token_ref(obj_xform_resources(pdf, pdf_cur_form));
set_obj_xform_resources(pdf, pdf_cur_form, null);
}
@@ -2010,18 +2097,18 @@ void pdf_end_page(PDF pdf)
/* Generate font resources */
if ((ol = get_page_resources_list(pdf, obj_type_font)) != NULL) {
- pdf_puts(pdf, "/Font << ");
+ pdf_add_name(pdf, "Font");
+ pdf_begin_dict(pdf);
while (ol != NULL) {
assert(ol->info > 0); /* always base font: an object number */
- pdf_puts(pdf, "/F");
- pdf_print_int(pdf, obj_info(pdf, ol->info));
- pdf_print_resname_prefix(pdf);
- pdf_out(pdf, ' ');
- pdf_print_int(pdf, ol->info);
- pdf_puts(pdf, " 0 R ");
+ p = s;
+ p += snprintf(p, 20, "F%i", obj_info(pdf, ol->info));
+ if (pdf->resname_prefix != NULL)
+ p += snprintf(p, 20, "%s", pdf->resname_prefix);
+ pdf_dict_add_ref(pdf, s, ol->info);
ol = ol->link;
}
- pdf_puts(pdf, ">>\n");
+ pdf_end_dict(pdf);
procset |= PROCSET_TEXT;
}
@@ -2029,47 +2116,47 @@ void pdf_end_page(PDF pdf)
ol = get_page_resources_list(pdf, obj_type_xform);
ol1 = get_page_resources_list(pdf, obj_type_ximage);
if (ol != NULL || ol1 != NULL) {
- pdf_puts(pdf, "/XObject << ");
+ pdf_add_name(pdf, "XObject");
+ pdf_begin_dict(pdf);
while (ol != NULL) {
- pdf_printf(pdf, "/Fm");
- pdf_print_int(pdf, obj_info(pdf, ol->info));
- pdf_print_resname_prefix(pdf);
- pdf_out(pdf, ' ');
- pdf_print_int(pdf, ol->info);
- pdf_puts(pdf, " 0 R ");
+ p = s;
+ p += snprintf(p, 20, "Fm%i", obj_info(pdf, ol->info));
+ if (pdf->resname_prefix != NULL)
+ p += snprintf(p, 20, "%s", pdf->resname_prefix);
+ pdf_dict_add_ref(pdf, s, ol->info);
ol = ol->link;
}
while (ol1 != null) {
- pdf_puts(pdf, "/Im");
- pdf_print_int(pdf, obj_data_ptr(pdf, ol1->info));
- pdf_print_resname_prefix(pdf);
- pdf_out(pdf, ' ');
- pdf_print_int(pdf, ol1->info);
- pdf_puts(pdf, " 0 R ");
+ p = s;
+ p += snprintf(p, 20, "Im%i", obj_info(pdf, ol1->info));
+ if (pdf->resname_prefix != NULL)
+ p += snprintf(p, 20, "%s", pdf->resname_prefix);
+ pdf_dict_add_ref(pdf, s, ol1->info);
procset |= img_procset(idict_array[obj_data_ptr(pdf, ol1->info)]);
ol1 = ol1->link;
}
- pdf_puts(pdf, ">>\n");
+ pdf_end_dict(pdf);
}
/* Generate ProcSet */
- pdf_puts(pdf, "/ProcSet [");
+ pdf_add_name(pdf, "ProcSet");
+ pdf_begin_array(pdf);
if ((procset & PROCSET_PDF) != 0)
- pdf_puts(pdf, " /PDF");
+ pdf_add_name(pdf, "PDF");
if ((procset & PROCSET_TEXT) != 0)
- pdf_puts(pdf, " /Text");
+ pdf_add_name(pdf, "Text");
if ((procset & PROCSET_IMAGE_B) != 0)
- pdf_puts(pdf, " /ImageB");
+ pdf_add_name(pdf, "ImageB");
if ((procset & PROCSET_IMAGE_C) != 0)
- pdf_puts(pdf, " /ImageC");
+ pdf_add_name(pdf, "ImageC");
if ((procset & PROCSET_IMAGE_I) != 0)
- pdf_puts(pdf, " /ImageI");
- pdf_puts(pdf, " ]\n");
-
+ pdf_add_name(pdf, "ImageI");
+ pdf_end_array(pdf);
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
}
-@* Finishing the PDF output file.
+@* Finishing the PDF output file.
@ Destinations that have been referenced but don't exists have
|obj_dest_ptr=null|. Leaving them undefined might cause troubles for
@@ -2094,10 +2181,12 @@ static void check_nonexisting_destinatio
(" has been referenced but does not exist, replaced by a fixed one");
print_ln();
print_ln();
- pdf_begin_obj(pdf, k, 1);
- pdf_out(pdf, '[');
- pdf_print_int(pdf, pdf->last_page);
- pdf_puts(pdf, " 0 R /Fit]\n");
+
+ pdf_begin_obj(pdf, k, OBJSTM_ALWAYS);
+ pdf_begin_array(pdf);
+ pdf_add_ref(pdf, pdf->last_page);
+ pdf_add_name(pdf, "Fit");
+ pdf_end_array(pdf);
pdf_end_obj(pdf);
}
}
@@ -2141,12 +2230,14 @@ static int pdf_print_info(PDF pdf, int l
trapped_given;
char *s = NULL;
int k, len = 0;
- k = pdf_new_dict(pdf, obj_type_info, 0, 3); /* keep Info readable unless explicitely forced */
+ k = pdf_create_obj(pdf, obj_type_info, 0);
+ pdf_begin_obj(pdf, k, 3); /* keep Info readable unless explicitely forced */
creator_given = false;
producer_given = false;
creationdate_given = false;
moddate_given = false;
trapped_given = false;
+ pdf_begin_dict(pdf);
if (pdf_info_toks != 0) {
s = tokenlist_to_cstring(pdf_info_toks, true, &len);
creator_given = substr_of_str("/Creator", s);
@@ -2157,36 +2248,41 @@ static int pdf_print_info(PDF pdf, int l
}
if (!producer_given) {
/* Print the Producer key */
- pdf_puts(pdf, "/Producer (LuaTeX-");
+ pdf_add_name(pdf, "Producer");
+ pdf_puts(pdf, " (LuaTeX-");
pdf_print_int(pdf, luatex_version / 100);
pdf_out(pdf, '.');
pdf_print_int(pdf, luatex_version % 100);
pdf_out(pdf, '.');
pdf_print(pdf, luatex_revision);
- pdf_puts(pdf, ")\n");
+ pdf_out(pdf, ')');
}
if (pdf_info_toks != null) {
if (len > 0) {
+ pdf_out(pdf, '\n');
pdf_puts(pdf, s);
- pdf_print_nl(pdf);
+ pdf_out(pdf, '\n');
xfree(s);
}
delete_token_ref(pdf_info_toks);
pdf_info_toks = null;
}
if (!creator_given)
- pdf_str_entry_ln(pdf, "Creator", "TeX");
+ pdf_dict_add_string(pdf, "Creator", "TeX");
if (!creationdate_given) {
- print_creation_date(pdf);
+ init_start_time(pdf);
+ pdf_dict_add_string(pdf, "CreationDate", pdf->start_time_str);
}
if (!moddate_given) {
- print_mod_date(pdf);
+ init_start_time(pdf);
+ pdf_dict_add_string(pdf, "ModDate", pdf->start_time_str);
}
if (!trapped_given) {
- pdf_puts(pdf, "/Trapped /False\n");
+ pdf_dict_add_name(pdf, "Trapped", "False");
}
- pdf_str_entry_ln(pdf, "PTEX.Fullbanner", pdftex_banner);
+ pdf_dict_add_string(pdf, "PTEX.Fullbanner", pdftex_banner);
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
return k;
}
@@ -2294,16 +2390,15 @@ void finish_pdf_file(PDF pdf, int luatex
/* Output article threads */
if (pdf->head_tab[obj_type_thread] != 0) {
- threads = pdf_new_obj(pdf, obj_type_others, 0, 1);
- pdf_out(pdf, '[');
+ threads = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, threads, OBJSTM_ALWAYS);
+ pdf_begin_array(pdf);
k = pdf->head_tab[obj_type_thread];
while (k != 0) {
- pdf_print_int(pdf, k);
- pdf_puts(pdf, " 0 R ");
+ pdf_add_ref(pdf, k);
k = obj_link(pdf, k);
}
- pdf_remove_last_space(pdf);
- pdf_puts(pdf, "]\n");
+ pdf_end_array(pdf);
pdf_end_obj(pdf);
k = pdf->head_tab[obj_type_thread];
while (k != 0) {
@@ -2315,34 +2410,38 @@ void finish_pdf_file(PDF pdf, int luatex
}
/* Output the /Catalog object */
- root = pdf_new_dict(pdf, obj_type_catalog, 0, 1);
- pdf_puts(pdf, "/Type /Catalog\n");
- pdf_indirect_ln(pdf, "Pages", pdf->last_pages);
+ root = pdf_create_obj(pdf, obj_type_catalog, 0);
+ pdf_begin_obj(pdf, root, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Catalog");
+ pdf_dict_add_ref(pdf, "Pages", pdf->last_pages);
if (threads != 0)
- pdf_indirect_ln(pdf, "Threads", threads);
+ pdf_dict_add_ref(pdf, "Threads", threads);
if (outlines != 0)
- pdf_indirect_ln(pdf, "Outlines", outlines);
+ pdf_dict_add_ref(pdf, "Outlines", outlines);
if (names_tree != 0)
- pdf_indirect_ln(pdf, "Names", names_tree);
+ pdf_dict_add_ref(pdf, "Names", names_tree);
if (pdf_catalog_toks != null) {
- pdf_print_toks_ln(pdf, pdf_catalog_toks);
+ pdf_print_toks(pdf, pdf_catalog_toks);
delete_token_ref(pdf_catalog_toks);
pdf_catalog_toks = null;
}
if (pdf_catalog_openaction != 0)
- pdf_indirect_ln(pdf, "OpenAction", pdf_catalog_openaction);
+ pdf_dict_add_ref(pdf, "OpenAction", pdf_catalog_openaction);
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
/* last candidate for object stream */
info = pdf_print_info(pdf, luatex_version, luatex_revision); /* final object for pdf->os_enable == false */
if (pdf->os_enable) {
- pdf_os_switch(pdf, true);
+ pdf_buffer_select(pdf, true);
pdf_os_write_objstream(pdf);
pdf_flush(pdf);
- pdf_os_switch(pdf, false);
+ pdf_buffer_select(pdf, false);
/* Output the cross-reference stream dictionary */
- xref_stm = pdf_new_dict(pdf, obj_type_others, 0, 0); /* final object for pdf->os_enable == true */
+ xref_stm = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, xref_stm, OBJSTM_NEVER); /* final object for pdf->os_enable == true */
if ((obj_offset(pdf, pdf->obj_ptr) / 256) > 16777215)
xref_offset_width = 5;
else if (obj_offset(pdf, pdf->obj_ptr) > 16777215)
@@ -2353,30 +2452,37 @@ void finish_pdf_file(PDF pdf, int luatex
xref_offset_width = 2;
/* Build a linked list of free objects */
build_free_object_list(pdf);
- pdf_puts(pdf, "/Type /XRef\n");
- pdf_puts(pdf, "/Index [0 ");
- pdf_print_int(pdf, pdf->obj_ptr + 1);
- pdf_puts(pdf, "]\n");
- pdf_int_entry_ln(pdf, "Size", pdf->obj_ptr + 1);
- pdf_puts(pdf, "/W [1 ");
- pdf_print_int(pdf, (int) xref_offset_width);
- pdf_puts(pdf, " 1]\n");
- pdf_indirect_ln(pdf, "Root", root);
- pdf_indirect_ln(pdf, "Info", info);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "XRef");
+ pdf_add_name(pdf, "Index");
+ pdf_begin_array(pdf);
+ pdf_add_int(pdf, 0);
+ pdf_add_int(pdf, pdf->obj_ptr + 1);
+ pdf_end_array(pdf);
+ pdf_dict_add_int(pdf, "Size", pdf->obj_ptr + 1);
+ pdf_add_name(pdf, "W");
+ pdf_begin_array(pdf);
+ pdf_add_int(pdf, 1);
+ pdf_add_int(pdf, (int) xref_offset_width);
+ pdf_add_int(pdf, 1);
+ pdf_end_array(pdf);
+ pdf_dict_add_ref(pdf, "Root", root);
+ pdf_dict_add_ref(pdf, "Info", info);
if (pdf_trailer_toks != null) {
- pdf_print_toks_ln(pdf, pdf_trailer_toks);
+ pdf_print_toks(pdf, pdf_trailer_toks);
delete_token_ref(pdf_trailer_toks);
pdf_trailer_toks = null;
}
print_ID(pdf, pdf->file_name);
- pdf_print_nl(pdf);
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
for (k = 0; k <= pdf->obj_ptr; k++) {
if (!is_obj_written(pdf, k)) { /* a free object */
pdf_out(pdf, 0);
pdf_out_bytes(pdf, obj_link(pdf, k), xref_offset_width);
pdf_out(pdf, 255);
- } else if (obj_os_idx(pdf, k) == -1) { /* object not in object stream */
+ } else if (obj_os_idx(pdf, k) == PDF_OS_MAX_OBJS) { /* object not in object stream */
pdf_out(pdf, 1);
pdf_out_bytes(pdf, obj_offset(pdf, k),
xref_offset_width);
@@ -2389,6 +2495,7 @@ void finish_pdf_file(PDF pdf, int luatex
}
}
pdf_end_stream(pdf);
+ pdf_end_obj(pdf);
/* TODO: generate a debug version of the crossref */
pdf_flush(pdf);
@@ -2418,26 +2525,28 @@ void finish_pdf_file(PDF pdf, int luatex
/* Output the trailer */
if (!pdf->os_enable) {
pdf_puts(pdf, "trailer\n");
- pdf_puts(pdf, "<< ");
- pdf_int_entry_ln(pdf, "Size", pdf->obj_ptr + 1);
- pdf_indirect_ln(pdf, "Root", root);
- pdf_indirect_ln(pdf, "Info", info);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_int(pdf, "Size", pdf->obj_ptr + 1);
+ pdf_dict_add_ref(pdf, "Root", root);
+ pdf_dict_add_ref(pdf, "Info", info);
if (pdf_trailer_toks != null) {
- pdf_print_toks_ln(pdf, pdf_trailer_toks);
+ pdf_print_toks(pdf, pdf_trailer_toks);
delete_token_ref(pdf_trailer_toks);
pdf_trailer_toks = null;
}
print_ID(pdf, pdf->file_name);
- pdf_puts(pdf, " >>\n");
+ pdf_end_dict(pdf);
+ pdf_out(pdf, '\n');
}
pdf_puts(pdf, "startxref\n");
if (pdf->os_enable)
- pdf_print_int_ln(pdf, obj_offset(pdf, xref_stm));
+ pdf_add_int(pdf, (int) obj_offset(pdf, xref_stm));
else
- pdf_print_int_ln(pdf, pdf_saved_offset(pdf));
- pdf_puts(pdf, "%%EOF\n");
+ pdf_add_int(pdf, (int) pdf->save_offset);
+ pdf_puts(pdf, "\n%%EOF\n");
pdf_flush(pdf);
+
if (callback_id == 0) {
tprint_nl("Output written on ");
tprint(pdf->file_name);
@@ -2469,12 +2578,11 @@ void finish_pdf_file(PDF pdf, int luatex
"\nPDF statistics: %d PDF objects out of %d (max. %d)\n",
(int) pdf->obj_ptr, (int) pdf->obj_tab_size,
(int) sup_obj_tab_size);
- if (pdf->os_cntr > 0) {
+ if (pdf->os->ostm_ctr > 0) {
fprintf(log_file,
" %d compressed objects within %d object stream%s\n",
- (int) ((pdf->os_cntr - 1) * pdf_os_max_objs +
- pdf->os_idx + 1), (int) pdf->os_cntr,
- (pdf->os_cntr > 1 ? "s" : ""));
+ (int) pdf->os->o_ctr, (int) pdf->os->ostm_ctr,
+ (pdf->os->ostm_ctr > 1 ? "s" : ""));
}
fprintf(log_file, " %d named destinations out of %d (max. %d)\n",
(int) pdf->dest_names_ptr, (int) pdf->dest_names_size,
@@ -2499,7 +2607,8 @@ void scan_pdfcatalog(PDF pdf)
} else {
check_o_mode(pdf, "\\pdfcatalog", 1 << OMODE_PDF, true);
p = scan_action(pdf);
- pdf_catalog_openaction = pdf_new_obj(pdf, obj_type_others, 0, 1);
+ pdf_catalog_openaction = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, pdf_catalog_openaction, OBJSTM_ALWAYS);
write_action(pdf, p);
pdf_end_obj(pdf);
delete_action_ref(p);
--- texk/web2c/luatexdir/pdf/pdfglyph.w
+++ texk/web2c/luatexdir/pdf/pdfglyph.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% pdfglyph.w
-% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2009-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -19,15 +19,12 @@
@ @c
static const char _svn_version[] =
- "$Id: pdfglyph.w 4131 2011-04-11 13:41:26Z taco $"
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/pdf/pdfglyph.w $";
+ "$Id: pdfglyph.w 4329 2011-07-13 21:27:51Z hhenkel $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/pdf/pdfglyph.w $";
#include "ptexlib.h"
-
-@ @c
#include "pdf/pdfpage.h"
-#define lround(a) (long) floor((a) + 0.5)
#define pdf2double(a) ((double) (a).m / ten_pow[(a).e])
@ eternal constants
@@ -58,32 +55,33 @@ void pdf_print_charwidth(PDF pdf, intern
@ @c
static void setup_fontparameters(PDF pdf, internal_font_number f)
{
- float slant, extend, expand;
+ float slant, extend, expand, scale = 1.0;
float u = 1.0;
pdfstructure *p = pdf->pstruct;
/* fix mantis bug \# 0000200 (acroread "feature") */
if ((font_format(f) == opentype_format ||
(font_format(f) == type1_format && font_encodingbytes(f) == 2))
&& font_units_per_em(f) > 0)
- u = (float) (font_units_per_em(f) / 1000.0);
+ u = font_units_per_em(f) / 1000.0;
pdf->f_cur = f;
p->f_pdf = pdf_set_font(pdf, f);
- p->fs.m = lround((float) font_size(f) / u / one_bp * ten_pow[p->fs.e]);
- slant = (float) font_slant(f) / (float) 1000.0;
- extend = (float) font_extend(f) / (float) 1000.0;
- expand = (float) 1.0 + (float) font_expand_ratio(f) / (float) 1000.0;
+ p->fs.m = lround(font_size(f) / u / one_bp * ten_pow[p->fs.e]);
+ slant = font_slant(f) / 1000.0;
+ extend = font_extend(f) / 1000.0;
+ expand = 1.0 + font_expand_ratio(f) / 1000.0;
p->tj_delta.e = p->cw.e - 1; /* "- 1" makes less corrections inside []TJ */
/* no need to be more precise than TeX (1sp) */
while (p->tj_delta.e > 0
&& (double) font_size(f) / ten_pow[p->tj_delta.e + e_tj] < 0.5)
p->tj_delta.e--; /* happens for very tiny fonts */
assert(p->cw.e >= p->tj_delta.e); /* else we would need, e. g., |ten_pow[-1]| */
- p->tm[0].m = lround(expand * extend * (float) ten_pow[p->tm[0].e]);
- p->tm[2].m = lround(slant * (float) ten_pow[p->tm[2].e]);
+ p->tm[0].m = lround(scale * expand * extend * ten_pow[p->tm[0].e]);
+ p->tm[2].m = lround(slant * ten_pow[p->tm[2].e]);
+ p->tm[3].m = lround(scale * ten_pow[p->tm[3].e]);
p->k2 =
ten_pow[e_tj +
- p->cw.e] / (ten_pow[p->pdf.h.e] * pdf2double(p->fs) *
- pdf2double(p->tm[0]));
+ p->cw.e] * scale / (ten_pow[p->pdf.h.e] * pdf2double(p->fs) *
+ pdf2double(p->tm[0]));
}
@ @c
@@ -92,18 +90,13 @@ static void set_font(PDF pdf)
pdfstructure *p = pdf->pstruct;
pdf_printf(pdf, "/F%d", (int) p->f_pdf);
pdf_print_resname_prefix(pdf);
- pdf_printf(pdf, " ");
+ pdf_out(pdf, ' ');
print_pdffloat(pdf, p->fs);
- pdf_printf(pdf, " Tf ");
+ pdf_puts(pdf, " Tf ");
p->f_pdf_cur = p->f_pdf;
p->fs_cur.m = p->fs.m;
-}
-
-@ @c
-static void print_tm(PDF pdf, pdffloat * tm)
-{
- print_pdf_matrix(pdf, tm);
- pdf_printf(pdf, " Tm ");
+ p->need_tf = false;
+ p->need_tm = true; /* always follow Tf by Tm */
}
@ @c
@@ -113,12 +106,40 @@ static void set_textmatrix(PDF pdf, scal
pdfstructure *p = pdf->pstruct;
assert(is_textmode(p));
move = calc_pdfpos(p, pos);
- if (p->need_tm == 1 || move) {
- print_tm(pdf, p->tm);
+ if (p->need_tm || move) {
+ print_pdf_matrix(pdf, p->tm);
+ pdf_puts(pdf, " Tm ");
p->pdf.h.m = p->pdf_bt_pos.h.m + p->tm[4].m; /* Tm replaces */
p->pdf.v.m = p->pdf_bt_pos.v.m + p->tm[5].m;
- p->need_tm = 0;
+ p->need_tm = false;
}
+ p->tm0_cur.m = p->tm[0].m;
+}
+
+@ Print out a character to PDF buffer; the character will be printed in octal
+form in the following cases: chars <= 32, backslash (92), left parenthesis
+(40), and right parenthesis (41).
+@c
+static void pdf_print_char(PDF pdf, int c)
+{
+ if (c > 255)
+ return;
+ /* pdf_print_escaped(c) */
+ if (c <= 32 || c == '\\' || c == '(' || c == ')' || c > 127) {
+ pdf_room(pdf, 4);
+ pdf_quick_out(pdf, '\\');
+ pdf_quick_out(pdf, (unsigned char) ('0' + ((c >> 6) & 0x3)));
+ pdf_quick_out(pdf, (unsigned char) ('0' + ((c >> 3) & 0x7)));
+ pdf_quick_out(pdf, (unsigned char) ('0' + (c & 0x7)));
+ } else
+ pdf_out(pdf, c);
+}
+
+static void pdf_print_wide_char(PDF pdf, int c)
+{
+ char hex[5];
+ snprintf(hex, 5, "%04X", c);
+ pdf_out_block(pdf, (const char *) hex, 4);
}
@ @c
@@ -127,10 +148,10 @@ static void begin_charmode(PDF pdf, inte
assert(is_chararraymode(p));
if (font_encodingbytes(f) == 2) {
p->ishex = 1;
- pdf_printf(pdf, "<");
+ pdf_out(pdf, '<');
} else {
p->ishex = 0;
- pdf_printf(pdf, "(");
+ pdf_out(pdf, '(');
}
p->mode = PMODE_CHAR;
}
@@ -142,9 +163,9 @@ void end_charmode(PDF pdf)
assert(is_charmode(p));
if (p->ishex == 1) {
p->ishex = 0;
- pdf_printf(pdf, ">");
+ pdf_out(pdf, '>');
} else {
- pdf_printf(pdf, ")");
+ pdf_out(pdf, ')');
}
p->mode = PMODE_CHARARRAY;
}
@@ -156,7 +177,7 @@ static void begin_chararray(PDF pdf)
assert(is_textmode(p));
p->pdf_tj_pos = p->pdf;
p->cw.m = 0;
- pdf_printf(pdf, "[");
+ pdf_out(pdf, '[');
p->mode = PMODE_CHARARRAY;
}
@@ -165,7 +186,7 @@ void end_chararray(PDF pdf)
{
pdfstructure *p = pdf->pstruct;
assert(is_chararraymode(p));
- pdf_printf(pdf, "]TJ\n");
+ pdf_puts(pdf, "]TJ\n");
p->pdf = p->pdf_tj_pos;
p->mode = PMODE_TEXT;
}
@@ -178,29 +199,34 @@ void pdf_place_glyph(PDF pdf, internal_f
scaledpos pos = pdf->posstruct->pos;
if (!char_exists(f, c))
return;
- if (f != pdf->f_cur || is_textmode(p) || is_pagemode(p)) {
+ /* ensure to be within BT...ET */
+ if (is_pagemode(p)) {
pdf_goto_textmode(pdf);
- if (f != pdf->f_cur)
- setup_fontparameters(pdf, f);
- if (p->f_pdf != p->f_pdf_cur || p->fs.m != p->fs_cur.m) {
+ p->need_tf = true;
+ }
+ /* all font setup */
+ if (f != pdf->f_cur || p->need_tf) {
+ setup_fontparameters(pdf, f);
+ if (p->need_tf || p->f_pdf != p->f_pdf_cur || p->fs.m != p->fs_cur.m) {
+ pdf_goto_textmode(pdf);
set_font(pdf);
- p->need_tm = 1; /* force Tm setting */
+ } else if (p->tm0_cur.m != p->tm[0].m) {
+ /* catch in-line HZ expand change due to efcode */
+ p->need_tm = true;
}
- set_textmatrix(pdf, pos);
- begin_chararray(pdf);
}
- assert(is_charmode(p) || is_chararraymode(p));
- move = calc_pdfpos(p, pos);
- if (move) {
- if ((p->wmode == WMODE_H
- && (p->pdf_bt_pos.v.m + p->tm[5].m) != p->pdf.v.m)
+ /* all movements */
+ move = calc_pdfpos(p, pos); /* within text or chararray or char mode */
+ if (move || p->need_tm) {
+ if (p->need_tm || (p->wmode == WMODE_H
+ && (p->pdf_bt_pos.v.m + p->tm[5].m) != p->pdf.v.m)
|| (p->wmode == WMODE_V
&& (p->pdf_bt_pos.h.m + p->tm[4].m) != p->pdf.h.m)
|| abs(p->tj_delta.m) >= 1000000) {
pdf_goto_textmode(pdf);
set_textmatrix(pdf, pos);
begin_chararray(pdf);
- move = calc_pdfpos(p, pos);
+ move = calc_pdfpos(p, pos); /* for fine adjustment */
}
if (move) {
assert((p->wmode == WMODE_H
@@ -214,6 +240,8 @@ void pdf_place_glyph(PDF pdf, internal_f
p->cw.m -= p->tj_delta.m * ten_pow[p->cw.e - p->tj_delta.e];
}
}
+ /* glyph output */
+ assert(is_chararraymode(p) || is_charmode(p));
if (is_chararraymode(p))
begin_charmode(pdf, f, p);
pdf_mark_char(f, c);
--- texk/web2c/luatexdir/pdf/pdfimage.w
+++ texk/web2c/luatexdir/pdf/pdfimage.w 2011-10-13 07:39:33.000000000 +0000
@@ -130,12 +130,12 @@ void place_img(PDF pdf, image_dict * idi
cm[5] = p->cm[5];
if (pdf->img_page_group_val == 0)
pdf->img_page_group_val = img_group_ref(idict); /* added from web for 1.40.8 */
- pdf_printf(pdf, "q\n");
+ pdf_puts(pdf, "q\n");
pdf_print_cm(pdf, cm);
- pdf_printf(pdf, "/Im");
+ pdf_puts(pdf, "/Im");
pdf_print_int(pdf, img_index(idict));
pdf_print_resname_prefix(pdf);
- pdf_printf(pdf, " Do\nQ\n");
+ pdf_puts(pdf, " Do\nQ\n");
addto_page_resources(pdf, obj_type_ximage, img_objnum(idict));
if (img_state(idict) < DICT_OUTIMG)
img_state(idict) = DICT_OUTIMG;
--- texk/web2c/luatexdir/pdf/pdflink.w
+++ texk/web2c/luatexdir/pdf/pdflink.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% pdflink.w
-% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2009-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -15,12 +15,12 @@
% License for more details.
% You should have received a copy of the GNU General Public License along
-% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
@ @c
static const char _svn_version[] =
- "$Id: pdflink.w 3891 2010-09-14 23:02:24Z hhenkel $"
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/pdf/pdflink.w $";
+ "$Id: pdflink.w 4309 2011-06-20 17:53:56Z hhenkel $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/pdf/pdflink.w $";
#include "ptexlib.h"
@@ -61,7 +61,7 @@ void do_link(PDF pdf, halfword p, halfwo
pdf_error("ext4", "link annotations cannot be inside an XForm");
assert(type(parent_box) == hlist_node);
if (is_obj_scheduled(pdf, pdf_link_objnum(p)))
- pdf_link_objnum(p) = pdf_new_objnum(pdf);
+ pdf_link_objnum(p) = pdf_create_obj(pdf, obj_type_others, 0);
push_link_level(pdf, p);
alt_rule.wd = width(p);
alt_rule.ht = height(p);
@@ -93,9 +93,9 @@ void end_link(PDF pdf, halfword p)
if (global_shipping_mode == SHIPPING_PAGE && matrixused()) {
matrixrecalculate(pos.h + pdf_link_margin);
pdf_ann_left(q) = getllx() - pdf_link_margin;
- pdf_ann_top(q) = cur_page_size.v - getury() - pdf_link_margin;
+ pdf_ann_top(q) = pdf->page_size.v - getury() - pdf_link_margin;
pdf_ann_right(q) = geturx() + pdf_link_margin;
- pdf_ann_bottom(q) = cur_page_size.v - getlly() + pdf_link_margin;
+ pdf_ann_bottom(q) = pdf->page_size.v - getlly() + pdf_link_margin;
} else {
switch (pdf->posstruct->dir) {
case dir_TLT:
@@ -114,7 +114,6 @@ void end_link(PDF pdf, halfword p)
pop_link_level(pdf);
}
-
@ For ``running'' annotations we must append a new node when the end of
annotation is in other box than its start. The new created node is identical to
corresponding whatsit node representing the start of annotation, but its
@@ -122,7 +121,7 @@ corresponding whatsit node representing
node, in order to use |flush_node_list| to do the job.
-@ Append a new pdf annot to |pdf_link_list|
+@ Append a new pdf annot to |pdf_link_list|.
@c
void append_link(PDF pdf, halfword parent_box, scaledpos cur, small_number i)
@@ -150,7 +149,7 @@ void scan_startlink(PDF pdf)
halfword r;
if (abs(cur_list.mode_field) == vmode)
pdf_error("ext1", "\\pdfstartlink cannot be used in vertical mode");
- k = pdf_new_objnum(pdf);
+ k = pdf_create_obj(pdf, obj_type_others, 0);
new_annot_whatsit(pdf_start_link_node);
set_pdf_link_attr(cur_list.tail_field, null);
if (scan_keyword("attr")) {
--- texk/web2c/luatexdir/pdf/pdfliteral.w
+++ texk/web2c/luatexdir/pdf/pdfliteral.w 2011-10-13 07:39:33.000000000 +0000
@@ -70,7 +70,7 @@ void pdf_out_literal(PDF pdf, halfword p
break;
case direct_always:
pdf_end_string_nl(pdf);
- ps->need_tm = 1;
+ ps->need_tm = true;
break;
default:
confusion("literal1");
@@ -136,7 +136,7 @@ void pdf_literal(PDF pdf, str_number s,
break;
case direct_always:
pdf_end_string_nl(pdf);
- p->need_tm = 1;
+ p->need_tm = true;
break;
default:
confusion("literal1");
@@ -150,5 +150,5 @@ void pdf_literal(PDF pdf, str_number s,
assert(s < 256);
pdf_out(pdf, s);
}
- pdf_print_nl(pdf);
+ pdf_out(pdf, '\n');
}
--- texk/web2c/luatexdir/pdf/pdfluaapi.w
+++ texk/web2c/luatexdir/pdf/pdfluaapi.w 2011-10-13 07:39:33.000000000 +0000
@@ -79,9 +79,9 @@ void pdflua_end_page(PDF pdf, int annots
lua_newtable(Luas); /* t f t ... */
lua_pushnumber(Luas, total_pages); /* i t f t ... */
lua_setfield(Luas, -2, "pagenum"); /* t f t ... */
- lua_pushnumber(Luas, cur_page_size.h); /* i t f t ... */
+ lua_pushnumber(Luas, pdf->page_size.h); /* i t f t ... */
lua_setfield(Luas, -2, "hsize"); /* t f t ... */
- lua_pushnumber(Luas, cur_page_size.v); /* i t f t ... */
+ lua_pushnumber(Luas, pdf->page_size.v); /* i t f t ... */
lua_setfield(Luas, -2, "vsize"); /* t f t ... */
if (annots != 0) {
lua_pushnumber(Luas, annots); /* i t f t ... */
--- texk/web2c/luatexdir/pdf/pdfobj.h
+++ texk/web2c/luatexdir/pdf/pdfobj.h 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
/* pdfobj.h
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
+ Copyright 2009-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -32,13 +32,13 @@
# define obj_obj_stream_attr(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 1] /* additional attributes into stream dict */
# define obj_obj_flags(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 2] /* stream/file flags */
# define obj_obj_pdfcompresslevel(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 3] /* overrides \pdfcompresslevel */
-# define obj_obj_pdfoslevel(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 4] /* for object stream compression */
+# define obj_obj_objstm_threshold(pdf, A) pdf->mem[obj_data_ptr((pdf), (A)) + 4] /* for object stream compression */
/* define set_obj_obj_data(pdf, A, B) obj_obj_data((pdf), (A)) = (B) */
/* define set_obj_obj_flags(pdf, A, B) obj_obj_flags((pdf), (A)) = (B) */
/* define set_obj_obj_stream_attr(pdf, A, B) obj_obj_stream_attr((pdf), (A)) = (B) */
/* define set_obj_obj_pdfcompresslevel(pdf, A, B) obj_obj_pdfcompresslevel((pdf), (A)) = (B) */
-/* define set_obj_obj_pdfoslevel(pdf, A, B) obj_obj_pdfoslevel((pdf), (A)) = (B) */
+/* define set_obj_obj_objstm_threshold(pdf, A, B) obj_obj_objstm_threshold((pdf), (A)) = (B) */
/**********************************************************************/
--- texk/web2c/luatexdir/pdf/pdfobj.w
+++ texk/web2c/luatexdir/pdf/pdfobj.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% pdfobj.w
-% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2009-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -38,16 +38,17 @@ void pdf_write_obj(PDF pdf, int k)
const_lstring st;
size_t li; /* index into |data.s| */
int saved_compress_level = pdf->compress_level;
- int os_level = 1; /* gives compressed objects for \.{\\pdfobjcompresslevel} $>$ 0 */
+ int os_threshold = OBJSTM_ALWAYS; /* gives compressed objects for \.{\\pdfobjcompresslevel} >= |OBJSTM_ALWAYS| */
int l = 0; /* possibly a lua registry reference */
int ll = 0;
data.s = NULL;
if (obj_obj_pdfcompresslevel(pdf, k) > -1) /* -1 = "unset" */
pdf->compress_level = obj_obj_pdfcompresslevel(pdf, k);
- if (obj_obj_pdfoslevel(pdf, k) > -1) /* -1 = "unset" */
- os_level = obj_obj_pdfoslevel(pdf, k);
+ if (obj_obj_objstm_threshold(pdf, k) != OBJSTM_UNSET)
+ os_threshold = obj_obj_objstm_threshold(pdf, k);
if (obj_obj_is_stream(pdf, k)) {
- pdf_begin_dict(pdf, k, 0);
+ pdf_begin_obj(pdf, k, OBJSTM_NEVER);
+ pdf_begin_dict(pdf);
l = obj_obj_stream_attr(pdf, k);
if (l != LUA_NOREF) {
lua_rawgeti(Luas, LUA_REGISTRYINDEX, l);
@@ -60,15 +61,17 @@ void pdf_write_obj(PDF pdf, int k)
luaL_unref(Luas, LUA_REGISTRYINDEX, l);
obj_obj_stream_attr(pdf, k) = LUA_NOREF;
}
+ pdf_dict_add_streaminfo(pdf);
+ pdf_end_dict(pdf);
pdf_begin_stream(pdf);
} else
- pdf_begin_obj(pdf, k, os_level);
+ pdf_begin_obj(pdf, k, os_threshold);
l = obj_obj_data(pdf, k);
lua_rawgeti(Luas, LUA_REGISTRYINDEX, l);
assert(lua_isstring(Luas, -1));
st.s = lua_tolstring(Luas, -1, &li);
st.l = li;
- lua_pop(Luas,1);
+ lua_pop(Luas, 1);
if (obj_obj_is_file(pdf, k)) {
boolean res = false; /* callback status value */
const char *fnam = NULL; /* callback found filename */
@@ -110,9 +113,10 @@ void pdf_write_obj(PDF pdf, int k)
if (!obj_obj_is_stream(pdf, k) && st.s[st.l - 1] != '\n')
pdf_out(pdf, '\n');
}
- if (obj_obj_is_stream(pdf, k))
+ if (obj_obj_is_stream(pdf, k)) {
pdf_end_stream(pdf);
- else
+ pdf_end_obj(pdf);
+ } else
pdf_end_obj(pdf);
luaL_unref(Luas, LUA_REGISTRYINDEX, l);
obj_obj_data(pdf, k) = LUA_NOREF;
@@ -127,7 +131,7 @@ void init_obj_obj(PDF pdf, int k)
unset_obj_obj_is_stream(pdf, k);
unset_obj_obj_is_file(pdf, k);
obj_obj_pdfcompresslevel(pdf, k) = -1; /* unset */
- obj_obj_pdfoslevel(pdf, k) = -1; /* unset */
+ obj_obj_objstm_threshold(pdf, k) = OBJSTM_UNSET; /* unset */
}
@ The \.{\\pdfobj} primitive is used to create a ``raw'' object in the PDF
@@ -148,7 +152,7 @@ void scan_obj(PDF pdf)
if (cur_cmd != spacer_cmd)
back_input();
pdf->obj_count++;
- k = pdf_create_obj(pdf, obj_type_obj, pdf->obj_ptr + 1);
+ k = pdf_create_obj(pdf, obj_type_obj, 0);
} else {
if (scan_keyword("useobjnum")) {
scan_int();
@@ -158,13 +162,13 @@ void scan_obj(PDF pdf)
luaL_error(Luas, "object in use");
} else {
pdf->obj_count++;
- k = pdf_create_obj(pdf, obj_type_obj, pdf->obj_ptr + 1);
+ k = pdf_create_obj(pdf, obj_type_obj, 0);
}
obj_data_ptr(pdf, k) = pdf_get_mem(pdf, pdfmem_obj_size);
init_obj_obj(pdf, k);
if (scan_keyword("uncompressed")) {
obj_obj_pdfcompresslevel(pdf, k) = 0; /* \pdfcompresslevel = 0 */
- obj_obj_pdfoslevel(pdf, k) = 0;
+ obj_obj_objstm_threshold(pdf, k) = OBJSTM_NEVER;
}
if (scan_keyword("stream")) {
set_obj_obj_is_stream(pdf, k);
--- texk/web2c/luatexdir/pdf/pdfoutline.w
+++ texk/web2c/luatexdir/pdf/pdfoutline.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% pdfoutline.w
-%
-% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
+
+% Copyright 2009-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -82,7 +82,7 @@ static int open_subentries(PDF pdf, half
return k;
}
-@ return number of outline entries in the same level with |p|
+@ return number of outline entries in the same level with |p|
@c
static int outline_list_count(PDF pdf, pointer p)
@@ -115,7 +115,8 @@ void scan_pdfoutline(PDF pdf)
}
scan_pdf_ext_toks();
q = def_ref;
- j = pdf_new_obj(pdf, obj_type_others, 0, 1);
+ j = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, j, OBJSTM_ALWAYS);
write_action(pdf, p);
pdf_end_obj(pdf);
delete_action_ref(p);
@@ -123,7 +124,8 @@ void scan_pdfoutline(PDF pdf)
set_obj_outline_ptr(pdf, k, pdf_get_mem(pdf, pdfmem_outline_size));
set_obj_outline_action_objnum(pdf, k, j);
set_obj_outline_count(pdf, k, i);
- l = pdf_new_obj(pdf, obj_type_others, 0, 1);
+ l = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, l, OBJSTM_ALWAYS);
{
char *s = tokenlist_to_cstring(q, true, NULL);
pdf_print_str_ln(pdf, s);
@@ -172,7 +174,7 @@ void scan_pdfoutline(PDF pdf)
}
@ In the end we must flush PDF objects that cannot be written out
-immediately after shipping out pages.
+immediately after shipping out pages.
@c
int print_outlines(PDF pdf)
@@ -180,7 +182,7 @@ int print_outlines(PDF pdf)
int k, l, a;
int outlines;
if (pdf->first_outline != 0) {
- outlines = pdf_new_dict(pdf, obj_type_others, 0, 1);
+ outlines = pdf_create_obj(pdf, obj_type_others, 0);
l = pdf->first_outline;
k = 0;
do {
@@ -191,11 +193,14 @@ int print_outlines(PDF pdf)
set_obj_outline_parent(pdf, l, pdf->obj_ptr);
l = obj_outline_next(pdf, l);
} while (l != 0);
- pdf_printf(pdf, "/Type /Outlines\n");
- pdf_indirect_ln(pdf, "First", pdf->first_outline);
- pdf_indirect_ln(pdf, "Last", pdf->last_outline);
- pdf_int_entry_ln(pdf, "Count", k);
+ pdf_begin_obj(pdf, outlines, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Outlines");
+ pdf_dict_add_ref(pdf, "First", pdf->first_outline);
+ pdf_dict_add_ref(pdf, "Last", pdf->last_outline);
+ pdf_dict_add_int(pdf, "Count", k);
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
/* Output PDF outline entries */
k = pdf->head_tab[obj_type_outline];
@@ -206,27 +211,31 @@ int print_outlines(PDF pdf)
if (obj_outline_next(pdf, k) == 0)
pdf->last_outline = k;
}
- pdf_begin_dict(pdf, k, 1);
- pdf_indirect_ln(pdf, "Title", obj_outline_title(pdf, k));
- pdf_indirect_ln(pdf, "A", obj_outline_action_objnum(pdf, k));
+ pdf_begin_obj(pdf, k, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_ref(pdf, "Title", obj_outline_title(pdf, k));
+ pdf_dict_add_ref(pdf, "A", obj_outline_action_objnum(pdf, k));
if (obj_outline_parent(pdf, k) != 0)
- pdf_indirect_ln(pdf, "Parent", obj_outline_parent(pdf, k));
+ pdf_dict_add_ref(pdf, "Parent", obj_outline_parent(pdf, k));
if (obj_outline_prev(pdf, k) != 0)
- pdf_indirect_ln(pdf, "Prev", obj_outline_prev(pdf, k));
+ pdf_dict_add_ref(pdf, "Prev", obj_outline_prev(pdf, k));
if (obj_outline_next(pdf, k) != 0)
- pdf_indirect_ln(pdf, "Next", obj_outline_next(pdf, k));
+ pdf_dict_add_ref(pdf, "Next", obj_outline_next(pdf, k));
if (obj_outline_first(pdf, k) != 0)
- pdf_indirect_ln(pdf, "First", obj_outline_first(pdf, k));
+ pdf_dict_add_ref(pdf, "First", obj_outline_first(pdf, k));
if (obj_outline_last(pdf, k) != 0)
- pdf_indirect_ln(pdf, "Last", obj_outline_last(pdf, k));
+ pdf_dict_add_ref(pdf, "Last", obj_outline_last(pdf, k));
if (obj_outline_count(pdf, k) != 0)
- pdf_int_entry_ln(pdf, "Count", obj_outline_count(pdf, k));
+ pdf_dict_add_int(pdf, "Count", obj_outline_count(pdf, k));
if (obj_outline_attr(pdf, k) != 0) {
- pdf_print_toks_ln(pdf, obj_outline_attr(pdf, k));
+ pdf_out(pdf, '\n');
+ pdf_print_toks(pdf, obj_outline_attr(pdf, k));
+ pdf_out(pdf, '\n');
delete_token_ref(obj_outline_attr(pdf, k));
set_obj_outline_attr(pdf, k, null);
}
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
k = obj_link(pdf, k);
}
--- texk/web2c/luatexdir/pdf/pdfpage.h
+++ texk/web2c/luatexdir/pdf/pdfpage.h 2011-10-13 07:39:33.000000000 +0000
@@ -47,7 +47,6 @@ void init_pdf_pagecalculations(PDF pdf);
void pdf_print_cm(PDF pdf, pdffloat * cm);
void pdf_set_pos(PDF pdf, scaledpos pos);
void pdf_set_pos_temp(PDF pdf, scaledpos pos);
-void print_pdffloat(PDF pdf, pdffloat f);
void print_pdf_matrix(PDF pdf, pdffloat * tm);
#endif
--- texk/web2c/luatexdir/pdf/pdfpage.w
+++ texk/web2c/luatexdir/pdf/pdfpage.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% pdfpage.w
-% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -29,8 +29,6 @@ static const char _svn_version[] =
#include <assert.h>
#include <math.h>
-#define lround(a) (long) floor((a) + 0.5)
-
@ eternal constants
@c
#define one_bp ((double) 65536 * (double) 72.27 / 72) /* number of sp per 1bp */
@@ -56,10 +54,11 @@ void init_pdf_pagecalculations(PDF pdf)
setpdffloat(p->cm[4], 0, decimal_digits); /* horizontal movement on page */
setpdffloat(p->cm[5], 0, decimal_digits); /* vertical movement on page */
/* for placement inside BT...ET */
+ setpdffloat(p->tm0_cur, 0, 6); /* mantissa holds HZ expand * ExtendFont */
setpdffloat(p->tm[0], ten_pow[6], 6); /* mantissa holds HZ expand * ExtendFont */
setpdffloat(p->tm[1], 0, 0);
setpdffloat(p->tm[2], 0, 3); /* mantissa holds SlantFont, 0 = default */
- setpdffloat(p->tm[3], 1, 0);
+ setpdffloat(p->tm[3], ten_pow[6], 6);
setpdffloat(p->tm[4], 0, decimal_digits); /* mantissa holds delta from |pdf_bt_pos.h| */
setpdffloat(p->tm[5], 0, decimal_digits); /* mantissa holds delta from |pdf_bt_pos.v| */
/* */
@@ -68,7 +67,8 @@ void init_pdf_pagecalculations(PDF pdf)
p->wmode = WMODE_H;
p->mode = PMODE_PAGE;
p->ishex = 0;
- p->need_tm = 0;
+ p->need_tf = false;
+ p->need_tm = false;
p->k1 = ten_pow[p->pdf.h.e] / one_bp;
}
@@ -158,38 +158,12 @@ boolean calc_pdfpos(pdfstructure * p, sc
}
@ @c
-void print_pdffloat(PDF pdf, pdffloat f)
-{
- char a[24];
- int e = f.e, i, j;
- long l, m = f.m;
- if (m < 0) {
- pdf_puts(pdf, "-");
- m *= -1;
- }
- l = m / ten_pow[e];
- pdf_print_int(pdf, l);
- l = m % ten_pow[e];
- if (l != 0) {
- pdf_puts(pdf, ".");
- j = snprintf(a, 23, "%ld", l + ten_pow[e]);
- assert(j < 23);
- for (i = e; i > 0; i--) {
- if (a[i] != '0')
- break;
- a[i] = '\0';
- }
- pdf_puts(pdf, (a + 1));
- }
-}
-
-@ @c
void print_pdf_matrix(PDF pdf, pdffloat * tm)
{
int i;
for (i = 0; i < 5; i++) {
print_pdffloat(pdf, tm[i]);
- pdf_puts(pdf, " ");
+ pdf_out(pdf, ' ');
}
print_pdffloat(pdf, tm[i]);
}
@@ -234,8 +208,7 @@ static void begin_text(PDF pdf)
p->pdf_bt_pos = p->pdf;
pdf_puts(pdf, "BT\n");
p->mode = PMODE_TEXT;
- p->f_pdf_cur = null_font; /* forces Tf operator */
- p->fs_cur.m = 0;
+ p->need_tf = true;
}
static void end_text(PDF pdf)
@@ -268,14 +241,14 @@ void pdf_goto_pagemode(PDF pdf)
end_chararray(pdf);
if (is_textmode(p))
end_text(pdf);
- assert(is_pagemode(p));
}
+ assert(is_pagemode(p));
}
void pdf_goto_textmode(PDF pdf)
{
pdfstructure *p = pdf->pstruct;
- scaledpos origin = {
+ const scaledpos origin = {
0, 0
};
if (!is_textmode(p)) {
@@ -288,6 +261,6 @@ void pdf_goto_textmode(PDF pdf)
if (is_chararraymode(p))
end_chararray(pdf);
}
- assert(is_textmode(p));
}
+ assert(is_textmode(p));
}
--- texk/web2c/luatexdir/pdf/pdfpagetree.h
+++ texk/web2c/luatexdir/pdf/pdfpagetree.h 2011-10-13 07:39:33.000000000 +0000
@@ -0,0 +1,29 @@
+/* pdfpagetree.h
+
+ Copyright 2009--2011 Taco Hoekwater <taco@luatex.org>
+
+ This file is part of LuaTeX.
+
+ LuaTeX 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 2 of the License, or (at your
+ option) any later version.
+
+ LuaTeX 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
+
+/* $Id: pdfpagetree.h 4214 2011-04-27 21:53:38Z hhenkel $ */
+
+#ifndef PAGETREE_H
+# define PAGETREE_H
+
+int output_pages_tree(PDF);
+int pdf_do_page_divert(PDF, int, int);
+void pdf_do_page_undivert(int, int);
+
+#endif /* PAGETREE_H */
--- texk/web2c/luatexdir/pdf/pdfpagetree.w
+++ texk/web2c/luatexdir/pdf/pdfpagetree.w 2011-10-13 07:39:33.000000000 +0000
@@ -0,0 +1,272 @@
+% pdfpagetree.w
+
+% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
+
+% This file is part of LuaTeX.
+
+% LuaTeX 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 2 of the License, or (at your
+% option) any later version.
+
+% LuaTeX 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 Lesser General Public
+% License for more details.
+
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+
+@ @c
+#include "ptexlib.h"
+
+static const char _svn_version[] =
+ "$Id: pdfpagetree.w 4217 2011-04-27 22:50:59Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/pdf/pdfpagetree.w $";
+
+@* Page diversions.
+
+@ @c
+#ifdef DEBUG
+# define PAGES_TREE_KIDSMAX 3
+#else
+# define PAGES_TREE_KIDSMAX 10
+#endif
+
+static struct avl_table *divert_list_tree = NULL;
+
+typedef struct pages_entry_ {
+ int objnum; /* object number of this /Pages object */
+ int number_of_pages; /* total number of all pages below */
+ int number_of_kids; /* number of direct kid objects */
+ int kids[PAGES_TREE_KIDSMAX]; /* array of kid object numbers */
+ struct pages_entry_ *next;
+} pages_entry;
+
+typedef struct divert_list_entry_ {
+ int divnum;
+ pages_entry *first;
+ pages_entry *last;
+} divert_list_entry;
+
+static int comp_divert_list_entry(const void *pa, const void *pb, void *p)
+{
+ (void) p;
+ if (((const divert_list_entry *) pa)->divnum >
+ ((const divert_list_entry *) pb)->divnum)
+ return 1;
+ if (((const divert_list_entry *) pa)->divnum <
+ ((const divert_list_entry *) pb)->divnum)
+ return -1;
+ return 0;
+}
+
+@ @c
+static pages_entry *new_pages_entry(PDF pdf)
+{
+ pages_entry *p;
+ int i;
+ p = xtalloc(1, pages_entry);
+ p->number_of_pages = p->number_of_kids = 0;
+ for (i = 0; i < PAGES_TREE_KIDSMAX; i++)
+ p->kids[i] = 0;
+ p->next = NULL;
+ p->objnum = pdf_create_obj(pdf, obj_type_pages, 0);
+ return p;
+}
+
+@ @c
+static divert_list_entry *new_divert_list_entry(void)
+{
+ divert_list_entry *d;
+ d = xtalloc(1, divert_list_entry);
+ d->first = d->last = NULL;
+ return d;
+}
+
+@ @c
+static void ensure_list_tree(void)
+{
+ if (divert_list_tree == NULL) {
+ divert_list_tree =
+ avl_create(comp_divert_list_entry, NULL, &avl_xallocator);
+ assert(divert_list_tree != NULL);
+ }
+}
+
+@ @c
+static divert_list_entry *get_divert_list(int divnum)
+{
+ divert_list_entry *d, tmp;
+ void **aa;
+ tmp.divnum = divnum;
+ d = (divert_list_entry *) avl_find(divert_list_tree, &tmp);
+ if (d == NULL) {
+ d = new_divert_list_entry();
+ d->divnum = divnum;
+ aa = avl_probe(divert_list_tree, d);
+ assert(aa != NULL);
+ }
+ return d;
+}
+
+@ |pdf_do_page_divert()| returns the current /Parent object number
+@c
+int pdf_do_page_divert(PDF pdf, int objnum, int divnum)
+{
+ divert_list_entry *d;
+ pages_entry *p;
+#ifdef DEBUG
+ pages_entry *q;
+ struct avl_traverser t;
+ int i;
+#endif
+ /* initialize the tree */
+ ensure_list_tree();
+ /* make sure we have a list for this diversion */
+ d = get_divert_list(divnum);
+ if (d->first == NULL || d->last->number_of_kids == PAGES_TREE_KIDSMAX) {
+ /* append a new |pages_entry| */
+ p = new_pages_entry(pdf);
+ if (d->first == NULL)
+ d->first = p;
+ else
+ d->last->next = p;
+ d->last = p;
+ }
+ p = d->last;
+ p->kids[p->number_of_kids++] = objnum;
+ p->number_of_pages++;
+#ifdef DEBUG
+ printf("\n");
+ avl_t_init(&t, divert_list_tree);
+ for (d = avl_t_first(&t, divert_list_tree); d != NULL; d = avl_t_next(&t)) {
+ printf("===== D-LIST %d: ", d->divnum);
+ for (q = d->first; q != NULL; q = q->next) {
+ printf("P=%d NK=%d (", q->objnum, q->number_of_kids);
+ for (i = 0; i < q->number_of_kids; i++)
+ printf("%d ", q->kids[i]);
+ printf(") ");
+ }
+ printf("\n");
+ }
+ printf("\n");
+#endif
+ return p->objnum;
+}
+
+@ @c
+static void movelist(divert_list_entry * d, divert_list_entry * dto)
+{
+ if (d != NULL && d->first != NULL && d->divnum != dto->divnum) { /* no undivert of empty list or into self */
+ if (dto->first == NULL)
+ dto->first = d->first;
+ else
+ dto->last->next = d->first;
+ dto->last = d->last;
+ d->first = d->last = NULL; /* one could as well remove this |divert_list_entry| */
+ }
+}
+
+@ undivert from diversion |divnum| into diversion |curdivnum|
+@c
+void pdf_do_page_undivert(int divnum, int curdivnum)
+{
+ divert_list_entry *d, *dto, tmp;
+ struct avl_traverser t;
+#ifdef DEBUG
+ pages_entry *p;
+ int i;
+#endif
+ /* initialize the tree */
+ ensure_list_tree();
+ /* find the diversion |curdivnum| list where diversion |divnum| should go */
+ dto = get_divert_list(curdivnum);
+ if (divnum == 0) { /* 0 = special case: undivert {\it all\/} lists */
+ avl_t_init(&t, divert_list_tree);
+ for (d = avl_t_first(&t, divert_list_tree); d != NULL;
+ d = avl_t_next(&t))
+ movelist(d, dto);
+ } else {
+ tmp.divnum = divnum;
+ d = (divert_list_entry *) avl_find(divert_list_tree, &tmp);
+ movelist(d, dto);
+ }
+#ifdef DEBUG
+ printf("\n");
+ avl_t_init(&t, divert_list_tree);
+ for (d = avl_t_first(&t, divert_list_tree); d != NULL; d = avl_t_next(&t)) {
+ printf("===== U-LIST %d: ", d->divnum);
+ for (p = d->first; p != NULL; p = p->next) {
+ printf("P=%d NK=%d (", p->objnum, p->number_of_kids);
+ for (i = 0; i < p->number_of_kids; i++)
+ printf("%d ", p->kids[i]);
+ printf(") ");
+ }
+ printf("\n");
+ }
+ printf("\n");
+#endif
+}
+
+@ write a /Pages object
+@c
+#define pdf_pages_attr equiv(pdf_pages_attr_loc)
+
+static void write_pages(PDF pdf, pages_entry * p, int parent)
+{
+ int i;
+ assert(p != NULL);
+ pdf_begin_obj(pdf, p->objnum, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_name(pdf, "Type", "Pages");
+ if (parent == 0) { /* it's root */
+ if (pdf_pages_attr != null) {
+ pdf_print_toks(pdf, pdf_pages_attr);
+ pdf_out(pdf, ' ');
+ }
+ print_pdf_table_string(pdf, "pagesattributes");
+ } else
+ pdf_dict_add_ref(pdf, "Parent", parent);
+ pdf_dict_add_int(pdf, "Count", (int) p->number_of_pages);
+ pdf_add_name(pdf, "Kids");
+ pdf_begin_array(pdf);
+ for (i = 0; i < p->number_of_kids; i++)
+ pdf_add_ref(pdf, (int) p->kids[i]);
+ pdf_end_array(pdf);
+ pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
+}
+
+@ loop over all /Pages objects, output them, create their parents,
+recursing bottom up, return the /Pages root object number
+@c
+static int output_pages_list(PDF pdf, pages_entry * pe)
+{
+ pages_entry *p, *q, *r;
+ assert(pe != NULL);
+ if (pe->next == NULL) { /* everything fits into one |pages_entry| */
+ write_pages(pdf, pe, 0); /* --> /Pages root found */
+ return pe->objnum;
+ }
+ q = r = new_pages_entry(pdf); /* one level higher needed */
+ for (p = pe; p != NULL; p = p->next) {
+ if (q->number_of_kids == PAGES_TREE_KIDSMAX) {
+ q->next = new_pages_entry(pdf);
+ q = q->next;
+ }
+ q->kids[q->number_of_kids++] = p->objnum;
+ q->number_of_pages += p->number_of_pages;
+ write_pages(pdf, p, q->objnum);
+ }
+ return output_pages_list(pdf, r); /* recurse through next higher level */
+}
+
+@ @c
+int output_pages_tree(PDF pdf)
+{
+ divert_list_entry *d;
+ pdf_do_page_undivert(0, 0); /* concatenate all diversions into diversion 0 */
+ d = get_divert_list(0); /* get diversion 0 */
+ return output_pages_list(pdf, d->first);
+}
--- texk/web2c/luatexdir/pdf/pdfrule.w
+++ texk/web2c/luatexdir/pdf/pdfrule.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% pdfrule.w
%
-% Copyright 2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2010-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -19,16 +19,12 @@
@ @c
static const char _svn_version[] =
- "$Id: pdfrule.w 3584 2010-04-02 17:45:55Z hhenkel $"
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/pdf/pdfrule.w $";
+ "$Id: pdfrule.w 4321 2011-07-01 19:32:05Z hhenkel $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/pdf/pdfrule.w $";
#include "ptexlib.h"
-
-@ @c
#include "pdf/pdfpage.h"
-#define lround(a) (long) floor((a) + 0.5)
-
@ @c
void pdf_place_rule(PDF pdf, halfword q, scaledpos size)
{
@@ -41,30 +37,30 @@ void pdf_place_rule(PDF pdf, halfword q,
dim.h.e = p->pdf.h.e;
dim.v.m = lround(size.v * p->k1);
dim.v.e = p->pdf.v.e;
- pdf_printf(pdf, "q\n");
+ pdf_puts(pdf, "q\n");
if (size.v <= one_bp) {
pos.v += (int) lround(0.5 * size.v);
pdf_set_pos_temp(pdf, pos);
- pdf_printf(pdf, "[]0 d 0 J ");
+ pdf_puts(pdf, "[]0 d 0 J ");
print_pdffloat(pdf, dim.v);
- pdf_printf(pdf, " w 0 0 m ");
+ pdf_puts(pdf, " w 0 0 m ");
print_pdffloat(pdf, dim.h);
- pdf_printf(pdf, " 0 l S\n");
+ pdf_puts(pdf, " 0 l S\n");
} else if (size.h <= one_bp) {
pos.h += (int) lround(0.5 * size.h);
pdf_set_pos_temp(pdf, pos);
- pdf_printf(pdf, "[]0 d 0 J ");
+ pdf_puts(pdf, "[]0 d 0 J ");
print_pdffloat(pdf, dim.h);
- pdf_printf(pdf, " w 0 0 m 0 ");
+ pdf_puts(pdf, " w 0 0 m 0 ");
print_pdffloat(pdf, dim.v);
- pdf_printf(pdf, " l S\n");
+ pdf_puts(pdf, " l S\n");
} else {
pdf_set_pos_temp(pdf, pos);
- pdf_printf(pdf, "0 0 ");
+ pdf_puts(pdf, "0 0 ");
print_pdffloat(pdf, dim.h);
- pdf_printf(pdf, " ");
+ pdf_out(pdf, ' ');
print_pdffloat(pdf, dim.v);
- pdf_printf(pdf, " re f\n");
+ pdf_puts(pdf, " re f\n");
}
- pdf_printf(pdf, "Q\n");
+ pdf_puts(pdf, "Q\n");
}
--- texk/web2c/luatexdir/pdf/pdfshipout.w
+++ texk/web2c/luatexdir/pdf/pdfshipout.w 2011-10-13 07:39:33.000000000 +0000
@@ -141,34 +141,34 @@ void ship_out(PDF pdf, halfword p, shipp
/* Calculate page dimensions and margins */
if (global_shipping_mode == SHIPPING_PAGE) {
if (page_width > 0)
- cur_page_size.h = page_width;
+ pdf->page_size.h = page_width;
else {
switch (page_direction) {
case dir_TLT:
- cur_page_size.h = width(p) + 2 * page_left_offset;
+ pdf->page_size.h = width(p) + 2 * page_left_offset;
break;
case dir_TRT:
- cur_page_size.h = width(p) + 2 * page_right_offset;
+ pdf->page_size.h = width(p) + 2 * page_right_offset;
break;
case dir_LTL:
- cur_page_size.h = height(p) + depth(p) + 2 * page_left_offset;
+ pdf->page_size.h = height(p) + depth(p) + 2 * page_left_offset;
break;
case dir_RTT:
- cur_page_size.h = height(p) + depth(p) + 2 * page_right_offset;
+ pdf->page_size.h = height(p) + depth(p) + 2 * page_right_offset;
break;
}
}
if (page_height > 0)
- cur_page_size.v = page_height;
+ pdf->page_size.v = page_height;
else {
switch (page_direction) {
case dir_TLT:
case dir_TRT:
- cur_page_size.v = height(p) + depth(p) + 2 * page_top_offset;
+ pdf->page_size.v = height(p) + depth(p) + 2 * page_top_offset;
break;
case dir_LTL:
case dir_RTT:
- cur_page_size.v = width(p) + 2 * page_top_offset;
+ pdf->page_size.v = width(p) + 2 * page_top_offset;
break;
}
}
@@ -179,13 +179,13 @@ void ship_out(PDF pdf, halfword p, shipp
switch (pdf->o_mode) {
case OMODE_DVI:
refpoint.pos.h = one_true_inch;
- refpoint.pos.v = cur_page_size.v - one_true_inch;
+ refpoint.pos.v = pdf->page_size.v - one_true_inch;
dvi = refpoint.pos;
break;
case OMODE_PDF:
case OMODE_LUA:
refpoint.pos.h = pdf_h_origin;
- refpoint.pos.v = cur_page_size.v - pdf_v_origin;
+ refpoint.pos.v = pdf->page_size.v - pdf_v_origin;
break;
default:
assert(0);
@@ -203,7 +203,7 @@ void ship_out(PDF pdf, halfword p, shipp
case dir_TRT:
case dir_RTT:
refpoint.pos.h +=
- cur_page_size.h - page_right_offset - one_true_inch;
+ pdf->page_size.h - page_right_offset - one_true_inch;
refpoint.pos.v -= v_offset;
break;
}
@@ -221,13 +221,13 @@ void ship_out(PDF pdf, halfword p, shipp
switch (pdf->posstruct->dir) {
case dir_TLT:
case dir_TRT:
- cur_page_size.h = width(p);
- cur_page_size.v = height(p) + depth(p);
+ pdf->page_size.h = width(p);
+ pdf->page_size.v = height(p) + depth(p);
break;
case dir_LTL:
case dir_RTT:
- cur_page_size.h = height(p) + depth(p);
- cur_page_size.v = width(p);
+ pdf->page_size.h = height(p) + depth(p);
+ pdf->page_size.v = width(p);
break;
}
switch (pdf->posstruct->dir) {
--- texk/web2c/luatexdir/pdf/pdftables.h
+++ texk/web2c/luatexdir/pdf/pdftables.h 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
/* pdftables.h
- Copyright 2009 Taco Hoekwater <taco@luatex.org>
+ Copyright 2009-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -67,30 +67,33 @@ structure depending on the object type;
well.
*/
-# define obj_info(pdf,A) pdf->obj_tab[(A)].u.int0 /* information representing identifier of this object */
-# define obj_start(pdf,A) pdf->obj_tab[(A)].u.str0
-# define obj_link(pdf,A) pdf->obj_tab[(A)].int1 /* link to the next entry in linked list */
-# define obj_offset(pdf,A) pdf->obj_tab[(A)].int2 /* negative (flags), or byte offset for this object in PDF
- output file, or object stream number for this object */
-# define obj_os_idx(pdf,A) pdf->obj_tab[(A)].int3 /* index of this object in object stream */
-# define obj_aux(pdf,A) pdf->obj_tab[(A)].v.int4 /* auxiliary pointer */
-# define obj_stop(pdf,A) pdf->obj_tab[(A)].v.str4
-# define obj_type(pdf,A) pdf->obj_tab[(A)].objtype
-
-# define obj_data_ptr obj_aux /* pointer to |pdf->mem| */
-
-# define set_obj_link(pdf,A,B) obj_link(pdf,A)=B
-# define set_obj_start(pdf,A,B) obj_start(pdf,A)=B
-# define set_obj_info(pdf,A,B) obj_info(pdf,A)=B
-# define set_obj_offset(pdf,A,B) obj_offset(pdf,A)=B
-# define set_obj_aux(pdf,A,B) obj_aux(pdf,A)=B
-# define set_obj_stop(pdf,A,B) obj_stop(pdf,A)=B
-# define set_obj_data_ptr(pdf,A,B) obj_data_ptr(pdf,A)=B
-
-# define set_obj_fresh(pdf,A) obj_offset(pdf,(A))=-2
-# define set_obj_scheduled(pdf,A) if (intcast(obj_offset(pdf,A))==-2) obj_offset(pdf,A)=-1
-# define is_obj_scheduled(pdf,A) (intcast(obj_offset(pdf,A))>-2)
-# define is_obj_written(pdf,A) (intcast(obj_offset(pdf,A))>-1)
+# define obj_info(pdf,A) pdf->obj_tab[(A)].u.int0 /* information representing identifier of this object */
+# define obj_start(pdf,A) pdf->obj_tab[(A)].u.str0
+# define obj_link(pdf,A) pdf->obj_tab[(A)].int1 /* link to the next entry in linked list */
+
+# define obj_offset(pdf,A) pdf->obj_tab[(A)].int2 /* negative (flags), or byte offset for this object in PDF
+ output file, or ... */
+# define obj_os_objnum(pdf,A) pdf->obj_tab[(A)].int2 /* ... object stream number for this object */
+# define obj_os_idx(pdf,A) pdf->obj_tab[(A)].int3 /* index of this object in object stream */
+# define obj_aux(pdf,A) pdf->obj_tab[(A)].v.int4 /* auxiliary pointer */
+# define obj_stop(pdf,A) pdf->obj_tab[(A)].v.str4
+# define obj_type(pdf,A) pdf->obj_tab[(A)].objtype
+
+# define obj_data_ptr obj_aux /* pointer to |pdf->mem| */
+
+# define set_obj_link(pdf,A,B) obj_link(pdf,A)=(B)
+# define set_obj_start(pdf,A,B) obj_start(pdf,A)=(B)
+# define set_obj_info(pdf,A,B) obj_info(pdf,A)=(B)
+# define set_obj_offset(pdf,A,B) obj_offset(pdf,A)=(B)
+# define set_obj_os_objnum(pdf,A,B) obj_offset(pdf,A)=(B)
+# define set_obj_aux(pdf,A,B) obj_aux(pdf,A)=(B)
+# define set_obj_stop(pdf,A,B) obj_stop(pdf,A)=(B)
+# define set_obj_data_ptr(pdf,A,B) obj_data_ptr(pdf,A)=(B)
+
+# define set_obj_fresh(pdf,A) obj_offset(pdf,(A))=-2
+# define set_obj_scheduled(pdf,A) if (intcast(obj_offset(pdf,A))==-2) obj_offset(pdf,A)=-1
+# define is_obj_scheduled(pdf,A) (intcast(obj_offset(pdf,A))>-2)
+# define is_obj_written(pdf,A) (intcast(obj_offset(pdf,A))>-1)
/* NOTE: The data structure definitions for the nodes on the typesetting side are
inside |nodes.h| */
@@ -102,9 +105,8 @@ well.
extern int find_obj(PDF pdf, int t, int i, boolean byname);
extern void check_obj_exists(PDF pdf, int objnum);
extern void check_obj_type(PDF pdf, int t, int objnum);
-extern int get_obj(PDF pdf, int t, int i, boolean byname);
+extern int pdf_get_obj(PDF pdf, int t, int i, boolean byname);
extern int pdf_create_obj(PDF pdf, int t, int i);
-extern int pdf_new_objnum(PDF pdf);
extern void set_rect_dimens(PDF pdf, halfword p, halfword parent_box,
scaledpos cur, scaled_whd alt_rule, scaled margin);
--- texk/web2c/luatexdir/pdf/pdftables.w
+++ texk/web2c/luatexdir/pdf/pdftables.w 2011-10-13 07:39:33.000000000 +0000
@@ -142,7 +142,7 @@ int pdf_create_obj(PDF pdf, int t, int i
if (i < 0) {
ss = makecstring(-i);
avl_put_str_obj(pdf, ss, pdf->obj_ptr, t);
- } else
+ } else if (i > 0)
avl_put_int_obj(pdf, i, pdf->obj_ptr, t);
if (t <= HEAD_TAB_MAX) {
obj_link(pdf, pdf->obj_ptr) = pdf->head_tab[t];
@@ -179,7 +179,7 @@ int find_obj(PDF pdf, int t, int i, bool
|vlist_out|.
@c
-int get_obj(PDF pdf, int t, int i, boolean byname)
+int pdf_get_obj(PDF pdf, int t, int i, boolean byname)
{
int r;
str_number s;
@@ -206,15 +206,8 @@ int get_obj(PDF pdf, int t, int i, boole
return r;
}
-@ create a new object and return its number
-
+@ object checking
@c
-int pdf_new_objnum(PDF pdf)
-{
- int k = pdf_create_obj(pdf, obj_type_others, 0);
- return k;
-}
-
void check_obj_exists(PDF pdf, int objnum)
{
if (objnum < 0 || objnum > pdf->obj_ptr)
@@ -290,7 +283,7 @@ void set_rect_dimens(PDF pdf, halfword p
@ @c
void libpdffinish(PDF pdf)
{
- fb_free(pdf);
+ strbuf_free(pdf->fb);
xfree(pdf->job_id_string);
fm_free();
t1_free();
@@ -302,7 +295,6 @@ void libpdffinish(PDF pdf)
zip_free(pdf);
}
-
@ Store some of the pdftex data structures in the format. The idea here is
to ensure that any data structures referenced from pdftex-specific whatsit
nodes are retained. For the sake of simplicity and speed, all the filled parts
--- texk/web2c/luatexdir/pdf/pdfthread.w
+++ texk/web2c/luatexdir/pdf/pdfthread.w 2011-10-13 07:39:33.000000000 +0000
@@ -36,8 +36,9 @@ void append_bead(PDF pdf, halfword p)
int a, b, c, t;
if (global_shipping_mode == SHIPPING_FORM)
pdf_error("ext4", "threads cannot be inside an XForm");
- t = get_obj(pdf, obj_type_thread, pdf_thread_id(p), pdf_thread_named_id(p));
- b = pdf_new_objnum(pdf);
+ t = pdf_get_obj(pdf, obj_type_thread, pdf_thread_id(p),
+ pdf_thread_named_id(p));
+ b = pdf_create_obj(pdf, obj_type_others, 0);
obj_bead_ptr(pdf, b) = pdf_get_mem(pdf, pdfmem_bead_size);
set_obj_bead_page(pdf, b, pdf->last_page);
set_obj_bead_data(pdf, b, p);
@@ -143,12 +144,13 @@ void end_thread(PDF pdf, halfword p)
@c
void thread_title(PDF pdf, int t)
{
- pdf_printf(pdf, "/Title (");
+ pdf_add_name(pdf, "Title");
+ pdf_out(pdf, '(');
if (obj_info(pdf, t) < 0)
pdf_print(pdf, -obj_info(pdf, t));
else
pdf_print_int(pdf, obj_info(pdf, t));
- pdf_printf(pdf, ")\n");
+ pdf_out(pdf, ')');
}
void pdf_fix_thread(PDF pdf, int t)
@@ -166,23 +168,32 @@ void pdf_fix_thread(PDF pdf, int t)
tprint(" has been referenced but does not exist, replaced by a fixed one");
print_ln();
print_ln();
- a = pdf_new_dict(pdf, obj_type_others, 0, 0);
- pdf_indirect_ln(pdf, "T", t);
- pdf_indirect_ln(pdf, "V", a);
- pdf_indirect_ln(pdf, "N", a);
- pdf_indirect_ln(pdf, "P", pdf->last_page);
- pdf_printf(pdf, "/R [0 0 ");
- pdf_print_bp(pdf, page_width);
- pdf_out(pdf, ' ');
- pdf_print_bp(pdf, page_height);
- pdf_printf(pdf, "]\n");
+ a = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, a, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_dict_add_ref(pdf, "T", t);
+ pdf_dict_add_ref(pdf, "V", a);
+ pdf_dict_add_ref(pdf, "N", a);
+ pdf_dict_add_ref(pdf, "P", pdf->last_page);
+ pdf_add_name(pdf, "R");
+ pdf_begin_array(pdf);
+ pdf_add_int(pdf, 0);
+ pdf_add_int(pdf, 0);
+ pdf_add_bp(pdf, page_width);
+ pdf_add_bp(pdf, page_height);
+ pdf_end_array(pdf);
pdf_end_dict(pdf);
- pdf_begin_dict(pdf, t, 1);
- pdf_printf(pdf, "/I << \n");
+ pdf_end_obj(pdf);
+
+ pdf_begin_obj(pdf, t, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
+ pdf_add_name(pdf, "I");
+ pdf_begin_dict(pdf);
thread_title(pdf, t);
- pdf_printf(pdf, ">>\n");
- pdf_indirect_ln(pdf, "F", a);
pdf_end_dict(pdf);
+ pdf_dict_add_ref(pdf, "F", a);
+ pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
}
void out_thread(PDF pdf, int t)
@@ -193,7 +204,8 @@ void out_thread(PDF pdf, int t)
pdf_fix_thread(pdf, t);
return;
}
- pdf_begin_dict(pdf, t, 1);
+ pdf_begin_obj(pdf, t, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
a = obj_thread_first(pdf, t);
b = a;
last_attr = 0;
@@ -205,26 +217,29 @@ void out_thread(PDF pdf, int t)
if (last_attr != 0) {
pdf_print_ln(pdf, last_attr);
} else {
- pdf_printf(pdf, "/I << \n");
+ pdf_add_name(pdf, "I");
+ pdf_begin_dict(pdf);
thread_title(pdf, t);
- pdf_printf(pdf, ">>\n");
+ pdf_end_dict(pdf);
}
- pdf_indirect_ln(pdf, "F", a);
+ pdf_dict_add_ref(pdf, "F", a);
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
do {
- pdf_begin_dict(pdf, a, 1);
+ pdf_begin_obj(pdf, a, OBJSTM_ALWAYS);
+ pdf_begin_dict(pdf);
if (a == b)
- pdf_indirect_ln(pdf, "T", t);
- pdf_indirect_ln(pdf, "V", obj_bead_prev(pdf, a));
- pdf_indirect_ln(pdf, "N", obj_bead_next(pdf, a));
- pdf_indirect_ln(pdf, "P", obj_bead_page(pdf, a));
- pdf_indirect_ln(pdf, "R", obj_bead_rect(pdf, a));
+ pdf_dict_add_ref(pdf, "T", t);
+ pdf_dict_add_ref(pdf, "V", obj_bead_prev(pdf, a));
+ pdf_dict_add_ref(pdf, "N", obj_bead_next(pdf, a));
+ pdf_dict_add_ref(pdf, "P", obj_bead_page(pdf, a));
+ pdf_dict_add_ref(pdf, "R", obj_bead_rect(pdf, a));
pdf_end_dict(pdf);
+ pdf_end_obj(pdf);
a = obj_bead_next(pdf, a);
} while (a != b);
}
-
@ @c
void scan_thread_id(void)
{
@@ -260,15 +275,16 @@ void print_bead_rectangles(PDF pdf)
int l;
if ((k = get_page_resources_list(pdf, obj_type_bead)) != NULL) {
while (k != NULL) {
- l = pdf_new_obj(pdf, obj_type_others, 0, 1);
- pdf_out(pdf, '[');
+ l = pdf_create_obj(pdf, obj_type_others, 0);
+ pdf_begin_obj(pdf, l, OBJSTM_ALWAYS);
+ pdf_begin_array(pdf);
i = obj_bead_data(pdf, k->info); /* pointer to a whatsit or whatsit-like node */
- pdf_print_rect_spec(pdf, i);
+ pdf_add_rect_spec(pdf, i);
if (subtype(i) == pdf_thread_data_node) /* thanh says it mis be destroyed here */
flush_node(i);
- pdf_printf(pdf, "]\n");
- set_obj_bead_rect(pdf, k->info, l); /* rewrite |obj_bead_data| */
+ pdf_end_array(pdf);
pdf_end_obj(pdf);
+ set_obj_bead_rect(pdf, k->info, l); /* rewrite |obj_bead_data| */
k = k->link;
}
}
--- texk/web2c/luatexdir/pdf/pdftypes.h
+++ texk/web2c/luatexdir/pdf/pdftypes.h 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
/* pdftypes.h
- Copyright 2009-2010 Taco Hoekwater <taco@luatex.org>
+ Copyright 2009-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -25,6 +25,33 @@
# include <zlib.h>
# include "lua/luatex-api.h"
+/* The prefix "PTEX" for the PDF keys is special to pdfTeX;
+ this has been registered with Adobe by Hans Hagen. */
+
+# define pdfkeyprefix "PTEX"
+
+# define lround(a) (long) floor((a) + 0.5)
+
+# define MAX_OBJ_COMPRESS_LEVEL 3 /* maximum/clipping value for \pdfobjcompresslevel */
+# define OBJSTM_UNSET -1 /* initial value */
+# define OBJSTM_ALWAYS 1 /* \pdfobjcompresslevel >= OBJSTM_ALWAYS: put object into object stream */
+# define OBJSTM_NEVER (MAX_OBJ_COMPRESS_LEVEL + 1)
+ /* above maximum/clipping value for \pdfobjcompresslevel */
+
+typedef int internal_font_number; /* |font| in a |char_node| */
+
+typedef enum {
+ NO_ZIP, /* no \.{ZIP} compression */
+ ZIP_WRITING, /* \.{ZIP} compression being used */
+ ZIP_FINISH /* finish \.{ZIP} compression */
+} zip_write_state_e;
+
+typedef enum {
+ PDFOUT_BUF,
+ OBJSTM_BUF,
+ LUASTM_BUF
+} buffer_e;
+
/* This stucture holds everything that is needed for the actual pdf generation.
Because this structure interfaces with C++, it is not wise to use |boolean|
@@ -35,11 +62,6 @@ the types explicitly defined in this hea
|integer| and |eight_bits| that are used elsewhere in the \LUATEX\ sources.
*/
-typedef struct os_obj_data_ {
- int num;
- int off;
-} os_obj_data;
-
typedef struct {
long m; /* mantissa (significand) */
int e; /* exponent * -1 */
@@ -101,6 +123,7 @@ typedef struct {
pdffloat tj_delta; /* rel. movement in [(..)..]TJ array (glyph raster) */
pdffloat fs; /* font size in PDF units */
pdffloat fs_cur; /* to check if fs.m has changed and Tf needed */
+ pdffloat tm0_cur; /* to check if tm[0] has changed and Tm needed */
pdffloat cm[6]; /* cm array */
pdffloat tm[6]; /* Tm array */
double k1; /* conv. factor from TeX sp to PDF page raster */
@@ -110,6 +133,7 @@ typedef struct {
writing_mode wmode; /* PDF writing mode WMode (horizontal/vertical) */
pos_mode mode; /* current positioning mode */
int ishex; /* Whether the current char string is <> or () */
+ int need_tf; /* flag whether Tf needs to be set */
int need_tm; /* flag whether Tm needs to be set */
} pdfstructure;
@@ -176,9 +200,62 @@ typedef struct pdf_resource_struct_ {
int last_resources; /* halfword to most recently generated Resources object. */
} pdf_resource_struct;
+/**********************************************************************/
+
+typedef struct os_obj_data_ {
+ int num;
+ int off;
+} os_obj_data;
+
+typedef struct strbuf_s_ {
+ unsigned char *data; /* a PDF stream buffer */
+ unsigned char *p; /* pointer to the next character in the PDF stream buffer */
+ size_t size; /* currently allocated size of the PDF stream buffer, grows dynamically */
+ size_t limit; /* maximum allowed PDF stream buffer size */
+} strbuf_s;
+
+typedef struct os_struct_ {
+ os_obj_data *obj; /* array of object stream objects */
+ strbuf_s *buf[3];
+ buffer_e curbuf; /* select into which buffer to output */
+ luaL_Buffer b; /* Lua buffer connected to luastm_buf */
+ unsigned int cur_objstm; /* number of current object stream object */
+ unsigned int idx; /* index of object within object stream [1...PDF_OS_MAX_OBJS - 1] */
+ unsigned int ostm_ctr; /* statistics: counter for object stream objects */
+ unsigned int o_ctr; /* statistics: counter for objects within object streams */
+ int trigger_luastm;
+} os_struct;
+
+/**********************************************************************/
+
+# define packet_max_recursion 100 /* see |packet_cur_s| */
+# define packet_stack_size 100
+
+typedef struct packet_stack_record_ {
+ float c0;
+ float c1;
+ float c2;
+ float c3;
+ scaledpos pos; /* c4, c5 */
+} packet_stack_record;
+
+typedef struct vf_struct_ {
+ packet_stack_record *packet_stack; /* for "push" and "pop" */
+ int packet_stack_level;
+ int packet_stack_minlevel; /* to check stack underflow */
+ internal_font_number lf; /* local font number, resolved */
+ int fs_f; /* local font size */
+ int packet_cur_s; /* do_vf_packet() nesting level */
+ posstructure *refpos;
+ int vflua; /* flag, whether vf.*() functions are allowed */
+} vf_struct;
+
+/**********************************************************************/
+
typedef struct pdf_output_file_ {
FILE *file; /* the PDF output file handle */
char *file_name; /* the PDF output file name */
+ char *job_name;
output_mode o_mode; /* output mode (DVI/PDF/...) */
output_state o_state;
/* generation parameters */
@@ -197,24 +274,11 @@ typedef struct pdf_output_file_ {
int objcompresslevel; /* fixed level for activating PDF object streams */
char *job_id_string; /* the full job string */
- /* output file buffering */
- unsigned char *op_buf; /* the PDF output buffer */
- int op_buf_size; /* output buffer size (static) */
- int op_ptr; /* store for PDF buffer |pdf_ptr| while inside object streams */
- unsigned char *os_buf; /* the PDF object stream buffer */
- int os_buf_size; /* current size of the PDF object stream buffer, grows dynamically */
- int os_ptr; /* store for object stream |pdf_ptr| while outside object streams */
-
- os_obj_data *os_obj; /* array of object stream objects */
- int os_idx; /* pointer into |pdf_os_objnum| and |pdf_os_objoff| */
- int os_cntr; /* counter for object stream objects */
- int os_mode; /* true if producing object stream */
int os_enable; /* true if object streams are globally enabled */
- int os_cur_objnum; /* number of current object stream object */
+ os_struct *os; /* object stream structure pointer */
+
+ strbuf_s *buf; /* pointer to the current stream buffer (PDF stream, ObjStm, or Lua) */
- unsigned char *buf; /* pointer to the PDF output buffer or PDF object stream buffer */
- int buf_size; /* end of PDF output buffer or PDF object stream buffer */
- int ptr; /* pointer to the first unused byte in the PDF buffer or object stream buffer */
off_t save_offset; /* to save |pdf_offset| */
off_t gone; /* number of bytes that were flushed to output */
@@ -223,14 +287,13 @@ typedef struct pdf_output_file_ {
time_t start_time; /* when this job started */
char *start_time_str; /* minimum size for time_str is 24: "D:YYYYmmddHHMMSS+HH'MM'" */
- /* define fb_ptr, fb_array & fb_limit */
- char *fb_array;
- char *fb_ptr;
- size_t fb_limit;
+ strbuf_s *fb; /* pointer to auxiliary buffer for font stuff */
char *zipbuf;
z_stream *c_stream; /* compression stream pointer */
- int zip_write_state; /* which state of compression we are in */
+ zip_write_state_e zip_write_state; /* which state of compression we are in */
+ int stream_deflate; /* true, if stream dict has /Filter/FlateDecode */
+ int stream_writing; /* true while writing stream */
int pk_scale_factor; /* this is just a preprocessed value that depends on
|pk_resolution| and |decimal_digits| */
@@ -270,6 +333,8 @@ typedef struct pdf_output_file_ {
pdf_resource_struct *page_resources;
+ scaledpos page_size; /* width and height of page being shipped */
+
/* the variables from pdfdest */
int dest_names_size;
int dest_names_ptr;
@@ -290,6 +355,9 @@ typedef struct pdf_output_file_ {
int f_cur; /* TeX font number */
int pdflua_ref;
+ int cave; /* stay away from previous PDF object */
+
+ vf_struct *vfstruct;
} pdf_output_file;
typedef pdf_output_file *PDF;
--- texk/web2c/luatexdir/pdf/pdfxform.w
+++ texk/web2c/luatexdir/pdf/pdfxform.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% pdfxform.w
-% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2009-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -59,11 +59,11 @@ void pdf_place_form(PDF pdf, halfword p)
(void) calc_pdfpos(q, pdf->posstruct->pos);
cm[4] = q->cm[4];
cm[5] = q->cm[5];
- pdf_printf(pdf, "q\n");
+ pdf_puts(pdf, "q\n");
pdf_print_cm(pdf, cm);
pdf_printf(pdf, "/Fm%d", (int) obj_info(pdf, objnum));
pdf_print_resname_prefix(pdf);
- pdf_printf(pdf, " Do\nQ\n");
+ pdf_puts(pdf, " Do\nQ\n");
addto_page_resources(pdf, obj_type_xform, objnum);
}
--- texk/web2c/luatexdir/tex/align.w
+++ texk/web2c/luatexdir/tex/align.w 2011-10-13 07:39:33.000000000 +0000
@@ -967,6 +967,7 @@ value is changed to zero and so is the n
glue_set(q) = glue_set(p);
shift_amount(q) = o;
r = vlink(list_ptr(q));
+ assert (type(r) == unset_node);
s = vlink(list_ptr(p));
do {
/* Set the glue in node |r| and change it from an unset node */
--- texk/web2c/luatexdir/tex/commands.h
+++ texk/web2c/luatexdir/tex/commands.h 2011-10-13 07:39:32.000000000 +0000
@@ -266,6 +266,7 @@ typedef enum {
Omega_revision_code, /* command code for \.{\\Omegarevision} */
eTeX_revision_code, /* command code for \.{\\eTeXrevision} */
font_identifier_code, /* command code for \.{tex.fontidentifier} (virtual) */
+ font_id_code, /* command code for \.{\\fontid} */
} convert_codes;
typedef enum {
--- texk/web2c/luatexdir/tex/commands.w
+++ texk/web2c/luatexdir/tex/commands.w 2011-10-13 07:39:33.000000000 +0000
@@ -480,6 +480,7 @@ void initialize_commands(void)
primitive_omega("OmegaVersion", convert_cmd, omega_code, 0);
primitive_aleph("AlephVersion", convert_cmd, aleph_code, 0);
primitive_tex("fontname", convert_cmd, font_name_code, 0);
+ primitive_luatex("fontid", convert_cmd, font_id_code, 0);
primitive_pdftex("pdftexrevision", convert_cmd, pdftex_revision_code, 0);
primitive_luatex("luatexrevision", convert_cmd, luatex_revision_code, 0);
primitive_luatex("luatexdatestamp", convert_cmd, luatex_date_code, 0);
--- texk/web2c/luatexdir/tex/inputstack.w
+++ texk/web2c/luatexdir/tex/inputstack.w 2011-10-13 07:39:33.000000000 +0000
@@ -307,12 +307,13 @@ void show_context(void)
print_int(iname - 1);
print_char('>');
};
- } else if (iindex != in_open) { /* input from a pseudo file */
- tprint_nl("l.");
- print_int(line_stack[iindex + 1]);
} else {
tprint_nl("l.");
- print_int(line);
+ if (iindex == in_open) {
+ print_int(line);
+ } else { /* input from a pseudo file */
+ print_int(line_stack[iindex + 1]);
+ }
}
print_char(' ');
PSEUDO_PRINT_THE_LINE();
@@ -390,7 +391,7 @@ void push_input(void)
incr(input_ptr);
}
-@
+@
Here is a procedure that starts a new level of token-list input, given
a token list |p| and its type |t|. If |t=macro|, the calling routine should
set |name| and |loc|.
@@ -490,7 +491,7 @@ void back_input(void)
iloc = p; /* that was |back_list(p)|, without procedure overhead */
}
-@ Insert token |p| into \TeX's input
+@ Insert token |p| into \TeX's input
@c
int reinsert_token(boolean a, halfword pp)
{
@@ -585,7 +586,7 @@ void clear_for_error_prompt(void)
}
@ To get \TeX's whole input mechanism going, we perform the following
- actions.
+ actions.
@c
void initialize_inputstack(void)
@@ -685,7 +686,7 @@ static halfword string_to_pseudo(str_num
}
-@ The |pseudo_start| procedure initiates reading from a pseudo file.
+@ The |pseudo_start| procedure initiates reading from a pseudo file.
@c
void pseudo_from_string(void)
@@ -779,7 +780,7 @@ boolean pseudo_input(void)
return true;
}
-@ When we are done with a pseudo file we `close' it
+@ When we are done with a pseudo file we `close' it.
@c
void pseudo_close(void)
--- texk/web2c/luatexdir/tex/linebreak.w
+++ texk/web2c/luatexdir/tex/linebreak.w 2011-10-13 07:39:33.000000000 +0000
@@ -105,13 +105,6 @@ void line_break(boolean d, int line_brea
pack_begin_line = cur_list.ml_field; /* this is for over/underfull box messages */
vlink(temp_head) = vlink(cur_list.head_field);
new_hyphenation(temp_head, cur_list.tail_field);
- if ((!is_char_node(vlink(cur_list.head_field)))
- && ((type(vlink(cur_list.head_field)) == whatsit_node)
- && (subtype(vlink(cur_list.head_field)) == local_par_node)))
- paragraph_dir = local_par_dir(vlink(cur_list.head_field));
- else {
- assert(0); /* |paragraph_dir = 0|; */
- }
cur_list.tail_field = new_ligkern(temp_head, cur_list.tail_field);
if (is_char_node(cur_list.tail_field)) {
tail_append(new_penalty(inf_penalty));
@@ -127,12 +120,34 @@ void line_break(boolean d, int line_brea
final_par_glue = new_param_glue(par_fill_skip_code);
couple_nodes(cur_list.tail_field, final_par_glue);
cur_list.tail_field = vlink(cur_list.tail_field);
+#ifdef DEBUG
+ {
+ int n = temp_head;
+ fprintf(stdout, "pre_linebreak_filter status:\n");
+ while (n) {
+ fprintf(stdout, " %s node %d\n",
+ get_node_name(type(n), subtype(n)), (int) n);
+ n = vlink(n);
+ }
+ }
+#endif
lua_node_filter(pre_linebreak_filter_callback,
line_break_context, temp_head,
addressof(cur_list.tail_field));
last_line_fill = cur_list.tail_field;
pop_nest();
start_of_par = cur_list.tail_field;
+#ifdef DEBUG
+ {
+ int n = temp_head;
+ fprintf(stdout, "pre_linebreak_filter returned:\n");
+ while (n) {
+ fprintf(stdout, " %s node %d\n",
+ get_node_name(type(n), subtype(n)), (int) n);
+ n = vlink(n);
+ }
+ }
+#endif
callback_id = callback_defined(linebreak_filter_callback);
if (callback_id > 0) {
callback_id =
@@ -169,6 +184,12 @@ void line_break(boolean d, int line_brea
}
}
if (callback_id == 0) {
+ if ((!is_char_node(vlink(temp_head)))
+ && ((type(vlink(temp_head)) == whatsit_node)
+ && (subtype(vlink(temp_head)) == local_par_node)))
+ paragraph_dir = local_par_dir(vlink(temp_head));
+ else
+ assert(0); /* |paragraph_dir = 0|; */
ext_do_line_break(paragraph_dir,
int_par(pretolerance_code),
int_par(tracing_paragraphs_code),
--- texk/web2c/luatexdir/tex/mainbody.h
+++ texk/web2c/luatexdir/tex/mainbody.h 2011-10-13 07:39:33.000000000 +0000
@@ -96,7 +96,6 @@ typedef unsigned char glue_ord; /* infin
typedef unsigned short group_code; /* |save_level| for a level boundary */
-typedef int internal_font_number; /* |font| in a |char_node| */
typedef int font_index; /* index into |font_info| */
typedef int save_pointer;
--- texk/web2c/luatexdir/tex/mlist.w
+++ texk/web2c/luatexdir/tex/mlist.w 2011-10-13 07:39:33.000000000 +0000
@@ -2050,19 +2050,19 @@ static void make_over_delimiter(pointer
static void make_delimiter_over(pointer q, int cur_style)
{
pointer x, y, v; /* temporary registers for box construction */
- scaled shift_up, shift_down, clr, delta;
+ scaled shift_up, shift_down, clr, actual;
y = clean_box(nucleus(q), cur_style, cur_style);
x = flat_delimiter(left_delimiter(q),
cur_size + (cur_size == script_script_size ? 0 : 1),
width(y), cur_style);
left_delimiter(q) = null;
fixup_widths(x, y);
- shift_up = over_delimiter_bgap(cur_style);
+ shift_up = over_delimiter_bgap(cur_style)-height(x)-depth(x);
shift_down = 0;
clr = over_delimiter_vgap(cur_style);
- delta = clr - ((shift_up - depth(x)) - (height(y) - shift_down));
- if (delta > 0) {
- shift_up = shift_up + delta;
+ actual = shift_up - height(y);
+ if (actual < clr) {
+ shift_up = shift_up + (clr-actual);
}
v = wrapup_delimiter(x, y, q, shift_up, shift_down);
width(v) = width(x); /* this also equals |width(y)| */
@@ -2077,7 +2077,7 @@ static void make_delimiter_over(pointer
static void make_delimiter_under(pointer q, int cur_style)
{
pointer x, y, v; /* temporary registers for box construction */
- scaled shift_up, shift_down, clr, delta;
+ scaled shift_up, shift_down, clr, actual;
x = clean_box(nucleus(q), cur_style, cur_style);
y = flat_delimiter(left_delimiter(q),
cur_size + (cur_size == script_script_size ? 0 : 1),
@@ -2085,11 +2085,11 @@ static void make_delimiter_under(pointer
left_delimiter(q) = null;
fixup_widths(x, y);
shift_up = 0;
- shift_down = under_delimiter_bgap(cur_style);
+ shift_down = under_delimiter_bgap(cur_style) - height(y)-depth(y);
clr = under_delimiter_vgap(cur_style);
- delta = clr - ((shift_up - depth(x)) - (height(y) - shift_down));
- if (delta > 0) {
- shift_down = shift_down + delta;
+ actual = shift_down - depth(x);
+ if (actual<clr) {
+ shift_down += (clr-actual);
}
v = wrapup_delimiter(x, y, q, shift_up, shift_down);
width(v) = width(y); /* this also equals |width(y)| */
--- texk/web2c/luatexdir/tex/printing.w
+++ texk/web2c/luatexdir/tex/printing.w 2011-10-13 07:39:33.000000000 +0000
@@ -946,7 +946,7 @@ void print_file_line(void)
if (level == in_open)
print_int(line);
else
- print_int(line_stack[iindex + 1 - (in_open - level)]);
+ print_int(line_stack[level + 1]);
tprint(": ");
}
}
--- texk/web2c/luatexdir/tex/stringpool.w
+++ texk/web2c/luatexdir/tex/stringpool.w 2011-10-13 07:39:33.000000000 +0000
@@ -334,11 +334,11 @@ boolean get_strings_started(void)
return true;
}
-@ The string recycling routines. \TeX{} uses 2
- upto 4 {\it new\/} strings when scanning a filename in an \.{\\input},
- \.{\\openin}, or \.{\\openout} operation. These strings are normally
- lost because the reference to them are not saved after finishing the
- operation. |search_string| searches through the string pool for the
+@ The string recycling routines.
+ \TeX{} uses 2 upto 4 {\it new\/} strings when scanning a filename in an
+ \.{\\input}, \.{\\openin}, or \.{\\openout} operation. These strings are
+ normally lost because the reference to them are not saved after finishing
+ the operation. |search_string| searches through the string pool for the
given string and returns either 0 or the found string number.
@c
--- texk/web2c/luatexdir/tex/textoken.w
+++ texk/web2c/luatexdir/tex/textoken.w 2011-10-13 07:39:33.000000000 +0000
@@ -1,6 +1,6 @@
% textoken.w
%
-% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
% This file is part of LuaTeX.
@@ -19,8 +19,8 @@
@ @c
static const char _svn_version[] =
- "$Id: textoken.w 4032 2010-12-11 09:38:19Z taco $"
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/tex/textoken.w $";
+ "$Id: textoken.w 4315 2011-06-28 08:54:07Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/tex/textoken.w $";
#include "ptexlib.h"
@@ -1605,6 +1605,27 @@ void ins_the_toks(void)
ins_list(token_link(temp_token_head));
}
+@ This routine, used in the next one, prints the job name, possibly
+modified by the |process_jobname| callback.
+
+@c
+static void print_job_name(void)
+{
+ if (job_name) {
+ char *s, *ss; /* C strings for jobname before and after processing */
+ int callback_id, lua_retval;
+ s = (char*)str_string(job_name);
+ callback_id = callback_defined(process_jobname_callback);
+ if (callback_id > 0) {
+ lua_retval = run_callback(callback_id, "S->S", s, &ss);
+ if ((lua_retval == true) && (ss != NULL))
+ s = ss;
+ }
+ tprint(s);
+ } else {
+ print(job_name);
+ }
+}
@ Here is a routine that print the result of a convert command, using
the argument |i|. It returns |false | if it does not know to print
@@ -1654,7 +1675,7 @@ static boolean print_convert_string(half
print(format_name);
break;
case job_name_code:
- print(job_name);
+ print_job_name();
break;
case font_name_code:
append_string((unsigned char *) font_name(i),
@@ -1665,6 +1686,9 @@ static boolean print_convert_string(half
tprint("pt");
}
break;
+ case font_id_code:
+ print_int(i);
+ break;
case math_style_code:
print_math_style();
break;
@@ -1681,7 +1705,7 @@ static boolean print_convert_string(half
tprint("pt");
break;
case pdf_page_ref_code:
- print_int(get_obj(static_pdf, obj_type_page, i, false));
+ print_int(pdf_get_obj(static_pdf, obj_type_page, i, false));
break;
case pdf_xform_name_code:
print_int(obj_info(static_pdf, i));
@@ -1768,6 +1792,7 @@ void conv_toks(void)
case aleph_code:
break;
case font_name_code:
+ case font_id_code:
scan_font_ident();
break;
case pdftex_revision_code:
--- texk/web2c/luatexdir/utils/utils.h
+++ texk/web2c/luatexdir/utils/utils.h 2011-10-13 07:39:33.000000000 +0000
@@ -1,7 +1,7 @@
/* utils.h
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2011 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -43,7 +43,6 @@ int xfflush(FILE *);
int xgetc(FILE *);
int xputc(int, FILE *);
scaled ext_xn_over_d(scaled, scaled, scaled);
-char *stripzeros(char *);
void initversionstring(char **versions);
extern void check_buffer_overflow(int wsize);
extern void check_pool_overflow(int wsize);
--- texk/web2c/luatexdir/utils/utils.w
+++ texk/web2c/luatexdir/utils/utils.w 2011-10-13 07:39:33.000000000 +0000
@@ -46,10 +46,6 @@ static const char _svn_version[] =
#include "png.h"
-/* POPPLER_VERSION is defined in poppler-config.h for poppler from
- * the TeX Live tree, or in the Makefile for an installed version. */
-#include "poppler-config.h"
-
@ @c
#define check_nprintf(size_get, size_want) \
if ((unsigned)(size_get) >= (unsigned)(size_want)) \
@@ -178,8 +174,10 @@ void pdftex_fail(const char *fmt, ...)
__attribute__ ((format(printf, 1, 2)))
void pdftex_warn(const char *fmt, ...)
{
+ int old_selector = selector;
va_list args;
va_start(args, fmt);
+ selector = term_and_log;
print_ln();
tex_printf("LuaTeX warning");
if (cur_file_name)
@@ -189,6 +187,7 @@ void pdftex_warn(const char *fmt, ...)
tprint(print_buf);
va_end(args);
print_ln();
+ selector = old_selector;
}
@ @c
@@ -273,6 +272,7 @@ scaled ext_xn_over_d(scaled x, scaled n,
@ function strips trailing zeros in string with numbers;
leading zeros are not stripped (as in real life)
@c
+#if 0
char *stripzeros(char *a)
{
enum { NONUM, DOTNONUM, INT, DOT, LEADDOT, FRAC } s = NONUM, t = NONUM;
@@ -339,6 +339,7 @@ char *stripzeros(char *a)
*q = '\0';
return a;
}
+#endif
@ @c
void initversionstring(char **versions)
@@ -346,9 +347,11 @@ void initversionstring(char **versions)
(void) asprintf(versions,
"Compiled with libpng %s; using libpng %s\n"
"Compiled with zlib %s; using zlib %s\n"
- "Compiled with poppler version %s\n",
+ "Compiled with poppler version %d.%d.%d\n",
PNG_LIBPNG_VER_STRING, png_libpng_ver,
- ZLIB_VERSION, zlib_version, POPPLER_VERSION);
+ ZLIB_VERSION, zlib_version,
+ poppler_version_major(), poppler_version_minor(),
+ poppler_version_micro());
}
@ @c