<> <> <> DIRECTORY JaMBasic, TextNode, TextLooks, NameSymbolTable; NodeStyle: CEDAR DEFINITIONS = BEGIN <<***** Declarations>> Ref: TYPE = REF StyleBody; StyleBody: TYPE = RECORD [ fontFace: FontFace _ Regular, -- 2 bits fontAlphabets: FontAlphabets _ CapsAndLower, -- 2 bits strikeout: FontUnderlining _ None, -- 2 bits underlining: FontUnderlining _ None, -- 2 bits lineFormatting: LineFormatting _ FlushLeft, -- 2 bits pathType: PathType _ Filled, -- 2 bits print: BOOL _ FALSE, -- true if using the hardcopy style rules isComment: BOOL _ FALSE, -- set to node.comment; readonly for style rules fixedTabs: BOOL _ FALSE, -- true if stops at fixed locations. else relative to left margin nestingLevel: [0..MaxNestingLevel] _ 0, -- node level in tree; readonly for style rules numTabStops: [0..64) _ 0, -- length of the tabStops list name: ARRAY NameParam OF Name, real: PACKED ARRAY RealParam OF RealCode, defaultTabStops: TabStop, -- if NIL, use 0.5 in flushLeft blank defaultTabStops tabStops: LIST OF TabStop, -- kept sorted by decreasing location, i.e., from right to left on page <> dataList: DataList -- for special parameters ]; MaxNestingLevel: INTEGER = 31; -- 5 bits NameParam: TYPE = { style, -- name of the style, such as "TechicalNote" fontFamily -- name of the font family, such as "Helvetica" }; DataList: TYPE = REF DataEntry; OfEntry: TYPE = { object, real, tab }; DataEntry: TYPE = RECORD [ next: DataList, data: SELECT kind:OfEntry FROM object => [ name: Name, -- name of the parameter object: NameSymbolTable.Object ], -- value of the parameter real => [ -- for real values which overflow the table of common values param: RealParam, -- which one it is value: Real, -- the value valueI: INTEGER -- the value rounded to an integer -- ], tab => [ -- for real values from tabspecs which overflow the table of common values tabStop: TabStop, -- which tab stop it is which: TabRealParam, -- which value for the tab stop it is value: Real, -- the value valueI: INTEGER -- the value rounded to an integer -- ] ENDCASE]; TabRealParam: TYPE = { loc, spacing, weight, vshift }; TabStop: TYPE = REF TabStopRec; LeaderTabStop: TYPE = REF leaders TabStopRec; RuleTabStop: TYPE = REF rule TabStopRec; RulesTabStop: TYPE = REF rules TabStopRec; TabStopRec: TYPE = RECORD [ looks: TextLooks.Looks, -- the default looks for the stop loc: RealCode, -- the location of the stop alignment: TabAlign _ FlushLeft, -- how the tab is aligned alignmentChar: CHAR _ 0C, -- only of interest if alignment=Character breakIfPast: BOOL _ FALSE, -- what to do if you are already beyond the tab stop fill: SELECT fillKind:OfTabFill FROM blank => [], leaders => [ congruent: BOOL _ TRUE, -- otherwise, centered char: CHAR _ 0C, -- the character to be repeated spacing: RealCode -- the distance between repetitions ], rule => [ weight: RealCode, -- the thickness of the rule vshift: RealCode -- the distance up from the baseline to the bottom of the rule ], rules => [ array: JaMArrayObject -- array[0] holds real for first weight, array[1] holds real for first vshift ], ENDCASE ]; TabAlign: TYPE = { FlushLeft, FlushRight, Centered, Character }; OfTabFill: TYPE = { blank, leaders, rule, rules }; JaMArrayObject: TYPE = array JaMBasic.Object _ [X, array[0, NIL]]; FontFace: TYPE = { Regular, Bold, Italic, BoldItalic }; FontAlphabets: TYPE = { CapsAndLower, CapsAndSmallCaps, LowerOnly, CapsOnly }; FontUnderlining: TYPE = { None, LettersAndDigits, Visible, All }; LineFormatting: TYPE = { FlushLeft, FlushRight, Justified, Centered }; PathType: TYPE = { Filled, Outlined, FilledAndOutlined }; Name: TYPE = NameSymbolTable.Name _ NameSymbolTable.nullName; Real: TYPE = REAL _ 0.0; RealParam: TYPE = { <> fontSize, -- in points vshift, -- distance to raise text above baseline (can be negative) tabStops, -- number of spaces equivalent to one tab minLineGap, -- min distance between line top and previous bottom (can be negative) freeVar, -- for use by extensions <> leftIndent, -- all lines indent this much on left rightIndent, -- all lines indent this much on right firstIndent, -- first line indent this much more on left restIndent, -- other lines indent this much more on left topIndent, -- top line at least this much down from top of viewer/page bottomIndent, -- bottom baseline at least this up from bottom of page <> leading, -- distance between baselines leadingStretch, leadingShrink, topLeading, -- min distance from first baseline to previous topLeadingStretch, topLeadingShrink, bottomLeading, -- min distance from last baseline to next bottomLeadingStretch, bottomLeadingShrink, <> areaHue, -- color for filled areas areaSaturation, areaBrightness, outlineHue, -- color for outlines outlineSaturation, outlineBrightness, textHue, -- color for text textSaturation, textBrightness, textRotation, lineWeight, -- width of graphics lines <> pageWidth, pageLength, leftMargin, rightMargin, topMargin, bottomMargin, headerMargin, footerMargin, bindingMargin, lineLength, column, -- number of columns <> pageBreakPenalty, -- penalty for breaking inside node pageBreakAfterFirstLinePenalty, -- penalty for breaking node after its first line pageBreakBeforeLastLinePenalty, -- penalty for breaking node before its last line pageBreakBeforeFirstLinePenalty, -- penalty for breaking before first line of node pageBreakAfterLastLinePenalty -- penalty for breaking after last line of node }; RealCode: TYPE = [0..255] _ 0; zero: RealCode = 0; PointsPerPica: REAL; PointsPerInch: REAL; PointsPerCentimeter: REAL; PointsPerMillimeter: REAL; PointsPerDidot: REAL; PointsPerFil: REAL; PointsPerFill: REAL; <<**** Style free variables>> <<>> <> RegisterStyleFreeVar: PROC [ name: Name, eval: PROC [node: TextNode.Ref] RETURNS [REAL]]; <> RegisterStyleFreeObjVar: PROC [ name: Name, eval: PROC [node: TextNode.Ref] RETURNS [JaMBasic.Object]]; RemoveNodeFromApplyAllCache: PROC [node: TextNode.Ref]; <> RemoveAllFromApplyAllCache: PROC; <> UnregisterStyleFreeVar: PROC [name: Name]; <<**** Special extension style parameters>> <<>> <> DefineSpecial: PROC [name: Name, initialValue: Real]; GetSpecial: PROC [s:Ref, name: Name] RETURNS [Real]; GetSpecialI: PROC [s:Ref, name: Name] RETURNS [INTEGER]; nonNumeric: ERROR; -- raised if call GetSpecial or GetSpecialI for nonnumeric variable DefineSpecialObj: PROC [name: Name, initialValue: JaMBasic.Object]; GetSpecialObj: PROC [s:Ref, name: Name] RETURNS [JaMBasic.Object]; <<**** Non-numeric style parameters>> GetStyleName: PROC [s:Ref] RETURNS [Name] = INLINE { RETURN [s.name[style]] }; GetFontFamily: PROC [s:Ref] RETURNS [Name] = INLINE { RETURN [s.name[fontFamily]] }; GetFontFace: PROC [s:Ref] RETURNS [FontFace] = INLINE { <> RETURN [s.fontFace] }; GetFontAlphabets: PROC [s:Ref] RETURNS [FontAlphabets] = INLINE { <> RETURN [s.fontAlphabets] }; GetUnderlining: PROC [s:Ref] RETURNS [FontUnderlining] = INLINE { <> RETURN [s.underlining] }; GetStrikeout: PROC [s:Ref] RETURNS [FontUnderlining] = INLINE { <> RETURN [s.strikeout] }; GetLineFormatting: PROC [s:Ref] RETURNS [LineFormatting] = INLINE { <> RETURN [s.lineFormatting] }; GetPathType: PROC [s:Ref] RETURNS [PathType] = INLINE { <> RETURN [s.pathType] }; <<**** Miscellaneous real value parameters>> GetFontSize: PROC [s:Ref] RETURNS [Real] = INLINE { -- in points RETURN [GetReal[s,fontSize]] }; GetFontSizeI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,fontSize]] }; GetVShift: PROC [s:Ref] RETURNS [Real] = INLINE { <> RETURN [GetReal[s,vshift]] }; GetVShiftI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,vshift]] }; GetTabStops: PROC [s:Ref] RETURNS [Real] = INLINE { <> RETURN [GetReal[s,tabStops]] }; GetTabStopsI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,tabStops]] }; GetMinLineGap: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,minLineGap]] }; GetMinLineGapI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,minLineGap]] }; GetTextRotation: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,textRotation]] }; GetLineWeight: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,lineWeight]] }; <<**** Indents>> GetLeftIndent: PROC [s:Ref] RETURNS [Real] = INLINE { <> RETURN [GetReal[s,leftIndent]] }; GetLeftIndentI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,leftIndent]] }; GetRightIndent: PROC [s:Ref] RETURNS [Real] = INLINE { <> RETURN [GetReal[s,rightIndent]] }; GetRightIndentI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,rightIndent]] }; GetFirstIndent: PROC [s:Ref] RETURNS [Real] = INLINE { <> RETURN [GetReal[s,firstIndent]] }; GetFirstIndentI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,firstIndent]] }; GetBodyIndent, GetRestIndent: PROC [s:Ref] RETURNS [Real] = INLINE { <> RETURN [GetReal[s,restIndent]] }; GetBodyIndentI, GetRestIndentI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,restIndent]] }; GetTopIndent: PROC [s:Ref] RETURNS [Real] = INLINE { <> RETURN [GetReal[s,topIndent]] }; GetTopIndentI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,topIndent]] }; GetBottomIndent: PROC [s:Ref] RETURNS [Real] = INLINE { <> RETURN [GetReal[s,bottomIndent]] }; GetBottomIndentI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,bottomIndent]] }; <<**** Leadings>> GetLeading: PROC [s:Ref] RETURNS [Real] = INLINE { <> RETURN [GetReal[s,leading]] }; GetLeadingI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,leading]] }; GetLeadingStretch: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,leadingStretch]] }; GetLeadingShrink: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,leadingShrink]] }; GetTopLeading: PROC [s:Ref] RETURNS [Real] = INLINE { <> RETURN [GetReal[s,topLeading]] }; GetTopLeadingI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,topLeading]] }; GetTopLeadingStretch: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,topLeadingStretch]] }; GetTopLeadingShrink: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,topLeadingShrink]] }; GetBottomLeading: PROC [s:Ref] RETURNS [Real] = INLINE { <> RETURN [GetReal[s,bottomLeading]] }; GetBottomLeadingI: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,bottomLeading]] }; GetBottomLeadingStretch: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,bottomLeadingStretch]] }; GetBottomLeadingShrink: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,bottomLeadingShrink]] }; <<**** Page layout parameters for typesetter>> GetPageWidth: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,pageWidth]] }; GetPageLength: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,pageLength]] }; GetLeftMargin: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,leftMargin]] }; GetRightMargin: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,rightMargin]] }; GetTopMargin: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,topMargin]] }; GetBottomMargin: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,bottomMargin]] }; GetHeaderMargin: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,headerMargin]] }; GetFooterMargin: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,footerMargin]] }; GetBindingMargin: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,bindingMargin]] }; GetLineLength: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,lineLength]] }; GetColumns: PROC [s:Ref] RETURNS [INTEGER] = INLINE { RETURN [GetInt[s,column]] }; <<**** Penalties>> GetPageBreakPenalty: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,pageBreakPenalty]] }; GetPageBreakAfterFirstLinePenalty: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,pageBreakAfterFirstLinePenalty]] }; GetPageBreakBeforeLastLinePenalty: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,pageBreakBeforeLastLinePenalty]] }; GetPageBreakBeforeFirstLinePenalty: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,pageBreakBeforeFirstLinePenalty]] }; GetPageBreakAfterLastLinePenalty: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,pageBreakAfterLastLinePenalty]] }; <<**** Colors>> GetAreaHue: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,areaHue]] }; GetAreaSaturation: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,areaSaturation]] }; GetAreaBrightness: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,areaBrightness]] }; GetOutlineHue: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,outlineHue]] }; GetOutlineSaturation: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,outlineSaturation]] }; GetOutlineBrightness: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,outlineBrightness]] }; GetTextHue: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,textHue]] }; GetTextSaturation: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,textSaturation]] }; GetTextBrightness: PROC [s:Ref] RETURNS [Real] = INLINE { RETURN [GetReal[s,textBrightness]] }; <<**** Tab stop info>> GetTabLoc: PROC [stop: TabStop, s:Ref] RETURNS [Real] = INLINE { code: RealCode; IF (code _ stop.loc) # overflow THEN RETURN [realArray[code]]; RETURN [GetTabOverflow[s,stop,loc]] }; GetTabLocI: PROC [stop: TabStop, s:Ref] RETURNS [INTEGER] = INLINE { code: RealCode; IF (code _ stop.loc) # overflow THEN RETURN [intArray[code]]; RETURN [GetTabIntOverflow[s,stop,loc]] }; GetTabLeaderSpacing: PROC [stop: LeaderTabStop, s:Ref] RETURNS [Real] = INLINE { code: RealCode; IF (code _ stop.spacing) # overflow THEN RETURN [realArray[code]]; RETURN [GetTabOverflow[s,stop,spacing]] }; <<>> GetTabLeaderSpacingI: PROC [stop: LeaderTabStop, s:Ref] RETURNS [INTEGER] = INLINE { code: RealCode; IF (code _ stop.spacing) # overflow THEN RETURN [intArray[code]]; RETURN [GetTabIntOverflow[s,stop,spacing]] }; <<>> GetTabRuleWeight: PROC [stop: RuleTabStop, s:Ref] RETURNS [Real] = INLINE { code: RealCode; IF (code _ stop.weight) # overflow THEN RETURN [realArray[code]]; RETURN [GetTabOverflow[s,stop,weight]] }; <<>> GetTabRuleWeightI: PROC [stop: RuleTabStop, s:Ref] RETURNS [INTEGER] = INLINE { code: RealCode; IF (code _ stop.weight) # overflow THEN RETURN [intArray[code]]; RETURN [GetTabIntOverflow[s,stop,weight]] }; <<>> GetTabRuleVShift: PROC [stop: RuleTabStop, s:Ref] RETURNS [Real] = INLINE { code: RealCode; IF (code _ stop.vshift) # overflow THEN RETURN [realArray[code]]; RETURN [GetTabOverflow[s,stop,vshift]] }; <<>> GetTabRuleVShiftI: PROC [stop: RuleTabStop, s:Ref] RETURNS [INTEGER] = INLINE { code: RealCode; IF (code _ stop.vshift) # overflow THEN RETURN [intArray[code]]; RETURN [GetTabIntOverflow[s,stop,vshift]] }; <<>> RulesTabCount: PROC [stop: RulesTabStop] RETURNS [count: INTEGER]; -- number of rules RulesTabInfo: PROC [stop: RulesTabStop, num: INTEGER] RETURNS [weight, vshift: REAL]; <> RulesTabInfoI: PROC [stop: RulesTabStop, num: INTEGER] RETURNS [weight, vshift: INTEGER]; GetTabOverflow: PRIVATE PROC [ref: Ref, stop: TabStop, which: TabRealParam] RETURNS [value: Real]; GetTabIntOverflow: PRIVATE PROC [ref: Ref, stop: TabStop, which: TabRealParam] RETURNS [value: INTEGER]; <<**** Support routines; not for clients to use directly>> realArray: REF ARRAY RealCode OF Real; -- array of distances intArray: REF ARRAY RealCode OF INTEGER; overflow: RealCode = LAST[RealCode]; GetReal: PROC [ref: Ref, param: RealParam] RETURNS [value: Real] = INLINE { code: RealCode; IF (code _ ref.real[param]) # overflow THEN RETURN [realArray[code]]; RETURN [GetRealOverflow[ref,param]] }; GetInt: PROC [ref: Ref, param: RealParam] RETURNS [value: INTEGER] = INLINE { code: RealCode; IF (code _ ref.real[param]) # overflow THEN RETURN [intArray[code]]; RETURN [GetIntOverflow[ref,param]] }; GetRealOverflow: PRIVATE PROC [ref: Ref, param: RealParam] RETURNS [value: Real]; GetIntOverflow: PRIVATE PROC [ref: Ref, param: RealParam] RETURNS [value: INTEGER]; <<**** Apply operations>> ApplyAll: PROC [ref: Ref, node: TextNode.Ref, kind: OfStyle _ screen]; <> <> <> <<1. ApplyAll[ref, Parent[node]]>> <<2. ApplyForNode[ref, node, alt]>> <> <> ApplyForNode: PROC [ref: Ref, node: TextNode.Ref, alt: Name, kind: OfStyle _ screen]; <<1. ApplyObject[ref, node prefix object]>> <<2. ApplyType[ref, node type, alt]>> <<3. ApplyObject[ref, node postfix object]>> ApplyType: PROC [ref: Ref, name, alt: Name, kind: OfStyle _ screen]; <> <> ApplyLooks: PROC [ref: Ref, looks: TextLooks.Looks, kind: OfStyle _ screen]; <> ApplyObject: PROC [ref: Ref, object: NameSymbolTable.Object, kind: OfStyle _ screen]; <> OfStyle: TYPE = { screen, print, base }; StyleNameForNode: PROC [TextNode.Ref] RETURNS [Name]; <> FlushCaches: PROC; <<**** Other Operations>> Create: PROC RETURNS [Ref]; -- create a body Copy: PROC [dest, source: Ref]; -- copy a body Alloc: PROC RETURNS [Ref]; -- get from a small cache Free: PROC [Ref]; -- don't free more than once or disaster! LoadStyle: PROC [name: Name] RETURNS [ok: BOOLEAN]; <> <> ReloadStyle: PROC [name: Name] RETURNS [ok: BOOLEAN]; <> <<**** Initialization>> Start: PROC; END.