19
19
20
20
"""
21
21
22
- from math import cos , sin , tan , atan2 , radians
23
22
import re
23
+ from math import atan2 , cos , radians , sin , tan
24
24
25
25
from .surface import cairo
26
26
from .url import parse_url
27
27
28
-
29
28
UNITS = {
30
29
'mm' : 1 / 25.4 ,
31
30
'cm' : 1 / 2.54 ,
@@ -125,78 +124,77 @@ def preserve_ratio(surface, node):
125
124
width = size (surface , node .get ('markerWidth' , '3' ), 'x' )
126
125
height = size (surface , node .get ('markerHeight' , '3' ), 'y' )
127
126
_ , _ , viewbox = node_format (surface , node )
128
- viewbox_width = viewbox [2 ]
129
- viewbox_height = viewbox [3 ]
127
+ viewbox_width , viewbox_height = viewbox [2 :]
130
128
elif node .tag in ('svg' , 'image' ):
131
129
width , height , _ = node_format (surface , node )
132
130
viewbox_width , viewbox_height = node .image_width , node .image_height
133
131
else :
134
132
# Safety measure
135
- return 1 , 1 , 0 , 0 , None
133
+ return 1 , 1 , 0 , 0
136
134
137
135
translate_x = 0
138
136
translate_y = 0
139
137
scale_x = width / viewbox_width if viewbox_width > 0 else 1
140
138
scale_y = height / viewbox_height if viewbox_height > 0 else 1
141
- clip_box = None
142
- align = node .get ('preserveAspectRatio' , 'xMidYMid' ).split (' ' )[0 ]
139
+
140
+ aspect_ratio = node .get ('preserveAspectRatio' , 'xMidYMid' ).split ()
141
+ align = aspect_ratio [0 ]
143
142
if align == 'none' :
144
143
x_position = 'min'
145
144
y_position = 'min'
146
145
else :
147
- mos_properties = node .get ('preserveAspectRatio' , '' ).split ()
148
- meet_or_slice = mos_properties [1 ] if len (mos_properties ) > 1 else None
146
+ meet_or_slice = aspect_ratio [1 ] if len (aspect_ratio ) > 1 else None
149
147
if meet_or_slice == 'slice' :
150
148
scale_value = max (scale_x , scale_y )
151
149
else :
152
150
scale_value = min (scale_x , scale_y )
153
151
scale_x = scale_y = scale_value
154
-
155
152
x_position = align [1 :4 ].lower ()
156
153
y_position = align [5 :].lower ()
157
154
158
155
if node .tag == 'marker' :
159
156
translate_x = - size (surface , node .get ('refX' , '0' ), 'x' )
160
157
translate_y = - size (surface , node .get ('refY' , '0' ), 'y' )
161
- if x_position == 'min' :
162
- clip_x = viewbox [0 ]
163
-
164
- if y_position == 'min' :
165
- clip_y = viewbox [1 ]
166
-
158
+ else :
159
+ translate_x = 0
167
160
if x_position == 'mid' :
168
- clip_x = viewbox [0 ] + (viewbox_width - width / scale_x ) / 2.
161
+ translate_x = (width / scale_x - viewbox_width ) / 2
162
+ elif x_position == 'max' :
163
+ translate_x = width / scale_x - viewbox_width
169
164
165
+ translate_y = 0
170
166
if y_position == 'mid' :
171
- clip_y = viewbox [1 ] + (viewbox_height - height / scale_y ) / 2.
167
+ translate_y += (height / scale_y - viewbox_height ) / 2
168
+ elif y_position == 'max' :
169
+ translate_y += height / scale_y - viewbox_height
172
170
173
- if x_position == 'max' :
174
- clip_x = viewbox [0 ] + (viewbox_width - width / scale_x )
171
+ return scale_x , scale_y , translate_x , translate_y
175
172
176
- if y_position == 'max' :
177
- clip_y = viewbox [1 ] + (viewbox_height - height / scale_y )
178
173
179
- clip_box = (clip_x , clip_y , width / scale_x , height / scale_y )
180
- else :
181
- if x_position == 'min' :
182
- translate_x = 0
183
-
184
- if y_position == 'min' :
185
- translate_y = 0
186
-
187
- if x_position == 'mid' :
188
- translate_x = (width / scale_x - viewbox_width ) / 2.
174
+ def clip_marker_box (surface , node , scale_x , scale_y ):
175
+ """Get the clip ``(x, y, width, height)`` of the marker box."""
176
+ width = size (surface , node .get ('markerWidth' , '3' ), 'x' )
177
+ height = size (surface , node .get ('markerHeight' , '3' ), 'y' )
178
+ _ , _ , viewbox = node_format (surface , node )
179
+ viewbox_width , viewbox_height = viewbox [2 :]
189
180
190
- if y_position == 'mid' :
191
- translate_y = (height / scale_y - viewbox_height ) / 2.
181
+ align = node .get ('preserveAspectRatio' , 'xMidYMid' ).split (' ' )[0 ]
182
+ x_position = 'min' if align == 'none' else align [1 :4 ].lower ()
183
+ y_position = 'min' if align == 'none' else align [5 :].lower ()
192
184
193
- if x_position == 'max' :
194
- translate_x = width / scale_x - viewbox_width
185
+ clip_x = viewbox [0 ]
186
+ if x_position == 'mid' :
187
+ clip_x += (viewbox_width - width / scale_x ) / 2.
188
+ elif x_position == 'max' :
189
+ clip_x += viewbox_width - width / scale_x
195
190
196
- if y_position == 'max' :
197
- translate_y = height / scale_y - viewbox_height
191
+ clip_y = viewbox [1 ]
192
+ if y_position == 'mid' :
193
+ clip_y += (viewbox_height - height / scale_y ) / 2.
194
+ elif y_position == 'max' :
195
+ clip_y += viewbox_height - height / scale_y
198
196
199
- return scale_x , scale_y , translate_x , translate_y , clip_box
197
+ return clip_x , clip_y , width / scale_x , height / scale_y
200
198
201
199
202
200
def quadratic_points (x1 , y1 , x2 , y2 , x3 , y3 ):
@@ -213,9 +211,8 @@ def rotate(x, y, angle):
213
211
return x * cos (angle ) - y * sin (angle ), y * cos (angle ) + x * sin (angle )
214
212
215
213
216
- def transform (surface , string , gradient = None ):
217
- """Update ``surface`` or ``gradient`` (if supplied)
218
- according to transformation ``string``.
214
+ def transform (surface , string , gradient = None ):
215
+ """Transform ``surface`` or ``gradient`` if supplied using ``string``.
219
216
220
217
See http://www.w3.org/TR/SVG/coords.html#TransformAttribute
221
218
@@ -252,7 +249,7 @@ def transform(surface, string, gradient = None):
252
249
apply_matrix_transform (surface , matrix , gradient )
253
250
254
251
255
- def apply_matrix_transform (surface , matrix , gradient = None ):
252
+ def apply_matrix_transform (surface , matrix , gradient = None ):
256
253
"""Apply a ``matrix`` to ``surface`` or ``gradient`` if supplied.
257
254
258
255
When the matrix is not invertible, this function clips the context to an
0 commit comments