python-lottie  0.7.0+dev418bd09
A framework to work with lottie files and telegram animated stickers (tgs)
fancy_text.py
Go to the documentation of this file.
1 import re
2 
3 from .font import FontStyle
4 from ..nvector import NVector
5 from ..parsers.svg.importer import parse_color
6 from ..objects.shapes import Group, Fill
7 
8 
9 class FancyStyle:
10  def __init__(self, font: FontStyle, color: NVector, font_size: float, offset: NVector, scale: NVector, rotation: float):
11  self.fontfont = font
12  self.colorcolor = color.clone()
13  self.font_sizefont_size = font_size
14  self.offsetoffset = offset.clone()
15  self.scalescale = scale.clone()
16  self.rotationrotation = rotation
17 
18  def clone(self):
19  return FancyStyle(self.fontfont, self.colorcolor, self.font_sizefont_size, self.offsetoffset, self.scalescale, self.rotationrotation)
20 
21  def render(self, text, pos, start_x):
22  pos += self.offsetoffset
23  g = self.fontfont.renderer.render(text, self.font_sizefont_size, pos, True, start_x)
24  g.add_shape(Fill(self.colorcolor))
25  if self.scalescale.x != 1 or self.scalescale.y != 1 or self.rotationrotation != 0:
26  center = g.bounding_box().center()
27  g.transform.anchor_point.value = center
28  g.transform.position.value += center
29  g.transform.scale.value = self.scalescale * 100
30  g.transform.rotation.value = self.rotationrotation
31  pos -= self.offsetoffset
32  return g
33 
34 
36  _regex = re.compile(r'\\([a-z0-9]+)(?:\{([^}]*)\})?')
37 
38  def __init__(self, font: FontStyle, default_color: NVector, font_size: float):
39  self.fontfont = font
40  self.font_sizefont_size = font_size
41  self.default_colordefault_color = default_color
42  self.groupsgroups = []
43 
44  @staticmethod
45  def _int_arg(value, default=0):
46  try:
47  return float(value)
48  except (ValueError, TypeError):
49  return default
50 
51  def render(self, text: str, pos: NVector = None):
52  if pos is None:
53  pos = NVector(0, 0)
54 
55  line_start = pos.x
56  default_style = FancyStyle(self.fontfont, self.default_colordefault_color, self.font_sizefont_size, NVector(0, 0), NVector(1, 1), 0)
57  style = default_style.clone()
58  container = Group()
59  last_pos = 0
60 
61  for match in self._regex_regex.finditer(text):
62  prev_text = text[last_pos:match.start()]
63  last_pos = match.end()
64  if prev_text:
65  container.insert_shape(0, style.render(prev_text, pos, line_start))
66 
67  style = style.clone()
68 
69  command = match.group(1)
70  arg = match.group(2)
71 
72  if command == "color":
73  if arg:
74  style.color = parse_color(arg, self.default_colordefault_color)
75  else:
76  style.color = self.default_colordefault_color
77  elif command == "huge":
78  style.font_size = self.font_sizefont_size * 2
79  elif command == "large":
80  style.font_size = self.font_sizefont_size * 1.5
81  elif command == "normal":
82  style.font_size = self.font_sizefont_size
83  elif command == "small":
84  style.font_size = self.font_sizefont_size / 1.5
85  elif command == "tiny":
86  style.font_size = self.font_sizefont_size / 2
87  elif command == "super":
88  style.offset.y -= self.font_sizefont_size / 2
89  elif command == "sub":
90  style.offset.y += self.font_sizefont_size / 2
91  elif command == "center":
92  style.offset.y = 0
93  elif command == "clear":
94  style = default_style.clone()
95  elif command == "flip":
96  style.scale.x *= -1
97  elif command == "vflip":
98  style.scale.y *= -1
99  elif command == "r":
100  pos.x = line_start
101  elif command == "n":
102  pos.x = line_start
103  pos.y += self.fontfont.line_height
104  elif command == "hspace":
105  pos.x += self._int_arg_int_arg(arg)
106  elif command == "rot":
107  style.rotation = self._int_arg_int_arg(arg)
108 
109  # Eat space after no argument command
110  if arg is None and len(text) > last_pos and text[last_pos] == ' ':
111  last_pos += 1
112 
113  last_text = text[last_pos:]
114  if last_text:
115  container.insert_shape(0, style.render(last_text, pos, line_start))
116 
117  if len(container.shapes) > 1:
118  container.next_x = container.shapes[-2].next_x
119  else:
120  container.next_x = pos.x
121 
122  return container
123 
124 
125 def render_fancy_text(text: str, font: FontStyle, default_color: NVector, font_size: float, pos: NVector = None):
126  renderer = FancyTextRenderer(font, default_color, font_size)
127  return renderer.render(text, pos)
Solid fill color.
Definition: shapes.py:511
ShapeElement that can contain other shapes.
Definition: shapes.py:435
def render(self, text, pos, start_x)
Definition: fancy_text.py:21
def __init__(self, FontStyle font, NVector color, float font_size, NVector offset, NVector scale, float rotation)
Definition: fancy_text.py:10
def render(self, str text, NVector pos=None)
Definition: fancy_text.py:51
def __init__(self, FontStyle font, NVector default_color, float font_size)
Definition: fancy_text.py:38
def render_fancy_text(str text, FontStyle font, NVector default_color, float font_size, NVector pos=None)
Definition: fancy_text.py:125