3 Adding the City Map

Having the program skeleton set up, the next issue considered, is the map of the city that is to be displayed in the Canvas. One way to display this map is to use an instance of the Predefined Graphical Object Rect, which describes a Rectangle, and then fill it with a TiledSolidColor using the BitMap for tiling. A TiledSolidColor is a solid color, e.g. black, which also has a Bitmap, a so called tile. When filling with a TiledSolidColor, only the bits in the tile, which are TRUE, will be painted. The tile will be replicated as many times as needed to fill out the Shape, hence the name.

Given that the bit map of the city map is in the file ~beta/bifrost/bitmaps/Aarhus.pbm in the PBM format discussed in [MIA 91-13], Chapter 5, the TiledSolidColor may be declared as follows in subway2.bet:

aarhus: @TiledSolidColor
      (# bits: @bitMap
            (#
            do 'Reading in map ... ' -> puttext;
               '~beta/bifrost/bitmaps/Aarhus.pbm' 
                 -> readFromPBMfile;
               'done' -> putline;
               (0,0) -> hotspot;
            #);   
         
         init::
            (#
            do black -> name;
               bits -> thetile;
            #)
      #);

The BitMap is read from the PBM file using ReadFromPBMFile. This may take a while, and to inform the user of what is going on, some explanatory text is written out on the screen. The hotspot of the BitMap is set to (0,0). This is to control the placement of the BitMap within the Rect, that it will be used to fill out.

In the TiledSolidColor, init simply evaluates the BitMap, and assigns the result of the evaluation, which is a reference to the BitMap, to the theTile attribute of the TiledSolidColor. It also evaluates the pattern black and assigns the result to the name attribute. This will make the bits of the tile, which are set, appear black on the screen. The black pattern is declared in the fragment ~beta/bifrost/ColorNames which must be INCLUDEd in subway2.bet.

With this definition of the TiledSolidColor, the Rect may then be declared as follows:

map: @Rect
   (# 
      init::
         (#
         do (* Make THIS(Rect) the size of the aarhus-bitmap *)
            aarhus.init;
            (0,aarhus.bits.height) -> upperleft;
            aarhus.bits.width -> width;
            aarhus.bits.height -> height;
            aarhus[] -> setpaint;
         #)
    #);

In the Rect, init first initializes the TiledSolidColor called aarhus which in turns reads the bitmap from the PBM file as described above. Then upperleft, width and height are set using the dimensions of the BitMap. Finally a reference to the TiledSolidColor is given to the setpaint attribute of the Rect, thus making aarhus be used as the paint to fill the Rect with. The shape of the Rect has a default hotspot in the upper left corner. When a graphical object is filled with a TiledSolidColor, the hotspot of theTile of the TiledSolidColor is placed in the hotspot of the Shape of the graphical object, and theTile is then replicated as needed to fill out the entire Shape. Thus having defined the hotspot of aarhus.bits to (0,0) and made the Rect have the exact dimensions of the BitMap, the BitMap will be shown exactly once within the Rect.

All that is needed now is to initialize and draw the Rect. It is initialized in myCanvas.open:

open:: 
  (# 
  do (* Make THIS(BifrostCanvas) the size of the map *)
     map.init;
     (map.width, map.height)->Size->theWindow.size;
  #);

Instead of the arbitrary size used in subway1.bet, the Canvas is given the same dimensions as the Rect containing the BitMap. Now the Rect is ready to be drawn when the Canvas has become visible on the screen. Thus myCanvas.onOpen becomes:

onOpen:: (# do map[] -> draw; #);

The predefined graphical object Rect is defined in a separate fragment, ~beta/bifrost/PredefinedGO, which must be INCLUDEd in subway2.bet.


The Bifrost Graphics System - Tutorial
© 1991-2002 Mjølner Informatics
[Modified: Sunday October 15th 2000 at 15:36]