home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 9 / CDACTUAL9.iso / share / Dos / VARIOS / siena / oplexam / B06GRAPH.TXT < prev    next >
Encoding:
Text File  |  1994-09-06  |  41.4 KB  |  1,115 lines

  1.  
  2.  
  3.  
  4. Graphics
  5.  
  6. OPL graphics allows you, for example, to:
  7.  
  8. Draw lines and boxes.
  9.  
  10. Fill areas with patterns.
  11.  
  12. Display text in a variety of styles, at any position 
  13. on the screen.
  14.  
  15. Scroll areas of the screen.
  16.  
  17. Manipulate windows and bit patterns.
  18.  
  19. Read data back from the screen.
  20.  
  21. You can draw using black, grey and white.
  22.  
  23. Graphics keywords begin a "G". In this manual a 
  24. lower case "g" is used  for example, "gBOX"  
  25. but you can type them using upper or lower case letters.
  26.  
  27. IMPORTANT: Some graphics keywords are mentioned only 
  28. briefly in this chapter. For more details about them, see the `Alphabetic 
  29. listing' chapter.
  30.  
  31.  
  32.  
  33.  
  34.  
  35. ------------------------------------
  36. ************ Simple graphics
  37.  
  38. The Series 3a screen is made up of a regular pattern of 480 points 
  39. across by 160 down. These points are sometimes referred to as pixels. 
  40.  
  41.  
  42. Each pixel is identified 
  43. by two numbers, giving its position across and down from the top left 
  44. corner of the screen. 0,0 denotes the pixel in the top left corner; 
  45. 2,1 is the pixel 2 points across and one down, and so on. 479,159 
  46. is the pixel in the bottom right corner.
  47.  
  48. Note that these co-ordinates are very different to the cursor positions 
  49. set by the AT command.
  50.  
  51. OPL maintains a current position on the screen. Graphics 
  52. commands which draw on the screen generally take effect at this position. 
  53. Initially, the current position is the top left corner, 0,0.
  54.  
  55. You can draw using black, grey and white although grey is not accessible 
  56. by default. See the section `Drawing in grey' below for further details.
  57.  
  58.  
  59. ****** Screen positions
  60.  
  61. *** Drawing lines
  62.  
  63. Here is a simple procedure to draw a horizontal line in the middle 
  64. of the screen:
  65.  
  66. PROC lines:
  67.   gMOVE 180,80
  68.   gLINEBY 120,0
  69.   GET
  70. ENDP
  71.  
  72. gMOVE moves the current 
  73. position by the specified amount. In this case, it moves the current 
  74. position 180 pixels right and 80 down, from 0,0 to 180,80. It does 
  75. not display anything on the screen.
  76.  
  77. gLINEBY (g-Line-By) draws a line from the current position 
  78. (just set to 180,80) to a point at the distance you specify  
  79. in this case 120 to the right and 0 down, ie 300,80.
  80.  
  81. When drawing a horizontal line, as in the above example, the line 
  82. that is drawn includes the pixel with the lower x coordinate and excludes 
  83. the pixel with the higher x coordinate. Similarly, when drawing a 
  84. vertical line, the line includes the pixel with the lower y coordinate 
  85. and excludes the pixel with the higher y coordinate.
  86.  
  87. On the Series 3a screen the y coordinate decreases as you 
  88. move toward the top of the screen.
  89.  
  90. When drawing a diagonal line, the coordinates of the end pixels are 
  91. turned into a rectangle. The top left pixel lies inside the boundary 
  92. of this rectangle and the bottom right pixel lies outside it. The 
  93. line drawing algorithm then fills in those pixels that are intersected 
  94. by a mathematical line between the corners of the rectangle. Thus 
  95. the line will be drawn minus one or both end points.
  96.  
  97. gLINEBY also has the effect of moving the current position 
  98. to the end of the line it draws.
  99.  
  100. With both gMOVE and gLINEBY, you specify positions relative 
  101. to the current position. Most OPL graphics commands do likewise. 
  102. gMOVE and gLINEBY, however, do have corresponding commands 
  103. which use absolute pixel positions. gAT moves 
  104. to the pixel position you specify; gLINETO 
  105. draws a line from the current position to an absolute position. The 
  106. horizontal line procedure could instead be written:
  107.  
  108. PROC lines:
  109.   gAT 180,80
  110.   gLINETO 300,80
  111.   GET
  112. ENDP
  113.  
  114. gAT and gLINETO may be useful in very short graphics 
  115. programs, and gAT is always the obvious command for moving 
  116. to a particular point on the screen, before you start drawing. But 
  117. once you do start drawing, use gMOVE and gLINEBY. They 
  118. make it much easier to develop and change programs, and allow you 
  119. to make useful graphics procedures which can display things anywhere 
  120. you set the current position. Almost all graphics drawing commands 
  121. use relative positioning for these reasons.
  122.  
  123. *** Drawing dots
  124.  
  125. You can set the pixel at the current position with "gLINEBY 0,0".
  126.  
  127. *** Right and down, left and up
  128.  
  129. gMOVE and gLINEBY find the position to use by adding 
  130. the numbers you specify onto the current position. If the numbers 
  131. are positive, it moves to the right and down the screen. If you use 
  132. negative numbers, however, you can specify positions to the left of 
  133. and/or above the current position. For example, this procedure draws 
  134. the same horizontal line as before, then another one above it:
  135.  
  136. PROC lines2:
  137.   gMOVE 180,80
  138.   gLINEBY 120,0
  139.   gMOVE 0,-20
  140.   gLINEBY -120,0
  141.   GET
  142. ENDP
  143.  
  144. The first two program lines are the same as before. gLINEBY 
  145. moves the current position to the end of the line it draws, so after 
  146. the first gLINEBY the current position is 300,80. The second 
  147. gMOVE moves the current position up by 20 pixels; the 
  148. second gLINEBY draws a line to a point 120 pixels to the left.
  149.  
  150. For horizontal and vertical lines, the right-hand/bottom pixel 
  151. is not set. For diagonal lines, the right-most and bottom-most pixels 
  152. are not set; these may be the same pixel.
  153.  
  154. *** Going off the screen
  155.  
  156. No error is reported if you try to draw off the edge of the screen. 
  157. It is quite possible to leave the current position off the screen  
  158. for example, "gLINETO 600,80" will draw a line from the current 
  159. position to some point on the right-hand screen edge, but the current 
  160. position will finish as 600,80.
  161.  
  162. There's no harm in the current position being off the screen. It allows 
  163. you to write procedures to display a certain pattern at the current 
  164. position, and not have to worry whether that position is too close 
  165. to the screen edge for the whole pattern to fit on.
  166.  
  167. *** Clearing the screen
  168.  
  169. "gCLS" clears the screen.
  170.  
  171.  
  172. ******  Drawing in grey
  173.  
  174. *** Initialising for the use of grey
  175.  
  176. To draw in grey you need to use "DEFAULTWIN 1" 
  177. at the start of your program. (Note that this clears the screen.) 
  178. Grey is not automatically available because it requires twice the 
  179. memory (and takes longer to scroll or move) compared to having just 
  180. black. So programs that do not need to use grey are not unnecessarily 
  181. penalised. 
  182.  
  183. "DEFAULTWIN 0" disables the use of grey again, also clearing 
  184. the screen.
  185.  
  186. It is not possible to have a screen using grey only. 
  187.  
  188. "DEFAULTWIN 1" does not cause PRINT to print in grey  
  189. it applies only to graphics and graphics text (see gPRINT  later).
  190.  
  191. When you use "DEFAULTWIN 1" the existing black-only screen is 
  192. cleared and replaced by one which contains a black plane and 
  193. also a grey plane. The black plane is also sometimes called 
  194. the the normal plane. These are referred to as `planes' because 
  195. intuitively it is simplest to think of there being a plane of black 
  196. pixels in front of (or on top of) a plane of grey pixels, with 
  197. any grey only ever visible if the black pixel in front of it is clear.
  198.  
  199. If you draw a pixel using both black and grey, it will appear black. 
  200. If you then clear the black plane only, the same pixel will appear 
  201. grey. If you draw a pixel using grey only it will appear grey unless 
  202. it is already black, in which case it is effectively hidden behind 
  203. the black plane.
  204.  
  205. If you need to use grey, you are recommended to use "DEFAULTWIN 1" 
  206. once and for all at the start of your program. One reason is because 
  207. DEFAULTWIN can fail with a `No system memory' error and it is unlikely that you would 
  208. want to continue without grey after trying to enable it.
  209.  
  210. Note that gXBORDER, gBUTTON  and gDRAWOBJECT  all 
  211. use grey and therefore can only be used when grey in enabled. If grey 
  212. is not enabled, they raise a `General 
  213. failure' error.
  214.  
  215. *** Using grey
  216.  
  217. Once you have used "DEFAULTWIN 1" you can use the gGREY 
  218. command to set which plane should be used for all subsequent graphics 
  219. drawing (until the next use of gGREY).
  220.  
  221. "gGREY 0"     draws to the black plane only.
  222. "gGREY 1"     draws to the grey plane only.
  223. "gGREY 2"     draws to both planes.
  224.  
  225. "gGREY 1" and "gGREY 2" raise an error if the current 
  226. window does not have a grey plane.
  227.  
  228. As mentioned earlier, when you set a pixel using both black and grey, 
  229. the pixel appears black because the black plane is effectively in 
  230. front of the grey plane. So drawing to both planes is generally only 
  231. used for clearing pixels. For example, if your screen has both black 
  232. and grey pixels, gCLS will clear the pixels only in the plane 
  233. selected by gGREY. To clear the whole screen with gCLS, 
  234. you therefore need "gGREY 2".
  235.  
  236. To draw in grey when the pixels to which you are drawing are currently 
  237. black, you first need to clear the black.
  238.  
  239. A pixel will appear white only if it is clear in both planes.
  240.  
  241. *** Example
  242.  
  243. The following procedure initialises the screen to allow grey, draws 
  244. a horizontal line in grey, another below it in black only and a third 
  245. below it in both black and grey. Pressing a key clears the black plane 
  246. only, revealing the grey behind the black in the bottom line and clearing 
  247. the middle line altogether.
  248.  
  249. PROC exgrey:
  250.   DEFAULTWIN 1                       REM enable grey
  251.   gAT 0,40  :gGREY 1 :gLINEBY 480,0  REM grey only
  252.   gAT 0,41  :gLINEBY 480,0
  253.   gAT 0,80  :gGREY 0 :gLINEBY 480,0  REM black only
  254.   gAT 0,81  :gLINEBY 480,0
  255.   gAT 0,120 :gGREY 2 :gLINEBY 480,0  REM both planes
  256.   gAT 0,121  :gLINEBY 480,0
  257.   GET
  258.   gGREY 0                            REM black only
  259.   gCLS                               REM clear it
  260.   GET
  261. ENDP
  262.  
  263.  
  264. ****** Overwriting pixels
  265.  
  266. *** Drawing rectangles
  267.  
  268. The gBOX command draws a box outline. For example, 
  269. "gBOX 100,20" draws a box from the current position to a point 
  270. 100 pixels to the right and 20 down. If the current position were 
  271. 200,40, the four corners of this box would be at 200,40, 300,40, 300,60 
  272. and 200,60.
  273.  
  274. If you have used "DEFAULTWIN 1" and gGREY as described 
  275. earlier, the box is drawn to the black and/or grey plane as selected.
  276.  
  277. gBOX does not change the current position.
  278.  
  279. gFILL draws a filled box in the same way as 
  280. gBOX draws a box outline, but it has a third argument to say 
  281. which pixels to set. If set to 0, the pixels which make up the box 
  282. would be set. If set to 1, pixels are cleared; if set to 2, they are 
  283. inverted, that is, pixels already set on the screen become cleared, 
  284. and vice versa. The values 1 and 2 are used when overwriting 
  285. areas of the screen which already have pixels set.
  286.  
  287. If you have used "DEFAULTWIN 1" and gGREY as described 
  288. earlier, the filled box will be set, cleared or inverted in the black 
  289. and/or grey plane as selected. Once again, it helps to think of the 
  290. pixels being set or clear in each plane independently: so clearing 
  291. the pixel in the black plane reveals the grey plane behind it where 
  292. the pixel may be set or clear.
  293.  
  294. So with "gGREY 1" set for drawing to the grey plane only, inverting 
  295. the pixels in the filled box will change the grey plane only  
  296. black pixels are left alone but clear or grey pixels are inverted 
  297. to grey and clear pixels respectively. Similarly, inverting the black 
  298. plane changes clear pixels to black, but "clearing" black pixels displays 
  299. grey if the pixel is set in the grey plane.
  300.  
  301. This procedure displays a "robot" face, using gFILL to draw 
  302. set and cleared boxes:
  303.  
  304. PROC face:
  305.   gFILL 120,120,0 REM set the entire face
  306.   gMOVE 10,20 :gFILL 30,20,1 REM left eye
  307.   gMOVE 70,0 :gFILL 30,20,1 REM right eye
  308.   gMOVE -30,30 :gFILL 20,30,1 REM nose
  309.   gMOVE -20,40 :gFILL 60,20,1 REM mouth
  310.   GET
  311. ENDP
  312.  
  313. Before calling such a procedure, you would set the current position 
  314. to be where you wanted the top left corner of the head.
  315.  
  316. You could make the robot wink with the following procedure, which 
  317. inverts part of one eye:
  318.  
  319. PROC wink:
  320.   gMOVE 10,20 REM move to left eye
  321.   gFILL 30,14,2 REM invert most of the eye
  322.   PAUSE 10
  323.   gFILL 30,14,2 REM invert it back again
  324.   GET
  325. ENDP
  326.  
  327. Again, you would set the current position before calling this.
  328.  
  329. The gPATT command can be used to draw a shaded 
  330. filled rectangle. To do this, use "-1" as its first argument, 
  331. then the same three arguments as for gFILL  width, height, 
  332. and overwrite method. Overwrite methods 0, 1 and 2 apply only to the 
  333. pixels which are `on' in the shading pattern. Whatever was on the 
  334. screen may still show through, as those pixels which are `clear' in 
  335. the shading pattern are left as they were.
  336.  
  337. To completely overwrite what was on the screen with the shaded pattern, 
  338. gPATT has an extra overwrite method of 3. So, for example, 
  339. "gPATT -1,120,120,3" in the first procedure would have displayed 
  340. a shaded robot head, whatever may have been on the screen.
  341.  
  342. Again, the shaded pattern will be drawn in grey if you have selected 
  343. the grey plane only using "gGREY 1". And again, if you are writing 
  344. to the black plane only, any pixels set in the grey plane can be seen 
  345. if the corresponding pixels in the black plane are clear.
  346.  
  347. *** Overwriting with any drawing command
  348.  
  349. By using the gGMODE command, any drawing 
  350. command such as gLINEBY or gBOX can be made to clear 
  351. or invert pixels, instead of setting them. gGMODE determines 
  352. the effect of all subsequent drawing commands.
  353.  
  354. The values are the same as for gFILL: "gGMODE 1" for 
  355. clearing pixels, "gGMODE 2" for inverting pixels, and "gGMODE 0" 
  356. for setting pixels again. (0 is the initial setting.)
  357.  
  358. For example, some white lines can give the robot a furrowed brow:
  359.  
  360. PROC brow:
  361.   gGMODE 1 REM gLINEBY will now clear pixels
  362.   gMOVE 10,8 :gLINEBY 100,0
  363.   gMOVE 0,4 :gLINEBY -100,0
  364.   gGMODE 0
  365.   GET
  366. ENDP
  367.  
  368. The setting for gGMODE applies to the planes selected by gGREY. 
  369. With "gGREY 1" for instance, "gGMODE 1" would cause gLINEBY 
  370. to clear pixels in the grey plane and "gGMODE 0" to set pixels 
  371. in the grey plane.
  372.  
  373. *** Other drawing keywords
  374.  
  375. *) gBUTTON: draw a 3-D button (a picture of a key, not 
  376. of an application button) enclosing supplied text. The button can 
  377. be raised, depressed or sunken.
  378.  
  379. *) gBORDER, gXBORDER: draw 2-D/3-D borders.
  380.  
  381. *) gINVERT: invert a rectangular area, except for its 
  382. four corner pixels.
  383.  
  384. *) gCOPY: copy a rectangular area from one position 
  385. on the screen to another. Both black and grey planes are copied.
  386.  
  387. *) gSCROLL: move a rectangular area from one position 
  388. on the screen to another, or scroll the contents of the screen in 
  389. any direction. Both black and grey planes are moved.
  390.  
  391. *) gPOLY: draw a sequence of lines.
  392.  
  393. *) gDRAWOBJECT: draw a graphics object. This 
  394. can be used to draw the "lozenge" used to display the words `City' 
  395. and `Home' in the World application.
  396.  
  397. Note that commands such as gSCROLL,, which move existing 
  398. pixels, affect both black and grey planes. gGREY only restricts 
  399. drawing and clearing of pixels.
  400.  
  401.  
  402. ****** Graphical text
  403.  
  404. *** Displaying text with gPRINT
  405.  
  406. The PRINT command displays text in one font, in a screen area 
  407. controlled by the FONT or SCREEN commands. You can, 
  408. however, display text in a variety of fonts and styles, at any pixel 
  409. position, with gPRINT. gPRINT also lets you draw text 
  410. to the grey plane, if you have used DEFAULTWIN and gGREY 
  411. (discussed earlier).
  412.  
  413. You can (to a lesser degree) control the font and style 
  414. used by OPL's other text-drawing keywords, such as PRINT and 
  415. EDIT. See "The text and graphics windows" at the end of this 
  416. chapter.
  417.  
  418. gPRINT is a graphical version of PRINT, and displays 
  419. a list of expressions in a similar way. Some examples:
  420. "gPRINT "Hello",name$"
  421. "gPRINT a$"
  422. "gPRINT "Sin(PI/3) is",sin(pi/3)"
  423.  
  424. Unlike PRINT, gPRINT does not end by moving to a new 
  425. line. A comma between expressions is still displayed as a space, but 
  426. a semi-colon has no effect. "gPRINT" used on its own does nothing.
  427.  
  428. The first character displayed has its left side 
  429. and baseline at the current position. The baseline is like 
  430. a line on lined notepaper  graphically, this is the horizontal 
  431. line which includes the lowest pixels of upper case characters. Some 
  432. characters, such as `g', `j', `p', `q' and `y', set pixels below the 
  433. baseline.
  434.  
  435. After using gPRINT, the current position is at the end of the 
  436. text so that you can print something else immediately beyond it. As 
  437. with other graphics keywords, no error is reported if you try to display 
  438. text off the edge of the screen.
  439.  
  440. While "CURSOR ON" displays a flashing cursor for ordinary text 
  441. displayed with PRINT, "CURSOR 1" switches on a cursor 
  442. for graphical text which is displayed at the current position. "CURSOR OFF" 
  443. removes either cursor.
  444.  
  445. *** Fonts
  446.  
  447. The gFONT command sets the font to be used 
  448. by subsequent gPRINT commands.
  449.  
  450. A large set of fonts which can be used with gFONT is provided 
  451. in the Series 3a ROM. In the following list, Swiss fonts refer to 
  452. fonts without serifs while Roman fonts either have serifs (eg font 
  453. 6) or are in a style designed for serifs but are too small to show 
  454. them (eg font 5). Mono-spaced fonts have characters which all 
  455. have the same width (and have their `pixel size' listed as width "x" height); 
  456. in proportional fonts each character can have a different width.
  457.  
  458. font number    Description        pixel size
  459. 1        Series 3 normal        8
  460. 2        Series 3 bold        8
  461. 3        Series 3 digits        6x6
  462. 4        Mono            8x8
  463. 5        Roman            8
  464. 6        Roman            11
  465. 7        Roman            13
  466. 8        Roman            16
  467. 9        Swiss            8
  468. 10        Swiss            11
  469. 11        Swiss            13
  470. 12        Swiss            16
  471. 13        Mono            6x6
  472.  
  473. The special font number "$9a" is set aside to give a machine's 
  474. default graphics font; this is the font used initially for graphics 
  475. text. The actual font may vary from machine to machine  eg 
  476. it is font 1 on the Series 3 and font 11 on the Series 3a. So 
  477. "gFONT 11" or "gFONT $9a" both set the Series 3a standard 
  478. font, which gPRINT normally uses.
  479.  
  480. Fonts 1,2 and 3 are the Series 3 fonts, used when running 
  481. in compatibility mode.
  482.  
  483. See gINFO in the alphabetic listing if you need to find out 
  484. more information about fonts.
  485.  
  486. The following program shows you examples of the fonts. ("!!!" is displayed 
  487. to emphasise the mono-spaced fonts):
  488.  
  489. PROC fonts:
  490.     showfont:(4,15,"Mono 8x8")
  491.     showfont:(5,25,"Roman 8")
  492.     showfont:(6,38,"Roman 11")
  493.     showfont:(7,53,"Roman 13")
  494.     showfont:(8,71,"Roman 16")
  495.     showfont:(9,81,"Swiss 8")
  496.     showfont:(10,94,"Swiss 11")
  497.     showfont:(11,109,"Swiss 13")
  498.     showfont:(12,127,"Swiss 16")
  499.     showfont:(13,135,"Mono 6x6")
  500.     GET
  501. ENDP
  502.  
  503.  PROC showfont:(font%,y%,str$)
  504.     gFONT font%
  505.     gAT 20,y% :gPRINT font%
  506.     gAT 50,y% :gPRINT str$
  507.     gAT 150,y% :gPRINT "!!!"
  508. ENDP
  509.  
  510. *** Text style
  511.  
  512. The gSTYLE command sets the text style to 
  513. be used by subsequent gPRINT commands.
  514.  
  515. Choose from these styles:
  516. "gSTYLE 1"    bold
  517. "gSTYLE 2"    underlined
  518. "gSTYLE 4"    inverse
  519. "gSTYLE 8"    double height
  520. "gSTYLE 16"    mono
  521. "gSTYLE 32"    italic
  522.  
  523. The `mono' style is not proportionally spaced  each character 
  524. is displayed with the same width, in the same way that PRINT 
  525. displays characters. A proportional font can be displayed as a mono-spaced 
  526. font by setting the `mono' style. See the previous section for the 
  527. list of mono-spaced and proportional fonts.
  528.  
  529. It is inefficient to use the `mono' style to display a font 
  530. which is already mono-spaced. 
  531.  
  532. You can combine these styles by adding the relevant numbers together. 
  533. "gSTYLE 12" sets the text style to inverse and double-height 
  534. (4+8=12). Here's an example of this style:
  535.  
  536. PROC style:
  537.   gAT 20,50 :gFONT 11
  538.   gSTYLE 12 :gPRINT "Attention!"
  539.   GET
  540. ENDP
  541.  
  542. Use "gSTYLE 0" to reset to normal style.
  543.  
  544. The bold style provides a way to make any font appear bolded. Except 
  545. for the smaller fonts, most Series 3a fonts look reasonably bold 
  546. already. Note that using the bold style sometimes causes a change 
  547. of font; if you use gINFO you may see the font name change.
  548.  
  549. *** Overwriting with gPRINT
  550.  
  551. gPRINT normally displays text as if writing it with a pen  
  552. the pixels that make up each letter are set, and that is all. If you're 
  553. using areas of the screen which already have some pixels set, or even 
  554. have all the pixels set, use gTMODE to change 
  555. the way gPRINT displays the text.
  556.  
  557. gTMODE controls the display of text in the same way as gGMODE 
  558. controls the display of lines and boxes. The values you use with gTMODE 
  559. are similar to those for gGMODE: "gTMODE 1" for clearing 
  560. pixels, "gTMODE 2" for inverting pixels, and "gTMODE 0" 
  561. for setting pixels again. There is also "gTMODE 3" which sets 
  562. the pixels of each character while clearing the character's background. 
  563. This is very useful as it guarantees that the text is readable (as 
  564. far as the current plane is concerned).
  565.  
  566. As for gGMODE, the setting for gTMODE applies to the 
  567. planes selected by gGREY. With "gGREY 1" for instance, 
  568. "gTMODE 1" would cause gLINEBY to clear pixels in the 
  569. grey plane and "gTMODE 0" to set pixels in the grey plane.
  570.  
  571. This procedure shows the various effects possible via gTMODE:
  572.  
  573. PROC tmode:
  574.   DEFAULTWIN 1                REM enable grey
  575.   gFONT 11    :gSTYLE 0
  576.   gAT 160,0   :gFILL 160,80,0 REM Black box
  577.   gAT 220,0   :gFILL 40,80,1  REM White box
  578.   gAT 180,20  :gTMODE 0 :gPRINT "ABCDEFGHIJK"
  579.   gAT 180,35  :gTMODE 1 :gPRINT "ABCDEFGHIJK"
  580.   gAT 180,50  :gTMODE 2 :gPRINT "ABCDEFGHIJK"
  581.   gAT 180,65  :gTMODE 3 :gPRINT "ABCDEFGHIJK"
  582.   gGREY 1
  583.   gAT 160,80  :gFILL 160,80,0 REM Grey box
  584.   gAT 220,80  :gFILL 40,80,1  REM White box
  585.   gAT 180,100 :gTMODE 0 :gPRINT "ABCDEFGHIJK"
  586.   gAT 180,115 :gTMODE 1 :gPRINT "ABCDEFGHIJK"
  587.   gAT 180,130 :gTMODE 2 :gPRINT "ABCDEFGHIJK"
  588.   gAT 180,145 :gTMODE 3 :gPRINT "ABCDEFGHIJK"
  589.   GET
  590. ENDP
  591.  
  592. *** Other graphical text keywords
  593.  
  594. *) gPRINTB: Display text left aligned, right aligned 
  595. or centred, in a cleared box. The gTMODE setting is ignored. 
  596. With "gGREY 1", only grey background pixels in the box are cleared 
  597. and with "gGREY 0", only black pixels; with "gGREY 2" 
  598. all background pixels in the box are cleared.
  599.  
  600. *) gXPRINT: Display text underlined/highlighted.
  601.  
  602. *) gPRINTCLIP: Display text clipped to whole characters.
  603.  
  604. *) gTWIDTH: Find width required by text.
  605.  
  606. All of these keywords take the current font and style into account, 
  607. and work on a single string. They display the text in black 
  608. or grey according to the current setting of gGREY.
  609.  
  610.  
  611.  
  612.  
  613.  
  614. ------------------------------------
  615. ************ Windows
  616.  
  617. So far, you've used the whole of the screen for displaying 
  618. graphics. You can, however, use windows  rectangular 
  619. areas of the screen.
  620.  
  621. Sprites (described in the `Advanced topics' chapter) can display 
  622. non-rectangular shapes.
  623.  
  624. OPL allows a program to use up to eight windows at any one time.
  625.  
  626. *** Window IDs and the default window
  627.  
  628. Each window has an ID number, allowing you to specify which 
  629. window you want to work with at any time.
  630.  
  631. When a program first runs, it has one window called the default window. 
  632. Its ID is 1, it 
  633. is the full size of the screen, and initially all graphics commands 
  634. operate on it. (This is why `0,0' has so far referred to the top left 
  635. of the screen: it is true for the default window.)
  636.  
  637. Other windows you create will have IDs from 2 to 8. When 
  638. you make another window it becomes the current window, and all subsequent graphics 
  639. commands operate on it.
  640.  
  641. The first half of this chapter used only the default window. However, 
  642. everything actually applies to the current window. For example, if 
  643. you make a small window current and try to draw a very long line, 
  644. the current position moves off past the window edge, and only that 
  645. part of the line which fits in the window is displayed.
  646.  
  647. *** Graphics keywords and windows
  648.  
  649. For OPL graphics keywords, positions apply to the window you are 
  650. using at any given time. The point 0,0 means the top left corner 
  651. of the current window, not the top left corner of the screen.
  652.  
  653. Each window can be created with a grey plane if required, in which 
  654. case gGREY is used 
  655. to specify whether the black plane, the grey plane or both should 
  656. be used for all subsequent graphics commands until the next call to 
  657. gGREY, exactly as described in the first half of this chapter.
  658.  
  659. For the default window, the special command DEFAULTWIN 
  660. is required to enable grey because that window is automatically created 
  661. for you with only a black plane; "DEFAULTWIN 1" closes the default 
  662. window and creates a new one which has a grey plane. All other windows 
  663. must be created with a grey plane if grey is required.
  664.  
  665. Once a window has been created with a grey plane, grey is used in 
  666. precisely the same way as in the default window with grey enabled: 
  667. "gGREY 0" directs all drawing to the black plane only, "gGREY 1" 
  668. to the grey plane only and "gGREY 2" to both planes. "gGREY 1" 
  669. and "gGREY 2" raise an error if the current window does not 
  670. have a grey plane.
  671.  
  672. gGREY, gGMODE, gTMODE, gFONT and gSTYLE can all be used with created windows in exactly 
  673. the same way as with the default window, as desribed earlier. They 
  674. change the settings for the current window only; all the settings 
  675. are remembered for each window.
  676.  
  677. *** Creating new windows
  678.  
  679. The gCREATE function sets up a new window 
  680. on the screen. It returns an ID number for the window. Whenever 
  681. you want to change to this window, use gUSE 
  682. with this ID.
  683.  
  684. You can create a window with only a black plane or with both a black 
  685. and a grey plane. You cannot create a window with just a grey plane.
  686.  
  687. Here is an example using gCREATE and gUSE, contrasting 
  688. the point 20,20 in the created window with 20,20 in the default window.
  689.  
  690. PROC windows:
  691.   LOCAL id%
  692.   id%=gCREATE(60,40,240,30,1,1)
  693.   gBORDER 0 :gAT 20,20 :gLINEBY 0,0
  694.   gPRINT " 20,20 (new)"
  695.   GET
  696.   gUSE 1 :gAT 20,20 :gLINEBY 0,0
  697.   gPRINT " 20,20 (default)"
  698.   GET
  699.   gUSE id%
  700.   gGREY 1        REM draw grey
  701.   gPRINT " Back"
  702.   gGREY 0
  703.   gPRINT " (with grey)"
  704.   GET
  705. ENDP
  706.  
  707. The line "id%=gCREATE(60,40,180,30,1,1)" creates a window with 
  708. its top left corner at 60,40 on the screen. The window is set to be 
  709. 180 pixels wide and 30 pixels deep. (You can use any integer values 
  710. for these arguments, even if it creates the window partially or even 
  711. totally off the screen.) The fifth argument to gCREATE specifies 
  712. whether the window should immediately be visible or not; 0 means invisible, 
  713. 1 (as here) means visible. The sixth argument specifies whether the 
  714. window should have a grey plane or not; 0 means black only, 1 (as 
  715. here) means black and grey. If the sixth argument is not supplied 
  716. at all (eg. "id%=gCREATE(60,40,180,30,1)") the window will not 
  717. have a grey plane.
  718.  
  719. gCREATE automatically makes the created window the current 
  720. window, and sets the current position in it to 0,0. It returns an 
  721. ID number for this window, which in this example is saved in 
  722. the variable "id%".
  723.  
  724. The "gBORDER 0" command draws a border one pixel wide around the current 
  725. window. Here this helps show the position and size of the window. 
  726. (gBORDER can draw a variety of borders. You can even display 
  727. the Series 3a 3-D style borders seen in menus and dialogs, with 
  728. the gXBORDER keyword.)
  729.  
  730. The program then sets the pixel at 20,20 in this new window, using 
  731. "gLINEBY 0,0".
  732.  
  733. "gUSE 1" goes back to using the default window. The program 
  734. then shows 20,20 in this window.
  735.  
  736. Finally, "gUSE id%" goes back to the created window again, and 
  737. a final message is displayed, in grey and black. 
  738.  
  739. Note that each window has its own current position. The current 
  740. position in the created window is remembered while the program goes 
  741. back to the default window. All the other settings, such as the 
  742. font, style and grey setting are also remembered.
  743.  
  744.  
  745.  
  746. *** Closing windows
  747.  
  748. When you've finished with a particular window, close it with gCLOSE 
  749. followed by its ID  for example, "gCLOSE 2". 
  750. You can create and close as many windows as you like, as long as there 
  751. are only eight or fewer open at any one time.
  752.  
  753. If you close the current window, the default window (ID=1) 
  754. becomes current.
  755.  
  756. An error is raised if you try to close the default window.
  757.  
  758. *** When windows overlap
  759.  
  760. Windows can overlap on the screen, or even hide each other entirely. 
  761. Use the gORDER command to control the foreground/background 
  762. positions of overlapping windows.
  763.  
  764. "gORDER 3,1" sets the window whose ID is 3 to be in the 
  765. foreground. This guarantees that it will be wholly visible. "gORDER 3,2" 
  766. makes it second in the list; unless the foreground window overlaps 
  767. it, it too will be visible.
  768.  
  769. Any position greater than the number of windows you have is interpreted 
  770. as the end of the list. "gORDER 3,9" will therefore always force 
  771. the window whose ID is 3 to the background, behind all others.
  772.  
  773. Note in particular that making a window the current window with 
  774. gUSE does not bring it to the foreground. You can make 
  775. a background window current and draw all kinds of things to it, but 
  776. nothing will happen on the screen until you bring it to the foreground 
  777. with gORDER.
  778.  
  779. When a window is first created with gCREATE it always becomes 
  780. the foreground window as well as the current window.
  781.  
  782. *** Hiding windows
  783.  
  784. If you are going to use several drawing commands on a particular window, 
  785. you may like to make it invisible while doing so. When you then make 
  786. it visible again, having completed the drawing commands, the whole 
  787. pattern appears on the screen in one go, instead of being built up 
  788. piece by piece.
  789.  
  790. Use "gVISIBLE ON" and "gVISIBLE OFF" 
  791. to perform this function on the current window. You can also make 
  792. new windows invisible as you create them, by using 0 as the fifth 
  793. argument to the gCREATE command, and you can hide windows behind 
  794. other windows.
  795.  
  796. *** The graphics cursor in windows
  797.  
  798. To make the graphics cursor appear in a particular window, use the 
  799. CURSOR command with the ID of the 
  800. window. It will appear flashing at the current position in that window, 
  801. provided it is not obscured by some other window.
  802.  
  803. The window you specify does not have to be the current window, and 
  804. does not become current; you can have the cursor in one window while 
  805. displaying graphical text in another. If you want to move to a different 
  806. window and put the graphics cursor in it, you must use both gUSE 
  807. and CURSOR.
  808.  
  809. Since the default window always has an ID of 1, "CURSOR 1" 
  810. will, as mentioned earlier, put the graphics cursor in it.
  811.  
  812. CURSOR OFF turns off the cursor, wherever it is.
  813.  
  814. *** Information about your windows
  815.  
  816. You don't have to keep a complete copy of all the information pertaining 
  817. to each window you use. These functions return information about the 
  818. current window:
  819.  
  820. *) gIDENTITY returns its ID number.
  821.  
  822. *) gRANK returns its foreground/background position, 
  823. from 1 to 8.
  824.  
  825. *) gWIDTH and gHEIGHT return its size.
  826.  
  827. *) gORIGINX and gORIGINY return its screen position.
  828.  
  829. *) gINFO returns information about the font, style, 
  830. grey setting, overwrite modes and cursor in use.
  831.  
  832. *) gX and gY return the current position.
  833.  
  834. *** Other window keywords
  835.  
  836. *) gSETWIN changes the position, and optionally the 
  837. size, of the current window.
  838.  
  839. You can use this command on the default window, if you 
  840. wish, but you must also use the SCREEN command to ensure 
  841. that the text window  the area for PRINT commands 
  842. to use  is wholly contained within the default window. See 
  843. `The text and graphics windows', later in this chapter.
  844.  
  845. *) gSCROLL scrolls all or part of both black and grey 
  846. planes of the current window.
  847.  
  848. *) gPATT fills an area in the current window with repetitions 
  849. of another window, or with a shaded pattern.
  850.  
  851. *) gCOPY copies an area from another window into the 
  852. current window, or from one position in the current window to another.
  853.  
  854. *) gSAVEBIT saves part or all of a window as a bitmap file. 
  855. If a window has a grey plane, the planes are saved as two bitmaps 
  856. to the same file with the black plane saved first and the grey plane 
  857. saved next. gLOADBIT, described later, can be used to load 
  858. bitmap files.
  859.  
  860. *) gPEEKLINE reads back a horizontal line of data from 
  861. either the black or grey plane of a specified window.
  862.  
  863. *** Copying grey 
  864. between windows
  865.  
  866. The commands gCOPY and gPATT can use two windows and 
  867. therefore special rules are needed for the cases when one window has 
  868. a grey plane and the other does not.
  869.  
  870. With "gGREY 0" in the destination window, only 
  871. the black plane of the source is copied.
  872.  
  873. With "gGREY 1" in the destination window, only the grey plane 
  874. of the source is copied, unless the source has only one plane in which 
  875. case that plane is used as the source.
  876.  
  877. With "gGREY 2" in the destination window, if the source has 
  878. both planes, they are copied to the appropriate planes in the destination 
  879. window (black to black, grey to grey); if the source has only one 
  880. plane, it is copied to both planes of the destination.
  881.  
  882.  
  883.  
  884.  
  885.  
  886. ------------------------------------
  887. ************ Advanced graphics
  888.  
  889. This section should provide a taste of some of the more exotic things 
  890. you can do with OPL graphics.
  891.  
  892. *** Bitmaps
  893.  
  894. A bitmap is an area in memory which acts just like an off-screen 
  895. window, except that it does not have two planes so that gGREY 
  896. cannot be used. You can create bitmaps with gCREATEBIT. They have the following uses:
  897.  
  898. *) You can manipulate an image in a bitmap before copying it 
  899. with gPATT or gCOPY 
  900. to a window on the screen. This is generally faster than manipulating 
  901. an image in a hidden window.
  902.  
  903. *) You can load bitmap files into 
  904. bitmaps in memory using gLOADBIT, then copy them to on-screen 
  905. windows using gCOPY or gPATT. (If a black and grey window 
  906. was saved to file as two bitmaps using gSAVEBIT, you must load 
  907. them separately into two bitmaps in memory, and copy them one at a 
  908. time to the respective planes of a window.)
  909.  
  910. OPL treats a bitmap as the equivalent of a window in most cases:
  911.  
  912. *) Both are identified by ID numbers. Only one window 
  913. or bitmap is current at any one time, set by gUSE.
  914.  
  915. *) If you use bitmaps as well as windows, the total number 
  916. must be eight or fewer.
  917.  
  918. *) The top left corner of the current bitmap is still referred 
  919. to as 0,0, even though it is not on the screen at all.
  920.  
  921. Together, windows and bitmaps are known as drawables  
  922. places you can draw to.
  923.  
  924. Most graphics keywords can be used with bitmaps in the same way as 
  925. with windows, but remember that a bitmap corresponds to only one plane 
  926. in a window. Once you have drawn to it, you might copy it to the appropriate 
  927. plane of a window.
  928.  
  929. The keywords that can be used with bitmaps include: gUSE, gBORDER, 
  930. gCLOSE, gCLS, gCOPY, gGMODE, gFONT, 
  931. gIDENTITY, gPATT, gPEEKLINE, gSAVEBIT, 
  932. gSCROLL, gTMODE, gWIDTH, gHEIGHT and gINFO. 
  933. These keywords are described earlier in this chapter.
  934.  
  935. *** Speed improvements
  936.  
  937. The Series 3a screen is usually updated whenever you display anything 
  938. on it. gUPDATE OFF switches off this feature. The screen 
  939. will be updated as few times as possible, although you can force an 
  940. update by using the gUPDATE command on its 
  941. own. (An update is also forced by GET, KEY and by all 
  942. graphics keywords which return a value, other than gX, gY, 
  943. gWIDTH and gHEIGHT).
  944.  
  945. This can result in a considerable speed improvement in some cases. 
  946. You might, for example, use "gUPDATE OFF", then a sequence of 
  947. graphics commands, followed by "gUPDATE". You should certainly 
  948. use gUPDATE OFF if you are about to write exclusively to 
  949. bitmaps.
  950.  
  951. gUPDATE ON returns to normal screen updating.
  952.  
  953. As mentioned previously, a window with both black and grey planes 
  954. takes longer to move or scroll than a window with only a black plane. 
  955. So avoid creating windows with unnecessary grey planes.
  956.  
  957. Also, remember that scrolling and moving windows require every pixel 
  958. in a window to be redrawn.
  959.  
  960. The gPOLY command draws a sequence of lines, 
  961. as if by gLINEBY and gMOVE commands. If you have to 
  962. draw a lot of lines (or dots, with "gLINEBY 0,0"), gPOLY 
  963. can greatly reduce the time taken to do so.
  964.  
  965. *** Displaying a running clock
  966.  
  967. gCLOCK displays or removes a running 
  968. clock showing the system time. The clock can be digital or conventional, 
  969. and can use many different formats.
  970.  
  971. *** User-defined fonts and cursors
  972.  
  973. If you have a user-defined font you can load it into memory with gLOADFONT. This returns an ID for the font; use this with gFONT 
  974. to make the font current. The gUNLOADFONT command removes a user-defined font from memory when you 
  975. have finished using it.
  976.  
  977. You can use four extra arguments with the CURSOR command. 
  978. Three of these specify the ascent, width and height of the cursor. 
  979. The ascent is the number of pixels (-128 to 127) by which the 
  980. top of the cursor should be above the baseline of the current font. 
  981. The height and width arguments should both be between 0 and 255. For 
  982. example, "CURSOR 1,12,4,14" sets a cursor 4 pixels wide by 14 
  983. high in the default window (ID=1), with the cursor top at 12 
  984. pixels above the font baseline.
  985.  
  986. If you do not use these arguments, the cursor is 2 pixels wide, and 
  987. has the same height and ascent as the current font.
  988.  
  989. By default the cursor has square corners, is black and is flashing. 
  990. Supply the fifth argument as 1 for a rounded cursor, 2 for non-flashing 
  991. or 4 for grey. You can add these together  eg use 5 for a grey, 
  992. rounded cursor.
  993.  
  994. Note that the gINFO command returns information about the cursor 
  995. and font.
  996.  
  997. *** The text and graphics 
  998. windows
  999.  
  1000. PRINT displays 
  1001. mono-spaced text in the text window. You can change the text 
  1002. window font (ie that used by PRINT) using the FONT keyword. 
  1003. You can use any of those listed earlier in the chapter in the description 
  1004. of gFONT; initially font 4 is used.
  1005.  
  1006. The text window is in fact part of the default graphics window. If 
  1007. you have other graphics windows in front of the default window, they 
  1008. may therefore hide any text you display with PRINT.
  1009.  
  1010. Initially the text window is very slightly smaller than the default 
  1011. graphics window which is full-screen size. They are not the same because 
  1012. the text window height and width always fits a whole number of 
  1013. characters of the current text window font. If you use the FONT 
  1014. command to change the font of the text window, this first sets the 
  1015. default graphics window to the maximum size that will fit in 
  1016. the screen (excluding any status window) and then resizes the text 
  1017. window to be as large as possible inside it.
  1018.  
  1019. You can also use the STYLE keyword to set the style for all 
  1020. characters subsequently written to the text window. This allows the 
  1021. mixing of different styles in the text window. You can only use those 
  1022. styles which do not change the size of the characters  ie inverse 
  1023. video and underline. (Any other styles will be ignored.) Use the same 
  1024. values as listed for gSTYLE, earlier in the chapter.
  1025.  
  1026. To find out exactly where the text window is positioned, use "SCREENINFO info%()". 
  1027. This sets "info%(1)/info%(2)" to the number of pixels from the 
  1028. left/top of the default window to the left/top of the text window. 
  1029. (These are called the margins.) "info%(7)" and "info%(8)" 
  1030. are the text window's character width and height respectively.
  1031.  
  1032. The margins are fully determined by the font being used and 
  1033. therefore change from their initial value only when FONT is 
  1034. used. You cannot choose your own margins. gSETWIN and SCREEN 
  1035. do not change the margins, so you can use FONT to select a 
  1036. font (also clearing the screen), followed by SCREENINFO  to 
  1037. find out the size of the margins with that font, and finally gSETWIN 
  1038. and SCREEN  to change the sizes and positions of the default 
  1039. window and text window taking the margins into account (see example 
  1040. below). The margins will be the same after calling gSETWIN 
  1041. and SCREEN as they were after FONT.
  1042.  
  1043. It is not generally recommended to use both the text and graphics 
  1044. windows. Graphics commands provide much finer control over the screen 
  1045. display than is possible in the text window, so it is not easy to 
  1046. mix the two.
  1047.  
  1048. If you do need to use the text window, for example to use keywords 
  1049. like EDIT, it's easy to use SCREEN to place it out of 
  1050. the way of your graphics windows. You can, however, use it on top 
  1051. of a graphics window  for example, you might want to use EDIT 
  1052. to simulate an edit box in the graphics window. Use gSETWIN 
  1053. to change the default window to about the size and position 
  1054. of the desired edit box. The text window moves with it  you 
  1055. must then make it the same size, or slightly smaller, with the SCREEN 
  1056. command. Use 1,1 as the last two arguments to SCREEN, to keep 
  1057. its top left corner fixed. "gORDER 1,1" will then bring the 
  1058. default window to the front, and with it the text window. EDIT 
  1059. can then be used.
  1060.  
  1061. Here is an example program which uses this technique  moving 
  1062. an `edit box', hiding it while you edit, then finally letting you 
  1063. move it around.
  1064.  
  1065.  
  1066.  
  1067. PROC gsetw1:
  1068.   LOCAL a$(100),w%,h%,g$(1),factor%,info%(10)
  1069.   LOCAL margx%,margy%,chrw%,chrh%,defw%,defh%
  1070.   SCREENINFO info%()       REM get text window information
  1071.   margx%=info%(1) :margy%=info%(2)
  1072.   chrw%=info%(7) :chrh%=info%(8)
  1073.   defw%=23*chrw%+2*margx%  REM new default window width
  1074.   defh%=chrh%+2*margy%     REM ... and height
  1075.   w%=gWIDTH :h%=gHEIGHT
  1076.   gSETWIN w%/4+margx%,h%/4+margy%,defw%,defh%
  1077.   SCREEN 23,1,1,1   REM text window
  1078.   PRINT "Text win:"; :GET
  1079.   gCREATE(w%*.1,h%*.1,w%*.8,h%*.8,1)   REM new window
  1080.   gPATT -1,gWIDTH,gHEIGHT,0 REM shade it
  1081.   gAT 2,h%*.7 :gTMODE 4
  1082.   gPRINT "Graphics window 2"
  1083.   gORDER 1,0 REM back to default+text window
  1084.   EDIT a$               REM you can see this edit
  1085.   gORDER 1,9 REM to background
  1086.   CLS
  1087.   a$=""
  1088.   PRINT "Hidden:";
  1089.   GIPRINT "Edit in hidden edit box"
  1090.   EDIT a$               REM YOU CAN'T SEE THIS EDIT
  1091.   GIPRINT ""
  1092.   gORDER 1,0 :GET REM now here it is
  1093.   gUSE 1 REM graphics go to default window
  1094.   DO  REM move default/text window around
  1095.     CLS
  1096.     PRINT "U,D,L,R,Quit";
  1097.     g$=UPPER$(GET$)
  1098.     IF kmod=2 REM Shift key moves quickly
  1099.       factor%=10
  1100.     ELSE
  1101.       factor%=1
  1102.     ENDIF
  1103.     IF g$="U"
  1104.       gSETWIN gORIGINX,gORIGINY-factor%
  1105.     ELSEIF g$="D"
  1106.       gSETWIN gORIGINX,gORIGINY+factor%
  1107.     ELSEIF g$="L"
  1108.       gSETWIN gORIGINX-factor%,gORIGINY
  1109.     ELSEIF g$="R"
  1110.       gSETWIN gORIGINX+factor%,gORIGINY
  1111.     ENDIF
  1112.   UNTIL g$="Q" OR g$=CHR$(27)
  1113. ENDP
  1114.  
  1115.