• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

AltME groups: search

Help · search scripts · search articles · search mailing list

results summary

worldhits
r4wp5907
r3wp58701
total:64608

results window for this page: [start: 11001 end: 11100]

world-name: r3wp

Group: !Uniserve ... Creating Uniserve processes [web-public]
Graham:
16-Mar-2005
I noticed this morning it rejected a legitimate email from my own 
hotmail account as the address given by the EHLO gave a none reverse 
DNS ... but checking it again, it was okay.  So, some type of dns 
timeout error I guess
Dockimbel:
17-Mar-2005
Yes, in a service called "Proxy-NTLM", but not yet released.
Dockimbel:
17-Mar-2005
I thought about making a standalone exe with Proxy-NTLM as replacement 
to this python product : http://www.geocities.com/rozmanov/ntlm/
Dockimbel:
17-Mar-2005
This might be useful to a lot of non-techie users. (Just a single 
exe file with a minimal form for login/pass).
[unknown: 5]:
17-Mar-2005
Ever find any more information on Kerberos to use as a module?
Graham:
18-Mar-2005
Anton, that was more likely a bug in my save-email routine, which 
I hope is now fixed.
Graham:
18-Mar-2005
clearly got to work on that ... my smtp service checks to see if 
the sender has a valid mailbox ...
Graham:
19-Mar-2005
this is my first crude webmail interface to my smtp service.

http://www.compkarori.co.nz:8001/
use userid: "test" password: "account"


If you send a message to [test-:-compkarori-:-com], it will take 15mins 
at least to get thru ( which is the default delay I have built in 
for mail from new users).  But after that it should be very quick.
Graham:
19-Mar-2005
Anyone like to collaborate on building a decent web interface ?
Graham:
19-Mar-2005
BTW, that is a test to the email account: [test-:-compkarori-:-com] ... 
and not me :)
Anton:
20-Mar-2005
Doc, could you have a look in !webmail group. Graham's cheyenne server 
is not getting through to me properly (hangs on second read-io of 
2048 bytes).
Dockimbel:
21-Mar-2005
I'll look at it. But remember that Cheyenne's RSP are early alpha 
and they are still a several issue to solve and bugs to fix before 
having making them reliable.
Dockimbel:
21-Mar-2005
The main issue with current RSP is that it includes a session variables 
synchronization system that's not yet finished. So, the freezing 
issues should be related to that. This system queues the RSP jobs 
if it detects that they use the same session variables. (It garanties 
that your session variable values would not be corrupted by the concurrent 
execution of RSP). It needs more testing and tuning to be fully reliable.
Dockimbel:
17-May-2005
Just a quick update info about Cheyenne: I'm working on a new version 
of the RSP module that should fix the previously encountered issues. 
It needs a lot of testing so it will take a few days before I'll 
publish anything.
Dockimbel:
17-May-2005
To answer a question of MikeL, UniServe is not tied in any way to 
LNS.
Graham:
17-May-2005
popd .. which is a pop server
Graham:
17-May-2005
and smtpd which is a smtp server ( receives mail only so far )
Graham:
17-May-2005
It was a contracted job that is still not finished ...
Graham:
17-May-2005
the uniserve client detects that a "packet" is sent by knowing how 
many bytes are coming ( as in http ), or in knowing at unique end 
sequence
Graham:
17-May-2005
but when you stream a file that is encrypted, the file length is 
now changed
Graham:
17-May-2005
I have also a smtp protocol that I will use to send mail.  Why not 
use the existing smtp that comes with Rebol?  My one uses Vincent's 
dig to find the email's mail server, and sends it directly.
MikeL:
17-May-2005
From the documentation, "Uniserve's purpose is to offer a simple 
but powerful solution for programming client and servers applications 
that can be combined with View interfaces easily."


The uses for the Asynch that I can come up with are: 1. Backup after 
transactions. 2. Journalizing / reporting after a committed transaction 
update 3. Database access 4. Queuing of side-effect events that are 
not needed for the response in the user interface. 


Aside from that, my understanding is that an synch event could be 
made asynch to allow a lower end server to process the workload.

Does anyone have any other uses from the 4 noted?


Does anyone have a simple sample of tying Uniserve into the View 
interfaces?


Are there any results of driving some load using uniserve versus 
synchronous or other solutions like threaded models?




I am trying to get my head around this a bit more and want to rely 
less on the Doc-likes-it-some-it-must-be-the-right-thing-to-do approach 
that I have used before.


