Silverfrost Logo About Us | Contact Us
 

Direct manipulation of the graphics surface

Every call to a drawing surface routine involves one or more calls the Windows API in order to perform the operation. This is usually not a problem when high level operations such as line drawing are being performed. However, it might be desirable to bypass this mechanism and construct the surface directly, particularly in applications that manipulate images and that must therefore operate at the pixel level. This is possible under Win32 (not Win32S or Windows 3.1) by specifying the USER_SURFACE option with %gr.

When this option is used, an INTEGER*4 variable is placed immediately after the two size parameters. This variable will receive the address of a buffer containing the graphics contents stored using 3 bytes per pixel. By manipulating this array you can change the graphics surface directly. The INTEGER variable should be passed to window_update@ after such a manipulation to cause the screen to be updated.

Later versions of ClearWin+ may accelerate some function calls (such as draw_line_between@) by using this direct access method if USER_SURFACE is coded, but at present this is not the case.

The USER_SURFACE option implies the RGB_COLOURS option and must not be mixed with METAFILE_RESIZE, although it can be combined with USER_RESIZE. A trade-off is involved here. The user surface will usually require more memory than the device dependent bitmap that ClearWin+ normally uses to implement %gr. Also each re-draw of the window will be slower. However, if you implement pixel-by-pixel graphics by directly manipulating the buffer, you will see a substantial speed improvement over making calls to draw_point@. If USER_SURFACE is combined with USER_RESIZE then the surface pointer variable will be updated each time the window is re-sized. It is important not to copy this variable and so use an obsolete version of the pointer. The row of the buffer has a layout corresponding to the following array:

INTEGER*1 buffer(3,width)

The first index covers the colours as follows:

1

Blue

2

Green

3

Red


After each row a few bytes of padding are added if necessary to make the row a multiple of four bytes. The next row then follows. This layout is imposed by the Windows operating system and not by ClearWin+.

Here is a simple Fortran example:

      WINAPP
       INCLUDE <windows.ins>
       EXTERNAL draw
       INTEGER ptr
       COMMON ptr
       ia=winio@('%ww%pv%^gr[black,user_resize,'//
     +    'user_surface]',256,256,ptr,draw)
      END

      INTEGER FUNCTION draw()
       INCLUDE <windows.ins>
       INTEGER ptr
       COMMON ptr
       INTEGER width,depth,m,i,q,x,y,full_on,pad_width
       IF(clearwin_info@('graphics_resizing').eq.1)THEN
         width=clearwin_info@('graphics_width')
         depth=clearwin_info@('graphics_depth')
         m=MIN(width,depth)
  c---   Calculate width in bites of one row
  c---   remembering to round up to nearest 4 bytes
         pad_width=ls(rs(3*width+3,2),2)
  c---   Draw a diagonal yellow line
         DO i=1,m
             x=i-1
             y=i-1
  c---       Compute index into array
             q=3*x+pad_width*y
             full_on=255
  c---       Red component 
             CORE1(ptr+q+2)=full_on
  c---       Green component
             CORE1(ptr+q+1)=full_on
         ENDDO
       ENDIF
       draw=2
      END

Note that it is possible (and often very useful) to mix calls to ClearWin+ graphics routines and direct manipulation of the pixel buffer. If you do this under Windows NT you must call the API function GdiFlush() to ensure that the effect of any previous function calls have 'flushed through' before you manipulate the buffer directly. This call is harmless but unnecessary under Windows 95. If you intend to perform all your graphics by direct buffer manipulation this need not concern you.

If you want to display a large image but do not have the screen space to do so or if you are producing a graphics and text output window, the routine scroll_graphics@ will be of great use. This routine will allow you to scroll graphics in any direction by any displacement (see scroll_graphics@).

 

 

Copyright © 1999-2017 Silverfrost Limited