chiark / gitweb /
JPEG support and other fixes from Nick Clark
[ssr] / StraySrc / Libraries / Sapphire / s / draw
1 ;
2 ; draw.s
3 ;
4 ; Renders DrawFiles (MDW)
5 ;
6 ; © 1994-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's Sapphire library.
12 ;
13 ; Sapphire is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
16 ; any later version.
17 ;
18 ; Sapphire is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 ; GNU General Public License for more details.
22 ;
23 ; You should have received a copy of the GNU General Public License
24 ; along with Sapphire.  If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
27 ;----- Standard header ------------------------------------------------------
28
29                 GET     libs:header
30                 GET     libs:swis
31
32 ;----- External dependencies ------------------------------------------------
33
34                 GET     sapphire:divide
35                 GET     sapphire:mem
36                 GET     sapphire:msgs
37                 GET     sapphire:roVersion
38                 GET     sapphire:sapphire
39                 GET     sapphire:screen
40                 GET     sapphire:sprite
41
42 ;----- Main code ------------------------------------------------------------
43
44                 AREA    |Sapphire$$Code|,CODE,READONLY
45
46 ; --- Register allocation ---
47 ;
48 ; R12 == pointer to font array
49 ; R10 == pointer to transform matrix
50 ;  R9 == pointer to clipping block (in Draw units)
51 ;  R8 == pointer to end of objects to render
52 ;  R7 == pointer to start of current object
53
54 ; --- draw_render ---
55 ;
56 ; On entry:     R0 == scale to plot drawfile (16.16 form)
57 ;               R1 == pointer to a redraw block
58 ;               R2 == pointer to drawfile in memory
59 ;               R3 == size of drawfile block
60 ;
61 ; On exit:      --
62 ;
63 ; Use:          Renders a DrawFile in a window.  Objects which aren't
64 ;               recognised are not rendered.  The objects which are handled
65 ;               are as follows:
66 ;
67 ;               * Font table objects
68 ;               * Text objects (in fonts, or in system font)
69 ;               * Draw path objects, filled and unfilled, including
70 ;                 dotted outlines
71 ;               * Group objects
72 ;               * Tagged objects
73 ;               * Sprite objects, rendered as well as we can make it
74 ;               * Transformed text, only on RISC OS 3
75 ;               * Transformed sprite, only on RISC OS 3
76
77                 EXPORT  draw_render
78 draw_render     ROUT
79
80                 STMFD   R13!,{R0-R12,R14}       ;Save a load of registers
81
82                 ; --- Set up the transformation matrix ---
83
84                 LDR     R4,[R1,#4]              ;Load minimum x coord
85                 ADD     R14,R1,#16              ;Point to maximum y coord
86                 LDMIA   R14,{R5-R7}             ;Load y coord and scroll pos
87                 SUB     R4,R4,R6                ;Work out x origin position
88                 SUB     R5,R5,R7                ;And the y origin position
89
90                 SUB     R13,R13,#24             ;Make way for the transform
91                 MOV     R10,R13                 ;Point to it nicely
92                 MOV     R14,R13                 ;Point to it for filling
93                 MOV     R6,R0                   ;Set up x scale from user
94                 MOV     R7,#0                   ;Don't do fancy x transforms
95                 MOV     R8,#0                   ;Don't do fancy y transforms
96                 MOV     R9,R0                   ;And scale y from user
97                 STMIA   R14!,{R6-R9}            ;Save this in the block
98                 MOV     R6,R4,LSL #8            ;Convert offset to draw units
99                 MOV     R7,R5,LSL #8            ;And convert y offset too
100                 STMIA   R14,{R6,R7}             ;Save these in the matrix too
101
102                 ; --- Set up the adjusted clipping block too ---
103
104                 SUB     R13,R13,#16             ;Make way for a clipping blk
105                 ADD     R14,R1,#28              ;Point to original block
106                 LDMIA   R14,{R6-R9}             ;Load the clipping coords
107                 SUB     R6,R6,R4                ;Convert these to window...
108                 SUB     R7,R7,R5                ;... coordinates for easy...
109                 SUB     R8,R8,R4                ;... clipping
110                 SUB     R9,R9,R5
111                 MOV     R4,R0                   ;Get the scale factor safe
112
113                 ; --- Now we have to divide by the scale factor ---
114
115                 MOV     R12,#&18000             ;A useful constant (1 1/2)
116                 RSB     R0,R12,R6,LSL #16       ;Take minimum x position
117                 MOV     R1,R4,LSR #8            ;And the scale factor
118                 BL      divide                  ;Do the division
119                 MOV     R6,R0                   ;Take the result away nicely
120
121                 RSB     R0,R12,R7,LSL #16       ;Take minimum y position
122                 MOV     R1,R4,LSR #8            ;And the scale factor
123                 BL      divide                  ;Do the division
124                 MOV     R7,R0                   ;Take the result away nicely
125
126                 ADD     R0,R12,R8,LSL #16       ;Take maximum x position
127                 MOV     R1,R4,LSR #8            ;And the scale factor
128                 ADD     R0,R0,R1                ;Make it round upwards
129                 BL      divide                  ;Do the division
130                 MOV     R8,R0                   ;Take the result away nicely
131
132                 ADD     R0,R12,R9,LSL #16       ;Take maximum y position
133                 MOV     R1,R4,LSR #8            ;And the scale factor
134                 ADD     R0,R0,R1                ;Make it round upwards
135                 BL      divide                  ;Do the division
136                 MOV     R9,R0                   ;Take the result away nicely
137
138                 STMIA   R13,{R6-R9}             ;Save the modified values
139                 MOV     R9,R13                  ;Point to the coords block
140
141                 ; --- Set up start and end values ---
142
143                 MOV     R7,R2                   ;Get start address to render
144                 ADD     R8,R7,R3                ;And calculate end address
145                 MOV     R0,R7                   ;Point to the drawfile
146                 BL      draw_checkValid ;Make sure the drawfile's OK
147                 BVS     %10draw_render          ;If not don't draw it
148                 ADD     R7,R7,#40               ;Point to renderable part
149
150                 ; --- And finally initialise the font array ---
151
152                 SUB     R13,R13,#1024           ;The font array is *big*
153                 MOV     R12,R13                 ;Point to it
154                 MOV     R0,R12                  ;Point to font array
155                 MOV     R1,#1024                ;Get its size
156                 MOV     R2,#0                   ;We're going to fill it
157                 BL      mem_set                 ;So make it all zeroes
158
159                 ; --- Do the main rendering and tidy up ---
160
161                 BL      draw__doRender          ;And do the main job
162 10draw_render   ADD     R13,R10,#24             ;Reclaim all the stack
163                 BL      draw__resetTextSize     ;Make the text size sensible
164                 LDMFD   R13!,{R0-R12,PC}^       ;Return to caller now
165
166 ; --- draw_checkValid ---
167 ;
168 ; On entry:     R0 == pointer to start of drawfile
169 ;
170 ; On exit:      May return an error
171 ;
172 ; Use:          Checks whether a drawfile is basically sound.  This checking
173 ;               isn't compulsory, and just checks the initial word and the
174 ;               format version number -- nothing very exciting.
175
176                 EXPORT  draw_checkValid
177 draw_checkValid ROUT
178
179                 BIC     R14,R14,#V_flag         ;Assume everything's OK
180                 STMFD   R13!,{R1,R14}           ;Save a register away
181                 LDR     R14,draw__drawMagic     ;Load the magic word out
182                 LDR     R1,[R0,#0]              ;Load the first word out
183                 CMP     R14,R1                  ;Do they match perfectly?
184                 BNE     %90draw_checkValid      ;No -- then return error
185                 LDR     R14,[R0,#4]             ;Load major format version
186                 CMP     R14,#201                ;Is it old enough for me?
187                 LDMLEFD R13!,{R1,PC}^           ;Return to caller if OK
188
189                 ; --- Version number is wrong ---
190
191                 ADR     R0,draw__tooNew         ;Point to the error message
192                 B       %95draw_checkValid      ;And handle the error
193
194 draw__drawMagic DCB     "Draw"
195
196 draw__tooNew    DCD     1
197                 DCB     "drawTOONEW",0
198
199                 ; --- It isn't a drawfile ---
200
201 90              ADR     R0,draw__badFile        ;Point to the error message
202 95              BL      msgs_error              ;Translate the error
203                 LDMFD   R13!,{R1,R14}           ;Unstack some registers
204                 ORRS    PC,R14,#V_flag          ;And return the error
205
206 draw__badFile   DCD     1
207                 DCB     "drawBADFILE",0
208
209                 LTORG
210
211 ; --- draw__doRender ---
212 ;
213 ; On entry:     R7 == pointer to object to start rendering
214 ;               R8 == pointer to first object not to render
215 ;               R9 == pointer to coordinate clipping block
216 ;               R10 == pointer to transformation matrix
217 ;               R12 == pointer to font array
218 ;
219 ; On exit:      R7 points past last object rendered
220 ;               R0-R6 may be corrupted
221 ;
222 ; Use:          Renders a group of objects.
223
224 draw__doRender  ROUT
225
226                 STMFD   R13!,{R14}              ;Save a register
227 00              CMP     R7,R8                   ;Is there anything to do?
228                 BLLT    draw__renderObject      ;Yes -- render an object
229                 BLT     %00draw__doRender       ;And go round again
230                 LDMFD   R13!,{PC}^              ;Return to caller
231
232                 LTORG
233
234 ; --- draw__renderObject ---
235 ;
236 ; On entry:     R7 == pointer to object to render
237 ;               R8 == pointer to first object not to render
238 ;               R9 == pointer to coordinate clipping block
239 ;               R10 == pointer to transformation matrix
240 ;               R12 == pointer to font array
241 ;
242 ; On exit:      R7 == pointer to next object to render
243 ;               R0-R6 may be corrupted
244 ;
245 ; Use:          The main object rendering dispatch routine.
246
247 draw__renderObject ROUT
248
249                 LDR     R0,[R7,#0]              ;Get the object's type
250                 CMP     R0,#(%10-%00)/4         ;Is it in range of my table?
251                 ADDLO   PC,PC,R0,LSL #2         ;Yes -- dispatch it then
252                 B       %10draw__renderObject   ;Out of range -- ignore it
253
254 00              B       draw__readFontTable     ;Font table object
255                 B       draw__renderText        ;Render a text string
256                 B       draw__renderPath        ;Render a standard draw path
257                 B       %10draw__renderObject   ;Type 3 is not defined
258                 B       %10draw__renderObject   ;Type 4 is not defined
259                 B       draw__renderSprite      ;Render a sprite
260                 B       draw__renderGroup       ;Handle a group of objects
261                 B       draw__renderTagged      ;Render a tagged object
262                 B       %10draw__renderObject   ;Type 8 is not defined
263                 B       %10draw__renderObject   ;Text area is too difficult
264                 B       %10draw__renderObject   ;Text column is too difficult
265                 B       %10draw__renderObject   ;Options are not renderable
266                 B       draw__renderTransformedText ;Render rotated text
267                 B       draw__renderTransformedSprite ;Render rotated sprite
268                 B       %10draw__renderObject   ;Type 14 is not defined
269                 B       %10draw__renderObject   ;Type 15 is not defined
270                 B       draw__renderJPEG        ;Render a JPEG
271
272 10              B       draw__next              ;Ignore unknown objects
273
274                 LTORG
275
276 ; --- draw__next ---
277 ;
278 ; On entry:     R7 == pointer to a draw object
279 ;
280 ; On exit:      R7 == pointer to next draw object
281 ;               R0 corrupted
282 ;
283 ; Use:          Moves the current pointer on to the next object
284
285 draw__next      ROUT
286
287                 LDR     R0,[R7,#4]              ;Load the object size
288                 ADD     R7,R7,R0                ;Advance the object pointer
289                 MOVS    PC,R14                  ;Return to caller
290
291                 LTORG
292
293 ; --- draw__clip ---
294 ;
295 ; On entry:     R7 == pointer to a draw object
296 ;               R9 == pointer to current clipping rectangle
297 ;
298 ; On exit:      R0-R6 corrupted
299 ;               CS if the object appears within the clipping rectangle,
300 ;               CC if it doesn't
301 ;
302 ; Use:          Determines if a draw object needs rendering in the current
303 ;               redraw job.
304
305 draw__clip      STMFD   R13!,{R7}               ;Save a register
306                 ADD     R7,R7,#8                ;Point to the bounding box
307                 LDMIA   R7,{R4-R7}              ;Load the box from it
308                 LDMIA   R9,{R0-R3}              ;And load the clipping box
309                 CMP     R0,R6                   ;Make sure the rectangles...
310                 CMPLE   R1,R7                   ;... overlap
311                 CMPLE   R4,R2
312                 CMPLE   R5,R3
313                 LDMFD   R13!,{R7}               ;Restore the R7 I saved
314                 ORRLES  PC,R14,#C_flag          ;If it is within, set C
315                 BICGTS  PC,R14,#C_flag          ;Otherwise clear C on exit
316
317                 LTORG
318
319 ; --- draw__setTextSize ---
320 ;
321 ; On entry:     R0 == x size in pixels
322 ;               R1 == y size in pixels
323 ;
324 ; On exit:      --
325 ;
326 ; Use:          Sets the VDU 5 text size.
327
328 draw__setTextSize ROUT
329
330                 STMFD   R13!,{R0-R2,R14}        ;Save a load of registers
331                 MOV     R1,R1,LSL #16           ;Shift up the y sizes
332                 ORR     R1,R1,R0                ;Add in the x sizes
333                 MOV     R0,#23                  ;Build initial VDU sequence
334                 ORR     R0,R0,#17<<8            ;Add in more chars
335                 ORR     R0,R0,#7<<16
336                 ORR     R0,R0,#2<<24
337                 MOV     R2,#0                   ;Wrap up the sequence nicely
338                 STMFD   R13!,{R0-R2}            ;Save it on the stack
339                 MOV     R0,R13                  ;Point to the sequence
340                 MOV     R1,#10                  ;Get the sequence size in R1
341                 SWI     OS_WriteN               ;Write it to the VDU stream
342                 MOV     R14,#4                  ;Now set the spacing up
343                 STRB    R14,[R13,#3]            ;Save it in the stream
344                 MOV     R0,R13                  ;Point to the sequence
345                 MOV     R1,#10                  ;Get the sequence size in R1
346                 SWI     OS_WriteN               ;Write it to the VDU stream
347                 ADD     R13,R13,#12             ;Restore the stack pointer
348                 LDMFD   R13!,{R0-R2,PC}^        ;Return to caller
349
350                 LTORG
351
352 ; --- draw__resetTextSize ---
353 ;
354 ; On entry:     --
355 ;
356 ; On exit:      --
357 ;
358 ; Use:          Makes the text size nice again after doing all sorts of
359 ;               horrid things to it for the sake of plotting text in the
360 ;               system font.
361
362 draw__resetTextSize ROUT
363
364                 STMFD   R13!,{R0,R1,R14}        ;Save some registers
365                 BL      screen_getInfo          ;Read the screen information
366                 LDMIA   R0,{R0,R1}              ;Load the eigen factors
367                 MOV     R14,#16                 ;Normal width 16 OS units
368                 MOV     R0,R14,LSR R0           ;Scale it into pixels
369                 MOV     R14,#32                 ;Normal height 32 OS units
370                 MOV     R1,R14,LSR R1           ;Scale it into pixels
371                 BL      draw__setTextSize       ;Set the pixel size nicely
372                 LDMFD   R13!,{R0,R1,PC}^        ;And return to caller
373
374                 LTORG
375
376 ;----- Object handlers ------------------------------------------------------
377 ;
378 ; All of these have the same entry and exit conditions as draw__renderObject.
379
380 ; --- draw__readFontTable ---
381
382 draw__readFontTable ROUT
383
384                 LDR     R1,[R7,#4]              ;Find the object size
385                 ADD     R1,R7,R1                ;Convert to object end
386                 ADD     R0,R7,#8                ;Find start of font data
387
388                 ; --- Read an entry from the table ---
389
390 00              CMP     R0,R1                   ;Have we finished yet?
391                 BGE     draw__next              ;Yes -- return to caller
392                 LDRB    R2,[R0],#1              ;Get the internal font handle
393                 CMP     R2,#0                   ;Is this a null one?
394                 BEQ     draw__next              ;Yes -- that's it then
395
396                 STR     R0,[R12,R2,LSL #2]      ;Save the name pointer away
397 10              LDRB    R2,[R0],#1              ;Get a font name character
398                 CMP     R2,#0                   ;Is this the end of the name?
399                 BNE     %10draw__readFontTable  ;No -- go round again then
400
401                 B       %00draw__readFontTable  ;Read the next font name
402
403                 LTORG
404
405 ; --- draw__renderText ---
406
407 draw__renderText ROUT
408
409                 STMFD   R13!,{R14}              ;Save the link temporarily
410                 BL      draw__clip              ;Do we have to render it?
411                 LDMFD   R13!,{R14}              ;Restore the link again
412                 BCC     draw__next              ;No -- then return
413
414                 ; --- Make sure the text isn't invisible ---
415
416                 LDR     R0,[R7,#24]             ;Load the foreground colour
417                 CMP     R0,#-1                  ;Is it transparent?
418                 MOVEQS  PC,R14                  ;Yes -- do nothing then
419                 ADD     R6,R7,#24               ;Point to the object data
420
421                 ; --- Find the font name ---
422
423                 LDR     R5,[R6,#8]              ;Load internal font handle
424                 CMP     R5,#0                   ;Is the handle 0?
425                 BEQ     draw__renderSystemText  ;Yes -- use the system font
426                 LDR     R5,[R12,R5,LSL #2]      ;Load the font name pointer
427                 CMP     R5,#0                   ;Is it defined?
428                 BEQ     draw__renderSystemText  ;No -- use the system font
429
430                 ; --- Work out the text size I need ---
431
432                 STMFD   R13!,{R14}              ;Save the link again
433                 ADD     R2,R6,#12               ;Point to the text sizes
434                 LDR     R4,[R10,#0]             ;Load the scale factor
435                 LDMIA   R2,{R2,R3}              ;Load x and y sizes
436                 MOV     R4,R4,LSR #8            ;Scale it down a little
437                 MUL     R2,R4,R2                ;Scale up the x size
438                 MUL     R3,R4,R3                ;And scale up the y size
439                 MOV     R4,#5                   ;So div10 rounds to nearest
440                 ADD     R2,R4,R2,LSR #10        ;Scale values down further
441                 ADD     R3,R4,R3,LSR #10        ;Both the x and the y
442                 MOV     R0,R2                   ;Get the x size
443                 BL      div10                   ;Convert to points
444                 MOV     R2,R0                   ;Move back into position
445                 MOV     R0,R3                   ;Get the y size
446                 BL      div10                   ;Convert to points
447                 MOV     R3,R0                   ;Move back into position
448                 LDMFD   R13!,{R14}              ;Restore the link again
449
450                 ; --- Get a font handle ---
451
452                 MOV     R1,R5                   ;Get the font name pointer
453                 MOV     R4,#0                   ;Default scaling, please
454                 MOV     R5,#0                   ;On x and y axes
455                 SWI     XFont_FindFont          ;Try to get a font handle
456                 BVS     draw__renderSystemText  ;Couldn't -- use system font
457
458                 ; --- Set the right colours ---
459
460                 LDR     R1,[R6,#4]              ;Load the background colour
461                 LDR     R2,[R6,#0]              ;Load the foreground colour
462                 MOV     R3,#14                  ;Antialias lots and lots
463                 SWI     ColourTrans_SetFontColours
464
465                 ; --- Work out where to paint the text ---
466
467                 ADD     R3,R6,#20               ;Point to the coordinates
468                 LDR     R5,[R10,#0]             ;Load the scale factor out
469                 LDMIA   R3,{R3,R4}              ;Load the coordinates out
470                 MOV     R5,R5,LSR #8            ;Scale it down a little
471                 MUL     R3,R5,R3                ;Multiply up the x position
472                 MUL     R4,R5,R4                ;Multiply up the y position
473                 MOV     R3,R3,ASR #16           ;Scale down the x position
474                 MOV     R4,R4,ASR #16           ;Scale down the y position
475                 ADD     R1,R10,#16              ;Point to the plot offset
476                 LDMIA   R1,{R1,R2}              ;Load the offsets out
477                 ADD     R3,R3,R1,ASR #8         ;Add it on (convert to OS)
478                 ADD     R4,R4,R2,ASR #8         ;Convert the y coordinate too
479
480                 ; --- Paint the actual text then ---
481
482                 ADD     R1,R6,#28               ;Point to the text string
483                 MOV     R2,#&10                 ;Coordinates are in OS units
484                 SWI     Font_Paint              ;Paint the text on the screen
485
486                 ; --- Tidy everything up then ---
487
488                 SWI     Font_LoseFont           ;Lose the font handle now
489                 B       draw__next              ;Find next draw object
490
491                 LTORG
492
493 ; --- draw__renderSystemText ---
494 ;
495 ; Notes:        This routine is entered with R6 set up as pointer to the
496 ;               specific object data, and havng made sure that the text
497 ;               actually does have to be rendered.
498
499 draw__renderSystemText ROUT
500
501                 ; --- Set up the plotting colour ---
502
503                 STMFD   R13!,{R14}              ;Save the link register
504                 LDR     R0,[R6,#0]              ;Load the foreground colour
505                 MOV     R3,#0                   ;Don't bother dithering it
506                 MOV     R4,#0                   ;And set normal GCOL action
507                 SWI     ColourTrans_SetGCOL     ;Set up the colour
508
509                 ; --- Set up the text size ---
510
511                 BL      screen_getInfo          ;Get things about the screen
512                 LDMIA   R0,{R2,R3}              ;Load the eigen factors
513                 ADD     R14,R6,#12              ;Point to the size arguments
514                 LDR     R4,[R10,#0]             ;Load the scale factor
515                 LDMIA   R14,{R0,R1}             ;Load the text sizes out
516                 MOV     R4,R4,LSR #8            ;Shift it down a little
517                 MUL     R0,R4,R0                ;Multiply x size up
518                 MUL     R1,R4,R1                ;Multiply y size up too
519                 MOV     R0,R0,LSR #16           ;Scale x size down more
520                 MOV     R0,R0,LSR R2            ;And divide by pixel size
521                 MOV     R1,R1,LSR #16           ;Scale y size down more
522                 MOV     R1,R1,LSR R3            ;And divide by pixel size
523                 BL      draw__setTextSize       ;Set the VDU 5 text size
524                 MOV     R3,R1,LSL R3            ;Multply y size up a bit
525
526                 ; --- Move to the right place ---
527
528                 ADD     R14,R6,#20              ;Point to the position data
529                 LDMIA   R14,{R1,R2}             ;Load the text positions
530                 MUL     R1,R4,R1                ;Scale up the x position
531                 MUL     R2,R4,R2                ;Scale up the y position
532                 MOV     R1,R1,ASR #16           ;Scale down the x pos
533                 MOV     R2,R2,ASR #16           ;Scale down the y pos
534                 SUB     R3,R3,R3,LSR #3         ;Find 7/8 of character height
535                 ADD     R2,R2,R3                ;Find top of text line
536                 ADD     R14,R10,#16             ;Find render offsets nicely
537                 LDMIA   R14,{R3,R4}             ;Load the offsets out
538                 ADD     R1,R1,R3,ASR #8         ;Add them and convert to OS
539                 ADD     R2,R2,R4,ASR #8         ;Both the x and the y please
540                 MOV     R0,#4                   ;Move cursor absolute
541                 SWI     OS_Plot                 ;Move graphics cursor nicely
542
543                 ; --- Plot the text and go home ---
544
545                 ADD     R0,R6,#28               ;Point to the text string
546                 SWI     OS_Write0               ;Plot it on the screen
547                 LDMFD   R13!,{R14}              ;Unstack the link register
548                 B       draw__next              ;And move to the next object
549
550                 LTORG
551
552 ; --- draw__renderPath ---
553
554 draw__renderPath ROUT
555
556                 STMFD   R13!,{R14}              ;Save the link temporarily
557                 BL      draw__clip              ;Do we have to render it?
558                 LDMCCFD R13!,{R14}              ;Restore the link again
559                 BCC     draw__next              ;No -- then return
560
561                 LDR     R6,[R7,#36]             ;Load the path style word
562                 TST     R6,#&80                 ;Is there a dot-dash pattern?
563                 ADDEQ   R5,R7,#40               ;No -- find path data then
564                 LDRNE   R5,[R7,#44]             ;Yes -- load dot-dash length
565                 ADDNE   R5,R7,R5,LSL #2         ;Add this to object start
566                 ADDNE   R5,R5,#48               ;And add fixed part of dash
567
568                 ; --- Handle the filled in bit ---
569
570                 LDR     R0,[R7,#24]             ;Load the fill colour
571                 CMP     R0,#-1                  ;Is it transparent?
572                 BEQ     %50draw__renderPath     ;Yes -- just draw outline
573
574                 ; --- Render a filled path ---
575
576                 MOV     R3,#&100                ;Try and dither the fill
577                 MOV     R4,#0                   ;Set normal GCOL action
578                 SWI     ColourTrans_SetGCOL     ;Set the colour up
579
580                 MOV     R0,#&c80000             ;The basic flatness is 200
581                 LDR     R1,[R10,#0]             ;Load the scale factor
582                 BL      div_round               ;Divide to get the flatness
583                 MOV     R3,R0                   ;Get flatness in R3 nicely
584
585                 AND     R1,R6,#&40              ;Get the path winding rule
586                 MOV     R1,R1,LSR #5            ;Shift it down into place
587                 ORR     R1,R1,#&30              ;And add in other fill bits
588                 MOV     R0,R5                   ;Point to path specification
589                 MOV     R2,R10                  ;Point to transform matrix
590                 SWI     Draw_Fill               ;And render the filled path
591
592                 ; --- Now handle an outline ---
593
594 50              LDR     R0,[R7,#28]             ;Load the outline colour
595                 CMP     R0,#-1                  ;Is it transparent?
596                 BEQ     %90draw__renderPath     ;Yes -- wrap everything up
597
598                 ; --- Render a path outline ---
599
600                 MOV     R3,#&100                ;Try and dither the outline
601                 MOV     R4,#0                   ;Set normal GCOL action
602                 SWI     ColourTrans_SetGCOL     ;Set the colour up
603
604                 ; --- Build the cap and join block ---
605                 ;
606                 ; Note that in fact the end cap and start cap specs are
607                 ; reversed.  This is a result of Acorn stupidity, bad
608                 ; documentation, or both.  We sit back and laugh as
609                 ; WimpExtension gets it wrong.
610
611                 AND     R0,R6,#&03              ;Get the join style style
612                 AND     R4,R6,#&30              ;Get the start cap style
613                 ORR     R0,R0,R4,LSL #12        ;Move that into byte 2
614                 AND     R4,R6,#&0C              ;Get the end cap style
615                 ORR     R0,R0,R4,LSL #6         ;Move that into byte 1
616
617                 MOV     R1,#&A0000              ;Mitre limit is 10.0
618
619                 AND     R2,R6,#&00FF0000        ;Get triangle cap width
620                 MOV     R2,R2,LSR #12           ;Move it into position
621                 AND     R4,R6,#&FF000000        ;Get triangle cap height
622                 ORR     R2,R2,R4,LSR #4         ;Move that into position
623
624                 MOV     R3,R2                   ;End triangle == start one
625
626                 STMFD   R13!,{R0-R3}            ;Save cap and join spec
627
628                 ; --- Finally, plot the path ---
629
630                 MOV     R0,#&c80000             ;The basic flatness is 200
631                 LDR     R1,[R10,#0]             ;Load the scale factor
632                 BL      div_round               ;Divide to get the flatness
633                 MOV     R3,R0                   ;Get flatness in R3 nicely
634                 MOV     R0,R5                   ;Point to the path spec
635                 MOV     R1,#&38                 ;A set fill style, please
636                 MOV     R2,R10                  ;Point to transform matrix
637                 LDR     R4,[R7,#32]             ;Load the line width
638                 MOV     R5,R13                  ;Point to join and cap block
639                 TST     R6,#&80                 ;Is there a dash pattern?
640                 MOVEQ   R6,#0                   ;No -- don't plot one then
641                 ADDNE   R6,R7,#40               ;Yes -- find the data
642                 SWI     Draw_Stroke             ;Plot the path outline
643                 ADD     R13,R13,#16             ;Recover used stack space
644
645                 ; --- Wrap it all up nicely ---
646
647 90              LDMFD   R13!,{R14}              ;Restore the link again
648                 B       draw__next              ;Find the next draw object
649
650                 LTORG
651
652 ; --- draw__renderSprite ---
653
654 draw__renderSprite ROUT
655
656                 ; --- Make sure I have to render it ---
657
658                 STMFD   R13!,{R14}              ;Save the link temporarily
659                 BL      draw__clip              ;Do we have to render it?
660                 LDMCCFD R13!,{R14}              ;Restore the link again
661                 BCC     draw__next              ;No -- then return
662
663                 ; --- Get a colour translation table for it ---
664
665                 ADD     R0,R7,#24               ;Point to the sprite def
666                 MOV     R1,R11                  ;Put table in scratchpad
667                 BL      sprite_getTable         ;Find a translation table
668
669                 ; --- Work out the correct scaling ---
670
671                 MOV     R0,#40+512              ;Read sprite info
672                                                 ;Sprite is pointed at
673                 MOV     R1,#&1000               ;Don't care about sprite area
674                 ADD     R2,R7,#24               ;Point to sprite block
675                 SWI     OS_SpriteOp             ;Read the sprite info
676                 BL      screen_getInfo          ;Read some screen info
677                 LDMIA   R0,{R0,R1}              ;Load the eigen factors
678                 MOV     R5,R4,LSL R1            ;Scale the y value into R5
679                 MOV     R4,R3,LSL R0            ;Scale the x value into R4
680
681                 ADD     R0,R7,#8                ;Point to sprite bounding box
682                 LDMIA   R0,{R0-R3}              ;Load the values out
683                 SUB     R2,R2,R0                ;Get sprite width in R2
684                 SUB     R3,R3,R1                ;Get sprite height in R3
685                 LDR     R14,[R10,#0]            ;Load the scale factor
686                 MOV     R2,R2,LSR #8            ;Scale the dimensions down
687                 MOV     R3,R3,LSR #8            ;In both directions
688                 MUL     R2,R14,R2               ;Scale the x size
689                 MUL     R3,R14,R3               ;And the y size
690                 MOV     R2,R2,LSR #16           ;And scale the value down
691                 MOV     R3,R3,LSR #16           ;Both directions again
692                 STMFD   R13!,{R2-R5,R7}         ;Save the resulting zoom blk
693                                                 ;Save R7 -- we need to use it
694
695                 MOV     R14,R14,LSR #8          ;Shift scale factor down
696                 MUL     R3,R14,R0               ;Scale the x position
697                 MUL     R4,R14,R1               ;And the y position
698                 MOV     R3,R3,ASR #16           ;Scale down the resulting pos
699                 MOV     R4,R4,ASR #16           ;In both directions
700                 ADD     R0,R10,#16              ;Find the transform offsets
701                 LDMIA   R0,{R0,R1}              ;Load them from the block
702                 ADD     R3,R3,R0,ASR #8         ;Add the x offset on
703                 ADD     R4,R4,R1,ASR #8         ;Add the y offset on too
704
705                 ; --- Now plot the sprite in the right place ---
706
707                 MOV     R0,#52+512              ;Plot sprite scaled, please
708                 MOV     R1,#&1000               ;A dummy sprite area
709                 ADD     R2,R7,#24               ;Point to the sprite def
710                 MOV     R5,#8                   ;Plot with mask, please
711                 MOV     R6,R13                  ;Point to my zoom block
712                 MOV     R7,R11                  ;Point to my translate table
713                 SWI     OS_SpriteOp             ;Plot the sprite
714                 ADD     R13,R13,#16             ;Recover the zoom block
715                 LDMFD   R13!,{R7, R14}          ;Unstack R7 and link register
716                 B       draw__next              ;And render the next object
717
718                 LTORG
719
720 ; --- draw__renderGroup ---
721
722 draw__renderGroup ROUT
723
724                 STMFD   R13!,{R14}              ;Save the link temporarily
725                 BL      draw__clip              ;Do we have to render it?
726                 LDMFD   R13!,{R14}              ;Restore the link again
727                 BCC     draw__next              ;No -- then return
728
729                 ADD     R7,R7,#36               ;Render the objects in there
730                 MOVS    PC,R14                  ;I've mangled the object ptr
731
732                 LTORG
733
734 ; --- draw__renderTagged ---
735
736 draw__renderTagged ROUT
737
738                 STMFD   R13!,{R14}              ;Save the link temporarily
739                 BL      draw__clip              ;Do we have to render it?
740                 LDMCCFD R13!,{R14}              ;Restore the link again
741                 BCC     draw__next              ;No -- then return
742
743                 STMFD   R13!,{R7,R8}            ;Save the object pointer
744                                                 ;SA optimised, looks crazy:
745                 LDR     R8,[R7,#32]             ;Get the object size
746                 ADD     R7,R7,#28               ;Point to the enclosed object
747                 ADD     R8,R7,R8                ;Point past the object
748                 BL      draw__doRender          ;Render the object
749                 LDMFD   R13!,{R7,R8,R14}        ;Restore registers
750                 B       draw__next              ;And move to the next object
751
752                 LTORG
753
754 ; --- draw__renderTransformedText ---
755
756 draw__renderTransformedText ROUT
757
758                 STMFD   R13!,{R14}              ;Save the link temporarily
759                 BL      draw__clip              ;Do we have to render it?
760                 BLCS    rov_version             ;Get the current OS version
761                 CMPCS   R0,#300                 ;Is it RISC OS 3 yet?
762                 LDMFD   R13!,{R14}              ;Restore the link again
763                 BCC     draw__next              ;No -- then return
764
765                 ; --- Make sure the text isn't invisible ---
766
767                 LDR     R0,[R7,#24]             ;Load the foreground colour
768                 CMP     R0,#-1                  ;Is it transparent?
769                 MOVEQS  PC,R14                  ;Yes -- do nothing then
770                 ADD     R6,R7,#24               ;Point to the object data
771
772                 ; --- Find the font name ---
773
774                 LDR     R5,[R6,#36]             ;Load internal font handle
775                 CMP     R5,#0                   ;Is the handle 0?
776                 BEQ     %90draw__renderTransformedText
777                 LDR     R5,[R12,R5,LSL #2]      ;Load the font name pointer
778                 CMP     R5,#0                   ;Is it defined?
779                 BEQ     %90draw__renderTransformedText
780
781                 ; --- Work out the text size I need ---
782
783                 STMFD   R13!,{R14}              ;Save the link again
784                 ADD     R2,R6,#40               ;Point to the text sizes
785                 LDR     R4,[R10,#0]             ;Load the scale factor
786                 LDMIA   R2,{R2,R3}              ;Load x and y sizes
787                 MOV     R4,R4,LSR #8            ;Scale it down a little
788                 MUL     R2,R4,R2                ;Scale up the x size
789                 MUL     R3,R4,R3                ;And scale up the y size
790                 MOV     R4,#5                   ;So div10 rounds to nearest
791                 ADD     R2,R4,R2,LSR #10        ;Scale values down further
792                 ADD     R3,R4,R3,LSR #10        ;Both the x and the y
793                 MOV     R0,R2                   ;Get the x size
794                 BL      div10                   ;Convert to points
795                 MOV     R2,R0                   ;Move back into position
796                 MOV     R0,R3                   ;Get the y size
797                 BL      div10                   ;Convert to points
798                 MOV     R3,R0                   ;Move back into position
799                 LDMFD   R13!,{R14}              ;Restore the link again
800
801                 ; --- Get a font handle ---
802
803                 MOV     R1,R5                   ;Get the font name pointer
804                 MOV     R4,#0                   ;Default scaling, please
805                 MOV     R5,#0                   ;On x and y axes
806                 SWI     XFont_FindFont          ;Try to get a font handle
807                 BVS     %90draw__renderTransformedText
808
809                 ; --- Set the right colours ---
810
811                 LDR     R1,[R6,#32]             ;Load the background colour
812                 LDR     R2,[R6,#28]             ;Load the foreground colour
813                 MOV     R3,#14                  ;Antialias lots and lots
814                 SWI     ColourTrans_SetFontColours
815
816                 ; --- Work out where to paint the text ---
817
818                 ADD     R3,R6,#48               ;Point to the coordinates
819                 LDR     R5,[R10,#0]             ;Load the scale factor out
820                 LDMIA   R3,{R3,R4}              ;Load the coordinates out
821                 MOV     R5,R5,LSR #8            ;Scale it down a little
822                 MUL     R3,R5,R3                ;Multiply up the x position
823                 MUL     R4,R5,R4                ;Multiply up the y position
824                 MOV     R3,R3,ASR #16           ;Scale down the x position
825                 MOV     R4,R4,ASR #16           ;Scale down the y position
826                 ADD     R1,R10,#16              ;Point to the plot offset
827                 LDMIA   R1,{R1,R2}              ;Load the offsets out
828                 ADD     R3,R3,R1,ASR #8         ;Add it on (convert to OS)
829                 ADD     R4,R4,R2,ASR #8         ;Convert the y coordinate too
830
831                 ; --- Scale position to millipoints ---
832                 ;
833                 ; Multiply by 500 (very quickly)
834
835                 ADD     R3,R3,R3,LSL #2         ;Multiply R3 by 5 (*5)
836                 ADD     R3,R3,R3,LSL #2         ;Multiply R3 by 5 (*25)
837                 MOV     R3,R3,LSL #4            ;Multiply R3 by 16 (*400)
838
839                 ADD     R4,R4,R4,LSL #2         ;Multiply R3 by 5 (*5)
840                 ADD     R4,R4,R4,LSL #2         ;Multiply R3 by 5 (*25)
841                 MOV     R4,R4,LSL #4            ;Multiply R3 by 16 (*400)
842
843                 ; --- Paint the actual text then ---
844
845                 LDR     R2,[R6,#24]             ;Load the special magic flags
846                 ADD     R1,R6,#56               ;Point to the text string
847                 MOV     R2,R2,LSL #9            ;Shift flags into position
848                 ORR     R2,R2,#&40              ;Specify transform matrix
849                 STMFD   R13!,{R0}               ;Save the font handle
850                 SWI     XFont_Paint             ;Paint the text on the screen
851                 LDMFD   R13!,{R0}               ;Restore the font handle
852
853                 ; --- Tidy everything up then ---
854
855                 SWI     Font_LoseFont           ;Lose the font handle now
856 90              B       draw__next              ;Find next draw object
857
858                 LTORG
859
860 ; --- draw__renderTransformedSprite ----
861
862 draw__renderTransformedSprite ROUT
863
864                 ; --- Make sure I have to render it ---
865
866                 STMFD   R13!,{R14}              ;Save the link temporarily
867                 BL      draw__clip              ;Do we have to render it?
868                 BLCS    rov_version             ;Get the current OS version
869                 CMPCS   R0,#300                 ;Is it RISC OS 3 yet?
870                 LDMCCFD R13!,{R14}              ;Restore the link again
871                 BCC     draw__next              ;No -- then return
872
873                 ; --- Get a colour translation table for it ---
874
875                 ADD     R0,R7,#48               ;Point to the sprite def
876                 MOV     R1,R11                  ;Put table in scratchpad
877                 BL      sprite_getTable         ;Find a translation table
878
879                 ; --- Build the transformation matrix ---
880
881                 ADD     R14,R7,#24              ;Find the transform matrix
882                 LDR     R6,[R10,#0]             ;Load the scale factor
883                 LDMIA   R14,{R0-R5}             ;Load all the bits I need
884                 MOV     R6,R6,LSR #8            ;Shift scale factor down
885                 MOV     R0,R0,ASR #8            ;Also shift down sprite scale
886                 MOV     R1,R1,ASR #8            ;Also shift down sprite scale
887                 MOV     R2,R2,ASR #8            ;Also shift down sprite scale
888                 MOV     R3,R3,ASR #8            ;Also shift down sprite scale
889                 MUL     R0,R6,R0                ;Apply scale to sprite matrix
890                 MUL     R1,R6,R1                ;Apply scale to sprite matrix
891                 MUL     R2,R6,R2                ;Apply scale to sprite matrix
892                 MUL     R3,R6,R3                ;Apply scale to sprite matrix
893                 STMFD   R13!,{R7}               ;Save R7 -- we need to use it
894                 SUB     R13,R13,#24             ;Make space for matrix
895                 STMIA   R13,{R0-R3}             ;Save transform on stack
896                 ADD     R14,R10,#16             ;Point to my offsets
897                 LDMIA   R14,{R0,R1}             ;Load the offsets out
898                 MUL     R4,R6,R4                ;Scale the sprite x offset
899                 MUL     R5,R6,R5                ;Scale the sprite y offset
900                 ADD     R4,R0,R4,ASR #8         ;Add on to original offset
901                 ADD     R5,R1,R5,ASR #8         ;Add on to original offset
902                 ADD     R14,R13,#16             ;Point to bit of matrix
903                 STMIA   R14,{R4,R5}             ;Save these in the matrix
904
905                 ; --- Now plot the sprite in the right place ---
906
907                 MOV     R0,#512+56              ;Plot sprite scaled, please
908                                                 ;Tell it I have a sprite ptr
909                 MOV     R1,#&1000               ;A dummy sprite area
910                 ADD     R2,R7,#48               ;Point to the sprite def
911                 MOV     R3,#0                   ;R6 points to a matrix
912                 MOV     R4,#0                   ;No source rectangle thing
913                 MOV     R5,#8                   ;Plot with mask, please
914                 MOV     R6,R13                  ;Point to my matrix
915                 MOV     R7,R11                  ;Point to my translate table
916                 SWI     OS_SpriteOp             ;Plot the sprite
917                 ADD     R13,R13,#24             ;Recover the matrix block
918                 LDMFD   R13!,{R7,R14}           ;Unstack R7 and link register
919                 B       draw__next              ;And render the next object
920
921 ; --- draw__renderJPEG ----
922
923 draw__renderJPEG ROUT
924
925                 ; --- Make sure I have to render it ---
926
927                 STMFD   R13!,{R14}              ;Save the link temporarily
928                 BL      draw__clip              ;Do we have to render it?
929                 BLCS    rov_version             ;Get the current OS version
930                 CMPCS   R0,#360                 ;Is it RISC OS 3.60 yet?
931                 LDMCCFD R13!,{R14}              ;Restore the link again
932                 BCC     draw__next              ;No -- then return
933
934                 ; --- Build the transformation matrix ---
935
936                 ADD     R14,R7,#40              ;Find the transform matrix
937                 LDR     R6,[R10,#0]             ;Load the scale factor
938                 LDMIA   R14,{R0-R5}             ;Load all the bits I need
939                 MOV     R6,R6,LSR #8            ;Shift scale factor down
940                 MOV     R0,R0,ASR #8            ;Also shift down JPEG scale
941                 MOV     R1,R1,ASR #8            ;Also shift down JPEG scale
942                 MOV     R2,R2,ASR #8            ;Also shift down JPEG scale
943                 MOV     R3,R3,ASR #8            ;Also shift down JPEG scale
944                 MUL     R0,R6,R0                ;Apply scale to JPEG matrix
945                 MUL     R1,R6,R1                ;Apply scale to JPEG matrix
946                 MUL     R2,R6,R2                ;Apply scale to JPEG matrix
947                 MUL     R3,R6,R3                ;Apply scale to JPEG matrix
948                 SUB     R13,R13,#24             ;Make space for matrix
949                 STMIA   R13,{R0-R3}             ;Save transform on stack
950                 ADD     R14,R10,#16             ;Point to my offsets
951                 LDMIA   R14,{R0,R1}             ;Load the offsets out
952                 MUL     R4,R6,R4                ;Scale the JPEG x offset
953                 MUL     R5,R6,R5                ;Scale the JPEG y offset
954                 ADD     R4,R0,R4,ASR #8         ;Add on to original offset
955                 ADD     R5,R1,R5,ASR #8         ;Add on to original offset
956                 ADD     R14,R13,#16             ;Point to bit of matrix
957                 STMIA   R14,{R4,R5}             ;Save these in the matrix
958
959                 ; --- Now plot the JPEG in the right place ---
960
961                 ADD     R0,R7,#68               ;Point to the JPEG def
962                 MOV     R1,#2                   ;R2 points to a matrix, dither
963                 MOV     R2,R13                  ;Point to my matrix
964                 LDR     R3,[R0,#-4]             ;Load length of JPEG
965                 SWI     JPEG_PlotTransformed    ;Plot the JPEG
966                 ADD     R13,R13,#24             ;Recover the matrix block
967                 LDMFD   R13!,{R14}              ;Unstack the link register
968                 B       draw__next              ;And render the next object
969
970                 LTORG
971
972 ;----- That's all, folks ----------------------------------------------------
973
974                 END