123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309(**************************************************************************)(* *)(* OCaml *)(* *)(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 1996 Institut National de Recherche en Informatique et *)(* en Automatique. *)(* *)(* All rights reserved. This file is distributed under the terms of *)(* the GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)exceptionGraphic_failureofstring(* Initializations *)let_=Callback.register_exception"Graphics.Graphic_failure"(Graphic_failure"")externalraw_open_graph:string->unit="caml_gr_open_graph"externalraw_close_graph:unit->unit="caml_gr_close_graph"externalsigio_signal:unit->int="caml_gr_sigio_signal"externalsigio_handler:int->unit="caml_gr_sigio_handler"letunix_open_grapharg=Sys.set_signal(sigio_signal())(Sys.Signal_handlesigio_handler);raw_open_graphargletunix_close_graph()=Sys.set_signal(sigio_signal())Sys.Signal_ignore;raw_close_graph()letopen_graph,close_graph=matchSys.os_typewith|"Unix"|"Cygwin"->(unix_open_graph,unix_close_graph)|"Win32"->(raw_open_graph,raw_close_graph)|"MacOS"->(raw_open_graph,raw_close_graph)|_->invalid_arg("Graphics: unknown OS type: "^Sys.os_type)externalset_window_title:string->unit="caml_gr_set_window_title"externalresize_window:int->int->unit="caml_gr_resize_window"externalclear_graph:unit->unit="caml_gr_clear_graph"externalsize_x:unit->int="caml_gr_size_x"externalsize_y:unit->int="caml_gr_size_y"(* Double-buffering *)externaldisplay_mode:bool->unit="caml_gr_display_mode"externalremember_mode:bool->unit="caml_gr_remember_mode"externalsynchronize:unit->unit="caml_gr_synchronize"letauto_synchronize=function|true->display_modetrue;remember_modetrue;synchronize()|false->display_modefalse;remember_modetrue(* Colors *)typecolor=intletrgbrgb=(rlsl16)+(glsl8)+bexternalset_color:color->unit="caml_gr_set_color"letblack=0x000000andwhite=0xFFFFFFandred=0xFF0000andgreen=0x00FF00andblue=0x0000FFandyellow=0xFFFF00andcyan=0x00FFFFandmagenta=0xFF00FFletbackground=whiteandforeground=black(* Drawing *)externalplot:int->int->unit="caml_gr_plot"letplotspoints=fori=0toArray.lengthpoints-1doletx,y=points.(i)inplotxydoneexternalpoint_color:int->int->color="caml_gr_point_color"externalmoveto:int->int->unit="caml_gr_moveto"externalcurrent_x:unit->int="caml_gr_current_x"externalcurrent_y:unit->int="caml_gr_current_y"letcurrent_point()=(current_x(),current_y())externallineto:int->int->unit="caml_gr_lineto"letrlinetoxy=lineto(current_x()+x)(current_y()+y)letrmovetoxy=moveto(current_x()+x)(current_y()+y)externalraw_draw_rect:int->int->int->int->unit="caml_gr_draw_rect"letdraw_rectxywh=ifw<0||h<0thenraise(Invalid_argument"draw_rect")elseraw_draw_rectxywhletdraw_poly,draw_poly_line=letdodrawclose_flagpoints=ifArray.lengthpoints>0then(letsavex,savey=current_point()inmoveto(fstpoints.(0))(sndpoints.(0));fori=1toArray.lengthpoints-1doletx,y=points.(i)inlinetoxydone;ifclose_flagthenlineto(fstpoints.(0))(sndpoints.(0));movetosavexsavey)in(dodrawtrue,dodrawfalse)letdraw_segmentssegs=letsavex,savey=current_point()infori=0toArray.lengthsegs-1doletx1,y1,x2,y2=segs.(i)inmovetox1y1;linetox2y2done;movetosavexsaveyexternalraw_draw_arc:int->int->int->int->int->int->unit="caml_gr_draw_arc""caml_gr_draw_arc_nat"letdraw_arcxyrxrya1a2=ifrx<0||ry<0thenraise(Invalid_argument"draw_arc/ellipse/circle")elseraw_draw_arcxyrxrya1a2letdraw_ellipsexyrxry=draw_arcxyrxry0360letdraw_circlexyr=draw_arcxyrr0360externalraw_set_line_width:int->unit="caml_gr_set_line_width"letset_line_widthw=ifw<0thenraise(Invalid_argument"set_line_width")elseraw_set_line_widthwexternalraw_fill_rect:int->int->int->int->unit="caml_gr_fill_rect"letfill_rectxywh=ifw<0||h<0thenraise(Invalid_argument"fill_rect")elseraw_fill_rectxywhexternalfill_poly:(int*int)array->unit="caml_gr_fill_poly"externalraw_fill_arc:int->int->int->int->int->int->unit="caml_gr_fill_arc""caml_gr_fill_arc_nat"letfill_arcxyrxrya1a2=ifrx<0||ry<0thenraise(Invalid_argument"fill_arc/ellipse/circle")elseraw_fill_arcxyrxrya1a2letfill_ellipsexyrxry=fill_arcxyrxry0360letfill_circlexyr=fill_arcxyrr0360(* Text *)externaldraw_char:char->unit="caml_gr_draw_char"externaldraw_string:string->unit="caml_gr_draw_string"externalset_font:string->unit="caml_gr_set_font"externalset_text_size:int->unit="caml_gr_set_text_size"externaltext_size:string->int*int="caml_gr_text_size"(* Images *)typeimagelettransp=-1externalmake_image:colorarrayarray->image="caml_gr_make_image"externaldump_image:image->colorarrayarray="caml_gr_dump_image"externaldraw_image:image->int->int->unit="caml_gr_draw_image"externalcreate_image:int->int->image="caml_gr_create_image"externalblit_image:image->int->int->unit="caml_gr_blit_image"letget_imagexywh=letimage=create_imagewhinblit_imageimagexy;image(* Events *)typestatus={mouse_x:int;mouse_y:int;button:bool;keypressed:bool;key:char;}typeevent=Button_down|Button_up|Key_pressed|Mouse_motion|Pollexternalwait_next_event:eventlist->status="caml_gr_wait_event"letmouse_pos()=lete=wait_next_event[Poll]in(e.mouse_x,e.mouse_y)letbutton_down()=lete=wait_next_event[Poll]ine.buttonletread_key()=lete=wait_next_event[Key_pressed]ine.keyletkey_pressed()=lete=wait_next_event[Poll]ine.keypressedletloop_at_exiteventshandler=letevents=List.filter(fune->e<>Poll)eventsinat_exit(fun_->trywhiletruedolete=wait_next_eventeventsinhandleredonewith|Exit->close_graph()|e->close_graph();raisee)(*** Sound *)externalsound:int->int->unit="caml_gr_sound"(* Splines *)letsub(x1,y1)(x2,y2)=(x1-.x2,y1-.y2)andmiddle(x1,y1)(x2,y2)=((x1+.x2)/.2.0,(y1+.y2)/.2.0)andarea(x1,y1)(x2,y2)=abs_float((x1*.y2)-.(x2*.y1))andnorm(x1,y1)=sqrt((x1*.x1)+.(y1*.y1))lettestabcd=letv=subdainlets=normvinareav(subab)<=s&&areav(subac)<=sletsplineabcd=letrecsplaccuabcd=iftestabcdthend::accuelseleta'=middleabando=middlebcinletb'=middlea'oandd'=middlecdinletc'=middleod'inleti=middleb'c'inspl(splaccuaa'b'i)ic'd'dinspl[a]abcdletcurvetobc((x,y)asd)=letfloat_point(x,y)=(float_of_intx,float_of_inty)inletroundf=int_of_float(f+.0.5)inletint_point(x,y)=(roundx,roundy)inletpoints=spline(float_point(current_point()))(float_pointb)(float_pointc)(float_pointd)indraw_poly_line(Array.of_list(List.mapint_pointpoints));movetoxy