it seems I cannot rotate Drawing at the centre.
I have a svg Drawing: drawing.getBounds()=(14.173228346456694, 14.173228346456654, 581.1023622047245, 581.1023622047245), drawing.width=595.2755905511812, drawing.height=595.2755905511812, drawing.transform=(1, 0, 0, 1, 0, 0), drawing.hAlign='LEFT', drawing.vAlign='BOTTOM'
I rotate and put several drawing in row*col array:
r = i // col
c_idx = i % col
x = c_idx * cell_w + padding
y = page_height - ((r + 1) * cell_h) + padding
drawing = svg2rlg(svg_path)
if drawing is None:
raise ValueError("Could not convert SVG to drawing object.")
# Scale to fit within cell
print(f"{drawing.getBounds()=}, {drawing.width=}, {drawing.height=}, {drawing.transform=}, {drawing.hAlign=}, {drawing.vAlign=}")
if rotate_x_y[0] > 0:
drawing.rotate(rotate_x_y[0], rotate_x_y[1]*drawing.width, rotate_x_y[2]*drawing.height)
max_w = cell_w - 2 * padding
max_h = cell_h - 2 * padding
scale_x = max_w / drawing.width
scale_y = max_h / drawing.height
scale = min(scale_x, scale_y)
drawing.width *= scale
drawing.height *= scale
drawing.scale(scale, scale)
# Center in cell
dx = x + (max_w - drawing.width) / 2
dy = y + (max_h - drawing.height) / 2
renderPDF.draw(drawing, c, dx, dy)
but I cannot get the drawing.rotate() to work
I tried call drawing.rotate(90), it seems the same as drawing.rotate(90, 0, 0)
the rotation centre also not at w/2, h/2
I always end up very strange results not matter what I tried.
the original pdf looks like:
rotated results:
this is a fundamental bug of the transform module in the project probably since the very beginning I verified it at least start from 2010. I think this project probably not worth using, it will waste you lots of time. https://hg.reportlab.com/hg-public/reportlab/file/a57692215f7c/src/reportlab/graphics/shapes.py
they use column major mmul (mmul(A, B) means v_new=A*B*v, so apply transform B then apply transform A), but throughout the entire project, they treat it as row major mmul, did self.transform=mmul(self.transform, new_transform).
# T = (1,0, 0,1, -100, -100) (Translate by -100, -100)
# R = (0,-1,1,0, 0, 0) (Rotate 90 degrees CCW)
# Test 1: mmult(T, R) (Apply R, then T)
print(transform.mmult((1,0, 0,1, -100, -100), (0,-1,1,0, 0, 0)))
# Result: (0, -1, 1, 0, -100, -100)
# The translation (-100, -100) was NOT rotated. This means R was applied first.
# Test 2: mmult(R, T) (Apply T, then R)
print(transform.mmult((0,-1,1,0, 0, 0), (1,0, 0,1, -100, -100)))
# Result: (0, -1, 1, 0, -100, 100)
# The translation (-100, -100) was rotated to (-100, 100). This means T was applied first.
print(f"Origin: {drawing.transform=}")
drawing.translate(
-drawing.width/2, -drawing.height/2
)
print(f"translate: {drawing.transform=}")
drawing.rotate(
90
)
print(f"Rotate: {drawing.transform=}")
output show it is rotate then translate:
drawing.getBounds()=(6.803149606299213, 6.803149606299229, 246.6141732283465, 246.61417322834652), drawing.width=253.41732283464572, drawing.height=253.41732283464572, drawing.transform=(1, 0, 0, 1, 0, 0), drawing.hAlign='LEFT', drawing.vAlign='BOTTOM'
Origin: drawing.transform=(1, 0, 0, 1, 0, 0)
translate: drawing.transform=(1, 0, 0, 1, -126.70866141732286, -126.70866141732286)
Rotate: drawing.transform=(6.123233995736766e-17, 1.0, -1.0, 6.123233995736766e-17, -126.70866141732286, -126.70866141732286)
print(f"Origin: {drawing.transform=}")
drawing.rotate(
90
)
print(f"Rotate: {drawing.transform=}")
drawing.translate(
-drawing.width/2, -drawing.height/2
)
print(f"translate: {drawing.transform=}")
output show it is translate then rotate
drawing.getBounds()=(6.803149606299213, 6.803149606299229, 246.6141732283465, 246.61417322834652), drawing.width=253.41732283464572, drawing.height=253.41732283464572, drawing.transform=(1, 0, 0, 1, 0, 0), drawing.hAlign='LEFT', drawing.vAlign='BOTTOM'
Origin: drawing.transform=(1, 0, 0, 1, 0, 0)
Rotate: drawing.transform=(6.123233995736766e-17, 1.0, -1.0, 6.123233995736766e-17, 0, 0)
translate: drawing.transform=(6.123233995736766e-17, 1.0, -1.0, 6.123233995736766e-17, 126.70866141732284, -126.70866141732287)