[Gtk-sharp-list] Using Pango to layout text oustise of GTK+
Peter Meyer
petermeyer99@hotmail.com
Mon, 10 May 2004 03:25:28 +0000
<html><div style='background-color:'><DIV class=RTE>Hi,</DIV>
<DIV class=RTE>I am looking to use Pnago with a .NET application that uses WindowsForms as its UI layer. I thought I might be able to use GTK# as a wrapper for Pango in order to avoid to have to wrap it all for myself.</DIV>
<DIV class=RTE>When I looked at GTK# I realized that the functions from the Pango win32 library are not mapped through GTK#. That is, there is no means to create a context or layout without getting the context from the GTK Widget, and no means to call the render functions that simply use an HDC (the Pango render functions are called as part of the GTK drawing).</DIV>
<DIV class=RTE> </DIV>
<DIV class=RTE>So I tried the following, which doesn't work...</DIV>
<DIV class=RTE> </DIV>
<DIV class=RTE>To get a context, I explicitly wrapped pango_win32_get_context via P/Invoke:</DIV>
<DIV class=RTE><IMG height=2 src="http://graphics.hotmail.com/greypixel.gif" width="100%" vspace=9></DIV>
<DIV class=RTE><PRE>using Pango;</PRE><PRE>[DllImport(path+"libpangowin32-1.0-0.dll", EntryPoint="pango_win32_get_context")]</PRE></DIV><PRE class=RTE>private static extern IntPtr PangoWin32GetContext();</PRE><PRE class=RTE><FONT color=#0000ff size=2><P>static</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>public</FONT><FONT size=2> Pango.Context CreateContext()</P><P>{</P><P> IntPtr p = PangoWin32GetContext();</P><P> Context c = </FONT><FONT color=#0000ff size=2>new</FONT><FONT size=2> Context(p);</P><P> c.Language = Language.FromString("en_US");</P><P> c.BaseDir = Pango.Direction.Ltr;</P><P> FontDescription f = </FONT><FONT color=#0000ff size=2>new</FONT><FONT size=2> FontDescription();</P><P> f.Family = "TrebuchetMS";</P><P> f.Style = Style.Normal;</P><P> f.Variant = Variant.Normal;</P><P> f.Weight = Weight.Normal;</P><P> f.Size = (</FONT><FONT color=#0000ff size=2>int</FONT><FONT size=2>) (16 * Pango.Scale.PangoScale);</P><P> f.Stretch = Stretch.Normal;</P><P> c.FontDescription = f;</P><P></FONT><FONT color=#0000ff size=2> return</FONT><FONT size=2> c;</P><P>}</FONT></P></PRE><PRE class=RTE><IMG height=2 src="http://graphics.hotmail.com/greypixel.gif" width="100%" vspace=9></PRE>
<P class=RTE>Then I create a Layout object as follows:</P>
<P class=RTE><IMG height=2 src="http://graphics.hotmail.com/greypixel.gif" width="100%" vspace=9></P><PRE class=RTE><FONT size=2><P>SimplePangoWrapper.Init();</P><P>Context c = SimplePangoWrapper.CreateContext();</P><P>layout = </FONT><FONT color=#0000ff size=2>new</FONT><FONT size=2> Layout(c);</P><P>layout.Wrap = Pango.WrapMode.Word;</P><P>layout.FontDescription = FontDescription.FromString ("TrebuchetMS 12");</P><P>layout.SetMarkup ("Hello Pango.Layout");</P></FONT></PRE><PRE class=RTE><IMG height=2 src="http://graphics.hotmail.com/greypixel.gif" width="100%" vspace=9></PRE>
<P class=RTE>SimplePangoWrapper.Init() calls the g_type_init() function in libgobject that otherwise would not be called, as I am not using any other part of GTK.</P>
<P class=RTE>Then, in the OnPaint event handler of my Form, I call:</P>
<P class=RTE><IMG height=2 src="http://graphics.hotmail.com/greypixel.gif" width="100%" vspace=9></P><FONT size=2><PRE>Graphics g = e.Graphics;</PRE><PRE>g.Clear(System.Drawing.Color.Orange);</PRE><PRE>IntPtr hdc = </FONT><FONT color=#0000ff size=2>new</FONT><FONT size=2> IntPtr();</PRE><PRE>hdc = g.GetHdc();</PRE><PRE>HandleRef hr = </FONT><FONT color=#0000ff size=2>new</FONT><FONT size=2> HandleRef(g, hdc);</PRE><PRE></FONT><FONT color=#0000ff size=2>try</FONT><FONT size=2> </PRE><PRE>{</PRE><PRE> SimplePangoWrapper.RenderLayout(hr, layout, 10, 10);</PRE></FONT><FONT size=2><PRE>}</PRE><PRE></FONT><FONT color=#0000ff size=2>catch</FONT><FONT size=2> (Exception ex)</PRE><PRE>{</PRE><PRE> Console.WriteLine(ex.ToString());</PRE><PRE>}</PRE><PRE></FONT><FONT color=#0000ff size=2>finally</PRE></FONT><FONT size=2><PRE>{</PRE><PRE> g.ReleaseHdc(hdc);</PRE><PRE>}</PRE><PRE><IMG height=2 src="http://graphics.hotmail.com/greypixel.gif" width="100%" vspace=9></PRE>
<P>Where RenderLayout is a call to:</P>
<P><IMG height=2 src="http://graphics.hotmail.com/greypixel.gif" width="100%" vspace=9></P></FONT><FONT size=2><PRE>[DllImport(path+"libpangowin32-1.0-0.dll", EntryPoint="pango_win32_render_layout")]</PRE><PRE></FONT><FONT color=#0000ff size=2>private</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>static</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>extern</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>void</FONT><FONT size=2> PangoWin32RenderLayout(HandleRef hdc,</PRE><PRE> HandleRef layout,</PRE><PRE></FONT><FONT color=#0000ff size=2> int</FONT><FONT size=2> x,</PRE><PRE></FONT><FONT color=#0000ff size=2> int</FONT><FONT size=2> y);</FONT></PRE><PRE><FONT size=2></FONT> </PRE><FONT size=2><FONT color=#0000ff size=2><PRE>static</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>public</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>void</FONT><FONT size=2> RenderLayout(HandleRef hr, Layout layout, </FONT><FONT color=#0000ff size=2>int</FONT><FONT size=2> x, </FONT><FONT color=#0000ff size=2>int</FONT><FONT size=2> y)</PRE><PRE>{</PRE></FONT><FONT size=2><PRE> HandleRef hL = </FONT><FONT color=#0000ff size=2>new</FONT><FONT size=2> HandleRef(layout, layout.Handle);</FONT><FONT color=#008000 size=2></PRE></FONT><FONT size=2><PRE> PangoWin32RenderLayout(hr, hL, x, y);</PRE><PRE>}</PRE><PRE><IMG height=2 src="http://graphics.hotmail.com/greypixel.gif" width="100%" vspace=9></PRE>
<P>So far so good. As far as I can tell in the debugger, the Layout object is created in a reasonable way and contains reasonable data. The hdc is correct and works when trying other hdc functions. Unfortunately, the call to pango_win32_Render_layout fails with a null pointer exception somewhere in the pango library, as far as I can tell.</P>
<P>I don't know how to build a debug version of the pango library to work with GTKSharp. Is there any quick tip or hint someone can offer me how to make this work? Or is there a fundamental reason why it can't work?</P>
<P>Thanks a lot!</P>
<P> PM</P></FONT></FONT></div><br clear=all><hr>Enjoy 25MB of inbox storage and 10MB per file attachment <a href="http://g.msn.com/8HMAENCA/2746??PS=47575">With MSN Premium </a> Get 2 Months FREE* </html>