mirror of
https://github.com/Kozea/WeasyPrint.git
synced 2024-10-05 08:27:22 +03:00
Clean some code in draw module
This commit is contained in:
parent
08fe4bae3a
commit
57f216cb91
@ -10,8 +10,8 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import math
|
|
||||||
import operator
|
import operator
|
||||||
|
from math import ceil, floor, hypot, pi, sqrt, tan
|
||||||
|
|
||||||
import cairocffi as cairo
|
import cairocffi as cairo
|
||||||
|
|
||||||
@ -322,7 +322,7 @@ def rounded_box_path(context, radii):
|
|||||||
context.scale(min(rx / ry, 1), min(ry / rx, 1))
|
context.scale(min(rx / ry, 1), min(ry / rx, 1))
|
||||||
context.arc(
|
context.arc(
|
||||||
(-1 if w else 1) * radius, (-1 if h else 1) * radius, radius,
|
(-1 if w else 1) * radius, (-1 if h else 1) * radius, radius,
|
||||||
(2 + i) * math.pi / 2, (3 + i) * math.pi / 2)
|
(2 + i) * pi / 2, (3 + i) * pi / 2)
|
||||||
context.restore()
|
context.restore()
|
||||||
|
|
||||||
|
|
||||||
@ -446,7 +446,7 @@ def draw_background_image(context, layer, image_rendering):
|
|||||||
repeat_width = image_width
|
repeat_width = image_width
|
||||||
else:
|
else:
|
||||||
assert repeat_x == 'space'
|
assert repeat_x == 'space'
|
||||||
n_repeats = math.floor(positioning_width / image_width)
|
n_repeats = floor(positioning_width / image_width)
|
||||||
if n_repeats >= 2:
|
if n_repeats >= 2:
|
||||||
# The repeat width is the whole positioning width with one image
|
# The repeat width is the whole positioning width with one image
|
||||||
# removed, divided by (the number of repeated images - 1). This
|
# removed, divided by (the number of repeated images - 1). This
|
||||||
@ -465,7 +465,7 @@ def draw_background_image(context, layer, image_rendering):
|
|||||||
repeat_height = image_height
|
repeat_height = image_height
|
||||||
else:
|
else:
|
||||||
assert repeat_y == 'space'
|
assert repeat_y == 'space'
|
||||||
n_repeats = math.floor(positioning_height / image_height)
|
n_repeats = floor(positioning_height / image_height)
|
||||||
if n_repeats >= 2:
|
if n_repeats >= 2:
|
||||||
repeat_height = (
|
repeat_height = (
|
||||||
positioning_height - image_height) / (n_repeats - 1)
|
positioning_height - image_height) / (n_repeats - 1)
|
||||||
@ -599,8 +599,8 @@ def clip_border_segment(context, enable_hinting, style, width, side,
|
|||||||
if enable_hinting and style != 'dotted' and (
|
if enable_hinting and style != 'dotted' and (
|
||||||
# Borders smaller than 1 device unit would disappear
|
# Borders smaller than 1 device unit would disappear
|
||||||
# without anti-aliasing.
|
# without anti-aliasing.
|
||||||
math.hypot(*context.user_to_device(width, 0)) >= 1 and
|
hypot(*context.user_to_device(width, 0)) >= 1 and
|
||||||
math.hypot(*context.user_to_device(0, width)) >= 1):
|
hypot(*context.user_to_device(0, width)) >= 1):
|
||||||
# Avoid an artifact in the corner joining two solid borders
|
# Avoid an artifact in the corner joining two solid borders
|
||||||
# of the same color.
|
# of the same color.
|
||||||
context.set_antialias(cairo.ANTIALIAS_NONE)
|
context.set_antialias(cairo.ANTIALIAS_NONE)
|
||||||
@ -637,8 +637,8 @@ def clip_border_segment(context, enable_hinting, style, width, side,
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
x = (a - b) / (a + b)
|
x = (a - b) / (a + b)
|
||||||
return math.pi / 8 * (a + b) * (
|
return pi / 8 * (a + b) * (
|
||||||
1 + 3 * x ** 2 / (10 + math.sqrt(4 - 3 * x ** 2)))
|
1 + 3 * x ** 2 / (10 + sqrt(4 - 3 * x ** 2)))
|
||||||
|
|
||||||
if side == 'top':
|
if side == 'top':
|
||||||
(px1, py1), rounded1 = transition_point(tlh, tlv, bl, bt)
|
(px1, py1), rounded1 = transition_point(tlh, tlv, bl, bt)
|
||||||
@ -703,9 +703,9 @@ def clip_border_segment(context, enable_hinting, style, width, side,
|
|||||||
else:
|
else:
|
||||||
# 2x - 1/2 dashes
|
# 2x - 1/2 dashes
|
||||||
dash = length / (dash_length + dash_length % 2 - 0.5)
|
dash = length / (dash_length + dash_length % 2 - 0.5)
|
||||||
dashes1 = int(math.ceil((chl1 - dash / 2) / dash))
|
dashes1 = int(ceil((chl1 - dash / 2) / dash))
|
||||||
dashes2 = int(math.ceil((chl2 - dash / 2) / dash))
|
dashes2 = int(ceil((chl2 - dash / 2) / dash))
|
||||||
line = int(math.floor(line_length / dash))
|
line = int(floor(line_length / dash))
|
||||||
|
|
||||||
def draw_dots(dashes, line, way, x, y, px, py, chl):
|
def draw_dots(dashes, line, way, x, y, px, py, chl):
|
||||||
if not dashes:
|
if not dashes:
|
||||||
@ -714,36 +714,36 @@ def clip_border_segment(context, enable_hinting, style, width, side,
|
|||||||
i += 0.5 # half dash
|
i += 0.5 # half dash
|
||||||
angle1 = (
|
angle1 = (
|
||||||
((2 * angle - way) + i * way * dash / chl) /
|
((2 * angle - way) + i * way * dash / chl) /
|
||||||
4 * math.pi)
|
4 * pi)
|
||||||
angle2 = (min if way > 0 else max)(
|
angle2 = (min if way > 0 else max)(
|
||||||
((2 * angle - way) + (i + 1) * way * dash / chl) /
|
((2 * angle - way) + (i + 1) * way * dash / chl) /
|
||||||
4 * math.pi,
|
4 * pi,
|
||||||
angle * math.pi / 2)
|
angle * pi / 2)
|
||||||
if side in ('top', 'bottom'):
|
if side in ('top', 'bottom'):
|
||||||
context.move_to(x + px, main_offset + py)
|
context.move_to(x + px, main_offset + py)
|
||||||
context.line_to(
|
context.line_to(
|
||||||
x + px - way * px * 1 / math.tan(angle2),
|
x + px - way * px * 1 / tan(angle2),
|
||||||
main_offset)
|
main_offset)
|
||||||
context.line_to(
|
context.line_to(
|
||||||
x + px - way * px * 1 / math.tan(angle1),
|
x + px - way * px * 1 / tan(angle1),
|
||||||
main_offset)
|
main_offset)
|
||||||
elif side in ('left', 'right'):
|
elif side in ('left', 'right'):
|
||||||
context.move_to(main_offset + px, y + py)
|
context.move_to(main_offset + px, y + py)
|
||||||
context.line_to(
|
context.line_to(
|
||||||
main_offset,
|
main_offset,
|
||||||
y + py + way * py * math.tan(angle2))
|
y + py + way * py * tan(angle2))
|
||||||
context.line_to(
|
context.line_to(
|
||||||
main_offset,
|
main_offset,
|
||||||
y + py + way * py * math.tan(angle1))
|
y + py + way * py * tan(angle1))
|
||||||
if angle2 == angle * math.pi / 2:
|
if angle2 == angle * pi / 2:
|
||||||
offset = (angle1 - angle2) / ((
|
offset = (angle1 - angle2) / ((
|
||||||
((2 * angle - way) + (i + 1) * way * dash / chl) /
|
((2 * angle - way) + (i + 1) * way * dash / chl) /
|
||||||
4 * math.pi) - angle1)
|
4 * pi) - angle1)
|
||||||
line += 1
|
line += 1
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
offset = 1 - (
|
offset = 1 - (
|
||||||
(angle * math.pi / 2 - angle2) / (angle2 - angle1))
|
(angle * pi / 2 - angle2) / (angle2 - angle1))
|
||||||
return line, offset
|
return line, offset
|
||||||
|
|
||||||
line, offset = draw_dots(
|
line, offset = draw_dots(
|
||||||
@ -1075,67 +1075,28 @@ def draw_text(context, textbox, enable_hinting, offset_x=0):
|
|||||||
textbox.pango_layout.deactivate()
|
textbox.pango_layout.deactivate()
|
||||||
|
|
||||||
|
|
||||||
def acos(x):
|
|
||||||
if x < 1:
|
|
||||||
return math.pi
|
|
||||||
elif x > 1:
|
|
||||||
return 0
|
|
||||||
else:
|
|
||||||
return math.acos(x)
|
|
||||||
|
|
||||||
|
|
||||||
def draw_wave(context, x, y, width, offset_x, radius):
|
def draw_wave(context, x, y, width, offset_x, radius):
|
||||||
|
context.new_path()
|
||||||
d = 2 * radius
|
diameter = 2 * radius
|
||||||
|
wave_index = offset_x // diameter
|
||||||
context.move_to(x, y)
|
remain = offset_x - wave_index * diameter
|
||||||
|
|
||||||
# Index of the current wave:
|
|
||||||
i = math.floor(offset_x // d)
|
|
||||||
|
|
||||||
while width > 0:
|
while width > 0:
|
||||||
|
up = (wave_index % 2 == 0)
|
||||||
|
center_x = x - remain + radius
|
||||||
|
alpha1 = (1 + remain / diameter) * pi
|
||||||
|
alpha2 = (1 + min(1, width / diameter)) * pi
|
||||||
|
|
||||||
remain = offset_x - i * d
|
if up:
|
||||||
|
context.arc(center_x, y, radius, alpha1, alpha2)
|
||||||
# Is the wave going up or down?
|
|
||||||
up = (i % 2 == 0)
|
|
||||||
|
|
||||||
# Start/stop of the wave on the x axis:
|
|
||||||
start = x - remain
|
|
||||||
stop = start + d
|
|
||||||
|
|
||||||
# Coordinates of the center:
|
|
||||||
xc = start + radius
|
|
||||||
|
|
||||||
# print((x, radius, offset_x, start, i, xc))
|
|
||||||
|
|
||||||
alpha1 = acos((x - xc) / radius)
|
|
||||||
|
|
||||||
if x + width > stop:
|
|
||||||
# Complete pattern:
|
|
||||||
if up:
|
|
||||||
context.arc(xc, y, radius, alpha1, 0)
|
|
||||||
else:
|
|
||||||
context.arc_negative(xc, y, radius,
|
|
||||||
2 * math.pi - alpha1,
|
|
||||||
2 * math.pi)
|
|
||||||
forward = stop - x
|
|
||||||
x = stop
|
|
||||||
offset_x = offset_x + forward
|
|
||||||
width = width - forward
|
|
||||||
i = i + 1
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Incomplete pattern:
|
context.arc_negative(
|
||||||
xf = x + width
|
center_x, y, radius, -alpha1, -alpha2)
|
||||||
alpha2 = acos((xf - xc) / radius)
|
|
||||||
if up:
|
x += diameter - remain
|
||||||
context.arc(xc, y, radius, alpha1, alpha2)
|
width -= diameter - remain
|
||||||
else:
|
remain = 0
|
||||||
context.arc_negative(xc, y, radius,
|
wave_index += 1
|
||||||
2 * math.pi - alpha1,
|
|
||||||
2 * math.pi - alpha2)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
def draw_text_decoration(context, textbox, offset_x, offset_y, thickness,
|
def draw_text_decoration(context, textbox, offset_x, offset_y, thickness,
|
||||||
@ -1153,14 +1114,13 @@ def draw_text_decoration(context, textbox, offset_x, offset_y, thickness,
|
|||||||
elif style == 'dotted':
|
elif style == 'dotted':
|
||||||
context.set_dash([thickness], offset=offset_x)
|
context.set_dash([thickness], offset=offset_x)
|
||||||
|
|
||||||
if style == "wavy":
|
if style == 'wavy':
|
||||||
draw_wave(context,
|
draw_wave(
|
||||||
textbox.position_x, textbox.position_y + offset_y,
|
context,
|
||||||
textbox.width,
|
textbox.position_x, textbox.position_y + offset_y,
|
||||||
offset_x, 0.75 * thickness)
|
textbox.width, offset_x, 0.75 * thickness)
|
||||||
else:
|
else:
|
||||||
context.move_to(textbox.position_x,
|
context.move_to(textbox.position_x, textbox.position_y + offset_y)
|
||||||
textbox.position_y + offset_y)
|
|
||||||
context.rel_line_to(textbox.width, 0)
|
context.rel_line_to(textbox.width, 0)
|
||||||
|
|
||||||
if style == 'double':
|
if style == 'double':
|
||||||
|
Loading…
Reference in New Issue
Block a user