Tform - clippath pathbbox 4 2 roll pop pop % MaxLen (V) Ff Q dx dy currentfont /ScaleMatrix .knownget { 3 get } { 1 } ifelse % MaxLen (V) Ff Q dx dy yy currentfont /FontBBox .knownget not { currentfont dup /FontType get 0 eq { /FDepVector get 0 get /FontBBox get} { pop //null % force an error } ifelse }if dup 1 get neg exch 3 get % MaxLen (V) Ff Q dx dy yy desc asc dup 0 ne { div } { pop pop 0 } ifelse % MaxLen (V) Ff Q dx dy yy desc/asc 1 index mul % MaxLen (V) Ff Q dx dy yy desc/asc*yy %% Check if this is declared as a multiine text widget, and if it is %% check that the string has at least 2 characters, so we can split it %% into at least two strings.... %% Bug #687498.pdf has a multiline text widget with an empty string (amongst %% many other problems with this file). 5 index 16#1000 and 0 ne 7 index length 1 gt and{ % multiline %% First lets see how many lines we have, make a copy of the string 6 index mark exch .splitstring % MaxLen (V) Ff Q dx dy yy desc/asc*yy [ () () ... counttomark 1 add 4 add index % MaxLen (V) Ff Q dx dy yy desc/asc*yy [ () () ... count Q dup 0 eq { pop % remove extra copy of Q counttomark dup 2 add 2 add index exch div % MaxLen (V) Ff Q dx dy yy desc/asc*yy [ () () ... line_height counttomark 1 add 1 roll % MaxLen (V) Ff Q dx dy yy desc/asc*yy line_height [ () () ... 2 0 moveto % start at bottom left of rect counttomark 1 1 3 -1 roll { % for every string pop gsave anchorsearch { pop } { anchorsearch { pop } if } ifelse Show grestore % pop loop counter, show string (saving current point) counttomark 1 add index 0 exch rmoveto % get line height, move that amount vertically. } for pop pop }{ 1 eq { counttomark dup 2 add 2 add index exch div % MaxLen (V) Ff Q dx dy yy desc/asc*yy [ () () ... line_height counttomark 1 add 1 roll % MaxLen (V) Ff Q dx dy yy desc/asc*yy line_height [ () () ... 2 0 moveto % start at bottom left of rect counttomark 1 1 3 -1 roll { % for every string pop gsave % pop loop counter anchorsearch { pop } { anchorsearch { pop } if } ifelse dup stringwidth pop counttomark 5 add index % get rectangle width exch sub 2 div 0 rmoveto % subtract width of string, divide by 2 move that amount Show grestore % show string counttomark 1 add index 0 exch rmoveto % get line height, move that amount vertically. } for pop pop }{ counttomark dup 2 add 2 add index exch div % MaxLen (V) Ff Q dx dy yy desc/asc*yy [ () () ... line_height counttomark 1 add 1 roll % MaxLen (V) Ff Q dx dy yy desc/asc*yy line_height [ () () ... 2 0 moveto % start at bottom left of rect counttomark 1 1 3 -1 roll { % for every string pop gsave % pop loop counter anchorsearch { pop } { anchorsearch { pop } if } ifelse dup stringwidth pop counttomark 5 add index % get rectangle width exch sub 2 sub 0 rmoveto % subtract width of string,move that amount Show grestore % show string counttomark 1 add index 0 exch rmoveto % get line height, move that amount vertically. } for pop pop }ifelse }ifelse 8 { pop } repeat } { 5 index 16#1000000 and 0 ne { % comb 6 index type /stringtype eq { 6 index length 0 gt { 6 index length 8 index % length of V and MaxLength gt { (Comb field with /V string which exceeds /MaxLength. Ignoring field.) = 8 {pop} repeat }{ 3 index 8 index div % field Rect width / MaxLength, the offset between 'comb' boxes 7 index anchorsearch { pop } { anchorsearch { pop } if } ifelse { currentpoint newpath moveto % new path, preserving currnt point currentpoint % store the current point, this is the origin for the next 'comb' 3 -1 roll 1 string dup 3 -1 roll exch 0 3 -1 roll put % turn the character code into a 1 byte string dup gsave false charpath flattenpath pathbbox grestore % get the bounding box of that character 3 -1 roll sub 3 1 roll exch sub % get its width and height (ch, cw) 8 index 6 index % comb box width and height (bh, bw) 3 -1 roll % ch cw bh bw -> ch bh bw cw sub 2 div % ch bh (bw - cw) / 2 = ch bh dw 3 1 roll % ch bh dw -> dw ch bh exch sub 2 div % dw (bh - ch) /2 = dw dh rmoveto % centers character in box Show exch 2 index add exch moveto % Draw the character } forall % repeat for every character in the original string 9 {pop} repeat % discard the various arguments }ifelse }{ 8 {pop} repeat % discard the parameters }ifelse }{ (Comb field with a non-string /V value is illegal. Ignoring field.) = 8 {pop} repeat } ifelse } { % plain text 3 1 roll sub add 2 div % MaxLen (V) Ff Q dx (dy-yy+desc)/2 0 exch moveto % MaxLen (V) Ff Q dx 1 index 0 ne { 3 index anchorsearch { pop } { anchorsearch { pop } if } ifelse stringwidth pop % MaxLen (V) Ff Q dx w sub exch 1 eq { 2 div } { 2 sub } ifelse % MaxLen (V) Ff (dx-w)/2 0 rmoveto % MaxLen (V) Ff pop % MaxLen (V) } { pop pop pop % MaxLen (V) 2 0 rmoveto } ifelse exch pop anchorsearch { pop } { anchorsearch { pop } if } ifelse Show % - } ifelse } ifelse } bind executeonly def end readonly put % GS_PDF_ProcSet .setglobal