I read the Medusa documentation that Doc refers to but it did not 
lead me to any good application examples.
MikeL:
17-May-2005
Thanks Graham.  Your response came in while I was composing this.... 
OK I have a simple View interface displaying a uniserve response 
so I follow that.  With a view user interface I can see you could 
get the data needed for multiple tab pages asynchronously and have 
some saving there.   For a script serving out html pages, it could 
be broken up so that asynch go after independent parts but they would 
have to be all emitted to the browser at once.   Is anyone doing 
that with Uniserv or other?
Graham:
17-May-2005
don't understand the scenario .. are u talking about writing a server 
or client application?
MikeL:
17-May-2005
In that ramble, I had both - I have a View client app that I want 
to know how to access Uniservices to make the programming easy and 
I also want to know how to Uniserve if I want to run  a CGI that 
connects to a database, does some credit application calculations, 
and emits html to the client.   For this CGI script, I would get 
both performance improvements and an easier programming model ... 
if I am reading the doc correctly.
Graham:
17-May-2005
I have a single odbc connection that is re-used by all the clients 
so that I do not have the overhead of opening/closing a database 
connection  for each transaction.
MikeL:
18-May-2005
Thanks Graham. One like a background refresh of more recently posted 
messages would be a great example.   I looked at Didier's code for 
lecture-forum.   If it uses Uniserve in the version that I located, 
it is very subtle.  I'll ask him if he can illuminate it for me.
Terry:
7-Oct-2005
I have another question though.. with the httpd service, where is 
the actual data?  I get the headers, and i get the length of the 
data, but not the actual binary.. im submitting a form using POST... 
GET is fine.
Terry:
7-Oct-2005
when i submit a basic form.. the only binary i receive is "POST / 
HTTP/1.1".. none of the other values?
Terry:
7-Oct-2005
I think the problems was trying to toy with the URL, rather than 
processing with a .cgi script.
Terry:
7-Oct-2005
the httpd is trying to serve up a page, and i wouldn't let it.??
Volker:
25-Oct-2005
Encap: You have encapping with external scripts in detective? should 
be a selfmade do then, to check authoirity. But would extract some 
files when running.
Volker:
25-Oct-2005
multiple ports - i guess. it can run multiple protocols, as plugins. 
so run the same plugin a few times on different ports.
Philippe:
28-Oct-2005
Hello, you could find a simple bench study I've made for my job about 
Uniserve vs Apache, on the Rebol Documentation Project (see http://www.rebdocproj.org/article.php3?id_article=181). 
It's in french, but with some charts.  Uniserve is very close to 
Apache 1.3 (and 2.0, not published).
MichaelB:
25-Jan-2006
Why does the following not work ? Anamonitor shows that the engage 
got into place, but the rate doesn't work. I seam to forget something,
 
with rebgui:

do %rebgui.r
display "test" [
    text "hello"
    do [
        face/rate: 5
        face/feel: context [
            engage: func [f a e][
                print 'bla
            ]
            redraw: detect: over: none
        ]
    ]
]
do-events


with vid:

x: layout [button "hallo"]

x/rate: 5
x/feel: context [
    engage: func [f a e][
        print 'bla
    ]
    redraw: detect: over: none
]

view x
do-events

???any help :-)
Dockimbel:
25-Jan-2006
Encryption methods are application-depend, it's hard to built-in 
Uniserve's kernel a general purpose encryption for communication 
that'll fit well any case...The kernel have to remain general purpose. 
But it may provides some helping features to allow easier encryption 
integration. Do you have some design ideas how the kernel should 
help integrating encryption ?
Graham:
25-Jan-2006
I think the problem I had is that uniserve either uses a terminating 
sequence, or a preset number of bytes.  If the size of each "packet" 
changes with encryption, how does one cope with that?
Terry:
4-Feb-2006
Still have this context issue though.. goes like this.. 


If I have a service, and in that service i have a "on-received' event.. 
and I put a function within that event (aka, in the on-received function 
itself.. then it works fine.. but if I try to add the same function 
to an external file, so that, when I trigger the on-received function, 
it does a DO to the external file, that function now DOESN'T work? 
 Some kind of context issue, and how do you work around it?  If i 
have a 1000 pieces of code that needs to be processed with each event, 
do i need to bury the whole thing in the service?
Dockimbel:
4-Feb-2006
I don't understand clearly what is the problem. Do you have a small 
code example ?
Terry:
4-Feb-2006
Again, this is a service.. 

on-received: func [data][
raw-input: copy to-string data 
if raw-input = "test" [print "works"]
]


But if I put the if raw-input = "test" [print "works"] line in a 
seperate file.. ie  process.r ,and do it like this.. 

on-received: func [data][
raw-input: copy to-string data 
do %./process.r
]


It doesn't work.. In fact, it seems difficult to put global functions 
that are truly global, anywhere.
Terry:
4-Feb-2006
But if that's what it takes to have a single server handling everything 
from POP to HTTP to direct TCP, then so be it.
Terry:
4-Feb-2006
Ok.. i can add external libraries.. just after the install-service 
[ ..   BUT..

to write back to the client, you use "write-client" so if in my processing, 
but that function wont work.. it's a catch 22.
Terry:
4-Feb-2006
Ok.. so now I can run the external script by placing waiting till 
i finsh the external, and get back to the 'on-received' function... 
but I have a number of functions that I use to process my external 
script.. 
Do I need to load those functions with every on-received event???
Terry:
4-Feb-2006
I see here a new law...  the query is exponentially  greater than 
the answer.
Terry:
4-Feb-2006
Also, it seems that this stuff is handled by a seperate module (for 
background processing)?
Terry:
4-Feb-2006
Another question.. where could I put a piece of code to handle unknown 
(aka unserviced) ports?  Should be able to create a catch-all or 
a port-analyzer etc... check for scanning or other security issues.
Terry:
4-Feb-2006
graham, what do I need to do with your smtp service to allow a localhost 
domain.. getting this.. "waiting 20s as {MYLAPTOPNAME} fails domain 
rule"
Volker:
5-Feb-2006
Mime-tpyes? (just a thought)
Terry:
5-Feb-2006
I did add a.. 
text/javascript	js
Terry:
5-Feb-2006
Here's an example.. prototype ( a javascript framework uses prototype.js 
 and that file uses includes to add other JS files.. like this.. 

<%= include 'ajax.js', 'dom.js', 'form.js', 'event.js', 'position.js' 
%>

the problem seems to be here somewhere?
Philippe:
10-May-2006
Doc, when will you release a beta of Cheyenne and a new version of 
Uniserve ?
Dockimbel:
13-May-2006
:-). I could release a new Uniserve version, but there's no much 
new protocols added yet. Uniserve also deserves some better docs. 
Cheyenne is still under development, my priority is to finish it 
asap. I'll release a beta as soon as I have a stable and almost feature-complete 
version. Cheyenne is meant to be a end-user product, so it needs 
some polishing and enhancement before giving it to users.
Dockimbel:
13-May-2006
I want it to be as good as possible starting from the first release 
because, it may become a major tool for the REBOL community.
Pekr:
13-May-2006
:-) isn't it just a - webserver? :-)
Dockimbel:
13-May-2006
Basically yes, but with the RSP module, it becomes a fast and flexible 
web application framework !
Philippe:
13-May-2006
Salut Doc, I have sent some informations about Uniserve on http://www.rebolfrance.info/projets/uniserve?s=Uniserve.
  I.e. the ability for Uniserve to use the lib Magic (O. Auverlot), 
