From 77b94822df48c1ae5b11fc0d4cdc3eefc8b5eff4 Mon Sep 17 00:00:00 2001 From: Benjamin Hackl Date: Sat, 24 Oct 2020 19:08:38 +0200 Subject: [PATCH 1/7] rename PangoText --> Text --- manim/mobject/svg/text_mobject.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/manim/mobject/svg/text_mobject.py b/manim/mobject/svg/text_mobject.py index 906be3d176..875d94d9b7 100644 --- a/manim/mobject/svg/text_mobject.py +++ b/manim/mobject/svg/text_mobject.py @@ -533,10 +533,10 @@ def change_alignment_for_a_line(self, alignment, line_no): ) -class PangoText(SVGMobject): +class Text(SVGMobject): r"""Display (non-LaTeX) text rendered using `Pango `_. - PangoText objects behave like a :class:`.VGroup`-like iterable of all characters + Text objects behave like a :class:`.VGroup`-like iterable of all characters in the given text. In particular, slicing is possible. Parameters @@ -546,7 +546,7 @@ class PangoText(SVGMobject): Returns ------- - :class:`PangoText` + :class:`Text` The mobject like :class:`.VGroup`. Examples @@ -556,17 +556,17 @@ class PangoText(SVGMobject): class MultipleFonts(Scene): def construct(self): - morning = PangoText("வணக்கம்", font="sans-serif") - chin = PangoText( + morning = Text("வணக்கம்", font="sans-serif") + chin = Text( "見 角 言 谷 辛 辰 辵 邑 酉 釆 里!", t2c={"見 角 言": BLUE} ) # works same as ``Text``. - mess = PangoText("Multi-Language", style=BOLD) - russ = PangoText("Здравствуйте मस नम म ", font="sans-serif") - hin = PangoText("नमस्ते", font="sans-serif") - arb = PangoText( + mess = Text("Multi-Language", style=BOLD) + russ = Text("Здравствуйте मस नम म ", font="sans-serif") + hin = Text("नमस्ते", font="sans-serif") + arb = Text( "صباح الخير \n تشرفت بمقابلتك", font="sans-serif" ) # don't mix RTL and LTR languages nothing shows up then ;-) - japanese = PangoText("臂猿「黛比」帶著孩子", font="sans-serif") + japanese = Text("臂猿「黛比」帶著孩子", font="sans-serif") self.add(morning,chin,mess,russ,hin,arb,japanese) for i,mobj in enumerate(self.mobjects): mobj.shift(DOWN*(i-3)) @@ -577,16 +577,16 @@ def construct(self): class PangoRender(Scene): def construct(self): - morning = PangoText("வணக்கம்", font="sans-serif") + morning = Text("வணக்கம்", font="sans-serif") self.play(Write(morning)) self.wait(2) Tests ----- - Check that the creation of :class:`~.PangoText` works:: + Check that the creation of :class:`~.Text` works:: - >>> PangoText('The horse does not eat cucumber salad.') + >>> Text('The horse does not eat cucumber salad.') Text('The horse does not eat cucumber salad.') .. WARNING:: From 34cff63e9c869225735daeec895bc7f6232b2d12 Mon Sep 17 00:00:00 2001 From: Benjamin Hackl Date: Sat, 24 Oct 2020 19:09:04 +0200 Subject: [PATCH 2/7] add a logger info pointing to CairoText --- manim/mobject/svg/text_mobject.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/manim/mobject/svg/text_mobject.py b/manim/mobject/svg/text_mobject.py index 875d94d9b7..f9a8e2b7c1 100644 --- a/manim/mobject/svg/text_mobject.py +++ b/manim/mobject/svg/text_mobject.py @@ -622,6 +622,10 @@ def construct(self): } def __init__(self, text: str, **config): # pylint: disable=redefined-outer-name + logger.info( + "Text now uses Pango for rendering. " + "In case of problems, the old implementation is available as CairoText." + ) self.full2short(config) digest_config(self, config) self.original_text = text From e5b5185551f416df095bc0321e7513918a7f8d0e Mon Sep 17 00:00:00 2001 From: Benjamin Hackl Date: Sat, 24 Oct 2020 19:11:30 +0200 Subject: [PATCH 3/7] move examples from old to new Text class --- manim/mobject/svg/text_mobject.py | 109 ++++++++++++------------------ 1 file changed, 43 insertions(+), 66 deletions(-) diff --git a/manim/mobject/svg/text_mobject.py b/manim/mobject/svg/text_mobject.py index f9a8e2b7c1..6276f09f61 100644 --- a/manim/mobject/svg/text_mobject.py +++ b/manim/mobject/svg/text_mobject.py @@ -551,6 +551,49 @@ class Text(SVGMobject): Examples --------- + + .. manim:: Example1Text + :save_last_frame: + + class Example1Text(Scene): + def construct(self): + text = Text('Hello world').scale(3) + self.add(text) + + .. manim:: TextColorExample + :save_last_frame: + + class TextColorExample(Scene): + def construct(self): + text1 = Text('Hello world', color=BLUE).scale(3) + text2 = Text('Hello world', gradient=(BLUE, GREEN)).scale(3).next_to(text1, DOWN) + self.add(text1, text2) + + .. manim:: TextItalicAndBoldExample + :save_last_frame: + + class TextItalicAndBoldExample(Scene): + def construct(self): + text0 = Text('Hello world', slant=ITALIC) + text1 = Text('Hello world', t2s={'world':ITALIC}) + text2 = Text('Hello world', weight=BOLD) + text3 = Text('Hello world', t2w={'world':BOLD}) + self.add(text0,text1, text2,text3) + for i,mobj in enumerate(self.mobjects): + mobj.shift(DOWN*(i-1)) + + + .. manim:: TextMoreCustomization + :save_last_frame: + + class TextMoreCustomization(Scene): + def construct(self): + text1 = Text( + 'Google', + t2c={'[:1]': '#3174f0', '[1:2]': '#e53125', + '[2:3]': '#fbb003', '[3:4]': '#3174f0', + '[4:5]': '#269a43', '[5:]': '#e53125'}, size=1.2).scale(3) + self.add(text1) .. manim:: MultipleFonts :save_last_frame: @@ -877,69 +920,3 @@ def text2svg(self): surface.finish() return file_name - -class Text(CairoText): - """Display (non-LaTeX) text. - - Text objects behave like a :class:`.VGroup`-like iterable of all characters - in the given text. In particular, slicing is possible. - - Examples - -------- - .. manim:: Example1Text - :save_last_frame: - - class Example1Text(Scene): - def construct(self): - text = Text('Hello world').scale(3) - self.add(text) - - .. manim:: TextColorExample - :save_last_frame: - - class TextColorExample(Scene): - def construct(self): - text1 = Text('Hello world', color=BLUE).scale(3) - text2 = Text('Hello world', gradient=(BLUE, GREEN)).scale(3).next_to(text1, DOWN) - self.add(text1, text2) - - .. manim:: TextItalicAndBoldExample - :save_last_frame: - - class TextItalicAndBoldExample(Scene): - def construct(self): - text0 = Text('Hello world', slant=ITALIC) - text1 = Text('Hello world', t2s={'world':ITALIC}) - text2 = Text('Hello world', weight=BOLD) - text3 = Text('Hello world', t2w={'world':BOLD}) - self.add(text0,text1, text2,text3) - for i,mobj in enumerate(self.mobjects): - mobj.shift(DOWN*(i-1)) - - - .. manim:: TextMoreCustomization - :save_last_frame: - - class TextMoreCustomization(Scene): - def construct(self): - text1 = Text( - 'Google', - t2c={'[:1]': '#3174f0', '[1:2]': '#e53125', - '[2:3]': '#fbb003', '[3:4]': '#3174f0', - '[4:5]': '#269a43', '[5:]': '#e53125'}, size=1.2).scale(3) - self.add(text1) - - .. WARNING:: - - Using a :class:`.Transform` on text with leading whitespace can look - `weird `_. Consider using - :meth:`remove_invisible_chars` to resolve this issue. - - """ - - def __init__(self, text, **config): - logger.warning( - "Using Text uses Cairo Toy API to Render Text." - "Using PangoText is recommended and soon Text would point to PangoText" - ) - CairoText.__init__(self, text, **config) From cef29ca233f987c82f3078b0a1e4d2dd467f91e4 Mon Sep 17 00:00:00 2001 From: Benjamin Hackl Date: Sat, 24 Oct 2020 19:12:47 +0200 Subject: [PATCH 4/7] add a paragraph in the documentation outlining pango's capabilities --- manim/mobject/svg/text_mobject.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/manim/mobject/svg/text_mobject.py b/manim/mobject/svg/text_mobject.py index 6276f09f61..95724cff67 100644 --- a/manim/mobject/svg/text_mobject.py +++ b/manim/mobject/svg/text_mobject.py @@ -594,6 +594,10 @@ def construct(self): '[2:3]': '#fbb003', '[3:4]': '#3174f0', '[4:5]': '#269a43', '[5:]': '#e53125'}, size=1.2).scale(3) self.add(text1) + + As :class:`Text` uses Pango to render text, rendering non-English + characters is easily possible: + .. manim:: MultipleFonts :save_last_frame: From 12a33e4e6ea94d22625515024dc7c0ac2f14319c Mon Sep 17 00:00:00 2001 From: Benjamin Hackl Date: Sat, 24 Oct 2020 19:13:08 +0200 Subject: [PATCH 5/7] remove PangoText from __all__ --- manim/mobject/svg/text_mobject.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manim/mobject/svg/text_mobject.py b/manim/mobject/svg/text_mobject.py index 95724cff67..a73857c1a6 100644 --- a/manim/mobject/svg/text_mobject.py +++ b/manim/mobject/svg/text_mobject.py @@ -1,6 +1,6 @@ """Mobjects used for displaying (non-LaTeX) text.""" -__all__ = ["Text", "Paragraph", "PangoText", "CairoText"] +__all__ = ["Text", "Paragraph", "CairoText"] import copy From 247f888b394bc4c2c4a7a44bbcc32a934e4be9d5 Mon Sep 17 00:00:00 2001 From: Benjamin Hackl Date: Sat, 24 Oct 2020 19:13:26 +0200 Subject: [PATCH 6/7] fix pango tests --- tests/test_pango.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/test_pango.py b/tests/test_pango.py index c1ff76b36c..9d0f5e96c3 100644 --- a/tests/test_pango.py +++ b/tests/test_pango.py @@ -1,4 +1,4 @@ -"""Tests :class:`PangoText` by comparing SVG files created. +"""Tests :class:`Text` by comparing SVG files created. """ import os import re @@ -6,7 +6,7 @@ import cairocffi import pangocairocffi import pangocffi -from manim import START_X, START_Y, PangoText, SVGMobject +from manim import START_X, START_Y, Text, SVGMobject RTL_TEXT: str = """صباح الخير مرحبا جميعا""" @@ -27,9 +27,9 @@ def remove_last_M(file_path: str) -> None: # pylint: disable=invalid-name def compare_SVGObject_with_PangoText( # pylint: disable=invalid-name - text: PangoText, svg_path: str + text: Text, svg_path: str ) -> bool: - """Checks for the path_string formed by PangoText and Formed SVG file. + """Checks for the path_string formed by Text and Formed SVG file. Uses SVGMobject as it parses the SVG and returns the path_string """ remove_last_M(svg_path) # to prevent issue displaying @@ -53,7 +53,7 @@ def test_general_text_svgobject() -> None: """ text = "hello" size = 1 - temp_pango_text = PangoText(text, size=size) + temp_pango_text = Text(text, size=size) surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH) context = cairocffi.Context(surface) context.move_to(START_X, START_Y) @@ -73,7 +73,7 @@ def test_rtl_text_to_svgobject() -> None: called using ``SVGMobject``""" size = 1 text = RTL_TEXT.replace("\n", "") - temp_pango_text = PangoText(text, size=1) + temp_pango_text = Text(text, size=1) surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH) context = cairocffi.Context(surface) context.move_to(START_X, START_Y) @@ -93,7 +93,7 @@ def test_font_face() -> None: size = 1 text = RTL_TEXT.replace("\n", "") font_face = "sans" - temp_pango_text = PangoText(text, size=1, font=font_face) + temp_pango_text = Text(text, size=1, font=font_face) surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH) context = cairocffi.Context(surface) context.move_to(START_X, START_Y) @@ -111,7 +111,7 @@ def test_font_face() -> None: def test_whether_svg_file_created() -> None: """Checks Whether SVG file is created in desired location""" - temp_pango_text = PangoText("hello", size=1) + temp_pango_text = Text("hello", size=1) theo_path = os.path.abspath( os.path.join(folder, temp_pango_text.text2hash() + ".svg") ) @@ -123,7 +123,7 @@ def test_tabs_replace() -> None: """Checks whether are there in end svg image. Pango should handle tabs and line breaks.""" size = 1 - temp_pango_text = PangoText("hello\thi\nf") + temp_pango_text = Text("hello\thi\nf") assert temp_pango_text.text == "hellohif" surface = cairocffi.SVGSurface(filename, WIDTH, HEIGTH) context = cairocffi.Context(surface) From 1118b1e2b504fa09aaaaf4153658ccbde228dae5 Mon Sep 17 00:00:00 2001 From: Benjamin Hackl Date: Sat, 24 Oct 2020 19:18:51 +0200 Subject: [PATCH 7/7] too many newlines at end of file --- manim/mobject/svg/text_mobject.py | 1 - 1 file changed, 1 deletion(-) diff --git a/manim/mobject/svg/text_mobject.py b/manim/mobject/svg/text_mobject.py index a73857c1a6..693b91ea51 100644 --- a/manim/mobject/svg/text_mobject.py +++ b/manim/mobject/svg/text_mobject.py @@ -923,4 +923,3 @@ def text2svg(self): offset_x += layout.get_extents()[0].x surface.finish() return file_name -