Megatest

Check-in [45a4edd000]
Login
Overview
Comment:Added ability to switch from records to vectors
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | v1.61
Files: files | file ages | folders
SHA1: 45a4edd00006f3d68e288080537d3c3af1e41591
User & Date: matt on 2016-07-24 18:23:26
Other Links: branch diff | manifest | tags
Context
2016-07-24
20:45
Fixed minor issues in vg check-in: fedfa235a2 user: matt tags: v1.61
18:23
Added ability to switch from records to vectors check-in: 45a4edd000 user: matt tags: v1.61
2016-07-23
23:49
Incremental drawing improvements. check-in: a6901d4365 user: matt tags: v1.61
Changes

Modified Makefile from [c12160c042] to [0b254e1d60].

60
61
62
63
64
65
66

67
68
69
70
71
72
73
tests.o runs.o dashboard.o dashboard-tests.o dashboard-main.o  : run_records.scm
db.o ezsteps.o keys.o launch.o megatest.o monitor.o runs-for-ref.o runs.o tests.o : key_records.scm
tests.o tasks.o dashboard-tasks.o : task_records.scm
runs.o : test_records.scm
megatest.o : megatest-fossil-hash.scm
client.scm common.scm configf.scm dashboard-guimonitor.scm dashboard-tests.scm dashboard.scm db.scm dcommon.scm ezsteps.scm fs-transport.scm http-transport.scm index-tree.scm items.scm keys.scm launch.scm megatest.scm monitor.scm mt.scm newdashboard.scm runconfig.scm runs.scm server.scm tdb.scm tests.scm tree.scm : common_records.scm rpc-transport.scm
common_records.scm : altdb.scm


# Temporary while transitioning to new routine
# runs.o : run-tests-queue-classic.scm  run-tests-queue-new.scm

megatest-fossil-hash.scm : $(SRCFILES) megatest.scm *_records.scm
	echo "(define megatest-fossil-hash \"$(MTESTHASH)\")" > megatest-fossil-hash.new
	if ! diff -q megatest-fossil-hash.new megatest-fossil-hash.scm ; then echo copying .new to .scm;cp -f megatest-fossil-hash.new megatest-fossil-hash.scm;fi







>







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
tests.o runs.o dashboard.o dashboard-tests.o dashboard-main.o  : run_records.scm
db.o ezsteps.o keys.o launch.o megatest.o monitor.o runs-for-ref.o runs.o tests.o : key_records.scm
tests.o tasks.o dashboard-tasks.o : task_records.scm
runs.o : test_records.scm
megatest.o : megatest-fossil-hash.scm
client.scm common.scm configf.scm dashboard-guimonitor.scm dashboard-tests.scm dashboard.scm db.scm dcommon.scm ezsteps.scm fs-transport.scm http-transport.scm index-tree.scm items.scm keys.scm launch.scm megatest.scm monitor.scm mt.scm newdashboard.scm runconfig.scm runs.scm server.scm tdb.scm tests.scm tree.scm : common_records.scm rpc-transport.scm
common_records.scm : altdb.scm
vg.o dashboard.o : vg_records.scm

# Temporary while transitioning to new routine
# runs.o : run-tests-queue-classic.scm  run-tests-queue-new.scm

megatest-fossil-hash.scm : $(SRCFILES) megatest.scm *_records.scm
	echo "(define megatest-fossil-hash \"$(MTESTHASH)\")" > megatest-fossil-hash.new
	if ! diff -q megatest-fossil-hash.new megatest-fossil-hash.scm ; then echo copying .new to .scm;cp -f megatest-fossil-hash.new megatest-fossil-hash.scm;fi
165
166
167
168
169
170
171








172

173
174
175
176
177
178
179
180

$(MTQA_FOSSIL) :
	fossil clone https://www.kiatoa.com/fossils/megatest_qa $(MTQA_FOSSIL)

clean : 
	rm -f $(OFILES) $(GOFILES) megatest dboard dboard.o megatest.o dashboard.o megatest-fossil-hash.* altdb.scm









