diff options
Diffstat (limited to 'examples/demo/demos/rotatedtext.py')
-rw-r--r-- | examples/demo/demos/rotatedtext.py | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/examples/demo/demos/rotatedtext.py b/examples/demo/demos/rotatedtext.py new file mode 100644 index 0000000..4dac189 --- /dev/null +++ b/examples/demo/demos/rotatedtext.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python +# -*- Mode: Python; py-indent-offset: 4 -*- +# vim: tabstop=4 shiftwidth=4 expandtab +# +# Copyright (C) 2010 Red Hat, Inc., John (J5) Palmieri <johnp@redhat.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 +# USA + +title = "Rotated Text" +description = """This demo shows how to use PangoCairo to draw rotated and +transformed text. The right pane shows a rotated GtkLabel widget. In both +cases, a custom PangoCairo shape renderer is installed to draw a red heard using +cairo drawing operations instead of the Unicode heart character. +""" + +from gi.repository import Gtk, Pango, PangoCairo, Gdk +import cairo +import math + + +UTF8_TEXT = u"I ♥ GTK" +HEART = u"♥" +BYTES_TEXT = UTF8_TEXT.encode("utf-8") +BYTES_HEART = HEART.encode("utf-8") + + +class RotatedTextApp: + RADIUS = 150 + N_WORDS = 5 + FONT = "Serif 18" + + def __init__(self): + + white = Gdk.RGBA() + white.red = 1.0 + white.green = 1.0 + white.blue = 1.0 + white.alpha = 1.0 + + self.window = Gtk.Window(title="Rotated Text") + self.window.set_default_size(4 * self.RADIUS, 2 * self.RADIUS) + self.window.connect('destroy', Gtk.main_quit) + + box = Gtk.HBox() + box.set_homogeneous(True) + self.window.add(box) + + # add a drawing area + da = Gtk.DrawingArea() + box.add(da) + + # override the background color from the theme + da.override_background_color(0, white) + + da.connect('draw', self.rotated_text_draw) + + label = Gtk.Label(label=UTF8_TEXT) + box.add(label) + label.set_angle(45) + + # Setup some fancy stuff on the label + layout = label.get_layout() + + PangoCairo.context_set_shape_renderer(layout.get_context(), + self.fancy_shape_renderer, + None) + attrs = self.create_fancy_attr_list_for_layout(layout) + label.set_attributes(attrs) + + self.window.show_all() + + def fancy_shape_renderer(self, cairo_ctx, attr, do_path): + x, y = cairo_ctx.get_current_point() + cairo_ctx.translate(x, y) + + cairo_ctx.scale(float(attr.inc_rect.width) / Pango.SCALE, + float(attr.inc_rect.height) / Pango.SCALE) + + if int(attr.data) == 0x2665: # U+2665 BLACK HEART SUIT + cairo_ctx.move_to(0.5, 0.0) + cairo_ctx.line_to(0.9, -0.4) + cairo_ctx.curve_to(1.1, -0.8, 0.5, -0.9, 0.5, -0.5) + cairo_ctx.curve_to(0.5, -0.9, -0.1, -0.8, 0.1, -0.4) + cairo_ctx.close_path() + + if not do_path: + cairo_ctx.set_source_rgb(1.0, 0.0, 0.0) + cairo_ctx.fill() + + def create_fancy_attr_list_for_layout(self, layout): + pango_ctx = layout.get_context() + metrics = pango_ctx.get_metrics(layout.get_font_description(), + None) + ascent = metrics.get_ascent() + + logical_rect = Pango.Rectangle() + logical_rect.x = 0 + logical_rect.width = ascent + logical_rect.y = -ascent + logical_rect.height = ascent + + # Set fancy shape attributes for all hearts + attrs = Pango.AttrList() + + # FIXME: attr_shape_new_with_data isn't introspectable + ''' + ink_rect = logical_rect + p = BYTES_TEXT.find(BYTES_HEART) + while (p != -1): + attr = Pango.attr_shape_new_with_data(ink_rect, + logical_rect, + ord(HEART), + None) + attr.start_index = p + attr.end_index = p + len(BYTES_HEART) + p = UTF8_TEXT.find(HEART, attr.end_index) + + attrs.insert(attr) + ''' + return attrs + + def rotated_text_draw(self, da, cairo_ctx): + # Create a cairo context and set up a transformation matrix so that the user + # space coordinates for the centered square where we draw are [-RADIUS, RADIUS], + # [-RADIUS, RADIUS]. + # We first center, then change the scale. + width = da.get_allocated_width() + height = da.get_allocated_height() + device_radius = min(width, height) / 2.0 + cairo_ctx.translate( + device_radius + (width - 2 * device_radius) / 2, + device_radius + (height - 2 * device_radius) / 2) + cairo_ctx.scale(device_radius / self.RADIUS, + device_radius / self.RADIUS) + + # Create a subtle gradient source and use it. + pattern = cairo.LinearGradient(-self.RADIUS, -self.RADIUS, self.RADIUS, self.RADIUS) + pattern.add_color_stop_rgb(0.0, 0.5, 0.0, 0.0) + pattern.add_color_stop_rgb(1.0, 0.0, 0.0, 0.5) + cairo_ctx.set_source(pattern) + + # Create a PangoContext and set up our shape renderer + context = da.create_pango_context() + PangoCairo.context_set_shape_renderer(context, + self.fancy_shape_renderer, + None) + + # Create a PangoLayout, set the text, font, and attributes */ + layout = Pango.Layout(context=context) + layout.set_text(UTF8_TEXT, -1) + desc = Pango.FontDescription(self.FONT) + layout.set_font_description(desc) + + attrs = self.create_fancy_attr_list_for_layout(layout) + layout.set_attributes(attrs) + + # Draw the layout N_WORDS times in a circle */ + for i in range(self.N_WORDS): + # Inform Pango to re-layout the text with the new transformation matrix + PangoCairo.update_layout(cairo_ctx, layout) + + width, height = layout.get_pixel_size() + cairo_ctx.move_to(-width / 2, -self.RADIUS * 0.9) + PangoCairo.show_layout(cairo_ctx, layout) + + # Rotate for the next turn + cairo_ctx.rotate(math.pi * 2 / self.N_WORDS) + + return False + + +def main(demoapp=None): + RotatedTextApp() + Gtk.main() + + +if __name__ == '__main__': + main() |