def main(): parser = argparse.ArgumentParser( "ezdxf", description=DESCRIPTION, ) add_common_arguments(parser) subparsers = parser.add_subparsers(dest="command") commands.add_parsers(subparsers) args = parser.parse_args(sys.argv[1:]) help_ = True options.log_unprocessed_tags = args.verbose if args.log: setup_log(args) if args.version: print_version(args.verbose) help_ = False run = commands.get(args.command) if run: # For the case automatic font loading is disabled: fonts.load() run(args) elif help_: parser.print_help()
def main(): parser = argparse.ArgumentParser( "ezdxf", description=DESCRIPTION, ) add_common_arguments(parser) subparsers = parser.add_subparsers(dest="command") commands.add_parsers(subparsers) args = parser.parse_args(sys.argv[1:]) help_ = True if args.config: config = Path(args.config) if config.exists(): options.read_file(args.config) if args.verbose: print(f'using config file: "{config}"') else: print(f'config file "{config}" not found') if args.log: setup_log(args) if args.version: print_version(verbose=args.verbose) help_ = False run = commands.get(args.command) if run: # For the case automatic font loading is disabled: fonts.load() run(args) elif help_: parser.print_help()
def test_save_and_load_caches(tmp_path): fonts.save(tmp_path) assert (tmp_path / 'font_face_cache.json').exists() assert (tmp_path / 'font_measurement_cache.json').exists() fonts.font_face_cache = {} fonts.font_measurement_cache = {} fonts.load(tmp_path) assert len(fonts.font_face_cache) > 0 assert len(fonts.font_measurement_cache) > 0
def _get_font_data( font: fonts.FontFace, ) -> Tuple[FontProperties, fonts.FontMeasurements]: fp = FontProperties( family=font.family, style=font.style, stretch=font.stretch, weight=font.weight, ) ttf_path = findfont(fp) fonts.load() # not expensive if already loaded # The ttf file path is the cache key for font measurements: fm = fonts.get_font_measurements(ttf_path) return fp, fm
def make_paths_from_entity(entity: AnyText) -> List[Path]: """ Convert text content from DXF entities TEXT and ATTRIB into a list of :class:`~ezdxf.path.Path` objects. All paths are returned in a single list. The paths are located at the location of the source entity. """ check_entity_type(entity) fonts.load() text = entity.plain_text() paths = make_paths_from_str( text, fonts.get_font_face(entity.font_name()), size=entity.dxf.height, # cap height in drawing units align=entity.get_align(), length=entity.fit_length(), ) m = entity.wcs_transformation_matrix() return path.transform_paths(paths, m)
def make_path_from_entity(entity: AnyText) -> Path: """Convert text content from DXF entities TEXT and ATTRIB into a :term:`Multi-Path` object. The paths are located at the location of the source entity. .. versionadded:: 0.17 """ check_entity_type(entity) fonts.load() text = entity.plain_text() p = make_path_from_str( text, fonts.get_font_face(entity.font_name()), size=entity.dxf.height, # cap height in drawing units align=entity.get_align_enum(), length=entity.fit_length(), ) m = entity.wcs_transformation_matrix() return p.transform(m)
# Copyright (c) 2021, Manfred Moitzi # License: MIT License from pathlib import Path import ezdxf from ezdxf import path, zoom from ezdxf.math import Matrix44 from ezdxf.tools import fonts from ezdxf.addons import text2path DIR = Path('~/Desktop/Outbox').expanduser() fonts.load() doc = ezdxf.new() doc.layers.new('OUTLINE') doc.layers.new('FILLING') msp = doc.modelspace() attr = {'color': 2} ff = fonts.FontFace(family="Arial") sx, sy = 4, 2 # create the target box: msp.add_lwpolyline([(0, 0), (sx, 0), (sx, sy), (0, sy)], close=True, dxfattribs={'color': 1}) # convert text string into path objects: text_as_paths = text2path.make_paths_from_str("Squeeze Me", ff) # fit text paths into a given box size by scaling, does not move the path objects:
def make_paths_from_entity(entity: AnyText) -> List[Path]: """ Convert text content from DXF entities TEXT and ATTRIB into a list of :class:`~ezdxf.render.Path` objects. All paths are returned in a single list. The paths are located at the location of the source entity, but don't expect a 100% match compared to CAD applications. """ def get_font_name(): font_name = 'arial.ttf' style_name = entity.dxf.style if entity.doc: try: style = entity.doc.styles.get(style_name) font_name = style.dxf.font except ValueError: pass return font_name def get_transformation(): """ Apply rotation, width factor, translation to the insertion point and if necessary transformation from OCS to WCS. """ # TODO: text generation flags - mirror-x and mirror-y angle = math.radians(entity.dxf.rotation) width_factor = entity.dxf.width if align == 'LEFT': location = p1 elif align in ('ALIGNED', 'FIT'): width_factor = 1.0 # text goes from p1 to p2, no stretching applied location = p1.lerp(p2, factor=0.5) angle = (p2 - p1).angle # override stored angle else: location = p2 m = Matrix44.chain( Matrix44.scale(width_factor, 1, 1), Matrix44.z_rotate(angle), Matrix44.translate(location.x, location.y, location.z), ) ocs = entity.ocs() if ocs.transform: m *= ocs.matrix return m if not entity.dxftype() in ('TEXT', 'ATTRIB'): raise TypeError(f'unsupported entity type: {entity.dxftype()}') fonts.load() text = entity.plain_text() align = entity.get_align() p1 = Vec3(entity.dxf.insert) if entity.dxf.hasattr('align_point'): p2 = Vec3(entity.dxf.align_point) else: p2 = p1 length = 0 if align in ('FIT', 'ALIGNED'): # text is stretch between p1 and p2 length = p1.distance(p2) paths = make_paths_from_str( text, fonts.get_font_face(get_font_name()), size=entity.dxf.height, # cap height in drawing units align=align, length=length, ) m = get_transformation() return path.transform_paths(paths, m)