In this section:
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 by specifying the USER_SURFACE option with %gr (Graphics Region).
When this option is used, an INTEGER(KIND=7) 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 (Graphics Region). 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(7) 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(7) 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 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. 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.