# Deploy section (not complete yet)

#
$(DEPLOYHELPERS) : utils/mt_*
	$(INSTALL) $< $@
	chmod a+X $@

deploytarg/apropos.so : Makefile
	chicken-install -p deploytarg -deploy -keep-installed $(EGGS)








>
>
>
>
>
>
>
>

>
|







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

$(MTQA_FOSSIL) :
	fossil clone https://www.kiatoa.com/fossils/megatest_qa $(MTQA_FOSSIL)

clean : 
	rm -f $(OFILES) $(GOFILES) megatest dboard dboard.o megatest.o dashboard.o megatest-fossil-hash.* altdb.scm

#======================================================================
# Make the records files
#======================================================================

vg_records.scm : records.sh
	./records.sh

#======================================================================
# Deploy section (not complete yet)
#======================================================================

$(DEPLOYHELPERS) : utils/mt_*
	$(INSTALL) $< $@
	chmod a+X $@

deploytarg/apropos.so : Makefile
	chicken-install -p deploytarg -deploy -keep-installed $(EGGS)

Modified dashboard.scm from [369e57cb18] to [020630095d].

39
40
41
42
43
44
45

46
47
48
49
50
51
52
(declare (uses mt))

(include "common_records.scm")
(include "db_records.scm")
(include "run_records.scm")
(include "task_records.scm")
(include "megatest-fossil-hash.scm")


