Here is the patch to enable font rotation on gtk2. The angle used is the
one defined in createfontindirect.

Someone still needs to implement the necessary functions in the gtk
bindings.

Luis

On Mon, 2007-09-10 at 18:39 +0100, Luis Rodrigues wrote:
> Hi,
> 
> Over the last weekend I've implemented text rotate in GTK2. I've
> implemented it in Gtk2WidgetSet.ExtTextOut. Since there is no way to
> define that the font is rotated, TGtk2WidgetSet.CreateFontIndirectEx ..
> lfEscapement can only be used to place the angle  somewhere to
> ExtTextOut to use.
> 
> The used functions (with gtk/pango version)
> pango_matrix_rotate -  gtk2.6 
> pango_matrix_translate - gtk2.6
> pango_context_set_matrix - gtk2.6
> pango_renderer_draw_layout - pango1.8
> 
> gdk_pango_renderer_get_default - gtk2.6
> gdk_pango_renderer_set_drawable - gtk2.6
> gdk_pango_renderer_set_gc - gtk2.6
> 
> gtk2.6 and pango1.8 where released in Dec 2004 so I guess i can be
> implemented with no problems :)
> 
> 
> I've defined in Gtk2int.pas
> 
>    TPangoMatrix = record
>      xx: double;
>      xy: double;
>      yx: double;
>      yy: double;
>      x0: double;
>      y0: double;
>    end;
>    PTPangoMatrix = ^TPangoMatrix;
>    PPangoRenderer = pointer;
>    PGdkPangoRenderer = pointer;
> 
> procedure pango_font_description_set_gravity
> (desc:PPangoFontDescription;gravity:TPangoGravity); cdecl; external
> 'libpango-1.0.so.0';
> procedure pango_matrix_rotate(matrix: PPangoMatrix; degrees: double);
> cdecl; external 'libpango-1.0.so.0';
> procedure pango_matrix_translate(matrix: PPangoMatrix; tx, ty: double);
> cdecl; external 'libpango-1.0.so.0';
> procedure pango_matrix_scale (matrix: PPangoMatrix; scale_x, scale_y:
> double);  cdecl; external 'libpango-1.0.so.0';
> procedure pango_context_set_matrix(context: PPangoContext; matrix:
> PPangoMatrix); cdecl; external 'libpango-1.0.so.0';
> procedure pango_renderer_draw_layout (renderer: PPangoRenderer; layout:
> PPangoLayout; x,y: Integer);  cdecl; external 'libpango-1.0.so.0';
> 
> function  gdk_pango_renderer_get_default (screen: PGdkScreen):
> PPangoRenderer; cdecl; external 'libgtk-x11-2.0.so';
> procedure gdk_pango_renderer_set_drawable (gdk_renderer:
> PGdkPangoRenderer;  drawable: PGdkDrawable); cdecl; external
> 'libgtk-x11-2.0.so';
> procedure gdk_pango_renderer_set_gc (gdk_renderer: PGdkPangoRenderer;
> gc: PGdkGC); cdecl; external 'libgtk-x11-2.0.so';
> 
> 
> and changed gtkwinapi.inc
> 
> 
>   procedure DoTextOut(X,Y : Integer; Str: Pchar; CurCount: Integer);
>   var
>     DevCtx: TDeviceContext;
>     CurScreenX: LongInt;
>     CharLen: LongInt;
> 
>     WidgetCont: PPangoContext;
>     matrix: TPangoMatrix;
>     renderer: PPangoRenderer;
>     screen: PGdkScreen;
>     gc: PGdkGc;
>   begin
>     DevCtx:=TDeviceContext(DC);
>     if (Dx<>nil) then begin
>       CurScreenX:=X;
>       while CurCount>0 do begin
>         CharLen:=UTF8CharacterLength(CurStr);
>         //gdk_draw_glyphs(DevCtx.drawable,DevCtx.gc );
>         pango_layout_set_text(UseFont, CurStr, CharLen);
>         gdk_draw_layout_with_colors(DevCtx.drawable, DevCtx.GC,
> CurScreenX, Y,
>                                     UseFont, Foreground, nil);
>         //gdk_draw_rectangle(DevCtx.Drawable,DevCtx.GC,1,CurScreenX,Y,3,3);
>         inc(CurScreenX,CurDx^);
>         inc(CurDx);
>         inc(CurStr,CharLen);
>         dec(CurCount,CharLen);
>       end;
>     end else begin //just changed this branch
>       pango_layout_set_text(UseFont, Str, Count);
>       
>       renderer :=
> gdk_pango_renderer_get_default( gtk_widget_get_screen(DevCtx.DCWidget) );
>       gdk_pango_renderer_set_drawable ( renderer, DevCtx.drawable);
>       gdk_pango_renderer_set_gc ( renderer, DevCtx.GC);
>   
>       WidgetCont := pango_layout_get_context(UseFont);
>       matrix.xx := 1.0;
>       matrix.xy := 0.0;
>       matrix.yx := 0.0;
>       matrix.yy := 1.0;
>       matrix.x0 := 0.0;
>       matrix.y0 := 0.0;
>       pango_matrix_translate (@matrix, X, Y);
>       pango_matrix_rotate (@matrix, 285); //<--this is the angle
>       
>       pango_context_set_matrix (WidgetCont, @matrix);
>       pango_layout_context_changed (UseFont);
> 
>       pango_renderer_draw_layout (renderer, UseFont, X, Y);
>       
>       gdk_pango_renderer_set_drawable ( renderer, nil);
>       gdk_pango_renderer_set_gc ( renderer, nil);
>     end;
>   end;
> 
> I could have done a patch but this code is just a proof of concept and
> needs to be integrated in the correct files (with I don't know with they
> are). So now we can have text rotate in Gtk2 also :) 
> 
> 
> regards,
> 
> Luis
> 
> 
> On Wed, 2007-09-05 at 11:43 +0200, Mattias Gaertner wrote:
> > On Tue, 04 Sep 2007 21:31:07 +0100
> > Luis Rodrigues <[EMAIL PROTECTED]> wrote:
> > 
> > > Hello,
> > > 
> > > I was going to implement rotating text on GTK2 but just noticed that
> > > pango_font_description_set_gravity, PangoGravity, etc are not defined
> > > on FreePascal Pango bindings.
> > > 
> > > I tried to find on GTK website and on FPC
> > > (http://www.freepascal.org/packages/gtk.html) but had no luke :(
> > > 
> > > Is anyone actively working on that?
> > 
> > No.
> > 
> > See lcl/interfaces/gtk2/gtk2winapi.inc
> > TGtk2WidgetSet.CreateFontIndirectEx for lfEscapement.
> > 
> > AFAIK rotating text needs pango 1.16, which is quite new and not all
> > linux distributions contain it yet.
> > So the gtk2 interface must check the pango version and then dynamically
> > load the needed function.
> > 
> > 
> > Mattias
> > 
> > _________________________________________________________________
> >      To unsubscribe: mail [EMAIL PROTECTED] with
> >                 "unsubscribe" as the Subject
> >    archives at http://www.lazarus.freepascal.org/mailarchives
> 
> _________________________________________________________________
>      To unsubscribe: mail [EMAIL PROTECTED] with
>                 "unsubscribe" as the Subject
>    archives at http://www.lazarus.freepascal.org/mailarchives
--- gtk2winapi.inc.old	2007-09-12 04:42:54.000000000 +0100
+++ gtk2winapi.inc	2007-09-12 04:43:42.000000000 +0100
@@ -338,17 +338,50 @@
     DevCtx: TDeviceContext;
     CurScreenX: LongInt;
     CharLen: LongInt;
+
+    WidgetCont: PPangoContext;
+    matrix: TPangoMatrix;
+    renderer: PPangoRenderer;
+    screen: PGdkScreen;
+    gc: PGdkGc;
+    
+    procedure do_draw_layout;
+    begin
+      renderer := gdk_pango_renderer_get_default( gtk_widget_get_screen(DevCtx.DCWidget) );
+      gdk_pango_renderer_set_drawable ( renderer, DevCtx.drawable);
+      gdk_pango_renderer_set_gc ( renderer, DevCtx.GC);
+
+      if PGdiObject(DevCtx.CurrentFont)^.LogFont.lfEscapement <> 0 then begin
+        WidgetCont := pango_layout_get_context(UseFont);
+        matrix.xx := 1.0;
+        matrix.xy := 0.0;
+        matrix.yx := 0.0;
+        matrix.yy := 1.0;
+        matrix.x0 := 0.0;
+        matrix.y0 := 0.0;
+        pango_matrix_translate (@matrix, X, Y);
+        pango_matrix_rotate (@matrix, PGdiObject(DevCtx.CurrentFont)^.LogFont.lfEscapement div 10);
+
+        pango_context_set_matrix (WidgetCont, @matrix);
+        pango_layout_context_changed (UseFont);
+      end;
+
+      pango_renderer_draw_layout (renderer, UseFont, X, Y);
+
+      gdk_pango_renderer_set_drawable ( renderer, nil);
+      gdk_pango_renderer_set_gc ( renderer, nil);
+
+    end;
   begin
     DevCtx:=TDeviceContext(DC);
     if (Dx<>nil) then begin
       CurScreenX:=X;
       while CurCount>0 do begin
         CharLen:=UTF8CharacterLength(CurStr);
-        //gdk_draw_glyphs(DevCtx.drawable,DevCtx.gc );
+
         pango_layout_set_text(UseFont, CurStr, CharLen);
-        gdk_draw_layout_with_colors(DevCtx.drawable, DevCtx.GC, CurScreenX, Y,
-                                    UseFont, Foreground, nil);
-        //gdk_draw_rectangle(DevCtx.Drawable,DevCtx.GC,1,CurScreenX,Y,3,3);
+        do_draw_layout();
+
         inc(CurScreenX,CurDx^);
         inc(CurDx);
         inc(CurStr,CharLen);
@@ -356,11 +389,11 @@
       end;
     end else begin
       pango_layout_set_text(UseFont, Str, Count);
-      gdk_draw_layout_with_colors(DevCtx.drawable, DevCtx.GC, X, Y, UseFont,
-                                  Foreground, nil);
+      do_draw_layout();
     end;
   end;
 
+
 begin
   //DebugLn(['TGtk2WidgetSet.ExtTextOut X=',X,' Y=',Y,' Str="',copy(Str,1,Count),'" Count=',Count,' DX=',dbgs(DX)]);
   Assert(False, Format('trace:> [TGtk2WidgetSet.ExtTextOut] DC:0x%x, X:%d, Y:%d, Options:%d, Str:''%s'', Count: %d', [DC, X, Y, Options, Str, Count]));

Reply via email to