123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204(***********************************************************************)(* *)(* Objective Caml *)(* *)(* Jun Furuse, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 1999-2004, *)(* Institut National de Recherche en Informatique et en Automatique. *)(* Distributed only by permission. *)(* *)(***********************************************************************)(* $Id: ximage.ml,v 1.1.2.1 2010/05/13 13:14:47 furuse Exp $*)openImagestypeelt=int(* must be int32, but lablgtk uses int *)typet={width:int;height:int;data:Gdk.image;}letdestroyt=Gdk.Image.destroyt.datamoduleTruecolor=struct(* Truecolor quick color query *)openGdk.Truecolorletcolor_creatorvisual=letf=color_creatorvisualinfunrgb->f~red:(rgb.r*257)~green:(rgb.g*257)~blue:(rgb.b*257)letcolor_parservisual=letf=color_parservisualinfunpixel->letr,g,b=fpixelin{r=rlsr8;g=glsr8;b=blsr8}endletcapsulatewidthheightdata={width=width;height=height;data=data;}letcreate~kind~visual~width~height=letximage=Gdk.Image.create~kind~visual~width~heightincapsulatewidthheightximageletunsafe_gettxy=Gdk.Image.get_pixelt.data~x~yletunsafe_settxyc=Gdk.Image.put_pixelt.data~x~y~pixel:cletgettxy=Region.checkt.widtht.heightxy;unsafe_gettxyletsettxyc=Region.checkt.widtht.heightxy;unsafe_settxycletget_imagedrawable~x~y~width~height=letximage=Gdk.Image.getdrawable~x~y~width~heightincapsulatewidthheightximage(*
external init_color_conversion : Gdk.visual -> unit
= "init_color_conversion"
external color_conversion : string -> int -> int
= "color_conversion"
*)letof_imagevisualprogressimg=letquick_color_create=Truecolor.color_creatorvisualinletprogv(* 0.0 .. 1.0 *)=matchprogresswith|Somef->fv|None->()inletput_rgbximgxyrgb=Gdk.Image.put_pixelximg.data~x~y~pixel:(quick_color_creatergb)inmatchimgwith|Rgb24t->letwidth=t.Rgb24.widthinletheight=t.Rgb24.heightinletximg=create~kind:`FASTEST~visual~width~heightinletf_height=floatheightinfory=0toheight-1doforx=0towidth-1doput_rgbximgxy(Rgb24.unsafe_gettxy)done;prog(float(y+1)/.f_height)done;ximg|Rgba32t->(* ignore alpha *)letwidth=t.Rgba32.widthinletheight=t.Rgba32.heightinletximg=create~kind:`FASTEST~visual~width~heightinletf_height=floatheightinfory=0toheight-1doforx=0towidth-1doput_rgbximgxy(Rgba32.unsafe_gettxy).colordone;prog(float(y+1)/.f_height)done;ximg|Index8t->letwidth=t.Index8.widthinletheight=t.Index8.heightinletcmap=t.Index8.colormap.mapinletximg=create~kind:`FASTEST~visual~width~heightinletf_height=floatheightinletxcmap=Array.mapquick_color_createcmapinfory=0toheight-1doforx=0towidth-1doGdk.Image.put_pixelximg.data~x~y~pixel:xcmap.(Index8.unsafe_gettxy)done;prog(float(y+1)/.f_height)done;ximg|Index16t->letwidth=t.Index16.widthinletheight=t.Index16.heightinletcmap=t.Index16.colormap.mapinletximg=create~kind:`FASTEST~visual~width~heightinletf_height=floatheightinletxcmap=Array.mapquick_color_createcmapinfory=0toheight-1doforx=0towidth-1doGdk.Image.put_pixelximg.data~x~y~pixel:xcmap.(Index16.unsafe_gettxy)done;prog(float(y+1)/.f_height)done;ximg|_->failwith"not supported"openGDrawletget_mono_gcwin=letcolormap=Gdk.Color.get_system_colormap()inletbmp=Gdk.Bitmap.create~window:win~width:1~height:1()inletgc=Gdk.GC.createbmpin(* GC.set_foreground gc (Color.color_parse "black"); *)Gdk.GC.set_foregroundgc(Gdk.Color.alloc~colormap:colormap`WHITE);gcletplain_maskwinwh=letcolormap=Gdk.Color.get_system_colormap()inletmono_gc=get_mono_gcwininletbmp=Gdk.Bitmap.create~window:win~width:w~height:h()inGdk.GC.set_foregroundmono_gc(Gdk.Color.alloc~colormap:colormap`WHITE);Gdk.Draw.rectanglebmpmono_gc~x:0~y:0~width:w~height:h~filled:true();bmpletmask_of_imagewinimg=(* It is really inefficient *)letmono_gc=get_mono_gcwininletwidth,height=Images.sizeimginletdraw_maskttranspimage_get=prerr_endline"making mask";letbmp=Gdk.Bitmap.create~window:win~width~height()inletximg=get_imagebmp~x:0~y:0~width~heightinforx=0towidth-1dofory=0toheight-1doifimage_gettxy=transpthenGdk.Image.put_pixelximg.data~x~y~pixel:0elseGdk.Image.put_pixelximg.data~x~y~pixel:1done;done;Gdk.Draw.imagebmpmono_gcximg.data~xsrc:0~ysrc:0~xdest:0~ydest:0~width~height;Somebmpin(* BUG ? of gtk or lablgtk? Using None for mask does not work *)letwidth,height=Images.sizeimginbeginmatchimgwith|Index8t->ift.Index8.transparent>=0thendraw_masktt.Index8.transparentIndex8.unsafe_getelseSome(plain_maskwinwidthheight)|Index16t->ift.Index16.transparent>=0thendraw_masktt.Index16.transparentIndex16.unsafe_getelseSome(plain_maskwinwidthheight)|_->Some(plain_maskwinwidthheight)endletpixmap_ofwinximage=letvisual=Gdk.Window.get_visualwininletpix=Gdk.Pixmap.create~window:win~depth:(Gdk.Visual.depthvisual)~width:ximage.width~height:ximage.height()inletpixmap=newdrawablepixinpixmap#put_image~x:0~y:0~width:ximage.width~height:ximage.height~xsrc:0~ysrc:0ximage.data;pixletpixmap_of_imagewinprogressimg=letvisual=Gdk.Window.get_visualwininletximage=of_imagevisualprogressimginletmsk=mask_of_imagewinimginletpixmap=newGDraw.pixmap?mask:msk(pixmap_ofwinximage)inpixmap