(define help (conc 
	      "Megatest Dashboard, documentation at http://www.kiatoa.com/fossils/megatest
  version " megatest-version "
  license GPL, Copyright (C) Matt Welland 2012-2016

Usage: dashboard [options]







>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
(declare (uses mt))

(include "common_records.scm")
(include "db_records.scm")
(include "run_records.scm")
(include "task_records.scm")
(include "megatest-fossil-hash.scm")
(include "vg_records.scm")

(define help (conc 
	      "Megatest Dashboard, documentation at http://www.kiatoa.com/fossils/megatest
  version " megatest-version "
  license GPL, Copyright (C) Matt Welland 2012-2016

Usage: dashboard [options]
1135
1136
1137
1138
1139
1140
1141
1142

1143
1144
1145
1146
1147
1148
1149
						    (begin
						      (dashboard:run-times-tab-run-data-updater commondat tabdat tab-num)
						      (dboard:tabdat-last-data-update-set! tabdat now-time)
						      (thread-start! (make-thread
								      (lambda ()
									(dboard:tabdat-running-layout-set! tabdat #t)
									(dashboard:run-times-tab-layout-updater commondat tabdat tab-num)
									(dboard:tabdat-running-layout-set! tabdat #f)))))

						  ))))))
				  "dashboard:run-times-tab-updater"))))
    (dboard:tabdat-drawing-set! tabdat drawing)
    (dboard:commondat-add-updater commondat run-times-tab-updater tab-num: tab-num)
    (iup:split
     #:orientation "VERTICAL" ;; "HORIZONTAL"
     #:value 200







|
>







1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
						    (begin
						      (dashboard:run-times-tab-run-data-updater commondat tabdat tab-num)
						      (dboard:tabdat-last-data-update-set! tabdat now-time)
						      (thread-start! (make-thread
								      (lambda ()
									(dboard:tabdat-running-layout-set! tabdat #t)
									(dashboard:run-times-tab-layout-updater commondat tabdat tab-num)
									(dboard:tabdat-running-layout-set! tabdat #f))
								      "run-times-tab-layout-updater")))
						  ))))))
				  "dashboard:run-times-tab-updater"))))
    (dboard:tabdat-drawing-set! tabdat drawing)
    (dboard:commondat-add-updater commondat run-times-tab-updater tab-num: tab-num)
    (iup:split
     #:orientation "VERTICAL" ;; "HORIZONTAL"
     #:value 200
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360



2361
2362
2363
2364
2365
2366
2367
2368

2369
2370
2371
2372


2373
2374
2375
2376
2377
2378
2379
(define-inline (dashboard:px-between px lx1 lx2)
  (and (< lx1 px)(> lx2 px)))

;; can a bar be placed in row "rownum" covering x1 to x2 without overlapping with existing 
;; bars? Use num-rows to check that a block will fit from rownum to (+ rownum num-rows)
;;
(define (dashboard:row-collision rowhash rownum x1 x2 #!key (num-rows #f))
  (let ((collision #f)
	(lastrow   (if num-rows (+ rownum num-rows) rownum)))
    (let loop ((i      0)
	       (rowdat (hash-table-ref/default rowhash rownum '())))
      (for-each
       (lambda (bar)



	 (let ((bx1 (car bar))
	       (bx2 (cdr bar)))
	   (cond
	    ;; newbar x1 inside bar
	    ((dashboard:px-between x1 bx1 bx2)(set! collision #t))
	    ((dashboard:px-between x2 bx1 bx2)(set! collision #t))
	    ((and (<= x1 bx1)(>= x2 bx2))(set! collision #t)))))
       rowdat)

      (if (< i lastrow)
	  (loop (+ i 1)
		(hash-table-ref/default rowhash (+ rownum i) '()))))
    collision))



(define (dashboard:add-bar rowhash rownum x1 x2 #!key (num-rows 0))
  (let loop ((i 0))
    (hash-table-set! rowhash 
		     (+ i rownum)
		     (cons (cons x1 x2) 
			   (hash-table-ref/default rowhash (+ i rownum) '())))







<
|


<
|
>
>
>
|
|
|
|
|
|
|
<
>
|
|
|
<
>
>







2350
2351
2352
2353
2354
2355
2356

2357
2358
2359

2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370

2371
2372
2373
2374

2375
2376
2377
2378
2379
2380
2381
2382
2383
(define-inline (dashboard:px-between px lx1 lx2)
  (and (< lx1 px)(> lx2 px)))

;; can a bar be placed in row "rownum" covering x1 to x2 without overlapping with existing 
;; bars? Use num-rows to check that a block will fit from rownum to (+ rownum num-rows)
;;
(define (dashboard:row-collision rowhash rownum x1 x2 #!key (num-rows #f))

  (let ((lastrow   (if num-rows (+ rownum num-rows) rownum)))
    (let loop ((i      0)
	       (rowdat (hash-table-ref/default rowhash rownum '())))

      (if (null? rowdat)
	  #f
	  (let rowloop ((bar (car rowdat))
			(tal (cdr rowdat)))
	    (let ((bx1 (car bar))
		  (bx2 (cdr bar)))
	      (cond
	       ;; newbar x1 inside bar
	       ((dashboard:px-between x1 bx1 bx2) #t)
	       ((dashboard:px-between x2 bx1 bx2) #t)
	       ((and (<= x1 bx1)(>= x2 bx2))      #t)

	       (else (if (null? tal)
			 (if (< i lastrow)
			     (loop (+ i 1)
				   (hash-table-ref/default rowhash (+ rownum i) '()))

			     #f)
			 (rowloop (car tal)(cdr tal)))))))))))

(define (dashboard:add-bar rowhash rownum x1 x2 #!key (num-rows 0))
  (let loop ((i 0))
    (hash-table-set! rowhash 
		     (+ i rownum)
		     (cons (cons x1 x2) 
			   (hash-table-ref/default rowhash (+ i rownum) '())))

Added records-vs-vectors-vs-coops.scm version [93fa590917].



























































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
;; (include "vg.scm")

;; (declare (uses vg))

(use foof-loop defstruct coops)

(defstruct obj     type fill-color angle)

(define (make-vg:obj)(make-vector 3))
(define-inline (vg:obj-get-type         vec)    (vector-ref  vec 0))
(define-inline (vg:obj-get-fill-color   vec)    (vector-ref  vec 1))
(define-inline (vg:obj-get-angle        vec)    (vector-ref  vec 2))
(define-inline (vg:obj-set-type!        vec val)(vector-set! vec 0 val))
(define-inline (vg:obj-set-fill-color!  vec val)(vector-set! vec 1 val))
(define-inline (vg:obj-set-angle!       vec val)(vector-set! vec 2 val))

(use simple-exceptions)
(define vgs:obj-exn (make-exception "wrong record type, expected vgs:obj." 'assert))
(define (make-vgs:obj)(let ((v (make-vector 4)))(vector-set! v 0 'vgs:obj) v))
(define-inline (vgs:obj-type             vec)(if (eq? (vector-ref vec 0) 'vgs:obj)(vector-ref  vec 1)(raise (vgs:obj-exn 'vgs:obj-type 'xpr))))
(define-inline (vgs:obj-fill-color       vec)(if (eq? (vector-ref vec 0) 'vgs:obj)(vector-ref  vec 2)(raise (vgs:obj-exn 'vgs:obj-fill-color 'xpr))))
(define-inline (vgs:obj-angle            vec)(if (eq? (vector-ref vec 0) 'vgs:obj)(vector-ref  vec 3)(raise (vgs:obj-exn 'vgs:obj-angle 'xpr))))
(define-inline (vgs:obj-type-set!        vec val)(if (eq? (vector-ref vec 0) 'vgs:obj)(vector-set! vec 1 val)(raise (vgs:obj-exn 'type))))
(define-inline (vgs:obj-fill-color-set!  vec val)(if (eq? (vector-ref vec 0) 'vgs:obj)(vector-set! vec 2 val)(raise (vgs:obj-exn 'fill-color))))
(define-inline (vgs:obj-angle-set!       vec val)(if (eq? (vector-ref vec 0) 'vgs:obj)(vector-set! vec 3 val)(raise (vgs:obj-exn 'angle))))

(define-class <vgc> ()
  ((type)
   (fill-color)
   (angle)))


;; first use raw vectors
(print "Using vectors")
(time
 (loop ((for r (up-from 0 (to 255))))
       (loop ((for g (up-from 0 (to 255))))
	     (loop ((for b (up-from 0 (to 255))))
		   (let ((obj (make-vg:obj)))
		     (vg:obj-set-type! obj 'abc)
		     (vg:obj-set-fill-color! obj "green")
		     (vg:obj-set-angle! obj 135)
		     (let ((a (vg:obj-get-type obj))
			   (b (vg:obj-get-fill-color obj))
			   (c (vg:obj-get-angle obj)))
		       obj))))))

;; first use raw vectors with safe mode
(print "Using vectors (safe mode)")
(time
 (loop ((for r (up-from 0 (to 255))))
       (loop ((for g (up-from 0 (to 255))))
	     (loop ((for b (up-from 0 (to 255))))
		   (let ((obj (make-vgs:obj)))
		     ;; (badobj (make-vector 20)))
		     (vgs:obj-type-set! obj 'abc)
		     (vgs:obj-fill-color-set! obj "green")
		     (vgs:obj-angle-set! obj 135)
		     (let ((a (vgs:obj-type obj))
			   (b (vgs:obj-fill-color obj))
			   (c (vgs:obj-angle obj)))
		       obj))))))

;; first use defstruct
(print "Using defstruct")
(time
 (loop ((for r (up-from 0 (to 255))))
       (loop ((for g (up-from 0 (to 255))))
	     (loop ((for b (up-from 0 (to 255))))
		   (let ((obj (make-obj)))
		     (obj-type-set! obj 'abc)
		     (obj-fill-color-set! obj "green")
		     (obj-angle-set! obj 135)
		     (let ((a (obj-type obj))
			   (b (obj-fill-color obj))
			   (c (obj-angle obj)))
		       obj))))))
		   

;; first use defstruct
(print "Using coops")
(time
 (loop ((for r (up-from 0 (to 255))))
       (loop ((for g (up-from 0 (to 255))))
	     (loop ((for b (up-from 0 (to 255))))
		   (let ((obj (make <vgc>)))
		     (set! (slot-value obj 'type) 'abc)
		     (set! (slot-value obj 'fill-color) "green")
		     (set! (slot-value obj 'angle) 135)
		     (let ((a (slot-value obj 'type))
			   (b (slot-value obj 'fill-color))
			   (c (slot-value obj 'angle)))
		       obj))))))

Modified vg-test.scm from [862cfe8e53] to [d11657d763].

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16

17
18
19
20
21
22
23
(use canvas-draw iup foof-loop)
(import canvas-draw-iup)

(load "vg.scm")

(define numtorun 1000)
;; (if (> (length (argv)) 1)
;; 		     (string->number (cadr (argv)))
;; 		     1000))

;; (use trace)
;; (trace 
;;  vg:draw-rect
;;  vg:grow-rect

;;  vg:components-get-extents
;;  vg:instances-get-extents)


(define d1 (vg:drawing-new))
(define l1 (vg:lib-new))
(define c1 (vg:comp-new))
(define c2 (vg:comp-new))
(define bt1 (vg:make-rect-obj 10 40 20 50 text: "A long piece of text" font: "Helvetica, -10"))











|
|
|
|
>
|
|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
(use canvas-draw iup foof-loop)
(import canvas-draw-iup)

(load "vg.scm")

(define numtorun 1000)
;; (if (> (length (argv)) 1)
;; 		     (string->number (cadr (argv)))
;; 		     1000))

 (use trace)
 (trace 
  ;; vg:draw-rect
  ;; vg:grow-rect
  vg:get-extents-for-objs
  vg:components-get-extents
  vg:instances-get-extents
  vg:get-extents-for-two-rects)

(define d1 (vg:drawing-new))
(define l1 (vg:lib-new))
(define c1 (vg:comp-new))
(define c2 (vg:comp-new))
(define bt1 (vg:make-rect-obj 10 40 20 50 text: "A long piece of text" font: "Helvetica, -10"))

Modified vg.scm from [a4aecf3ba5] to [675e34e5b3].

11
12
13
14
15
16
17



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
;;  strftime('%m/%d/%Y %H:%M:%S','now','localtime')

(use defstruct srfi-1)

(declare (unit vg))
(use canvas-draw iup)
(import canvas-draw-iup)



;; structs
;;
(defstruct vg:lib     comps)
(defstruct vg:comp    objs name file)
;; extents caches extents calculated on draw
;; proc is called on draw and takes the obj itself as a parameter
;; attrib is an alist of parameters
(defstruct vg:obj     type pts fill-color text line-color call-back angle font attrib extents proc)
(defstruct vg:inst    libname compname theta xoff yoff scalex scaley mirrx mirry call-back cache)
(defstruct vg:drawing libs insts scalex scaley xoff yoff cnv cache) ;; libs: hash of name->lib, insts: hash of instname->inst

;; inits
;;
(define (vg:comp-new)
  (make-vg:comp objs: '() name: #f file: #f))

(define (vg:lib-new)







>
>
>
|
|
|
|
|
|
|
|
|
|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
;;  strftime('%m/%d/%Y %H:%M:%S','now','localtime')

(use defstruct srfi-1)

(declare (unit vg))
(use canvas-draw iup)
(import canvas-draw-iup)

(include "vg_records.scm")

;; ;; structs
;; ;;
;; (defstruct vg:lib     comps)
;; (defstruct vg:comp    objs name file)
;; ;; extents caches extents calculated on draw
;; ;; proc is called on draw and takes the obj itself as a parameter
;; ;; attrib is an alist of parameters
;; (defstruct vg:obj     type pts fill-color text line-color call-back angle font attrib extents proc)
;; (defstruct vg:inst    libname compname theta xoff yoff scalex scaley mirrx mirry call-back cache)
;; (defstruct vg:drawing libs insts scalex scaley xoff yoff cnv cache) ;; libs: hash of name->lib, insts: hash of instname->inst

;; inits
;;
(define (vg:comp-new)
  (make-vg:comp objs: '() name: #f file: #f))

(define (vg:lib-new)
189
190
191
192
193
194
195














196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218




219
220
221
222
223
224
225

226
227

228

229
230
231
232
233
234
235
;; get component from drawing (look in apropriate lib) given libname and compname
(define (vg:get-component drawing libname compname)
  (let* ((lib  (hash-table-ref (vg:drawing-libs drawing) libname))
	 (inst (hash-table-ref (vg:lib-comps lib) compname)))
    inst))

(define (vg:get-extents-for-objs drawing objs)














  (let ((extents #f))
    (for-each
     (lambda (obj)
       (set! extents
	 (vg:get-extents-for-two-rects
	  extents
	  (vg:obj-get-extents drawing obj))))
     objs)
    extents))

;; given rectangles r1 and r2, return the box that bounds both
;;
(define (vg:get-extents-for-two-rects r1 r2)
  (if (not r1)
      r2
      (if (not r2)
	  r1 ;; #f ;; no extents from #f #f
	  (list (min (car r1)(car r2))           ;; llx
		(min (cadr r1)(cadr r2))         ;; lly
		(max (caddr r1)(caddr r2))       ;; ulx
		(max (cadddr r1)(cadddr r2)))))) ;; uly

(define (vg:components-get-extents drawing . comps)




  (let ((extents #f))
    (for-each
     (lambda (comp)
       (let* ((objs  (vg:comp-objs comp)))
	 (set! extents 
	   (vg:get-extents-for-two-rects
	    extents

	    (vg:get-extents-for-objs drawing objs)))))
     comps)

    extents))


;;======================================================================
;; libraries
;;======================================================================

;; register lib with drawing








>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|














>
>
>
>
|
<
<
|
|
|
|
>
|
<
>
|
>







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240


241
242
243
244
245
246

247
248
249
250
251
252
253
254
255
256
;; get component from drawing (look in apropriate lib) given libname and compname
(define (vg:get-component drawing libname compname)
  (let* ((lib  (hash-table-ref (vg:drawing-libs drawing) libname))
	 (inst (hash-table-ref (vg:lib-comps lib) compname)))
    inst))

(define (vg:get-extents-for-objs drawing objs)
  (if (or (not objs)
	  (null? objs))
      #f
      (let loop ((hed     (car objs))
		 (tal     (cdr objs))
		 (extents (vg:obj-get-extents drawing (car objs))))
	(let ((newextents
	       (vg:get-extents-for-two-rects
		extents
		(vg:obj-get-extents drawing hed))))
	  (if (null? tal)
	      extents
	      (loop (car tal)(cdr tal) newextents))))))

;;   (let ((extents #f))
;;     (for-each
;;      (lambda (obj)
;;        (set! extents
;; 	 (vg:get-extents-for-two-rects
;; 	  extents
;; 	  (vg:obj-get-extents drawing obj))))
;;      objs)
;;     extents))

;; given rectangles r1 and r2, return the box that bounds both
;;
(define (vg:get-extents-for-two-rects r1 r2)
  (if (not r1)
      r2
      (if (not r2)
	  r1 ;; #f ;; no extents from #f #f
	  (list (min (car r1)(car r2))           ;; llx
		(min (cadr r1)(cadr r2))         ;; lly
		(max (caddr r1)(caddr r2))       ;; ulx
		(max (cadddr r1)(cadddr r2)))))) ;; uly

(define (vg:components-get-extents drawing . comps)
  (if (null? comps)
      #f
      (let loop ((hed  (car comps))
		 (tal  (cdr comps))
		 (extents #f))


	(let* ((objs  (vg:comp-objs hed))
	       (newextents (if extents
			       (vg:get-extents-for-two-rects
				extents
				(vg:get-extents-for-objs drawing objs))
			       (vg:get-extents-for-objs drawing objs))))

	  (if (null? tal)
	      newextents
	      (loop (car tal)(cdr tal) newextents))))))

;;======================================================================
;; libraries
;;======================================================================

;; register lib with drawing