Example #1
0
def test_get_font_without_definition():
    # Creates a pseudo entry:
    assert fonts.get_font_face("mozman.ttf") == (
        "mozman.ttf",
        "mozman",
        "normal",
        "normal",
        "normal",
    )
    with pytest.raises(TypeError):
        fonts.get_font_face(None)  # should not accept None as argument"
Example #2
0
def get_font_face(entity: DXFGraphic, doc=None) -> fonts.FontFace:
    """Returns the :class:`~ezdxf.tools.fonts.FontFace` defined by the
    associated text style. Returns the default font face if the `entity` does
    not have or support the DXF attribute "style".

    Pass a DXF document as argument `doc` to resolve text styles for virtual
    entities which are not assigned to a DXF document. The argument `doc`
    always overrides the DXF document to which the `entity` is assigned to.

    """
    if entity.doc and doc is None:
        doc = entity.doc
    assert doc is not None, "valid DXF document required"

    style_name = ""
    # This works also for entities which do not support "style",
    # where style_name = entity.dxf.get("style") would fail.
    if entity.dxf.is_supported("style"):
        style_name = entity.dxf.style

    font_face = fonts.FontFace()
    if style_name and doc is not None:
        style = cast(Textstyle, doc.styles.get(style_name))
        family, italic, bold = style.get_extended_font_data()
        if family:
            text_style = "italic" if italic else "normal"
            text_weight = "bold" if bold else "normal"
            font_face = fonts.FontFace(family=family,
                                       style=text_style,
                                       weight=text_weight)
        else:
            ttf = style.dxf.font
            if ttf:
                font_face = fonts.get_font_face(ttf)
    return font_face
def test_font_ttf_path_from_font_face():
    # low level support
    path = mpl_fs.find_filename(family="Arial", weight=900)
    assert path.name == "ariblk.ttf"

    # high level support, see also test_resolve_font_ttf_path()
    ff = fonts.get_font_face(path.name)
    assert fonts.find_ttf_path(ff) == "ariblk.ttf"
Example #4
0
def test_get_font_face_for_shx_fonts():
    assert fonts.get_font_face("TXT") == (
        "txt_____.ttf",
        "Txt",
        "normal",
        "normal",
        400,
    )
Example #5
0
 def add_text_style(self, text_style: 'Textstyle'):
     """ Setup text style properties. """
     name = table_key(text_style.dxf.name)
     ttf = text_style.dxf.font
     font_face = fonts.get_font_face(ttf, map_shx=True)
     # 2021-02-02: Removed TTF check!
     # AutoCAD supports only TTF-fonts, but we can do better!
     self.fonts[name] = font_face
Example #6
0
    def add_text_style(self, text_style: 'Textstyle'):
        """ Setup text style properties. """
        name = table_key(text_style.dxf.name)
        font_file = text_style.dxf.font
        font_face = None
        if font_file == "":  # Font family stored in XDATA?
            family, italic, bold = text_style.get_extended_font_data()
            if family:
                font_face = fonts.find_font_face_by_family(family, italic, bold)
        else:
            font_face = fonts.get_font_face(font_file, map_shx=True)

        if font_face is None:  # fall back to default font
            font_face = fonts.FontFace()
        self.fonts[name] = font_face
Example #7
0
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)
Example #8
0
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)
def test_resolve_font_ttf_path():
    ff = fonts.get_font_face("ariblk.ttf")
    assert ff.family == "Arial"
    assert ff.weight == 900
Example #10
0
def test_get_font_face_for_shx_fonts():
    assert fonts.get_font_face('TXT') == ('txt_____.ttf', 'Txt', 'normal',
                                          'normal', 400)
Example #11
0
def test_get_font_face_with_definition():
    assert fonts.get_font_face('Arial.ttf') is fonts.find_font_face(
        'arial.ttf')
Example #12
0
def test_get_font_without_definition():
    # Creates a pseudo entry:
    assert fonts.get_font_face('mozman.ttf') == ('mozman.ttf', 'mozman',
                                                 'normal', 'normal', 'normal')
    with pytest.raises(TypeError):
        fonts.get_font_face(None)  # should not accept None as argument"
Example #13
0
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)