def path(self): if not self._pang_ctx: self._pre_render() # here we create a new cairo.Context in order to hold the pathdata tempCairoContext = cairo.Context(cairo.RecordingSurface(cairo.CONTENT_ALPHA, None)) if GI: tempCairoContext = _UNSAFE_cairocffi_context_to_pycairo(tempCairoContext) tempCairoContext.move_to(self.x, self.y - self.baseline) # in here we create a pangoCairoContext in order to display layout on it # supposedly showlayout should work, but it fills the path instead, # therefore we use layout_path instead to render the layout to pangoCairoContext # tempCairoContext.show_layout(self.layout) PangoCairo.layout_path(tempCairoContext, self.layout) # here we extract the path from the temporal cairo.Context we used to draw on the previous step pathdata = tempCairoContext.copy_path() # creates a BezierPath instance for storing new shoebot path p = BezierPath(self._bot) # parsing of cairo path to build a shoebot path for item in pathdata: cmd = item[0] args = item[1] if cmd == PATH_MOVE_TO: p.moveto(*args) elif cmd == PATH_LINE_TO: p.lineto(*args) elif cmd == PATH_CURVE_TO: p.curveto(*args) elif cmd == PATH_CLOSE_PATH: p.closepath() # cairo function for freeing path memory return p
def _render(self, ctx=None): if not self._doRender: return ctx = ctx or self._get_context() if GI: ctx = _UNSAFE_cairocffi_context_to_pycairo(ctx) # we build a PangoCairo context linked to cairo context # then we create a pango layout # we update the context as we already used a null one on the pre-rendering # supposedly there should not be a big performance penalty self._pang_ctx = PangoCairo.create_context(ctx) if self._fillcolor is not None: # Go to initial point (CORNER or CENTER): transform = self._call_transform_mode(self._transform) if GI: transform = pycairo.Matrix(*transform.as_tuple()) ctx.set_matrix(transform) ctx.translate(self.x, self.y - self.baseline) if self._outline is False: ctx.set_source_rgba(*self._fillcolor) PangoCairo.show_layout(ctx, self.layout) PangoCairo.update_layout(ctx, self.layout)
def _pre_render(self): # we use a new CairoContext to pre render the text rs = cairo.RecordingSurface(cairo.CONTENT_ALPHA, None) cr = cairo.Context(rs) if GI: cr = _UNSAFE_cairocffi_context_to_pycairo(cr) self._pang_ctx = PangoCairo.create_context(cr) self.layout = PangoCairo.create_layout(cr) # layout line spacing # TODO: the behaviour is not the same as nodebox yet # self.layout.set_spacing(int(((self._lineheight-1)*self._fontsize)*Pango.SCALE)) #pango requires an int casting # we pass pango font description and the text to the pango layout self.layout.set_font_description(self._fontface) self.layout.set_text(self.text, -1) # check if max text width is set and pass it to pango layout # text will wrap, meanwhile it checks if and indent has to be applied # indent is subordinated to width because it makes no sense on a single-line text block if self.width: self.layout.set_width(int(self.width) * Pango.SCALE) if self._indent: self.layout.set_indent(self._indent * Pango.SCALE) # set text alignment if self._align == "right": self.layout.set_alignment(Pango.Alignment.RIGHT) elif self._align == "center": self.layout.set_alignment(Pango.Alignment.CENTER) elif self._align == "justify": self.layout.set_alignment(Pango.Alignment.LEFT) self.layout.set_justify(True) else: self.layout.set_alignment(Pango.Alignment.LEFT)
def path(self): if not self._pang_ctx: self._pre_render() # here we create a new cairo.Context in order to hold the pathdata tempCairoContext = cairo.Context(cairo.RecordingSurface(cairo.CONTENT_ALPHA, None)) if GI: tempCairoContext = _UNSAFE_cairocffi_context_to_pycairo(tempCairoContext) tempCairoContext.move_to(self.x,self.y-self.baseline) # in here we create a pangoCairoContext in order to display layout on it # supposedly showlayout should work, but it fills the path instead, # therefore we use layout_path instead to render the layout to pangoCairoContext #tempCairoContext.show_layout(self.layout) PangoCairo.layout_path(tempCairoContext, self.layout) #here we extract the path from the temporal cairo.Context we used to draw on the previous step pathdata = tempCairoContext.copy_path() # creates a BezierPath instance for storing new shoebot path p = BezierPath(self._bot) # parsing of cairo path to build a shoebot path for item in pathdata: cmd = item[0] args = item[1] if cmd == PATH_MOVE_TO: p.moveto(*args) elif cmd == PATH_LINE_TO: p.lineto(*args) elif cmd == PATH_CURVE_TO: p.curveto(*args) elif cmd == PATH_CLOSE_PATH: p.closepath() # cairo function for freeing path memory return p
def _render(self, ctx=None): if not self._doRender: return ctx = ctx or self._get_context() if GI: ctx = _UNSAFE_cairocffi_context_to_pycairo(ctx) # we build a PangoCairo context linked to cairo context # then we create a pango layout # we update the context as we already used a null one on the pre-rendering # supposedly there should not be a big performance penalty self._pang_ctx = PangoCairo.create_context(ctx) if self._fillcolor is not None: # Go to initial point (CORNER or CENTER): transform = self._call_transform_mode(self._transform) if GI: transform = pycairo.Matrix(*transform.as_tuple()) ctx.set_matrix(transform) ctx.translate(self.x, self.y-self.baseline) if self._outline is False: ctx.set_source_rgba(*self._fillcolor) PangoCairo.show_layout(ctx, self.layout) PangoCairo.update_layout(ctx, self.layout)
def _pre_render(self): #we use a new CairoContext to pre render the text rs = cairo.RecordingSurface(cairo.CONTENT_ALPHA, None) cr = cairo.Context(rs) if GI: cr = _UNSAFE_cairocffi_context_to_pycairo(cr) self._pang_ctx = PangoCairo.create_context(cr) self.layout = PangoCairo.create_layout(cr) # layout line spacing # TODO: the behaviour is not the same as nodebox yet ## self.layout.set_spacing(int(((self._lineheight-1)*self._fontsize)*Pango.SCALE)) #pango requires an int casting # we pass pango font description and the text to the pango layout self.layout.set_font_description(self._fontface) self.layout.set_text(self.text, -1) # check if max text width is set and pass it to pango layout # text will wrap, meanwhile it checks if and indent has to be applied # indent is subordinated to width because it makes no sense on a single-line text block if self.width: self.layout.set_width(int(self.width)*Pango.SCALE) if self._indent: self.layout.set_indent(self._indent*Pango.SCALE) # set text alignment if self._align == "right": self.layout.set_alignment(Pango.Alignment.RIGHT) elif self._align == "center": self.layout.set_alignment(Pango.Alignment.CENTER) elif self._align == "justify": self.layout.set_alignment(Pango.Alignment.LEFT) self.layout.set_justify(True) else: self.layout.set_alignment(Pango.Alignment.LEFT)