mirror of
https://github.com/3b1b/manim.git
synced 2025-11-15 16:37:45 +00:00
Merge pull request #1316 from TonyCrane/shaders
Improve Text's handling of non-display characters in shaders and Add a feature
This commit is contained in:
commit
19e93454d9
8 changed files with 79 additions and 40 deletions
|
|
@ -29,6 +29,10 @@ universal_import_line: "from manimlib.imports import *"
|
||||||
style:
|
style:
|
||||||
font: "Consolas"
|
font: "Consolas"
|
||||||
background_color: "#333333"
|
background_color: "#333333"
|
||||||
|
# Set the position of preview window, you can use directions, e.g. UL/DR/OL/OO/...
|
||||||
|
# also, you can also specify the position(pixel) of the upper left corner of
|
||||||
|
# the window on the monitor, e.g. "960,540"
|
||||||
|
window_position: UR
|
||||||
camera_qualities:
|
camera_qualities:
|
||||||
low:
|
low:
|
||||||
resolution: "854x480"
|
resolution: "854x480"
|
||||||
|
|
|
||||||
|
|
@ -24,4 +24,5 @@ dependencies:
|
||||||
- pyyaml
|
- pyyaml
|
||||||
- validators
|
- validators
|
||||||
- ipython
|
- ipython
|
||||||
|
- PyOpenGL
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ class TextExample(Scene):
|
||||||
|
|
||||||
fonts = Text(
|
fonts = Text(
|
||||||
"And you can also set the font according to different words",
|
"And you can also set the font according to different words",
|
||||||
|
font="Arial",
|
||||||
t2f={"font": "Consolas", "words": "Consolas"},
|
t2f={"font": "Consolas", "words": "Consolas"},
|
||||||
t2c={"font": BLUE, "words": GREEN}
|
t2c={"font": BLUE, "words": GREEN}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,23 @@ def get_configuration(args):
|
||||||
else:
|
else:
|
||||||
window_width = monitor.width / 2
|
window_width = monitor.width / 2
|
||||||
window_height = window_width * 9 / 16
|
window_height = window_width * 9 / 16
|
||||||
window_position = (int(monitor.width - window_width), 0)
|
custom_position = custom_defaults["window_position"]
|
||||||
|
if "," in custom_position:
|
||||||
|
posx, posy = map(int, custom_position.split(","))
|
||||||
|
else:
|
||||||
|
if custom_position[1] == "L":
|
||||||
|
posx = 0
|
||||||
|
elif custom_position[1] == "O":
|
||||||
|
posx = int((monitor.width - window_width) / 2)
|
||||||
|
elif custom_position[1] == "R":
|
||||||
|
posx = int(monitor.width - window_width)
|
||||||
|
if custom_position[0] == "U":
|
||||||
|
posy = 0
|
||||||
|
elif custom_position[0] == "O":
|
||||||
|
posy = int((monitor.height - window_height) / 2)
|
||||||
|
elif custom_position[0] == "D":
|
||||||
|
posy = int(monitor.height - window_height)
|
||||||
|
window_position = (posx, posy)
|
||||||
config["window_config"] = {
|
config["window_config"] = {
|
||||||
"size": (window_width, window_height),
|
"size": (window_width, window_height),
|
||||||
"position": window_position,
|
"position": window_position,
|
||||||
|
|
|
||||||
|
|
@ -61,24 +61,12 @@ JOINT_TYPE_MAP = {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Related to Text
|
# Related to Text
|
||||||
NOT_SETTING_FONT_MSG = '''
|
|
||||||
Warning:
|
|
||||||
You haven't set font.
|
|
||||||
If you are not using English, this may cause text rendering problem.
|
|
||||||
You set font like:
|
|
||||||
text = Text('your text', font='your font')
|
|
||||||
or:
|
|
||||||
class MyText(Text):
|
|
||||||
CONFIG = {
|
|
||||||
'font': 'My Font'
|
|
||||||
}
|
|
||||||
'''
|
|
||||||
START_X = 30
|
START_X = 30
|
||||||
START_Y = 20
|
START_Y = 20
|
||||||
NORMAL = 'NORMAL'
|
NORMAL = "NORMAL"
|
||||||
ITALIC = 'ITALIC'
|
ITALIC = "ITALIC"
|
||||||
OBLIQUE = 'OBLIQUE'
|
OBLIQUE = "OBLIQUE"
|
||||||
BOLD = 'BOLD'
|
BOLD = "BOLD"
|
||||||
|
|
||||||
DEFAULT_STROKE_WIDTH = 4
|
DEFAULT_STROKE_WIDTH = 4
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import copy
|
||||||
import hashlib
|
import hashlib
|
||||||
import cairo
|
import cairo
|
||||||
from manimlib.constants import *
|
from manimlib.constants import *
|
||||||
|
from manimlib.mobject.geometry import Dot, Rectangle
|
||||||
from manimlib.mobject.svg.svg_mobject import SVGMobject
|
from manimlib.mobject.svg.svg_mobject import SVGMobject
|
||||||
from manimlib.utils.config_ops import digest_config
|
from manimlib.utils.config_ops import digest_config
|
||||||
from manimlib.utils.customization import get_customization
|
from manimlib.utils.customization import get_customization
|
||||||
|
|
@ -13,9 +14,6 @@ from manimlib.utils.directories import get_text_dir
|
||||||
TEXT_MOB_SCALE_FACTOR = 0.001048
|
TEXT_MOB_SCALE_FACTOR = 0.001048
|
||||||
|
|
||||||
|
|
||||||
# Warning, these classes are currently based on an old rendering mode
|
|
||||||
# not supported in this version of manim
|
|
||||||
|
|
||||||
class TextSetting(object):
|
class TextSetting(object):
|
||||||
def __init__(self, start, end, font, slant, weight, line_num=-1):
|
def __init__(self, start, end, font, slant, weight, line_num=-1):
|
||||||
self.start = start
|
self.start = start
|
||||||
|
|
@ -29,33 +27,39 @@ class TextSetting(object):
|
||||||
class Text(SVGMobject):
|
class Text(SVGMobject):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
# Mobject
|
# Mobject
|
||||||
'color': WHITE,
|
"color": WHITE,
|
||||||
'height': None,
|
"height": None,
|
||||||
'stroke_width': 0,
|
"stroke_width": 0,
|
||||||
# Text
|
# Text
|
||||||
'font': '',
|
"font": '',
|
||||||
'gradient': None,
|
"gradient": None,
|
||||||
'lsh': -1,
|
"lsh": -1,
|
||||||
'size': 1,
|
"size": 1,
|
||||||
'font_size': 48,
|
"font_size": 48,
|
||||||
'slant': NORMAL,
|
"tab_width": 4,
|
||||||
'weight': NORMAL,
|
"slant": NORMAL,
|
||||||
't2c': {},
|
"weight": NORMAL,
|
||||||
't2f': {},
|
"t2c": {},
|
||||||
't2g': {},
|
"t2f": {},
|
||||||
't2s': {},
|
"t2g": {},
|
||||||
't2w': {},
|
"t2s": {},
|
||||||
|
"t2w": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, text, **config):
|
def __init__(self, text, **config):
|
||||||
self.text = text
|
|
||||||
self.full2short(config)
|
self.full2short(config)
|
||||||
digest_config(self, config)
|
digest_config(self, config)
|
||||||
self.lsh = self.size if self.lsh == -1 else self.lsh
|
self.lsh = self.size if self.lsh == -1 else self.lsh
|
||||||
|
text_without_tabs = text
|
||||||
|
if text.find('\t') != -1:
|
||||||
|
text_without_tabs = text.replace('\t', ' ' * self.tab_width)
|
||||||
|
self.text = text_without_tabs
|
||||||
file_name = self.text2svg()
|
file_name = self.text2svg()
|
||||||
self.remove_last_M(file_name)
|
self.remove_last_M(file_name)
|
||||||
|
self.remove_empty_path(file_name)
|
||||||
SVGMobject.__init__(self, file_name, **config)
|
SVGMobject.__init__(self, file_name, **config)
|
||||||
|
self.text = text
|
||||||
|
self.apply_space_chars()
|
||||||
|
|
||||||
if self.t2c:
|
if self.t2c:
|
||||||
self.set_color_by_t2c()
|
self.set_color_by_t2c()
|
||||||
|
|
@ -68,6 +72,18 @@ class Text(SVGMobject):
|
||||||
if self.height is None:
|
if self.height is None:
|
||||||
self.scale(TEXT_MOB_SCALE_FACTOR * self.font_size)
|
self.scale(TEXT_MOB_SCALE_FACTOR * self.font_size)
|
||||||
|
|
||||||
|
def apply_space_chars(self):
|
||||||
|
submobs = self.submobjects.copy()
|
||||||
|
for char_index in range(self.text.__len__()):
|
||||||
|
if self.text[char_index] == " " or self.text[char_index] == "\t" or self.text[char_index] == "\n":
|
||||||
|
space = Dot(radius=0, fill_opacity=0, stroke_opacity=0)
|
||||||
|
if char_index == 0:
|
||||||
|
space.move_to(submobs[char_index].get_center())
|
||||||
|
else:
|
||||||
|
space.move_to(submobs[char_index - 1].get_center())
|
||||||
|
submobs.insert(char_index, space)
|
||||||
|
self.set_submobjects(submobs)
|
||||||
|
|
||||||
def remove_last_M(self, file_name):
|
def remove_last_M(self, file_name):
|
||||||
with open(file_name, 'r') as fpr:
|
with open(file_name, 'r') as fpr:
|
||||||
content = fpr.read()
|
content = fpr.read()
|
||||||
|
|
@ -75,6 +91,13 @@ class Text(SVGMobject):
|
||||||
with open(file_name, 'w') as fpw:
|
with open(file_name, 'w') as fpw:
|
||||||
fpw.write(content)
|
fpw.write(content)
|
||||||
|
|
||||||
|
def remove_empty_path(self, file_name):
|
||||||
|
with open(file_name, 'r') as fpr:
|
||||||
|
content = fpr.read()
|
||||||
|
content = re.sub(r'<path .*?d=""/>', '', content)
|
||||||
|
with open(file_name, 'w') as fpw:
|
||||||
|
fpw.write(content)
|
||||||
|
|
||||||
def find_indexes(self, word):
|
def find_indexes(self, word):
|
||||||
m = re.match(r'\[([0-9\-]{0,}):([0-9\-]{0,})\]', word)
|
m = re.match(r'\[([0-9\-]{0,}):([0-9\-]{0,})\]', word)
|
||||||
if m:
|
if m:
|
||||||
|
|
|
||||||
|
|
@ -539,9 +539,14 @@ class Scene(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_key_press(self, symbol, modifiers):
|
def on_key_press(self, symbol, modifiers):
|
||||||
if chr(symbol) == "r":
|
try:
|
||||||
|
char = chr(symbol)
|
||||||
|
except OverflowError:
|
||||||
|
print(" Warning: The value of the pressed key is too large.")
|
||||||
|
return
|
||||||
|
if char == "r":
|
||||||
self.camera.frame.to_default_state()
|
self.camera.frame.to_default_state()
|
||||||
elif chr(symbol) == "q":
|
elif char == "q":
|
||||||
self.quit_interaction = True
|
self.quit_interaction = True
|
||||||
|
|
||||||
def on_resize(self, width: int, height: int):
|
def on_resize(self, width: int, height: int):
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,5 @@ pyyaml
|
||||||
screeninfo
|
screeninfo
|
||||||
pyreadline; sys_platform == 'win32'
|
pyreadline; sys_platform == 'win32'
|
||||||
validators
|
validators
|
||||||
ipython
|
ipython
|
||||||
|
PyOpenGL
|
||||||
Loading…
Add table
Reference in a new issue