home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-09-28 | 28.6 KB | 954 lines | [TEXT/MPS ] |
- %
- % File: TextFaceProcs.ps
- %
- % Contains: This file contains Procedures needed to construct layered fonts for text faces.
- %
- % Version: Technology: Quickdraw GX 1.1.x.
- %
- % Copyright: © 1991-7 by Apple Computer, Inc., all rights reserved.
- %
- %
-
- % Add the bounding box on the stack as a rectangle to the current path.
- %
- % x1 y1 x2 y2 BBoxPath -
- %
- /BBoxPath {
-
- 3 index 3 index % Stack is: x1 y1 x2 y2 x1 y1
- moveto % Stack is: x1 y1 x2 y2
- 3 index 1 index % Stack is: x1 y1 x2 y2 x1 y2
- lineto % Stack is: x1 y1 x2 y2
- 2 copy % Stack is: x1 y1 x2 y2 x2 y2
- lineto % Stack is: x1 y1 x2 y2
- pop 1 index % Stack is: x1 y1 x2 y1
- lineto lineto
- closepath
-
- } Bdef
-
-
- %
- % Procedure StringBBox:
- %
- % Procedure computes an accurate bounding box in current userspace for the string in the
- % current font.
- %
- % string StringBBox x1 y1 x2 y2
- %
- % string: string containing text of which to obtain bounding box.
- % x1 y1 x2 y2: returned on stack: tight bounding box of glyph in user space.
- %
- /SaveMatrix matrix def
- /SaveFont null def
- /StringBBox {
-
- currentpoint 3 -1 roll % Stack is Cx Cy char
-
- % Make the CTM so that character paths are in untransformed user space (Glyph space).
-
- SaveMatrix currentmatrix pop % Save the current matrix.
- initmatrix % Set up the normal userspace matrix.
- currentpoint translate % Make the currentpoint the origin.
- currentfont dup /SaveFont Xstore % Save the current font
- 100 scalefont % and Make sure the font is scaled so we don't
- setfont % get hinting errors when we do the charpath (NTX shows this problem)
-
- false userdict /charpath known { % Get the path
- userdict /charpath get exec % If defined in userdict (by TT scaler for example) use it
- } { % else
- charpath % Execute whatever charpath is around
- } ifelse
-
- pathbbox % Get the bounding box.
- 4 {100 div 4 1 roll} repeat % Divide the result by how much we scaled the font.
- newpath
-
- % Restore the graphics state (Matrix and font, path is left uninialized)
- SaveMatrix setmatrix
- SaveFont setfont
-
- % Stack is: Cx Cy x1 y1 x2 y2 (Bouding box in Glyph space).
-
- 6 -2 roll % Stack is: x1 y1 x2 y2 Cx Cy
- 2 copy % Stack is: x1 y1 x2 y2 Cx Cy Cx Cy
- translate % Stack is: x1 y1 x2 y2 Cx Cy
-
- % CTM now has been translated so origin is at the currentpoint.
- % Mapping the points through this and then back through untranslated CTM yields userspace.
-
- 6 2 roll % Stack is: Cx Cy x1 y1 x2 y2
-
- % Translate the bounding box to device space
-
- transform % Stack is: Cx Cy x1 y1 x2' y2'
- 4 2 roll transform % Stack is: Cx Cy x2' y2' x1' y1'
- 4 2 roll % Stack is: Cx Cy x1' y1' x2' y2'
-
- % untranslate the CTM and put bounding box back in user space.
-
- 6 -2 roll % Stack is: x1' y1' x2' y2' Cx Cy
- neg exch neg exch % Stack is: x1' y1' x2' y2' -Cx -Cy
- translate % Stack is: x1' y1' x2' y2'
- itransform 4 2 roll % Stack is: x2'' y2'' x1' y1'
- itransform 4 2 roll % Stack is: x1'' y1'' x2'' y2''
-
- } Bdef
-
-
-
- %<FF>
- %
- % Procedure AddBBoxes:
- %
- % Procedure produces the union of the passed in rectangle to the path's bounding box.
- % if the first one is null, the second one is just left on the stack.
- % x1 y1 x2 y2 px1 py1 px2 py2 AddBBoxes x1' y1' x2' y2'
- % or
- % null px1 py1 px2 py2 AddBBoxes px1 py1 px2 py2
- %
- % x1 y1 x2 y2: starting bounding box
- % px1 py1 px2 py2: bounding box todd.
- % x1' y1' x2' y2': union of starting box and box to add.
- %
- /AddBBoxes {
-
- 4 index null ne { % the first box is not null, add the two boxes.
-
- % stack is x1 y1 x2 y2 px1 py1 px2 py2
-
- 4 index Max
- 4 1 roll
-
- % stack is x1 y1 x2 y2 y2' px1 py1 px2
-
- 5 index Max
- 4 1 roll
- % stack is x1 y1 x2 y2 x2' y2' px1 py1
-
- 6 index Min
- 4 1 roll
-
- % stack is x1 y1 x2 y2 y1' x2' y2' px1
-
- 7 index Min
- 4 1 roll
-
- % stack is x1 y1 x2 y2 x1' y2' x2' y2'
-
- 8 4 roll
- pop pop pop pop
-
- } {
-
- 5 -1 roll pop % Get rid of the null and leave the box as the sum of the two bounding boxes.
-
- } ifelse
-
- } Bdef
-
-
- %<FF>
- %
- % Procedure: LW8LayerBuildChar
- %
- % This is a super-trimmed down version of LayerBuildChar that works for basic text
- % faces. All that is respected from the layers is:
- % outlineTransform,
- % framed layers (only if base font supports PaintType = 2)
- % whiteLayer, but drawn in white rather than transparently (like LW 7.x and 8.x drivers)
- % BuildChar does not use PS font cache, thus allowing us to draw with white for white layers.
- %
- /LW8LayerBuildChar {
-
- exch begin % Put layered font dictionary on stack.
-
- Moby begin % Make sure Moby Dict is on stack.
-
- % Set up the metrics for the layered glyph.
-
- baseFont setfont
-
- theChar exch 0 exch put % Make the integer back into a string.
- theChar stringwidth % Get the metrics for this character
- advanceMapping transform % Run through advanceMapping.
- setcharwidth % Set up advances.
-
- faceLayers {
-
- gsave
- begin % Put layer dictionary on dictionary stack.
-
- fillKey /No ne { % Don't bother for no fill layers.
-
- LayerFont setfont % Set font for layer.
- whiteLayer {1.0 setgray} if % This is wrong, but fast. Real LayerBuildChar does right thing.
-
- outlineTransform begin % Get the transform dictionary on the dict. stack.
-
- isSimpleTranslation { % If it is simple translation, can just do moveto without modifying CTM.
-
- xTrans yTrans moveto % Move to xTrans yTrans
-
- } { % Else
-
- Mapping concat % Concatenate the mapping with the CTM
- TrSetClip % Set the clip
- 0 0 moveto % Move to 0,0 (goes through mapping)
-
- } ifelse
-
- end % Pop transform dictionary off stack.
-
- theChar show % Draw the layer's glyph (We can assume we don't need to use QD2Show for LW8 case.
-
- } if
-
- end
- grestore
-
- } forall
-
-
- end
-
- end
-
- } Bdef
-
-
-
- %<FF>
- %
- % Procedure AdvanceMappingBuildChar:
- % This is the buildchar procedure for a text face that has no layers but has an advance
- % mapping.
- %
- /AdvanceMappingBuildChar {
-
- exch begin % Put the layered font dictionary on the stack.
-
- theChar 0 3 -1 roll put % Save the character to render in the string.
-
- % Compute the new advance for the glyph
-
- baseFont setfont
- theChar stringwidth
- advanceMapping transform % Transform the advance of the character by the advanceMapping.
- setcharwidth % Set the transformed value to be new advance widths.
-
- % Now draw the glyph.
-
- 0 0 moveto
- theChar show
-
- end
-
- } Bdef
-
-
-
- %
- % TextFaceSetupFontCache is a wrapper for "setcachedevice"
- % It either does a setcharwidth or a setcachedevice.
- % It also sets the clip to the bounding box passed in.
- % Assumes text face font dictionary is on stack.
- %
- /TextFaceSetupFontCache {
-
- 6 copy % Copy the setcachedevice parameters so we can set the clip.
-
- languagelevel 2 ge HasPattern and { % since in L2 patterns are colors, we can't use font cache.
- pop pop pop pop setcharwidth % so don't, just set up metrics
- } { % else
- setcachedevice % Set up the font cache parameters for layered glyph.
- } ifelse
-
- % Now with the copied setcachedevice parameters, set the clip. Do it after call to
- % setcachedevice becuase setcachedevice can modify the CTM depending on whether or not
- % it actually succeeds in caching. We wouldn't have to do any of this if we could depend
- % on setcachedevice setting the clip to the glyph bounding box like it is supposed to do.
-
- 2 copy 6 -2 roll % Stack is now: wX wY x1 y1 x1 y1 x2 y2
- BoxWidths % stack is now: wX wY x1 y2 W H
-
- %%%%% Draw X in bbox
- %%%%% 0.02 setlinewidth 4 copy RStr
-
- RCl % Set the clip!
- pop pop
-
-
- } Bdef
-
-
-
- %
- % ComputeLayerBBox
- %
- % Function computes the bounding box for a layer.
- %
- % Assumes dictionary for layer is on dict stack, layered font dict behind it,
- % and theChar contains the character passed into BuildChar.
- %
- /ComputeLayerBBox {
-
- LayerFont setfont % Make the current font the layer's font.
-
- newpath 0 0 moveto % Place currentpoint at 0,0
- theChar StringBBox % Get the bounding box of the glyph in userspace.
- % The rectangle: X1,Y1 X2,Y2 X3,Y3 X4,Y4
-
-
-
- % Take into account the layer's transform, bolness, pen, and dash to expand bounding box
-
- % Compute the rectangle: X1,Y1 X2,Y2 X3,Y3 X4,Y4
- /Y3 Xdef /X3 Xdef % Y3 X3 Y1 X1 are on stack
- /Y1 Xdef /X1 Xdef %
- /X2 X3 def /Y2 Y1 def % X2, Y2 is really X3,Y1
- /X4 X1 def /Y4 Y3 def % X4, Y4 is really X1,Y3
-
-
- % Run the 4 points of the bounding box through the layer's transform.
-
- X1 Y1 outlineTransform /Mapping get transform /Y1 Xdef /X1 Xdef
- X2 Y2 outlineTransform /Mapping get transform /Y2 Xdef /X2 Xdef
- X3 Y3 outlineTransform /Mapping get transform /Y3 Xdef /X3 Xdef
- X4 Y4 outlineTransform /Mapping get transform /Y4 Xdef /X4 Xdef
-
- % We now have the rectangle enclosing the glyph transformed through the layer's mapping, thus in glyph space.
- % Now compute the glyph space box that encloses these points.
-
- X1 X2 Min X3 Min X4 Min % x1
- Y1 Y2 Min Y3 Min Y4 Min % y1
- X1 X2 Max X3 Max X4 Max % x2
- Y1 Y2 Max Y3 Max Y4 Max % y2
-
-
- %% Expand bounding box by pen, boldness, and dash bounding box.
-
- /LayerBBoxGrowX xBold 2 div def % half of bold because bold specifies total in both in and out.
- /LayerBBoxGrowY yBold 2 div def
-
- %
- % If it is a framed layer, expand the bounding box even more.
- %
- fillKey /Fr eq LayerFont /PaintType 2 copy known {get} {pop pop 0} ifelse 2 eq or {
-
- % Compute a device gridded pen size.
-
- outlineStyle /pen get dup dtransform % Map pen to device space
- 2.0 Max exch 2.0 Max exch % Make sure it is at least one pixel on each side of path to be stroked
- idtransform % Map it back to user space.
- Max % Take the biggest of the x&y pen thickness.
- /LayerPen exch def % Save the value.
-
- outlineStyle /dash get null ne { % If it dashed, expand by dash size.
-
- outlineStyle /dash get /Shape get ShapeBBox % Get the bounding box of the dash.
- BoxWidths exch pop % Get the height of the dash shape.
- LayerPen 2 div mul dup % Multiply the Y height by pen thickness.
- LayerBBoxGrowY add /LayerBBoxGrowY Xdef % add it to the expansion value.
- LayerBBoxGrowX add /LayerBBoxGrowX Xdef % add it to the expansion value.
-
- } { % Else, just expand by half the pen width.
-
- LayerBBoxGrowY LayerPen 2 div add /LayerBBoxGrowY Xdef
- LayerBBoxGrowX LayerPen 2 div add /LayerBBoxGrowX Xdef
-
- } ifelse
-
- } if
-
- LayerBBoxGrowY add % Stack is now: x1 y1 x2 y2+yBold
- exch LayerBBoxGrowX add % Stack is now: x1 y1 y2+yBold x2+xBold
- 4 2 roll % Stack is now: y2+yBold x2+xBold x1 y1
- LayerBBoxGrowY sub % Stack is now: y2+yBold x2+xBold x1 y1-Bold
- exch LayerBBoxGrowX sub % Stack is now: y2+yBold x2+xBold y1+yBold x1-xBold
- exch 4 2 roll exch % stack is now: x1-xBold y1-yBold x2+xBold y2+yBold
-
- } Bdef
-
-
-
-
-
- %<FF>
- %
- % Procedure: ComputeFaceBBox
- %
- % Computes the bounding box of a text face. Can compute the tight bounding box for a particular
- % glyph or the smallest necessary for any glyph.
- %
- % If autoAdvance is true, or any layers have inverseFill, then tight box is computed for character
- % stored in theChar in layered font dictionary. Otherwise, computes a gross bounding box.
- %
- % assumes Layered font dictionary is on dict stack.
- %
- % - ComputeFacBBox x1 y1 x2 y2
- %
- /ComputeFaceBBox {
-
- null % Start the bounding box with null.
- faceLayers {
-
- begin % Put this layer dictionary on dict stack
-
- whiteLayer not fillKey /No ne and { % White layers and noFil layers do not affect bounding box.
-
- ComputeLayerBBox % Compute bounding box for this layer.
- AddBBoxes % Add it into the layered glyph bounding box
-
- } if
-
- end
-
- } forall
-
- dup null eq { % If there is a null on the stack, none of the layers contributed to bounding box.
-
- pop % Pop off nul
- 0 0 0 0 % Leave an empty bounding box on the stack.
-
- } if
-
- } Bdef
-
-
-
-
-
- %<FF>
- /LayerBuildChar {
-
- /TextFaceSave save store % do a save for the buildchar
- % This ensures that the buildchar has no side effects.
-
- Moby begin % Put Moby dict on stack. Text face fonts can be
- % called from synonyms in which case Moby is taken off stack.
-
- 1 0 0 1 0 0 % Make the current font mapping the identity since all fonts drawn
- AugGstate /FontMapping get % in the layer are unscaled and boldness uses this mapping.
- astore pop
-
-
- exch begin % Put the layered font dictionary on the dict stack.
-
- theChar exch 0 exch put % Make the integer back into a string.
-
- %
- % Generate the metrics for the layered glyph
- %
- baseFont setfont % Make the base font the current font.
- theChar stringwidth % Get the advance metrics of the base glyph.
-
-
- % If autoadvance was turned on, modify the advance width of the glyph by adding the difference
- % between the bounding box of the layered glyph and the base glyph to the advance widths of
- % the base glyph. Only modify non-zero advance, however.
-
- autoAdvance {
-
- ComputeFaceBBox % Compute the tight bounding box for the glyph
-
- % The 6 items on the top of the stack are now the bounding box number for the layered glyph
- % and the advance metrics of the original glyph.
-
- 4 copy % Make a copy of the layered glyph's bounding box
- 10 4 roll % Move the copy behind the previously mentioned 6 items.
-
- % Get bounding box of original glyph
-
- baseFont setfont
- newpath
- 0 0 moveto
- theChar StringBBox
-
- % stack is now: x1 y1 x2 y2 wX wY x1 y1 x2 y2 x3 y3 x4 y4, (x3, y3, x4, y4 is box of original glyph)
-
- BoxWidths
-
- % stack is now: x1 y1 x2 y2 wX wY x1 y1 x2 y2 (x4-x3) (y4-y3)
-
- 6 2 roll
-
- % stack is now: x1 y1 x2 y2 wX wY (x4-x3) (y4-y3) x1 y1 x2 y2
-
- BoxWidths
-
- % stack is now: x1 y1 x2 y2 wX wY (x4-x3) (y4-y3) (x2-x1) (y2-y1)
-
- BoxWidths
-
- % Stack is now: x1 y1 x2 y2 wX wY delta-X delta-Y, deltas = differences in bbox dimensions.
-
- 4 2 roll
- % Stack is now: x1 y1 x2 y2 delta-X delta-Y wX wY
-
- dup 0 ne {2 index add} if % If starting wY wasn't 0 add delta-y to it.
- exch
- % Stack is now: x1 y1 x2 y2 delta-X delta-Y wYfinal wx
-
- dup 0 ne {3 index add} if % If starting wX wasn't 0 add delta-X to it.
- exch
- % Stack is now: x1 y1 x2 y2 delta-X delta-Y wXfinal wYfinal
-
- 4 2 roll pop pop % Stack is now x1 y1 x2 y2 wXfinal wYfinal
-
- advanceMapping transform % Run the advance metrics through the advance mapping.
-
- 6 2 roll % Stack is now wXfinal wYfinal x1 y1 x2 y2
-
- } { % Else, if no autoadvance, transform the normal advances.
-
- advanceMapping transform % Transform them by the advance mapping.
-
- ComputeBBox { % Inverse fill requires tight bounding box.
- ComputeFaceBBox % Compute it.
- } { % Else
- /FontBBox load cvx exec % Just use the Layered font's big bounding box, its faster.
- } ifelse
-
- } ifelse
-
- % Stack now contains bounding box and metrics
-
- TextFaceSetupFontCache
-
- %
- % Now draw the layered glyph into the font cache:
- % • The layers are drawn in reverse order so white-layers can be done as clips.
- %
- nLayers 1 sub -1 0 { % Traverse layers in reverse order.
-
- faceLayers exch get begin % Put this layer's dictionary on dict stack.
-
- fillKey /No ne { % Ignore layer if it is noFill.
-
- newpath % Get ready for drawing
- LayerFont setfont % Make this layer's font the current font
- whiteLayer { % If it is a white layer then set clip
-
- CurrCTM currentmatrix % Save a copy of the current transform (on stack) for restoring.
-
- outlineTransform SetTr % Apply the outline transform.
- 0 0 moveto % Move to 0 0 before drawing the glyph.
- theChar false GXCharPath % Get the path of the character
- /In {QD2Clip} stopped { % Inverse clip to the character. (if we can't clip oh well)
- newpath % If not, then just clean up the current path.
- } if
-
- setmatrix % Restore the transform, clips carry through for subsequent layers.
-
- } {
-
- outlineStyle SetStyle % Set the style for this layer in augmented g-state.
- xBold yBold SetBold % Set the boldness for the layer in augmented g-state.
-
- gsave
-
- outlineTransform SetTr
- SynchPatMatrix % Synchronize the pattern with the CTM.
- newpath 0 0 moveto % moveto where 0 0.
- mark % Set up to clean up after the show
- theChar fillKey {QD2Show} stopped { % Do the show if it fails.
- counttomark 6 eq{ % Check if we have to do any clean up
- 5{pop}repeat % Pop the parameters to image mask
- dup type /savetype eq{restore}if % Do the restore for save that TT scaler left.
- }if %
- } if %
- cleartomark
-
- grestore
-
- } ifelse
-
- } if
-
- end % Pop layer dictionary off dict stack.
-
- } for
-
- end % pop font dictionary off dict stack.
-
-
- end % Pop Moby dict off dict stack.
-
- TextFaceSave restore % Restore it!
-
- } Bdef
-
-
- %<FF>
- %
- % Procedure MakeLayerDict:
- %
- % Procedure Makes a face layer dictionary.
- %
- % fillKey whiteLayer outlineStyle outlineTransform xBold yBold MakeLayerDict dict
- %
- % fillKey: The fill key for the layer.
- % whiteLayer: Boolean, true if this bit is set in the layerFlags.
- % outlineStyle: The style for this layer.
- % outlineTransform: The transform for this layer.
- % xBold yBold: boldness from layer.
- %
- % dict: Left on stack, a layer dictionary.
- %
- /MakeLayerDict {
-
- 19 dict begin % Create a dictionary
-
- /yBold Xdef
- /xBold Xdef
- /outlineTransform Xdef
- /outlineStyle Xdef
- /whiteLayer Xdef
- /fillKey Xdef
- /layerIndex 0 def
-
- /LayerFont null def % The seventh entry will be base font for this layer.
-
- /LayerBBoxGrowX 0 def % Compute amount to grow layer's bounding box in X
- /LayerBBoxGrowY 0 def % Compute amount to grow layer's bounding box in Y
- /X1 0 def /Y1 0 def /X2 0 def /Y2 0 def % Store layer's bouding box in here.
- /X3 0 def /Y3 0 def /X4 0 def /Y4 0 def
-
- /LayerPen 0 def % Compute device gridded pen size for framed layers here.
-
- currentdict % Leave the layer dictionary on the operand stack.
-
- end
-
- } Bdef
-
-
-
- %<FF>
- %
- % Procedure MakeLayeredFontDict:
- % Procedure makes a type-3 font to represent the text face (without underlines) applied to
- % The base font specified. The base font cannot be a composite font.
- %
- % baseFont faceBBox autoAdvance advanceMapping faceLayers useLW8BuildChar MakeLayeredFontDict layeredFontDict
- %
- % useLW8BuildChar: Use the fast buildchar routine?
- % faceLayers: An array of layer dictionaries
- % advanceMapping: The Skia Advance mapping from the face data structure.
- % autoAdvance: Boolean, Autoadvance bit from style runs's style.
- % faceBBox: Bounding box of text face at 1 point as 4 element array., null means unknown, must be computed.
- % baseFont: The base font dictionary.
- %
- % Left on stack:
- % layeredFontDict: The dictionary describing the layered font.
- %
- /MakeLayeredFontDict {
-
- 16 dict begin % Make a dictionary for the type-3 font.
-
- % Save the parameters
-
- /useLW8BuildChar Xdef
- /faceLayers Xdef
- /advanceMapping Xdef
- /autoAdvance Xdef
-
- % Stack is: baseFont faceBBox
- %Invert Y axis of base font and Face's bounding box.
- % Since the layered-font must be selected without flipping the Y axis so skewing
- % in the layer's transform works correctly. (works backwards otherwise)
- % Use this opportunity of calling makefont to apply the layer's style's point size as well.
- % Also, properly scale the bounding box by the same matrix.
-
- [ 1 0 0 -1 0 0 ] exch
- dup null ne {
- aload pop 4 index transform 4 2 roll 4 index transform 4 2 roll 4 array astore /FontBBox Xdef
- /ComputeBBox false def
- } {
- pop
- /FontBBox [0 0 0 0] def
- /ComputeBBox true def % We must compute a bounding box for each glyph.
- } ifelse
-
- makefont /baseFont Xdef
-
- % Some needed local variables for the layered font.
-
- /theChar 1 string def % Place for character to render.
- /nLayers faceLayers length def % Number of layers.
- /CurrCTM matrix def % We need to save the CTM someplace during layering.
-
- /HasPattern false def % We need to know if any layers have a pattern.
-
- % Some needed font dictionary entries.
-
- /FontType 3 def
- /FontMatrix matrix def
- /Encoding % Copy the encoding vector from the base font.
- baseFont /Encoding get
- def
-
- nLayers 0 eq { % If # layers is zero then
-
- /BuildChar /AdvanceMappingBuildChar load def % Use simple build-char for zero layer faces
-
- } { % Else use the layer-build char and compute modified layer fonts.
-
- useLW8BuildChar {
-
- /BuildChar /LW8LayerBuildChar load def
-
- } {
-
- /BuildChar /LayerBuildChar load def
-
- } ifelse
-
- %
- % For each layer, create The modified base font that will be used.
- %
- %
- baseFont % Get base font dict on the stack.
-
- faceLayers { % For each layer:
-
- exch dup 3 -1 roll % Duplicate the base font dict, stick it behind the layer dict.
- begin % Put layer dictionary on dict stack.
- outlineStyle begin % Put the layer's style dictionary on dict stack.
-
- % Stack is now baseFontDict
-
- % If the layer's style is framed, and there is no dash, and the font supports changing PaintType
- % make a framed font and change the fill key to windingNumber
- fillKey /Fr eq dash null eq and baseFont /PaintType known and {
-
- pen % Stack is now baseFontDict stylePen
- 1 index exch MakeFramedFont
- /FredTheFramedFont exch definefont % Stack is now baseFontDict framedFontDict
- exch pop % Get rid duplicate base font
- /fillKey /W store % Change the fill in layerDict to be winding-number because show will now do framed.
-
- } if
-
- % Now the font dictionary is on the stack.
- % Scale font for layer and bounding box if necessary.
-
- textSize 1 ne {
-
- textSize scalefont % Scale layerFontDict by textSize.
- /LayerFont Xstore % Store in in layer dictionary.
-
- } {
-
- /LayerFont Xstore % No need to change font on stack.
-
- } ifelse
-
- pattern null ne {/HasPattern true store} if % set flag in the font dictionary if there is pattern.
- fillKey /In eq {/ComputeBBox true store} if % Inverse Fill means we need to compute a tight bounding box.
-
- end
-
- end
-
- } forall
-
- pop % Get rid of the extra base font dictionary.
-
- } ifelse
-
- currentdict % Leave the dictionary on the operand stack.
-
- end
-
- } Bdef
-
-
-
- %<FF>
- /cUseLW8BuildChar false def
- /cFaceLayers null def
- /cAdvanceMapping null def
- /cAutoAdvance null def
- /cfaceBBox null def
- %
- % Procedure MakeLayeredCompositeFont
- % Procedure makes a composite font's whose child fonts are type-3 layered font dictionaries.
- % The face layer parameters are retrieved from the globals stored in Moby Dict by MakeLayeredFont
- %
- % baseFont MakeLayeredCompositeFont layeredFontDict:
- %
- % baseFont: the base font dictionary of the composite font.
- %
- /MakeLayeredCompositeFont {
-
- dup /FontType get 0 eq { % If the font passed is a composite font then get all of the child fonts
-
-
- 0 MakeFontClone dup begin % Make a clone of the font, put it on dict stack
-
- FDepVector { % For each font in the FDepVector
-
- MakeLayeredCompositeFont % Pass font dictionary from the vector back in recursively
- /FDepLayeredFont exch definefont % Make it a valid font.
-
- } forall
-
- FDepVector length array astore % Make a new FDepVector with the new layered fonts.
- /FDepVector exch def
-
- end
-
-
- } { % Recursive termination condition: font was not composite, make a layered font out of it.
-
- cfaceBBox
- cAutoAdvance
- cAdvanceMapping
-
- % Make a new array of face layers so the child font has its own copy.
- % since each child font has its own base font dictionary (as opposed to the main
- % font dictionary) which is stored in the layer dictionary.
- [
- cFaceLayers {
-
- begin
- fillKey whiteLayer outlineStyle outlineTransform xBold yBold
- end
-
- MakeLayerDict % make a new Copy of the layer dictionary.
-
- } forall
- ]
-
- cUseLW8BuildChar
-
- MakeLayeredFontDict
-
- } ifelse
-
- } Bdef
-
-
-
- % Procedure MakeLayeredFont:
- % Procedure makes a type-3 font to represent the text face (without underlines) applied to
- % The base font specified. The base font can be a composite font and the layered font
- % is generated recursively (in this case, the font created is a type-0 with child
- % fonts that are type-3 text face fonts.
- %
- % psFontName layerFontName baseFont faceBBox autoAdvance advanceMapping faceLayers cUseLW8BuildChar MakeLayeredFont layeredFontDict
- %
- % cUseLW8BuildChar: Boolean of indicating to use fast/wrong buildChar for LW driver performance.
- % faceLayers: An array of layer dictionaries
- % advanceMapping: The Skia Advance mapping from the face data structure.
- % autoAdvance: Boolean, Autoadvance bit from style runs's style.
- % faceBBox: Bounding box of text face font at 1 point.
- % baseFont: The base font dictionary.
- % layerFontName: The name to give the text face font so it can be used again.
- % psFontName: Name of potential font on printer that may be usable for this face.
- %
- % Left on stack:
- % layeredFontDict: The dictionary describing the layered font.
- %
- /MakeLayeredFont {
-
- 6 index FontDirectory exch known { % If layerFontName exists, then we've already made this font.
-
- pop pop pop pop pop pop % Pop the face parameters off the stack.
-
- % (Using Cached font:) print dup == flush
-
- findfont % Just get the font we already made.
- exch pop % pop off the psFontName.
-
- } { % Else, make the font from the text face parameters
-
- 7 index FontDirectory exch known { % Can we make it from the psFontName font
-
- pop pop pop pop pop % stack is: psFontName layerFontName baseFont
-
- % (Making Face from ROM:) print 2 index == flush
-
- % Get the encoding to use from the base font.
-
- /Encoding get % stack is: psFontName layerFontName encoding
- 2 index findfont % stack is: psFontName layerFontName encoding psFontDict
- [1 0 0 -1 0 0] makefont % flip it in the Y direction - so Imaging Engine's SFt works correctly.
- 0 MakeFontClone % Clone the font dictionary.
- dup 3 -1 roll % Stack is: psFontName layerFontName psFontDict psFontDict encoding
- /Encoding exch put % Stack is: psFontName layerFontName reencodedFlippedFontDict.
-
- } {
-
- % (Making Algorithmic font) == flush
-
- 5 index /FontType get 0 ne { % If baseFont is not a composite font then just do it.
-
- MakeLayeredFontDict
-
- } { % Else recursively traverse the embedded font dictionaries
-
- % Store the face parameters in Moby Dict
-
- /cUseLW8BuildChar Xdef
- /cFaceLayers Xdef
- /cAdvanceMapping Xdef
- /cAutoAdvance Xdef
- /cfaceBBox Xdef
-
- % the base font dict is left on the stack.
-
- MakeLayeredCompositeFont % Make a layered composite font
-
- } ifelse
-
- } ifelse
-
- % Stack is: psFontName layerFontName layeredFontDict
-
- exch dup /DontCache eq { % If the name is DontCache, then just use name LayeredFont and it won't be cached.
-
- pop /LayeredFont
-
- } if
-
- exch % Stack is psFontName layeredFontName layerFontDict
-
- definefont % Define it using layerFontName, leave the dict on the stack.
-
- exch pop % Pop off the psFontName
-
- } ifelse
-
- } Bdef
-
-
-
- %<FF>
- % Procedure MakeSimpleLayeredFont:
- % Procedure makes a text face font for the simple one layer case.
- % This can be many orders of magnitude faster in the uncached case as a general
- % text face font.
- %
- % baseFont faceMapping MakeSimpleLayeredFont layeredFontDict
- %
- % layerMapping: The mapping in the text face's layer.
- % baseFont: The base font dictionary.
- %
- % Left on stack:
- % layeredFontDict: The dictionary describing the layered font.
- %
- /MakeSimpleLayeredFont {
-
- % Concatenate the face mapping with invert in Y direction
- % because PostScript coordinate system is flipped. Do it here otherwise skewing happens backwards.
-
- [1 0 0 -1 0 0] exch ScratchMatrix concatmatrix % Scale the layer's mapping by 1,-1
- makefont % Do a makefont.
-
- % We're done, very simple Eh??
-
- } Bdef
-