/*
 * FSBwraps.psw
 *
 * (c) Copyright 1991-1994 Adobe Systems Incorporated.
 * All rights reserved.
 * 
 * Permission to use, copy, modify, distribute, and sublicense this software
 * and its documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notices appear in all copies and that
 * both those copyright notices and this permission notice appear in
 * supporting documentation and that the name of Adobe Systems Incorporated
 * not be used in advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.  No trademark license
 * to use the Adobe trademarks is hereby granted.  If the Adobe trademark
 * "Display PostScript"(tm) is used to describe this software, its
 * functionality or for any other purpose, such use shall be limited to a
 * statement that this software works in conjunction with the Display
 * PostScript system.  Proper trademark attribution to reflect Adobe's
 * ownership of the trademark shall be given whenever any such reference to
 * the Display PostScript system is made.
 * 
 * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
 * ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
 * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NON- INFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO EVENT SHALL ADOBE BE LIABLE
 * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  ADOBE WILL NOT
 * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
 * 
 * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
 * Incorporated which may be registered in certain jurisdictions
 * 
 * Author:  Adobe Systems Incorporated
 */

defineps _DPSFClearWindow(DPSContext ctxt)
    1 setgray
    0 0 2000 2000 rectfill
endps

defineps _DPSFPreviewString(DPSContext ctxt; char *font; float size;
			  char *text; int height | boolean *bogus)
    mark {
	/font size selectfont
	0 height neg 5 div itransform
	exch pop 5 exch moveto
	0 setgray
	(text) show
    } stopped bogus cleartomark
endps

defineps _DPSFReclip(DPSContext ctxt)
    initclip
    initviewclip
endps

defineps _DPSFUndefineFont(DPSContext ctxt; char *font; boolean oldServer)
    currentshared true setshared		% currentshared
	{/font undefinefont} stopped 		% currentshared [font] stopped
	{
	    false setshared			% currentshared font
	    {undefinefont} stopped {
		pop
	    } if
	} if
    setshared
    oldServer { 2 vmreclaim } if
endps

defineps _DPSFDefineFontEnumFunctions(DPSContext ctxt)
    $Adobe$DPS$Lib$Dict begin
	/GetFontName {          % int GetFontName string
            $Adobe$DPS$Lib$Dict /FontDict get begin
                dup maxItems div truncate cvi baseArray exch get
                exch maxItems mod get
            end
        } bind def

	% (str) x y 	SafeBBox	 left bottom right top
	/SafeBBox {
	    3 copy				% (str) x y (str) x y
	    newpath
	    moveto				% (str) x y (str)
	    {
		mark exch false charpath flattenpath pathbbox
	    } stopped {
		cleartomark
		3 -1 roll dup length dup	% x y (str) len len
		1 le {
		    pop
		    % punt; we can't divide it any more
		    0 0 moveto stringwidth pop 	% x y wx
		    dup 2 index add exch 3 index add exch
		} {
		    2 copy			% x y (str) len (str) len
		    2 idiv 			% x y (str) len (str) len/2
		    0 exch			% x y (str) len (str) 0 len/2
		    getinterval	dup		% x y (str) len (s1) (s1)
		    5 index 5 index		% x y (str) len (s1) (s1) x y
		    $Adobe$DPS$Lib$Dict /SafeBBox get exec
					% x y (str) len (s1) l1 b1 r1 t1
		    9 4 roll		% l1 b1 r1 t1 x y (str) len (s1)
		    stringwidth			% ... x y (str) len wx wy
		    5 -1 roll add exch		% ... x (str) len y+wy wx
		    5 -1 roll add exch		% ... (str) len x+wx y+wy
		    4 2 roll			% ... x+wx y+wy (str) len
		    dup 2 idiv			% ... x+wx y+wy (str) len len/2
		    exch 2 div ceiling cvi
					% ... x+wx y+wy (str) len/2 ceil(len/2)
		    getinterval			% ... x+wx y+wy (s2)
		    3 1 roll 			% ... (s2) x+wx y+wy
		    $Adobe$DPS$Lib$Dict /SafeBBox get exec
						% l1 b1 r1 t1 l2 b2 r2 t2
		    5 -1 roll 2 copy		% l1 b1 r1 l2 b2 r2 t2 t1 t2 t1
		    gt {pop} {exch pop} ifelse	% l1 b1 r1 l2 b2 r2 t
		    7 1 roll			% t l1 b1 r1 l2 b2 r2
		    4 -1 roll 2 copy		% t l1 b1 l2 b2 r2 r1 r2 r1
		    gt {pop} {exch pop} ifelse	% t l1 b1 l2 b2 r
		    6 1 roll			% r t l1 b1 l2 b2
		    3 -1 roll 2 copy		% r t l1 l2 b2 b1 b2 b1
		    lt {pop} {exch pop} ifelse	% r t l1 l2 b
		    5 1 roll			% b r t l1 l2
		    2 copy			% b r t l1 l2 l1 l2
		    lt {pop} {exch pop} ifelse	% b r t l
		    4 1 roll			% l b r t
		} ifelse
	    } {					% mark (str) x y l b r t
		8 -4 roll pop pop pop pop
	    } ifelse
	} bind def
	/DownloadPS {
	    $Adobe$DPS$Lib$Dict /downloadSuccess false put
	    (%stdin) (r) file
	    cvx stopped
	    pop	% always true
	    % Flush until you get the magic line
	    {
		    {currentfile 256 string readline} stopped
		    pop % don't care stopped result
		    pop % don't care readline bool result
(Magic end of data line \)\)\)\)\)\)\)\)\)\) 99#2 2#99 <xyz> // 7gsad,32h4ghNmndFgj2)
		    eq
		    {exit} if
		} loop
	} bind def
    end
