def __init__(self, antialias): G15Text.__init__(self, antialias) PangoCairo.context_set_font_options(pango_context, self._create_font_options()) self.__pango_cairo_context = None self.valign = Pango.Alignment.CENTER self.__layout = Pango.Layout.new(pango_context)
def text_block(ctx, obj, text, font, lang="en-US", debug=False): ctx.save() lyt = PangoCairo.create_layout(ctx) pg_ctx = lyt.get_context() pg_ctx.set_language(Pango.Language.from_string(lang)) fo = cairo.FontOptions() fo.set_antialias(cairo.ANTIALIAS_SUBPIXEL) PangoCairo.context_set_font_options(pg_ctx, fo) font_family = font.family if not font.replace else font.replace pg_font = Pango.FontDescription("{} {}px".format(font_family, font.size)) lyt.set_font_description(pg_font) lyt.set_markup(text, -1) # force length calculation lyt.set_height(obj.height * Pango.SCALE * 1.5) # TODO what? lyt.set_width(obj.width * Pango.SCALE) lyt.set_alignment(Pango.Alignment.CENTER) #PangoCairo.update_layout(ctx, lyt) pg_size = lyt.get_pixel_size() ink, logical = lyt.get_pixel_extents() while ink.height > obj.height and pg_font.get_size() > 0: pg_font.set_size(pg_font.get_size() - Pango.SCALE) lyt.set_font_description(pg_font) ink, logical = lyt.get_pixel_extents() #x = obj["x"] - pext.x - pext.width / 2 #y = obj["y"] - pext.y - pext.height / 2 x = (obj.x + obj.width / 2) - ((ink.x + ink.width / 2)) y = (obj.y + obj.height / 2) - ((ink.y + ink.height / 2)) #x = obj["x"] #y = obj["y"] if debug: print("x,y: %s, %s" % (x, y)) ctx.translate(x, y) PangoCairo.update_layout(ctx, lyt) PangoCairo.layout_path(ctx, lyt) ctx.set_line_width(9.0) ctx.set_line_cap(cairo.LINE_CAP_ROUND) ctx.set_line_join(cairo.LINE_JOIN_ROUND) ctx.set_source_rgb(*font.color) PangoCairo.show_layout(ctx, lyt) ctx.new_path() ctx.restore() if debug: rectangle(ctx, ink.x, ink.y, ink.width, ink.height, True, 2.0, (0, 1, 0)) rectangle(ctx, obj.x, obj.y, obj.width, obj.height, True, 2.0, (0.8, 0.8, 0))
def text_path(context, font, size, text, debug=False): """Create a Pango text layout and return it as a Cairo path""" context.save() pg_layout = PangoCairo.create_layout(context) pg_context = pg_layout.get_context() font_options = cairo.FontOptions() font_options.set_antialias(cairo.ANTIALIAS_SUBPIXEL) PangoCairo.context_set_font_options(pg_context, font_options) font_descp = "{0} {1:d}".format(font, size) pg_layout.set_font_description(Pango.FontDescription(font_descp)) pg_layout.set_text(text, -1) # force length calculation PangoCairo.update_layout(context, pg_layout) # TODO watch out for ink & logical, need check extents = pg_layout.get_pixel_extents()[0] # TODO debug necessary? if debug: context.set_source_rgb(0, 0, 0) PangoCairo.show_layout(context, pg_layout) print("text_path: ({0}, {1}, {2}, {3})".format(extents.x, extents.y, extents.width, extents.height)) context.rectangle(extents.x, extents.y, extents.width, extents.height) context.set_line_width(1.0) context.set_line_join(cairo.LINE_JOIN_MITER) context.set_source_rgb(0, 0.8, 0) context.stroke() #PangoCairo.layout_path(context, pg_layout) PangoCairo.layout_line_path(context, pg_layout.get_line(0)) path = context.copy_path() # clear the path context.new_path() context.restore() return (path, extents, xheight(pg_layout).height)
def do_paint_numbers(self): self.number_tex = LW.CairoTexture.new(self.board_size, self.board_size) self.number_tex.enable() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) self.number_tex.disable() cr = self.number_tex.cairo_create() font_desc = Pango.FontDescription("Ubuntu Mono 18") for stone in self.stones: if stone.stone_color == Stone.WHITE: cr.set_source_rgba(0.0, 0.0, 0.0, stone.stone_alpha) elif stone.stone_color == Stone.BLACK: cr.set_source_rgba(1.0, 1.0, 1.0, stone.stone_alpha) layout = PangoCairo.create_layout(cr) pctx = layout.get_context() fo = cairo.FontOptions() fo.set_antialias(cairo.ANTIALIAS_SUBPIXEL) PangoCairo.context_set_font_options(pctx, fo) layout.set_font_description(font_desc) layout.set_text(str(stone.number), -1) if stone.number > 9: x_shift = 4 else: x_shift = 11 y_shift = 5 cr.move_to( stone.get_real_x() + self.board_size / 2 - self.square_size / 2 + x_shift, -stone.get_real_y() + self.board_size / 2 - self.square_size / 2 + y_shift) PangoCairo.show_layout(cr, layout) self.number_tex.update()
def run(self): """Create the output file. The derived class overrides EXT and create_cairo_surface """ # get paper dimensions paper_width = self.paper.get_size().get_width() * DPI / 2.54 paper_height = self.paper.get_size().get_height() * DPI / 2.54 page_width = round(self.paper.get_usable_width() * DPI / 2.54) page_height = round(self.paper.get_usable_height() * DPI / 2.54) left_margin = self.paper.get_left_margin() * DPI / 2.54 top_margin = self.paper.get_top_margin() * DPI / 2.54 # create cairo context and pango layout filename = self._backend.filename # Cairo can't reliably handle unicode filenames on Linux or # Windows, so open the file for it. with open(filename, 'wb') as fd: try: surface = self.create_cairo_surface(fd, paper_width, paper_height) surface.set_fallback_resolution(300, 300) cr = cairo.Context(surface) fontmap = PangoCairo.font_map_new() fontmap.set_resolution(DPI) pango_context = fontmap.create_context() options = cairo.FontOptions() options.set_hint_metrics(cairo.HINT_METRICS_OFF) PangoCairo.context_set_font_options(pango_context, options) layout = Pango.Layout(pango_context) PangoCairo.update_context(cr, pango_context) # paginate the document self.paginate_document(layout, page_width, page_height, DPI, DPI) body_pages = self._pages # build the table of contents and alphabetical index toc_page = None index_page = None toc = [] index = {} for page_nr, page in enumerate(body_pages): if page.has_toc(): toc_page = page_nr if page.has_index(): index_page = page_nr for mark in page.get_marks(): if mark.type == INDEX_TYPE_ALP: if mark.key in index: if page_nr + 1 not in index[mark.key]: index[mark.key].append(page_nr + 1) else: index[mark.key] = [page_nr + 1] elif mark.type == INDEX_TYPE_TOC: toc.append([mark, page_nr + 1]) # paginate the table of contents rebuild_required = False if toc_page is not None: toc_pages = self.__generate_toc(layout, page_width, page_height, toc) offset = len(toc_pages) - 1 if offset > 0: self.__increment_pages(toc, index, toc_page, offset) rebuild_required = True else: toc_pages = [] # paginate the index if index_page is not None: index_pages = self.__generate_index( layout, page_width, page_height, index) offset = len(index_pages) - 1 if offset > 0: self.__increment_pages(toc, index, index_page, offset) rebuild_required = True else: index_pages = [] # rebuild the table of contents and index if required if rebuild_required: if toc_page is not None: toc_pages = self.__generate_toc( layout, page_width, page_height, toc) if index_page is not None: index_pages = self.__generate_index( layout, page_width, page_height, index) # render the pages if toc_page is not None: body_pages = body_pages[:toc_page] + toc_pages + \ body_pages[toc_page+1:] if index_page is not None: body_pages = body_pages[:index_page] + index_pages + \ body_pages[index_page+1:] self._pages = body_pages for page_nr in range(len(self._pages)): cr.save() cr.translate(left_margin, top_margin) self.draw_page(page_nr, cr, layout, page_width, page_height, DPI, DPI) cr.show_page() cr.restore() # close the surface (file) surface.finish() except IOError as msg: errmsg = "%s\n%s" % (_("Could not create %s") % filename, msg) raise ReportError(errmsg) except Exception as err: errmsg = "%s\n%s" % (_("Could not create %s") % filename, err) raise ReportError(errmsg)
def _draw(self, cr, highlight, bounding): try: layout = self.layout except AttributeError: layout = PangoCairo.create_layout(cr) # set font options # see http://lists.freedesktop.org/archives/cairo/2007-February/009688.html context = layout.get_context() fo = cairo.FontOptions() fo.set_antialias(cairo.ANTIALIAS_DEFAULT) fo.set_hint_style(cairo.HINT_STYLE_NONE) fo.set_hint_metrics(cairo.HINT_METRICS_OFF) try: PangoCairo.context_set_font_options(context, fo) except TypeError: # XXX: Some broken pangocairo bindings show the error # 'TypeError: font_options must be a cairo.FontOptions or None' pass except KeyError: # cairo.FontOptions is not registered as a foreign # struct in older PyGObject versions. # https://git.gnome.org/browse/pygobject/commit/?id=b21f66d2a399b8c9a36a1758107b7bdff0ec8eaa pass # set font font = Pango.FontDescription() # https://developer.gnome.org/pango/stable/PangoMarkupFormat.html markup = GObject.markup_escape_text(self.t) if self.pen.bold: markup = '<b>' + markup + '</b>' if self.pen.italic: markup = '<i>' + markup + '</i>' if self.pen.underline: markup = '<span underline="single">' + markup + '</span>' if self.pen.strikethrough: markup = '<s>' + markup + '</s>' if self.pen.superscript: markup = '<sup><small>' + markup + '</small></sup>' if self.pen.subscript: markup = '<sub><small>' + markup + '</small></sub>' success, attrs, text, accel_char = Pango.parse_markup( markup, -1, '\x00') assert success layout.set_attributes(attrs) font.set_family(self.pen.fontname) font.set_absolute_size(self.pen.fontsize * Pango.SCALE) layout.set_font_description(font) # set text layout.set_text(text, -1) # cache it self.layout = layout else: PangoCairo.update_layout(cr, layout) descent = 2 # XXX get descender from font metrics width, height = layout.get_size() width = float(width) / Pango.SCALE height = float(height) / Pango.SCALE # we know the width that dot thinks this text should have # we do not necessarily have a font with the same metrics # scale it so that the text fits inside its box if width > self.w: f = self.w / width width = self.w # equivalent to width *= f height *= f descent *= f else: f = 1.0 y = self.y - height + descent if bounding is None or (y <= bounding[3] and bounding[1] <= y + height): x = self.x - 0.5 * (1 + self.j) * width cr.move_to(x, y) cr.save() cr.scale(f, f) cr.set_source_rgba(*self.select_pen(highlight).color) PangoCairo.show_layout(cr, layout) cr.restore() if 0: # DEBUG # show where dot thinks the text should appear cr.set_source_rgba(1, 0, 0, .9) x = self.x - 0.5 * (1 + self.j) * width cr.move_to(x, self.y) cr.line_to(x + self.w, self.y) cr.stroke()
def main(args) -> int: # open output archive with tarfile.open(args.out, "w:xz") as tar: for lang in languages(args.podir): # these are the 1.6:1 of some common(ish) screen widths if lang == "en": label_translated: str = args.label else: potfile = PotFile( os.path.join(args.podir, "{}.po".format(lang))) try: label_translated = potfile.msgs[args.label] except KeyError as _: continue if label_translated == args.label: continue for width, height in ( (640, 480), (800, 600), (1024, 768), (1280, 720), (1280, 800), (1366, 768), (1536, 864), (1600, 900), (1920, 1080), (1920, 1200), (2160, 1350), (2560, 1440), (3840, 2160), (5120, 2880), (5688, 3200), (7680, 4320), ): # generate PangoLanguage font_desc = "Sans %.2fpx" % (height / 32, ) fd = Pango.FontDescription(font_desc) font_option = cairo.FontOptions() font_option.set_antialias(cairo.ANTIALIAS_SUBPIXEL) l = Pango.Language.from_string(lang) # create surface img = cairo.ImageSurface(cairo.FORMAT_RGB24, 1, 1) cctx = cairo.Context(img) layout = PangoCairo.create_layout(cctx) pctx = layout.get_context() pctx.set_font_description(fd) pctx.set_language(l) fs = pctx.load_fontset(fd, l) PangoCairo.context_set_font_options(pctx, font_option) attrs = Pango.AttrList() length = len(bytes(label_translated, "utf8")) items = Pango.itemize(pctx, label_translated, 0, length, attrs, None) gs = Pango.GlyphString() Pango.shape(label_translated, length, items[0].analysis, gs) del img, cctx, pctx, layout def find_size(fs, f, data): """ find our size, I hope... """ (ink, log) = gs.extents(f) if ink.height == 0 or ink.width == 0: return False data.update({"log": log, "ink": ink}) return True data: Dict[str, Any] = {} fs.foreach(find_size, data) if len(data) == 0: print("Missing sans fonts") return 2 log = data["log"] ink = data["ink"] surface_height = math.ceil( max(ink.height, log.height) / Pango.SCALE) surface_width = math.ceil( max(ink.width, log.width) / Pango.SCALE) x = -math.ceil(log.x / Pango.SCALE) y = -math.ceil(log.y / Pango.SCALE) img = cairo.ImageSurface(cairo.FORMAT_RGB24, surface_width, surface_height) cctx = cairo.Context(img) layout = PangoCairo.create_layout(cctx) pctx = layout.get_context() PangoCairo.context_set_font_options(pctx, font_option) cctx.set_source_rgb(1, 1, 1) cctx.move_to(x, y) def do_write(fs, f, data): """ write out glyphs """ ink = gs.extents(f)[0] if ink.height == 0 or ink.width == 0: return False PangoCairo.show_glyph_string(cctx, f, gs) return True fs.foreach(do_write, None) img.flush() # convert to BMP and add to archive with io.BytesIO() as io_bmp: io_bmp.write(_cairo_surface_write_to_bmp(img)) filename = "fwupd-{}-{}-{}.bmp".format(lang, width, height) tarinfo = tarfile.TarInfo(filename) tarinfo.size = io_bmp.tell() io_bmp.seek(0) tar.addfile(tarinfo, fileobj=io_bmp) # success return 0
def _draw(self, cr, highlight, bounding): try: layout = self.layout except AttributeError: layout = PangoCairo.create_layout(cr) # set font options # see http://lists.freedesktop.org/archives/cairo/2007-February/009688.html context = layout.get_context() fo = cairo.FontOptions() fo.set_antialias(cairo.ANTIALIAS_DEFAULT) fo.set_hint_style(cairo.HINT_STYLE_NONE) fo.set_hint_metrics(cairo.HINT_METRICS_OFF) try: PangoCairo.context_set_font_options(context, fo) except TypeError: # XXX: Some broken pangocairo bindings show the error # 'TypeError: font_options must be a cairo.FontOptions or None' pass except KeyError: # cairo.FontOptions is not registered as a foreign # struct in older PyGObject versions. # https://git.gnome.org/browse/pygobject/commit/?id=b21f66d2a399b8c9a36a1758107b7bdff0ec8eaa pass # set font font = Pango.FontDescription() # https://developer.gnome.org/pango/stable/PangoMarkupFormat.html markup = GObject.markup_escape_text(self.t) if self.pen.bold: markup = '<b>' + markup + '</b>' if self.pen.italic: markup = '<i>' + markup + '</i>' if self.pen.underline: markup = '<span underline="single">' + markup + '</span>' if self.pen.strikethrough: markup = '<s>' + markup + '</s>' if self.pen.superscript: markup = '<sup><small>' + markup + '</small></sup>' if self.pen.subscript: markup = '<sub><small>' + markup + '</small></sub>' success, attrs, text, accel_char = Pango.parse_markup(markup, -1, '\x00') assert success layout.set_attributes(attrs) font.set_family(self.pen.fontname) font.set_absolute_size(self.pen.fontsize*Pango.SCALE) layout.set_font_description(font) # set text layout.set_text(text, -1) # cache it self.layout = layout else: PangoCairo.update_layout(cr, layout) descent = 2 # XXX get descender from font metrics width, height = layout.get_size() width = float(width)/Pango.SCALE height = float(height)/Pango.SCALE # we know the width that dot thinks this text should have # we do not necessarily have a font with the same metrics # scale it so that the text fits inside its box if width > self.w: f = self.w / width width = self.w # equivalent to width *= f height *= f descent *= f else: f = 1.0 y = self.y - height + descent if bounding is None or (y <= bounding[3] and bounding[1] <= y + height): x = self.x - 0.5 * (1 + self.j) * width cr.move_to(x, y) cr.save() cr.scale(f, f) cr.set_source_rgba(*self.select_pen(highlight).color) PangoCairo.show_layout(cr, layout) cr.restore() if 0: # DEBUG # show where dot thinks the text should appear cr.set_source_rgba(1, 0, 0, .9) x = self.x - 0.5 * (1 + self.j) * width cr.move_to(x, self.y) cr.line_to(x+self.w, self.y) cr.stroke()
def run(self): """Create the output file. The derived class overrides EXT and create_cairo_surface """ # get paper dimensions paper_width = self.paper.get_size().get_width() * DPI / 2.54 paper_height = self.paper.get_size().get_height() * DPI / 2.54 page_width = round(self.paper.get_usable_width() * DPI / 2.54) page_height = round(self.paper.get_usable_height() * DPI / 2.54) left_margin = self.paper.get_left_margin() * DPI / 2.54 top_margin = self.paper.get_top_margin() * DPI / 2.54 # create cairo context and pango layout filename = self._backend.filename # Cairo can't reliably handle unicode filenames on Linux or # Windows, so open the file for it. with open(filename, 'wb') as fd: try: surface = self.create_cairo_surface(fd, paper_width, paper_height) surface.set_fallback_resolution(300, 300) cr = cairo.Context(surface) fontmap = PangoCairo.font_map_new() fontmap.set_resolution(DPI) pango_context = fontmap.create_context() options = cairo.FontOptions() options.set_hint_metrics(cairo.HINT_METRICS_OFF) PangoCairo.context_set_font_options(pango_context, options) layout = Pango.Layout(pango_context) PangoCairo.update_context(cr, pango_context) # paginate the document self.paginate_document(layout, page_width, page_height, DPI, DPI) body_pages = self._pages # build the table of contents and alphabetical index toc_page = None index_page = None toc = [] index = {} for page_nr, page in enumerate(body_pages): if page.has_toc(): toc_page = page_nr if page.has_index(): index_page = page_nr for mark in page.get_marks(): if mark.type == INDEX_TYPE_ALP: if mark.key in index: if page_nr + 1 not in index[mark.key]: index[mark.key].append(page_nr + 1) else: index[mark.key] = [page_nr + 1] elif mark.type == INDEX_TYPE_TOC: toc.append([mark, page_nr + 1]) # paginate the table of contents rebuild_required = False if toc_page is not None: toc_pages = self.__generate_toc(layout, page_width, page_height, toc) offset = len(toc_pages) - 1 if offset > 0: self.__increment_pages(toc, index, toc_page, offset) rebuild_required = True else: toc_pages = [] # paginate the index if index_page is not None: index_pages = self.__generate_index(layout, page_width, page_height, index) offset = len(index_pages) - 1 if offset > 0: self.__increment_pages(toc, index, index_page, offset) rebuild_required = True else: index_pages = [] # rebuild the table of contents and index if required if rebuild_required: if toc_page is not None: toc_pages = self.__generate_toc(layout, page_width, page_height, toc) if index_page is not None: index_pages = self.__generate_index(layout, page_width, page_height, index) # render the pages if toc_page is not None: body_pages = body_pages[:toc_page] + toc_pages + \ body_pages[toc_page+1:] if index_page is not None: body_pages = body_pages[:index_page] + index_pages + \ body_pages[index_page+1:] self._pages = body_pages for page_nr in range(len(self._pages)): cr.save() cr.translate(left_margin, top_margin) self.draw_page(page_nr, cr, layout, page_width, page_height, DPI, DPI) cr.show_page() cr.restore() # close the surface (file) surface.finish() except IOError as msg: errmsg = "%s\n%s" % (_("Could not create %s") % filename, msg) raise ReportError(errmsg) except Exception as err: errmsg = "%s\n%s" % (_("Could not create %s") % filename, err) raise ReportError(errmsg)
def do_tool_operation(self, operation): cairo_context = self.start_tool_operation(operation) font_fam = operation['font_fam'] font_size = operation['font_size'] * 2 entire_text = operation['text'] background_color = operation['rgba2'] text_x = operation['x'] text_y = operation['y'] font_description_string = font_fam if operation['is_italic']: font_description_string += " Italic" if operation['is_bold']: font_description_string += " Bold" font_description_string += " " + str(font_size) font = Pango.FontDescription(font_description_string) p_context = PangoCairo.create_context(cairo_context) layout = Pango.Layout(p_context) layout.set_font_description(font) if not operation['antialias']: font_options = cairo.FontOptions() font_options.set_antialias(cairo.Antialias.NONE) font_options.set_hint_metrics(cairo.HintMetrics.OFF) font_options.set_hint_style(cairo.HintStyle.FULL) PangoCairo.context_set_font_options(p_context, font_options) ######################################################################## # Draw background ###################################################### if operation['background'] == 'rectangle': lines = entire_text.split('\n') line_y = text_y for line_text in lines: line_y = self._op_bg_rectangle(cairo_context, layout, \ background_color, text_x, line_y, line_text) elif operation['background'] == 'shadow': dist = max(min(int(font_size / 16), 4), 1) cairo_context.set_source_rgba(*background_color) self._show_text_at_coords(cairo_context, layout, entire_text, \ text_x + dist, text_y + dist) elif operation['background'] == 'thin-outline': cairo_context.set_source_rgba(*background_color) dist = min(int(font_size / 16), 10) dist = max(dist, 2) for dx in range(-dist, dist): for dy in range(-dist, dist): if abs(dx) + abs(dy) <= dist * 1.5: self._show_text_at_coords(cairo_context, layout, \ entire_text, text_x + dx, text_y + dy) # these `for`s and this `if` should outline with an octogonal shape, # which is close enough to a smooth round outline imho. elif operation['background'] == 'thick-outline': cairo_context.set_source_rgba(*background_color) dist = int(font_size / 10) dist = max(dist, 2) for dx in range(-dist, dist): for dy in range(-dist, dist): if abs(dx) + abs(dy) <= dist * 1.5: self._show_text_at_coords(cairo_context, layout, \ entire_text, text_x + dx, text_y + dy) # looks better, but so much computation for bullshit... ######################################################################## # Draw text ############################################################ cairo_context.set_source_rgba(*operation['rgba1']) self._show_text_at_coords(cairo_context, layout, entire_text, \ text_x, text_y) self.non_destructive_show_modif()
def set_canvas(self, canvas): G15Text.set_canvas(self, canvas) self.__layout = PangoCairo.create_layout(self.canvas) self.__pango_cairo_context = self.__layout.get_context() PangoCairo.context_set_font_options(self.__pango_cairo_context, self._create_font_options())
def text(ctx, obj, text, font, lang="en-US", debug=False): ctx.save() lyt = PangoCairo.create_layout(ctx) pg_ctx = lyt.get_context() pg_ctx.set_language(Pango.Language.from_string(lang)) fo = cairo.FontOptions() fo.set_antialias(cairo.ANTIALIAS_SUBPIXEL) PangoCairo.context_set_font_options(pg_ctx, fo) font_family = font.family if not font.replace else font.replace pg_font = Pango.FontDescription("{} {}px".format(font_family, font.size)) lyt.set_font_description(pg_font) lyt.set_text(text, -1) # force length calculation # lyt.set_height(obj["height"]) # lyt.set_width(obj["height"]) # PangoCairo.update_layout(ctx, lyt) pg_size = lyt.get_pixel_size() ink, logical = lyt.get_pixel_extents() if debug: print("pg: %s x %s" % pg_size) print("ink: %s %s %s %s" % (ink.x, ink.y, ink.width, ink.height)) print("logical: %s %s %s %s" % (logical.x, logical.y, logical.width, logical.height)) print("spacing: %s" % (lyt.get_spacing())) print("height: %s" % (lyt.get_height())) print("width: %s" % (lyt.get_width())) #x = obj["x"] - pext.x - pext.width / 2 #y = obj["y"] - pext.y - pext.height / 2 x = (obj.x + obj.width / 2) - ((ink.x + ink.width / 2)) y = (obj.y + obj.height / 2) - ((ink.y + ink.height / 2)) if debug: print("x,y: %s, %s" % (x, y)) ctx.translate(x, y) PangoCairo.update_layout(ctx, lyt) PangoCairo.layout_path(ctx, lyt) if font.outline: # set stroke outline stroke_width = font.size * 0.066 stroke_width = 5.0 if stroke_width < 5.0 else stroke_width ctx.set_line_width(stroke_width) ctx.set_line_cap(cairo.LINE_CAP_ROUND) ctx.set_line_join(cairo.LINE_JOIN_ROUND) ctx.set_source_rgb(*font.outline) ctx.stroke() ctx.set_source_rgb(*font.color) PangoCairo.show_layout(ctx, lyt) if debug: ctx.rectangle(ink.x, ink.y, ink.width, ink.height) ctx.set_line_width(2.0) ctx.set_line_join(cairo.LINE_JOIN_MITER) ctx.set_source_rgb(0, 0.8, 0) ctx.stroke() ctx.rectangle(logical.x, logical.y, logical.width, logical.height) ctx.set_line_width(2.0) ctx.set_line_join(cairo.LINE_JOIN_MITER) ctx.set_source_rgb(0, 0.2, 0.9) ctx.stroke() ctx.restore() if debug: #crosshair(ctx, obj["x"] + obj["width"] / 2, obj["y"] + obj["height"] / 2, 20, (1, 1, 1)) crosshair(ctx, obj.x, obj.y, 20, (1, 1, 1))