Message-ID: <44EEF5B2.7030701 at tin.it> Date: Fri, 25 Aug 2006 15:05:54 +0200 From: Stalkern 2 MIME-Version: 1.0 To: lablgtk at math.nagoya-u.ac.jp Subject: Re: how to put text in a drawing_area ? References: <44EE235F.2050809 at tin.it> <44EE9E1A.9050409 at tin.it> <44EED402.6010006 at tin.it> <20060825.203217.06629593.garrigue at math.nagoya-u.ac.jp> <44EEEAFB.8000204 at tin.it> In-Reply-To: <44EEEAFB.8000204 at tin.it> Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=ISO-8859-1 Content-Length: 8507 Stalkern 2 wrote: > Jacques Garrigue wrote: >> From: Stalkern 2 >>> Still searching... >>> >>> So far I need to go from a GDraw.pixmap (server-side offscreen buffer >>> IIRC) to a Gdk.Image (client-side offscreen buffer). >>> >>> What kind of object would allow me this move, apart from a visible window? >> I'm not sure I understand your problem. You can extract a Gdk.pixmap >> from a GDraw.pixmap (using the pixmap method). Then you can get an >> image with the Gdk.Imgage.get function. Do you need anything else? >> >> Jacques >> Still advancing... I had confused a width and a height!!! How WAFUL!!! :-)) Now I can ROTATE the text ---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---->8---- (* textRotator *) (* ------------------------------------------------------------- *) (* Use with lablgtk 2.x *) (* As usual, simply launch lablgtk2 from a console *) (* ------------------------------------------------------------- *) (*sizes*) let (windowWidth,windowHeight) = (300,300);; (*can't see what an exposed area looks like? * set to "true" to mark exposed areas so that you can't miss them :-) *) let advertiseExposedAreaFlag = false;; (* ------------------------------------------------------------- *) open GMain;; let window = GWindow.window ~width:windowWidth ~height:windowHeight ();; let dwArea = GMisc.drawing_area ~packing:window#add ();; (*realize drawing areas as soon as possible*) let (w:Gdk.window) = (dwArea#misc#realize (); dwArea#misc#window);; let (dwb:GDraw.drawable) = new GDraw.drawable w;; let () = (* (http://developer.gnome.org/doc/GGAD/z132.html) * GDK's GdkRGB module allows you to copy a client-side buffer of image data to a drawable. * If you need to manipulate images extensively, or copy image data to the server, * this is the correct way to do it. You can't directly manipulate a GdkPixmap * because a pixmap is a server-side object. Copying image data to the server with * gdk_draw_point() would be unbelievably slow, since each point would require a server request * (probably more than one, since you will need to change the GC for each point). * Internally, GdkRGB uses an object called GdkImage to rapidly copy image data to the server * in a single request. This is still somewhat slow---sizeable data does have to be copied--- * but GdkRGB is highly tuned and uses shared memory if the client and server happen to be * on the same machine. So it's the fastest way to perform this task, given the X architecture. * It will also handle some tricky issues for you (such as adapting to the colormaps and * visuals available on a given X server). * The GdkRGB functions are in a separate header, gdk/gdkrgb.h. Before using any * GdkRGB functions, you must initialize the module with gdk_rgb_init() (Figure 24); * this sets up the visual and colormap GdkRGB will use, and some internal data structures. *) Gdk.Rgb.init () ;; let backingPxm:(GDraw.pixmap) = ( GDraw.pixmap ~width:windowWidth ~height:windowHeight ~mask:false ~colormap:(Gdk.Rgb.get_cmap ())(*Gdk.Color.get_system_colormap ()*) () ) ;; let () = backingPxm#set_foreground (`NAME "orange"); backingPxm#rectangle ~filled:true ~x:0 ~y:0 ~width:windowWidth ~height:windowHeight () ;; (* ------------------------------------------------------------- *) (* background restoration callback *) let redraw_on_exposure ?(simulate = false) (aDrawing:GDraw.drawable) aExposedArea = (*TEST*) (*let () = Printf.printf "EXPOSURE!\n%!" in*) (*the first one happens when showing!*) ( let exposedAreaX = (Gdk.Rectangle.x aExposedArea) in let exposedAreaY = (Gdk.Rectangle.y aExposedArea) in let exposedAreaWidth = (Gdk.Rectangle.width aExposedArea) in let exposedAreaHeight = (Gdk.Rectangle.height aExposedArea) in (* Hint given by Claude Marché; * book area to redraw with respect to the clipping area * that will be used by the animation function, * otherwise the clipping mask for the moving image would * only take care of the moving image *) let () = aDrawing#set_clip_rectangle aExposedArea in (*paste exposed areas back from the background pixmap*) (*use ~xsrc:0 ~ysrc:0 for checking the behaviour*) let () = aDrawing#put_pixmap ~x:exposedAreaX ~y:exposedAreaY ~xsrc:exposedAreaX ~ysrc:exposedAreaY ~width:exposedAreaWidth ~height:exposedAreaHeight backingPxm#pixmap in let () = if ((advertiseExposedAreaFlag) && (not simulate)) then ( let () = aDrawing#set_foreground (`NAME "yellow") in let () = aDrawing#set_line_attributes ~width:5 () in let () = aDrawing#lines [ (exposedAreaX,exposedAreaY); ((exposedAreaX + exposedAreaWidth),(exposedAreaY)); ((exposedAreaX + exposedAreaWidth),(exposedAreaY + exposedAreaHeight)); ((exposedAreaX),(exposedAreaY + exposedAreaHeight)); ((exposedAreaX + exposedAreaWidth),(exposedAreaY)); (exposedAreaX,exposedAreaY); ((exposedAreaX + exposedAreaWidth),(exposedAreaY + exposedAreaHeight)) ] in () ) else () in (* * in GTK, a callback returning false means: * "Continue until some signal handler returns TRUE, * or until the top-level widget is reached" *) false ) ;; (* ------------------------------------------------------------- *) let gui () = let () = ignore (window#connect#destroy ~callback:Main.quit) in let () = ignore (dwArea#event#connect#expose ~callback: (fun event -> redraw_on_exposure dwb (GdkEvent.Expose.area event))) in (*ATTEMPT TO ROTATE A PART OF THE DRAWABLE*) let () = ( let pc = dwArea#misc#create_pango_context in let () = pc#set_font_by_name ("sans " ^ string_of_int 30) in let pl = pc#create_layout in let () = Pango.Layout.set_text pl "HELLOOO" in let plw,plh = Pango.Layout.get_pixel_size pl in let () = Printf.printf "w=%d,h=%d\n%!" plw plh in let usedTechnique =`USE_IMG_FROM_PIXMAP in let () = ( match usedTechnique with | `USE_IMG_FROM_PIXMAP -> (* A pixmap is an _off-screen_ buffer *) ( let (pxm_1,pxm_2) = ( ( GDraw.pixmap ~width:plw ~height:plh ~mask:true ~colormap:(*Gdk.Rgb.get_cmap ()*)(Gdk.Color.get_system_colormap ()) () ), ((*swap w and h*) GDraw.pixmap ~width:plh ~height:plw ~mask:true ~colormap:(*Gdk.Rgb.get_cmap ()*)(Gdk.Color.get_system_colormap ()) () ) ) in let () = pxm_1#set_foreground `BLACK in let () = pxm_1#rectangle ~filled:true ~x:0 ~y:0 ~width:plw ~height:plh () in let () = pxm_1#put_layout ~x:0 ~y:0 ~fore:`WHITE pl in (* draw whatever you like *) (* let () = pxm_1#set_line_attributes ~width:5 () in (*let () = pxm_1#set_background (`NAME "cyan") in*) let () = pxm_1#set_foreground `BLACK in let () = pxm_1#line ~x:0 ~y:(plh/2) ~x:plw ~y:(plh/2) in *) (**) let img_1 = Gdk.Image.get pxm_1#pixmap ~x:0 ~y:0 ~width:plw ~height:plh in let img_2 = Gdk.Image.create ~kind:`NORMAL ~visual:(Gdk.Rgb.get_visual () ) ~width:plh ~height:plw in (**) (* ROTATE *) let () = for i=0 to (plw -1) do ( for j=0 to (plh -1) do (Gdk.Image.put_pixel img_2 ~x:j ~y:i ~pixel:(Gdk.Image.get_pixel img_1 ~x:(plw - i -1) ~y:j) ) done ) done in (* COPY TO DEST *) let () = backingPxm#put_image ~x:((windowWidth-plh)/2) ~y:((windowHeight-plw)/2) ~xsrc:0 ~ysrc:0 ~width:plh ~height:plw img_2 in (**) (*CLEANUP tmp images *) let () = ( Gdk.Pixmap.destroy (pxm_1#pixmap); Gdk.Pixmap.destroy (pxm_2#pixmap) ) in () ) ) in () ) in let () = window#show () in Main.main () ;; (* ------------------------------------------------------------- *) (* Go! *) let _ = gui ();; (*EOF*) ----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<----8<---- But why do I still get a (ocaml:15984): Gdk-WARNING **: No colormap in gc_get_background ? Ernesto