# Path: gymnast/pdf_operation/pdf_operation.py
# class PdfOperation(object):
#     """PDF content stream operations dispatcher.  Content stream operations are
#     registered by calling PdfOperation.register(), passing the opcode, the type
#     of operation, and the function that does it."""
#     # Operation type constants (see Reference p. 196)
#     # These mostly exist to make things easier in PdfRenderer methods
#     NOP                    =     0
#     GENERAL_GRAPHICS_STATE =     1
#     SPECIAL_GRAPHICS_STATE =     2
#     PATH_CONSTRUCTION      =     4
#     PATH_PAINTING          =     8
#     CLIPPING_PATHS         =    16
#     TEXT_OBJECTS           =    32
#     TEXT_STATE             =    64
#     TEXT_POSITIONING       =   128
#     TEXT_SHOWING           =   256
#     TYPE_3_FONTS           =   512
#     COLOR                  =  1024
#     SHADING_PATTERNS       =  2048
#     INLINE_IMAGES          =  4096
#     XOBJECTS               =  8192
#     MARKED_CONTENT         = 16384
#     COMPATIBILITY          = 32768
# 
#     _opcodes = {}
#     _nops    = {} # As we spawn new NOP classes, we'll cache them here
#     @classmethod
#     def register(cls, opcode, optype, opfunc):
#         """Register a new PDF operation.  Arguments are the opcode, the type of
#         operation, and the function that actually does the operation."""
#         opcode = ensure_str(opcode)
#         if not callable(opfunc):
#             raise TypeError('opfunc must be callable')
#         args = inspect.getfullargspec(opfunc)
#         if not (args.varargs or args.args):
#             raise ValueError('opfunc must take at least one positional argument')
#         opcode = ensure_str(opcode)
#         cls._opcodes[opcode] = new_opcode(opcode, optype, opfunc)
# 
#     @classmethod
#     def __getitem__(cls, operator):
#         operator = ensure_str(operator)
#         try:
#             return cls._opcodes[operator]
#         except KeyError:
#             return cls._nop(operator)
#     @classmethod
#     def _nop(cls, operator):
#         """Get the corresponding NOP operation, creating it if necessary."""
#         warnings.warn("Opcode '{}' not implemented. NOP".format(operator),
#                       PdfOpWarning)
#         try:
#             return cls._nops[operator]
#         except KeyError:
#             tpe = new_opcode(operator, 0, lambda *x: None)
#             cls._nops[operator] = tpe
#             return tpe
# 
# Path: gymnast/pdf_matrix.py
# class PdfMatrix(object):
#     """Very limited matrix class representing PDF transformations"""
#     def __init__(self, a, b, c, d, e, f):
#         """Create a new PdfMatrix object.  Arguments real numbers and represent
#         a matrix as described on p. 208 of the Reference:
#                                       [ a b 0 ]
#         PdfMatrix(a, b, c, d, e, f) = [ c d 0 ]
#                                       [ e f 1 ]
#         """
#         self.a = float(a)
#         self.b = float(b)
#         self.c = float(c)
#         self.d = float(d)
#         self.e = float(e)
#         self.f = float(f)
#     def transform_coords(self, x, y):
#         return (self.a*x+self.c*y+self.e,
#                 self.b*x+self.d*y+self.f)
#     def __mul__(self, other):
#         """Matrix multiplication.
#         Given the type constraint below, this will be self*other"""
#         if not isinstance(other, PdfMatrix):
#             raise TypeError('Can only multiply PdfMatrices by PdfMatrice')
#         return PdfMatrix(self.a*other.a+self.b*other.c,
#                          self.a*other.b+self.b*other.d,
#                          self.c*other.a+self.d*other.c,
#                          self.c*other.b+self.d*other.d,
#                          self.e*other.a+self.f*other.c+other.e,
#                          self.e*other.b+self.f*other.d+other.f)
#     @property
#     def current_coords(self):
#         """Current x, y offset in whatever space this matrix represents"""
#         return self.e, self.f
#     def copy(self):
#         """Return a copy of this matrix"""
#         return PdfMatrix(self.a, self.b,
#                          self.c, self.d,
#                          self.e, self.f)


from ..pdf_operation import PdfOperation
from ...pdf_matrix   import PdfMatrix
"""
Text positioning operations - Reference p. 406
"""


def opcode_Td(renderer, t_x, t_y):
    """Move to a new line, parallel to the current one, at text space
    coordinates offset from the start of the current line by (t_x, t_y)"""

