diff --git a/manim/mobject/svg/text_mobject.py b/manim/mobject/svg/text_mobject.py index 906be3d176..693b91ea51 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 @@ -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,27 +546,74 @@ class PangoText(SVGMobject): Returns ------- - :class:`PangoText` + :class:`Text` The mobject like :class:`.VGroup`. 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) + + As :class:`Text` uses Pango to render text, rendering non-English + characters is easily possible: + .. manim:: MultipleFonts :save_last_frame: 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 +624,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:: @@ -622,6 +669,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 @@ -872,70 +923,3 @@ def text2svg(self): offset_x += layout.get_extents()[0].x 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) 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)