Thursday, April 17, 2014

Segments and printing in more than 72dpi

Printing is fairly straightforward in Realbasic (or Xojo if you will). If a call of OpenPrinterDialog returns a Graphics pointer that is not nil, then it is a simple drawing onto that Graphics object. It has the size of the available page, but of course in pixels. Probably to enable being truly cross-platform, the Realbasic printer has a resolution of 72dpi, even though the printer will be capable of much higher resolutions.

Luckily, drawing text with DrawString will draw crisp text in the high resolution of the printer. When drawing graphical shapes however the positioning is limited to the integer pixel coordinates. A widely written about solution to this is to draw the graphics on a Picture (Graphics) with a higher resolution and then use DrawPicture to draw it scaled down onto the printer Graphics. Then it will be drawn in the high printer resolution and you still can draw to actual dimensions. I.e. it is still possible to draw a line that is one inch long on paper.

By defining a magnification factor and then drawing a magnified Picture to be drawn scaled down by that same factor again on the printer's Graphics, more precise graphics is possible and the printer's (default) higher resolution is used. With the magnified Picture (BarsImage) already prepared, the menu handler for the print menu becomes simply:


  Dim h As Graphics
  h = OpenPrinterDialog
  If h<> Nil Then
    h.DrawPicture(BarsImage, 0, 0,BarsImage.Width/MagFactor, BarsImage.Height/MagFactor, 0, 0, BarsImage.Width, BarsImage.Height)
  End if
  Return True
 

This is all implemented in the small utility to draw strobe discs. Strobe discs are used to check or adjust the speed of turntables. There is no shortage of strobe disc images on the internet for download of course. This small utility allows fairly easy printing of a strobe disc with the settings you want. Source for the Strobe Maker project is downloadable, so you can tweak the design as desired.
Another item encountered was drawing speed. When drawing this particular graphics, the first obvious method tried was to use the ArcShape object and then draw a series of these rotated. (Drawing a white circle over the centre to make them bars.) This was very crisp and accurate, but really slow. The drawing of the whole shape with ~70 arc segments was slow; drawing 216 arc segments made the program freeze and think about that for almost a minute.

Oddly and fortunately drawing a FigureShape is much faster. Calculating the 4 points of the ArcShape (and accepting that the ends are straight lines) these FigureShape draws the 216 segments in just under a second on the same machine. Then drawing a white bounding circle even adds the rounded segment ends then.