PyCairo指南的這個部分,咱們將與文本打交道。 python
在第一個例子中,咱們將在窗口中顯示一些歌詞。 web
def on_draw(self, wdith, cr): 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")
這段code中,咱們顯示了來自於Natasha Bedingfields Soulmate這首歌的歌詞的一部分。 編程
cr.select_font_face("Purisa", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
此處咱們先則了font face。這個方法接收三個參數,font family,font slant和font weight. app
cr.set_font_size(13)
此處咱們指定了字體大小。 字體
cr.move_to(20, 30) cr.show_text("Most relationships seem so transitory")
咱們經過爲文本指定位置並調用show_text()方法來將文本顯示在窗口中。 ui
Figure: Soulmate
spa
接下來咱們將演示如何在窗口中居中顯示文字。 code
def on_draw(self, wdith, cr): 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")
這段code將一段文字放在窗口的中心。即便調整了窗口的大小,它也依然會位於中心。 索引
w, h = self.get_size()
爲了使文字位於窗口的中心,則須要獲取窗口的客戶端區域的大小。 ip
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")
咱們獲取extents,這是一些用來描述文字的數字。咱們的例子須要文字的寬度。
cr.move_to(w/2 - width/2, h/2) cr.show_text("ZetCode")
咱們將文字定位在窗口的中間,並用show_text()來顯示它。
Figure: Centered text
如今咱們將在窗口中建立一個陰影文字。
def on_draw(self, wdith, cr): 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) 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")
第二段文字用某種灰色墨水來畫。它像右邊和下邊移開了3px。
Figure: Shaded text
下面的例子將建立一個很棒的效果。咱們將用一些線性漸變來填充文字。
def on_draw(self, wdith, cr): 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) cr.paint()
爲了使它的視覺效果更吸引人,咱們用深灰色來畫背景。
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()
文字被顯示於窗口中。咱們用漸變做爲source來畫。
Figure: Text filled with gradient
在這個效果中,咱們將逐字符的來顯示一段文字。字符的顯示將有些延時。
#!/usr/bin/python ''' ZetCode PyCairo tutorial This program shows text letter by letter. author: Jan Bodnar website: zetcode.com last edited: August 2012 ''' import gtk, glib import cairo class cv(object): SPEED = 800 TEXT_SIZE = 35 COUNT_MAX = 8 class MainWindow(gtk.Window): def __init__(self): super(self.__class__, self).__init__() self.init_ui() self.init_vars() def init_ui(self): self.darea = gtk.DrawingArea() self.darea.connect("expose_event", self.expose) 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.WIN_POS_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 expose(self, widget, event): self.context = widget.window.cairo_create() self.on_draw(350, self.context) def on_draw(self, wdith, cr): cr.select_font_face("Serif", 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 + 6 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(): window = MainWindow() gtk.main() if __name__ == "__main__": main()
在咱們的例子中,咱們以某種延時,逐個字符的在GTK窗口中顯示 "ZetCode" 字串。
self.text = ["Z", "e", "t", "C", "o", "d", "e"]
這是將在窗口中顯示的字符的列表。
cr.select_font_face("Serif", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
咱們選擇一個Courier font face,bold weight。
for i in range(self.count): (x, y, width, height, dx, dy) = cr.text_extents(self.text[i]) dis += width + 6 cr.move_to(dis + 30, 50) cr.show_text(self.text[i])
此處咱們逐個字符的來畫。咱們獲取每個字符的寬度,而後計算沿x軸須要移動的距離。
Figure: Letter by letter
show_text()方法只適合簡單的文本渲染。Cairo開發者稱它爲一個玩具方法。更專業的文本渲染經過glyphs來完成。一個glyph是爲一個字符提供一個外形的圖形符號。一個字符提供一個含義,它能夠有多個glyphs。一個字符沒有固有的外觀。一個glyph沒有固定的含義。
注意,就文本而言,許多通用編程須要Pango庫來定址。
def on_draw(self, wdith, cr): 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)
這段code顯示了一個選中的字體中的700個glyphs。
glyphs = []
glyphs列表將存儲三個整數值。第一個值是glyph在選中的字體類型中的索引。第二個和第三個是glyph的x,y位置。
cr.show_glyphs(glyphs)
show_glyphs()方法在窗口中顯示glyphs。
Figure: Glyphs
本章討論了PyCairo中的文本。