[pygtk] Rotate Pango by 90 degrees ?

Jean-Baptiste Cazier jean-baptiste.cazier at decode.is
Fri Sep 24 17:22:27 WST 2004

Sæl !

About a year ago John Hunter proposed a routine to rotate pango text ( draw=

I wonder if the procedure has been implemented by default in a pango method=
It would be VERY useful for many to have the possibility to rotate pangolay=
out, at least by 90,180,270 degrees




>>>>> "John" =3D=3D John Hunter <jdhunter at ace.bsd.uchicago.edu> writes:

    John> I want to rotate some text 90 degrees.  I'm using pango
    John> layouts and drawable.draw_layout to draw my text.

OK, got this working at the level of manipulating individual pixels in
a gtk.gdk.Image with pixbufs and pixmaps.  For my purposes, making
ylabels, this is probably fast enough, but if anyone has a more
efficient solution, let me know...

However, if the 'Rotate' button is clicked repeatedly, which just
repeats the rotated drawing operation, strange things start to appear
in the region where the rotated text is rendered.  Since repeated
clicks should just be repeating the same drawing operations, it is not
clear to me why this is happening.

Below is an example script.

John Hunter

import pygtk
import gtk
import pango

win =3D gtk.Window()
vbox =3D gtk.VBox()

class C:

    def __init__(self, text):
        self.text =3D text
    def realize(self, drawingArea):
        self.drawingArea =3D drawingArea
        self.drawable =3D drawingArea.window

        # text properties
        context =3D self.drawingArea.create_pango_context()
        self.layout  =3D self.drawingArea.create_pango_layout(self.text)
        desc =3D pango.FontDescription('Sans 14')
        self.layout.set_font_description(desc)   =20

    def draw_text(self, drawable=3DNone, x=3D100, y=3D100):
        if drawable is None: drawable=3Dself.drawable
        # draw some text in the foreground color
        gc =3D drawable.new_gc()
        drawable.draw_layout(gc, x=3Dx, y=3Dy, layout=3Dself.layout)

    def draw_text_rotated(self):
        draw the text to a pixmap, rotate the image, fill a pixbuf
        and draw from the pixbuf

        inkRect, logicalRect =3D self.layout.get_pixel_extents()
        x, y, w, h =3D logicalRect
        winw, winh =3D self.drawable.get_size()
        pixmap =3D gtk.gdk.Pixmap(self.drawable, winw, winh)
        c.draw_text(drawable=3Dpixmap, x=3D0, y=3D0)

        gc =3D pixmap.new_gc()
        if 0:
            # These lines test that the pixmap was drawn to ok
            pixbuf =3D gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8, w, h)
            pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(),
                                     0, 0, 0, 0, w, h)
            pixbuf.render_to_drawable(self.drawable, gc, 0, 0, 0, 0, w, h, =
0, 0, 0)

        imageIn =3D pixmap.get_image(x=3D0, y=3D0, width=3Dw, height=3Dh)
        imageOut =3D gtk.gdk.Image(type=3D0,
                                 width=3Dh, height=3Dw)
        for i in range(w):
            for j in range(h):
                imageOut.put_pixel(j, i, imageIn.get_pixel(w-i-1,j) )

        pixbuf =3D gtk.gdk.Pixbuf(colorspace=3Dgtk.gdk.COLORSPACE_RGB,
                                has_alpha=3D0, bits_per_sample=3D8,
                                width=3Dh, height=3Dw)
        pixbuf.get_from_image(src=3DimageOut, cmap=3DimageIn.get_colormap(),
                              src_x=3D0, src_y=3D0, dest_x=3D0, dest_y=3D0,
                              width=3Dh, height=3Dw)
        pixbuf.render_to_drawable(self.drawable, gc,
                                  src_x=3D0, src_y=3D0,
                                  dest_x=3D50, dest_y=3D100,
                                  width=3Dh, height=3Dw,
                                  dither=3D0, x_dither=3D0, y_dither=3D0)

c =3D C('Some text')

da =3D gtk.DrawingArea()
da.connect('realize', c.realize)

vbox.pack_start(da, gtk.TRUE, gtk.TRUE)

hbox =3D gtk.HBox()
vbox.pack_start(hbox, gtk.FALSE, gtk.FALSE)

button =3D gtk.Button('Draw')
button.connect('clicked', lambda b: c.draw_text())
hbox.pack_start(button, gtk.TRUE, gtk.TRUE)

button =3D gtk.Button('Rotate')
button.connect('clicked', lambda b: c.draw_text_rotated())
hbox.pack_start(button, gtk.TRUE, gtk.TRUE)

button =3D gtk.Button('Quit')
button.connect('clicked', lambda b: gtk.mainquit())
hbox.pack_start(button, gtk.TRUE, gtk.TRUE)


Jean-Baptiste.Cazier at decode.is

Department of Statistics
deCODE genetics     Sturlugata,8
570 2993          101 Reykjavík

More information about the pygtk mailing list