def border(self, title=None, clear=None): x1 = self.fontwidth / 2 y1 = self.fontheight / 2 x2 = x1 + (self.width_chars - 1) * self.fontwidth y2 = y1 + (self.height_chars - 1) * self.fontheight ctx = cairo.Context(self._surface) ctx.set_source_rgb(*colours[self.colour.foreground]) self._rect(ctx, self.fontwidth, x1, x2, y1, y2) ctx.stroke() if title: layout = PangoCairo.create_layout(ctx) layout.set_text(title, -1) layout.set_font_description(self.font) width, height = layout.get_pixel_size() ctx.set_source_rgb(*colours[self.colour.background]) x = self.fontwidth + 4 ctx.rectangle(x, 0, width, self.fontheight) ctx.fill() ctx.set_source_rgb(*colours[self.colour.foreground]) ctx.move_to(x, 0) PangoCairo.show_layout(ctx, layout) if clear: layout = PangoCairo.create_layout(ctx) layout.set_text(clear, -1) layout.set_font_description(self.font) width, height = layout.get_pixel_size() ctx.set_source_rgb(*colours[self.colour.background]) x = self.width - self.fontwidth - width - 4 y = self.height - self.fontheight ctx.rectangle(x, y, width, self.fontheight) ctx.fill() ctx.set_source_rgb(*colours[self.colour.foreground]) ctx.move_to(x, y) PangoCairo.show_layout(ctx, layout) self.damage(0, 0, self.height, self.width)
def _get_default_art(self, album_id, size): album_name = Objects["albums"].get_name(album_id) artist_id = Objects["albums"].get_artist_id(album_id) artist_name = Objects["artists"].get_name(artist_id) center = size / 2 surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, size, size) ctx = cairo.Context(surface) ctx.save() ctx.set_source_rgba(0.0, 0.0, 0.0, 0.0) ctx.move_to(0, 0) ctx.rectangle(0, 0, size, size) ctx.fill() ctx.save() ctx.arc(center, center, size/2, 0.0, 2.0 * pi); ctx.set_source_rgba(0.0, 0.0, 0.0, 1.0) ctx.fill() ctx.restore() ctx.save() r = uniform(0.05, 0.9) g = uniform(0.05, 0.9) b = uniform(0.05, 0.9) ctx.arc(center, center, size/6.5, 0.0, 2.0 * pi); ctx.set_source_rgba(r, g ,b, 0.8) ctx.fill() ctx.restore() ctx.save() ctx.arc(center, center, size/70, 0.0, 2.0 * pi); ctx.set_source_rgba(1, 1, 1, 1) ctx.fill() ctx.restore() ctx.save() ctx.set_source_rgba(1, 1, 1, 0.2) ctx.set_line_width(1) circle_size = size/6.5 while circle_size < size/2: ctx.arc(center, center, circle_size, 0.0, 2.0 * pi); ctx.stroke() circle_size += 2 ctx.restore() ctx.save() layout = PangoCairo.create_layout(ctx) layout.set_width(size/6.5*Pango.SCALE) layout.set_ellipsize(Pango.EllipsizeMode.MIDDLE) layout.set_markup('''<span foreground="white" font_desc="Sans %s">%s</span>''' % (size/60, escape(artist_name))) string_width = layout.get_size()[0]/Pango.SCALE string_height = layout.get_size()[1]/Pango.SCALE ctx.move_to(center - string_width/2, center - 10 - string_height) PangoCairo.show_layout(ctx, layout) ctx.restore() ctx.save() layout = PangoCairo.create_layout(ctx) layout.set_width(size/6.5*Pango.SCALE) layout.set_ellipsize(Pango.EllipsizeMode.MIDDLE) layout.set_markup('''<span foreground="white" font_desc="Sans %s">%s</span>''' % (size/60, escape(album_name))) string_width = layout.get_size()[0]/Pango.SCALE string_height = layout.get_size()[1]/Pango.SCALE ctx.move_to(center - string_width/2, center + 10 - string_height/2) PangoCairo.show_layout(ctx, layout) return Gdk.pixbuf_get_from_surface(surface, 0, 0, size, size)
def draw_results(self, cr): # Draw background. w = self.bounds.width - 400 h = self.bounds.height - 200 x = self.bounds.width/2 - w/2 y = self.bounds.height/2 - h/2 cr.set_source_rgb(0.762, 0.762, 0.762) cr.rectangle(x, y, w, h) cr.fill() cr.set_source_rgb(0, 0, 0) cr.rectangle(x, y, w, h) cr.stroke() # Draw text title = _('You finished!') + '\n' cr.set_source_rgb(0, 0, 0) pango_layout = PangoCairo.create_layout(cr) fd = Pango.FontDescription('Serif Bold') fd.set_size(16 * Pango.SCALE) pango_layout.set_font_description(fd) pango_layout.set_text(title.encode('utf-8'), len(title.encode('utf-8'))) size = pango_layout.get_size() tx = x + (w / 2) - (size[0] / Pango.SCALE) / 2 ty = y + 100 cr.move_to(tx, ty) PangoCairo.update_layout(cr, pango_layout) PangoCairo.show_layout(cr, pango_layout) report = '' report += _('Your score was %(score)d.') % { 'score': self.score } + '\n' if self.medal: report += _('You earned a %(type)s medal!') % self.medal + '\n' report += '\n' report += _('Press the ENTER key to continue.') cr.set_source_rgb(0, 0, 0) pango_layout = PangoCairo.create_layout(cr) fd = Pango.FontDescription('Times') fd.set_size(12 * Pango.SCALE) pango_layout.set_font_description(fd) pango_layout.set_text(report, len(report)) size = pango_layout.get_size() sx = x + w / 2 - (size[0] / Pango.SCALE) / 2 sy = y + 200 cr.move_to(sx, sy) PangoCairo.update_layout(cr, pango_layout) PangoCairo.show_layout(cr, pango_layout)
def show_text(cr, fd, label, size, x, y, page_width, page_height): fd.set_size(int(size * Pango.SCALE)) # TODO: RTL support # Pango doesn't like nulls if type(label) == str or type(label) == unicode: text = label.replace('\0', ' ').rstrip() else: text = str(label).rstrip() top = y left = x right = page_width - LEFT_MARGIN bottom = page_height - TOP_MARGIN * 2 sentences = text.split('\n') for s, sentence in enumerate(sentences): pl = PangoCairo.create_layout(cr) pl.set_font_description(fd) words = sentence.split(' ') for w, word in enumerate(words): pl.set_text(word + ' ', -1) width, height = pl.get_size() width /= Pango.SCALE height /= Pango.SCALE if x + width > right: x = LEFT_MARGIN y += size * 1.5 if y > bottom and \ (w < len(words) - 1 or s < len(sentences) - 1): cr.show_page() pl = PangoCairo.create_layout(cr) pl.set_font_description(fd) y = TOP_MARGIN x = LEFT_MARGIN pl.set_text(word + ' ', -1) cr.save() cr.translate(x, y) PangoCairo.update_layout(cr, pl) PangoCairo.show_layout(cr, pl) cr.restore() x += width x = LEFT_MARGIN y += size * 1.5 if y > bottom and s < len(sentences) - 1: cr.show_page() pl = PangoCairo.create_layout(cr) pl.set_font_description(fd) y = TOP_MARGIN x = LEFT_MARGIN
def _draw_text(cc, label, x, y, size, width, scale, heading, rgb, wrap=False): import textwrap final_scale = int(size * scale) * Pango.SCALE label = str(label) if wrap: label = '\n'.join(textwrap.wrap(label, int(width / scale))) pl = PangoCairo.create_layout(cc) fd = Pango.FontDescription(self._font) fd.set_size(final_scale) pl.set_font_description(fd) if isinstance(label, (str, unicode)): text = label.replace('\0', ' ') elif isinstance(label, (float, int)): text = str(label) else: text = label pl.set_text(str(label), len(str(label))) pl.set_width(int(width) * Pango.SCALE) cc.save() cc.translate(x, y) cc.rotate(heading * DEGTOR) cc.set_source_rgb(rgb[0] / 255., rgb[1] / 255., rgb[2] / 255.) PangoCairo.update_layout(cc, pl) PangoCairo.show_layout(cc, pl) cc.restore()
def _draw_time(self, cr): """Draw the time in colors (digital display). """ # TRANS: The format used to display the time for digital clock # You can add AM/PM indicator or use 12/24 format, for example # "%I:%M:%S %p". See # http://docs.python.org/lib/module-time.html for available # strftime formats If the display of the time is moving # horizontally, it means that the glyphs of the digits used in # the font don't have the same width. Try to use a Monospace # font. xgettext:no-python-format cr.save() markup = _('<markup>\ <span lang="en" font_desc="Sans,Monospace Bold 96">\ <span foreground="#005FE4">%I</span>:\ <span foreground="#00B20D">%M</span>:\ <span foreground="#E6000A">%S</span>%p</span></markup>') markup_time = self._time.strftime(markup) cr.set_source_rgba(*style.Color(self._COLOR_BLACK).get_rgba()) pango_layout = PangoCairo.create_layout(cr) d = int(self._center_y + 0.3 * self._radius) pango_layout.set_markup(markup_time) dx, dy = pango_layout.get_pixel_size() pango_layout.set_alignment(Pango.Alignment.CENTER) cr.translate(self._center_x - dx / 2.0, d - dy / 2.0) PangoCairo.update_layout(cr, pango_layout) PangoCairo.show_layout(cr, pango_layout) cr.restore()
def make_layout(self, ctx): layout = PangoCairo.create_layout(ctx) layout.set_text(self.text, -1) for k, v in self.attrs.items(): getattr(layout, "set_" + k)(v) PangoCairo.update_layout(ctx, layout) return layout
def _render_hits(self, surface): """Add the number of hits to a Cairo surface""" if not self.creature or not self.creature.hits: return ctx = cairo.Context(surface) ctx.set_antialias(cairo.ANTIALIAS_SUBPIXEL) layout = PangoCairo.create_layout(ctx) layout.set_alignment(Pango.Alignment.CENTER) # TODO Vary font size with scale desc = Pango.FontDescription("monospace 20") layout.set_font_description(desc) layout.set_text(str(self.creature.hits), -1) size = surface.get_width() layout.set_width(size) ctx.set_source_rgb(1, 0, 0) x = 0.5 * size y = 0.2 * size ctx.set_source_rgb(1, 1, 1) ctx.set_line_width(1) width, height = layout.get_pixel_size() ctx.rectangle(x - 0.5 * width, y, 0.9 * width, 0.8 * height) ctx.fill() ctx.set_source_rgb(1, 0, 0) ctx.move_to(x, y) PangoCairo.show_layout(ctx, layout)
def draw_text(ctx, x, y, w, h, text, color, fontname, size=12, justification='left'): # ctx.save() # ctx.translate(x, y) # ctx.rectangle(0, 0, w, h) # ctx.clip() layout = PangoCairo.create_layout(ctx) font = Pango.FontDescription('%s %s' % (fontname, size)) layout.set_font_description(font) layout.set_text(u'%s' % text, -1) layout.set_ellipsize(Pango.EllipsizeMode.END) layout.set_width(Pango.SCALE * w) PangoCairo.update_layout(ctx, layout) tw, th = layout.get_pixel_size() ctx.set_source_rgb(*color) if justification == 'center': ctx.move_to(x + (w*0.5 - tw*0.5), y + (h*0.5 - th*0.5)) elif justification == 'left': ctx.move_to(x, y + (h*0.5 - th*0.5)) elif justification == 'right': ctx.move_to(x+w-tw, y + (h*0.5 - th*0.5)) PangoCairo.show_layout(ctx, layout)
def draw_balloon(self, cr, b): x = int(b.x) y = int(b.y) # Draw the string. cr.set_source_rgb(0, 0, 0) cr.move_to(int(b.x), int(b.y + b.size / 2)) cr.line_to(int(b.x), int(b.y + b.size)) cr.stroke() # Draw the balloon. cr.save() cr.set_source_rgb(b.color[0], b.color[1], b.color[2]) cr.arc(b.x, b.y, b.size / 2, 0, 2 * math.pi) cr.fill() cr.restore() cr.set_source_rgb(0, 0, 0) pango_layout = PangoCairo.create_layout(cr) fd = Pango.FontDescription('Sans') fd.set_size(12 * Pango.SCALE) pango_layout.set_font_description(fd) pango_layout.set_text(b.word, len(b.word)) size = pango_layout.get_size() x = x - (size[0] / Pango.SCALE) / 2 y = y - (size[1] / Pango.SCALE) / 2 cr.move_to(x, y) PangoCairo.update_layout(cr, pango_layout) PangoCairo.show_layout(cr, pango_layout)
def _nvim_resize(self, columns, rows): da = self._drawing_area # create FontDescription object for the selected font/size font_str = '{0} {1}'.format(self._font_name, self._font_size) self._font, pixels, normal_width, bold_width = _parse_font(font_str) # calculate the letter_spacing required to make bold have the same # width as normal self._bold_spacing = normal_width - bold_width cell_pixel_width, cell_pixel_height = pixels # calculate the total pixel width/height of the drawing area pixel_width = cell_pixel_width * columns pixel_height = cell_pixel_height * rows gdkwin = da.get_window() content = cairo.CONTENT_COLOR self._cairo_surface = gdkwin.create_similar_surface(content, pixel_width, pixel_height) self._cairo_context = cairo.Context(self._cairo_surface) self._pango_layout = PangoCairo.create_layout(self._cairo_context) self._pango_layout.set_alignment(Pango.Alignment.LEFT) self._pango_layout.set_font_description(self._font) self._pixel_width, self._pixel_height = pixel_width, pixel_height self._cell_pixel_width = cell_pixel_width self._cell_pixel_height = cell_pixel_height self._screen = Screen(columns, rows) self._window.resize(pixel_width, pixel_height)
def __init__(self, text, style, context, width=None): self.layout = PangoCairo.create_layout(context) font = Pango.FontDescription() font.set_family(', '.join(style.font_family)) font.set_variant(PANGO_VARIANT[style.font_variant]) font.set_style(PANGO_STYLE[style.font_style]) font.set_absolute_size(Pango.units_from_double(style.font_size)) font.set_weight(style.font_weight) self.layout.set_font_description(font) self.layout.set_text(text, -1) self.layout.set_wrap(Pango.WrapMode.WORD) word_spacing = style.word_spacing letter_spacing = style.letter_spacing if letter_spacing == 'normal': letter_spacing = 0 if text and (word_spacing != 0 or letter_spacing != 0): word_spacing = Pango.units_from_double(word_spacing) letter_spacing = Pango.units_from_double(letter_spacing) markup = escape(text).replace( ' ', '<span letter_spacing="%i"> </span>' % ( word_spacing + letter_spacing,)) markup = '<span letter_spacing="%i">%s</span>' % ( letter_spacing , markup) attributes_list = Pango.parse_markup(markup, -1, '\x00')[1] self.layout.set_attributes(attributes_list) if width is not None: self.layout.set_width(Pango.units_from_double(width))
def do_draw(self, cairo_ctx): cairo_ctx.save() try: layout = PangoCairo.create_layout(cairo_ctx) if self.font: font = Pango.FontDescription() font.set_family(self.font) layout.set_font_description(font) layout.set_text(self.text, -1) txt_size = layout.get_size() if 0 in txt_size: return txt_factor = float(self.height) / txt_size[1] self.size = ( int(txt_size[0] * txt_factor), int(txt_size[1] * txt_factor) ) self.position = ( int(self.center_position[0] - (self.size[0] / 2)), int(self.center_position[1] - (self.size[1] / 2)) ) cairo_ctx.translate(self.position[0], self.position[1]) if txt_factor <= 0.0: return cairo_ctx.scale(txt_factor * Pango.SCALE, txt_factor * Pango.SCALE) cairo_ctx.set_source_rgb(0.0, 0.0, 0.0) PangoCairo.update_layout(cairo_ctx, layout) PangoCairo.show_layout(cairo_ctx, layout) finally: cairo_ctx.restore()
def do_draw(self, gpsmap, ctx): """ Draw all the messages """ ctx.save() font_size = "%s %d" % (self.font, self.size) font = Pango.FontDescription(font_size) descr = Pango.font_description_from_string(self.font) descr.set_size(self.size * Pango.SCALE) color = Gdk.color_parse(self.color) ctx.set_source_rgba(float(color.red / 65535.0), float(color.green / 65535.0), float(color.blue / 65535.0), 0.9) # transparency d_width = gpsmap.get_allocation().width d_width -= 100 ctx.restore() ctx.save() ctx.move_to(100, 5) layout = PangoCairo.create_layout(ctx) layout.set_font_description(descr) layout.set_indent(Pango.SCALE * 0) layout.set_alignment(Pango.Alignment.LEFT) layout.set_wrap(Pango.WrapMode.WORD_CHAR) layout.set_spacing(Pango.SCALE * 3) layout.set_width(d_width * Pango.SCALE) layout.set_text(self.message, -1) PangoCairo.show_layout(ctx, layout) ctx.restore() ctx.stroke()
def write_image(self, filename): w = 8 + len(self.ref)*7 h = CONFIG.image_size[1] # create an image where the text fits img = cairo.SVGSurface(filename, w, h) ctx = cairo.Context(img) # background fill ctx.rectangle(0, 0, w, h) ctx.set_source_rgb(*CONFIG.swiss_mobile_bgcolor) ctx.fill_preserve() # border ctx.set_line_width(CONFIG.image_border_width) levcol = CONFIG.level_colors[self.level] ctx.set_source_rgb(*levcol) ctx.stroke() # text ctx.set_source_rgb(*CONFIG.swiss_mobile_color) layout = PangoCairo.create_layout(ctx) layout.set_font_description(Pango.FontDescription(CONFIG.swiss_mobile_font)) layout.set_text(self.ref, -1) tw, th = layout.get_pixel_size() PangoCairo.update_layout(ctx, layout) ctx.move_to(w - tw - CONFIG.image_border_width/2, h - layout.get_iter().get_baseline()/Pango.SCALE - CONFIG.image_border_width/2) PangoCairo.show_layout(ctx, layout) ctx.show_page()
def __init__(self, x=0, y=0): self.x, self.y = x, y self._label_context = cairo.Context(cairo.ImageSurface(cairo.FORMAT_A1, 0, 0)) self.layout = pangocairo.create_layout(self._label_context) self.layout.set_font_description(pango.FontDescription(graphics._font_desc)) self.layout.set_markup("Hamster") # dummy self.height = self.layout.get_pixel_size()[1]
def draw_string(self, label, x, y, offsets=None): '''Draw a string at the specified point. offsets is an optional tuple specifying where the string will be drawn relative to the coordinates passed in; for instance, if offsets are (-1, -1) the string will be drawn with the bottom right edge at the given x, y. ''' fontname = "Sans Italic 14" # fontname = "Sans Italic 14" layout = PangoCairo.create_layout(self.ctx) desc = Pango.font_description_from_string(fontname) layout.set_font_description( desc) layout.set_text(label, -1) if offsets: width, height = layout.get_pixel_size() # # pango draws text with the upper left corner at x, y. # # So that's an offset of (1, 1). Adjust if offsets are different. # # XXX Cairo may do things differently. # xbearing, ybearing, width, height, xadvance, yadvance = \ # self.ctx.text_extents(label) if offsets[0] == 0: x -= int(width/2) elif offsets[0] != 1: x += int(width * offsets[0]) if offsets[1] != 1: y += int(height * offsets[1] - height/2) self.ctx.move_to(x, y) PangoCairo.show_layout (self.ctx, layout)
def do_draw_cb(self, widget, cr): # The do_draw_cb is called when the widget is asked to draw itself # with the 'draw' as opposed to old function 'expose event' # Remember that this will be called a lot of times, so it's usually # a good idea to write this code as optimized as it can be, don't # Create any resources in here. cr.translate ( RADIUS, RADIUS) layout = PangoCairo.create_layout (cr) layout.set_text("శ్రీమదాంధ్రమహాభారతము", -1) desc = Pango.font_description_from_string (FONT) layout.set_font_description( desc) rangec = range(0, N_WORDS) for i in rangec: width, height = 0,0 angle = (360. * i) / N_WORDS; cr.save () red = (1 + math.cos ((angle - 60) * math.pi / 180.)) / 2 cr.set_source_rgb ( red, 0, 1.0 - red) cr.rotate ( angle * math.pi / 180.) #/* Inform Pango to re-layout the text with the new transformation */ PangoCairo.update_layout (cr, layout) width, height = layout.get_size() cr.move_to ( - (float(width) / 1024.) / 2, - RADIUS) PangoCairo.show_layout (cr, layout) cr.restore()
def render_paragraph(cr, unit_scale, y, text, font = "Serif 6.5", align_top = False): x = INSET + SIDE_TITLE_WIDTH + SIDE_GAP cr.save() cr.move_to(x, y) # Remove the mm scale cr.scale(1.0 / unit_scale, 1.0 / unit_scale) layout = PangoCairo.create_layout(cr) m = re.match(r'(.*?)([0-9]+(\.[0-9]*)?)$', font) font_size = float(m.group(2)) font_size *= unit_scale / POINTS_PER_MM font = m.group(1) + str(font_size) fd = Pango.FontDescription.from_string(font) layout.set_font_description(fd) layout.set_width((CARD_WIDTH - x - INSET) * unit_scale * Pango.SCALE) layout.set_text(text, -1) (ink_rect, logical_rect) = layout.get_pixel_extents() if align_top: cr.rel_move_to(0, -logical_rect.height) PangoCairo.show_layout(cr, layout) cr.restore() return logical_rect.height / unit_scale
def write_image(self, filename): # get text size tw, th = _get_text_size(self.ref) # create an image where the text fits w = int(tw + CONFIG.text_border_width + 2 * CONFIG.image_border_width) h = CONFIG.image_size[1] img = cairo.SVGSurface(filename, w, h) ctx = cairo.Context(img) # background fill ctx.rectangle(0, 0, w, h) ctx.set_source_rgb(*CONFIG.text_bgcolor) ctx.fill_preserve() # border ctx.set_line_width(CONFIG.text_border_width) levcol = CONFIG.level_colors[self.level] ctx.set_source_rgb(*levcol) ctx.stroke() # reference text ctx.set_source_rgb(*CONFIG.text_color) layout = PangoCairo.create_layout(ctx) layout.set_font_description(Pango.FontDescription(CONFIG.text_font)) layout.set_text(self.ref, -1) PangoCairo.update_layout(ctx, layout) ctx.move_to((w-tw)/2, (h-CONFIG.text_border_width-layout.get_iter().get_baseline()/Pango.SCALE)/2.0) PangoCairo.show_layout(ctx, layout) ctx.show_page()
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) cr = driver.ensure_pycairo_context(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 do_render(self, cr, widget, bg_area, cell_area, flags): # Initialize values self.accum_header_width = 0 self.total_height = 0 context = widget.get_style_context() xpad = self.get_property('xpad') ypad = self.get_property('ypad') # Setting up font and layout font = Pango.FontDescription('Sans') layout = PangoCairo.create_layout(cr) layout.set_wrap(Pango.WrapMode.WORD) layout.set_font_description(font) layout.set_width(Pango.SCALE * cell_area.width) context.save() # Render header self.__render_reposted_icon(cr, cell_area) self.__render_username(context, cr, cell_area, layout) self.__render_protected_icon(cr, cell_area) self.__render_verified_icon(cr, cell_area) # Render body self.__render_message(context, cr, cell_area, layout) self.__render_datetime(context, cr, cell_area, layout) self.__render_reposted_by(context, cr, cell_area, layout) context.restore() return
def draw(self, cr, layout_info, hide_if_empty=False): if not hide_if_empty or self.obj.text: layout = create_layout(cr, self.obj.id_str() + " " + self.obj.text, layout_info, 6) xpos, ypos = show_layout(cr, layout, layout_info) cr.move_to(self.obj.x, self.obj.y) cr.line_to(xpos, ypos) cr.set_line_width(LINE_WIDTH) set_rgb_from_color_cycle(cr) cr.stroke() cr.set_fill_rule(cairo.FILL_RULE_EVEN_ODD) cr.set_source_rgba(0.0, 0.0, 1.0, 0.5) cr.set_line_width(LINE_WIDTH) self.draw_box(cr) text = str(self.obj.id[-1]) layout = PangoCairo.create_layout(cr) layout.set_text(text, len(text)) # Dont recreate the description all the time? font = Pango.FontDescription(layout_info['boxfont']) layout.set_font_description(font) cr.move_to(self.obj.x + LINE_WIDTH, self.obj.y + LINE_WIDTH) PangoCairo.show_layout(cr, layout) cr.new_path()
def sync_layout(self, size): """ Sync layout changes and calculate intrinsic size based on the parent's size. """ super(Text, self).sync_layout(size) width, height = self.size if self.__intrinsic_size_param == (width, height, self.text, self.font.name, self.font.size): self.intrinsic_size = self.__intrinsic_size_cache return self.__intrinsic_size_cache cr = create_cairo_context() layout = PangoCairo.create_layout(cr) layout.set_width(width * Pango.SCALE) layout.set_height(height * Pango.SCALE) layout.set_ellipsize(Pango.EllipsizeMode.END) layout.set_wrap(Pango.WrapMode.WORD_CHAR) layout.set_font_description(self.font.get_font_description()) layout.set_text(self.text, -1) PangoCairo.show_layout(cr, layout) self.__intrinsic_size_cache = \ int(min(width, Pango.units_to_double(layout.get_size()[0]))), \ int(min(height, Pango.units_to_double(layout.get_size()[1]))) self.__intrinsic_size_param = (width, height, self.text, self.font.name, self.font.size) self.intrinsic_size = self.__intrinsic_size_cache return self.__intrinsic_size_cache
def write(c, text, name, size, centered=False, at_top=False): pc = PangoCairo.create_context(c) font = Pango.FontDescription(name) font.set_size(int(round(size * Pango.SCALE))) lo = PangoCairo.create_layout(pc) lo.set_font_description(font) lo.set_text('X', -1) baseline_offset = lo.get_baseline() / Pango.SCALE if not at_top: c.rel_move_to(0, -baseline_offset) lo.set_font_description(font) lo.set_text(text, -1) if hasattr(lo, 'get_logical_extents'): extents = lo.get_logical_extents() ex = extents.get_width() / Pango.SCALE else: ex = size ex *= len(text) if centered: c.rel_move_to(-ex / 2, 0) PangoCairo.update_layout(c, lo) PangoCairo.show_layout(c, lo) c.rel_move_to(ex, 0) if not at_top: c.rel_move_to(0, -baseline_offset)
def draw(self, cc): if self.text: cc.save() x_scale = cc.get_matrix()[0] x_trans = cc.get_matrix()[4] cc.identity_matrix() #layout = cc.create_layout() layout = PangoCairo.create_layout(cc) layout.set_markup(self.text) layout.set_font_description(Pango.FontDescription(self.font)) txw, txh = layout.get_size() if self.conf['text_position'] in [POSITION_SW, POSITION_NW]: x_trans = x_trans - txw / Pango.SCALE - x_scale * self.conf['border'] layout.set_alignment(Pango.Alignment.RIGHT) else: x_trans = x_trans + x_scale * (1 + self.conf['border']) layout.set_alignment(Pango.Alignment.LEFT) if self.conf['text_position'] in [POSITION_NE, POSITION_NW]: y_trans = x_scale * self.conf['border'] / 2 else: y_trans = x_scale * (1 - self.conf['border'] / 2) - txh / Pango.SCALE cc.translate(x_trans, y_trans) # Draw text shadow cc.translate(1,1) cc.set_source_rgba(self.conf['text_shadow_color_r'], self.conf['text_shadow_color_g'], self.conf['text_shadow_color_b'], self.conf['text_shadow_color_a']) PangoCairo.show_layout(cc, layout) # Draw text cc.translate(-1,-1) cc.set_source_rgba(self.conf['text_color_r'], self.conf['text_color_g'], self.conf['text_color_b'], self.conf['text_color_a']) PangoCairo.show_layout(cc, layout) cc.restore()
def _create_layout(self, ctx): layout = PangoCairo.create_layout(ctx) font = Pango.FontDescription.from_string(self._font_descr) font.set_size(self._font_size * Pango.SCALE) layout.set_font_description(font) layout.set_markup(self._markup, -1) return layout
def __on_expose_event( self, widget, context ): """ Draws the text on the widget. This should be called indirectly by using self.queue_draw() """ #if self.__graphics_context is None: # self.__graphics_context = self.get_window().new_gc() #self.get_window().draw_layout(_context, # int(self.__x_offset), 0, self.__pango_layout, # self._fg) #context.show_text("test") if not self.__graphics_context: self.__graphics_context = context self.__graphics_context.set_source_rgb(1.0, 1.0, 1.0) #self.__graphics_context.set_source_rgb(self._fg) self.__pango_layout = PangoCairo.create_layout(self.__graphics_context) #self.__reset_widget() self.__pango_layout.set_markup(self.text, -1) PangoCairo.show_layout(self.__graphics_context, self.__pango_layout) lbl_x, lbl_y = self.__pango_layout.get_pixel_size() #self.set_size_request( -1, lbl_y ) print lbl_x, lbl_y self.__graphics_context.move_to(0, 0)
def getSize (self, ctxt, style): layout = PangoCairo.create_layout (ctxt) globalLayoutMutate (layout) layout.set_markup (self.markup) e = layout.get_extents ()[1] return e.width / S, e.height / S
def draw_text_bubble(self, cr, pointx, pointy): """ Draw bubble with information text """ margin_top = 12.0 margin_bottom = 12.0 margin_start = 24.0 margin_end = 24.0 # Corner radius rounded = 9.0 if not self._bubble_text: return alloc = self.get_allocation() layout = PangoCairo.create_layout(cr) font_description = Pango.font_description_from_string(BUBBLE_TEXT_FONT) layout.set_font_description(font_description) layout.set_alignment(Pango.Alignment.CENTER) layout.set_spacing(3) layout.set_markup(self._bubble_text) (ink_rect, logical_rect) = layout.get_pixel_extents() # Calculate the bubble size based on the text layout size width = logical_rect.width + margin_start + margin_end height = logical_rect.height + margin_top + margin_bottom if pointx < alloc.width / 2: x = pointx + 20 else: x = pointx - width - 20 y = pointy - height / 2 # Make sure it fits in the visible area x = self.clamp(x, 0, alloc.width - width) y = self.clamp(y, 0, alloc.height - height) cr.save() cr.translate(x, y) # Draw the bubble cr.new_sub_path() cr.arc(width - rounded, rounded, rounded, -math.pi / 2, 0) cr.arc(width - rounded, height - rounded, rounded, 0, math.pi / 2) cr.arc(rounded, height - rounded, rounded, math.pi / 2, math.pi) cr.arc(rounded, rounded, rounded, math.pi, math.radians(270)) cr.close_path() cr.set_source_rgba(0.2, 0.2, 0.2, 0.7) cr.fill() # And finally draw the text cr.set_source_rgb(1, 1, 1) cr.move_to(margin_start, margin_top) PangoCairo.show_layout(cr, layout) cr.restore()
def do_render(self, cr, widget, background_area, cell_area, flags): cr.set_source_rgb (FONT_COLOR[0], FONT_COLOR[1], FONT_COLOR[2]) layout = PangoCairo.create_layout(cr) layout.set_font_description(GENERAL_FONT_DESCRIPTION) layout.set_text(self.__formated_text, -1) cr.save() #PangoCairo.update_layout(cr, layout) cr.move_to(cell_area.x, cell_area.y) PangoCairo.show_layout(cr, layout) cr.restore()
def draw_text_at_pos(ctx, x, y, text, font_size=6): layout = PangoCairo.create_layout(ctx) font = Pango.FontDescription.from_string('Ubuntu Light') font.set_size(font_size * Pango.SCALE) layout.set_font_description(font) layout.set_markup(text, -1) fw, fh = [num / Pango.SCALE / 2 for num in layout.get_size()] ctx.move_to(x, y) PangoCairo.show_layout(ctx, layout)
def __init__(self, x=0, y=0, color=None): self.x = x self.y = y self.color = color self._label_context = cairo.Context( cairo.ImageSurface(cairo.FORMAT_A1, 0, 0)) self.layout = pangocairo.create_layout(self._label_context) self.layout.set_font_description( pango.FontDescription(graphics._font_desc)) self.set_text("Hamster") # dummy
def doLayout(self, ctxt, style, isfinal, w, h, bt, br, bl, bb): layout = PangoCairo.create_layout(ctxt) globalLayoutMutate(layout) layout.set_markup(self.markup) e = layout.get_extents()[1] # [1] -> use logical extents self._dx = self.hAlign * (w - e.width / S) + e.x / S self._dy = self.vAlign * (h - e.height / S) + e.y / S return base.LayoutInfo(minsize=(e.width / S, e.height / S))
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'] c1 = operation['rgba1'] c2 = operation['rgba2'] text_x = int(operation['x']) text_y = int(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) layout = PangoCairo.create_layout(cairo_context) layout.set_font_description(font) ######################################################################## # 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, c2, \ text_x, line_y, line_text) elif operation['background'] == 'shadow': dist = max(min(int(font_size / 16), 4), 1) cairo_context.set_source_rgba(c2.red, c2.green, c2.blue, c2.alpha) self._show_text_at_coords(cairo_context, layout, entire_text, \ text_x + dist, text_y + dist) elif operation['background'] == 'outline': cairo_context.set_source_rgba(c2.red, c2.green, c2.blue, c2.alpha) 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. ######################################################################## # Draw text ############################################################ cairo_context.set_source_rgba(c1.red, c1.green, c1.blue, c1.alpha) self._show_text_at_coords(cairo_context, layout, entire_text, \ text_x, text_y) self.non_destructive_show_modif()
def draw_event(self, doc, cr): #print ("Painting .. ", self.cnt) self.cnt += 1 ctx = self.get_style_context() fg_color = ctx.get_color(Gtk.StateFlags.NORMAL) #bg_color = ctx.get_background_color(Gtk.StateFlags.NORMAL) self.layout = PangoCairo.create_layout(cr) self.rect = self.get_allocation() self.cr = cr self.crh = CairoHelper(cr) # Paint white, ignore system BG border = 4 cr.set_source_rgba(255 / 255, 255 / 255, 255 / 255) cr.rectangle(border, border, self.rect.width - border * 2, self.rect.height - border * 2) cr.fill() # Draw connections cr.set_source_rgba(55 / 255, 55 / 255, 55 / 255) for aa in self.coll: for cc in aa.other: for bb in self.coll: if cc == bb.id: #print("connect draw", aa.text, bb.text) aac = aa.center() cr.move_to(aac[0], aac[1]) bbc = bb.center() cr.line_to(bbc[0], bbc[1]) cr.stroke() #for aa in self.coll: # aa.dump() sortx = sorted(self.coll, reverse=False, key=lambda item: item.zorder) # Draw objects #for aa in self.coll: for aa in sortx: try: aa.draw(cr, self) except: put_exception("Cannot draw " + str(type(aa))) #aa.dump() init = 0 for aa, bb in self.stroke: if init == 0: self.cr.move_to(aa, bb) else: self.cr.line_to(aa, bb) init += 1 self.cr.stroke()
def update_fonts(self): cr = self.main_tex.cairo_create() if not self.use_24_hour_clock: self.p_font = self.t_font.copy() self.p_font.set_size(self.p_font.get_size() / 3.0) self.d_font = self.t_font.copy() size = self.d_font.get_size() / 2.0 self.d_font.set_size(size) # Time font layout = PangoCairo.create_layout(cr) layout.set_font_description(self.t_font) layout.set_text("00:00", -1) t_width = layout.get_extents()[0].width / Pango.SCALE if not self.use_24_hour_clock: layout = PangoCairo.create_layout(cr) layout.set_font_description(self.p_font) layout.set_text("AM", -1) t_width += layout.get_extents()[0].width / Pango.SCALE + 5 # Date font layout = PangoCairo.create_layout(cr) layout.set_font_description(self.d_font) layout.set_text("00.00.0000", -1) d_width = layout.get_extents()[0].width / Pango.SCALE if d_width > t_width: while d_width > t_width: size -= Pango.SCALE self.d_font.set_size(size) layout.set_font_description(self.d_font) d_width = layout.get_extents()[0].width / Pango.SCALE elif d_width < t_width: while d_width < t_width: size += Pango.SCALE self.d_font.set_size(size) layout.set_font_description(self.d_font) d_width = layout.get_extents()[0].width / Pango.SCALE self.d_font.set_size(size - Pango.SCALE)
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 draw_string(self, cairo_ctx, string, x, y, is_center): pl = PangoCairo.create_layout(cairo_ctx) pl.set_text(string, -1) pl.set_font_description(self.font) width = pl.get_size()[0] / Pango.SCALE if is_center: x = x - width / 2 cairo_ctx.move_to(int(x), int(y)) PangoCairo.layout_path(cairo_ctx, pl)
def get_text_layout(cairo_context, text, size): c = cairo_context layout = PangoCairo.create_layout(c) layout.set_text(text, -1) font_name = constants.INTERFACE_FONT font = FontDescription(font_name + " " + str(size)) layout.set_font_description(font) return layout
def draw_string(self, label, x, y, offsets=None, xspacing=4, yspacing=4): '''Draw a string at the specified point. offsets is an optional tuple specifying where the string will be drawn relative to the coordinates passed in; for instance, if offsets are (-1, -1) the string will be drawn with the bottom right edge at the given x, y. ''' fontname = "Sans Italic 12" layout = PangoCairo.create_layout(self.ctx) desc = Pango.font_description_from_string(fontname) layout.set_font_description(desc) layout.set_text(label, -1) if offsets: width, height = layout.get_pixel_size() # # pango draws text with the upper left corner at x, y. # # So that's an offset of (1, 1). Adjust if offsets are different. # # XXX Cairo may do things differently. # xbearing, ybearing, width, height, xadvance, yadvance = \ # self.ctx.text_extents(label) if offsets[0] == 0: x -= int(width / 2) elif offsets[0] != 1: x += int(width * offsets[0]) if offsets[0] < 1: xspacing = -xspacing # Weirdly, height is quite a bit taller than the text height height *= .55 if offsets[1] == 0: y -= int(height / 2) else: y -= int(height * (offsets[1] + .5)) if offsets[1] < 1: yspacing = -yspacing # Will the text be off the screen? if x < 0: x += width xspacing = -xspacing elif x + width > self.width: x -= width xspacing = -xspacing if y < 0: y += height yspacing = -yspacing elif y + height > self.height: y -= height yspacing = -yspacing self.ctx.move_to(x + xspacing, y + yspacing) PangoCairo.show_layout(self.ctx, layout)
def renderText(cr, x, y, text, fontStr=""): global fontDesc if fontStr == "": fontStr = fontDesc layout = PangoCairo.create_layout(cr) layout.set_font_description(Pango.font_description_from_string(fontStr)) layout.set_alignment(Pango.Alignment.CENTER) layout.set_text(text, -1) #layout.set_markup(text, -1) cr.move_to(x, y) PangoCairo.show_layout(cr, layout)
def draw_text(self, text, font_desc, cr, x, y, color): layout = PangoCairo.create_layout(cr) layout.set_text(text, -1) desc = Pango.FontDescription(font_desc) layout.set_font_description(desc) cr.set_source_rgb(*color) cr.move_to(x, y) PangoCairo.update_layout(cr, layout) PangoCairo.show_layout(cr, layout)
def paintAt(self, ctxt, x, y, color): layout = PangoCairo.create_layout(ctxt) globalLayoutMutate(layout) layout.set_markup(self.markup) e = layout.get_extents()[1] ctxt.save() ctxt.set_source_rgb(*color) ctxt.move_to(x + e.x / S, y + e.y / S) PangoCairo.show_layout(ctxt, layout) ctxt.restore()
def _draw_key(self, k, cr): bounds = self.get_allocation() # HACK: this is a hack used when the widget is not shown yet, # in that case bounds will be gtk.gdk.Rectangle(-1, -1, 1, 1) # and the key will be outside the canvas. This is used only # for the first key that appears below the instructions if bounds.x == -1: screen_x = screen_y = 0 else: screen_x = int(bounds.width - self.image.width) / 2 screen_y = int(bounds.height - self.image.height) / 2 x1 = k['key-x'] + screen_x y1 = k['key-y'] + screen_y x2 = x1 + k['key-width'] y2 = y1 + k['key-height'] corner = 5 points = [(x1 + corner, y1), (x2 - corner, y1), (x2, y1 + corner), (x2, y2 - corner), (x2 - corner, y2), (x1 + corner, y2), (x1, y2 - corner), (x1, y1 + corner)] cr.new_path() cr.set_source_rgb(0.396, 0.698, 0.392) cr.set_line_width(2) for point in points: cr.line_to(*point) cr.close_path() cr.fill_preserve() cr.stroke() text = '' if k['key-label']: text = k['key-label'] else: text = self.get_letter_for_key_state_group(k, self.active_state, self.active_group) cr.set_source_rgb(0, 0, 0) pango_layout = PangoCairo.create_layout(cr) fd = Pango.FontDescription('Monospace') fd.set_size(10 * Pango.SCALE) pango_layout.set_font_description(fd) if type(text) is bytes: pango_layout.set_text(text.decode('utf-8'), len(text.decode('utf-8'))) else: pango_layout.set_text(text, len(text)) cr.move_to(x1 + 8, y2 - 23) PangoCairo.update_layout(cr, pango_layout) PangoCairo.show_layout(cr, pango_layout)
def _create_layout_with_font(self, ctx, pc, font_desc): layout = PangoCairo.create_layout(ctx) layout.set_font_description(font_desc) font = layout.get_context().load_font(font_desc) font_metric = font.get_metrics() fascent = float(font_metric.get_ascent()) / Pango.SCALE fheight = float((font_metric.get_ascent() + font_metric.get_descent()) / Pango.SCALE) em = float(font_metric.get_approximate_char_width()) / Pango.SCALE return layout, fascent, fheight, em
def doPaint(self, ctxt, style): layout = PangoCairo.create_layout(ctxt) globalLayoutMutate(layout) layout.set_markup(self.markup) ctxt.save() style.apply(ctxt, self.style) ctxt.set_source_rgb(*style.getColor(self.color)) ctxt.move_to(self.border[3] + self._dx, self.border[0] + self._dy) PangoCairo.show_layout(ctxt, layout) ctxt.restore()
def line_to_render_object(self, line, in_code): md = re.match(r'^SVG: +([^\s#*=]+)(?:#([0-9]+)(=)?)?\s*$', line) if md: max_layer = md.group(2) if max_layer is not None: max_layer = int(max_layer) exact = bool(md.group(3)) return ImageRenderObject(md.group(1), max_layer, exact) if in_code: font = "Mono" font_size = 10 else: font = "Sans" font_size = 16 layout = PangoCairo.create_layout(self.cr) if not in_code: md = re.match(r'(#+) +(.*)', line) if md: header_level = len(md.group(1)) font_size *= 1.2 ** (6 - header_level) line = md.group(2) self.add_index_item(header_level, line) else: md = re.match(r'((?: )*)\* +(.*)', line) if md: spaces = len(md.group(1)) // 2 line = "\u2022\t" + md.group(2) tab_stop = 10 * POINTS_PER_MM * Pango.SCALE if spaces > 0: n_tabs = 2 else: n_tabs = 1 tab_array = Pango.TabArray(n_tabs, False) if spaces > 0: line = "\t" + line tab_array.set_tab(0, Pango.TabAlign.LEFT, tab_stop * spaces) tab_array.set_tab(n_tabs - 1, Pango.TabAlign.LEFT, tab_stop * (spaces + 1)) layout.set_tabs(tab_array) layout.set_indent(-tab_stop * (spaces + 1)) fd = Pango.FontDescription.from_string("{} {}".format(font, font_size)) layout.set_font_description(fd) layout.set_width(PAGE_WIDTH * 0.7 * POINTS_PER_MM * Pango.SCALE) layout.set_text(line, -1) return LayoutRenderObject(layout)
def create_layout(cr, text, layout_info, indent=0): layout = PangoCairo.create_layout(cr) layout.set_text(text, -1) # Dont recreate the description all the time? font = Pango.FontDescription(layout_info['font']) layout.set_font_description(font) layout.set_width((layout_info['twidth'] - 2 * indent) * Pango.SCALE) layout.set_wrap(Pango.WrapMode.WORD_CHAR) layout.indent = indent return layout
def draw(self, context): if not PangoCairo.create_layout(context): self.recalc_edges() if not self.editing: # We should draw the entire bounding box around ourselves # We should also have our coordinates figured out. If not, scream! if not self.ul or not self.lr: print("Warning: Trying to draw unfinished box " + str(self.identity) + ". Aborting.") return style = utils.STYLE_EXTENDED_CONTENT if len(self.extended_buffer.get_text()) == 0: style = utils.STYLE_NORMAL utils.draw_thought_outline(context, self.ul, self.lr, self.background_color, self.am_selected, self.am_primary, style) else: ux, uy = self.ul if prefs.get_direction() == Gtk.TextDirection.LTR: context.move_to(ux, uy + 5) context.line_to(ux, uy) context.line_to(ux + 5, uy) else: lx = self.lr[0] context.move_to(lx, uy + 5) context.line_to(lx, uy) context.line_to(lx - 5, uy) context.stroke() textx, texty = (self.text_location[0], self.text_location[1]) if (self.foreground_color): r, g, b = utils.Gtk_to_cairo_color(self.foreground_color) else: r, g, b = utils.default_colors["text"] context.set_source_rgb(r, g, b) context.move_to(textx, texty) context.show_layout(self.layout) if self.editing: if self.preedit: strong, weak = self.layout.get_cursor_pos(self.index + self.preedit[2]) else: strong, weak = self.layout.get_cursor_pos(self.index) (startx, starty, curx, cury) = strong startx /= Pango.SCALE starty /= Pango.SCALE curx /= Pango.SCALE cury /= Pango.SCALE context.move_to(textx + startx, texty + starty) context.line_to(textx + startx, texty + starty + cury) context.stroke() context.set_source_rgb(0, 0, 0) context.stroke()
def on_draw(self, widget, cr): areaW = self.get_allocation().width areaH = self.get_allocation().height # fill background color cr.set_source_rgb(0.5, 0.1, 0.1) cr.paint() cr.set_font_size(self.size) cr.select_font_face("Microsoft JhengHei UI Bold") (x, y, width, height, dx, dy) = cr.text_extents("香港九龍尖沙咀東") contentWidth = width + self.padding # Get nunmber will Repeat msgRepeat = int(areaW / contentWidth) desc = Pango.font_description_from_string( "Microsoft JhengHei UI Bold" + " " + str(self.size)) # set text color cr.set_source_rgba(0.0, 1.0, 0.0, 1.0) drawX = self.fristPosX for n in range(msgRepeat + 2): # print(drawX) layout = PangoCairo.create_layout(cr) layout.set_font_description(desc) cr.move_to(drawX, areaH / 2) layout.set_text("香港九龍尖沙咀東", -1) # cr.text_path("香港") PangoCairo.show_layout(cr, layout) drawX = drawX + contentWidth if abs(self.fristPosX) < contentWidth: self.fristPosX = self.fristPosX - 1 else: self.fristPosX = 0 # print(self.fristPosX) # if self.startdraw: # rx = areaW - self.movex # self.movex = self.movex + 1 # else: # rx = areaW # self.startdraw = True # cr.move_to(self.fristPosX, areaH / 2) # layout = PangoCairo.create_layout(cr) # desc = Pango.font_description_from_string( # "Microsoft JhengHei UI Bold" + " " + str(self.size) # ) # layout.set_font_description(desc) # cr.set_source_rgba(0.0, 1.0, 0.0, 1.0) # layout.set_text("香港九龍尖沙咀", -1) cr.clip()
def render_size(font, weight, size, spacing, text, width=1000, lines=1, cache_key=None): """Check whether rendered text fits.""" configure_fontconfig() # Setup Pango/Cairo surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width * 2, lines * size * 4) context = cairo.Context(surface) layout = PangoCairo.create_layout(context) # Load and configure font fontdesc = Pango.FontDescription.from_string(font) fontdesc.set_size(size * Pango.SCALE) if weight: fontdesc.set_weight(weight) layout.set_font_description(fontdesc) # This seems to be only way to set letter spacing # See https://stackoverflow.com/q/55533312/225718 layout.set_markup( '<span letter_spacing="{}">{}</span>'.format(spacing, escape(text)) ) # Set width and line wrapping layout.set_width(width * Pango.SCALE) layout.set_wrap(Pango.WrapMode.WORD) # Calculate dimensions line_count = layout.get_line_count() pixel_size = layout.get_pixel_size() # Show text PangoCairo.show_layout(context, layout) # Render box around desired size expected_height = lines * pixel_size.height / line_count context.new_path() context.set_source_rgb(246, 102, 76) context.set_source_rgb(246.0 / 255, 102.0 / 255, 76.0 / 255) context.set_line_width(1) context.move_to(1, 1) context.line_to(width, 1) context.line_to(width, expected_height) context.line_to(1, expected_height) context.line_to(1, 1) context.stroke() if cache_key: with BytesIO() as buff: surface.write_to_png(buff) cache.set(cache_key, buff.getvalue()) return pixel_size, line_count
def draw_label(self, cr): ''' Draw the label based on its attributes ''' my_width = self.rect[2] - self._margins[0] - self._margins[2] if my_width < 0: my_width = 0 my_height = self.rect[3] - self._margins[1] - self._margins[3] for i in range(len(self.labels)): pl = PangoCairo.create_layout(cr) pl.set_text(str(self.labels[i]), -1) self._fd.set_size(int(self._scale[i] * Pango.SCALE)) pl.set_font_description(self._fd) w = pl.get_size()[0] / Pango.SCALE if w > my_width: if self._rescale[i]: self._fd.set_size( int(self._scale[i] * Pango.SCALE * my_width / w)) pl.set_font_description(self._fd) w = pl.get_size()[0] / Pango.SCALE else: j = len(self.labels[i]) - 1 while(w > my_width and j > 0): pl.set_text( "…" + self.labels[i][len(self.labels[i]) - j:], -1) self._fd.set_size(int(self._scale[i] * Pango.SCALE)) pl.set_font_description(self._fd) w = pl.get_size()[0] / Pango.SCALE j -= 1 if self._x_pos[i] is not None: x = int(self.rect[0] + self._x_pos[i]) elif self._horiz_align[i] == 'center': x = int(self.rect[0] + self._margins[0] + (my_width - w) / 2) elif self._horiz_align[i] == 'left': x = int(self.rect[0] + self._margins[0]) else: # right x = int(self.rect[0] + self.rect[2] - w - self._margins[2]) h = pl.get_size()[1] / Pango.SCALE if self._y_pos[i] is not None: y = int(self.rect[1] + self._y_pos[i]) elif self._vert_align[i] == 'middle': y = int(self.rect[1] + self._margins[1] + (my_height - h) / 2) elif self._vert_align[i] == 'top': y = int(self.rect[1] + self._margins[1]) else: # bottom y = int(self.rect[1] + self.rect[3] - h - self._margins[3]) cr.save() cr.translate(x, y) cr.set_source_rgb(self._colors[i][0], self._colors[i][1], self._colors[i][2]) PangoCairo.update_layout(cr, pl) PangoCairo.show_layout(cr, pl) cr.restore()
def __init__(self, **kwargs): graphics.Sprite.__init__(self, **kwargs) self.x_align = 0 self.y_align = 0 self.values = [] self._label_context = cairo.Context(cairo.ImageSurface(cairo.FORMAT_A1, 0, 0)) self.layout = pangocairo.create_layout(self._label_context) self.layout.set_font_description(pango.FontDescription(graphics._font_desc)) self.layout.set_markup("Hamster") # dummy self.label_height = self.layout.get_pixel_size()[1] self._max = 0
def draw_instructions(self, cr): # Draw instructions. cr.set_source_rgb(0, 0, 0) pango_layout = PangoCairo.create_layout(cr) pango_layout.set_font_description(Pango.FontDescription('Times 14')) text = _('Type the words to pop the balloons!') pango_layout.set_text(text, len(text)) size = pango_layout.get_size() x = (self.bounds.width - size[0] / Pango.SCALE) / 2 y = self.bounds.height - 20 - size[1] / Pango.SCALE cr.move_to(x, y) PangoCairo.update_layout(cr, pango_layout) PangoCairo.show_layout(cr, pango_layout)
def area_draw(self, widget, cr): layout = PangoCairo.create_layout(cr) pctx = layout.get_context() print("PangoContext: %s (%s)" % (pctx, type(pctx))) #print("PangoContext: %s" % dir(pctx)) print(" font map=%s" % pctx.get_font_map()) #print(" families=%s" % pctx.list_families()) print(" font description=%s" % pctx.get_font_description()) print(" language=%s" % pctx.get_language()) print(" get_base_dir=%s" % pctx.get_base_dir()) for y in range(2): for x in range(2): cr.save() antialias = tuple(ANTIALIAS.keys())[y * 2 + x] label = ANTIALIAS[antialias] self.paint_pattern(cr, x, y, antialias, label, BLACK, WHITE) self.paint_pattern(cr, x, y + 2, antialias, label, WHITE, BLACK) cr.restore() alloc = widget.get_allocated_size()[0] w, h = alloc.width, alloc.height bw = w // 4 bh = h // 4 #copy ANTIALIAS_NONE to right hand side, #then substract each image for background, foreground, yoffset in ( (BLACK, WHITE, 0), (WHITE, BLACK, 2), ): for y in range(2): for x in range(2): cr.save() #paint antialias value: antialias = tuple(ANTIALIAS.keys())[y * 2 + x] v = self.paint_to_image(bw, bh, background, foreground, antialias) none = self.paint_to_image(bw, bh, background, foreground) #xor the buffers vdata = v.get_data() ndata = none.get_data() for i in range(len(vdata)): vdata[i] = vdata[i] ^ ndata[i] #paint the resulting image: cr.set_operator(cairo.OPERATOR_SOURCE) cr.set_source_surface(v, (x + 2) * bw, (y + yoffset) * bh) cr.rectangle((x + 2) * bw, (y + yoffset) * bh, bw, bh) cr.clip() cr.paint() cr.restore()
def draw_text_adjusted(ctx, text, x, y, width, height, max_char_number=None, text_color=(0, 0, 0, 1), align=Pango.Alignment.CENTER, width_adjust=0.7, height_adjust=0.8): """ Draw a text adjusted to a maximum character number Args: ctx (cairo.Context): The cairo context to use to draw. text (str): the text to draw. x/y (numbers): The position on the canvas. width/height (numbers): The area we want to write into (cairo units). max_char_number (number): If set a maximum character number. """ pc = PangoCairo.create_context(ctx) layout = PangoCairo.create_layout(ctx) layout.set_width(int(width_adjust * width * Pango.SCALE)) layout.set_alignment(align) fd = Pango.FontDescription("Georgia Bold") fd.set_size(Pango.SCALE) layout.set_font_description(fd) if max_char_number: # adjust size with the max character number layout.set_text('0'*max_char_number, -1) adjust_font_size(layout, fd, width_adjust*width, height_adjust*height) # set the real text layout.set_text(text, -1) if not max_char_number: adjust_font_size(layout, fd, width_adjust*width, height_adjust*height) # draw ink, logical = layout.get_extents() ctx.save() ctx.set_source_rgba(*text_color) if align == Pango.Alignment.CENTER: x = x - (ink.width/2.0)/Pango.SCALE - int(float(ink.x)/Pango.SCALE) y = y - (ink.height/2.0)/Pango.SCALE - int(float(ink.y)/Pango.SCALE) else: y = y - (ink.height/2.0)/Pango.SCALE - ink.y/Pango.SCALE ctx.translate(x, y) if align == Pango.Alignment.LEFT: # Hack to workaround what appears to be a Cairo bug: without # drawing a rectangle here, the translation above is not taken # into account for rendering the text. ctx.rectangle(0, 0, 0, 0) PangoCairo.update_layout(ctx, layout) PangoCairo.show_layout(ctx, layout) ctx.restore()
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'] c1 = operation['rgba1'] c2 = operation['rgba2'] text_x = int(operation['x']) text_y = int(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) layout = PangoCairo.create_layout(cairo_context) layout.set_font_description(font) ######################################################################## # Draw background for the line ######################################### 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, c2, \ text_x, line_y, line_text) elif operation['background'] == 'shadow': dist = max(min(int(font_size / 16), 4), 1) cairo_context.set_source_rgba(c2.red, c2.green, c2.blue, c2.alpha) self._show_text_with_options(cairo_context, layout, entire_text, \ text_x + dist, text_y + dist) elif operation['background'] == 'outline': cairo_context.set_source_rgba(c2.red, c2.green, c2.blue, c2.alpha) dist = max(min(int(font_size / 16), 8), 1) for dx in range(-dist, dist): for dy in range(-dist, dist): self._show_text_with_options(cairo_context, layout, \ entire_text, text_x + dx, text_y + dy) ######################################################################## # Draw text for the line ############################################### cairo_context.set_source_rgba(c1.red, c1.green, c1.blue, c1.alpha) self._show_text_with_options(cairo_context, layout, entire_text, \ text_x, text_y) self.non_destructive_show_modif()
def draw_Token(context, x, y, construct, options, forward): margin = options.raildraw_token_margin h_padding = options.raildraw_token_padding v_padding = options.raildraw_token_padding if construct.type not in (rr.TEXT, rr.ANYCASE): h_padding += options.raildraw_token_rect_padding layout = PangoCairo.create_layout(context) layout.set_text(construct.text, -1) layout.set_font_description(get_font_for_token(options, construct)) text_width, text_height = layout.get_pixel_size() if construct.type in (rr.TEXT, rr.ANYCASE): diameter = v_padding + text_height + v_padding radius = diameter / 2 context.move_to(x + margin + radius + h_padding, y + margin + v_padding) PangoCairo.show_layout(context, layout) context.move_to(x + margin + radius, y + margin) context.line_to( x + margin + radius + h_padding + text_width + h_padding, y + margin) context.arc(x + margin + radius + h_padding + text_width + h_padding, y + margin + radius, radius, radians(270), radians(90)) context.line_to(x + margin + radius, y + margin + v_padding + text_height + v_padding) context.arc(x + margin + radius, y + margin + radius, radius, radians(90), radians(270)) context.close_path( ) # Shouldn't have any effect since we're already at # the start, but just in case context.stroke() width = margin + radius + h_padding + text_width + h_padding + radius + margin else: context.move_to(x + margin + h_padding, y + margin + v_padding) PangoCairo.show_layout(context, layout) context.move_to(x + margin, y + margin) context.line_to(x + margin + h_padding + text_width + h_padding, y + margin) context.line_to(x + margin + h_padding + text_width + h_padding, y + margin + v_padding + text_height + v_padding) context.line_to(x + margin, y + margin + v_padding + text_height + v_padding) context.close_path() context.stroke() width = margin + h_padding + text_width + h_padding + margin context.move_to(x, y + margin + v_padding + (text_height / 2)) context.line_to(x + margin, y + margin + v_padding + (text_height / 2)) context.stroke() context.move_to(x + width, y + margin + v_padding + (text_height / 2)) context.line_to(x + width - margin, y + margin + v_padding + (text_height / 2)) context.stroke()
def generate_thumb(self, book): if cairo is None: raise RuntimeError('cairo library is missing. must install it.') H = 128 W = 128 LINE_WIDTH = 4 TEMPLATE = '{.title}' if type(book) is int: book = self.get_scoped_session().query(db.Book).get(book) path = self.get_path('res/thumbs/{}.svg'.format(book.id), writable=True) path.parent.mkdir(parents=True, exist_ok=True) surface = cairo.SVGSurface(str(path), W, H) ctx = cairo.Context(surface) ctx.set_source_rgb(1, 1, 1) ctx.rectangle(0, 0, W, H) ctx.fill() ctx.set_line_width(LINE_WIDTH) x = y = LINE_WIDTH / 2 w = W - LINE_WIDTH h = H - LINE_WIDTH ctx.rectangle(x, y, w, h) ctx.set_source_rgb(0, 0, 0) ctx.stroke_preserve() ctx.clip() lout = PangoCairo.create_layout(ctx) lout.set_font_description(Pango.FontDescription('Sans 10')) lout.set_width(Pango.SCALE * w) lout.set_alignment(Pango.Alignment.CENTER) text = TEMPLATE.format(book) lout.set_markup(text, -1) extent = lout.get_size() xtrans = x ytrans = y - extent.height / Pango.SCALE / 2 + h / 2 ctx.translate(xtrans, ytrans) PangoCairo.update_layout(ctx, lout) PangoCairo.show_layout(ctx, lout) surface.finish() return path