diff options
author | 2022-11-13 23:46:45 +0530 | |
---|---|---|
committer | 2022-11-13 23:46:45 +0530 | |
commit | 9468226a9e2e2ab8cdd599f1d8538e860ca86120 (patch) | |
tree | 0a77ada226d6db80639f96b438bf83e4e756edb5 /env/lib/python3.10/site-packages/pikepdf/models/matrix.py | |
download | idcard-9468226a9e2e2ab8cdd599f1d8538e860ca86120.tar.gz idcard-9468226a9e2e2ab8cdd599f1d8538e860ca86120.tar.bz2 idcard-9468226a9e2e2ab8cdd599f1d8538e860ca86120.zip |
id card generator
Diffstat (limited to 'env/lib/python3.10/site-packages/pikepdf/models/matrix.py')
-rw-r--r-- | env/lib/python3.10/site-packages/pikepdf/models/matrix.py | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/env/lib/python3.10/site-packages/pikepdf/models/matrix.py b/env/lib/python3.10/site-packages/pikepdf/models/matrix.py new file mode 100644 index 0000000..c660320 --- /dev/null +++ b/env/lib/python3.10/site-packages/pikepdf/models/matrix.py @@ -0,0 +1,145 @@ +# SPDX-FileCopyrightText: 2022 James R. Barlow +# SPDX-License-Identifier: MPL-2.0 + +"""PDF content matrix support.""" + +from __future__ import annotations + +from math import cos, pi, sin + + +class PdfMatrix: + """ + Support class for PDF content stream matrices. + + PDF content stream matrices are 3x3 matrices summarized by a shorthand + ``(a, b, c, d, e, f)`` which correspond to the first two column vectors. + The final column vector is always ``(0, 0, 1)`` since this is using + `homogenous coordinates <https://en.wikipedia.org/wiki/Homogeneous_coordinates>`_. + + PDF uses row vectors. That is, ``vr @ A'`` gives the effect of transforming + a row vector ``vr=(x, y, 1)`` by the matrix ``A'``. Most textbook + treatments use ``A @ vc`` where the column vector ``vc=(x, y, 1)'``. + + (``@`` is the Python matrix multiplication operator.) + + Addition and other operations are not implemented because they're not that + meaningful in a PDF context (they can be defined and are mathematically + meaningful in general). + + PdfMatrix objects are immutable. All transformations on them produce a new + matrix. + + """ + + def __init__(self, *args): + # fmt: off + if not args: + self.values = ((1, 0, 0), (0, 1, 0), (0, 0, 1)) + elif len(args) == 6: + a, b, c, d, e, f = map(float, args) + self.values = ((a, b, 0), + (c, d, 0), + (e, f, 1)) + elif isinstance(args[0], PdfMatrix): + self.values = args[0].values + elif len(args[0]) == 6: + a, b, c, d, e, f = map(float, args[0]) + self.values = ((a, b, 0), + (c, d, 0), + (e, f, 1)) + elif len(args[0]) == 3 and len(args[0][0]) == 3: + self.values = (tuple(args[0][0]), + tuple(args[0][1]), + tuple(args[0][2])) + else: + raise ValueError('invalid arguments: ' + repr(args)) + # fmt: on + + @staticmethod + def identity(): + """Constructs and returns an identity matrix.""" + return PdfMatrix() + + def __matmul__(self, other): + """Multiply this matrix by another matrix. + + Can be used to concatenate transformations. + """ + a = self.values + b = other.values + return PdfMatrix( + [ + [sum(float(i) * float(j) for i, j in zip(row, col)) for col in zip(*b)] + for row in a + ] + ) + + def scaled(self, x, y): + """Concatenates a scaling matrix on this matrix.""" + return self @ PdfMatrix((x, 0, 0, y, 0, 0)) + + def rotated(self, angle_degrees_ccw): + """Concatenates a rotation matrix on this matrix.""" + angle = angle_degrees_ccw / 180.0 * pi + c, s = cos(angle), sin(angle) + return self @ PdfMatrix((c, s, -s, c, 0, 0)) + + def translated(self, x, y): + """Translates this matrix.""" + return self @ PdfMatrix((1, 0, 0, 1, x, y)) + + @property + def shorthand(self): + """Return the 6-tuple (a,b,c,d,e,f) that describes this matrix.""" + return (self.a, self.b, self.c, self.d, self.e, self.f) + + @property + def a(self): + """Return matrix this value.""" + return self.values[0][0] + + @property + def b(self): + """Return matrix this value.""" + return self.values[0][1] + + @property + def c(self): + """Return matrix this value.""" + return self.values[1][0] + + @property + def d(self): + """Return matrix this value.""" + return self.values[1][1] + + @property + def e(self): + """Return matrix this value. + + Typically corresponds to translation on the x-axis. + """ + return self.values[2][0] + + @property + def f(self): + """Return matrix this value. + + Typically corresponds to translation on the y-axis. + """ + return self.values[2][1] + + def __eq__(self, other): + if isinstance(other, PdfMatrix): + return self.shorthand == other.shorthand + return False + + def encode(self): + """Encode this matrix in binary suitable for including in a PDF.""" + return '{:.6f} {:.6f} {:.6f} {:.6f} {:.6f} {:.6f}'.format( + self.a, self.b, self.c, self.d, self.e, self.f + ).encode() + + def __repr__(self): + return f"pikepdf.PdfMatrix({repr(self.values)})" |