summaryrefslogtreecommitdiff
path: root/examples/demo/demos/rotatedtext.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/demo/demos/rotatedtext.py')
-rw-r--r--examples/demo/demos/rotatedtext.py191
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()