原文: https://zetcode.com/gfx/pycairo/text/

在 PyCairo 教程的这一部分中,我们将处理文本。

灵魂伴侣

在第一个示例中,我们将在窗口上显示一些歌词。

  1. def on_draw(self, wid, cr):
  2. cr.set_source_rgb(0.1, 0.1, 0.1)
  3. cr.select_font_face("Purisa", cairo.FONT_SLANT_NORMAL,
  4. cairo.FONT_WEIGHT_NORMAL)
  5. cr.set_font_size(13)
  6. cr.move_to(20, 30)
  7. cr.show_text("Most relationships seem so transitory")
  8. cr.move_to(20, 60)
  9. cr.show_text("They're all good but not the permanent one")
  10. cr.move_to(20, 120)
  11. cr.show_text("Who doesn't long for someone to hold")
  12. cr.move_to(20, 150)
  13. cr.show_text("Who knows how to love without being told")
  14. cr.move_to(20, 180)
  15. cr.show_text("Somebody tell me why I'm on my own")
  16. cr.move_to(20, 210)
  17. cr.show_text("If there's a soulmate for everyone")

在此代码中,我们显示了 Natasha Bedingfields Soulmate 歌曲的部分歌词。

  1. cr.select_font_face("Purisa", cairo.FONT_SLANT_NORMAL,
  2. cairo.FONT_WEIGHT_NORMAL)

在这里,我们选择字体。 该方法采用三个参数:字体系列,字体倾斜度和字体粗细。

  1. cr.set_font_size(13)

在这里,我们指定字体大小。

  1. cr.move_to(20, 30)
  2. cr.show_text("Most relationships seem so transitory")

我们通过指定文本的位置并调用show_text()方法在窗口上显示文本。

PyCairo 中的文字 - 图1

图:灵魂伴侣

居中文字

接下来,我们将展示如何在窗口上居中放置文本。

  1. def on_draw(self, wid, cr):
  2. w, h = self.get_size()
  3. cr.select_font_face("Courier", cairo.FONT_SLANT_NORMAL,
  4. cairo.FONT_WEIGHT_BOLD)
  5. cr.set_font_size(60)
  6. (x, y, width, height, dx, dy) = cr.text_extents("ZetCode")
  7. cr.move_to(w/2 - width/2, h/2)
  8. cr.show_text("ZetCode")

该代码将使文本在窗口上居中。 即使我们调整窗口大小,它仍然居中。

  1. w, h = self.get_size()

为了使文本在窗口上居中,有必要获取窗口工作区的大小。

  1. cr.select_font_face("Courier", cairo.FONT_SLANT_NORMAL,
  2. cairo.FONT_WEIGHT_BOLD)
  3. cr.set_font_size(60)

我们选择要显示的字体及其大小。

  1. (x, y, width, height, dx, dy) = cr.text_extents("ZetCode")

我们得到了文本范围。 这些是描述文字的数字。 我们的示例需要文本的宽度。

  1. cr.move_to(w/2 - width/2, h/2)
  2. cr.show_text("ZetCode")

我们将文本放置在窗口的中间,并使用show_text()方法显示它。

PyCairo 中的文字 - 图2

图:居中文本

带阴影的文字

现在,我们将在窗口上创建一个阴影文本。

  1. def on_draw(self, wid, cr):
  2. cr.select_font_face("Serif", cairo.FONT_SLANT_NORMAL,
  3. cairo.FONT_WEIGHT_BOLD)
  4. cr.set_font_size(50)
  5. cr.set_source_rgb(0, 0, 0)
  6. cr.move_to(40, 60)
  7. cr.show_text("ZetCode")
  8. cr.set_source_rgb(0.5, 0.5, 0.5)
  9. cr.move_to(43, 63)
  10. cr.show_text("ZetCode")

要创建阴影,我们将文本绘制两次。 以不同的颜色。 第二个文本向右和向下移动一点。

  1. cr.set_source_rgb(0, 0, 0)
  2. cr.move_to(40, 60)
  3. cr.show_text("ZetCode")

第一个文本用黑色墨水绘制。 它充当阴影。

  1. cr.set_source_rgb(0.5, 0.5, 0.5)
  2. cr.move_to(43, 63)
  3. cr.show_text("ZetCode")

第二个文本用灰色墨水绘制。 它向右和向下移动了 3px。

PyCairo 中的文字 - 图3

图:阴影文本

渐变填充文本

以下示例将产生很好的效果。 我们将使用一些线性渐变填充文本。

  1. def on_draw(self, wid, cr):
  2. cr.set_source_rgb(0.2, 0.2, 0.2)
  3. cr.paint()
  4. h = 90
  5. cr.select_font_face("Serif", cairo.FONT_SLANT_ITALIC,
  6. cairo.FONT_WEIGHT_BOLD)
  7. cr.set_font_size(h)
  8. lg = cairo.LinearGradient(0, 15, 0, h*0.8)
  9. lg.set_extend(cairo.EXTEND_REPEAT)
  10. lg.add_color_stop_rgb(0.0, 1, 0.6, 0)
  11. lg.add_color_stop_rgb(0.5, 1, 0.3, 0)
  12. cr.move_to(15, 80)
  13. cr.text_path("ZetCode")
  14. cr.set_source(lg)
  15. cr.fill()

