Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# Save absolute values for x and y, useful if next letter is s or S
x1 += x
x2 += x
x3 += x
y1 += y
y2 += y
y3 += y
elif letter == 'C':
# Curve
x1, y1, string = point(surface, string)
x2, y2, string = point(surface, string)
x3, y3, string = point(surface, string)
node.vertices.append((
point_angle(x2, y2, x1, y1), point_angle(x2, y2, x3, y3)))
surface.context.curve_to(x1, y1, x2, y2, x3, y3)
current_point = x3, y3
elif letter == 'h':
# Relative horizontal line
x, string = (string + ' ').split(' ', 1)
old_x, old_y = current_point
angle = 0 if size(surface, x, 'x') > 0 else pi
node.vertices.append((pi - angle, angle))
x = size(surface, x, 'x')
surface.context.rel_line_to(x, 0)
current_point = current_point[0] + x, current_point[1]
elif letter == 'H':
# Horizontal line
x, string = (string + ' ').split(' ', 1)
current_point = current_point[0] + x, current_point[1]
elif letter == 'H':
# Horizontal line
x, string = (string + ' ').split(' ', 1)
old_x, old_y = current_point
angle = 0 if size(surface, x, 'x') > old_x else pi
node.vertices.append((pi - angle, angle))
x = size(surface, x, 'x')
surface.context.line_to(x, old_y)
current_point = x, current_point[1]
elif letter == 'l':
# Relative straight line
x, y, string = point(surface, string)
angle = point_angle(0, 0, x, y)
node.vertices.append((pi - angle, angle))
surface.context.rel_line_to(x, y)
current_point = current_point[0] + x, current_point[1] + y
elif letter == 'L':
# Straight line
x, y, string = point(surface, string)
old_x, old_y = current_point
angle = point_angle(old_x, old_y, x, y)
node.vertices.append((pi - angle, angle))
surface.context.line_to(x, y)
current_point = x, y
elif letter == 'm':
# Current point relative move
x, y, string = point(surface, string)
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 polyline(surface, node):
"""Draw a polyline ``node``."""
points = normalize(node.get('points', ''))
if points:
x, y, points = point(surface, points)
surface.context.move_to(x, y)
node.vertices = [(x, y)]
while points:
x_old, y_old = x, y
x, y, points = point(surface, points)
angle = point_angle(x_old, y_old, x, y)
node.vertices.append((pi - angle, angle))
surface.context.line_to(x, y)
node.vertices.append((x, y))
# Choose between the two circles according to flags
if not (large ^ sweep):
yc = -yc
# Define the arc sweep
arc = (
surface.context.arc if sweep else surface.context.arc_negative)
# Put the second point and the center back to their positions
xe, ye = rotate(xe, 0, angle)
xc, yc = rotate(xc, yc, angle)
# Find the drawing angles
angle1 = point_angle(xc, yc, 0, 0)
angle2 = point_angle(xc, yc, xe, ye)
# Store the tangent angles
node.vertices.append((-angle1, -angle2))
# Draw the arc
surface.context.save()
surface.context.translate(x1, y1)
surface.context.rotate(rotation)
surface.context.scale(1, radii_ratio)
arc(xc, yc, rx, angle1, angle2)
surface.context.restore()
current_point = current_point[0] + x3, current_point[1] + y3
elif letter == 'c':
# Relative curve
x, y = current_point
extents = text_extents[4]
if text_path:
start = surface.text_path_width + surface.cursor_d_position[0]
start_point = point_following_path(cairo_path, start)
middle = start + extents / 2
middle_point = point_following_path(cairo_path, middle)
end = start + extents
end_point = point_following_path(cairo_path, end)
surface.text_path_width += extents + letter_spacing
if not all((start_point, middle_point, end_point)):
continue
if not 0 <= middle <= length:
continue
surface.context.save()
surface.context.translate(*start_point)
surface.context.rotate(point_angle(*(start_point + end_point)))
surface.context.translate(0, surface.cursor_d_position[1])
surface.context.move_to(0, 0)
bounding_box = extend_bounding_box(
bounding_box, ((end_point[0], text_extents[3]),))
else:
surface.context.save()
x = surface.cursor_position[0] if x is None else x
y = surface.cursor_position[1] if y is None else y
surface.context.move_to(x + letter_spacing, y)
cursor_position = x + letter_spacing + extents, y
surface.context.rel_move_to(*surface.cursor_d_position)
surface.context.rel_move_to(-x_align, y_align)
surface.context.rotate(last_r if r is None else r)
points = (
(cursor_position[0] - x_align +
surface.cursor_d_position[0],
x3, y3, string = point(surface, string)
xq1, yq1, xq2, yq2, xq3, yq3 = quadratic_points(
x1, y1, x2, y2, x3, y3)
surface.context.curve_to(xq1, yq1, xq2, yq2, xq3, yq3)
node.vertices.append((0, 0))
current_point = x3, y3
elif letter == 's':
# Relative smooth curve
x, y = current_point
x1 = x3 - x2 if last_letter in 'csCS' else 0
y1 = y3 - y2 if last_letter in 'csCS' else 0
x2, y2, string = point(surface, string)
x3, y3, string = point(surface, string)
node.vertices.append((
point_angle(x2, y2, x1, y1), point_angle(x2, y2, x3, y3)))
surface.context.rel_curve_to(x1, y1, x2, y2, x3, y3)
current_point = current_point[0] + x3, current_point[1] + y3
# Save absolute values for x and y, useful if next letter is s or S
x1 += x
x2 += x
x3 += x
y1 += y
y2 += y
y3 += y
elif letter == 'S':
# Smooth curve
x, y = current_point
x1 = x3 + (x3 - x2) if last_letter in 'csCS' else x
y1 = y3 + (y3 - y2) if last_letter in 'csCS' else y
surface.context.line_to(x, old_y)
current_point = x, current_point[1]
elif letter == 'l':
# Relative straight line
x, y, string = point(surface, string)
angle = point_angle(0, 0, x, y)
node.vertices.append((pi - angle, angle))
surface.context.rel_line_to(x, y)
current_point = current_point[0] + x, current_point[1] + y
elif letter == 'L':
# Straight line
x, y, string = point(surface, string)
old_x, old_y = current_point
angle = point_angle(old_x, old_y, x, y)
node.vertices.append((pi - angle, angle))
surface.context.line_to(x, y)
current_point = x, y
elif letter == 'm':
# Current point relative move
x, y, string = point(surface, string)
surface.context.rel_move_to(x, y)
current_point = current_point[0] + x, current_point[1] + y
elif letter == 'M':
# Current point move
x, y, string = point(surface, string)
surface.context.move_to(x, y)
current_point = x, y
x3 -= x1
y3 -= y1
# rx=0 or ry=0 means straight line
if not rx or not ry:
string = 'l {} {} {}'.format(x3, y3, string)
continue
radii_ratio = ry / rx
# Cancel the rotation of the second point
xe, ye = rotate(x3, y3, -rotation)
ye /= radii_ratio
# Find the angle between the second point and the x axis
angle = point_angle(0, 0, xe, ye)
# Put the second point onto the x axis
xe = (xe ** 2 + ye ** 2) ** .5
ye = 0
# Update the x radius if it is too small
rx = max(rx, xe / 2)
# Find one circle centre
xc = xe / 2
yc = (rx ** 2 - xc ** 2) ** .5
# Choose between the two circles according to flags
if not (large ^ sweep):
yc = -yc