def render(self, text, x, y, canvas, max_width=None, center=False, dry_run=False): """ Renders an HTML formatted string onto a canvas. Arguments: text -- The text string. x -- The left-most coordinate. y -- The top coordinate. canvas -- An openexp canvas. Keyword arguments: max_width -- The maximum width, after which line wrapping should occur, or None to wrap at screen edge. (default=None) center -- Indicates whether the text should be center aligned. (default=False) dry_run -- Indicates whether a dry run should be performed, in which case the size of the to-be-written text is returned without modifying the canvas. Returns: None if dry_run is False, or a (width, height) tuple if dry_run is True. """ text = safe_decode(text) debug.msg(text) # Parse bi-directional strings. Bidi doesn't play nice with HTML tags, # which is especially annoying for BR tags. So we first convert all BR # tags to newlines. if canvas.bidi and bidi_func is not None: text = re.sub(u'<[ ]*(br|BR)[ ]*/>', u'\n', text) text = bidi_func(text) # Convert line breaks to HTML break tags text = text.replace(os.linesep, u'<br />').replace(u'\n', u'<br />') # Initialize the style self.canvas = canvas backup_cfg = canvas.get_config() # Set the maximum width if max_width is None: max_x = canvas.experiment.var.width else: if center: max_x = x + max_width / 2 else: max_x = x + max_width # First parse the HTML self.text = [] self.paragraph = [] self.style_stack = [] self.current_tag = None self.push_style() # Optionally parse HTML if self.canvas.html: self.feed(text) else: self.handle_data(text) self.text.append(self.paragraph) # If we want to center the next, we need a dry run to calculate all the # line lengths and determine the vertical and horizontal offset for each # line max_width = 0 height = 0 if center or dry_run: l_x_offset = [] _y = y for paragraph in self.text: _x = x width = 0 dy = canvas._text_size(u'dummy')[1] for word, style in paragraph: canvas.set_config(**style) # Line wrap if we run out of the screen dx, dy = canvas._text_size(word) if _x + dx > max_x + (max_x - x): l_x_offset.append(-(_x - x) / 2) _x = x _y += dy dx = canvas._text_size(word.lstrip())[0] word = word.lstrip() # Draw! _x += dx width += dx l_x_offset.append(-(_x - x) / 2) _y += dy max_width = max(max_width, width) height += dy l_x_offset.reverse() y_offset = -(_y - y) / 2 if not dry_run: # Now render it onto the canvas if center: _y = y + y_offset else: _y = y for paragraph in self.text: if center: _x = x + l_x_offset.pop() else: _x = x dy = canvas._text_size(u'dummy')[1] for word, style in paragraph: canvas.set_config(**style) # Line wrap if we run out of the screen dx, dy = canvas._text_size(word) if _x + dx > max_x: if center: _x = x + l_x_offset.pop() else: _x = x _y += dy dx = canvas._text_size(word.lstrip())[0] word = word.lstrip() # Draw! canvas._text(word, _x, _y) _x += dx _y += dy # Restore the canvas font and colors canvas.set_config(**backup_cfg) if dry_run: return max_width, height
def render(self, text, x, y, canvas, max_width=None, center=False, dry_run=False): """ Renders an HTML formatted string onto a canvas. Arguments: text -- The text string. x -- The left-most coordinate. y -- The top coordinate. canvas -- An openexp canvas. Keyword arguments: max_width -- The maximum width, after which line wrapping should occur, or None to wrap at screen edge. (default=None) center -- Indicates whether the text should be center aligned. (default=False) dry_run -- Indicates whether a dry run should be performed, in which case the size of the to-be-written text is returned without modifying the canvas. Returns: None if dry_run is False, or a (width, height) tuple if dry_run is True. """ text = safe_decode(text) debug.msg(text) # Parse bi-directional strings. Bidi doesn't play nice with HTML tags, # which is especially annoying for BR tags. So we first convert all BR # tags to newlines. if canvas.bidi and bidi_func is not None: text = re.sub(u'<[ ]*(br|BR)[ ]*/>', u'\n', text) text = bidi_func(text) # Convert line breaks to HTML break tags text = text.replace(os.linesep, u'<br />').replace(u'\n', u'<br />') # Initialize the style self.canvas = canvas backup_cfg = canvas.get_config() # Set the maximum width if max_width is None: max_x = canvas.experiment.var.width else: if center: max_x = x + max_width/2 else: max_x = x + max_width # First parse the HTML self.text = [] self.paragraph = [] self.style_stack = [] self.current_tag = None self.push_style() # Optionally parse HTML if self.canvas.html: self.feed(text) else: self.handle_data(text) self.text.append(self.paragraph) # If we want to center the next, we need a dry run to calculate all the # line lengths and determine the vertical and horizontal offset for each # line max_width = 0 height = 0 if center or dry_run: l_x_offset = [] _y = y for paragraph in self.text: _x = x width = 0 dy = canvas._text_size(u'dummy')[1] for word, style in paragraph: canvas.set_config(**style) # Line wrap if we run out of the screen dx, dy = canvas._text_size(word) if _x+dx > max_x + (max_x-x): l_x_offset.append(-(_x-x)/2) _x = x _y += dy dx = canvas._text_size(word.lstrip())[0] word = word.lstrip() # Draw! _x += dx width += dx l_x_offset.append(-(_x-x)/2) _y += dy max_width = max(max_width, width) height += dy l_x_offset.reverse() y_offset = -(_y-y)/2 if not dry_run: # Now render it onto the canvas if center: _y = y+y_offset else: _y = y for paragraph in self.text: if center: _x = x+l_x_offset.pop() else: _x = x dy = canvas._text_size(u'dummy')[1] for word, style in paragraph: canvas.set_config(**style) # Line wrap if we run out of the screen dx, dy = canvas._text_size(word) if _x+dx > max_x: if center: _x = x+l_x_offset.pop() else: _x = x _y += dy dx = canvas._text_size(word.lstrip())[0] word = word.lstrip() # Draw! canvas._text(word, _x, _y) _x += dx _y += dy # Restore the canvas font and colors canvas.set_config(**backup_cfg) if dry_run: return max_width, height
def render(self, text, x, y, canvas, max_width=None, center=False, \ color=None, bidi=False, html=True): """ Renders an HTML formatted string onto a canvas. Arguments: text -- The text string. x -- The left-most coordinate. y -- The top coordinate. canvas -- An openexp canvas. Keyword arguments: max_width -- The maximum width, after which line wrapping should occur, or None to wrap at screen edge. (default=None) center -- Indicates whether the text should be center aligned. (default=False) color -- Indicates the color of the text or None for canvas default. (default=None) bidi -- Indicates whether bi-directional text support should be enabled. (default=False) html -- Indicates whether HTML should be parsed. (default=True) """ # Make sure that it's a string text = canvas.experiment.unistr(text) debug.msg(text) # Parse bi-directional strings if bidi and bidi_func != None: text = bidi_func(text) # Convert line breaks to HTML break tags text = text.replace(os.linesep, u'<br />').replace(u'\n', u'<br />') # Initialize the style self.canvas = canvas self.default_style = { u'style' : canvas.font_style, u'bold' : canvas.font_bold, u'italic' : canvas.font_italic, u'color' : canvas.fgcolor, u'size' : canvas.font_size, u'underline' : canvas.font_underline } backup_style = self.default_style.copy() # Optionally override color if color != None: self.default_style[u'color'] = color # Set the maximum width if max_width == None: max_x = canvas.experiment.width else: if center: max_x = x + max_width/2 else: max_x = x + max_width # First parse the HTML self.text = [] self.paragraph = [] self.style_stack = [] self.current_tag = None self.push_style() # Optionally parse HTML if html: self.feed(text) else: self.handle_data(text) self.text.append(self.paragraph) # If we want to center the next, we need a dry run to calculate all the # line lengths and determine the vertical and horizontal offset for each # line if center: l_x_offset = [] _y = y for paragraph in self.text: _x = x dy = canvas.text_size(u'dummy')[1] for word, style in paragraph: # Set the style canvas.set_font(style[u'style'], int(style[u'size']), \ bold=style[u'bold'], italic=style[u'italic'], \ underline=style[u'underline']) # Line wrap if we run out of the screen dx, dy = canvas.text_size(word) if _x+dx > max_x + (max_x-x): l_x_offset.append(-(_x-x)/2) _x = x _y += dy dx = canvas.text_size(word.lstrip())[0] word = word.lstrip() # Draw! _x += dx l_x_offset.append(-(_x-x)/2) _y += dy l_x_offset.reverse() y_offset = -(_y-y)/2 # Now render it onto the canvas if center: _y = y+y_offset else: _y = y for paragraph in self.text: if center: _x = x+l_x_offset.pop() else: _x = x dy = canvas.text_size(u'dummy')[1] for word, style in paragraph: # Set the style canvas.set_font(style[u'style'], int(style[u'size']), \ bold=style[u'bold'], italic=style[u'italic'], underline= \ style[u'underline']) canvas.set_fgcolor(style[u'color']) # Line wrap if we run out of the screen dx, dy = canvas.text_size(word) if _x+dx > max_x: if center: _x = x+l_x_offset.pop() else: _x = x _y += dy dx = canvas.text_size(word.lstrip())[0] word = word.lstrip() # Draw! canvas._text(word, _x, _y) _x += dx _y += dy # Restore the canvas font and colors canvas.set_fgcolor(backup_style[u'color']) canvas.set_font(backup_style[u'style'], int(backup_style[u'size']), \ bold=backup_style[u'bold'], italic=backup_style[u'italic'])
def render(self, text, x, y, canvas, max_width=None, center=False, \ color=None, bidi=False, html=True): """ Renders an HTML formatted string onto a canvas. Arguments: text -- The text string. x -- The left-most coordinate. y -- The top coordinate. canvas -- An openexp canvas. Keyword arguments: max_width -- The maximum width, after which line wrapping should occur, or None to wrap at screen edge. (default=None) center -- Indicates whether the text should be center aligned. (default=False) color -- Indicates the color of the text or None for canvas default. (default=None) bidi -- Indicates whether bi-directional text support should be enabled. (default=False) html -- Indicates whether HTML should be parsed. (default=True) """ # Make sure that it's a string text = canvas.experiment.unistr(text) debug.msg(text) # Parse bi-directional strings if bidi and bidi_func != None: text = bidi_func(text) # Convert line breaks to HTML break tags text = text.replace(os.linesep, u'<br />').replace(u'\n', u'<br />') # Initialize the style self.canvas = canvas self.default_style = { u'style': canvas.font_style, u'bold': canvas.font_bold, u'italic': canvas.font_italic, u'color': canvas.fgcolor, u'size': canvas.font_size, u'underline': canvas.font_underline } backup_style = self.default_style.copy() # Optionally override color if color != None: self.default_style[u'color'] = color # Set the maximum width if max_width == None: max_x = canvas.experiment.width else: if center: max_x = x + max_width / 2 else: max_x = x + max_width # First parse the HTML self.text = [] self.paragraph = [] self.style_stack = [] self.current_tag = None self.push_style() # Optionally parse HTML if html: self.feed(text) else: self.handle_data(text) self.text.append(self.paragraph) # If we want to center the next, we need a dry run to calculate all the # line lengths and determine the vertical and horizontal offset for each # line if center: l_x_offset = [] _y = y for paragraph in self.text: _x = x dy = canvas.text_size(u'dummy')[1] for word, style in paragraph: # Set the style canvas.set_font(style[u'style'], int(style[u'size']), \ bold=style[u'bold'], italic=style[u'italic'], \ underline=style[u'underline']) # Line wrap if we run out of the screen dx, dy = canvas.text_size(word) if _x + dx > max_x + (max_x - x): l_x_offset.append(-(_x - x) / 2) _x = x _y += dy dx = canvas.text_size(word.lstrip())[0] word = word.lstrip() # Draw! _x += dx l_x_offset.append(-(_x - x) / 2) _y += dy l_x_offset.reverse() y_offset = -(_y - y) / 2 # Now render it onto the canvas if center: _y = y + y_offset else: _y = y for paragraph in self.text: if center: _x = x + l_x_offset.pop() else: _x = x dy = canvas.text_size(u'dummy')[1] for word, style in paragraph: # Set the style canvas.set_font(style[u'style'], int(style[u'size']), \ bold=style[u'bold'], italic=style[u'italic'], underline= \ style[u'underline']) canvas.set_fgcolor(style[u'color']) # Line wrap if we run out of the screen dx, dy = canvas.text_size(word) if _x + dx > max_x: if center: _x = x + l_x_offset.pop() else: _x = x _y += dy dx = canvas.text_size(word.lstrip())[0] word = word.lstrip() # Draw! canvas._text(word, _x, _y) _x += dx _y += dy # Restore the canvas font and colors canvas.set_fgcolor(backup_style[u'color']) canvas.set_font(backup_style[u'style'], int(backup_style[u'size']), \ bold=backup_style[u'bold'], italic=backup_style[u'italic'])