例子
代码:
#!/usr/bin/env python3
# Created by xiaosanyu at 16/7/6
# section 142
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. """
import gi
gi.require_version("Gtk", "3.0")
gi.require_version('PangoCairo', '1.0')
from gi.repository import Gtk, Gdk, Pango, PangoCairo, GLib
import cairo
import sys
# Python 2 and 3 handle UTF8 differently
if sys.version_info < (3, 0):
BYTES_TEXT = "I \xe2\x99\xa5 GTK+"
UTF8_TEXT = unicode(BYTES_TEXT, 'UTF-8')
BYTES_HEART = "\xe2\x99\xa5"
HEART = unicode(BYTES_HEART, 'UTF-8')
else:
UTF8_TEXT = "I ♥ GTK+"
BYTES_TEXT = bytes(UTF8_TEXT, 'utf-8')
HEART = "♥"
BYTES_HEART = bytes(HEART, 'utf-8')
RADIUS = 150
N_WORDS = 5
class PyApp(Gtk.Window):
def __init__(self):
super(PyApp, self).__init__()
self.connect("destroy", Gtk.main_quit)
self.set_title("Rotated Text")
self.set_size_request(600, 300)
box = Gtk.Box()
box.set_homogeneous(True)
self.add(box)
# Add a drawing area
drawing_area = Gtk.DrawingArea()
box.add(drawing_area)
drawing_area.get_style_context().add_class(Gtk.STYLE_CLASS_VIEW)
drawing_area.connect("draw", self.rotated_text_draw)
# And a label
label = Gtk.Label()
label.set_markup(UTF8_TEXT.replace(HEART, "<span foreground=\"#FF0000\">%s</span>" % HEART))
box.add(label)
label.set_angle(45)
# Set up fancy stuff on the label
layout = label.get_layout()
PangoCairo.context_set_shape_renderer(layout.get_context(), self.fancy_shape_renderer, None)
self.show_all()
# this method not run??
def fancy_shape_renderer(self, cr, attr, do_path, data):
x, y = cr.get_current_point()
cr.translate(x, y)
cr.scale(attr.ink_rect.width, # PANGO_SCALE,
attr.ink_rect.height # PANGO_SCALE
)
if attr.data == 0x2665: # U+2665 BLACK HEART SUIT
cr.move_to(0.5, 0)
cr.line_to(0.9, -0.4)
cr.curve_to(1.1, -0.8, 0.5, -.09, 0.5, -0.5)
cr.curve_to(0.5, -0.9, -0.1, -.08, 0.1, -0.4)
cr.close_path()
if not do_path:
cr.set_source_rgb(1., 0., 0.)
cr.fill()
def rotated_text_draw(self, widget, cr):
# 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 = widget.get_allocated_width()
height = widget.get_allocated_height()
device_radius = min(width, height) / 2
cr.translate(device_radius + (width - 2 * device_radius) / 2,
device_radius + (height - 2 * device_radius) / 2)
cr.scale(device_radius / RADIUS, device_radius / RADIUS)
# Create and a subtle gradient source and use it.
pattern = cairo.LinearGradient(-RADIUS, -RADIUS, RADIUS, RADIUS)
pattern.add_color_stop_rgb(0, 0.5, 0, 0)
pattern.add_color_stop_rgb(1, 0, 0, 0.5)
cr.set_source(pattern)
# Create a PangoContext and set up our shape renderer
context = widget.create_pango_context()
PangoCairo.context_set_shape_renderer(context, self.fancy_shape_renderer)
# Create a PangoLayout, set the text, font, and attributes
layout = Pango.Layout.new(context)
layout.set_text(UTF8_TEXT, -1)
desc = Pango.FontDescription.from_string("Serif 18")
layout.set_font_description(desc)
# Draw the layout N_WORDS times in a circle
for i in range(N_WORDS):
# Inform Pango to re-layout the text with the new transformation matrix
layout.set_markup(layout.get_text().replace(HEART, "<span foreground=\"#FF0000\">%s</span>" % HEART), -1)
PangoCairo.update_layout(cr, layout)
width, height = layout.get_pixel_size()
cr.move_to(- width / 2, - RADIUS * .9)
PangoCairo.show_layout(cr, layout)
# Rotate for the next turn
cr.rotate(GLib.PI * 2 / N_WORDS)
return False
def main():
PyApp()
Gtk.main()
if __name__ == '__main__':
main()