%!PS
% $Header: /cvsroot/html2ps/postscript/header.ps,v 1.1 2005/12/18 07:21:38 Konstantin Exp $
/DeviceRGB setcolorspace
/cm {28.34 mul} def
/mm {2.834 mul} def
/rounding-epsilon 0.001 def
/default-font /Times-Roman findfont def
% User settings
##PAGE##
##PT##
##PS2PDF##
##TRANSPARENCY##
##IMAGEQUALITY##
/setting-debug-box ##DEBUGBOX## def
/setting-draw-page-border ##PAGEBORDER## def
/real-page-height { pageheight tmargin sub bmargin sub } def
/real-page-width { pagewidth lmargin sub rmargin sub } def
% We need to call init page now, unless PS2PDF will incorrecly determine th orientation of the very first PDF page
initpage
% MAX and MIN functions are build-ins in ghostscript;
% Adobe distiller (and, well, most other PS interpreters) will require
% the definition of MIN and MAX
currentdict /max known not {
/max { 2 copy lt { exch } if pop } def
} if
currentdict /min known not {
/min { 2 copy gt { exch } if pop } def
} if
/normalize { % => Array
dup sum
1 exch div
map-scale
} def
/map-scale { % => Array Scale
/mul cvx
/exch cvx
/array-append
cvx % => Array Scale mul exch array-prepend
4 array astore
cvx % => Array {Scale mul array-prepend}
[] % => Array {Scale mul array-prepend} []
3 2 roll % => {Scale mul array-prepend} [] Array
reduce
} def
/reduce-max {
{max} 0 % => Array {max} 0
3 2 roll % => {max} 0 Array
reduce % => Max
} def
/in-zip-with { % => Data A B Fun
1 index length 0 gt {
2 index 0 get % => Data A B Fun A0
2 index 0 get % => Data A B Fun A0 B0
2 index exec % => Data A B Fun (A0 Fun B0)
5 2 roll array-pop-first % => Fun (A0 Fun B0) Data A B'
5 1 roll array-pop-first % => B' Fun (A0 Fun B0) Data A'
5 1 roll array-prepend % => A' B' Fun Data'
4 1 roll % => Data' A' B' Fun
in-zip-with
} {
pop pop pop
} ifelse
} def
/zip-with { % => A B Fun
[] 4 1 roll % => [] A B Fun
in-zip-with
} def
/font-underline-thick { % => <>
dup /FontInfo get
% some fonts (especially when you're using Adobe Distiller) do not contain /UnderlinePosition.
dup /UnderlineThickness known {
/UnderlineThickness get
} {
pop 1 px
} ifelse % => <> UT
exch /FontMatrix get
transform
exch pop % => UT
} def
% Table helpers
/in-array-extend { % => Left Value Array
2 index 0 gt {
2 copy % => Left Value Array Value Array
array-prepend % => Left Value Array Array'
exch pop % => Left Value Array'
3 2 roll % => Value Array' Left
1 sub % => Value Array' Left-1
3 1 roll % => Left Value Array'
in-array-extend % => Array'
} {
3 1 roll % => Array Left Value
pop pop % => Array
} ifelse
} def
/array-extend { % => Array Size DefValue
2 index length % => Array Size DefValue ALen
2 index exch sub % => Array Size DefValue Size-ALen
1 index % => Array Size DefValue Size-ALen DefValue
4 index % => Array Size DefValue Size-ALen DefValue Array
in-array-extend % => Array Size DefValue Array'
4 1 roll % => Array' Array Size DefValue
pop pop pop % => Array'
} def
% height constraint priority
/hc-lt { % => C1 C2
1 index
array-last
/wc-none cvx eq {
pop pop true
} {
1 index array-last
/hc-constant cvx eq {
dup array-last
/wc-none cvx ne
exch pop
exch pop
} {
dup array-last
/wc-fraction cvx eq
exch pop
exch pop
} ifelse
} ifelse
} def
% priority: percentage, absolute, no-constraint
/row-get-height-constraint { % => Row
{ % =>
get-height-constraint
exch
array-append
}
[]
2 index
reduce
exch pop % => CellHCs
{
2 copy
hc-lt {
exch pop
} {
pop
} ifelse
}
{wc-none}
2 index
reduce
exch pop % => HCWithMostPriority
} def
/table-get-colspans { % => Table
get-content % => Content
3 get % => Colspans
} def
/table-get-rowspans { % => Table
get-content % => Content
4 get % => Rowspans
} def
/table-put-colspans { % => Colspans Table
get-content % => Colspans Content
3 % => Colspans Content 3
3 2 roll % => Content 3 Colspans
put % =>
} def
/table-put-rowspans { % => Rowspans Table
get-content % => Colspans Content
4 % => Colspans Content 3
3 2 roll % => Content 3 Rowspans
put % =>
} def
/table-add-colspan { % => SpanSize CurRow CurColumn Table
4 1 roll % => Table SpanSize CurRow CurColumn
3 array astore % => Table NewSpan
1 index % => Table NewSpan Table
table-get-colspans % => Table NewSpan Colspans
array-append % => Table Colspans'
exch
table-put-colspans % =>
} def
/table-add-rowspan { % => SpanSize CurRow CurColumn Table
4 1 roll % => Table SpanSize CurRow CurColumn
3 array astore % => Table NewSpan
1 index % => Table NewSpan Table
table-get-rowspans % => Table NewSpan Colspans
% determine index to place new rowspan to
{ % => ... [CColumn Index] [Sz Row Col]
1 index 0 get % => ... [CColumn Index] [Sz Row Col] CColumn
1 index 2 get % => ... [CColumn Index] [Sz Row Col] CColumn Col
ge {
pop
dup 1 get % => ... [CColumn Index] Index
1 add
1 index exch
1 exch put % => ... [CColumn Index+1]
} {
pop % => ... [CColumn Index]
} ifelse
}
2 index 2 get
0
2 array astore % => Table NewSpan Colspans [CColumn 0]
2 index
reduce % => Table NewSpan Colspans [CColumn Index]
1 get % => Table NewSpan Colspans Index
3 1 roll % => Table Index NewSpan Rowspans
array-insert % => Table Rowspans'
exch
table-put-rowspans % =>
} def
/replicate-row { % => Length Length
dup 0 gt {
% make 'fake' cells to pad table row to the desired length
box-block-create
% => Length Length []
3 1 roll % => [] Length Length
1 sub % => [] Length Length-1
replicate-row
} if
} def
/render-background-image-transparent {
2 index /Mask get % => Box ImageDict W H Mask
3 index /Samples get % => Box ImageDict W H Mask Samples
4 index /XRepeat known
{
5 index get-width-padded % => Box ImageDict W H Mask Sample WP
4 index px div ceiling cvi % => Box ImageDict W H Mask Sample HRepeats
} {
1
} ifelse % => Box ImageDict W H Mask Sample HRepeats
5 index /YRepeat known
{
6 index get-height-padded % => Box ImageDict W H Mask Sample HRepeats HP
4 index px div ceiling cvi % => Box ImageDict W H Mask Sample HRepeats VRepeats
} {
1
} ifelse % => Box ImageDict W H Mask Sample HRepeats VRepeats
{ % => Box ImageDict W H Mask Samples HRepeats
currentpoint % => Box ImageDict W H Mask Samples HRepeats X Y
exch pop % => Box ImageDict W H Mask Samples HRepeats Y
7 index get-left-padded % => Box ImageDict W H Mask Samples HRepeats Y X
exch moveto % => Box ImageDict W H Mask Samples HRepeats
0 4 index px neg rmoveto
dup
{ % => Box ImageDict W H Mask Samples HRepeats
5 1 roll % => Box ImageDict HRepeats W H Mask Samples
4 copy % => Box ImageDict HRepeats W H Mask Samples W H Mask Samples
4 2 roll % => Box ImageDict HRepeats W H Mask Samples Mask Samples W H
2 copy % => Box ImageDict HRepeats W H Mask Samples Mask Samples W H W H
6 2 roll px 6 1 roll px
6 1 roll % => Box Image Dict HRepeats W H Mask Samples W H W H Mask Samples
11 index /Init get
show-transparent-image % => Box Image Dict HRepeats W H Mask Samples
5 4 roll % => Box Image Dict W H Mask Samples HRepeats
4 index px 0 rmoveto
} repeat
} repeat
pop pop pop pop pop pop
} def
/render-background-image {
2 index /Samples get % => Box ImageDict W H Samples
3 index /XRepeat known
{
4 index get-width-padded % => Box ImageDict W H Sample WP
3 index px div ceiling cvi % => Box ImageDict W H Sample HRepeats
} {
1
} ifelse % => Box ImageDict W H Sample HRepeats
4 index /YRepeat known
{
5 index get-height-padded % => Box ImageDict W H Sample HRepeats HP
3 index px div ceiling cvi % => Box ImageDict W H Sample HRepeats VRepeats
} {
1
} ifelse % => Box ImageDict W H Sample HRepeats VRepeats
{ % => Box ImageDict W H Samples HRepeats
currentpoint % => Box ImageDict W H Samples HRepeats X Y
exch pop % => Box ImageDict W H Samples HRepeats Y
6 index get-left-padded % => Box ImageDict W H Samples HRepeats Y X
exch moveto % => Box ImageDict W H Samples HRepeats
0 3 index px neg rmoveto
dup
{ % => Box ImageDict W H Samples HRepeats
4 1 roll % => Box ImageDict HRepeats W H Samples
3 copy % => Box ImageDict HRepeats W H Samples W H Samples
3 1 roll % => Box ImageDict HRepeats W H Samples Samples W H
2 copy % => Box ImageDict HRepeats W H Samples Samples W H W H
5 2 roll px 5 1 roll px
5 1 roll % => Box Image Dict HRepeats W H Samples W H W H Samples
9 index /Init get
show-image % => Box Image Dict HRepeats W H Samples
4 3 roll % => Box Image Dict W H Samples HRepeats
3 index px 0 rmoveto
} repeat
} repeat
pop pop pop pop pop
} def
% Show absolute positioned boxes layer
/show-box-absolute {
dup is-static not {
show-box-force
} if
} def
% Displaying data
/show-text { % => Text FontSize FontName
findfont
exch % => Text FontSize
scalefont % => Text
setfont % => Text
show % =>
} def
/in-add-table-row { % => Box
dup get-content % => Box [Cols Rows Content](RawContent)
dup 1 get 1 add % => Box [Cols Rows Content](RawContent) Rows+1
1 index exch
1 exch put % => Box [Cols Rows+1 Content](RawContent)
dup 2 get % => Box [Cols Rows+1 Content](RawContent) Content
aload length % => Box [Cols Rows+1 Content](RawContent) Row1 .. RowN N
1 add % => Box [Cols Rows+1 Content](RawContent) Row1 .. RowN N+1
[] % => Box [Cols Rows+1 Content](RawContent) Row1 .. RowN N+1 []
exch % => Box [Cols Rows+1 Content](RawContent) Row1 .. RowN [] N+1
array astore % => Box [Cols Rows+1 Content](RawContent) NewContent
2 exch put
} def
/add-table-row { % => Box
dup is-table {
in-add-table-row
} if
} def
% BOX getters
/get-real-height { 1 get } def
/get-parent-height-fraction { % => Box Fraction
1 index get-box-dict
/Parent known {
1 index get-box-dict /Parent get
get-height
mul
exch pop
} {
% if it is the top-level box, just return its own height
pop get-height
} ifelse
} def
/get-max-height {
dup get-box-dict % => Box HB
/Height get
dup /MaxPercentage get {
/Max get
1 index exch
get-parent-height-fraction
} {
/Max get
} ifelse
exch pop
} def
% Compatibility with old code function;
% generates old-fashined height-constraint function using min-height data
/get-color { get-color-array aload pop } def
/get-background-color { get-background aload pop } def
% BOX setters
/put-td-dict { exch 26 exch put } def
/put-vertical-align { exch 25 exch put } def
/put-local-align { exch 24 exch put } def
%/put-valign { exch 22 exch put } def
/put-z-index { exch 21 exch put } def
/put-background-image-transparent {
% => [W H Mask Samples Init] Box
get-background-image % => [W H Mask Samples Init] Dict
dup /W 3 index 0 get put % => [W H Mask Samples Init] Dict(W)
dup /H 3 index 1 get put % => [W H Mask Samples Init] Dict(W H)
dup /Mask 3 index 2 get put % => [W H Mask Samples Init] Dict(W H Mask)
dup /Samples 3 index 3 get put % => [W H Mask Samples Init] Dict(W H Mask Samples)
dup /Init 3 index 4 get put
pop pop
} def
/put-background-image { % => [W H Samples Init] Box
get-background-image % => [W H Samples Init] Dict
dup /W 3 index 0 get put % => [W H Samples Init] Dict(W)
dup /H 3 index 1 get put % => [W H Samples Init] Dict(W H)
dup /Samples 3 index 2 get put % => [W H Samples Init] Dict(W H Samples)
dup /Init 3 index 3 get put
pop pop
} def
/put-position { exch 18 exch put } def
/put-color-array { exch 14 exch put } def
/put-text-align { exch 13 exch put } def
/put-background { exch 12 exch put } def
/put-display { exch 8 exch put } def
/put-color { 4 1 roll 3 array astore exch put-color-array } def
/put-background-color { 4 1 roll 3 array astore exch put-background } def
/put-full-width-force { % => Width Element
dup get-hor-extra % => Width Element Padding+Margin+Border
3 2 roll % => Element Padding+Margin+Border Width
exch sub % => Element Width
exch % => Width Element
put-width
} def
/put-full-height { % => Height Element
dup get-vert-extra % => Height Element Padding+Margin+Border
3 2 roll % => Element Padding+Margin+Border Height
exch sub % => Element Height'
exch % => Height'' Element
put-height
} def
/in-get-table-content { % => Data Content Rows
dup 0 gt {
2 copy % => Data Content Rows Content Rows
1 sub get % => Data Content Rows Row
aload length % => Data Content Rows Cell1 .. CellN N
dup 3 add % => Data Content Rows Cell1 .. CellN N N+4
index % => Data Content Rows Cell1 .. CellN N Data
aload length % => Data Content Rows Cell1 .. CellN N Data1 .. DataM M
dup 2 add % => Data Content Rows Cell1 .. CellN N Data1 .. DataM M M+2
dup 1 sub % => Data Content Rows Cell1 .. CellN N Data1 .. DataM M M+2 M+1
roll % => Data Content Rows Cell1 .. CellN Data1 .. DataM M N
add % => Data Content Rows Cell1 .. CellN Data1 .. DataM M+N
array astore % => Data Content Rows NewData
4 3 roll pop % => Content Rows NewData
3 1 roll % => NewData Content Rows
1 sub
in-get-table-content
} {
pop pop
} ifelse
} def
/get-table-content { % => Box
dup
get-table-content-rows % => Box Content
1 index get-content % => Box Content RawContent
1 get % => Box Content Rows
[] % => Box Content Rows []
4 3 roll pop % => Content Rows []
3 1 roll % => [] Content Rows
in-get-table-content
} def
/get-table-content-rows { % => Box
get-content % => RawContent
2 get % => Content
} def
/get-table-content-column { % => Box ColumnNo
exch get-content % => ColumnNo Content
dup 1 get exch % => ColumnNo RowsNum Content
2 get % => ColumnNo RowsNum Rows
{ % => ColumnNo RowsNum Row
2 index get % => ColumnNo RowsNum Cell
3 1 roll % => Cell ColumnNo RowsNum
} forall % => Cell1 .. CellN ColumnNo N
exch pop % => Cell1 .. CellN N
array astore % => Column
} def
/get-table-content-columns { % => Box
dup get-content % => Box [Cols Rows Content]
0 get 1 sub % => Box Cols-1
[] % => Box Cols []
in-get-table-content-columns % => ColsList
} def
/in-get-table-content-columns { % => Box ColsIndex ColsList
1 index 0 ge {
3 1 roll % => ColsList Box ColsIndex
2 copy % => ColsList Box ColsIndex Box ColsIndex
get-table-content-column % => ColsList Box ColsIndex Column
4 1 roll % => Column ColsList Box ColsIndex
1 sub % => Column ColsList Box ColsIndex-1
4 2 roll % => Box ColsIndex-1 Column ColsList
array-append % => Box ColsIndex-1 ColsList'
in-get-table-content-columns
} {
3 1 roll
pop pop
} ifelse
} def
/table-get-cell-content { % => R C Box
% One based idices are passed
get-table-content-rows % => R C Rows
2 index 1 sub get % => R C Row
1 index 1 sub get % => R C Cell
3 1 roll pop pop % => Cell
} def
/rmove-current-point { % => Box DX DY
2 index get-current-y add % => Box DX DY'
2 index put-current-y % => Box' DX
1 index get-current-x add % => Box' DX'
1 index put-current-x % => Box''
} def
/safe-div { % => A B
dup 0 % => A B B 0
eq { % => A B
pop 1 % => A 1
} if
div
} def
/find-best-column { % => Width MinWidths MaxWidths
dup sum % => Width MinWidths MaxWidths MaxWidth
3 index % => Width MinWidths MaxWidths MaxWidth Width
exch safe-div % => Width MinWidths MaxWidths Width/MaxWidth(WK)
3 1 roll % => Width WK MinWidths MaxWidths
2 copy {safe-div} zip-with % => Width WK MinWidths MaxWidths [MinI/MaxI]
dup reduce-max % => Width WK MinWidths MaxWidths [MinI/MaxI] MAX[MinI/MaxI]
4 index gt { % => Width WK MinWidths MaxWidths [MinI/MaxI]
dup reduce-max % => Width WK MinWidths MaxWidths [MinI/MaxI] MaxKoeff
array-find % => Width WK MinWidths MaxWidths MaxKoeffIndex
2 index 1 index get % => Width WK MinWidths MaxWidths MaxKoeffIndex SW
6 2 roll % => MaxKoeffIndex SW Width WK MinWidths MaxWidths
pop pop pop pop % => MaxKoeffIndex SW
} { % => Width WK MinWidths MaxWidths [MinI/MaxI]
pop % => Width WK MinWidths MaxWidths
3 2 roll % => Width MinWidths MaxWidths WK
1 index 0 get mul % => Width MinWidths MaxWidths W*WidthKoeff
2 index 0 get % => Width MinWidths MaxWidths W*WidthKoeff MinW
max % => Width MinWidths MaxWidths SelectedWidth
0 exch % => Width MinWidths MaxWidths 0 SelectedWidth
5 2 roll % => 0 SelectedWidth Width MinWidths MaxWidths
pop pop pop
} ifelse
} def
/is-fraction { % => WC
aload % => X ... X WC
1 index /wc-fraction eq
2 index /hc-fraction eq or {
astore pop true
} {
astore pop false
} ifelse
} def
/array-reverse {
{
exch array-prepend
} [] 2 index reduce
exch pop
} def
/table-normalize-cwc { % => Box
/temp-table-normalize-cwc 1 def
{ % => ... CVal Val
dup is-fraction { % => ... CVal Val
aload pop pop % => ... CVal Fraction
temp-table-normalize-cwc
min % => ... CVal Fraction'
temp-table-normalize-cwc
1 index sub % => ... CVal Fraction' Rest
/temp-table-normalize-cwc
exch def % => ... CVal Fraction'
/wc-fraction cvx
2 array astore cvx % => ... CVal WC'
} if
exch array-prepend % => ... CVal
} [] 2 index table-get-cwc array-reverse
reduce % => Box CWC'
exch pop
} def
/calc-text-indent { % => Box
dup get-box-dict
/Text-Indent get
dup /Relative get { % => Box TIDict
/Value get
1 index get-width
mul
} {
/Value get
} ifelse % => Box Indent
% add special offset (for example, if we have marker box with position: inside)
1 index get-box-dict
/AdditionalTextIndent get
add
exch pop
} def
/flow-page-break { % => Parent Child
1 index get-current-x
2 index get-current-y % => Parent Child X Y
2 index
move-to-box % => Parent Child
1 index get-width % => Parent Child PW
1 index put-full-width % => Parent Child
% Setup height for the "fake" box
1 index get-current-y % => Parent Child PCY
bmargin sub
real-page-height sub neg
real-page-height div
ceiling % => Parent Child Pages
real-page-height mul
neg % => Parent Child EndOfLastPage0
real-page-height add % => Parent Child EndOfLastPage
2 index get-current-y
bmargin sub
exch sub
1 index put-height
% we're now interested in last content y, not the bottom border of the containing
% block, because, due the min-height, bottom border can contain lesser (lower on the page)
% value than current y
% 1 index get-bottom-internal
dup get-height
2 index exch % => Parent Child Parent CH
extend-height pop % => Parent Child
dup get-top
1 index get-height
sub
2 index
put-current-y
pop
dup get-right-internal
1 index put-current-x
dup close-line
pop
} def