with a lot of shorcuts to quickly create forms, check boxs, etc.
Philippe:
13-May-2006
Have you planned a target date for a beta of Cheyenne ?
Dockimbel:
13-May-2006
Not yet, I can only work on Cheyenne and other REBOL projects on 
my spare time, I'm currently almost full time on a big project for 
a customer (until end of july). I expect to make a first beta release 
of Cheyenne before that.
Will:
31-Aug-2006
Mike, I started using Apache and rebol as cgi, this is not suited 
for performances as on every call to the cgi, a new instance of rebol 
is  initialized, run and closed.

I thought about using fastcgi, but never came to a working solution.
Now I use uniserve as main webserver, here some advantages:

-it is fast! On my local machine I get +- 600 req/sec for static 
pages and a max of 160req/sec for dynamic rsp pages

-it is written in rebol, I could easly(less than 10 lines code) add 
a rewrite engine

-child process are persistent, this mean you can keep state of your 
web applications, implement caching, keep a pool of connection to 
databases open (in apache + rebol/cgi you'd have to open and close 
the connection for every request)
-it is written by Dock whom I may be the biggest fan ;-)

btw I'm running an unreleased version (have bought commercial support) 
 that support http 1.1, stuff like If-Modified etc..

If you have more specific questions, I'll be glad to try and answer.
MikeL:
31-Aug-2006
Thanks Will.   I would like to see how to put together a simple web 
form application that posts to a Uniserve script and provides an 
acceptance message.  When I looked at Uniserve I couldn't see how 
this simple thing could be done and how / which services to use. 
  Do you have a "Hello World" level example that follows that post/reply 
approach?
Graham:
1-Sep-2006
Ask Doc for a copy of Cheyenne ...
MikeL:
1-Sep-2006
Thanks Will - I have uniserve running and can serve up static webpages 
and the sample cgi that Doc provided. How do I allow RSP or ML to 
be loaded so that a page that uses them does not have to run as CGI 
and flag .rsp or .rhtml files as handled by RSP.
Will:
1-Sep-2006
well in the release you dl the rsp support is "basic", I used a customized 
one but now I'm using Dock latest rsp, sorry but you should definitely 
ask Dock for latest version or wait till he release.
Volker:
1-Sep-2006
Is there a good way to contact Doc?
Oldes:
1-Sep-2006
Hm, it was the hard part of the learning uniserve, but now I know, 
how to do-task. But the question now is - what if I need to do task 
once a day, I don't want the launched helper process to be still 
running in the background. Is there someone who can help?
Oldes:
1-Sep-2006
Found a way - to modify on-received function in the task-master to 
send the task port with data to the service using on-task-done and 
than closing the task if needed from the service:-) If there is some 
other way how it should be done, let me know.
Dockimbel:
4-Sep-2006
I have a much more recent version of UniServe almost ready to release, 
but docs are not updated and some of the protocols are still alpha. 
But with the current interest in UniServe, I'm thinking about releasing 
a beta version here this week.
Oldes:
4-Sep-2006
I'm using UniServ as a core for my MicroChat - http://box.lebeda.ws/~hmm/chat.html
:-)
Dockimbel:
4-Sep-2006
Busy, I am ;-). But there's a new version sitting on my hard drive 
which could be useful to some people here.
Group: SVG Renderer ... SVG rendering in Draw AGG [web-public]
shadwolf:
23-Jun-2005
REBOL [
	Title:		"SVG Demo"
	Owner:		"Ashley G. Trüter"
	Version:	0.0.1
	Date:		21-Jun-2005
	Purpose:	"Loads and displays a resizeable SVG file."
	History: {
		0.0.1	Initial release
	}
	Notes: {
		Tested on very simple SVG icons
		Only a few basic styles / attributes / commands supported

  Does not handle sizes in units other than pixels (e.g. pt, in, cm, 
  mm, etc)

  SVG path has an optional close command, "z" ... AGG shape equivalent 
  auto-closes

  load-svg function needs to be totally refactored / optimized ... 
  *sample only*
	}
]

;	The following commands are available for path data:
;
;		M = moveto
;		L = lineto
;		H = horizontal lineto
;		V = vertical lineto
;		C = curveto
;		S = smooth curveto
;		Q = quadratic Belzier curve
;		T = smooth quadratic Belzier curveto
;		A = elliptical Arc
;		Z = closepath

;print: none	; comment out this line to enable debug messages