endps

defineps _DPSFEnumFonts(DPSContext ctxt | int *count; int *totalLength)
    $Adobe$DPS$Lib$Dict begin
	/FontDict 5 dict def
	FontDict begin
	    /currentItem 0 def
	    /maxItems 100 def
	    /maxArrays 20 def	% This is the max index, not the array size!
	    /baseArray maxArrays 1 add array def
	    /currentArray 0 def
	    baseArray 0 maxItems array put
	end

	/AddFontName {		% string AddFontName success
	    $Adobe$DPS$Lib$Dict /FontDict get begin
		1 {		% provides enclosing loop for exit
		    currentItem maxItems eq
		    {
			currentArray maxArrays eq {pop false exit} if
			/currentArray currentArray 1 add def
			baseArray currentArray maxItems array put
			/currentItem 0 def
		    } if
		    dup length string copy
		    baseArray currentArray get currentItem 3 -1 roll put
		    /currentItem currentItem 1 add def
		    true
		} repeat	% provides enclosing loop for exit
	    end
	} bind def

	3 dict begin
	    /$listString 256 string def
	    /countFonts 0 def
	    /totalLen 0 def

	    % Enumerate SharedFontDirectory
	    SharedFontDirectory {		% forall
		pop				% /fontname
		$listString cvs		% (fontname)
		dup AddFontName		% (name) success
		{
		    /countFonts countFonts 1 add def
		    length 1 add totalLen add /totalLen exch def
		} { 
		    pop
		} ifelse
	    } forall

	    % Enumerate %font% storage device, if available.
	    /filenameforall where {		% if
		pop
		(%font%*) {			% filenameforall
		    % Check if name is something we really believe
		    % is a font.  Leave either "false" or "(name) true"
		    % on stack

		    % Discard filenames containing "."
		    (.) search {		% if
			pop pop pop null false
		    } { % else
			dup			% (%font%name) (%font%name)
			(%font%) anchorsearch {	% if
						% (%font%name) (name) (%font%)
			    pop exch pop	% (name)
			    dup AddFontName	% (name) success
			} { % else
			    pop null false
			} ifelse
		    } ifelse

		    % Stack is either "<something> false" or "(name) true"
		    {
			/countFonts countFonts 1 add def
			length 1 add totalLen add /totalLen exch def
		    } {
			pop
		    } ifelse
		} $listString filenameforall
	    } if
	    totalLen totalLength countFonts count
	end
    end

    $Adobe$DPS$Lib$Dict /AddFontName undef
