<> <> DIRECTORY Basics, CD, CDApplications, CDCells, CDDirectory, CDInline, CDInterestRects, CDOps, CDRects, CDSequencer, CDX, CornerStitching, Graphics, GraphicsBasic, GraphicsOps, Real, Rope, TerminalIO; CreateFont: CEDAR PROGRAM IMPORTS Basics, CD, CDApplications, CDCells, CDDirectory, CDInline, CDInterestRects, CDOps, CDSequencer, CDRects, CDX, CornerStitching, Graphics, GraphicsOps, Real, Rope, TerminalIO = BEGIN scale: INT ; -- arbitrary choice, if font is defined as n pixels high, unscaled chars will be n/2 designNumbers high design: CD.Design; unitSize: CD.DesignPosition; metal, poly: CD.Level; baseLine, finalBaseLine: CD.ApplicationPtr; tes: REF CornerStitching.Tesselation; CellInfoRef: TYPE = REF CellInfo; CellInfo: TYPE = RECORD [ cell: CD.ObPtr, relOrigin: CD.ApplicationPtr ] ; cellArray: ARRAY CHAR OF Rope.ROPE _ ALL[NIL] ; IncludeRect: PROC [ x, y: LONG CARDINAL, cell: CD.ObPtr, relOrigin: CD.ApplicationPtr] = BEGIN cdx, cdy: INT; rect: CD.ObPtr _ CDRects.CreateRect[ size: unitSize, l: metal] ; apPtr: CD.ApplicationPtr; cdx _ x; cdy _ y; apPtr _ CDApplications.NewApplicationI[ob: rect, location: [x: cdx*scale, y: y*scale] ] ; [] _ CDCells.IncludeApplication[design: design, cell: cell, aptr: apPtr, draw: FALSE, relativeTo: relOrigin] ; END; -- IncludeRect IncludeTile: CornerStitching.PerTileProc = <> BEGIN rect: CD.ObPtr _ CDRects.CreateRect[ size: [x: (tile.EastEdge - tile.WestEdge), y: (tile.NorthEdge - tile.SouthEdge)] , l: metal] ; cellInfo: CellInfoRef _ NARROW[data, CellInfoRef] ; apPtr: CD.ApplicationPtr _ CDApplications.NewApplicationI[ob: rect, location: [x: tile.WestEdge, y: tile.SouthEdge ] ] ; [] _ CDCells.IncludeApplication[design: design, cell: cellInfo.cell, aptr: apPtr, draw: FALSE, relativeTo: cellInfo.relOrigin] ; END; -- IncludeTile NoteMetalRectangle: PROC [ r: CD.DesignRect, l: CD.Level, pr: CD.DrawRef ] = BEGIN IF CDInline.NonEmpty[r] THEN BEGIN IF CD.LevelKey[l] = $met THEN tes.ChangeRect[rect: r, newValue: $covered] ; END; END; -- NoteMetalRectangle DrawCell: PROC [cell: CD.ObPtr] RETURNS [CD.ApplicationPtr] = BEGIN app: CD.ApplicationPtr; name: Rope.ROPE; cellptr: CD.CellPtr; DO cellptr _ NARROW[cell.specificRef, CD.CellPtr] ; name _ cellptr.name; app _ CDX.IncludeRelative[design: design, ob: cell, cellPosition: [0,0] , obPosition: CDInline.BaseOfRect[CDInterestRects.GetInterestRect[cell] .r] , orientation: 0, coordSystem: outerCoordinates ] ; RETURN [app] ENDLOOP END; -- DrawCell PlaceAndCornerStitch: PROC[cell: CD.ObPtr] = BEGIN data: CellInfoRef _ NEW[CellInfo] ; ap: CD.ApplicationPtr; cornerCell: CD.ObPtr; cellPtr: CD.CellPtr; dr: CD.DrawRef = CD.NewNullDeviceDrawRef[design] ; tes _ CornerStitching.NewTesselation[] ; dr.minimalSize _ 0; dr.drawRect _ dr.saveRect _ NoteMetalRectangle; dr.worldClip _ CDInline.universe; <> ap _ DrawCell[cell] ; <> CDOps.DrawDesign[design, dr] ; <> { cornerCell _ CDCells.CreateEmptyCell[]; cellPtr _ NARROW[cornerCell.specificRef, CD.CellPtr] ; cellPtr.name _ Rope.Replace[ base: NARROW[cell.specificRef, CD.CellPtr].name, start: 0, len: 1, with: NIL]; cornerCell.size _ [x: [] _ CDDirectory.Include[design: design, object: cornerCell] ; [] _ CDCells.IncludeApplication[design: design, cell: cornerCell, aptr: baseLine, draw: FALSE] ; }; <> data.cell _ cornerCell; data.relOrigin _ baseLine; [] _ tes.EnumerateArea[rect: [x1: 0, y1: 0, x2: cell.size.x, y2: cell.size.y] , perTile: IncludeTile, data: data] ; CornerStitching.FreeTesselation[plane: tes] ; <> [] _ CDCells.IncludeApplication[design: design, cell: cornerCell, aptr: finalBaseLine, draw: FALSE, relativeTo: baseLine] ; [] _ CDCells.RemoveApplication[design: design, cell: cornerCell, aptr: baseLine, draw: FALSE] ; <> CDOps.RemoveApplication[design: design, aptr: ap, draw: FALSE] ; END; -- PlaceAndCornerStitch MakeCDFont: PROC [ fontName: Rope.ROPE] = BEGIN xmin,ymin,xmax,ymax: REAL; xw,yw: REAL; bitsRef: LONG POINTER TO CARDINAL; j, k, i: LONG CARDINAL; width, bits: CARDINAL; bitmap: GraphicsOps.BitmapRef; pixContext: Graphics.Context; fontRef: Graphics.FontRef _ Graphics.MakeFont[fontName] ; <> [xmin,ymin,xmax,ymax] _ Graphics.FontBox[fontRef] ; bitmap _ GraphicsOps.NewBitmap[width: Real.RoundC[(xmax - xmin)] , height: Real.RoundC[(ymax - ymin)] ] ; <<>> pixContext _ GraphicsOps.NewContextFromBitmap[bitmap] ; FOR char: CHAR IN CHAR DO { <> Graphics.SetCP[self: pixContext, x: 0-xmin, y: 0-ymin] ; <> [] _ pixContext.SetPaintMode[opaque] ; pixContext.SetColor[Graphics.white] ; pixContext.DrawBox[[xmin: 0, ymin: 0, xmax: (xmax - xmin), ymax: (ymax - ymin)] ] ; [] _ pixContext.SetPaintMode[transparent] ; pixContext.SetColor[Graphics.black] ; IF cellArray[char] # NIL THEN { charCell: CD.ObPtr _ CDCells.CreateEmptyCell[] ; cellPtr: CD.CellPtr _ NARROW[charCell.specificRef, CD.CellPtr] ; charCell.size _ [x: Real.RoundI[(xmax - xmin)] , y: Real.RoundI[(ymax - ymin)] ] ; [] _ CDDirectory.Include[design: design, object: charCell] ; cellPtr.name _ cellArray[char]; [xw: xw, yw: yw] _ Graphics.CharWidth[font: fontRef, char: char] ; Graphics.DrawChar[self: pixContext, char: char, font: fontRef] ; <> <> <> baseLine _ CDApplications.NewApplicationI[ ob: CDRects.CreateRect[size: [x: Real.RoundI[xw] , y: 1] , l: poly] , location: [x: 0, y: 0 ] ] ; [] _ CDCells.IncludeApplication[design: design, cell: charCell, aptr: baseLine, draw: FALSE] ; <> FOR j IN [0..bitmap.height) DO { FOR k IN [0..bitmap.raster) DO TRUSTED { bitsRef _ LOOPHOLE[bitmap.base, LONG POINTER TO CARDINAL] + (INT[bitmap.raster] *j + k); bits _ bitsRef^; width _ MIN[Basics.bitsPerWord, bitmap.width-(Basics.LowHalf[k] *Basics.bitsPerWord)] ; FOR i IN [0..width) DO { IF Basics.BITAND[bits, 32768] = 32768 THEN IncludeRect[k*Basics.bitsPerWord + i, bitmap.height - j, charCell, baseLine] ; bits _ Basics.BITSHIFT[value: bits, count: 1] ; }; ENDLOOP; }; ENDLOOP; }; ENDLOOP; <> finalBaseLine _ CDApplications.NewApplicationI[ ob: CDRects.CreateRect[size: [x: (Real.RoundI[xw] +1)*scale, y: 1+scale] , l: poly] , location: [x: Real.RoundI[-xmin] *scale, y: Real.RoundI[-ymin] *scale] ] ; [] _ CDCells.IncludeApplication[design: design, cell: charCell, aptr: finalBaseLine, draw: FALSE, relativeTo: baseLine] ; [] _ CDCells.RemoveApplication[design: design, cell: charCell, aptr: baseLine, draw: FALSE] ; <> PlaceAndCornerStitch[cell: charCell] ; <> [] _ CDDirectory.Remove[design: design, name: cellArray[char]]; }; }; ENDLOOP; END; -- MakeCDFont CreateCDFont: PROC[ comm: CDSequencer.Command] = BEGIN fontName: Rope.ROPE _ TerminalIO.RequestRope["Input font name -> "] ; scale _ TerminalIO.RequestInt["Input scale (INT) -> "]; unitSize _ [x: 1+scale, y: 1+scale]; design _ comm.design; metal _ CD.FetchLevel[t: design.technology, uniqueKey: $met] ; poly _ CD.FetchLevel[t: design.technology, uniqueKey: $pol] ; MakeCDFont[fontName] ; TerminalIO.WriteRope["Done with font\n"] ; TerminalIO.WriteRope["*************\n"] ; END; -- CreateCDFont Init: PROC[] = BEGIN cellArray['a] _ "#LA"; cellArray['b] _ "#LB"; cellArray['c] _ "#LC"; cellArray['d] _ "#LD"; cellArray['e] _ "#LE"; cellArray['f] _ "#LF"; cellArray['g] _ "#LG"; cellArray['h] _ "#LH"; cellArray['i] _ "#LI"; cellArray['j] _ "#LJ"; cellArray['k] _ "#LK"; cellArray['l] _ "#LL"; cellArray['m] _ "#LM"; cellArray['n] _ "#LN"; cellArray['o] _ "#LO"; cellArray['p] _ "#LP"; cellArray['q] _ "#LQ"; cellArray['r] _ "#LR"; cellArray['s] _ "#LS"; cellArray['t] _ "#LT"; cellArray['u] _ "#LU"; cellArray['v] _ "#LV"; cellArray['w] _ "#LW"; cellArray['x] _ "#LX"; cellArray['y] _ "#LY"; cellArray['z] _ "#LZ"; cellArray['A] _ "#UA"; cellArray['B] _ "#UB"; cellArray['C] _ "#UC"; cellArray['D] _ "#UD"; cellArray['E] _ "#UE"; cellArray['F] _ "#UF"; cellArray['G] _ "#UG"; cellArray['H] _ "#UH"; cellArray['I] _ "#UI"; cellArray['J] _ "#UJ"; cellArray['K] _ "#UK"; cellArray['L] _ "#UL"; cellArray['M] _"#UM"; cellArray['N] _ "#UN"; cellArray['O] _ "#UO"; cellArray['P] _ "#UP"; cellArray['Q] _"#UQ"; cellArray['R] _ "#UR"; cellArray['S] _ "#US"; cellArray['T] _ "#UT"; cellArray['U] _ "#UU"; cellArray['V] _ "#UV"; cellArray['W] _"#UW"; cellArray['X] _ "#UX"; cellArray['Y] _ "#UY"; cellArray['Z] _"#UZ"; cellArray['1] _"#N1"; cellArray['2] _"#N2"; cellArray['3] _"#N3"; cellArray['4] _ "#N4"; cellArray['5] _ "#N5"; cellArray['6] _ "#N6"; cellArray['7] _ "#N7"; cellArray['8] _ "#N8"; cellArray['9] _ "#N9"; cellArray['0] _ "#N0"; cellArray['/ ] _ "#SLASH"; cellArray['(] _ "#LEFTPAREN"; cellArray[':] _ "#COLON"; cellArray[')] _ "#RIGHTPAREN"; cellArray[',] _ "#COMMA"; cellArray['.] _ "#PERIOD"; cellArray['#] _ "#SPLAT"; cellArray['$] _ "#DOLLARSIGN"; cellArray['!] _ "#EXCLMARK"; cellArray['%] _ "#PERCENT"; cellArray['&] _ "#AMPERSAND"; cellArray['*] _ "#ASTERISK"; cellArray['?] _ "#QUESTIONMARK"; CDSequencer.ImplementCommand[$MirrorS, CreateCDFont] ; END; <> Init[]; END.