load-svg: function [svg-file [file! string!] size [pair!]] [

 id defs x y to-color to-byte draw-blk append-style svg-size scale-x 
 scale-y
][
	xml: either string? svg-file [parse-xml svg-file] [

  unless %.svg = suffix? svg-file [to error! "File has an invalid suffix!"]
		parse-xml read svg-file
	]

 unless xml/3/1/1 = "svg" [to error! "Could not find SVG header!"]

 ;unless find ["id" "xmlns"] xml/3/1/2/1 [to error! "Could not find 
 ID header!"]

 ;unless xml/3/1/3/1/1 = "defs" [to error! "Could not find DEFS header!"]

	id: xml/3/1/2
	defs: xml/3/1/3


	;
	;	--- Parse SVG id
	;

	svg-size: either find ["32pt" "48pt" "72pt"] select id "width" [
		switch select id "width" [
			"72pt"	[120x120]
			"48pt"	[80x80]
			"32pt"	[60x60]
		]
	][

  as-pair to integer! any [select id "width" "100"] to integer! any 
  [select id "height" "100"]
	]

	x: to integer! any [select id "x" "0"]
	y: to integer! any [select id "y" "0"]

	scale-x: size/x / svg-size/x
	scale-y: size/y / svg-size/y

	;
	;	--- Helper functions
	;


 to-color: func [s [string!]] [	; converts a string in the form "#FFFFFF" 
 to a 4-byte tuple
		to tuple! load rejoin ["#{" next s "00}"]
	]


 to-byte: func [s [string!]] [	; converts a string with a value 0-1 
 to an inverted byte
		255 - to integer! 255 * to decimal! s
	]

	;
	;	--- Parse SVG defs
	;

	draw-blk: copy []

	append-style: function [
		command [string!] blk [block!]
	][
		x xy pen-color fill-color line-width mode size radius shape
		closed? matrix transf-command
	][
		xy: 0x0
		size: 0x0
		line-width: 1
		matrice: make block! []
		radius: none
		transf-command: none
		
		
		foreach [attr val] blk [
			switch attr [
				"transform" [print "tranform have been found" 
						;probe val halt 
						val: parse val "(),"
						transf-command: first val
						probe transf-command
						switch transf-command [
							"matrix" [ 
								foreach word val [
									if not find word "matrix"
									[ 
										insert tail matrice to-decimal word
									]
								]
							
							]
						]
				]
				"style" [
					foreach [attr val] parse val ":;" [
						switch/default attr [
						
							"font-size" [ ]
							"stroke" [
								switch/default first val [
									#"#" [pen-color: to-color val]
									#"n" [pen-color: none]
								][
									print ["Unknown stroke:" val]
								]
							]
							"stroke-width" [line-width: to decimal! val]
							"fill" [
								fill-color: switch/default first val [
									#"#" [to-color val]
									#"n" [none]
								][
									print ["Unknown fill value:" val]
									none
								]
							]
							"fill-rule" [
								mode: switch/default val [
									"evenodd"	['even-odd]
								][
									print ["Unknown fill-rule value:" val]
									none
								]
							]

       "stroke-opacity" [pen-color: any [pen-color 0.0.0.0] pen-color/4: 
       to-byte val]

       "fill-opacity" [fill-color: any [fill-color 0.0.0.0] fill-color/4: 
       to-byte val]
							"stroke-linejoin" [
								insert tail draw-blk switch/default val [
									"miter"		[compose [line-join miter]]
									"round"		[compose [line-join round]]
									"bevel"		[compose [line-join bevel]]
								][
									print ["Unknown stroke-linejoin value:" val]
									none
								]
							]
							"stroke-linecap" [
								insert tail draw-blk 'line-cap
								insert tail draw-blk to word! val
							]
						][
							print ["Unknown style:" attr]
						]
					]
				]
				"x"			[xy/x: scale-x * val]
				"y"			[xy/y: scale-y * val]
				"width"		[size/x: scale-x * val]
				"height"	[size/y: scale-y * val]
				"rx"		[print "rx"]
				"ry"		[radius: to decimal! val]
				"d"	[
					shape: copy []
					x: none
					closed?: false
					foreach token load val [
						switch/default token [
							M	[insert tail shape 'move]
							C	[insert tail shape 'curve]
							L	[insert tail shape 'line]
							z	[closed?: true]
						][

       unless number? token [print ["Unknown path command:" token]]

       either x [insert tail shape as-pair x scale-y * token x: none] [x: 
       scale-x * token]
						]
					]
				]
			]
		]
		insert tail draw-blk compose [
			pen (pen-color)
			fill-pen (fill-color)
			fill-rule (mode)
			line-width (line-width * min scale-x scale-y)
		]
		switch command [
			"rect" [
				insert tail draw-blk compose [box (xy) (xy + size)]
				if radius [insert tail draw-blk radius]
			]
			"path" [
				unless closed? [print "Path closed"]
				either transf-command <> none  [
					switch transf-command [

      "matrix" [insert tail draw-blk compose/only [ (to-word transf-command) 
      (matrice) shape (shape) reset-matrix]]
					]
				][
					insert tail draw-blk compose/only [shape (shape)]
			 	]
				]

   "g" [ print "Write here how to handle G insertion to Draw block" 

    insert tail draw-blk probe compose/only [reset-matrix (to-word transf-command) 
    (matrice)]
				
				]
			]
	]	
  
	probe defs
	foreach blk defs [
		switch first blk [
			"rect"	[append-style first blk second blk]
			"path"	[append-style first blk second blk]
			"g"		[
						print "key word" probe first blk  
						print "matrix and style in G" probe second blk  
						append-style first blk second blk 
						;print "what to draw in G" probe third blk
						foreach blk2 third blk [
							probe blk2
							switch first blk2[ 
								"path" [append-style first blk2 second blk2]
							]
						]
					]
		]
	]
	
	
probe draw-blk
	draw-blk
]

view make face [
	offset:	100x100
	size:	200x200
	action:	request-file/filter/only "*.svg"
	text:	rejoin ["SVG Demo [" last split-path action "]"]
	data:	read action
	color:	white
	effect:	compose/only [draw (load-svg data size)]
	edge: font: para: none
	feel: make feel [
		detect: func [face event] [
			if event/type = 'resize [
				insert clear face/effect/draw load-svg face/data face/size
				show face
			]
			if event/type = 'close [quit]
		]
	]
	options: [resize]
]
shadwolf:
23-Jun-2005
Vincent add some path rendering commands S Q T H A V
shadwolf:
23-Jun-2005
REBOL [
	Title:		"SVG Demo"
	Owner:		"Ashley G. Trüter"
	Version:	0.0.1
	Date:		21-Jun-2005
	Purpose:	"Loads and displays a resizeable SVG file."
	History: {
		0.0.1	Initial release
	}
	Notes: {
		Tested on very simple SVG icons
		Only a few basic styles / attributes / commands supported

  Does not handle sizes in units other than pixels (e.g. pt, in, cm, 
  mm, etc)

  SVG path has an optional close command, "z" ... AGG shape equivalent 
  auto-closes

  load-svg function needs to be totally refactored / optimized ... 
  *sample only*
	}
]

;	The following commands are available for path data:
;
;		M = moveto
;		L = lineto
;		H = horizontal lineto
;		V = vertical lineto
;		C = curveto
;		S = smooth curveto
;		Q = quadratic Belzier curve
;		T = smooth quadratic Belzier curveto
;		A = elliptical Arc
;		Z = closepath

;print: none	; comment out this line to enable debug messages

load-svg: function [svg-file [file! string!] size [pair!]] [

 id defs x y to-color to-byte draw-blk append-style svg-size scale-x 
 scale-y
][
	xml: either string? svg-file [parse-xml svg-file] [

  unless %.svg = suffix? svg-file [to error! "File has an invalid suffix!"]
		parse-xml read svg-file
	]

 unless xml/3/1/1 = "svg" [to error! "Could not find SVG header!"]

 ;unless find ["id" "xmlns"] xml/3/1/2/1 [to error! "Could not find 
 ID header!"]

 ;unless xml/3/1/3/1/1 = "defs" [to error! "Could not find DEFS header!"]

	id: xml/3/1/2
	defs: xml/3/1/3


	;
	;	--- Parse SVG id
	;

	svg-size: either find ["32pt" "48pt" "72pt"] select id "width" [
		switch select id "width" [
			"72pt"	[120x120]
			"48pt"	[80x80]
			"32pt"	[60x60]
		]
	][

  as-pair to integer! any [select id "width" "100"] to integer! any 
  [select id "height" "100"]
	]

	x: to integer! any [select id "x" "0"]
	y: to integer! any [select id "y" "0"]

	scale-x: size/x / svg-size/x
	scale-y: size/y / svg-size/y

	;
	;	--- Helper functions
	;


 to-color: func [s [string!]] [	; converts a string in the form "#FFFFFF" 
 to a 4-byte tuple
		to tuple! load rejoin ["#{" next s "00}"]
	]


 to-byte: func [s [string!]] [	; converts a string with a value 0-1 
 to an inverted byte
		255 - to integer! 255 * to decimal! s
	]

	;
	;	--- Parse SVG defs
	;

	draw-blk: copy []

	append-style: function [
		command [string!] blk [block!]
	][
		x xy pen-color fill-color line-width mode size radius shape
		closed? matrix transf-command
	][
		xy: 0x0
		size: 0x0
		line-width: 1
		matrice: make block! []
		radius: none
		transf-command: none
		
		
		foreach [attr val] blk [
			switch attr [
				"transform" [print "tranform have been found" 
						;probe val halt 
						val: parse val "(),"
						transf-command: first val
						probe transf-command
						switch transf-command [
							"matrix" [ 
								foreach word val [
									if not find word "matrix"
									[ 
										insert tail matrice to-decimal word
									]
								]
							
							]
						]
				]
				"style" [
					foreach [attr val] parse val ":;" [
						switch/default attr [
						
							"font-size" [ ]
							"stroke" [
								switch/default first val [
									#"#" [pen-color: to-color val]
									#"n" [pen-color: none]
								][
									print ["Unknown stroke:" val]
								]
							]
							"stroke-width" [line-width: to decimal! val]
							"fill" [
								fill-color: switch/default first val [
									#"#" [to-color val]
									#"n" [none]
								][
									print ["Unknown fill value:" val]
									none
								]
							]
							"fill-rule" [
								mode: switch/default val [
									"evenodd"	['even-odd]
								][
									print ["Unknown fill-rule value:" val]
									none
								]
							]

       "stroke-opacity" [pen-color: any [pen-color 0.0.0.0] pen-color/4: 
       to-byte val]

       "fill-opacity" [fill-color: any [fill-color 0.0.0.0] fill-color/4: 
       to-byte val]
							"stroke-linejoin" [
								insert tail draw-blk switch/default val [
									"miter"		[compose [line-join miter]]
									"round"		[compose [line-join round]]
									"bevel"		[compose [line-join bevel]]
								][
									print ["Unknown stroke-linejoin value:" val]
									none
								]
							]
							"stroke-linecap" [
								insert tail draw-blk 'line-cap
								insert tail draw-blk to word! val
							]
						][
							print ["Unknown style:" attr]
						]
					]
				]
				"x"			[xy/x: scale-x * val]
				"y"			[xy/y: scale-y * val]
				"width"		[size/x: scale-x * val]
				"height"	[size/y: scale-y * val]
				"rx"		[print "rx"]
				"ry"		[radius: to decimal! val]
				"d"	[
					shape: copy []
					x: none
					closed?: false
					foreach token load val [
						switch/default token [
							M	[insert tail shape 'move]
							C	[insert tail shape 'curve]
							S   [insert tail shape 'curv]
							L	[insert tail shape 'line]
							Q   [insert tail shape 'qcurve]
							T   [insert tail shape 'qcurv]
							z	[closed?: true]
							H   [insert tail shape 'hline]
							V   [insert tail shape 'vline]
							A   [insert tail shape 'arc]
						][

       unless number? token [print ["Unknown path command:" token]]

       either x [insert tail shape as-pair x scale-y * token x: none] [x: 
       scale-x * token]
						]
					]
				]
			]
		]
		insert tail draw-blk compose [
			pen (pen-color)
			fill-pen (fill-color)
			fill-rule (mode)
			line-width (line-width * min scale-x scale-y)
		]
		switch command [
			"rect" [
				insert tail draw-blk compose [box (xy) (xy + size)]
				if radius [insert tail draw-blk radius]
			]
			"path" [
				unless closed? [print "Path closed"]
				either transf-command <> none  [
					switch transf-command [

      "matrix" [insert tail draw-blk compose/only [ (to-word transf-command) 
      (matrice) shape (shape) reset-matrix]]
					]
				][
					insert tail draw-blk compose/only [shape (shape)]
			 	]
				]

   "g" [ print "Write here how to handle G insertion to Draw block" 

    insert tail draw-blk probe compose/only [reset-matrix (to-word transf-command) 
    (matrice)]
				
				]
			]
	]	
  
	probe defs
	foreach blk defs [
		switch first blk [
			"rect"	[append-style first blk second blk]
			"path"	[append-style first blk second blk]
			"g"		[
						print "key word" probe first blk  
						print "matrix and style in G" probe second blk  
						append-style first blk second blk 
						;print "what to draw in G" probe third blk
						foreach blk2 third blk [
							probe blk2
							switch first blk2[ 
								"path" [append-style first blk2 second blk2]
							]
						]
					]
		]
	]
	
	
probe draw-blk
	draw-blk
]

view make face [
	offset:	100x100
	size:	200x200
	action:	request-file/filter/only "*.svg"
	text:	rejoin ["SVG Demo [" last split-path action "]"]
	data:	read action
	color:	white
	effect:	compose/only [draw (load-svg data size)]
	edge: font: para: none
	feel: make feel [
		detect: func [face event] [
			if event/type = 'resize [
				insert clear face/effect/draw load-svg face/data face/size
				show face
			]
			if event/type = 'close [quit]
		]
	]
	options: [resize]
]
Vincent:
23-Jun-2005
Oops too fast: 

commands Q S T -> OK

commands H &t V -> need to add (just before "foreach token load val 
[") :
if all [x not number? token] [
    insert tail shape x * either token = 'V [scale-y][scale-x]
    x: none
]
command A -> not yet solved sign issues
shadwolf:
23-Jun-2005
REBOL [
	Title:		"SVG Demo"
	Owner:		"Ashley G. Trüter"
	Version:	0.0.1
	Date:		21-Jun-2005
	Purpose:	"Loads and displays a resizeable SVG file."
	History: {
		0.0.1	Initial release
	}
	Notes: {
		Tested on very simple SVG icons
		Only a few basic styles / attributes / commands supported

  Does not handle sizes in units other than pixels (e.g. pt, in, cm, 
  mm, etc)

  SVG path has an optional close command, "z" ... AGG shape equivalent 
  auto-closes

  load-svg function needs to be totally refactored / optimized ... 
  *sample only*
	}
]

;	The following commands are available for path data:
;
;		M = moveto
;		L = lineto
;		H = horizontal lineto
;		V = vertical lineto
;		C = curveto
;		S = smooth curveto
;		Q = quadratic Belzier curve
;		T = smooth quadratic Belzier curveto
;		A = elliptical Arc
;		Z = closepath

;print: none	; comment out this line to enable debug messages

load-svg: function [svg-file [file! string!] size [pair!]] [

 id defs x y to-color to-byte draw-blk append-style svg-size scale-x 
 scale-y
][
	xml: either string? svg-file [parse-xml svg-file] [

  unless %.svg = suffix? svg-file [to error! "File has an invalid suffix!"]
		parse-xml read svg-file
	]

 unless xml/3/1/1 = "svg" [to error! "Could not find SVG header!"]

 ;unless find ["id" "xmlns"] xml/3/1/2/1 [to error! "Could not find 
 ID header!"]

 ;unless xml/3/1/3/1/1 = "defs" [to error! "Could not find DEFS header!"]

	id: xml/3/1/2
	defs: xml/3/1/3


	;
	;	--- Parse SVG id
	;

	svg-size: either find ["32pt" "48pt" "72pt"] select id "width" [
		switch select id "width" [
			"72pt"	[120x120]
			"48pt"	[80x80]
			"32pt"	[60x60]
		]
	][

  as-pair to integer! any [select id "width" "100"] to integer! any 
  [select id "height" "100"]
	]

	x: to integer! any [select id "x" "0"]
	y: to integer! any [select id "y" "0"]

	scale-x: size/x / svg-size/x
	scale-y: size/y / svg-size/y

	;
	;	--- Helper functions
	;


 to-color: func [s [string!]] [	; converts a string in the form "#FFFFFF" 
 to a 4-byte tuple
		to tuple! load rejoin ["#{" next s "00}"]
	]


 to-byte: func [s [string!]] [	; converts a string with a value 0-1 
 to an inverted byte
		255 - to integer! 255 * to decimal! s
	]

	;
	;	--- Parse SVG defs
	;

	draw-blk: copy []

	append-style: function [
		command [string!] blk [block!]
	][
		x xy pen-color fill-color line-width mode size radius shape
		closed? matrix transf-command
	][
		xy: 0x0
		size: 0x0
		line-width: 1
		matrice: make block! []
		radius: none
		transf-command: none
		
		
		foreach [attr val] blk [
			switch attr [
				"transform" [print "tranform have been found" 
						;probe val halt 
						val: parse val "(),"
						transf-command: first val
						probe transf-command
						switch transf-command [
							"matrix" [ 
								foreach word val [
									if not find word "matrix"
									[ 
										insert tail matrice to-decimal word
									]
								]
							
							]
						]
				]
				"style" [
					foreach [attr val] parse val ":;" [
						switch/default attr [
						
							"font-size" [ ]
							"stroke" [
								switch/default first val [
									#"#" [pen-color: to-color val]
									#"n" [pen-color: none]
								][
									print ["Unknown stroke:" val]
								]
							]
							"stroke-width" [line-width: to decimal! val]
							"fill" [
								fill-color: switch/default first val [
									#"#" [to-color val]
									#"n" [none]
								][
									print ["Unknown fill value:" val]
									none
								]
							]
							"fill-rule" [
								mode: switch/default val [
									"evenodd"	['even-odd]
								][
									print ["Unknown fill-rule value:" val]
									none
								]
							]

       "stroke-opacity" [pen-color: any [pen-color 0.0.0.0] pen-color/4: 
       to-byte val]

       "fill-opacity" [fill-color: any [fill-color 0.0.0.0] fill-color/4: 
       to-byte val]
							"stroke-linejoin" [
								insert tail draw-blk switch/default val [
									"miter"		[compose [line-join miter]]
									"round"		[compose [line-join round]]
									"bevel"		[compose [line-join bevel]]
								][
									print ["Unknown stroke-linejoin value:" val]
									none
								]
							]
							"stroke-linecap" [
								insert tail draw-blk 'line-cap
								insert tail draw-blk to word! val
							]
						][
							print ["Unknown style:" attr]
						]
					]
				]
				"x"			[xy/x: scale-x * val]
				"y"			[xy/y: scale-y * val]
				"width"		[size/x: scale-x * val]
				"height"	[size/y: scale-y * val]
				"rx"		[print "rx"]
				"ry"		[radius: to decimal! val]
				"d"	[
					shape: copy []
					x: none
					closed?: false
					if all [x not number? token] [

          insert tail shape x * either token = 'V [scale-y][scale-x]
  						    x: none
					]
					foreach token load val [
						switch/default token [
							M	[insert tail shape 'move]
							C	[insert tail shape 'curve]
							S   [insert tail shape 'curv]
							L	[insert tail shape 'line]
							Q   [insert tail shape 'qcurve]
							T   [insert tail shape 'qcurv]
							z	[closed?: true]
							H   [insert tail shape 'hline]
							V   [insert tail shape 'vline]
							A   [insert tail shape 'arc]
						][

       unless number? token [print ["Unknown path command:" token]]

       either x [insert tail shape as-pair x scale-y * token x: none] [x: 
       scale-x * token]
						]
					]
				]
			]
		]
		insert tail draw-blk compose [
			pen (pen-color)
			fill-pen (fill-color)
			fill-rule (mode)
			line-width (line-width * min scale-x scale-y)
		]
		switch command [
			"rect" [
				insert tail draw-blk compose [box (xy) (xy + size)]
				if radius [insert tail draw-blk radius]
			]
			"path" [
				unless closed? [print "Path closed"]
				either transf-command <> none  [
					switch transf-command [

      "matrix" [insert tail draw-blk compose/only [ (to-word transf-command) 
      (matrice) shape (shape) reset-matrix]]
					]
				][
					insert tail draw-blk compose/only [shape (shape)]
			 	]
				]

   "g" [ print "Write here how to handle G insertion to Draw block" 

    insert tail draw-blk probe compose/only [reset-matrix (to-word transf-command) 
    (matrice)]
				
				]
			]
	]	
  
	probe defs
	foreach blk defs [
		switch first blk [
			"rect"	[append-style first blk second blk]
			"path"	[append-style first blk second blk]
			"g"		[
						print "key word" probe first blk  
						print "matrix and style in G" probe second blk  
						append-style first blk second blk 
						;print "what to draw in G" probe third blk
						foreach blk2 third blk [
							probe blk2
							switch first blk2[ 
								"path" [append-style first blk2 second blk2]
							]
						]
					]
		]
	]
	
	
probe draw-blk
	draw-blk
]

view make face [
	offset:	100x100
	size:	200x200
	action:	request-file/filter/only "*.svg"
	text:	rejoin ["SVG Demo [" last split-path action "]"]
	data:	read action
	color:	white
	effect:	compose/only [draw (load-svg data size)]
	edge: font: para: none
	feel: make feel [
		detect: func [face event] [
			if event/type = 'resize [
				insert clear face/effect/draw load-svg face/data face/size
				show face
			]
			if event/type = 'close [quit]
		]
	]
	options: [resize]
]
shadwolf:
23-Jun-2005
so my version of the script supports in the SVG <g> block with in 
this block header   transform matrix and in block <G> path with or 
without in it tranform matrix. I have a little problem with this 
point. Then I add the support for path d field coded in the format 
of INKSCAPE SVG PLAIN TEXT (the SVG light weight version available 
under inkscape )
Ashley:
23-Jun-2005
Thanks for taking this up and running with it guys, you're making 
great progress (far better than I could have). Feel free to take 
ownership of the code and refactor it as needed.

Two minor improvements are:

	unless closed? [insert tail shape reduce ['move 0x0]]

which is Gabriele's fix to the shape close problem, and:

	feel: make feel [
		redraw: func [face act pos] [

   if act = 'draw [insert clear face/effect/draw load-svg face/data 
   face/size]
		]
	]


which cleans the sample feel code up a bit. I'd also remove "VID" 
from the title of this group as DRAW AGG is tied to View. ;)
shadwolf:
23-Jun-2005
matrix intervention of cyphre could be very educationnal and help 
me a lot to see what I'm messing in my code
Vincent:
23-Jun-2005
Thanks Ashley: there's still a lot of work to do - as SVG is quite 
flexible
shadwolf:
23-Jun-2005
yes it' quite a nightmare for a AGG newbie as I'm ...
shadwolf:
24-Jun-2005
drawing  primitives have a xlink:href field that point to the appropiate 
main lineargradient (countainer)
shadwolf:
24-Jun-2005
how to apply a matrix tranformation only over a grendient definition 
?
shadwolf:
24-Jun-2005
if you wants to write the "in" AGG/draw code that is based on my 
rebol linear gradient list there is the code and a sample file from 
InkScape
Ashley:
25-Jun-2005
Noticed you found some conversion numbers (where from?? ;) ), so 
here's a simple func to make use of them:

to-unit: func [s [string!]] [
	switch/default skip tail s -2 [
		"pt"	[1.25 * to decimal! copy/part s -2 + length? s]
		"pc"	[15 * to decimal! copy/part s -2 + length? s]
		"mm"	[3.543307 * to decimal! copy/part s -2 + length? s]
		"cm"	[35.43307 * to decimal! copy/part s -2 + length? s]
		"in"	[90 * to decimal! copy/part s -2 + length? s]
		"px"	[to decimal! copy/part s -2 + length? s]
	][
		to decimal! s
	]
]
shadwolf:
26-Jun-2005
I copy past the conversion units into the script becaus I know that 
could be usefull but AS I was working on lineargradient and as it's 
a complicated part of the format SVG I had no time to make a conversion 
algorithm I glad to see that you make it  :)
shadwolf:
29-Jun-2005
okay good stuf in it Vincent and I are planning to use the xml-to-object.r 
script from Brian Wisti to enbetter and make a more sophisticate 
support for our actual work upon SVG parsing translation and rendering 
into a VID  window
BrianW:
29-Jun-2005
shadwolf, I'm not the author - just a guy who made it available in 
the Rebol library :-)
shadwolf:
29-Jun-2005
opkay so we are planning on the opportinity to use a REBOL tree object! 
structure to represente SVG datas :)
shadwolf:
30-Jun-2005
I make a base code but now I have to find a good code to exploit 
the relevent datas from the object tree
shadwolf:
30-Jun-2005
this means to interogate the content of the objet a gived level
shadwolf:
30-Jun-2005
then construc path to get data then translate this data to a draw 
equivalent exploitable datas
shadwolf:
30-Jun-2005
my point is to make a recursif capapble code
shadwolf:
30-Jun-2005
I I want to interrogate the first shape description on the top level 
( out of group blocks) I have to build a path like that xml/svg/path/1/d
shadwolf:
30-Jun-2005
or maybe build the path xml/svg/path then attribute to a temporary 
var the foreach ob  xml/svg/path [ ob processing ]
shadwolf:
2-Jul-2005
hum xpdf.svg file shows me a problem with the use of xml-to-object 
 ... if you have serveral g block at the same level all g block are 
compacted into the same reference
shadwolf:
2-Jul-2005
so in Rebol tree object the g block can be a bloc of sub object or 
an object  ;)
Ashley:
2-Jul-2005
I've spent quite a bit of time looking at Inkscape (http://www.inkscape.org/) 
and it seems to be the only / best SVG game in town (their command-line 
driven SVG to PNG conversion seems to be particularly well regarded). 
Looking forward to their 0.42 release as it supports OS/X as well.


The Clip Art site that they link to (http://www.openclipart.org/) 
is also a treasure trove of Public Domain files (which solves the 
GPL concerns I had with many of the dedicated KDE / Gnome icon sets). 
I'm also looking forward to their release 15 which seems to be just 
around the corner.


Lots of good news in the SVG world, I wonder how long before mainstream 
browsers start supporting it? (without plugins).
shadwolf:
2-Jul-2005
I like the XML  primitive draw explorer like a tree view of the compoun 
of your draw this is particularly good to write SVG renderer
Graham:
2-Jul-2005
Firefox is supposed to be able to support SVG ( a subset at least 
) without plugins, but I couldn't get it to work.  I had to download 
Adobe's plugin.
shadwolf:
2-Jul-2005
maybe they saw a boggus open door in this plugin and disable it's 
support (this can be the case for a 1.0.4)
shadwolf:
2-Jul-2005
this could be a good promotion point to insert SVG rendering into 
the rebplug for firefox once it's completed and optimised ;)
11001 / 6460812345...109110[111] 112113...643644645646647