Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def text(surface, node, draw_as_text=False):
"""Draw a text ``node``."""
font_family = (
(node.get('font-family') or 'sans-serif').split(',')[0].strip('"\' '))
font_style = getattr(
cairo, ('font_slant_{}'.format(node.get('font-style')).upper()),
cairo.FONT_SLANT_NORMAL)
font_weight = getattr(
cairo, ('font_weight_{}'.format(node.get('font-weight')).upper()),
cairo.FONT_WEIGHT_NORMAL)
surface.context.select_font_face(font_family, font_style, font_weight)
surface.context.set_font_size(surface.font_size)
ascent, descent, _, max_x_advance, max_y_advance = (
surface.context.font_extents())
text_path_href = parse_url(node.get_href() or node.parent.get_href() or '')
if text_path_href.fragment:
text_path = surface.paths.get(text_path_href.fragment)
else:
text_path = None
letter_spacing = size(surface, node.get('letter-spacing'))
x_bearing, y_bearing, width, height = (
surface.context.text_extents(node.text)[:4])
def point_following_path(path, width):
"""Get the point at ``width`` distance on ``path``."""
total_length = 0
for item in path:
if item[0] == cairo.PATH_MOVE_TO:
old_point = item[1]
elif item[0] == cairo.PATH_LINE_TO:
new_point = item[1]
length = distance(
old_point[0], old_point[1], new_point[0], new_point[1])
total_length += length
if total_length < width:
old_point = new_point
else:
length -= total_length - width
angle = point_angle(
old_point[0], old_point[1], new_point[0], new_point[1])
x = cos(angle) * length + old_point[0]
y = sin(angle) * length + old_point[1]
return x, y
def point_following_path(path, width):
"""Get the point at ``width`` distance on ``path``."""
total_length = 0
for item in path:
if item[0] == cairo.PATH_MOVE_TO:
old_point = item[1]
elif item[0] == cairo.PATH_LINE_TO:
new_point = item[1]
length = distance(
old_point[0], old_point[1], new_point[0], new_point[1])
total_length += length
if total_length < width:
old_point = new_point
else:
length -= total_length - width
angle = point_angle(
old_point[0], old_point[1], new_point[0], new_point[1])
x = cos(angle) * length + old_point[0]
y = sin(angle) * length + old_point[1]
return x, y
surface.context.scale(scale_x * tree_scale_x, scale_y * tree_scale_y)
surface.context.translate(translate_x, translate_y)
surface.draw(tree)
surface.context.restore()
return
else:
png_file = BytesIO()
image = Image.open(BytesIO(image_bytes))
if surface.map_image:
image = surface.map_image(image)
image.save(png_file, 'PNG')
png_file.seek(0)
image_surface = cairo.ImageSurface.create_from_png(png_file)
image_surface.pattern = cairo.SurfacePattern(image_surface)
image_surface.pattern.set_filter(IMAGE_RENDERING.get(
node.get('image-rendering'), cairo.FILTER_GOOD))
node.image_width = image_surface.get_width()
node.image_height = image_surface.get_height()
scale_x, scale_y, translate_x, translate_y = preserve_ratio(
surface, node)
# Clip image region (if necessary)
if not (translate_x == 0 and
translate_y == 0 and
width == scale_x * node.image_width and
height == scale_y * node.image_height):
surface.context.rectangle(x, y, width, height)
surface.context.clip()
def path_length(path):
"""Get the length of ``path``."""
total_length = 0
for item in path:
if item[0] == cairo.PATH_MOVE_TO:
old_point = item[1]
elif item[0] == cairo.PATH_LINE_TO:
new_point = item[1]
length = distance(
old_point[0], old_point[1], new_point[0], new_point[1])
total_length += length
old_point = new_point
return total_length
"""
from .bounding_box import calculate_bounding_box, is_non_empty_bounding_box
from .features import match_features
from .helpers import paint, size, transform
from .parser import Tree
from .shapes import rect
from .surface import cairo
from .url import parse_url
BLEND_OPERATORS = {
'darken': cairo.OPERATOR_DARKEN,
'lighten': cairo.OPERATOR_LIGHTEN,
'multiply': cairo.OPERATOR_MULTIPLY,
'normal': cairo.OPERATOR_OVER,
'screen': cairo.OPERATOR_SCREEN,
}
EXTEND_OPERATORS = {
'none': cairo.EXTEND_NONE,
'pad': cairo.EXTEND_PAD,
'reflect': cairo.EXTEND_REFLECT,
'repeat': cairo.EXTEND_REPEAT,
}
def update_def_href(surface, def_name, def_dict):
"""Update the attributes of the def according to its href attribute."""
def_node = def_dict[def_name]
href = parse_url(def_node.get_href()).fragment
if href in def_dict:
update_def_href(surface, href, def_dict)
Images manager.
"""
import os.path
from io import BytesIO
from PIL import Image, ImageOps
from .helpers import node_format, preserve_ratio, size
from .parser import Tree
from .surface import cairo
from .url import parse_url
IMAGE_RENDERING = {
'optimizeQuality': cairo.FILTER_BEST,
'optimizeSpeed': cairo.FILTER_FAST,
}
def image(surface, node):
"""Draw an image ``node``."""
base_url = node.get('{http://www.w3.org/XML/1998/namespace}base')
if not base_url and node.url:
base_url = os.path.dirname(node.url) + '/'
url = parse_url(node.get_href(), base_url)
image_bytes = node.fetch_url(url, 'image/*')
if len(image_bytes) < 5:
return
x, y = size(surface, node.get('x'), 'x'), size(surface, node.get('y'), 'y')
surface.context.translate(x, y)
surface.set_context_size(
*node_format(surface, tree, reference=False), scale=1,
preserved_ratio=preserved_ratio(tree))
surface.context.translate(*surface.context.get_current_point())
surface.context.scale(scale_x, scale_y)
surface.context.translate(translate_x, translate_y)
surface.draw(tree)
surface.context.restore()
return
else:
png_file = BytesIO()
Image.open(BytesIO(image_bytes)).save(png_file, 'PNG')
png_file.seek(0)
image_surface = cairo.ImageSurface.create_from_png(png_file)
### DSB
## Added:
image_surface.pattern = cairo.SurfacePattern(image_surface)
image_surface.pattern.set_filter(cairo.FILTER_NEAREST)
### DSB
node.image_width = image_surface.get_width()
node.image_height = image_surface.get_height()
scale_x, scale_y, translate_x, translate_y = preserve_ratio(
surface, node)
# Clip image region (if necessary)
if not (translate_x == 0 and
translate_y == 0 and
width == scale_x * node.image_width and