def _get_layout_metrics(self): f = self._get_font() l = self._get_size_layout() l.set_font_description(f) l.set_text(SINGLE_WIDE_CHARACTERS) ink, logic = l.get_line(0).get_pixel_extents() return (pango.ASCENT(logic), pango.DESCENT(logic))
def _layout_text(pc, text, height): layout = pc.create_layout() layout.set_font_description(pango.FontDescription(FONT_NAME)) layout.set_text(text) extents = layout.get_line(0).get_extents()[1] layout_width = pango.units_to_double(extents[2]) layout_height = pango.units_to_double(pango.ASCENT(extents)) scale_ratio = float(height) / layout_height return layout, scale_ratio, scale_ratio * layout_width
def _update_base(self, elements_list=None): if elements_list is None: elements_list = [''] self._smilies = {} self._base_attrlist = pango.AttrList() text = '' if type(elements_list) in (str, unicode): elements_list = [elements_list] for element in elements_list: if type(element) in (str, unicode): try: attrl, ptxt, unused = pango.parse_markup(element, u'\x00') except: attrl, ptxt = pango.AttrList(), element #append attribute list shift = len(text) itter = attrl.get_iterator() while True: attrs = itter.get_attrs() for attr in attrs: attr.end_index += shift attr.start_index += shift self._base_attrlist.insert(attr) if not itter.next(): break text += ptxt elif type(element) == gtk.gdk.Pixbuf: self._smilies[len(text)] = element text += '_' pango.Layout.set_text(self, text) if hasattr(pango, 'find_base_dir'): for line in text.splitlines(): if (pango.find_base_dir(line, -1) == pango.DIRECTION_RTL): self._is_rtl = True break else: self._is_rtl = False logical = self.get_line(0).get_pixel_extents()[1] ascent = pango.ASCENT(logical) decent = pango.DESCENT(logical) self._text_height = ascent + decent self._base_to_center = (self._text_height // 2) - decent self._update_smilies()
def _draw_layouted_line_text(self, context, layout, cur_f_color, l, t, w, h): line_context, line_p_context = context ink, logic = layout.get_line(0).get_pixel_extents() ascent, descent = self._get_layout_metrics() r, g, b, a = self._get_color(cur_f_color) line_context.set_source_rgba(r, g, b, a) line_context.move_to(l + pango.LBEARING(logic), h - descent - pango.ASCENT(logic)) line_p_context.update_layout(layout) line_p_context.show_layout(layout)
def _draw_layout(self, context, x, y, width, height, underline_drawer): line_height = 0 alignment = self.layout.get_alignment() for i in xrange(self.layout.get_line_count()): line = self.layout.get_line_readonly(i) extents = line.get_pixel_extents()[1] next_line_height = line_height + extents[3] if next_line_height > height: break if alignment == pango.ALIGN_CENTER: line_x = max(x, x + (width - extents[2]) / 2.0) elif alignment == pango.ALIGN_RIGHT: line_x = max(x, x + width - extents[2]) else: line_x = x baseline = y + line_height + pango.ASCENT(extents) context.move_to(line_x, baseline) context.context.show_layout_line(line) underline_drawer.draw(context, line_x, baseline, line) line_height = next_line_height
def draw(self, ctx, area): x, y, width, height = area pxls = pango.PIXELS ctx.rectangle(x, y, width, height) ctx.clip() if self._is_rtl: layout_width = pango.Layout.get_pixel_size(self)[0] ctx.translate(x + width - layout_width, y) else: ctx.translate(x, y) #Clipping and ellipsation if self._width >= 0: inline, byte = 0, 1 X, Y, W, H = 0, 1, 2, 3 layout_width = self._width lst = self.get_attributes() e_ascent = pango.ASCENT( self._elayout.get_line(0).get_pixel_extents()[1]) coords = [] # of path in px for i in range(self.get_line_count()): line = self.get_line(i) edge = line.x_to_index(layout_width) if edge[inline]: #create ellipsize layout with the style of the char attrlist = pango.AttrList() itter = lst.get_iterator() while True: attrs = itter.get_attrs() for attr in attrs: if not attr.type == pango.ATTR_SHAPE: start, end = itter.range() if start <= edge[byte] < end: n_attr = attr.copy() n_attr.start_index = 0 n_attr.end_index = 3 attrlist.insert(n_attr) if not itter.next(): break self._elayout.set_attributes(attrlist) ellipsize_width = self._elayout.get_size()[0] edge = line.x_to_index(layout_width - ellipsize_width) char = self.index_to_pos(edge[byte]) char_x, char_y, char_h = (pxls(char[X]), pxls(char[Y]), pxls(char[H])) y1, y2 = char_y, char_y + char_h if edge[inline]: x1 = char_x else: x1 = 0 coords.append((x1, y1)) coords.append((x1, y2)) line_ascent = pango.ASCENT(line.get_pixel_extents()[1]) ctx.move_to(x1, y1 + line_ascent - e_ascent) ctx.show_layout(self._elayout) else: char = self.index_to_pos(edge[byte]) coords.append((pxls(char[X] + char[W]), pxls(char[Y]))) coords.append( (pxls(char[X] + char[W]), pxls(char[Y] + char[H]))) if coords: ctx.move_to(0, 0) for x, y in coords: ctx.line_to(x, y) ctx.line_to(0, coords[-1][1]) ctx.close_path() ctx.clip() #layout ctx.move_to(0, 0) ctx.show_layout(self) #smilies for index in self._smilies.keys(): try: x, y, width, height = self.index_to_pos(index) pixbuf = self._smilies_scaled[index] tx = pxls(x) ty = pxls(y) + (pxls(height) // 2) - (pixbuf.get_height() // 2) ctx.set_source_pixbuf(pixbuf, tx, ty) ctx.paint() except Exception, error: log.error("Error when painting smilies: %s" % error)