endps

defineps _DPSFGetAllFontNames(DPSContext ctxt; int fontCount; int arrLen |
	char fontNames[arrLen])
    $Adobe$DPS$Lib$Dict begin
	FontDict begin
	    0 1 fontCount 1 sub {
		GetFontName fontNames
		( ) fontNames
	    } for
	end
    end
endps

defineps _DPSFGetFontInfo(DPSContext ctxt; int fontNum; boolean oldServer |
			char *familyName; char *fullName; char *weight;
			boolean *blendedFont, *undefineIt, *bogus)
    fontNum $Adobe$DPS$Lib$Dict /GetFontName get exec

    dup dup			% fontname fontname fontname
    SharedFontDirectory exch known % fontname fontname known
    dup undefineIt exch		% fontname known fontname
    				% (leave fontname and known on stack
				% for the duration of this call
				% even though I don't list them in
			    	% the comments)
    { % stopped
    findfont dup		% fontdir fontdir
    /FontInfo known {		% fontdir bool
	/FontInfo get dup dup	% fontinfo fontinfo fontinfo
	/FamilyName known {	% fontinfo fontinfo bool
	    /FamilyName get	% fontinfo (familyname)
	} {
	    pop ()
	} ifelse
	exch dup dup		% (familyname) fontinfo fontinfo fontinfo
	/FullName known {	% (familyname) fontinfo fontinfo bool
	    /FullName get	% (familyname) fontinfo (fullname)
	} {
	    pop ()
	} ifelse
	exch dup dup		% (familyname) (fullname) fontinfo*3
	/Weight known {		% (familyname) (fullname) fontinfo*2 bool
	    /Weight get		% (familyname) (fullname) fontinfo (weight)
	} {
	    pop (Medium)
	} ifelse
	exch			% (familyname) (fullname) (weight) fontinfo
	/BlendAxisTypes known   % (familyname) (fullname) (weight) blendedFont
        
	dup blendedFont		% (familyname) (fullname) (weight) blendedFont
    } {
	pop () () ()
        false false blendedFont
    } ifelse			% (familyname) (fullname) (weight) blendedFont
    false bogus

    } stopped {			
	() () ()
	false false blendedFont
	true bogus
    } if

    4 1 roll			% blendedFont (familyname) (fullname) (weight)
    weight fullName familyName
				% fontname known is still on the stack so...
				% fontname known blendedFont

    % if blendedFont (the bool on the stack) is true, don't undefine things
    % just yet since we'll be coming back quite soon for more stuff

    not and {				% undefine font if we just defined 
					% it to get this information
	currentshared true setshared
	    exch 			% currentshared fontname
	    {undefinefont} stopped	% currentshared [fontname] stopped
	    {
		false setshared		% currentshared fontname

		{undefinefont} stopped {
		    pop
	        } if
	    } if
	setshared

	oldServer {2 vmreclaim} if
    } {
	pop
    } ifelse
endps

defineps _DPSFFreeFontInfo(DPSContext ctxt)
    $Adobe$DPS$Lib$Dict /FontDict undef
    $Adobe$DPS$Lib$Dict /GetFontName undef
    1 vmreclaim
endps

defineps _DPSFIsFontResident(DPSContext ctxt; char *name; | boolean *resident)
    SharedFontDirectory /name known {
	true resident
    } {
	/buf (name) length 6 add string def
	buf 0 (%font%) putinterval
	buf 6 (name) putinterval
	buf status dup resident { pop pop pop pop } if
    } ifelse
endps