# Path: gymnast/pdf_operation/pdf_operation.py
# class PdfOperation(object):
#     """PDF content stream operations dispatcher.  Content stream operations are
#     registered by calling PdfOperation.register(), passing the opcode, the type
#     of operation, and the function that does it."""
#     # Operation type constants (see Reference p. 196)
#     # These mostly exist to make things easier in PdfRenderer methods
#     NOP                    =     0
#     GENERAL_GRAPHICS_STATE =     1
#     SPECIAL_GRAPHICS_STATE =     2
#     PATH_CONSTRUCTION      =     4
#     PATH_PAINTING          =     8
#     CLIPPING_PATHS         =    16
#     TEXT_OBJECTS           =    32
#     TEXT_STATE             =    64
#     TEXT_POSITIONING       =   128
#     TEXT_SHOWING           =   256
#     TYPE_3_FONTS           =   512
#     COLOR                  =  1024
#     SHADING_PATTERNS       =  2048
#     INLINE_IMAGES          =  4096
#     XOBJECTS               =  8192
#     MARKED_CONTENT         = 16384
#     COMPATIBILITY          = 32768
# 
#     _opcodes = {}
#     _nops    = {} # As we spawn new NOP classes, we'll cache them here
#     @classmethod
#     def register(cls, opcode, optype, opfunc):
#         """Register a new PDF operation.  Arguments are the opcode, the type of
#         operation, and the function that actually does the operation."""
#         opcode = ensure_str(opcode)
#         if not callable(opfunc):
#             raise TypeError('opfunc must be callable')
#         args = inspect.getfullargspec(opfunc)
#         if not (args.varargs or args.args):
#             raise ValueError('opfunc must take at least one positional argument')
#         opcode = ensure_str(opcode)
#         cls._opcodes[opcode] = new_opcode(opcode, optype, opfunc)
# 
#     @classmethod
#     def __getitem__(cls, operator):
#         operator = ensure_str(operator)
#         try:
#             return cls._opcodes[operator]
#         except KeyError:
#             return cls._nop(operator)
#     @classmethod
#     def _nop(cls, operator):
#         """Get the corresponding NOP operation, creating it if necessary."""
#         warnings.warn("Opcode '{}' not implemented. NOP".format(operator),
#                       PdfOpWarning)
#         try:
#             return cls._nops[operator]
#         except KeyError:
#             tpe = new_opcode(operator, 0, lambda *x: None)
#             cls._nops[operator] = tpe
#             return tpe
# 
# Path: gymnast/pdf_matrix.py
# class PdfMatrix(object):
#     """Very limited matrix class representing PDF transformations"""
#     def __init__(self, a, b, c, d, e, f):
#         """Create a new PdfMatrix object.  Arguments real numbers and represent
#         a matrix as described on p. 208 of the Reference:
#                                       [ a b 0 ]
#         PdfMatrix(a, b, c, d, e, f) = [ c d 0 ]
#                                       [ e f 1 ]
#         """
#         self.a = float(a)
#         self.b = float(b)
#         self.c = float(c)
#         self.d = float(d)
#         self.e = float(e)
#         self.f = float(f)
#     def transform_coords(self, x, y):
#         return (self.a*x+self.c*y+self.e,
#                 self.b*x+self.d*y+self.f)
#     def __mul__(self, other):
#         """Matrix multiplication.
#         Given the type constraint below, this will be self*other"""
#         if not isinstance(other, PdfMatrix):
#             raise TypeError('Can only multiply PdfMatrices by PdfMatrice')
#         return PdfMatrix(self.a*other.a+self.b*other.c,
#                          self.a*other.b+self.b*other.d,
#                          self.c*other.a+self.d*other.c,
#                          self.c*other.b+self.d*other.d,
#                          self.e*other.a+self.f*other.c+other.e,
#                          self.e*other.b+self.f*other.d+other.f)
#     @property
#     def current_coords(self):
#         """Current x, y offset in whatever space this matrix represents"""
#         return self.e, self.f
#     def copy(self):
#         """Return a copy of this matrix"""
#         return PdfMatrix(self.a, self.b,
#                          self.c, self.d,
#                          self.e, self.f)


# Path: gymnast/pdf_operation/operations/text_positioning.py
from ..pdf_operation import PdfOperation
from ...pdf_matrix   import PdfMatrix

"""
Text positioning operations - Reference p. 406
"""


def opcode_Td(renderer, t_x, t_y):
    """Move to a new line, parallel to the current one, at text space
    coordinates offset from the start of the current line by (t_x, t_y)"""

    renderer.ts.m = PdfMatrix(1, 0, 0, 1, t_x, t_y)*renderer.ts.lm