Text in PyCairo
In this part of the PyCairo tutorial, we will work with text.Soulmate
In the first example, we will display some lyrics on a window.def on_draw(self, wid, cr):In this code, we display part of the lyrics from the Natasha Bedingfields Soulmate song.
cr.set_source_rgb(0.1, 0.1, 0.1)
cr.select_font_face("Purisa", cairo.FONT_SLANT_NORMAL,
cairo.FONT_WEIGHT_NORMAL)
cr.set_font_size(13)
cr.move_to(20, 30)
cr.show_text("Most relationships seem so transitory")
cr.move_to(20, 60)
cr.show_text("They're all good but not the permanent one")
cr.move_to(20, 120)
cr.show_text("Who doesn't long for someone to hold")
cr.move_to(20, 150)
cr.show_text("Who knows how to love without being told")
cr.move_to(20, 180)
cr.show_text("Somebody tell me why I'm on my own")
cr.move_to(20, 210)
cr.show_text("If there's a soulmate for everyone")
cr.select_font_face("Purisa", cairo.FONT_SLANT_NORMAL,Here we select the font face. The method takes three parameters, the font family, font slant and the font weight.
cairo.FONT_WEIGHT_NORMAL)
cr.set_font_size(13)Here we specify the font size.
cr.move_to(20, 30)We display the text on the window by specifying the position of the text and calling the
cr.show_text("Most relationships seem so transitory")
show_text()
method. Figure: Soulmate
Centered text
Next we will show, how to center text on the window.def on_draw(self, wid, cr):The code will center a text on the window. It remains centered, even if we resize the window.
w, h = self.get_size()
cr.select_font_face("Courier", cairo.FONT_SLANT_NORMAL,
cairo.FONT_WEIGHT_BOLD)
cr.set_font_size(60)
(x, y, width, height, dx, dy) = cr.text_extents("ZetCode")
cr.move_to(w/2 - width/2, h/2)
cr.show_text("ZetCode")
w, h = self.get_size()To center a text on the window, it is necessary to get the size of the client area of the window.
cr.select_font_face("Courier", cairo.FONT_SLANT_NORMAL,We select a font and its size to be displayed.
cairo.FONT_WEIGHT_BOLD)
cr.set_font_size(60)
(x, y, width, height, dx, dy) = cr.text_extents("ZetCode")We get the text extents. These are some numbers that describe the text. We need the width of the text for our example.
cr.move_to(w/2 - width/2, h/2)We position the text into the middle of the window and show it using the
cr.show_text("ZetCode")
show_text()
method. Shaded text
Now we will create a shaded text on the window.def on_draw(self, wid, cr):To create a shade, we draw the text twice. In different colours. The second text is moved a bit to the right and bottom.
cr.select_font_face("Serif", cairo.FONT_SLANT_NORMAL,
cairo.FONT_WEIGHT_BOLD)
cr.set_font_size(50)
cr.set_source_rgb(0, 0, 0)
cr.move_to(40, 60)
cr.show_text("ZetCode")
cr.set_source_rgb(0.5, 0.5, 0.5)
cr.move_to(43, 63)
cr.show_text("ZetCode")
cr.set_source_rgb(0, 0, 0)The first text is drawn in black ink. It serves as a shade.
cr.move_to(40, 60)
cr.show_text("ZetCode")
cr.set_source_rgb(0.5, 0.5, 0.5)The second text is drawn in some gray ink. It is moved by 3px to the right and to the bottom.
cr.move_to(43, 63)
cr.show_text("ZetCode")
Text filled with gradient
The following example will create a nice effect. We will fill a text with some linear gradient.def on_draw(self, wid, cr):We draw a text on the window filled with a linear gradient. The colours are some orange colours.
cr.set_source_rgb(0.2, 0.2, 0.2)
cr.paint()
h = 90
cr.select_font_face("Serif", cairo.FONT_SLANT_ITALIC,
cairo.FONT_WEIGHT_BOLD)
cr.set_font_size(h)
lg = cairo.LinearGradient(0, 15, 0, h*0.8)
lg.set_extend(cairo.EXTEND_REPEAT)
lg.add_color_stop_rgb(0.0, 1, 0.6, 0)
lg.add_color_stop_rgb(0.5, 1, 0.3, 0)
cr.move_to(15, 80)
cr.text_path("ZetCode")
cr.set_source(lg)
cr.fill()
cr.set_source_rgb(0.2, 0.2, 0.2)To make it more visually appealing, we paint the background in dark gray colour.
cr.paint()
lg = cairo.LinearGradient(0, 15, 0, h*0.8)The linear gradient is created.
lg.set_extend(cairo.EXTEND_REPEAT)
lg.add_color_stop_rgb(0.0, 1, 0.6, 0)
lg.add_color_stop_rgb(0.5, 1, 0.3, 0)
cr.move_to(15, 80)The text is displayed on the window. We use the gradient as a source for painting.
cr.text_path("ZetCode")
cr.set_source(lg)
cr.fill()
Letter by letter
In this effect, we will display a text letter by letter. The letters will be drawn with some delay.#!/usr/bin/pythonIn our example, we will draw the "ZetCode" string on the GTK window letter by letter with some delay.
'''
ZetCode PyCairo tutorial
This program shows text letter by
letter.
author: Jan Bodnar
website: zetcode.com
last edited: August 2012
'''
from gi.repository import Gtk, GLib
import cairo
class cv(object):
SPEED = 800
TEXT_SIZE = 35
COUNT_MAX = 8
class Example(Gtk.Window):
def __init__(self):
super(Example, self).__init__()
self.init_ui()
self.init_vars()
def init_ui(self):
self.darea = Gtk.DrawingArea()
self.darea.connect("draw", self.on_draw)
self.add(self.darea)
GLib.timeout_add(cv.SPEED, self.on_timer)
self.set_title("Letter by letter")
self.resize(350, 200)
self.set_position(Gtk.WindowPosition.CENTER)
self.connect("delete-event", Gtk.main_quit)
self.show_all()
def init_vars(self):
self.timer = True
self.count = 0
self.text = [ "Z", "e", "t", "C", "o", "d", "e" ]
def on_timer(self):
if not self.timer: return False
self.darea.queue_draw()
return True
def on_draw(self, wid, cr):
cr.select_font_face("Courier", cairo.FONT_SLANT_NORMAL,
cairo.FONT_WEIGHT_BOLD)
cr.set_font_size(cv.TEXT_SIZE)
dis = 0
for i in range(self.count):
(x, y, width, height, dx, dy) = cr.text_extents(self.text[i])
dis += width + 2
cr.move_to(dis + 30, 50)
cr.show_text(self.text[i])
self.count += 1
if self.count == cv.COUNT_MAX:
self.timer = False
self.count = 0
def main():
app = Example()
Gtk.main()
if __name__ == "__main__":
main()
self.text = [ "Z", "e", "t", "C", "o", "d", "e" ]This is a list of letters to be displayed on the window.
cr.select_font_face("Courier", cairo.FONT_SLANT_NORMAL,We select a Courier font face in bold weight.
cairo.FONT_WEIGHT_BOLD)
for i in range(self.count):Here we draw the text letter by letter. We get the width of each of the letters and compute the disptance on the x axis.
(x, y, width, height, dx, dy) = cr.text_extents(self.text[i])
dis += width + 2
cr.move_to(dis + 30, 50)
cr.show_text(self.text[i])
Glyphs
Theshow_text()
method is only suitable for simple text rendering. Cairo developers call it a toy method. More professional text rendering is done with glyphs. A glyph is a graphic symbol which provides a form for a character. A character provides a meaning. It can have multiple glyphs. A character has no intrinsic appearance. A glyph has no intrinsic meaning. Note that many common programming requirements conserning text are addressed by the Pango library.
def on_draw(self, wid, cr):This code shows 700 glyphs of a chosen font.
cr.select_font_face("Serif", cairo.FONT_SLANT_NORMAL,
cairo.FONT_WEIGHT_NORMAL)
cr.set_font_size(13)
glyphs = []
index = 0
for y in range(20):
for x in range(35):
glyphs.append((index, x*15 + 20, y*18 + 20))
index += 1
cr.show_glyphs(glyphs)
glyphs = []The glyphs list will store three integer values. The first value is the index of the glyph to the chosen font type. The second and the third values are x, y positions of a glyph.
cr.show_glyphs(glyphs)The
show_glyphs()
method shows the glyphs on the window. Figure: Glyphs
This chapter covered text in PyCairo.
0 comments:
Post a Comment