stabilizing, user experience

use class for glyph availability
use isinstance instead of type
better user experience when export directory does not exist
This commit is contained in:
jrkb 2025-05-29 15:27:24 +02:00
parent 777644e509
commit 335ab1face
4 changed files with 279 additions and 129 deletions

View file

@ -515,7 +515,11 @@ def load_font_from_filepath(filepath, glyphs="", font_name="", face_name=""):
for mff in modified_font_faces:
mff_glyphs = []
face = Font.fonts[mff["font_name"]].faces[mff["face_name"]]
face : Font.FontFace = Font.get_font_face(mff["font_name"], mff["face_name"])
if face is None:
print(f"{utils.prefix()}::load_font_from_path({filepath=}, {glyphs=}, {font_name=}, {face_name=}) failed")
print(f"modified font face {mff=} could not be accessed.")
continue
# iterate glyphs
for g in face.glyphs:
# iterate alternates
@ -543,17 +547,18 @@ def load_font_from_filepath(filepath, glyphs="", font_name="", face_name=""):
def update_available_fonts():
abc3d_data = bpy.context.scene.abc3d_data
for font_name in Font.fonts.keys():
for face_name in Font.fonts[font_name].faces.keys():
found = False
for f in abc3d_data.available_fonts.values():
if font_name == f.font_name and face_name == f.face_name:
found = True
if not found:
f = abc3d_data.available_fonts.add()
f.font_name = font_name
f.face_name = face_name
print(f"{__name__} added {font_name} {face_name}")
for font_and_face in Font.get_loaded_fonts_and_faces():
found = False
font_name = font_and_face[0]
face_name = font_and_face[1]
for f in abc3d_data.available_fonts.values():
if font_name == f.font_name and face_name == f.face_name:
found = True
if not found:
f = abc3d_data.available_fonts.add()
f.font_name = font_name
f.face_name = face_name
print(f"{__name__} added {font_name} {face_name}")
# def update_available_texts():
@ -754,21 +759,28 @@ def get_glyph_height(glyph_obj):
def prepare_text(font_name, face_name, text, allow_replacement=True):
loaded, missing, loadable, files = Font.test_glyphs_availability(
availability = Font.test_glyphs_availability(
font_name, face_name, text
)
if isinstance(availability, int):
if availability == Font.MISSING_FONT:
print(f"{utils.prefix()}::prepare_text({font_name=}, {face_name=}, {text=}) failed with MISSING_FONT")
if availability is Font.MISSING_FACE:
print(f"{utils.prefix()}::prepare_text({font_name=}, {face_name=}, {text=}) failed with MISSING_FACE")
return False
loadable = availability.unloaded
# possibly replace upper and lower case letters with each other
if len(missing) > 0 and allow_replacement:
if len(availability.missing) > 0 and allow_replacement:
replacement_search = ""
for m in missing:
for m in availability.missing:
if m.isalpha():
replacement_search += m.swapcase()
r = Font.test_availability(font_name, face_name, replacement_search)
loadable += r["maybe"]
loadable += r.unloaded
# not update (loaded, missing, files), we only use loadable/maybe later
if len(loadable) > 0:
for filepath in files:
for filepath in availability.filepaths:
load_font_from_filepath(filepath, loadable, font_name, face_name)
return True
@ -776,9 +788,9 @@ def predict_actual_text(text_properties):
availability = Font.test_availability(text_properties.font_name, text_properties.face_name, text_properties.text)
AVAILABILITY = Font.test_availability(text_properties.font_name, text_properties.face_name, text_properties.text.swapcase())
t_text = text_properties.text
for c in availability["missing"]:
for c in availability.missing:
t_text = t_text.replace(c, "")
for c in AVAILABILITY["missing"]:
for c in AVAILABILITY.missing:
t_text = t_text.replace(c, "")
return t_text
@ -1016,14 +1028,8 @@ def transfer_text_object_to_text_properties(text_object, text_properties, id_fro
if text == text_properties.text:
is_good_text = True
else:
availability = Font.test_availability(text_properties.font_name, text_properties.face_name, text_properties.text)
AVAILABILITY = Font.test_availability(text_properties.font_name, text_properties.face_name, text_properties.text.swapcase())
t_text = text_properties.text
for c in availability["missing"]:
t_text = t_text.replace(c, "")
for c in AVAILABILITY["missing"]:
t_text = t_text.replace(c, "")
if len(t_text) == len(text):
t_text = predict_actual_text(text_properties)
if t_text == text:
is_good_text = True
if is_good_text:
text_properties.actual_text = text
@ -1252,7 +1258,7 @@ def set_text_on_curve(text_properties, reset_timeout_s=0.1, reset_depsgraph_n=4,
actual_text = ""
for i, c in enumerate(text_properties.text):
face = Font.fonts[text_properties.font_name].faces[text_properties.face_name]
face = Font.get_font_face(text_properties.font_name, text_properties.face_name)
scalor = face.unit_factor * text_properties.font_size
if c == "\\":
is_command = True