def update_example(self, widget=None): start = 0 end = len(self.example) attributes = pango.AttrList() attributes.insert(pango.AttrForeground(self.text_color.red, self.text_color.green, self.text_color.blue, start, end)) attributes.insert(pango.AttrBackground(self.highlight_color.red, self.highlight_color.green, self.highlight_color.blue, start, end)) # Bold verification if self.bold_tg_button.get_active(): attributes.insert(pango.AttrWeight(pango.WEIGHT_HEAVY, start, end)) else: attributes.insert(pango.AttrWeight(pango.WEIGHT_NORMAL, start, end)) # Italic verification if self.italic_tg_button.get_active(): attributes.insert(pango.AttrStyle(pango.STYLE_ITALIC, start, end)) else: attributes.insert(pango.AttrStyle(pango.STYLE_NORMAL, start, end)) # Underline verification if self.underline_tg_button.get_active(): attributes.insert(pango.AttrUnderline(pango.UNDERLINE_SINGLE, start, end)) else: attributes.insert(pango.AttrUnderline(pango.UNDERLINE_NONE, start, end)) self.example_label.set_attributes(attributes)
def create_attribute(self, attribute, start, end): if attribute == 'bold': return pango.AttrWeight(pango.WEIGHT_BOLD, start, end) elif attribute == 'italic': return pango.AttrStyle(pango.STYLE_ITALIC, start, end) elif attribute == 'underline': return pango.AttrUnderline(pango.UNDERLINE_SINGLE, start, end)
def __init__(self, attrs, unistr): super(PangoAttrList, self).__init__() if attrs == None: return offsets = [] offset = 0 for c in unistr: offsets.append(offset) offset += len(c.encode("utf8")) offsets.append(offset) for attr in attrs: pango_attr = None start_index = attr.start_index if attr.start_index >= 0 else 0 end_index = attr.end_index if attr.end_index >= 0 else 0 start_index = offsets[start_index] if start_index < len( offsets) else offsets[-1] end_index = offsets[end_index] if end_index < len( offsets) else offsets[-1] if attr.type == ibus.ATTR_TYPE_FOREGROUND: r = (attr.value & 0x00ff0000) >> 8 g = (attr.value & 0x0000ff00) b = (attr.value & 0x000000ff) << 8 pango_attr = pango.AttrForeground(r, g, b, start_index, end_index) elif attr.type == ibus.ATTR_TYPE_BACKGROUND: r = (attr.value & 0x00ff0000) >> 8 g = (attr.value & 0x0000ff00) b = (attr.value & 0x000000ff) << 8 pango_attr = pango.AttrBackground(r, g, b, start_index, end_index) elif attr.type == ibus.ATTR_TYPE_UNDERLINE: pango_attr = pango.AttrUnderline(int(attr.value), start_index, end_index) if pango_attr != None: self.insert(pango_attr)
def add_pango_attributes(self, attrs, start_index, end_index): """Insert attributes for this StyleSpec into a pango.AttrList. Not every property of StyleSpec maps into a pango.Attribute - the ones that don't map are ignored and need to be handled separately. @param attrs: pango.AttrList to insert attributes into. @param start_index: byte offset of the start of the range this spec applies to @param end_index: byte offset of the ned of the range this spec applies to """ if self.family is not None: attrs.insert(pango.AttrFamily(self.family, start_index, end_index)) if self.foreground is not None: color = pango.Color(self.foreground) attrs.insert( pango.AttrForeground(color.red, color.green, color.blue, start_index, end_index)) if self.style is not None: attrs.insert(pango.AttrStyle(self.style, start_index, end_index)) if self.underline is not None: attrs.insert( pango.AttrUnderline(self.underline, start_index, end_index)) if self.weight is not None: attrs.insert(pango.AttrWeight(self.weight, start_index, end_index)) if self.weight is not None: attrs.insert(pango.AttrWeight(self.weight, start_index, end_index))
def _draw(self, xrandr, cr): cfg = xrandr.configuration state = xrandr.state cr.set_source_rgb(0.25, 0.25, 0.25) cr.rectangle(0, 0, *state.virtual.max) cr.fill() cr.set_source_rgb(0.5, 0.5, 0.5) cr.rectangle(0, 0, *cfg.virtual) cr.fill() for on in self.sequence: o = cfg.outputs[on] if not o.active: continue rect = (o.tentative_position if hasattr(o, 'tentative_position') else o.position) + tuple(o.size) center = rect[0] + rect[2] / 2, rect[1] + rect[3] / 2 # paint rectangle cr.set_source_rgba(1, 1, 1, 0.7) cr.rectangle(*rect) cr.fill() cr.set_source_rgb(0, 0, 0) cr.rectangle(*rect) cr.stroke() # set up for text cr.save() textwidth = rect[3 if o.rotation.is_odd else 2] widthperchar = textwidth / len(on) textheight = int( widthperchar * 0.8 ) # i think this looks nice and won't overflow even for wide fonts newdescr = pango.FontDescription("sans") newdescr.set_size(textheight * pango.SCALE) # create text layout = cr.create_layout() layout.set_font_description(newdescr) if o.primary: attrs = pango.AttrList() attrs.insert( pango.AttrUnderline(pango.UNDERLINE_SINGLE, end_index=-1)) layout.set_attributes(attrs) layout.set_text(on) # position text layoutsize = layout.get_pixel_size() layoutoffset = -layoutsize[0] / 2, -layoutsize[1] / 2 cr.move_to(*center) cr.rotate(o.rotation.angle) cr.rel_move_to(*layoutoffset) # pain text cr.show_layout(layout) cr.restore()
def setup_default_tags(self): self.italics = self.get_tags_from_attrs(None, None, [pango.AttrStyle('italic')])[0] self.bold = self.get_tags_from_attrs(None, None, [pango.AttrWeight('bold')])[0] self.underline = self.get_tags_from_attrs( None, None, [pango.AttrUnderline('single')])[0]
def create_attribute(self, attribute, start, end, value): if attribute == 'bold': return pango.AttrWeight(value, start, end) elif attribute == 'italic': return pango.AttrStyle(value, start, end) elif attribute == 'underline': return pango.AttrUnderline(value, start, end)
def load(self, node): self.index = int(node.getAttribute("cursor")) if node.hasAttribute("selection_end"): self.end_index = int(node.getAttribute("selection_end")) else: self.end_index = self.index tmp = node.getAttribute("ul-coords") self.ul = utils.parse_coords(tmp) tmp = node.getAttribute("lr-coords") self.lr = utils.parse_coords(tmp) self.identity = int(node.getAttribute("identity")) try: tmp = node.getAttribute("background-color") self.background_color = gtk.gdk.color_parse(tmp) tmp = node.getAttribute("foreground-color") self.foreground_color = gtk.gdk.color_parse(tmp) except ValueError: pass if node.hasAttribute("edit"): self.editing = True else: self.editing = False self.end_index = self.index self.am_selected = node.hasAttribute("current_root") self.am_primary = node.hasAttribute("primary_root") for n in node.childNodes: if n.nodeType == n.TEXT_NODE: self.text = n.data elif n.nodeName == "Extended": self.extended_buffer.load(n) elif n.nodeName == "attribute": attrType = n.getAttribute("type") start = int(n.getAttribute("start")) end = int(n.getAttribute("end")) if attrType == "bold": attr = pango.AttrWeight(pango.WEIGHT_BOLD, start, end) elif attrType == "italics": attr = pango.AttrStyle(pango.STYLE_ITALIC, start, end) elif attrType == "underline": attr = pango.AttrUnderline(pango.UNDERLINE_SINGLE, start, end) elif attrType == "font": font_name = str(n.getAttribute("value")) pango_font = pango.FontDescription(font_name) attr = pango.AttrFontDesc(pango_font, start, end) self.attributes.change(attr) else: print "Unknown: " + n.nodeName self.rebuild_byte_table() self.recalc_edges()
def _createLayout(self, text): """Produces a Pango layout describing this text in this __font""" # create layout layout = pango.Layout(gtk.gdk.pango_context_get()) layout.set_font_description(self.fd) if self.underline: attrs = layout.get_attributes() if not attrs: attrs = pango.AttrList() attrs.insert(pango.AttrUnderline(pango.UNDERLINE_SINGLE, 0, 32767)) layout.set_attributes(attrs) layout.set_text(text) return layout
def set_font(self, pango_layout): """Sets the font for draw_text""" wx2pango_weights = { wx.FONTWEIGHT_BOLD: pango.WEIGHT_BOLD, wx.FONTWEIGHT_LIGHT: pango.WEIGHT_LIGHT, wx.FONTWEIGHT_NORMAL: None, # Do not set a weight by default } wx2pango_styles = { wx.FONTSTYLE_NORMAL: None, # Do not set a style by default wx.FONTSTYLE_SLANT: pango.STYLE_OBLIQUE, wx.FONTSTYLE_ITALIC: pango.STYLE_ITALIC, } cell_attributes = self.code_array.cell_attributes[self.key] # Text font attributes textfont = cell_attributes["textfont"] pointsize = cell_attributes["pointsize"] fontweight = cell_attributes["fontweight"] fontstyle = cell_attributes["fontstyle"] underline = cell_attributes["underline"] strikethrough = cell_attributes["strikethrough"] # Now construct the pango font font_description = pango.FontDescription(" ".join( [textfont, str(pointsize)])) pango_layout.set_font_description(font_description) attrs = pango.AttrList() # Underline attrs.insert(pango.AttrUnderline(underline, 0, MAX_RESULT_LENGTH)) # Weight weight = wx2pango_weights[fontweight] if weight is not None: attrs.insert(pango.AttrWeight(weight, 0, MAX_RESULT_LENGTH)) # Style style = wx2pango_styles[fontstyle] if style is not None: attrs.insert(pango.AttrStyle(style, 0, MAX_RESULT_LENGTH)) # Strikethrough attrs.insert( pango.AttrStrikethrough(strikethrough, 0, MAX_RESULT_LENGTH)) pango_layout.set_attributes(attrs)
def draw(self, context): cr = context.cairo if isinstance(cr, cairo.Context): cr = pangocairo.CairoContext(cr) layout = cr.create_layout() layout.set_font_description(pango.FontDescription(self.font)) layout.set_text(self.render() or '') if hasattr(self.subject, 'isStatic') and self.subject.isStatic: attrlist = pango.AttrList() attrlist.insert( pango.AttrUnderline(pango.UNDERLINE_SINGLE, 2, -1)) layout.set_attributes(attrlist) cr.show_layout(layout)
def _set_underline(self, label, underline=False): # Set an underline in a label widget. att_list = label.get_attributes() if att_list is None: att_list = pango.AttrList() if underline: att_list.insert(pango.AttrUnderline(pango.UNDERLINE_SINGLE, start_index=0, end_index=-1)) else: att_list = att_list.filter(lambda a: a.type != pango.ATTR_UNDERLINE) if att_list is None: att_list = pango.AttrList() label.set_attributes(att_list)
def on_timeout_min(self): attr = self.label.get_attributes() attr.change(pango.AttrUnderline(pango.UNDERLINE_NONE, 0, -1)) self.label.set_attributes(attr)
def add_text(self, buddy, text, status_message=False): """Display text on screen, with name and colors. buddy -- buddy object or dict {nick: string, color: string} (The dict is for loading the chat log from the journal, when we don't have the buddy object any more.) text -- string, what the buddy said status_message -- boolean False: show what buddy said True: show what buddy did hippo layout: .------------- rb ---------------. | +name_vbox+ +----msg_vbox----+ | | | | | | | | | nick: | | +--msg_hbox--+ | | | | | | | text | | | | +---------+ | +------------+ | | | | | | | | +--msg_hbox--+ | | | | | text | url | | | | | +------------+ | | | +----------------+ | `--------------------------------' """ if not buddy: buddy = self.owner if type(buddy) is dict: # dict required for loading chat log from journal nick = buddy['nick'] color = buddy['color'] else: nick = buddy.props.nick color = buddy.props.color try: color_stroke_html, color_fill_html = color.split(',') except ValueError: color_stroke_html, color_fill_html = ('#000000', '#888888') # Select text color based on fill color: color_fill_rgba = Color(color_fill_html).get_rgba() color_fill_gray = (color_fill_rgba[0] + color_fill_rgba[1] + color_fill_rgba[2]) / 3 color_stroke = Color(color_stroke_html).get_int() color_fill = Color(color_fill_html).get_int() if color_fill_gray < 0.5: text_color = COLOR_WHITE.get_int() else: text_color = COLOR_BLACK.get_int() self._add_log(nick, color, text, status_message) # Check for Right-To-Left languages: if pango.find_base_dir(nick, -1) == pango.DIRECTION_RTL: lang_rtl = True else: lang_rtl = False # Check if new message box or add text to previous: new_msg = True if self._last_msg_sender: if not status_message: if buddy == self._last_msg_sender: # Add text to previous message new_msg = False if not new_msg: rb = self._last_msg msg_vbox = rb.get_children()[1] msg_hbox = hippo.CanvasBox( orientation=hippo.ORIENTATION_HORIZONTAL) msg_vbox.append(msg_hbox) else: rb = CanvasRoundBox(background_color=color_fill, border_color=color_stroke, padding=4) rb.props.border_color = color_stroke # Bug #3742 self._last_msg = rb self._last_msg_sender = buddy if not status_message: name = hippo.CanvasText(text=nick + ': ', color=text_color) name_vbox = hippo.CanvasBox( orientation=hippo.ORIENTATION_VERTICAL) name_vbox.append(name) rb.append(name_vbox) msg_vbox = hippo.CanvasBox(orientation=hippo.ORIENTATION_VERTICAL) rb.append(msg_vbox) msg_hbox = hippo.CanvasBox( orientation=hippo.ORIENTATION_HORIZONTAL) msg_vbox.append(msg_hbox) if status_message: self._last_msg_sender = None match = URL_REGEXP.search(text) while match: # there is a URL in the text starttext = text[:match.start()] if starttext: message = hippo.CanvasText( text=starttext, size_mode=hippo.CANVAS_SIZE_WRAP_WORD, color=text_color, xalign=hippo.ALIGNMENT_START) msg_hbox.append(message) url = text[match.start():match.end()] message = CanvasLink(text=url, color=text_color) attrs = pango.AttrList() attrs.insert(pango.AttrUnderline(pango.UNDERLINE_SINGLE, 0, 32767)) message.set_property("attributes", attrs) message.connect('activated', self._link_activated_cb) # call interior magic which should mean just: # CanvasInvoker().parent = message CanvasInvoker(message) msg_hbox.append(message) text = text[match.end():] match = URL_REGEXP.search(text) if text: message = hippo.CanvasText(text=text, size_mode=hippo.CANVAS_SIZE_WRAP_WORD, color=text_color, xalign=hippo.ALIGNMENT_START) msg_hbox.append(message) # Order of boxes for RTL languages: if lang_rtl: msg_hbox.reverse() if new_msg: rb.reverse() if new_msg: box = hippo.CanvasBox(padding=2) box.append(rb) self._conversation.append(box)
def __expose_event(self, widget, event=None): """Handle drawing bread crumbs""" foreground_context = widget.get_style().fg_gc[self._state] background_context = widget.window.cairo_create() layout = widget.create_pango_layout('') text_to_draw = self._path path_length = len(self._path) # make sure we have allocation if self._allocation is None: self._allocation = widget.get_allocation() # create attributes attributes = pango.AttrList() # check if path is part of previous one if self._type is Breadcrumbs.TYPE_SMART \ and self._previous_path is not None \ and self._previous_path.startswith(self._path): smart_color = (self._smart_color.red, self._smart_color.green, self._smart_color.blue) attributes.insert( pango.AttrForeground(*smart_color, start_index=path_length, end_index=len(self._previous_path))) text_to_draw = self._previous_path # calculate width of path elements if self._elements_width is None: path = None provider = self._parent._parent.get_provider() self._elements_size = [] self._elements_width = [] # split root element from others root_element = provider.get_root_path(text_to_draw) other_elements = text_to_draw[len(root_element):] # make sure our path doesn't begin with slash if other_elements.startswith(os.path.sep): other_elements = other_elements[1:] # split elements elements = other_elements.split(os.path.sep) elements.insert(0, root_element) for element in elements: # get path size path = os.path.join(path, element) if path is not None else element layout.set_text(path) # add width to the list width = layout.get_size()[0] / pango.SCALE self._elements_size.append(len(path)) self._elements_width.append(width) # underline hovered path if specified if None not in (self._highlight_index, self._elements_size): width = self._elements_size[self._highlight_index] attributes.insert( pango.AttrUnderline(pango.UNDERLINE_SINGLE, 0, width)) # prepare text for drawing layout.set_text(text_to_draw) layout.set_attributes(attributes) # draw background color background_context.set_source_color(self._colors[0]) background_context.rectangle(0, 0, self._allocation[2], self._allocation[3]) background_context.fill() # draw text widget.window.draw_layout(foreground_context, 0, 0, layout) return True
def get_calculated_rect(self, context, rect): angle = 2 * math.pi * self._rotation / 360.0 if self._context == None: label = gtk.Label() self._context = label.create_pango_context() pango_context = self._context attrs = pango.AttrList() attrs.insert(pango.AttrWeight(self._weight, 0, len(self._text))) attrs.insert(pango.AttrStyle(self._slant, 0, len(self._text))) attrs.insert(pango.AttrUnderline(self._underline, 0, len(self._text))) if self._size != None: attrs.insert(pango.AttrSize(1000 * self._size, 0, len(self._text))) if self._layout == None: self._layout = pango.Layout(pango_context) layout = self._layout if self._markup: layout.set_markup(self._text) else: layout.set_text(self._text) layout.set_attributes(attrs) #find out where to draw the layout and calculate the maximum width width = rect.width * math.cos(angle) + rect.height * math.sin(angle) if self._anchor in [ANCHOR_BOTTOM_LEFT, ANCHOR_TOP_LEFT, ANCHOR_LEFT_CENTER]: width = rect.width - self._position[0] elif self._anchor in [ANCHOR_BOTTOM_RIGHT, ANCHOR_TOP_RIGHT, ANCHOR_RIGHT_CENTER]: width = self._position[0] text_width, text_height = layout.get_pixel_size() width = min(width, self._max_width) if self._wrap: layout.set_wrap(pango.WRAP_WORD_CHAR) layout.set_width(int(1000 * width)) #====================================================================== text_width, text_height = layout.get_pixel_size() anchor = self._anchor x, y = self._position #anchor translation tx, ty = 0, 0 ttx, tty = 0, 0 if anchor == ANCHOR_BOTTOM_LEFT: tx = text_height * math.sin(angle) ty = text_height * math.cos(angle) ttx = 0 tty = text_height elif anchor == ANCHOR_TOP_LEFT: tx = 0 ty = 0 elif anchor == ANCHOR_TOP_RIGHT: tx = text_width * math.cos(angle) ty = -text_width * math.sin(angle) ttx = text_width tty = 0 elif anchor == ANCHOR_BOTTOM_RIGHT: tx = text_width * math.cos(angle) + text_height * math.sin(angle) ty = -text_width * math.sin(angle) + text_height * math.cos(angle) ttx = text_width tty = text_height elif anchor == ANCHOR_CENTER: tx = (text_width * math.cos(angle) + text_height * math.sin(angle)) / 2 ty = (-text_width * math.sin(angle) + text_height * math.cos(angle)) / 2 ttx = text_width / 2 tty = text_height / 2 elif anchor == ANCHOR_TOP_CENTER: tx = text_width * math.cos(angle) / 2 ty = -text_width * math.sin(angle) / 2 ttx = text_width / 2 tty = 0 elif anchor == ANCHOR_BOTTOM_CENTER: tx = text_width * math.cos(angle) / 2 + text_height * math.sin(angle) ty = -text_width * math.sin(angle) / 2 + text_height * math.cos(angle) ttx = text_width / 2 tty = text_height elif anchor == ANCHOR_LEFT_CENTER: tx = text_height * math.sin(angle) / 2 ty = text_height * math.cos(angle) / 2 ttx = 0 tty = text_height / 2 elif anchor == ANCHOR_RIGHT_CENTER: tx = text_width * math.cos(angle) + text_height * math.sin(angle) / 2 ty = -text_width * math.sin(angle) + text_height * math.cos(angle) / 2 ttx = text_width tty = text_height / 2 #calculate the bounding rect real_x = x - ttx real_y = y - tty top_left = real_x, real_y bottom_left = real_x , real_y + text_height bottom_right = real_x + text_width, real_y + text_height top_right = real_x + text_width, real_y offset = x, y n_top_left = rotate_vector(offset, top_left, angle) n_bottom_left = rotate_vector(offset, bottom_left, angle) n_bottom_right = rotate_vector(offset, bottom_right, angle) n_top_right = rotate_vector(offset, top_right, angle) alloc_x_min = int(min(n_top_left[0], n_bottom_left[0], n_bottom_right[0], n_top_right[0])) alloc_x_max = int(max(n_top_left[0], n_bottom_left[0], n_bottom_right[0], n_top_right[0])) alloc_y_min = int(min(n_top_left[1], n_bottom_left[1], n_bottom_right[1], n_top_right[1])) alloc_y_max = int(max(n_top_left[1], n_bottom_left[1], n_bottom_right[1], n_top_right[1])) rect = gtk.gdk.Rectangle(alloc_x_min, alloc_y_min, alloc_x_max - alloc_x_min, alloc_y_max - alloc_y_min) return rect
def get_calculated_dimensions(self, context, rect): angle = 2 * math.pi * self._rotation / 360.0 if self._context == None: label = gtk.Label() self._context = label.create_pango_context() pango_context = self._context attrs = pango.AttrList() attrs.insert(pango.AttrWeight(self._weight, 0, len(self._text))) attrs.insert(pango.AttrStyle(self._slant, 0, len(self._text))) attrs.insert(pango.AttrUnderline(self._underline, 0, len(self._text))) if self._size != None: attrs.insert(pango.AttrSize(1000 * self._size, 0, len(self._text))) if self._layout == None: self._layout = pango.Layout(pango_context) layout = self._layout layout.set_text(self._text) layout.set_attributes(attrs) #find out where to draw the layout and calculate the maximum width width = rect.width if self._anchor in [ ANCHOR_BOTTOM_LEFT, ANCHOR_TOP_LEFT, ANCHOR_LEFT_CENTER ]: width = rect.width - self._position[0] elif self._anchor in [ ANCHOR_BOTTOM_RIGHT, ANCHOR_TOP_RIGHT, ANCHOR_RIGHT_CENTER ]: width = self._position[0] text_width, text_height = layout.get_pixel_size() width = width * math.cos(angle) width = min(width, self._max_width) if self._wrap: layout.set_wrap(pango.WRAP_WORD_CHAR) layout.set_width(int(1000 * width)) x, y = get_text_pos(layout, self._position, self._anchor, angle) if not self._fixed: #Find already drawn labels that would intersect with the current one #and adjust position to avoid intersection. text_width, text_height = layout.get_pixel_size() real_width = abs(text_width * math.cos(angle)) + abs( text_height * math.sin(angle)) real_height = abs(text_height * math.cos(angle)) + abs( text_width * math.sin(angle)) other_labels = get_registered_labels() this_rect = gtk.gdk.Rectangle(int(x), int(y), int(real_width), int(real_height)) for label in other_labels: label_rect = label.get_allocation() intersection = this_rect.intersect(label_rect) if intersection.width == 0 and intersection.height == 0: continue y_diff = 0 if label_rect.y <= y and label_rect.y + label_rect.height >= y: y_diff = y - label_rect.y + label_rect.height elif label_rect.y > y and label_rect.y < y + real_height: y_diff = label_rect.y - real_height - y y += y_diff #calculate the dimensions text_width, text_height = layout.get_pixel_size() real_width = abs(text_width * math.cos(angle)) + abs( text_height * math.sin(angle)) real_height = abs(text_height * math.cos(angle)) + abs( text_width * math.sin(angle)) return real_width, real_height
def render(self, text, antialias=True, color=(255, 255, 255), background=None): """Render the font onto a new Surface and return it. We ignore 'antialias' and use system settings. text -- (unicode) string with the text to render antialias -- attempt to antialias the text or not color -- three or four-tuple of 0-255 values specifying rendering colour for the text background -- three or four-tuple of 0-255 values specifying rendering colour for the background, or None for trasparent background returns a pygame image instance """ log.info('render: %r, antialias = %s, color=%s, background=%s', text, antialias, color, background) # create layout layout = pango.Layout(gtk.gdk.pango_context_get()) layout.set_font_description(self.fd) if self.underline: attrs = layout.get_attributes() if not attrs: attrs = pango.AttrList() attrs.insert(pango.AttrUnderline(pango.UNDERLINE_SINGLE, 0, 32767)) layout.set_attributes(attrs) layout.set_text(text) # determine pixel size (logical, ink) = layout.get_pixel_extents() ink = pygame.rect.Rect(ink) # Create a new Cairo ImageSurface csrf, cctx = _cairoimage.newContext(ink.w, ink.h) cctx = pangocairo.CairoContext(cctx) # Mangle the colors on little-endian machines. The reason for this # is that Cairo writes native-endian 32-bit ARGB values whereas # Pygame expects endian-independent values in whatever format. So we # tell our users not to expect transparency here (avoiding the A issue) # and we swizzle all the colors around. # render onto it if background is not None: background = _cairoimage.mangle_color(background) cctx.set_source_rgba(*background) cctx.paint() log.debug('incoming color: %s', color) color = _cairoimage.mangle_color(color) log.debug(' translated color: %s', color) cctx.new_path() cctx.layout_path(layout) cctx.set_source_rgba(*color) cctx.fill() # Create and return a new Pygame Image derived from the Cairo Surface return _cairoimage.asImage(csrf)
def attrs_changed(self): bold = False italics = False underline = False pango_font = None del self.attrlist self.attrlist = pango.AttrList() # TODO: splice instead of own method it = self.attributes.get_iterator() while 1: at = it.get_attrs() for x in at: self.attrlist.insert(x) if it.next() == False: break if self.preedit: ins_text = self.preedit[0] ins_style = self.preedit[1] if self.index == len(self.text): show_text = self.text + ins_text elif self.index == 0: show_text = ins_text + self.text else: split1 = self.text[:self.index] split2 = self.text[self.index:] show_text = split1 + ins_text + split2 self.attrlist.splice(ins_style, self.index, len(ins_text)) else: show_text = self.text it = self.attributes.get_iterator() while (1): found = False r = it.range() if self.index == self.end_index: if r[0] <= self.index and r[1] > self.index: found = True elif self.index < self.end_index: if r[0] > self.end_index: break if self.index == self.end_index and \ r[0] < self.index and \ r[1] > self.index: found = True elif self.index != self.end_index and r[0] <= self.index and \ r[1] >= self.end_index: # We got a winner! found = True else: if r[0] > self.index: break if self.index == self.end_index and \ r[0] < self.index and \ r[1] > self.index: found = True elif self.index != self.end_index and r[0] <= self.end_index and \ r[1] >= self.index: # We got another winner! found = True if found: # FIXME: the it.get() seems to crash python # through pango. attr = it.get_attrs() for x in attr: if x.type == pango.ATTR_WEIGHT and \ x.value == pango.WEIGHT_BOLD: bold = True elif x.type == pango.ATTR_STYLE and \ x.value == pango.STYLE_ITALIC: italics = True elif x.type == pango.ATTR_UNDERLINE and \ x.value == pango.UNDERLINE_SINGLE: underline = True elif x.type == pango.ATTR_FONT_DESC: pango_font = x.desc if it.next() == False: break to_add = [] if bold: to_add.append( pango.AttrWeight(pango.WEIGHT_BOLD, self.index, self.index)) if italics: to_add.append( pango.AttrStyle(pango.STYLE_ITALIC, self.index, self.index)) if underline: to_add.append( pango.AttrUnderline(pango.UNDERLINE_SINGLE, self.index, self.index)) if pango_font: to_add.append( pango.AttrFontDesc(pango_font, self.index, self.index)) for x in self.current_attrs: if x.type == pango.ATTR_WEIGHT and x.value == pango.WEIGHT_BOLD: bold = True to_add.append(x) if x.type == pango.ATTR_STYLE and x.value == pango.STYLE_ITALIC: italics = True to_add.append(x) if x.type == pango.ATTR_UNDERLINE and x.value == pango.UNDERLINE_SINGLE: underline = True to_add.append(x) if x.type == pango.ATTR_FONT_DESC: pango_font = x.desc to_add.append(x) del self.current_attrs self.current_attrs = to_add self.emit("update-attrs", bold, italics, underline, pango_font) return show_text
def attrs_changed(self): bold = False italics = False underline = False pango_font = None del self.attrlist self.attrlist = self.attributes.copy() if self.preedit: ins_text = self.preedit[0] ins_style = self.preedit[1] if self.index == len(self.text): show_text = self.text + ins_text elif self.index == 0: show_text = ins_text + self.text else: split1 = self.text[:self.index] split2 = self.text[self.index:] show_text = split1 + ins_text + split2 self.attrlist.splice(ins_style, self.index, len(ins_text)) else: show_text = self.text it = wrap_attriterator(self.attributes.get_iterator()) for attrs, (start, end) in it: found = False if self.index == self.end_index: if start <= self.index and end > self.index: found = True elif self.index < self.end_index: if start > self.end_index: break elif start <= self.index and \ end >= self.end_index: # We got a winner! found = True else: # i.e. self.index > self.end_index if start > self.index: break elif start <= self.end_index and \ end >= self.index: # We got another winner! found = True if found: for x in attrs: if x.type == pango.ATTR_WEIGHT and \ x.value == pango.WEIGHT_BOLD: bold = True elif x.type == pango.ATTR_STYLE and \ x.value == pango.STYLE_ITALIC: italics = True elif x.type == pango.ATTR_UNDERLINE and \ x.value == pango.UNDERLINE_SINGLE: underline = True elif x.type == pango.ATTR_FONT_DESC: pango_font = x.desc to_add = [] if bold: to_add.append( pango.AttrWeight(pango.WEIGHT_BOLD, self.index, self.index)) if italics: to_add.append( pango.AttrStyle(pango.STYLE_ITALIC, self.index, self.index)) if underline: to_add.append( pango.AttrUnderline(pango.UNDERLINE_SINGLE, self.index, self.index)) if pango_font: to_add.append( pango.AttrFontDesc(pango_font, self.index, self.index)) for x in self.current_attrs: if x.type == pango.ATTR_WEIGHT and x.value == pango.WEIGHT_BOLD: bold = True to_add.append(x) if x.type == pango.ATTR_STYLE and x.value == pango.STYLE_ITALIC: italics = True to_add.append(x) if x.type == pango.ATTR_UNDERLINE and x.value == pango.UNDERLINE_SINGLE: underline = True to_add.append(x) if x.type == pango.ATTR_FONT_DESC: pango_font = x.desc to_add.append(x) del self.current_attrs self.current_attrs = to_add self.emit("update-attrs", bold, italics, underline, pango_font) return show_text
def generate_images(opts,args): # Set up variables for drawing space width = 2550 # Will resize to match text; default 8.5"x11" @ 300dpi height = 3300 MARGIN_X = 300 MARGIN_Y = 300 LINE_SPACE = 35 #TODO: Command-line opts LANG = "ka" TESS_LANG = "kat" # Set up decent spacing for box files attrs = pango.AttrList() #TODO: Command line opts or config attrs.insert(pango.AttrLanguage(LANG,0,-1)) attrs.insert(pango.AttrLetterSpacing(10000,0,-1)) attrs.insert(pango.AttrSize(48000,0,-1)) attrs.insert(pango.AttrFallback(False,0,-1)) attrs.insert(pango.AttrStyle(pango.STYLE_NORMAL,0,-1)) attrs.insert(pango.AttrWeight(pango.WEIGHT_NORMAL,0,-1)) attrs.insert(pango.AttrUnderline(pango.UNDERLINE_NONE,0,-1)) # Instantiate Cairo surface and context surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) context = pangocairo.CairoContext(cairo.Context(surf)) # Instantiate PangoCairo context context.set_antialias(cairo.ANTIALIAS_SUBPIXEL) #get font families: font_map = pangocairo.cairo_font_map_get_default() # to see family names: if opts.list_fonts: print [f.get_name() for f in font_map.list_families()] return # Set up pango layout layout = context.create_layout() layout.set_attributes(attrs) layout.set_width((width+MARGIN_X)*pango.SCALE) layout.set_spacing(LINE_SPACE*pango.SCALE) #print layout.get_width() # Read text from file TODO: Command line argument # TODO: Multiple files print to multiple image documents text = '' with codecs.open(opts.input_file) as text_file: for line in text_file: text += line + '\n' font_names = args # (variant, reset,"desc") #Font variants is an array of tuples consisting of: (AttrStyle, InverseAttrStyle, Name) font_variants = [ (pango.AttrStyle(pango.STYLE_NORMAL,0,-1),pango.AttrStyle(pango.STYLE_NORMAL,0,-1),"")] #Add other stylings based on command-line options if opts.italic: font_variants.append((pango.AttrStyle(pango.STYLE_ITALIC,0,-1),pango.AttrStyle(pango.STYLE_NORMAL,0,-1),"italic")) if opts.bold: font_variants.append((pango.AttrWeight(pango.WEIGHT_HEAVY,0,-1),pango.AttrWeight(pango.WEIGHT_NORMAL,0,-1),"bold")) if opts.underline: font_variants.append((pango.AttrUnderline(pango.UNDERLINE_SINGLE,0,-1),pango.AttrUnderline(pango.UNDERLINE_NONE,0,-1),"underline")) #Generate pages for each font name and variation. for fn in font_names: for fvar in font_variants: # Change to a new variant attrs.change(fvar[0]) layout.set_attributes(attrs) # Change to a new font fontname = fn font = pango.FontDescription(fontname + " 25") layout.set_font_description(font) layout.set_text(text) (ink, logical) = layout.get_pixel_extents() # If layout exceeds size of surface, change surface size if logical[2] > (width-MARGIN_X) or logical[3] > (height-MARGIN_Y): width = logical[2]+MARGIN_X height = logical[3]+MARGIN_Y surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) context = pangocairo.CairoContext(cairo.Context(surf)) context.update_layout(layout) #draw a background rectangle: context.rectangle(0,0,width,height) context.set_source_rgb(1, 1, 1) context.fill() # Translate context so that desired text upperleft corner is at 0,0 context.translate(50,25) context.set_source_rgb(0, 0, 0) context.update_layout(layout) context.show_layout(layout) # Write to image # TODO: Specify outfile on command line #print fontname #print fvar[2] with open(TESS_LANG+"."+fontname+fvar[2]+".exp0.png", "wb") as image_file: surf.write_to_png(image_file) attrs.change(fvar[1]) layout.set_attributes(attrs)
def update_surface(self, bbox, zoom, style, callback=lambda x=None: None): rendertimer = Timer("Rendering image") if "image" not in style.cache: style.cache["image"] = ImageLoader() timer = Timer("Getting data") self.zoom = zoom self.bbox = bbox self.bbox_p = projections.from4326(bbox, self.proj) print self.bbox_p scale = abs(self.w / (self.bbox_p[0] - self.bbox_p[2]) / math.cos(math.pi * (self.bbox[1] + self.bbox[3]) / 2 / 180)) zscale = 0.5 * scale cr = cairo.Context(self.surface) # getting and setting canvas properties bgs = style.get_style("canvas", {}, self.zoom, scale, zscale) if not bgs: bgs = [{}] bgs = bgs[0] cr.rectangle(0, 0, self.w, self.h) # canvas color and opcity color = bgs.get("fill-color", (0.7, 0.7, 0.7)) cr.set_source_rgba(color[0], color[1], color[2], bgs.get("fill-opacity", 1)) cr.fill() callback() # canvas antialiasing antialias = bgs.get("antialias", "full") if antialias == "none": "no antialiasing enabled" cr.set_antialias(1) #cr.font_options_set_antialias(1) elif antialias == "text": "only text antialiased" cr.set_antialias(1) #cr.font_options_set_antialias(2) else: "full antialias" cr.set_antialias(2) #cr.font_options_set_antialias(2) datatimer = Timer("Asking backend") if "get_sql_hints" in dir(style): hints = style.get_sql_hints('way', self.zoom) else: hints = None if "get_interesting_tags" in dir(style): itags = style.get_interesting_tags(zoom=self.zoom) else: itags = None # enlarge bbox by 20% to each side. results in more vectors, but makes less artifaces. span_x, span_y = bbox[2] - bbox[0], bbox[3] - bbox[1] bbox_expand = [ bbox[0] - 0.2 * span_x, bbox[1] - 0.2 * span_y, bbox[2] + 0.2 * span_x, bbox[3] + 0.2 * span_y ] vectors = self.data.get_vectors(bbox_expand, self.zoom, hints, itags).values() datatimer.stop() datatimer = Timer("Applying styles") ww = [] for way in vectors: type = "line" if way.coords[0] == way.coords[-1]: type == "area" st = style.get_style("area", way.tags, self.zoom, scale, zscale) if st: for fpt in st: #debug(fpt) ww.append([way.copy(), fpt]) datatimer.stop() debug("%s objects on screen (%s in dataset)" % (len(ww), len(vectors))) er = Timer("Projecing data") if self.data.proj != self.proj: for w in ww: w[0].cs = [ self.lonlat2screen(coord) for coord in projections.transform( w[0].coords, self.data.proj, self.proj) ] else: for w in ww: w[0].cs = [self.lonlat2screen(coord) for coord in w[0].coords] for w in ww: if "offset" in w[1]: offset = float(w[1]["offset"]) w[0] = w[0].copy() w[0].cs = offset_line(w[0].cs, offset) if "raise" in w[1] and not "extrude" in w[1]: w[0] = w[0].copy() offset = float(w[1]["raise"]) w[0].cs_real = w[0].cs w[0].cs = [(x, y - offset) for x, y in w[0].cs] if "extrude" in w[1]: if w[1]["extrude"] < 2: del w[1]["extrude"] if "extrude" in w[1] and "fill-color" not in w[1] and "width" in w[ 1]: w[1]["fill-color"] = w[1].get("color", (0, 0, 0)) w[1]["fill-opacity"] = w[1].get("opacity", 1) w[0] = w[0].copy() #print w[0].cs w[0].cs = offset_line(w[0].cs, w[1]["width"] / 2) #print w[0].cs aa = offset_line(w[0].cs, -w[1]["width"]) del w[1]["width"] aa.reverse() w[0].cs.extend(aa) er.stop() ww.sort(key=lambda x: x[1]["layer"]) layers = list(set([int(x[1]["layer"] / 100.) for x in ww])) layers.sort() objs_by_layers = {} for layer in layers: objs_by_layers[layer] = [] for obj in ww: objs_by_layers[int(obj[1]["layer"] / 100.)].append(obj) del ww timer.stop() timer = Timer("Rasterizing image") linecaps = {"butt": 0, "round": 1, "square": 2} linejoin = {"miter": 0, "round": 1, "bevel": 2} text_rendered_at = set([(-100, -100)]) for layer in layers: data = objs_by_layers[layer] #data.sort(lambda x,y:cmp(max([x1[1] for x1 in x[0].cs]), max([x1[1] for x1 in y[0].cs]))) # - fill polygons for obj in data: if ("fill-color" in obj[1] or "fill-image" in obj[1] ) and not "extrude" in obj[1]: ## TODO: fill-image color = obj[1].get("fill-color", (0, 0, 0)) cr.set_source_rgba(color[0], color[1], color[2], obj[1].get("fill-opacity", 1)) if "fill-image" in obj[1]: image = style.cache["image"][obj[1]["fill-image"]] if image: pattern = cairo.SurfacePattern(image) pattern.set_extend(cairo.EXTEND_REPEAT) cr.set_source(pattern) poly(cr, obj[0].cs) # - draw casings on layer for obj in data: ### Extras: casing-linecap, casing-linejoin if "casing-width" in obj[1] or "casing-color" in obj[ 1] and "extrude" not in obj[1]: cr.set_dash(obj[1].get("casing-dashes", obj[1].get("dashes", []))) cr.set_line_join( linejoin.get( obj[1].get("casing-linejoin", obj[1].get("linejoin", "round")), 1)) color = obj[1].get("casing-color", (0, 0, 0)) cr.set_source_rgba(color[0], color[1], color[2], obj[1].get("casing-opacity", 1)) ## TODO: good combining of transparent lines and casing ## Probable solution: render casing, render way as mask and put casing with mask chopped out onto image cr.set_line_width(obj[1].get("width", 0) + obj[1].get("casing-width", 1)) cr.set_line_cap( linecaps.get( obj[1].get("casing-linecap", obj[1].get("linecap", "butt")), 0)) line(cr, obj[0].cs) # - draw line centers for obj in data: if ("width" in obj[1] or "color" in obj[1] or "image" in obj[1]) and "extrude" not in obj[1]: cr.set_dash(obj[1].get("dashes", [])) cr.set_line_join( linejoin.get(obj[1].get("linejoin", "round"), 1)) color = obj[1].get("color", (0, 0, 0)) cr.set_source_rgba(color[0], color[1], color[2], obj[1].get("opacity", 1)) ## TODO: better overlapping of transparent lines. ## Probable solution: render them (while they're of the same opacity and layer) on a temporary canvas that's merged into main later cr.set_line_width(obj[1].get("width", 1)) cr.set_line_cap( linecaps.get(obj[1].get("linecap", "butt"), 0)) if "image" in obj[1]: image = style.cache["image"][obj[1]["image"]] if image: pattern = cairo.SurfacePattern(image) pattern.set_extend(cairo.EXTEND_REPEAT) cr.set_source(pattern) line(cr, obj[0].cs) callback() # - extruding polygons #data.sort(lambda x,y:cmp(max([x1[1] for x1 in x[0].cs]), max([x1[1] for x1 in y[0].cs]))) # Pass 1. Creating list of extruded polygons extlist = [] # fromat: (coords, ("h"/"v", y,z), real_obj) for obj in data: if "extrude" in obj[1]: def face_to_poly(face, hgt): """ Converts a line into height-up extruded poly """ return [ face[0], face[1], (face[1][0], face[1][1] - hgt), (face[0][0], face[0][1] - hgt), face[0] ] hgt = obj[1]["extrude"] raised = float(obj[1].get("raise", 0)) excoords = [(a[0], a[1] - hgt - raised) for a in obj[0].cs] faces = [] coord = obj[0].cs[-1] #p_coord = (coord[0],coord[1]-raised) p_coord = False for coord in obj[0].cs: c = (coord[0], coord[1] - raised) if p_coord: extlist.append((face_to_poly([c, p_coord], hgt), ("v", min(coord[1], p_coord[1]), hgt), obj)) p_coord = c extlist.append( (excoords, ("h", min(coord[1], p_coord[1]), hgt), obj)) #faces.sort(lambda x,y:cmp(max([x1[1] for x1 in x]), max([x1[1] for x1 in y]))) # Pass 2. Sorting def compare_things(a, b): """ Custom comparator for extlist sorting. Sorts back-to-front, bottom-to-top, | > \ > _, horizontal-to-vertical. """ t1, t2 = a[1], b[1] # if t1[1] > t2[1]: # back-to-front return 1 if t1[1] < t2[1]: return -1 if t1[2] > t2[2]: # bottom-to-top return 1 if t1[2] < t2[2]: return -1 if t1[0] < t2[0]: # h-to-v return 1 if t1[0] > t2[0]: return -1 return cmp( math.sin( math.atan2(a[0][0][0] - a[0][1][0], a[0][0][0] - a[0][1][0])), math.sin( math.atan2(b[0][0][0] - b[0][1][0], b[0][0][0] - b[0][1][0]))) print t1 print t2 extlist.sort(compare_things) # Pass 3. Rendering using painter's algorythm cr.set_dash([]) for ply, prop, obj in extlist: if prop[0] == "v": color = obj[1].get("extrude-face-color", obj[1].get("color", (0, 0, 0))) cr.set_source_rgba( color[0], color[1], color[2], obj[1].get("extrude-face-opacity", obj[1].get("opacity", 1))) poly(cr, ply) color = obj[1].get("extrude-edge-color", obj[1].get("color", (0, 0, 0))) cr.set_source_rgba( color[0], color[1], color[2], obj[1].get("extrude-edge-opacity", obj[1].get("opacity", 1))) cr.set_line_width(.5) line(cr, ply) if prop[0] == "h": if "fill-color" in obj[1]: color = obj[1]["fill-color"] cr.set_source_rgba( color[0], color[1], color[2], obj[1].get("fill-opacity", obj[1].get("opacity", 1))) poly(cr, ply) color = obj[1].get("extrude-edge-color", obj[1].get("color", (0, 0, 0))) cr.set_source_rgba( color[0], color[1], color[2], obj[1].get("extrude-edge-opacity", obj[1].get("opacity", 1))) cr.set_line_width(1) line(cr, ply) #cr.set_line_width (obj[1].get("width", 1)) #color = obj[1].get("color", (0,0,0) ) #cr.set_source_rgba(color[0], color[1], color[2], obj[1].get("extrude-edge-opacity", obj[1].get("opacity", 1))) #line(cr,excoords) #if "fill-color" in obj[1]: #color = obj[1]["fill-color"] #cr.set_source_rgba(color[0], color[1], color[2], obj[1].get("fill-opacity", 1)) #poly(cr,excoords) for obj in data: if "icon-image" in obj[1]: image = style.cache["image"][obj[1]["icon-image"]] if image: dy = image.get_height() / 2 dx = image.get_width() / 2 where = self.lonlat2screen( projections.transform(obj[0].center, self.data.proj, self.proj)) cr.set_source_surface(image, where[0] - dx, where[1] - dy) cr.paint() callback() # - render text labels texttimer = Timer("Text rendering") cr.set_line_join( 1 ) # setting linejoin to "round" to get less artifacts on halo render for obj in data: if "text" in obj[1]: text = obj[1]["text"] #cr.set_line_width (obj[1].get("width", 1)) #cr.set_font_size(float(obj[1].get("font-size", 9))) ft_desc = pango.FontDescription() ft_desc.set_family(obj[1].get('font-family', 'sans')) ft_desc.set_size(pango.SCALE * int(obj[1].get('font-size', 9))) fontstyle = obj[1].get('font-style', 'normal') if fontstyle == 'italic': fontstyle = pango.STYLE_ITALIC else: fontstyle = pango.STYLE_NORMAL ft_desc.set_style(fontstyle) fontweight = obj[1].get('font-weight', 400) try: fontweight = int(fontweight) except ValueError: if fontweight == 'bold': fontweight = 700 else: fontweight = 400 ft_desc.set_weight(fontweight) if obj[1].get('text-transform', None) == 'uppercase': text = text.upper() p_ctx = pangocairo.CairoContext(cr) p_layout = p_ctx.create_layout() p_layout.set_font_description(ft_desc) p_layout.set_text(text) p_attrs = pango.AttrList() decoration = obj[1].get('text-decoration', 'none') if decoration == 'underline': p_attrs.insert( pango.AttrUnderline(pango.UNDERLINE_SINGLE, end_index=-1)) decoration = obj[1].get('font-variant', 'none') if decoration == 'small-caps': p_attrs.insert( pango.AttrVariant(pango.VARIANT_SMALL_CAPS, start_index=0, end_index=-1)) p_layout.set_attributes(p_attrs) if obj[1].get("text-position", "center") == "center": where = self.lonlat2screen( projections.transform(obj[0].center, self.data.proj, self.proj)) for t in text_rendered_at: if ((t[0] - where[0])**2 + (t[1] - where[1])**2) < 15 * 15: break else: text_rendered_at.add(where) #debug ("drawing text: %s at %s"%(text, where)) if "text-halo-color" in obj[ 1] or "text-halo-radius" in obj[1]: cr.new_path() cr.move_to(where[0], where[1]) cr.set_line_width(obj[1].get( "text-halo-radius", 1)) color = obj[1].get("text-halo-color", (1., 1., 1.)) cr.set_source_rgb(color[0], color[1], color[2]) cr.text_path(text) cr.stroke() cr.new_path() cr.move_to(where[0], where[1]) cr.set_line_width(obj[1].get( "text-halo-radius", 1)) color = obj[1].get("text-color", (0., 0., 0.)) cr.set_source_rgb(color[0], color[1], color[2]) cr.text_path(text) cr.fill() else: ### render text along line c = obj[0].cs text = unicode(text, "utf-8") # - calculate line length length = reduce( lambda x, y: (x[0] + ((y[0] - x[1])**2 + (y[1] - x[2])**2)**0.5, y[0], y[1]), c, (0, c[0][0], c[0][1]))[0] #print length, text, cr.text_extents(text) if length > cr.text_extents(text)[2]: # - function to get (x, y, normale) from (c, length_along_c) def get_xy_from_len(c, length_along_c): x0, y0 = c[0] for x, y in c: seg_len = ((x - x0)**2 + (y - y0)**2)**0.5 if length_along_c < seg_len: normed = length_along_c / seg_len return (x - x0) * normed + x0, ( y - y0) * normed + y0, math.atan2( y - y0, x - x0) else: length_along_c -= seg_len x0, y0 = x, y else: return None da = 0 os = 1 z = length / 2 - cr.text_extents(text)[2] / 2 # print get_xy_from_len(c,z) if c[0][0] < c[1][0] and get_xy_from_len( c, z)[2] < math.pi / 2 and get_xy_from_len( c, z)[2] > -math.pi / 2: da = 0 os = 1 z = length / 2 - cr.text_extents(text)[2] / 2 else: da = math.pi os = -1 z = length / 2 + cr.text_extents(text)[2] / 2 z1 = z if "text-halo-color" in obj[ 1] or "text-halo-radius" in obj[1]: cr.set_line_width( obj[1].get("text-halo-radius", 1.5) * 2) color = obj[1].get("text-halo-color", (1., 1., 1.)) cr.set_source_rgb(color[0], color[1], color[2]) xy = get_xy_from_len(c, z) cr.save() #cr.move_to(xy[0],xy[1]) p_ctx.translate(xy[0], xy[1]) cr.rotate(xy[2] + da) #p_ctx.translate(x,y) #p_ctx.show_layout(p_layout) p_ctx.layout_path(p_layout) cr.restore() cr.stroke() #for letter in text: #cr.new_path() #xy = get_xy_from_len(c,z) ##print letter, cr.text_extents(letter) #cr.move_to(xy[0],xy[1]) #cr.save() #cr.rotate(xy[2]+da) #cr.text_path(letter) #cr.restore() #cr.stroke() #z += os*cr.text_extents(letter)[4] color = obj[1].get("text-color", (0., 0., 0.)) cr.set_source_rgb(color[0], color[1], color[2]) z = z1 xy = get_xy_from_len(c, z) cr.save() #cr.move_to(xy[0],xy[1]) p_ctx.translate(xy[0], xy[1]) cr.rotate(xy[2] + da) #p_ctx.translate(x,y) p_ctx.show_layout(p_layout) cr.restore() #for letter in text: #cr.new_path() #xy = get_xy_from_len(c,z) ##print letter, cr.text_extents(letter) #cr.move_to(xy[0],xy[1]) #cr.save() #cr.rotate(xy[2]+da) #cr.text_path(letter) #cr.restore() #cr.fill() #z += os*cr.text_extents(letter)[4] texttimer.stop() del data del layers timer.stop() rendertimer.stop() debug(self.bbox) callback(True)