Esempio n. 1
0
 def test_scaled_height_and_length_for_aligned_text(self, size, ff):
     length = 3
     paths = text2path.make_paths_from_str("XXX", font=ff, size=size,
                                           align="LEFT")
     default = path.bbox(paths)
     paths = text2path.make_paths_from_str(
         "XXX", font=ff, size=size, align="ALIGNED", length=length)
     bbox = path.bbox(paths)
     scale = bbox.size.x / default.size.x
     assert bbox.size.x == pytest.approx(length), "expect exact length"
     assert bbox.size.y == pytest.approx(size * scale), \
         "text height should be scaled"
Esempio n. 2
0
def test_gear():
    # basic gear tool is tested here: test_702_render_forms.py
    gear = shapes.gear(16, 0.1, 0.3, 0.2, 1.0)
    # first vertex is on th x-axis!
    extends = bbox([gear])
    assert extends.extmin.isclose((-0.999, -0.999), abs_tol=1e-3)
    assert extends.extmax.isclose((0.999, 0.999), abs_tol=1e-3)
    assert gear.is_closed is True
Esempio n. 3
0
 def test_length_for_fit_alignment(self, size, ff):
     length = 3
     paths = text2path.make_paths_from_str(
         "XXX", font=ff, size=size, align="FIT", length=length)
     bbox = path.bbox(paths)
     assert bbox.size.x == pytest.approx(length), "expect exact length"
     assert bbox.size.y == pytest.approx(size), \
         "text height should be unscaled"
Esempio n. 4
0
def test_star():
    # basic star tool is tested here: test_702_render_forms.py
    star4 = shapes.star(4, r1=1, r2=0.5)
    # first vertex is on th x-axis!
    extends = bbox([star4])

    assert extends.extmin.isclose((-1, -1))
    assert extends.extmax.isclose((1, 1))
    assert star4.is_closed is True
Esempio n. 5
0
def test_ngon():
    # basic ngon tool is tested here: test_702_render_forms.py
    square = shapes.ngon(4, length=1.0)
    # first vertex is on th x-axis => square is rotated about 45 deg:
    extends = bbox([square])
    d = math.sin(math.pi / 4)
    assert extends.extmin.isclose((-d, -d))
    assert extends.extmax.isclose((d, d))
    assert square.is_closed is True
Esempio n. 6
0
 def test_total_length_for_fit_alignment(self, ff):
     length = 3
     hatches = text2path.make_hatches_from_str(
         "XXX", font=ff, align="FIT", length=length)
     paths = []
     for hatch in hatches:
         paths.extend(path.from_hatch(hatch))
     bbox = path.bbox(paths)
     assert bbox.size.x == pytest.approx(length), "expect exact length"
     assert bbox.size.y == pytest.approx(1.0), \
         "text height should be unscaled"
Esempio n. 7
0
def test_wedge():
    wedge = shapes.wedge(0, math.pi / 2)
    assert wedge.has_curves
    assert wedge.has_lines
    assert wedge.is_closed is True
    assert len(wedge) == 3, "expected 2 lines and 1 cubic Bèzier segment"
    assert wedge.start.isclose((0, 0, 0)), "has to start at the center"
    assert wedge.end.isclose((0, 0, 0)), "has to end at the center"
    extends = bbox([wedge])
    assert extends.extmin.isclose((0.0, 0.0))
    assert extends.extmax.isclose((1.0, 1.0))
Esempio n. 8
0
def make_path_from_str(
    s: str,
    font: fonts.FontFace,
    size: float = 1.0,
    align=TextEntityAlignment.LEFT,
    length: float = 0,
    m: Matrix44 = None,
) -> Path:
    """Convert a single line string `s` into a :term:`Multi-Path` object.
    The text `size` is the height of the uppercase letter "X" (cap height).
    The paths are aligned about the insertion point at (0, 0).
    BASELINE means the bottom of the letter "X".

    Args:
         s: text to convert
         font: font face definition as :class:`~ezdxf.tools.fonts.FontFace` object
         size: text size (cap height) in drawing units
         align: alignment as :class:`ezdxf.enums.TextEntityAlignment`,
            default is :attr:`LEFT`
         length: target length for the :attr:`ALIGNED` and :attr:`FIT` alignments
         m: transformation :class:`~ezdxf.math.Matrix44`

    .. versionadded:: 0.17

    .. version changed: 0.17.2

        Enum :class:`ezdxf.enums.TextEntityAlignment` replaces string
        values.

    """
    if len(s) == 0:
        return Path()
    font_properties, font_measurements = _get_font_data(font)
    # scale font rendering units to drawing units:
    render_size = size / font_measurements.cap_height
    p = _str_to_path(s, font_properties, render_size)
    bbox = path.bbox([p], flatten=0)

    # Text is rendered in drawing units,
    # therefore do alignment in drawing units:
    draw_units_fm = font_measurements.scale_from_baseline(size)
    matrix = alignment_transformation(draw_units_fm, bbox, align, length)
    if m is not None:
        matrix *= m
    return p.transform(matrix)
