def explode(self, mtext: MText, destroy=True): location = mtext.dxf.insert align = text_layout.LayoutAlignment(mtext.dxf.attachment_point) layout_engine = self.layout_engine(mtext) layout_engine.place(align=align) m = Matrix44.translate(location.x, location.y, location.z) layout_engine.render(m) if destroy: mtext.destroy()
def explode(self, mtext: MText, destroy=True): """Explode `mtext` and destroy the source entity if argument `destroy` is ``True``. """ align = tl.LayoutAlignment(mtext.dxf.attachment_point) layout_engine = self.layout_engine(mtext) layout_engine.place(align=align) layout_engine.render(mtext.ucs().matrix) if destroy: mtext.destroy()
def complex_mtext_renderer(ctx: RenderContext, backend: BackendInterface, mtext: MText, properties: Properties) -> None: cmr = ComplexMTextRenderer(ctx, backend, properties) align = tl.LayoutAlignment(mtext.dxf.attachment_point) layout_engine = cmr.layout_engine(mtext) layout_engine.place(align=align) layout_engine.render(mtext.ucs().matrix)
def make_bg_renderer(mtext: MText): assert mtext.doc is not None, "valid DXF document required" layout = mtext.get_layout() assert layout is not None, "valid layout required" attribs = get_base_attribs(mtext) dxf = mtext.dxf bg_fill = dxf.get("bg_fill", 0) bg_aci = None bg_true_color = None has_text_frame = False offset = 0 if bg_fill: # The fill scale is a multiple of the initial char height and # a scale of 1, fits exact the outer border # of the column -> offset = 0 offset = dxf.char_height * (dxf.get("box_fill_scale", 1.5) - 1) if bg_fill & ezdxf.const.MTEXT_BG_COLOR: if dxf.hasattr("bg_fill_color"): bg_aci = dxf.bg_fill_color if dxf.hasattr("bg_fill_true_color"): bg_aci = None bg_true_color = dxf.bg_fill_true_color if (bg_fill & 3) == 3: # canvas color = bit 0 and 1 set # can not detect canvas color from DXF document! # do not draw any background: bg_aci = None bg_true_color = None if bg_fill & ezdxf.const.MTEXT_TEXT_FRAME: has_text_frame = True return ColumnBackgroundRenderer( attribs, layout, bg_aci=bg_aci, bg_true_color=bg_true_color, offset=offset, text_frame=has_text_frame, )
def mtext(num): height = 1.0 width = 1.0 p1 = Vector(0, 0, 0) t = MText.new(dxfattribs={ 'char_height': height, 'width': width, 'text_direction': (1, 0, 0), 'attachment_point': 7, 'layer': 'text', }, doc=doc) t.text = content.format(num) tlen = height * len(t.text) * width p2 = p1.replace(x=tlen) p3 = p2.replace(y=height) p4 = p1.replace(y=height) v = [p1, p2, p3, p4, p3.lerp(p4), p2.lerp(p3)] return t, v
def mtext(num): height = 1.0 width = 1.0 p1 = Vec3(0, 0, 0) t = MText.new( dxfattribs={ "char_height": height, "width": width, "text_direction": (1, 0, 0), "attachment_point": 7, "layer": "text", }, doc=doc, ) t.text = content.format(num) tlen = height * len(t.text) * width p2 = p1.replace(x=tlen) p3 = p2.replace(y=height) p4 = p1.replace(y=height) v = [p1, p2, p3, p4, p3.lerp(p4), p2.lerp(p3)] return t, v
def entities(self): return EntityQuery([ MText.new( dxfattribs={"text": "content"}), # virtual text attribute Text.new(dxfattribs={"text": "content"}) ])
def layout_engine(self, mtext: MText) -> text_layout.Layout: def get_base_attribs() -> Dict: dxf = mtext.dxf attribs = { "layer": dxf.layer, "color": dxf.color, } return attribs def append_paragraph(): paragraph = new_paragraph(cells, ctx, initial_cap_height, line_spacing) layout.append_paragraphs([paragraph]) cells.clear() def column_heights(): if columns.heights: # dynamic manual heights = list(columns.heights) else: # static, dynamic auto heights = [columns.defined_height] * columns.count # last height has to be auto height = None if heights: heights[-1] = None else: heights = [None] return heights content = mtext.all_columns_raw_content() initial_cap_height = mtext.dxf.char_height # same line spacing for all paragraphs line_spacing = mtext.dxf.line_spacing_factor base_attribs = get_base_attribs() ctx = mtext_context(mtext) parser = MTextParser(content, ctx) layout = text_layout.Layout(width=mtext.dxf.width) bg_renderer = make_bg_renderer(mtext, base_attribs, self.layout) if mtext.has_columns: columns = mtext.columns for height in column_heights(): layout.append_column( width=columns.width, height=height, gutter=columns.gutter_width, renderer=bg_renderer, ) else: # column with auto height and default width layout.append_column(renderer=bg_renderer) cells = [] for token in parser: ctx = token.ctx if token.type == TokenType.NEW_PARAGRAPH: append_paragraph() elif token.type == TokenType.NEW_COLUMN: append_paragraph() # todo: layout.next_column() elif token.type == TokenType.SPACE: cells.append(self.space(ctx)) elif token.type == TokenType.NBSP: cells.append(self.non_breaking_space(ctx)) elif token.type == TokenType.TABULATOR: cells.append(self.space(ctx)) elif token.type == TokenType.WORD: if cells and isinstance(cells[-1], Word): # property change inside a word, create an unbreakable # connection between those two parts of the same word. cells.append(super_glue()) cells.append(self.word(token.data, ctx, base_attribs)) elif token.type == TokenType.STACK: cells.append(self.fraction(token.data, ctx, base_attribs)) if cells: append_paragraph() return layout
def test_set_mtext(self): attrib = Attrib.new(dxfattribs={"color": 3, "text": "TEST"}) mtext = MText.new(dxfattribs={"color": 3}) mtext.text = "LINE1\nLINE2" attrib.set_mtext(mtext) assert attrib.has_embedded_mtext_entity is True