def shape_from_text(new_text, x_add): nonlocal shape, last_type self.layout.set_markup( f"<span " f'strikethrough="{str(self.strikeout).lower()}" ' f'underline="{"single" if self.underline else "none"}"' f">" f"{html.escape(new_text)}" f"</span>", -1, ) self.context.save() self.context.scale( self.downscale * self.xscale * self.fonthack_scale, self.downscale * self.yscale * self.fonthack_scale, ) PangoCairo.layout_path(self.context, self.layout) self.context.restore() path = self.context.copy_path() # Convert points to shape for current_entry in path: current_type = current_entry[0] current_path = current_entry[1] if current_type == 0: # MOVE_TO if last_type != current_type: # Avoid repetition of command tags shape.append("m") last_type = current_type shape.extend([ Shape.format_value(current_path[0] + x_add), Shape.format_value(current_path[1]), ]) elif current_type == 1: # LINE_TO if last_type != current_type: # Avoid repetition of command tags shape.append("l") last_type = current_type shape.extend([ Shape.format_value(current_path[0] + x_add), Shape.format_value(current_path[1]), ]) elif current_type == 2: # CURVE_TO if last_type != current_type: # Avoid repetition of command tags shape.append("b") last_type = current_type shape.extend([ Shape.format_value(current_path[0] + x_add), Shape.format_value(current_path[1]), Shape.format_value(current_path[2] + x_add), Shape.format_value(current_path[3]), Shape.format_value(current_path[4] + x_add), Shape.format_value(current_path[5]), ]) self.context.new_path()
def path(self): if not self._pangocairo_ctx: self._pre_render() # Render path data to a temporary cairo Context cairo_ctx = cairo.Context( cairo.RecordingSurface(cairo.CONTENT_ALPHA, None)) cairo_ctx = driver.ensure_pycairo_context(cairo_ctx) cairo_ctx.move_to(self.x, self.y - self.baseline) # show_layout should work here, but fills the path instead, # instead, use layout_path to render the layout. PangoCairo.layout_path(cairo_ctx, self._pango_layout) # Parse cairo path into Shoebot BezierPath cairo_text_path = cairo_ctx.copy_path() p = BezierPath(self._bot) for item in cairo_text_path: 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() del cairo_ctx return p
def drawNumber(self, cr, width, height, number): # create pango desc/layout if self.layout is None: self.layout = PangoCairo.create_layout(cr) self.desc = Pango.font_description_from_string("Ubuntu Mono") self.desc.set_absolute_size(0.75 * height * Pango.SCALE) self.desc.set_weight(Pango.Weight.NORMAL) self.desc.set_style(Pango.Style.NORMAL) self.layout.set_font_description(self.desc) # print and layout string (pango-wise) self.layout.set_text(str(int(number)), -1) # determine center position for number rects = self.layout.get_extents() x = width / 2 - rects[0].x / Pango.SCALE - rects[ 0].width / Pango.SCALE / 2 y = height / 2 - rects[0].y / Pango.SCALE - rects[ 0].height / Pango.SCALE / 2 # draw text cr.move_to(x, y) PangoCairo.layout_path(cr, self.layout) cr.set_operator(cairo.OPERATOR_SOURCE) cr.set_source_rgb(0.0, 0.0, 0.0) cr.fill()
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 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)) tempCairoContext = driver.ensure_pycairo_context(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 on_draw(self, widget, cr, *args, **kwargs): cr.save() if self.is_animating(): # translate to the center, then set the rotation a = widget.get_allocation() cr.translate(a.width * 0.5, a.height * 0.5) cr.rotate(self.rotation) # pass on the translation details kwargs['xo'] = -(a.width * 0.5) kwargs['yo'] = -(a.height * 0.5) # do icon drawing SymbolicIcon.on_draw(self, widget, cr, *args, **kwargs) cr.restore() if not self.is_animating() or not self.transaction_count: return # paint transactions bubble # get the layout extents and calc the bubble size ex = self.layout.get_pixel_extents()[1] x = ((a.width - self.icon.get_width()) / 2 + self.icon.get_width() - ex.width + 2) y = ((a.height - self.icon.get_height()) / 2 + self.icon.get_height() - ex.height + 2) w = ex.width + 2 * self.BUBBLE_XPADDING h = ex.height + 2 * self.BUBBLE_YPADDING border_radius = w / 3 if border_radius > self.BUBBLE_MAX_BORDER_RADIUS: border_radius = self.BUBBLE_MAX_BORDER_RADIUS # paint background context = widget.get_style_context() context.save() color = context.get_background_color(Gtk.StateFlags.SELECTED) rounded_rect(cr, x + 1, y + 1, w - 2, h - 2, border_radius) Gdk.cairo_set_source_rgba(cr, color) cr.fill() context.restore() # paint outline rounded_rect(cr, x + 1.5, y + 1.5, w - 3, h - 3, border_radius - 1) cr.set_source_rgb(1, 1, 1) cr.set_line_width(1) cr.stroke() # paint layout cr.save() cr.translate(x + (w - ex.width) * 0.5, y + (h - ex.height) * 0.5) cr.move_to(0, 1) PangoCairo.layout_path(cr, self.layout) cr.set_source_rgba(0, 0, 0, 0.6) cr.fill() Gtk.render_layout(context, cr, 0, 0, self.layout) cr.restore()
def _draw(self, widget, ctx): alloc =self.get_allocation() # draw border ctx.set_line_width(self.border_size) ctx.set_source_rgb( \ self.border_color.red / COLOR_MAX, \ self.border_color.green / COLOR_MAX, \ self.border_color.blue / COLOR_MAX) ctx.rectangle(0, 0, alloc.width-1, alloc.height-1) ctx.stroke() # draw background ctx.new_path() if not self._selected: if not self.background_gradient: self.background_gradient = cairo.LinearGradient(0, 0, alloc.width, alloc.height) start = Gdk.color_parse("#FFD700")[1] end = Gdk.color_parse("#fff")[1] self.background_gradient.add_color_stop_rgb( \ 0.0, start.red / COLOR_MAX, start.green / COLOR_MAX, start.blue / COLOR_MAX) self.background_gradient.add_color_stop_rgb( \ 0.975, end.red / COLOR_MAX, end.green / COLOR_MAX, end.blue / COLOR_MAX) ctx.set_source(self.background_gradient) else: ctx.set_source_rgb( \ self.selected_background_color.red / COLOR_MAX, \ self.selected_background_color.green / COLOR_MAX, \ self.selected_background_color.blue / COLOR_MAX) ctx.rectangle( \ self.border_size, \ self.border_size, \ alloc.width - self.border_size - 1, \ alloc.height - self.border_size - 1) ctx.fill() # draw text ctx.set_line_width(1.0) ctx.new_path() if not self._selected: ctx.set_source_rgb( \ self.foreground_color.red / COLOR_MAX, \ self.foreground_color.green / COLOR_MAX, \ self.foreground_color.blue / COLOR_MAX) else: ctx.set_source_rgb( \ self.selected_foreground_color.red / COLOR_MAX, \ self.selected_foreground_color.green / COLOR_MAX, \ self.selected_foreground_color.blue / COLOR_MAX) ctx.move_to(self.border_size + self.item_hpad, self.border_size + self.item_vpad) PangoCairo.layout_path(ctx, self._layout) ctx.stroke()
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 on_draw(self, widget, cr): # 清空窗口上的内容。 cr.set_operator(cairo.OPERATOR_CLEAR) # 浅色背景,未锁定鼠标移动到歌词窗口上时显示 if self.status['show-bg'] == True: cr.set_source_rgba(0.5, 0.5, 0.5, 0.5) else: cr.set_source_rgba(0.0, 0.0, 0.0, 0.0) cr.set_operator(cairo.OPERATOR_SOURCE) cr.paint() if self.txt == '': return # 创建字体布局 layout = PangoCairo.create_layout(cr) #ctx = layout.get_context() #ctx.set_base_gravity(Pango.Gravity.EAST) fd = Pango.FontDescription(self.config['font']) layout.set_font_description(fd) layout.set_markup(self.txt, -1) logic_ext, ink_ext = layout.get_pixel_extents() #widget.resize(logic_ext.x + logic_ext.width, logic_ext.y + logic_ext.height) w = logic_ext.x + logic_ext.width h = logic_ext.y + logic_ext.height cr.move_to(self.config['x-padding'], self.config['y-padding']) # 布局转路径 PangoCairo.layout_path(cr, layout) if (self.config['stroke_outline']): cr.set_operator(cairo.OPERATOR_OVER) #cr.set_source_rgba(0.7, 0.2, 0.1, 1.0) cr.set_source_rgba(*self.config['outline_color']) # 路径描边 cr.set_line_width(1) cr.stroke_preserve() # 路径渐变填充 #cr.set_source_rgba(0.1, 0.2, 0.7, 1.0) pattern = cairo.LinearGradient(0, 0, w, h) pattern.add_color_stop_rgba(*self.pos) pattern.add_color_stop_rgba(*self.pos2) pattern.add_color_stop_rgba(*self.pos3) pattern.add_color_stop_rgba(*self.pos4) cr.set_source(pattern) cr.fill() return True
def _draw(self, widget, ctx): alloc = self.get_allocation() r = self.button_radius d = self.space_between_buttons ds = (self._first_w - r) / 2 ctx.set_line_width(1.0) if self.bg_color: ctx.set_source_rgb( self.bg_color.red / COLOR_MAX, self.bg_color.green / COLOR_MAX, self.bg_color.blue / COLOR_MAX ) ctx.rectangle(0, 0, alloc.width, alloc.height) ctx.fill() ctx.new_path() ctx.set_source_rgb( self.button_color.red / COLOR_MAX, self.button_color.green / COLOR_MAX, self.button_color.blue / COLOR_MAX ) # for every button for i in range(0, len(self._problem_titles)): xc = ds + i * (d + r) + r / 2 yc = alloc.height / 2 # draw the button ctx.arc(xc, yc, r, 0, 2 * math.pi) ctx.close_path() # if selected, fill the circle, otherwise stroke it if self.selected_problem == i or self._hovered_problem == i: ctx.fill() else: ctx.stroke() ctx.set_source_rgb( self.text_color.red / COLOR_MAX, self.text_color.green / COLOR_MAX, self.text_color.blue / COLOR_MAX ) # draw the selected label above self._move_ctx_to_label_start(ctx, self.selected_problem, True) PangoCairo.layout_path(ctx, self._layouts[self.selected_problem]) ctx.stroke() # draw the hovered label, if any if self._hovered_problem != None: self._move_ctx_to_label_start(ctx, self._hovered_problem, False) PangoCairo.layout_path(ctx, self._layouts[self._hovered_problem]) ctx.stroke()
def drawAlignmentBase(self, base, x, y, cr, invert=False): if invert: cr.set_source_rgba(*self.bgcolors_inv[base]) else: cr.set_source_rgba(*self.bgcolors[base]) cr.rectangle(x, y, self.fwidth, self.fheight) cr.fill() if invert: cr.set_source_rgba(*self.basecolors_inv[base]) else: cr.set_source_rgba(*self.basecolors[base]) self.txtlayout.set_text(base, 1) tw = self.txtlayout.get_pixel_size()[0] cr.move_to(x + (self.fwidth - tw) / 2, y) PangoCairo.layout_path(cr, self.txtlayout) cr.fill()
def draw_layout(self, cr, x, y, rotation, xscale, yscale): cr.save() layout = PangoCairo.create_layout(cr) layout.set_text(self.text, -1) layout.set_font_description(self.font_desc) layout.set_alignment(self.alignment) self.pixel_size = layout.get_pixel_size() # Shadow if self.shadow_on: cr.save() r, g, b = self.shadow_color_rgb a = self.shadow_opacity / 100.0 cr.set_source_rgba(r, g, b, a) cr.move_to(x + self.shadow_xoff, y + self.shadow_yoff) cr.scale(xscale, yscale) cr.rotate(rotation) PangoCairo.update_layout(cr, layout) PangoCairo.show_layout(cr, layout) cr.restore() # Text if self.fill_on: cr.set_source_rgba(*self.color_rgba) cr.move_to(x, y) cr.scale(xscale, yscale) cr.rotate(rotation) PangoCairo.update_layout(cr, layout) PangoCairo.show_layout(cr, layout) # Outline if self.outline_on: if self.fill_on == False: # case when user only wants outline we need to transform here cr.move_to(x, y) cr.scale(xscale, yscale) cr.rotate(rotation) PangoCairo.layout_path(cr, layout) cr.set_source_rgba(*self.outline_color_rgba) cr.set_line_width(self.outline_width) cr.stroke() cr.restore()
def draw_layout(self, cr, x, y, rotation, xscale, yscale): cr.save() layout = PangoCairo.create_layout(cr) layout.set_text(self.text, -1) layout.set_font_description(self.font_desc) layout.set_alignment(self.alignment) self.pixel_size = layout.get_pixel_size() # Shadow if self.shadow_on: cr.save() r, g, b = self.shadow_color_rgb a = self.shadow_opacity / 100.0 cr.set_source_rgba(r, g, b, a) cr.move_to(x + self.shadow_xoff, y + self.shadow_yoff) cr.scale(xscale, yscale) cr.rotate(rotation) PangoCairo.update_layout(cr, layout) PangoCairo.show_layout(cr, layout) cr.restore() # Text if self.fill_on: cr.set_source_rgba(*self.color_rgba) cr.move_to(x, y) cr.scale(xscale, yscale) cr.rotate(rotation) PangoCairo.update_layout(cr, layout) PangoCairo.show_layout(cr, layout) # Outline if self.outline_on: if self.fill_on == False: # case when user only wants outline we need to transform here cr.move_to(x, y) cr.scale(xscale, yscale) cr.rotate(rotation) PangoCairo.layout_path(cr, layout) cr.set_source_rgba(*self.outline_color_rgba) cr.set_line_width(self.outline_width) cr.stroke() cr.restore()
def draw_title_info(self, cr): cr.save() do_shadow = (self.conf.shadow[0] != -1.0) do_outline = (self.conf.outline[0] != -1.0) self.set_name("osd_bubble") qltk.add_css( self, """ #osd_bubble { background-color:rgba(0,0,0,0); } """) cr.set_operator(cairo.OPERATOR_OVER) cr.set_source_rgba(*self.conf.fill) radius = min(25, self.corners_factor * min(*self.get_size())) self.draw_conf_rect(cr, 0, 0, self.get_size()[0], self.get_size()[1], radius) cr.fill() # draw border if do_outline: # Make border darker and more translucent than the fill f = self.conf.fill rgba = (f[0] / 1.25, f[1] / 1.25, f[2] / 1.25, f[3] / 2.0) cr.set_source_rgba(*rgba) self.draw_conf_rect(cr, 1, 1, self.get_size()[0] - 2, self.get_size()[1] - 2, radius) cr.set_line_width(2.0) cr.stroke() textx = self.BORDER if self.cover_pixbuf is not None: rect = self.cover_rectangle textx += rect.width + self.BORDER pbuf = self.cover_pixbuf transmat = cairo.Matrix() if do_shadow: cr.set_source_rgba(*self.conf.shadow) self.draw_conf_rect(cr, rect.x + 2, rect.y + 2, rect.width, rect.height, 0.6 * self.corners_factor * rect.width) cr.fill() if do_outline: cr.set_source_rgba(*self.conf.outline) self.draw_conf_rect(cr, rect.x, rect.y, rect.width, rect.height, 0.6 * self.corners_factor * rect.width) cr.stroke() set_ctx_source_from_pbosf(cr, pbuf) transmat.scale( pbosf_get_width(pbuf) / float(rect.width), pbosf_get_height(pbuf) / float(rect.height)) transmat.translate(-rect.x, -rect.y) cr.get_source().set_matrix(transmat) self.draw_conf_rect(cr, rect.x, rect.y, rect.width, rect.height, 0.6 * self.corners_factor * rect.width) cr.fill() PangoCairo.update_layout(cr, self.title_layout) height = self.title_layout.get_pixel_size()[1] texty = (self.get_size()[1] - height) // 2 if do_shadow: cr.set_source_rgba(*self.conf.shadow) cr.move_to(textx + 2, texty + 2) PangoCairo.show_layout(cr, self.title_layout) if do_outline: cr.set_source_rgba(*self.conf.outline) cr.move_to(textx, texty) PangoCairo.layout_path(cr, self.title_layout) cr.stroke() cr.set_source_rgb(*self.conf.text[:3]) cr.move_to(textx, texty) PangoCairo.show_layout(cr, self.title_layout) cr.restore()
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))
def draw_title_info(self, cr): cr.save() do_shadow = (self.conf.shadow[0] != -1.0) do_outline = (self.conf.outline[0] != -1.0) self.set_name("osd_bubble") style_provider = Gtk.CssProvider() css = """ #osd_bubble { background-color:rgba(0,0,0,0); } """ style_provider.load_from_data(css.encode("utf8")) style_context = self.get_style_context() style_context.add_provider( style_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION ) cr.set_operator(cairo.OPERATOR_OVER) cr.set_source_rgba(*self.conf.fill) radius = min(25, self.conf.corners * min(*self.get_size())) self.draw_conf_rect(cr, 0, 0, self.get_size()[0], self.get_size()[1], radius) cr.fill() # draw border if do_outline: # Make border darker and more translucent than the fill f = self.conf.fill rgba = (f[0] / 1.25, f[1] / 1.25, f[2] / 1.25, f[3] / 2.0) cr.set_source_rgba(*rgba) self.draw_conf_rect(cr, 1, 1, self.get_size()[0] - 2, self.get_size()[1] - 2, radius) cr.set_line_width(2.0) cr.stroke() textx = self.conf.border if self.cover_pixbuf is not None: rect = self.cover_rectangle textx += rect.width + self.conf.border pbuf = self.cover_pixbuf transmat = cairo.Matrix() if do_shadow: cr.set_source_rgba(*self.conf.shadow) self.draw_conf_rect(cr, rect.x + 2, rect.y + 2, rect.width, rect.height, 0.6 * self.conf.corners * rect.width) cr.fill() if do_outline: cr.set_source_rgba(*self.conf.outline) self.draw_conf_rect(cr, rect.x, rect.y, rect.width, rect.height, 0.6 * self.conf.corners * rect.width) cr.stroke() Gdk.cairo_set_source_pixbuf(cr, pbuf, 0, 0) transmat.scale(pbuf.get_width() / float(rect.width), pbuf.get_height() / float(rect.height)) transmat.translate(-rect.x, -rect.y) cr.get_source().set_matrix(transmat) self.draw_conf_rect(cr, rect.x, rect.y, rect.width, rect.height, 0.6 * self.conf.corners * rect.width) cr.fill() PangoCairo.update_layout(cr, self.title_layout) height = self.title_layout.get_pixel_size()[1] texty = (self.get_size()[1] - height) // 2 if do_shadow: cr.set_source_rgba(*self.conf.shadow) cr.move_to(textx + 2, texty + 2) PangoCairo.show_layout(cr, self.title_layout) if do_outline: cr.set_source_rgba(*self.conf.outline) cr.move_to(textx, texty) PangoCairo.layout_path(cr, self.title_layout) cr.stroke() cr.set_source_rgb(*self.conf.text[:3]) cr.move_to(textx, texty) PangoCairo.show_layout(cr, self.title_layout) cr.restore()
def draw_title_info(self, cr): cr.save() do_shadow = (self.conf.shadow[0] != -1.0) do_outline = (self.conf.outline[0] != -1.0) self.set_name("osd_bubble") qltk.add_css(self, """ #osd_bubble { background-color:rgba(0,0,0,0); } """) cr.set_operator(cairo.OPERATOR_OVER) cr.set_source_rgba(*self.conf.fill) radius = min(25, self.corners_factor * min(*self.get_size())) self.draw_conf_rect(cr, 0, 0, self.get_size()[0], self.get_size()[1], radius) cr.fill() # draw border if do_outline: # Make border darker and more translucent than the fill f = self.conf.fill rgba = (f[0] / 1.25, f[1] / 1.25, f[2] / 1.25, f[3] / 2.0) cr.set_source_rgba(*rgba) self.draw_conf_rect(cr, 1, 1, self.get_size()[0] - 2, self.get_size()[1] - 2, radius) cr.set_line_width(2.0) cr.stroke() textx = self.BORDER if self.cover_pixbuf is not None: rect = self.cover_rectangle textx += rect.width + self.BORDER pbuf = self.cover_pixbuf transmat = cairo.Matrix() if do_shadow: cr.set_source_rgba(*self.conf.shadow) self.draw_conf_rect(cr, rect.x + 2, rect.y + 2, rect.width, rect.height, 0.6 * self.corners_factor * rect.width) cr.fill() if do_outline: cr.set_source_rgba(*self.conf.outline) self.draw_conf_rect(cr, rect.x, rect.y, rect.width, rect.height, 0.6 * self.corners_factor * rect.width) cr.stroke() set_ctx_source_from_pbosf(cr, pbuf) transmat.scale(pbosf_get_width(pbuf) / float(rect.width), pbosf_get_height(pbuf) / float(rect.height)) transmat.translate(-rect.x, -rect.y) cr.get_source().set_matrix(transmat) self.draw_conf_rect(cr, rect.x, rect.y, rect.width, rect.height, 0.6 * self.corners_factor * rect.width) cr.fill() PangoCairo.update_layout(cr, self.title_layout) height = self.title_layout.get_pixel_size()[1] texty = (self.get_size()[1] - height) // 2 if do_shadow: cr.set_source_rgba(*self.conf.shadow) cr.move_to(textx + 2, texty + 2) PangoCairo.show_layout(cr, self.title_layout) if do_outline: cr.set_source_rgba(*self.conf.outline) cr.move_to(textx, texty) PangoCairo.layout_path(cr, self.title_layout) cr.stroke() cr.set_source_rgb(*self.conf.text[:3]) cr.move_to(textx, texty) PangoCairo.show_layout(cr, self.title_layout) cr.restore()
def do_draw(self, cr): """Handler for the 'draw' signal. :type cr: cairo.Context :rtype: bool """ alloc = self.get_allocation() width, height = alloc.width, alloc.height # Mood if self.surf: cr.save() cr.scale(width / self.surf.get_width(), height / self.surf.get_height()) cr.set_source_surface(self.surf, 0, 0) cr.paint() cr.restore() # Text text = self.text if text: cr.save() # TODO: Do we need PangoCairo.update_layout anywhere? ext = self.text_extents scale = Pango.SCALE tx = int((width - ext.width / scale) / 2 - ext.x / scale) ty = int((height - ext.height / scale) / 2 - ext.y / scale) cr.move_to(tx, ty) cr.set_line_width(4) PangoCairo.layout_path(cr, self.pango_layout) cr.set_source_rgba(1, 1, 1, 0.8) cr.stroke_preserve() cr.set_source_rgb(0, 0, 0) cr.fill() cr.restore() # Seek position pos = self._seek_position if pos is not None: cr.save() x = pos * width y = height * self.POS_SIZE xd = y linesize = self.POS_LINESIZE top = linesize / 2 - 0.5 # Triangle cr.move_to(x, y) cr.line_to(x - xd, top) cr.line_to(x + xd, top) cr.close_path() # White fill cr.set_source_rgb(1, 1, 1) cr.fill_preserve() # Black stroke cr.set_source_rgb(0, 0, 0) cr.set_line_width(linesize) cr.stroke() cr.restore() # Border cr.save() cr.rectangle(0, 0, width, height) if self.surf or pos is not None: cr.set_source_rgb(0, 0, 0) else: cr.set_source_rgb(0.63, 0.63, 0.63) cr.stroke() cr.restore() # Tint tint = self.tint if tint is not None: cr.save() cr.set_source_rgba(tint.red, tint.green, tint.blue, tint.alpha) cr.paint() cr.restore() return False
cr.line_to(0, 0) cr.set_source_rgba(1.0, 1.0, 1.0, 1.0) cr.fill() # use cr.fill_preserve to preserve the path cr.restore() layout = PangoCairo.create_layout(cr) layout.set_justify(True) layout.set_width(width * Pango.SCALE) layout.set_font_description(Pango.FontDescription.from_string(fontstr)) layout.set_wrap(Pango.WrapMode.WORD) layout.set_indent(indent * Pango.SCALE) layout.set_markup(lstring, len(lstring)) # Create path for contents PangoCairo.layout_path(cr, layout) # stroke the letters (draw the outline) cr.set_line_width(2.0) cr.set_source_rgba(*stroke_col) cr.stroke_preserve() # fill the letters # cr.set_source_rgba(*fill_col) # cr.fill_preserve() # PangoCairo.show_layout(cr, layout) ink_rect, logical_rect = layout.get_pixel_extents() print_rect(ink_rect, "ink_rect") print_rect(logical_rect, "logical_rect") ink_rect, logical_rect = layout.get_pixel_extents() print_rect(ink_rect, "ink_rect") print_rect(logical_rect, "logical_rect")
def _draw(self, widget, ctx): alloc = self.get_allocation() (lbl_w, lbl_h) = self._layout.get_pixel_size() # set gradient gradient = cairo.LinearGradient(0, 0, 0, alloc.height) start = None end = None if self._pressed: start = self.button_color_end end = self.button_color_start else: start = self.button_color_start end = self.button_color_end gradient.add_color_stop_rgb(0.0, start.red / COLOR_MAX, start.green / COLOR_MAX, start.blue / COLOR_MAX) gradient.add_color_stop_rgb(0.975, end.red / COLOR_MAX, end.green / COLOR_MAX, end.blue / COLOR_MAX) ctx.set_source(gradient) # fill rectangle # TODO: should be rounded. Very low priority. ctx.rectangle(0, 0, alloc.width, alloc.height) ctx.fill() # draw text ctx.set_source_rgb( self.text_color.red / COLOR_MAX, self.text_color.green / COLOR_MAX, self.text_color.blue / COLOR_MAX ) ctx.new_path() ctx.set_line_width(1.0) ctx.move_to(self.hpad, self.vpad) PangoCairo.layout_path(ctx, self._layout) ctx.stroke() # draw divider ctx.set_source_rgb( self.divider_color.red / COLOR_MAX, self.divider_color.green / COLOR_MAX, self.divider_color.blue / COLOR_MAX, ) ctx.set_line_width(self.div_width) ctx.new_path() div_x = self.hpad + lbl_w + self.div_pad ctx.move_to(div_x, (alloc.height - self.div_height) / 2) ctx.line_to(div_x, (alloc.height + self.div_height) / 2) ctx.stroke() # draw down button ctx.set_source_rgb( self.text_color.red / COLOR_MAX, self.text_color.green / COLOR_MAX, self.text_color.blue / COLOR_MAX ) ctx.new_path() btn_x_0 = div_x + self.div_width + self.div_pad btn_y_0 = (alloc.height - self.dwn_btn_h) / 2 ctx.move_to(btn_x_0, btn_y_0) ctx.line_to(btn_x_0 + self.dwn_btn_w, btn_y_0) ctx.line_to(btn_x_0 + self.dwn_btn_w / 2, btn_y_0 + self.dwn_btn_h) ctx.close_path() ctx.fill()
def prepare(self, session): layout = self.make_layout(session.context) PangoCairo.layout_path(session.context, layout) path = session.context.copy_path() session.context.new_path() return path
def drawBaseCalls(self, startx, dwidth, cr): """ Draws the base calls, confidence scores and bars, and lines from the base calls to the trace peaks. startx: The x position at which to start drawing. dwidth: The width (in pixels) to draw. If dwidth is 0, the entire surface will be drawn. """ width = self.drawingarea.get_allocated_width() height = self.drawingarea.get_allocated_height() if dwidth == 0: dwidth = width # Save the Cairo context settings. cr.save() cr.set_dash((1, 1)) cr.set_line_width(1) # Calculate the confidence bar dimensions. drawheight = height - self.bottom_margin - self.bcheight confbarmax = drawheight / 4 confbarwidth = self.getConfBarWidth() conf_hue_best = 0.68 conf_hue_worst = 1.0 samps = self.seqt.getTraceLength() startsamp = int(startx * samps) / width endsamp = int((float(startx + dwidth) * samps) / width + 0.5) if endsamp < (samps - 1): endsamp += 2 startbcindex = self.seqt.getPrevBaseCallIndex(startsamp) #print startbcindex endbcindex = self.seqt.getNextBaseCallIndex(endsamp) if endbcindex < self.seqt.getNumBaseCalls(): endbcindex += 1 #print endbcindex xscale = float(width) / samps yscale = float(drawheight) / self.sigmax y = drawheight + self.bcpadding confbarcolor = Gdk.RGBA() confbarcolor.parse('#c8c8c8') for index in range(startbcindex, endbcindex): # Get the base and position. base = self.seqt.getBaseCall(index) pos = self.seqt.getBaseCallPos(index) x = int(pos * xscale) if self.show_confidence: # Draw the confidence bar. bcconf = self.seqt.getBaseCallConf(index) cr.set_source_rgba(*confbarcolor) #hue = float(bcconf) * (conf_hue_best - conf_hue_worst) / 61 + conf_hue_worst #cr.set_source_rgba(*colorFromHSV(hue, 0.34, 1.0)) cr.rectangle(x - (confbarwidth / 2), 6, confbarwidth, (confbarmax * bcconf) / 61) cr.fill() # Draw the confidence score. hue = float(bcconf) * (conf_hue_best - conf_hue_worst) / 61 + conf_hue_worst cr.set_source_rgba(*colorFromHSV(hue, 1.0, 0.9)) self.bclayout.set_text(str(bcconf), -1) txtwidth = self.bclayout.get_pixel_size()[0] cr.move_to(x - (txtwidth / 2), 6) PangoCairo.layout_path(cr, self.bclayout) cr.fill() # Draw the base. cr.set_source_rgba(*self.tracecolors[base]) self.bclayout.set_text(base, 1) txtwidth = self.bclayout.get_pixel_size()[0] cr.move_to(x - (txtwidth / 2), y) PangoCairo.layout_path(cr, self.bclayout) cr.fill() # Calculate the y coordinate of the trace location for this base and draw a line to # it from the base call. It only makes sense to do this for non-ambiguous bases. if base in ('A', 'T', 'G', 'C'): traceval = self.seqt.getTraceSample(base, pos) ysamp = int((self.sigmax - traceval) * yscale + 0.5) # Draw the line to the trace. # As with drawing the trace lines, add 0.5 to the x coordinates to ensure # the lines appear in the "correct" location (with reference to the standard # GTK drawing routines and that they are exactly 1 pixel wide. cr.set_source_rgba(*self.pklinecolors[base]) cr.move_to(x + 0.5, ysamp) cr.line_to(x + 0.5, y - (self.bcpadding / 2)) cr.stroke() # Restore the old Cairo context settings. cr.restore()
def do_draw(self, cr): """Handler for the 'draw' signal. :type cr: cairo.Context :rtype: bool """ alloc = self.get_allocation() width, height = alloc.width, alloc.height # Mood if self.surf: cr.save() cr.scale(width / self.surf.get_width(), height / self.surf.get_height()) cr.set_source_surface(self.surf, 0, 0) cr.paint() cr.restore() # Text text = self.text if text: cr.save() # TODO: Do we need PangoCairo.update_layout anywhere? ext = self.text_extents scale = Pango.SCALE tx = int((width - ext.width / scale) / 2 - ext.x / scale) ty = int((height - ext.height / scale) / 2 - ext.y / scale) cr.move_to(tx, ty) cr.set_line_width(4) PangoCairo.layout_path(cr, self.pango_layout) cr.set_source_rgba(1, 1, 1, 0.8) cr.stroke_preserve() cr.set_source_rgb(0, 0, 0) cr.fill() cr.restore() # Seek position pos = self._seek_position if pos is not None: cr.save() x = pos * width y = height * self.POS_SIZE xd = y linesize = self.POS_LINESIZE top = linesize / 2 - 0.5 # Triangle cr.move_to(x, y) cr.line_to(x - xd, top) cr.line_to(x + xd, top) cr.close_path() # White fill cr.set_source_rgb(1, 1, 1) cr.fill_preserve() # Black stroke cr.set_source_rgb(0, 0, 0) cr.set_line_width(linesize) cr.stroke() cr.restore() # Border cr.save() cr.rectangle(0, 0, width, height) if self.surf or pos is not None: cr.set_source_rgb(0, 0, 0) else: cr.set_source_rgb(0.63, 0.63, 0.63) cr.stroke() cr.restore() # Tint tint = self.tint if tint is not None: cr.save() cr.set_source_rgba(tint.red, tint.green, tint.blue, tint.alpha) cr.paint() cr.restore() return False