def get_ctm(x1, y1, x2, y2): """Get the scaled and translated CTM for an image to be placed in the bounding box defined by [x1, y1, x2, y2]. """ return matrix_multiply( translate(x1, y1), scale(x2 - x1, y2 - y1), )
def test_multiply_is_associative(self): R = rotate(45) S = scale(3, 2) T = translate(5, -1) # T*(S*R) M1 = matrix_multiply(T, matrix_multiply(S, R)) # (T*S)*R M2 = matrix_multiply(matrix_multiply(T, S), R) assert M1 == M2 assert M1 == matrix_multiply(T, S, R)
def _get_transform(bounding_box, rotation, _scale): """Get the transformation required to go from the user's desired coordinate space to PDF user space, taking into account rotation, scaling, translation (for things like weird media boxes). """ # Unrotated width and height, in pts W = bounding_box[2] - bounding_box[0] H = bounding_box[3] - bounding_box[1] scale_matrix = scale(*_scale) x_translate = 0 + min(bounding_box[0], bounding_box[2]) y_translate = 0 + min(bounding_box[1], bounding_box[3]) mb_translate = translate(x_translate, y_translate) # Because of how rotation works the point isn't rotated around an axis, # but the axis itself shifts. So we have to represent the rotation as # rotation + translation. rotation_matrix = rotate(rotation) translate_matrix = identity() if rotation == 90: translate_matrix = translate(W, 0) elif rotation == 180: translate_matrix = translate(W, H) elif rotation == 270: translate_matrix = translate(0, H) # Order matters here - the transformation matrices are applied in # reverse order. So first we scale to get the points in PDF user space, # since all other operations are in that space. Then we rotate and # scale to capture page rotation, then finally we translate to account # for offset media boxes. transform = matrix_multiply( mb_translate, translate_matrix, rotation_matrix, scale_matrix, ) return transform
def test_invert_scale(self): assert scale(2, 4) == matrix_inverse(scale(0.5, 0.25)) assert scale(0.1, 8) == matrix_inverse(scale(10, 0.125)) assert identity() == matrix_multiply(scale(2, 4), scale(0.5, 0.25)) assert identity() == matrix_multiply(scale(0.1, 8), scale(10, 0.125))
def test_scales_multiply(self): S1 = scale(2, 3) S2 = scale(5, 2) assert scale(10, 6) == matrix_multiply(S1, S2) assert scale(10, 6) == matrix_multiply(S2, S1)