REBOL [ Title: "DRAW Tutorial" Author: "Larry Palmiter" File: %easy-draw.r Date: 14-Apr-2001 Version: 0.1 Comments: { Uses easy-vid 1.1.2 by Carl Sassenrath Draw docs by Holger Kruse Examples by Carl, Holger and Larry} ] content: {DRAW Dialect for REBOL Faces ===Fancy Example The DRAW dialect is part of the EFFECTS block of a face. For example: view layout [ box black 100x100 effect [ draw [ pen red line 30x30 50x20 70x70 40x50 pen blue box 20x20 80x80 fill-pen leaf box 20x60 40x80 polygon 10x10 40x40 40x80 10x0 pen white text 8x25 "Example" fill-pen gold flood 2x2 ] ] ] !Note: To shorten the code, in most of the remaining examples only the contents of the layout box are specified. view layout [...] is implicit. See easy-vid. ===Draw Attribute Words !pen [foreground-color [tuple! none!]] Set the current foreground color for outline rendering (line, circle, polygon, box). A color of none is equivalent to transparent. The default is foreground: inverse of face color. !fill-pen [foreground-color [tuple! none!]] [background-color [tuple! none!]] Set the current foreground color for area filling (circle, box, flood, to be implemented: polygon). A color of none is equivalent to transparent. The default is none. !line-pattern [len1 [integer!]] [len2 [integer!]] ... [lenn [integer!]] Set the line pattern. Each len parameter defines the length of a set (foreground) or unset (background) segment of the line, Set and unset segments alternate. For instance "line-pattern 1 5" defines a dotted line, with dots 5 pixels apart, "line-pattern 8 8" defines a dashed line, "line-pattern 1 4 4 4" defines a morse-code-style line (alternating between dotted and dashed). Up to 8 segments can be defined. An empty line-pattern call (without parameters following) resets to the default: a solid line. !font [textfont [object!]] Set the font to be used in subsequent text calls. The default is the font used by the face. !Note: Keyword arguments of different datatypes can appear in any order ===Draw Object Words !line [point1 [pair!]] [point2 [pair!]] ... [pointn [pair!]] Draw a line from point1 to point2, from point 2 to point 3, ... to point n. The current pen colors and line pattern are observed. !polygon [point1 [pair!]] [point2 [pair!]] ... [pointn [pair!]] Similar to line, except that points n and 1 are connected afterwards, to create a closed polygon. If the fill-pen is different from none then the polygon is filled in the specified color. !circle [center [pair!]] [radius [integer!]] Draw a circle at the given point, with the given radius. Both the outline pen colors and the fill colors are observed. The line pattern is NOT observed. !box [point1 [pair!]] [point2 [pair!]] Draw a rectangle, parallel to the x/y axes, through the two diagonal endpoints specified. Both the outline pen colors and the fill colors are observed. The line pattern is observed for the box outline. !text [point [pair!]] [text [string!]] Renders the specified text at the specified position, using the current font setting, foreground and background color. !image [[point [pair!]] image [image!]] [transp-color [tuple!]] Renders the specified image at the specified position. If transp-color is specified then this color (in the image) is considered to be transparent. ===Draw Function Words !flood [point [pair!]] [border-color [tuple!]] Flood-fills the area around the specified point with the current foreground fill color. If border-color is not specified then any pixel with a color different from the color of the starting point is considered to be part of the border. Otherwise all pixels with a color of border-color define the border. ===Line Examples Draw a single red line into a face with a black grid and display it: box ivory 200x200 effect [grid 20x20 draw [pen 200.0.0 line 20x20 180x180]] Draw a few connected red lines and a blue box: box ivory 200x200 effect [ draw [ pen 200.0.0 line 50x50 150x150 50x150 150x50 50x50 pen 0.0.200 box 20x20 180x180 ] ] ===Circle Examples Draw a circle: box ivory 200x200 effect [ draw [pen 200.0.0 circle 100x100 50] ] Draw a filled circle: box ivory 200x200 effect [ draw [pen 200.0.0 fill-pen gold circle 100x100 50] ] Draw a box and a circle, then use a flood fill: box black 200x200 effect [ draw [ pen white box 20x20 180x180 pen red circle 100x100 100 fill-pen blue flood 100x100 ] ] ===Text Examples Draw text in a maroon color: box ivory 200x200 effect [ draw [ pen maroon text "Hello World" 20x20 ] ] Using other fonts for text: do [ italic-font: make face/font [ size: 15 style: [italic bold] name: font-serif ] ] box 200x200 gold effect [ draw [ pen blue text 20x20 "Default Font" font italic-font pen black text 20x60 "Bold Times Italic Font" ] ] ===Combining Effects Other face effects can be done before the DRAW operation. This example draws 100 random lines in random colors on a gradient backdrop effect: do [fx: [gradient 1x1 0.150.0 0.0.150 draw []] lines: select fx 'draw loop 100 [ repend lines [ 'pen random 250.50.50 'line random 200x200 random 200x200 ] ] ] box ivory 200x200 effect fx Other face effects can follow the DRAW operation. This example draws a line and a box then inverts and blurs them: box ivory 200x200 effect [ draw [ pen 200.0.0 line 50x50 150x150 50x150 150x50 50x50 pen 0.0.200 box 20x20 180x180 ] invert blur ] ===Pre+Post Effects Perform a pre-effect and a post-effect. A gradient is created, then 100 random circles are drawn, then the result is color differenced with an image bitmap. do [fx: [gradient 1x1 0.150.0 0.0.150 draw []] lines: select fx 'draw loop 100 [ repend lines [ 'pen random 250.50.50 'circle random 200x200 random 100 ] ] img: load-thru/binary http://www.rebol.com/view/palms.jpg repend fx ['difference img] ] box ivory img/size effect fx ===Images in Draw Draw an image twice. The first includes all of its colors. The second makes one of its colors transparent. do [i: make image! 2x2 poke i 1 red poke i 2 yellow poke i 3 green poke i 4 blue ; make the image 20 times larger i: to-image layout [origin 0x0 image i 40x40] ] box black 200x200 effect [ draw [ image i 20x20 image i 80x80 green ] ] ===Mouse Actions 1 Draws lines when you hold the mouse button down and move it. view f: layout [ box ivory 400x400 with [ effect: copy/deep [draw [pen black line]] line: second effect feel: make feel [ engage: func [f a e] [ if find [down over] a [ append f/line e/offset show f ] if a = 'up [append f/line 'line] ] ] ] ] ===Mouse Actions 2 Draws filled circles as the mouse is slowly moved with the button down: view f: layout [ box ivory 400x400 with [ effect: copy/deep [draw [pen black]] line: second effect feel: make feel [ engage: func [f a e] [ if find [down over] a [ repend f/line [ 'fill-pen random 0.255.0 'circle e/offset 20 ] show f ] ] ] ] ] } ;end of content string code: text: layo: xview: none sections: [] layouts: [] space: charset " ^-" chars: complement charset " ^-^/" rules: [title some parts] title: [text-line (title-line: text)] parts: [ newline | "===" section | "---" subsect | "!" note | example | paragraph ] text-line: [copy text to newline newline] indented: [some space thru newline] paragraph: [copy para some [chars thru newline] (emit txt para)] note: [copy para some [chars thru newline] (emit-note para)] example: [ copy code some [indented | some newline indented] (emit-code code) ] section: [ text-line ( append sections text append/only layouts layo: copy page-template emit h1 text ) newline ] subsect: [text-line (emit h2 text)] emit: func ['style data] [repend layo [style data]] emit-code: func [code] [ remove back tail code repend layo ['code 460x-1 trim/auto code 'show-example] ] emit-note: func [code] [ remove back tail code repend layo ['tnt 460x-1 code] ] show-example: [ if xview [xy: xview/offset unview/only xview] xcode: load/all face/text if not block? xcode [xcode: reduce [xcode]] ;!!! fix load/all if here: select xcode 'layout [xcode: here] xview: view/new/offset layout xcode xy ] page-template: [ size 500x480 origin 8x8 backdrop white style code tt black silver bold as-is para [origin: margin: 12x8] font [colors: [0.0.0 0.80.0]] style tnt txt maroon bold ] parse/all detab content rules show-page: func [i /local blk][ i: max 1 min length? sections i append clear tl/picked pick sections i show tl if blk: pick layouts this-page: i [f-box/pane: layout/offset blk 0x0 show f-box] ] main: layout [ across h2 title-line return space 0 tl: text-list 160x480 bold black white data sections [ show-page index? find sections value ] h: at f-box: info 500x480 at h + 456x-24 across space 4 arrow left keycode [up left] [show-page this-page - 1] arrow right keycode [down right] [show-page this-page + 1] pad -120 txt form system/script/header/date/date ] show-page 1 xy: main/offset + 480x100 view main