defineps _DPSFGetBlendedFontInfo(DPSContext ctxt; int fontNum;
			boolean undefineIt; boolean oldServer |
			int *axes; int *designs;
			char axisNames[256];
			float blendPos[64]; int breakCount[4];
			int blendBreak[48]; float blendBreakValue[48];
			boolean *bogus)

    fontNum $Adobe$DPS$Lib$Dict /GetFontName get exec
    $Adobe$DPS$Lib$Dict /stringbuf 256 string put
    dup				% duplicate fontname; we'll need it later

    findfont /FontInfo get dup	% fontinfo fontinfo
    /BlendAxisTypes get		% fontinfo array
    dup length axes		% fontinfo array
    {				% Concatenate all the names into axisNames
        $Adobe$DPS$Lib$Dict /stringbuf get cvs
	axisNames
	( ) axisNames
    } forall
    dup dup			% fontinfo fontinfo fontinfo
    /BlendDesignPositions known { % fontinfo fontinfo known
	/BlendDesignPositions get % fontinfo array
	dup length designs	% fontinfo array
	{			% enumerate the subarrays
	    {
		blendPos
	    } forall
	} forall
	false
    } {
	pop true
    } ifelse			% fontinfo bool
    exch dup			% bool fontinfo fontinfo
    /BlendDesignMap known {	% bool fontinfo known
	/BlendDesignMap get	% bool array
	{
	    dup length		% bool subarray len
	    breakCount		% bool subarray len
	    {
		aload pop	% bool break breakvalue
		blendBreakValue
		blendBreak	
	    } forall
	} forall
	false
    } {
	pop true
    } ifelse			% bool bool

    or bogus

    undefineIt {			% undefine font if we just defined 
					% it to get this information
	currentshared true setshared
	    exch 			% currentshared fontname
	    {undefinefont} stopped	% currentshared [fontname] stopped
	    {
		false setshared		% currentshared fontname

		{undefinefont} stopped {
		    pop
	        } if
	    } if
	setshared
	oldServer { 2 vmreclaim } if
    } {
	pop
    } ifelse
    $Adobe$DPS$Lib$Dict /stringbuf undef    
endps

defineps _DPSFShowText(DPSContext ctxt; char *text; char *font; float size;
		       int x, y | boolean *bogus)
    mark {
	/font size selectfont
	x y moveto
	(text) show
    } stopped dup bogus cleartomark
endps

defineps _DPSFShowTextAndGetDimensions(DPSContext ctxt;
				       char *text; char *font; float size;
				       int x, y | 
				       float *width, *left, *right,
						*top, *bottom)
    mark {
	/font size selectfont
	x y moveto
	(text) show
	(text) stringwidth pop width
	(text) x y $Adobe$DPS$Lib$Dict /SafeBBox get exec
    } stopped {0 0 0 0} if
    top right bottom left
    cleartomark
endps

defineps _DPSFGetTextDimensions(DPSContext ctxt;
				char *text; char *font; float size;
				float x, y | 
				float *width, *height,
					*left, *right, *top, *bottom;
				boolean *bogus)
    mark {
	/font size selectfont
	(text) stringwidth height width

	(text) x y $Adobe$DPS$Lib$Dict /SafeBBox get exec
    } stopped dup bogus {0 0 0 0} if
    top right bottom left
    cleartomark
endps

defineps _DPSFGetCTM(DPSContext ctx | float ctm[6], invctm[6])
    matrix currentmatrix dup ctm matrix invertmatrix invctm
endps

defineps _DPSFSetUpMM(DPSContext ctxt; char *font, *str; float size;
		      int height; float p[n]; int n | boolean *bogus)
    userdict /fontDefined known {
	/tempfont undefinefont
    } if
    mark {
	/tempfont /font findfont p makeblendedfont definefont
	size scalefont setfont
	0 height neg 5 div itransform
	exch pop 5 exch moveto	    
	(str) stringwidth pop pop
	/fontDefined true def
    } stopped bogus cleartomark
endps

defineps _DPSFDrawMM(DPSContext ctxt; char *str; int height)
    0 height neg 5 div itransform
    exch pop 5 exch moveto	    
    (str) show
endps

defineps _DPSFPrepareToDownload(DPSContext ctxt; boolean makeShared | 
				boolean *currShared)
	$Adobe$DPS$Lib$Dict /DownloadPS get
	currentshared currShared makeShared setshared
endps

defineps _DPSFFinishDownload(DPSContext ctxt; boolean shared | boolean *ok)
	shared setshared
	$Adobe$DPS$Lib$Dict /downloadSuccess get ok
endps
