implement Op; include "sys.m"; sys: Sys; include "draw.m"; draw: Draw; Display, Image, Rect, Point: import draw; include "arg.m"; stderr: ref Sys->FD; # usage: draw xpos ypos img.bit [xpos ypos img.bit]... Op: module { init: fn(ctxt: ref Draw->Context, argv: list of string); }; width := 0; src: ref Draw->Image; init(ctxt: ref Draw->Context, argv: list of string) { sys = load Sys Sys->PATH; stderr = sys->fildes(2); draw = load Draw Draw->PATH; arg := load Arg Arg->PATH; displ := ctxt.display; arg->init(argv); arg->setusage("usage: op [-s srcimage] [-w width] drawop args\n"); src = displ.black; while ((opt := arg->opt()) != 0) { case opt { 's' => src = displ.open(arg->earg()); if (src == nil) { sys->fprint(stderr, "op: cannot open image %r\n"); raise "fail:error"; } 'w' => width = int arg->earg(); * => arg->usage(); } } argv = arg->argv(); if (argv == nil) arg->usage(); base := displ.readimage(sys->fildes(0)); if (base == nil) { sys->fprint(stderr, "draw: cannot read base image: %r\n"); raise "fail:error"; } case hd argv { "line" => line(base, argv); "fillellipse" or "ellipse" => ellipse(base, argv); } displ.writeimage(sys->fildes(1), base); } line(dst: ref Draw->Image, argv: list of string) { argv = tl argv; p0 := Point(int hd argv, int hd tl argv); p1 := Point(int hd tl tl argv, int hd tl tl tl argv); dst.line(p0, p1, Draw->Endsquare, Draw->Endsquare, width, src, p0); } ellipse(dst: ref Draw->Image, argv: list of string) { fill := hd argv == "fillellipse"; argv = tl argv; c := Point(int hd argv, int hd tl argv); a := int hd tl tl argv; b := int hd tl tl tl argv; if(fill) dst.fillellipse(c, a, b, src, c); else dst.ellipse(c, a, b, width, src, c); }