<> <> <> <<>> <> <<>> DIRECTORY Atom USING [MakeAtom], Imager USING [Color, Context, Error, MaskRectangleI, --MaskVector, SetStrokeEnd, SetStrokeWidth, --SetXYI, SetColor, SetFont, ShowRope, white, black], ImagerBackdoor USING [MakeStipple], ImagerFont USING [Font, FontBoundingBox, Scale, Find, Modify], ImagerOps USING [KindOf], ImagerTransformation USING [Scale2, Transformation], IO USING [GetInt, RIS], NodeStyle USING [FontFace, FontAlphabets], NodeStyleFont USING [FontFromStyleParams], Real USING [Fix], Rope USING [Concat, Fetch, Find, Length, Replace, ROPE, SkipTo, Substr], SilColor, SilCommand, SilDisplayInternal, SilDisplayUtils, SilFile, SilKernel, ViewRec USING [SampleRV] ; SilDisplayUtilsImplA: CEDAR MONITOR IMPORTS Atom, Imager, ImagerBackdoor, ImagerFont, ImagerOps, ImagerTransformation, IO, NodeStyleFont, Real, Rope, ViewRec, SilKernel, SilFile, SilColor EXPORTS SilDisplayUtils, SilKernel = BEGIN OPEN SilFile; ROPE: TYPE = Rope.ROPE; SilData: TYPE = SilKernel.SilData; SilDisplayData: TYPE = REF SilDisplayDataRec; SilDisplayDataRec: PUBLIC TYPE = SilDisplayInternal.SilDisplayDataRec; SilModel: TYPE = SilFile.SilModel; SilUIData: TYPE = SilKernel.SilUIData; <> <> allModelsFonts: ARRAY SilFile.InternalPresetFonts OF ImagerFont.Font; -- current fonts allModelsFontsAscents: ARRAY SilFile.InternalPresetFonts OF INTEGER; -- current fonts ascents allModelsItalicFonts: ARRAY SilFile.InternalPresetFonts OF ImagerFont.Font; allModelsItalicFontsAscents: ARRAY SilFile.InternalPresetFonts OF INTEGER; allModelsPFonts: ARRAY SilFile.InternalPresetFonts OF ImagerFont.Font; -- printing fonts allModelsPFontsAscents: ARRAY SilFile.InternalPresetFonts OF INTEGER; -- printing fonts ascents allModelsItalicPFonts: ARRAY SilFile.InternalPresetFonts OF ImagerFont.Font; allModelsItalicPFontsAscents: ARRAY SilFile.InternalPresetFonts OF INTEGER; allModelsDFonts: ARRAY SilFile.InternalPresetFonts OF ImagerFont.Font; -- display fonts allModelsDFontsAscents: ARRAY SilFile.InternalPresetFonts OF INTEGER; -- display fonts ascents allModelsItalicDFonts: ARRAY SilFile.InternalPresetFonts OF ImagerFont.Font; allModelsItalicDFontsAscents: ARRAY SilFile.InternalPresetFonts OF INTEGER; fontState: SilFile.FontType _ display; selectGrey: Imager.Color _ ImagerBackdoor.MakeStipple[122645B]; backgroundGrey: Imager.Color _ ImagerBackdoor.MakeStipple[102041B]; selectedBackgroundGrey: Imager.Color _ ImagerBackdoor.MakeStipple[100000B]; SilUtilsInit: PUBLIC PROC [] = { <> SilPrintFontsInit[]; -- this must be called before SilDisplayFontsInit is called !! SilDisplayFontsInit[]; UpEndFonts[]; -- turn fonts upside down to match Sil coordinate system with Y pointing down UsePrintFonts[]; -- required upon initialization because Sil files carry print font sizes internally }; UpEndFonts: PROC [] RETURNS [] ~ { <> xform: ImagerTransformation.Transformation _ ImagerTransformation.Scale2[s: [1.0, -1.0]]; FOR i: SilFile.InternalPresetFonts IN SilFile.InternalPresetFonts DO allModelsPFonts[i] _ ImagerFont.Modify[font: allModelsPFonts[i], m: xform]; allModelsPFontsAscents[i] _ Real.Fix[ImagerFont.FontBoundingBox[allModelsPFonts[i]].descent]; allModelsItalicPFonts[i] _ ImagerFont.Modify[font: allModelsItalicPFonts[i], m: xform]; allModelsItalicPFontsAscents[i] _ Real.Fix[ImagerFont.FontBoundingBox[allModelsItalicPFonts[i]].descent]; allModelsDFonts[i] _ ImagerFont.Modify[font: allModelsDFonts[i], m: xform]; allModelsDFontsAscents[i] _ Real.Fix[ImagerFont.FontBoundingBox[allModelsDFonts[i]].descent]; allModelsItalicDFonts[i] _ ImagerFont.Modify[font: allModelsItalicDFonts[i], m: xform]; allModelsItalicDFontsAscents[i] _ Real.Fix[ImagerFont.FontBoundingBox[allModelsItalicDFonts[i]].descent]; ENDLOOP; }; SilPrintFontsInit: PROC [] = { tFont: ImagerFont.Font _ NIL; fontNamePrefix: ROPE = "xerox/pressfonts/"; FOR fontIndex: PresetFonts IN PresetFonts DO fShortName: ROPE _ SilFile.FontNameFromInternalFont[fontIndex, print]; isBold, isItalic: BOOL _ FALSE; < Helvetica, 7)>> fSize, length: INTEGER _ 0; controlPos: INTEGER _ fShortName.SkipTo[0, "0123456789"]; control: ROPE _ fShortName.Substr[controlPos, fShortName.Length[] - controlPos]; fName: ROPE _ Rope.Concat[fontNamePrefix, fShortName.Substr[0, controlPos] ]; fTemp, fSuccessful: ROPE; < Helvetica, 7, bold)>> IF Rope.Find[s1: control, s2: "B", case: FALSE] # -1 THEN isBold _ TRUE; IF Rope.Find[s1: control, s2: "I", case: FALSE] # -1 THEN isItalic _ TRUE; fName _ Rope.Concat[fName, "-"]; IF isBold THEN fName _ Rope.Concat[fName, "B"] ELSE fName _ Rope.Concat[fName, "M"]; IF isItalic THEN fName _ Rope.Concat[fName, "I"] ELSE fName _ Rope.Concat[fName, "R"]; fName _ Rope.Concat[fName, "R"]; -- no more narrow fonts fTemp _ fName; length _ Rope.Length[fName]; <> fSize _ IO.GetInt[IO.RIS[control]]; fSuccessful _ fName; tFont _ ImagerFont.Find[fName ! Imager.Error => { fName _ Rope.Replace[fName, length - 3, 3, "MRR"]; fSuccessful _ fName; RETRY; };]; tFont _ allModelsPFonts[fontIndex*2] _ ImagerFont.Scale[tFont, fSize]; allModelsPFontsAscents[fontIndex*2] _ Real.Fix[ImagerFont.FontBoundingBox[tFont].ascent]; fName _ Rope.Replace[fName, length - 3, 1, "B"]; tFont _ ImagerFont.Find[fName ! Imager.Error => {fName _ fSuccessful; RETRY; };]; tFont _ allModelsPFonts[fontIndex*2 + 1] _ ImagerFont.Scale[tFont, fSize]; allModelsPFontsAscents[fontIndex*2 + 1] _ Real.Fix[ImagerFont.FontBoundingBox[tFont].ascent]; fTemp _ Rope.Replace[fTemp, length - 2, 1, "I"]; fSuccessful _ fTemp; tFont _ ImagerFont.Find[fTemp ! Imager.Error => { fTemp _ Rope.Replace[fTemp, length - 3, 3, "MRR"]; fSuccessful _ fTemp; RETRY; };]; tFont _ allModelsItalicPFonts[fontIndex*2] _ ImagerFont.Scale[tFont, fSize]; allModelsItalicPFontsAscents[fontIndex*2] _ Real.Fix[ImagerFont.FontBoundingBox[tFont].ascent]; fTemp _ Rope.Replace[fTemp, length - 3, 1, "B"]; tFont _ ImagerFont.Find[fTemp ! Imager.Error => {fTemp _ fSuccessful; RETRY;};]; tFont _ allModelsItalicPFonts[fontIndex*2 + 1] _ ImagerFont.Scale[tFont, fSize]; allModelsItalicPFontsAscents[fontIndex*2 + 1] _ Real.Fix[ImagerFont.FontBoundingBox[tFont].ascent]; ENDLOOP; }; <<>> SilDisplayFontsInit: PROC [] = { FindFont: PROC [index: InternalPresetFonts, prefix: ATOM, family: Rope.ROPE, face: NodeStyle.FontFace, size: REAL, alphabets: NodeStyle.FontAlphabets] RETURNS [ImagerFont.Font] ~ { f: ImagerFont.Font _ NodeStyleFont.FontFromStyleParams[prefix: prefix, family: Atom.MakeAtom[family], face: face, size: size, alphabets: alphabets]; IF Rope.Find[s1: f.name, s2: family, case: FALSE] = -1 THEN RETURN[IF face=Italic OR face=BoldItalic THEN allModelsItalicPFonts[index] ELSE allModelsPFonts[index]]; RETURN[f]; }; tFont: ImagerFont.Font; isBold, isItalic: BOOL _ FALSE; fSize: INTEGER _ 0; face: NodeStyle.FontFace; fontNamePrefix: ATOM = Atom.MakeAtom["xerox/tiogafonts/"]; FOR fontIndex: PresetFonts IN PresetFonts DO fShortName: ROPE _ SilFile.FontNameFromInternalFont[fontIndex, display]; < Helvetica, 7, bold)>> controlPos: INTEGER _ fShortName.SkipTo[0, "0123456789"]; control: ROPE _ fShortName.Substr[controlPos, fShortName.Length[] - controlPos]; fName: ROPE _ fShortName.Substr[0, controlPos]; IF Rope.Find[s1: control, s2: "B", case: FALSE] # -1 THEN isBold _ TRUE; IF Rope.Find[s1: control, s2: "I", case: FALSE] # -1 THEN isItalic _ TRUE; face _ SELECT TRUE FROM isBold AND isItalic => BoldItalic, isBold => Bold, isItalic => Italic, ENDCASE => Regular; <> fSize _ IO.GetInt[IO.RIS[control]]; <> tFont _ allModelsDFonts[fontIndex*2] _ FindFont[index: fontIndex*2, prefix: fontNamePrefix, family: fName, face: face, size: fSize, alphabets: CapsAndLower]; allModelsDFontsAscents[fontIndex*2] _ Real.Fix[ImagerFont.FontBoundingBox[tFont].ascent]; tFont _ allModelsDFonts[fontIndex*2 + 1] _ FindFont[index: fontIndex*2 + 1, prefix: fontNamePrefix, family: fName, face: Bold, size: fSize, alphabets: CapsAndLower]; allModelsDFontsAscents[fontIndex*2 + 1] _ Real.Fix[ImagerFont.FontBoundingBox[tFont].ascent]; tFont _ allModelsItalicDFonts[fontIndex*2] _ FindFont[index: fontIndex*2, prefix: fontNamePrefix, family: fName, face: Italic, size: fSize, alphabets: CapsAndLower]; allModelsItalicDFontsAscents[fontIndex*2] _ Real.Fix[ImagerFont.FontBoundingBox[tFont].ascent]; tFont _ allModelsItalicDFonts[fontIndex*2 + 1] _ FindFont[index: fontIndex*2 + 1, prefix: fontNamePrefix, family: fName, face: BoldItalic, size: fSize, alphabets: CapsAndLower]; allModelsItalicDFontsAscents[fontIndex*2 + 1] _ Real.Fix[ImagerFont.FontBoundingBox[tFont].ascent]; ENDLOOP; }; <<>> GetFont: PUBLIC PROC [font: SilFile.InternalFonts, italic: BOOL _ FALSE] RETURNS [fontRef: ImagerFont.Font] = { <> IF italic THEN RETURN [allModelsItalicFonts[font]] ELSE RETURN[allModelsFonts[font]]; }; UsePrintFonts: ENTRY PROC [] = { allModelsFonts _ allModelsPFonts; -- transfer entire array allModelsFontsAscents _ allModelsPFontsAscents; -- transfer entire array allModelsItalicFonts _ allModelsItalicPFonts; -- transfer entire array allModelsItalicFontsAscents _ allModelsItalicPFontsAscents; -- transfer entire array fontState _ print; }; UseDisplayFonts: ENTRY PROC [] = { allModelsFonts _ allModelsDFonts; -- transfer entire array allModelsFontsAscents _ allModelsDFontsAscents; -- transfer entire array allModelsItalicFonts _ allModelsItalicDFonts; -- transfer entire array allModelsItalicFontsAscents _ allModelsItalicDFontsAscents; -- transfer entire array fontState _ display; }; SwapFonts: PUBLIC PROC [data: SilData, ctx: Imager.Context] = { <> IF fontState = display THEN UsePrintFonts[] ELSE UseDisplayFonts[]; SilKernel.RepaintSilViewers[]; }; ChangeCommandLineData: PUBLIC PROC [data: SilData, ctx: Imager.Context, change: SilDisplayUtils.CommandChange _ Pos, boolArg: BOOL _ FALSE, intArg1: INTEGER _ 0, intArg2: INTEGER _ 0] = { <> dData: SilDisplayData _ data.displayData; commandLine: SilCommand.CommandRef _ NARROW[dData.commandLine]; SELECT change FROM Bold => { <> }; Italic => { <> }; Grid => { commandLine.Grid _ dData.currentGridSpacing _ intArg1; }; LineWidth => { commandLine.LineW _ dData.currentBoxWidth _ intArg1; }; Mag => { commandLine.Mag _ dData.currentMagnification _ intArg1; }; Font => { commandLine.Font _ dData.currentFont _ intArg1; }; Color => { dData.currentColor _ intArg1; commandLine.Color _ intArg1; <> }; MacExpand => { commandLine.MX _ dData.currentOneLevel _ boolArg; }; Ylock => { commandLine.Ylk _ dData.yLock _ boolArg; }; Selections => { commandLine.Selected _ dData.currentNumObjectsSelected _ intArg1; }; Pos => { commandLine.X _ intArg1; commandLine.Y _ intArg2; }; ENDCASE => ERROR; ViewRec.SampleRV[dData.viewRec]; }; PaintObject: PUBLIC PROC [model: SilModel, sobr: SilObjectRec, dMode: SilDisplayUtils.DisplayChoice, ctx: Imager.Context, oneLevel, foregroundOnly: BOOLEAN _ FALSE, print: BOOLEAN _ FALSE] = { <> <<>> SELECT dMode FROM show => Imager.SetColor[ctx, IF ImagerOps.KindOf[ctx] = $Bitmap THEN Imager.black ELSE SilColor.silColors[sobr.color]]; erase => Imager.SetColor[ctx, Imager.white]; select => Imager.SetColor[ctx, selectGrey]; ENDCASE; --no need to optimize calls to SetColor SELECT sobr.font FROM IN InternalPresetFonts => { fontRef: ImagerFont.Font; fontAscent: INTEGER _ 0; notPrint: BOOL _ NOT print; notItalic: BOOL _ NOT sobr.italic; SELECT TRUE FROM notItalic AND notPrint => { fontRef _ allModelsFonts[sobr.font]; fontAscent _ allModelsFontsAscents[sobr.font]; }; notItalic AND print => { fontRef _ allModelsPFonts[sobr.font]; fontAscent _ allModelsPFontsAscents[sobr.font]; }; sobr.italic AND notPrint => { fontRef _ allModelsItalicFonts[sobr.font]; fontAscent _ allModelsItalicFontsAscents[sobr.font]; }; sobr.italic AND print => { fontRef _ allModelsItalicPFonts[sobr.font]; fontAscent _ allModelsItalicPFontsAscents[sobr.font]; }; ENDCASE => ERROR; Imager.SetXYI[ctx, sobr.xMin, sobr.yMin + fontAscent]; --Put where belongs Imager.SetFont[ctx, fontRef]; --set the new font Imager.ShowRope[ctx, sobr.value]; }; IN InternalMacroFonts => { needFinalRepaint: BOOLEAN _ FALSE; currentX: INTEGER _ sobr.xMin; currentY: INTEGER _ sobr.yMin; FOR i: INT IN [0..Rope.Length[sobr.value]) DO c: CHAR _ Rope.Fetch[sobr.value, i]; mxMin, mxMax : INTEGER; [xMin: mxMin, yMin: , xMax: mxMax, yMax: ] _ SilFile.GetMacroBoundingBox[model, sobr.font, c]; FOR s: SilObject _ GetObjectList[model, macro, sobr.font, c], s.rest WHILE s # NIL DO macElem: SilObjectRec _ s.first; macElem.xMin _ macElem.xMin + currentX; macElem.yMin _ macElem.yMin + currentY; macElem.xMax _ macElem.xMax + currentX; macElem.yMax _ macElem.yMax + currentY; macElem.color _ sobr.color; <> IF macElem.font IN SilFile.InternalFileMacroFonts THEN macElem.font _ sobr.font; PaintObject[model, macElem, dMode, ctx, oneLevel, foregroundOnly, print]; IF macElem.font IN InternalBackgroundBoxFonts THEN needFinalRepaint _ TRUE; ENDLOOP; <> IF needFinalRepaint THEN { FOR s: SilObject _ GetObjectList[model, macro, sobr.font, c ], s.rest WHILE s # NIL DO macElem: SilObjectRec _ s.first; macElem.xMin _ macElem.xMin + currentX; macElem.yMin _ macElem.yMin + currentY; macElem.xMax _ macElem.xMax + currentX; macElem.yMax _ macElem.yMax + currentY; macElem.color _ sobr.color; PaintObject[model, macElem, dMode, ctx, TRUE, TRUE, print]; ENDLOOP; needFinalRepaint _ FALSE; }; currentX _ currentX + mxMax - mxMin; ENDLOOP; }; IN InternalForegroundBoxFonts => { Imager.MaskRectangleI[ctx, sobr.xMin, sobr.yMin, sobr.xMax - sobr.xMin, sobr.yMax - sobr.yMin]; }; IN InternalBackgroundBoxFonts => { IF foregroundOnly THEN RETURN; SELECT dMode FROM erase => Imager.MaskRectangleI[ctx, sobr.xMin, sobr.yMin, sobr.xMax - sobr.xMin, sobr.yMax - sobr.yMin]; show, select => { sSel: SilSelection _ GetSelection[]; IF dMode = show THEN Imager.SetColor[ctx, backgroundGrey] ELSE { Imager.SetColor[ctx, Imager.white]; Imager.MaskRectangleI[ctx, sobr.xMin, sobr.yMin, sobr.xMax - sobr.xMin, sobr.yMax - sobr.yMin]; Imager.SetColor[ctx, selectedBackgroundGrey]; }; Imager.MaskRectangleI[ctx, sobr.xMin, sobr.yMin, sobr.xMax - sobr.xMin, sobr.yMax - sobr.yMin]; <> IF oneLevel THEN RETURN; FOR s: SilObject _ GetObjectList[model: model, mode: fgnd], s.rest WHILE s # NIL DO IF IBBoxFilter[sobr.xMin, sobr.yMin, sobr.xMax, sobr.yMax, s.first] THEN PaintObject[model, s.first, show, ctx, TRUE, FALSE, print]; ENDLOOP; IF sSel.model = model THEN FOR s: SilObject _ sSel.objects, s.first.selectObj WHILE s # sSel.lastObject DO IF NOT SilFile.ObjectIsSelected[model, s] AND IBBoxFilter[sobr.xMin, sobr.yMin, sobr.xMax, sobr.yMax, s.first] THEN PaintObject[model, s.first, select, ctx, TRUE, FALSE, print]; ENDLOOP; }; ENDCASE; }; <<>> ENDCASE; }; IBBoxFilter: PROC [xMin, yMin, xMax, yMax: INTEGER, sobr: SilObjectRec] RETURNS [BOOL] = INLINE { <> RETURN[ NOT (yMin > sobr.yMax OR xMin > sobr.xMax OR yMax < sobr.yMin OR xMax < sobr.xMin)]; }; END. <<>> <> <> <> <>