我们在充满线性渐变的窗口上绘制文本。 颜色是一些橙色。

  1. cr.set_source_rgb(0.2, 0.2, 0.2)
  2. cr.paint()

为了使其更具视觉吸引力,我们将背景涂成深灰色。

  1. lg = cairo.LinearGradient(0, 15, 0, h*0.8)
  2. lg.set_extend(cairo.EXTEND_REPEAT)
  3. lg.add_color_stop_rgb(0.0, 1, 0.6, 0)
  4. lg.add_color_stop_rgb(0.5, 1, 0.3, 0)

将创建线性渐变。

  1. cr.move_to(15, 80)
  2. cr.text_path("ZetCode")
  3. cr.set_source(lg)
  4. cr.fill()

文本显示在窗口上。 我们使用渐变作为绘画源。

PyCairo 中的文字 - 图4

图:用渐变填充的文本

逐个字母

为此,我们将逐个字母显示一个文本。 这些字母将被绘制得有些延迟。

  1. #!/usr/bin/python
  2. '''
  3. ZetCode PyCairo tutorial
  4. This program shows text letter by
  5. letter.
  6. author: Jan Bodnar
  7. website: zetcode.com
  8. last edited: August 2012
  9. '''
  10. from gi.repository import Gtk, GLib
  11. import cairo
  12. class cv(object):
  13. SPEED = 800
  14. TEXT_SIZE = 35
  15. COUNT_MAX = 8
  16. class Example(Gtk.Window):
  17. def __init__(self):
  18. super(Example, self).__init__()
  19. self.init_ui()
  20. self.init_vars()
  21. def init_ui(self):
  22. self.darea = Gtk.DrawingArea()
  23. self.darea.connect("draw", self.on_draw)
  24. self.add(self.darea)
  25. GLib.timeout_add(cv.SPEED, self.on_timer)
  26. self.set_title("Letter by letter")
  27. self.resize(350, 200)
  28. self.set_position(Gtk.WindowPosition.CENTER)
  29. self.connect("delete-event", Gtk.main_quit)
  30. self.show_all()
  31. def init_vars(self):
  32. self.timer = True
  33. self.count = 0
  34. self.text = [ "Z", "e", "t", "C", "o", "d", "e" ]
  35. def on_timer(self):
  36. if not self.timer: return False
  37. self.darea.queue_draw()
  38. return True
  39. def on_draw(self, wid, cr):
  40. cr.select_font_face("Courier", cairo.FONT_SLANT_NORMAL,
  41. cairo.FONT_WEIGHT_BOLD)
  42. cr.set_font_size(cv.TEXT_SIZE)
  43. dis = 0
  44. for i in range(self.count):
  45. (x, y, width, height, dx, dy) = cr.text_extents(self.text[i])
  46. dis += width + 2
  47. cr.move_to(dis + 30, 50)
  48. cr.show_text(self.text[i])
  49. self.count += 1
  50. if self.count == cv.COUNT_MAX:
  51. self.timer = False
  52. self.count = 0
  53. def main():
  54. app = Example()
  55. Gtk.main()
  56. if __name__ == "__main__":
  57. main()

在我们的示例中,我们将在 GTK 窗口上逐个字母地绘制"ZetCode"字符串,并稍作延迟。

  1. self.text = [ "Z", "e", "t", "C", "o", "d", "e" ]

这是要在窗口上显示的字母列表。

  1. cr.select_font_face("Courier", cairo.FONT_SLANT_NORMAL,
  2. cairo.FONT_WEIGHT_BOLD)

我们选择粗体的 Courier 字体。

  1. for i in range(self.count):
  2. (x, y, width, height, dx, dy) = cr.text_extents(self.text[i])
  3. dis += width + 2
  4. cr.move_to(dis + 30, 50)
  5. cr.show_text(self.text[i])

在这里,我们逐个字母地绘制文本。 我们获得每个字母的宽度并计算 x 轴上的距离。

字形

show_text()方法仅适用于简单的文本呈现。 Cairo 开发者将其称为玩具方法。 使用字形可以完成更专业的文本渲染。 标志符号是图形符号,可提供字符形式。 字符提供含义。 它可以有多个字形。 角色没有内在的外观。 字形没有内在的含义。

请注意,Pango 库解决了许多常见的编程要求,包括文本。

  1. def on_draw(self, wid, cr):
  2. cr.select_font_face("Serif", cairo.FONT_SLANT_NORMAL,
  3. cairo.FONT_WEIGHT_NORMAL)
  4. cr.set_font_size(13)
  5. glyphs = []
  6. index = 0
  7. for y in range(20):
  8. for x in range(35):
  9. glyphs.append((index, x*15 + 20, y*18 + 20))
  10. index += 1
  11. cr.show_glyphs(glyphs)

该代码显示了所选字体的 700 个字形。

  1. glyphs = []

字形列表将存储三个整数值。 第一个值是字形到所选字体类型的索引。 第二和第三值是字形的 x,y 位置。

  1. cr.show_glyphs(glyphs)

show_glyphs()方法在窗口上显示字形。

PyCairo 中的文字 - 图5

图:字形

本章介绍了 PyCairo 中的文本。