Esempio n. 9
0
def make_paths_from_str(s: str,
                        font: fonts.FontFace,
                        size: float = 1.0,
                        align: str = 'LEFT',
                        length: float = 0,
                        m: Matrix44 = None) -> List[Path]:
    """ Convert a single line string `s` into a list of
    :class:`~ezdxf.path.Path` objects. All paths are returned in a single
    list. The text `size` is the height of the uppercase letter "X" (cap height).
    The paths are aligned about the insertion point at (0, 0).
    BASELINE means the bottom of the letter "X".

    Args:
         s: text to convert
         font: font face definition
         size: text size (cap height) in drawing units
         align: alignment as string, default is "LEFT"
         length: target length for the "ALIGNED" and "FIT" alignments
         m: transformation :class:`~ezdxf.math.Matrix44`

    """
    if len(s) == 0:
        return []
    font_properties, font_measurements = _get_font_data(font)
    scaled_size = size / font_measurements.cap_height
    scaled_fm = font_measurements.scale_from_baseline(scaled_size)
    paths = _str_to_paths(s, font_properties, scaled_size)
    bbox = path.bbox(paths, precise=False)
    halign, valign = const.TEXT_ALIGN_FLAGS[align.upper()]
    matrix = get_alignment_transformation(scaled_fm, bbox, halign, valign)

    stretch_x = 1.0
    stretch_y = 1.0
    if align == 'ALIGNED':
        stretch_x = length / bbox.size.x
        stretch_y = stretch_x
    elif align == 'FIT':
        stretch_x = length / bbox.size.x
    if stretch_x != 1.0:
        matrix *= Matrix44.scale(stretch_x, stretch_y, 1.0)
    if m is not None:
        matrix *= m
    return list(path.transform_paths(paths, matrix))
Esempio n. 10
0
def make_paths_from_str(s: str,
                        font: fonts.FontFace,
                        size: float = 1.0,
                        align: str = 'LEFT',
                        length: float = 0,
                        m: Matrix44 = None) -> List[Path]:
    """ Convert a single line string `s` into a list of
    :class:`~ezdxf.path.Path` objects. All paths are returned in a single
    list. The text `size` is the height of the uppercase letter "X" (cap height).
    The paths are aligned about the insertion point at (0, 0).
    BASELINE means the bottom of the letter "X".

    Args:
         s: text to convert
         font: font face definition as :class:`~ezdxf.tools.fonts.FontFace` object
         size: text size (cap height) in drawing units
         align: alignment as string, default is "LEFT"
         length: target length for the "ALIGNED" and "FIT" alignments
         m: transformation :class:`~ezdxf.math.Matrix44`

    """
    if len(s) == 0:
        return []
    font_properties, font_measurements = _get_font_data(font)
    # scale font rendering units to drawing units:
    render_size = size / font_measurements.cap_height
    paths = _str_to_paths(s, font_properties, render_size)
    bbox = path.bbox(paths, flatten=False)

    # Text is rendered in drawing units,
    # therefore do alignment in drawing units:
    draw_units_fm = font_measurements.scale_from_baseline(size)
    matrix = alignment_transformation(draw_units_fm, bbox, align, length)
    if m is not None:
        matrix *= m
    return list(path.transform_paths(paths, matrix))
Esempio n. 11
0
 def test_uniform_shrink_paths(self, spath):
     result = fit_paths_into_box([spath], (1.5, 1.5, 1.5))
     box = bbox(result)
     assert box.size.isclose((0.5, 1, 1.5))
Esempio n. 12
0
 def test_uniform_stretch_paths_limited_by_x(self, spath):
     result = fit_paths_into_box([spath], (1.2, 6, 6))
     box = bbox(result)
     # stretch factor: 1.2
     assert box.size.isclose((1.2, 2.4, 3.6))
Esempio n. 13
0
 def test_uniform_stretch_paths_limited_by_y(self, spath):
     result = fit_paths_into_box([spath], (6, 3, 6))
     box = bbox(result)
     # stretch factor: 1.5
     assert box.size == (1.5, 3, 4.5)
