How to Work with Primitives in Python
Aspose.PDF FOSS for Python’s engine.primitives module provides Matrix, a lightweight 2D affine transform value type: six float components (a, b, c, d, e, f) that you can read, translate, and multiply together to compose transforms in your own code. It is a pure-Python dataclass with no external dependencies, installed from PyPI with pip.
Step-by-Step Guide
Step 1: Install the Package
Install the Aspose.PDF FOSS package from PyPI:
pip install aspose-pdf-foss-for-pythonVerify the installation:
import aspose_pdf
print("aspose_pdf OK")Step 2: Import the Matrix Class
Matrix lives in the engine.primitives submodule rather than the top-level aspose_pdf package:
from aspose_pdf.engine.primitives import MatrixStep 3: Create a Matrix and Inspect Its Components
Matrix() with no arguments gives you the identity matrix (a=1.0, b=0.0, c=0.0, d=1.0, e=0.0, f=0.0). Pass keyword arguments to override only the components you need:
from aspose_pdf.engine.primitives import Matrix
identity = Matrix()
print(identity.a, identity.b, identity.c, identity.d, identity.e, identity.f)
# 1.0 0.0 0.0 1.0 0.0 0.0
scale = Matrix(a=2.0, d=2.0)
print(scale.a, scale.d)
# 2.0 2.0Step 4: Translate a Matrix
translate(x, y) adds x to the e component and y to the f component in place — it mutates the matrix and returns None, unlike multiply, which returns a new instance:
from aspose_pdf.engine.primitives import Matrix
matrix = Matrix()
matrix.translate(10.0, 5.0)
print(matrix.e, matrix.f)
# 10.0 5.0
matrix.translate(10.0, 5.0)
print(matrix.e, matrix.f)
# 20.0 10.0Step 5: Multiply Two Matrices to Compose Transforms
multiply(other) combines two matrices and returns a brand-new Matrix, leaving both operands unchanged. The e/f translation components simply add together regardless of order, but the a–d linear part is combined via true matrix multiplication — once one of the matrices has an off-diagonal (b or c) component, a.multiply(b) and b.multiply(a) produce different a–d values:
from aspose_pdf.engine.primitives import Matrix
scale = Matrix(a=2.0, d=3.0)
shear = Matrix(b=1.0, c=1.0)
scale_then_shear = scale.multiply(shear)
print(scale_then_shear.a, scale_then_shear.b, scale_then_shear.c, scale_then_shear.d)
# 2.0 2.0 3.0 3.0
shear_then_scale = shear.multiply(scale)
print(shear_then_scale.a, shear_then_scale.b, shear_then_scale.c, shear_then_scale.d)
# 2.0 3.0 2.0 3.0Step 6: Build a Custom Transform from Components
Because Matrix is a plain dataclass, you can set any of its six fields directly instead of going through translate/multiply — useful when you already know the exact affine transform (for example, a shear) you want to represent:
from aspose_pdf.engine.primitives import Matrix
shear = Matrix()
shear.b = 0.5 # shear the y-axis
shear.c = 0.0
print(shear.a, shear.b, shear.c, shear.d)
# 1.0 0.5 0.0 1.0Common Issues and Fixes
translate() doesn’t seem to return anything usable
translate(x, y) mutates the matrix’s e/f components in place and returns None. If you need the translated matrix as a new object instead of mutating an existing one, build the translation as its own Matrix(e=x, f=y) and combine it with multiply().
multiply() gives a different result than expected
The linear a–d part of the result depends on multiplication order once either matrix has a nonzero b or c component — a.multiply(b) is not generally the same as b.multiply(a). The e/f translation part, by contrast, always just adds regardless of order.
Confusing Matrix with IMatrix
Matrix (in engine.primitives) is a standalone value type with a–f components. IMatrix is a separate interface (used by IPath.transform) that also exposes a translate(x, y) method but is not the same class — they are not interchangeable, and constructing one does not give you the other.
Passing the wrong number of positional arguments
Matrix’s six components (a, b, c, d, e, f) all have defaults, so Matrix() alone is valid. When you do pass positional arguments, they fill a, b, c, d, e, f in that order — prefer keyword arguments (Matrix(e=10.0, f=5.0)) to avoid mismatching a component by position.
Frequently Asked Questions
What do the six Matrix components represent?
a, b, c, d, e, f are the standard six values of a 2D affine transform, equivalent to the augmented matrix [[a, b, 0], [c, d, 0], [e, f, 1]] — the same convention PDF content streams use for transformation matrices.
Does creating a Matrix automatically transform a page or piece of content?
No. In this edition, Matrix is a standalone value type for representing and composing 2D transforms in your own code — it is not automatically wired into page rendering or content-stream operations.
How do I get an identity matrix?
Call Matrix() with no arguments — the class defaults to a=1.0, b=0.0, c=0.0, d=1.0, e=0.0, f=0.0, which is the identity transform.
Can I combine a translation with an existing matrix?
Yes — build the translation as Matrix(e=x, f=y) and combine it with your existing matrix via multiply(), or call translate(x, y) directly on the existing matrix to adjust its e/f components in place.
Is there a matrix-like type used elsewhere in the API?
Yes — IMatrix is a separate interface with its own translate(x, y) method, referenced by IPath.transform. It is unrelated to the Matrix dataclass covered here.