Esempio n. 14
0
 def test_uniform_stretch_paths_limited_by_z(self, spath):
     result = fit_paths_into_box([spath], (6, 6, 6))
     box = bbox(result)
     assert box.size == (2, 4, 6)
Esempio n. 15
0
 def test_precise_box(self, quadratic):
     result = bbox([quadratic], flatten=0.01)
     assert result.extmax.y == pytest.approx(0.5)  # parabola
Esempio n. 16
0
 def test_path_coordinates_for_positive_size(self, size, ff):
     paths = text2path.make_paths_from_str("X", font=ff, size=size)
     bbox = path.bbox(paths)
     assert bbox.extmax.y == pytest.approx(size)
     assert bbox.extmin.y == pytest.approx(0)
Esempio n. 17
0
 def test_non_uniform_stretch_paths(self, spath):
     result = fit_paths_into_box([spath], (8, 7, 6), uniform=False)
     box = bbox(result)
     assert box.size == (8, 7, 6)
Esempio n. 18
0
 def test_one_path(self):
     p = Path()
     p.line_to((1, 2, 3))
     assert bbox([p]).size == (1, 2, 3)
Esempio n. 19
0
 def test_project_into_yz(self, spath):
     result = fit_paths_into_box([spath], (0, 6, 6), uniform=False)
     box = bbox(result)
     assert box.size == (0, 6, 6), "x-axis should be ignored"
Esempio n. 20
0
 def test_project_into_xz(self, spath):
     result = fit_paths_into_box([spath], (6, 0, 6))
     box = bbox(result)
     assert box.size == (2, 0, 6), "y-axis should be ignored"
Esempio n. 21
0
def get_path_bbox(text):
    paths = text2path.make_paths_from_entity(text)
    return path.bbox(paths, flatten=0)
Esempio n. 22
0
 def test_text_path_height_for_exact_drawing_units(self, size, ff):
     paths = text2path.make_paths_from_str("X", font=ff, size=size)
     bbox = path.bbox(paths)
     assert bbox.size.y == pytest.approx(abs(size))
Esempio n. 23
0
 def test_project_into_xy(self, spath):
     result = fit_paths_into_box([spath], (6, 6, 0))
     box = bbox(result)
     # Note: z-axis is also ignored by extent detection:
     # scaling factor = 3x
     assert box.size.isclose((3, 6, 0)), "z-axis should be ignored"
Esempio n. 24
0
 def test_two_path(self):
     p1 = Path()
     p1.line_to((1, 2, 3))
     p2 = Path()
     p2.line_to((-3, -2, -1))
     assert bbox([p1, p2]).size == (4, 4, 4)
Esempio n. 25
0
 def test_project_into_yz(self, spath):
     result = fit_paths_into_box([spath], (0, 6, 6))
     box = bbox(result)
     assert box.size.isclose((0, 4, 6)), "x-axis should be ignored"
Esempio n. 26
0
 def test_not_precise_box(self, quadratic):
     result = bbox([quadratic], flatten=0)
     assert result.extmax.y == pytest.approx(1)  # control point
Esempio n. 27
0
 def test_non_uniform_shrink_paths(self, spath):
     result = fit_paths_into_box([spath], (1.5, 1.5, 1.5), uniform=False)
     box = bbox(result)
     assert box.size == (1.5, 1.5, 1.5)
Esempio n. 28
0
 def test_path_coordinates_for_negative_size(self, size, ff):
     # Negative text height mirrors text about the x-axis!
     paths = text2path.make_paths_from_str("X", font=ff, size=size)
     bbox = path.bbox(paths)
     assert bbox.extmax.y == pytest.approx(0)
     assert bbox.extmin.y == pytest.approx(size)
Esempio n. 29
0
# 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:
# uniform=True, keeps the text aspect ratio
# uniform=False, scales the text to touch all 4 sides of the box
final_paths = path.fit_paths_into_box(text_as_paths,
                                      size=(sx, sy, 0),
                                      uniform=False)

# mirror text along x-axis
final_paths = path.transform_paths(final_paths, Matrix44.scale(-1, 1, 1))

# move bottom/left corner to (0, 0) if required:
bbox = path.bbox(final_paths)
dx, dy, dz = -bbox.extmin
final_paths = path.transform_paths(final_paths, Matrix44.translate(dx, dy, dz))

path.render_lwpolylines(msp,
                        final_paths,
                        distance=0.01,
                        dxfattribs={'color': 2})

zoom.extents(msp)
doc.saveas(DIR / 'SqeezeMe.dxf')
Esempio n. 30
0
 def test_empty_paths(self):
     result = bbox([])
     assert result.has_data is False