# 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/exc.py
# class PdfError(Exception):
#     """Generic PDF exception"""
#     pass
# 
# Path: gymnast/renderer/renderer_states.py
# class TextState(object):
#     """Renderer text state.  Has all of the various text rendering parameters
#     described on pp. 396-404 in the Reference (without the leading T).
# 
#     Attributes (all units are in text space units):
#         m:  The current text matrix
#         lm: Text matrix at the start of the current line
#         c: Charcter spacing - Amount of extra space between characters before
#            scaling by T_h.  Default 0.
#         w: Word spacing - Extra space (pre-T_h) added on encountering a space.
#            Default 0.
#         h: Horizontal scaling - Scaling factor applied to character width and
#            horizontal spacing (i.e., T_c and T_w).  Default 1.
#            N.B.: The associated Tz operator sets this to its operand divided by
#            100.
#         l: Leading - Vertical distance between the baselines of adjacent text
#            lines. Default 0.
#         f: Text font - The name of the current font in the current resource
#            dictionary.  No default value.
#         fs: Text font size - Scaling factor applied to the font in all
#             directions.  No default value.
#         mode: Text rendering mode - Determines text shading, outlining, when
#               rendering text.  Default 0 (solid fill, no stroke).
#         rise: Text rise - Vertical offset from the baseline at which to draw
#               the text.  Positive values result in superscript, negative in
#               subsctipt. Default 0.
#         k: Text knockout - Boolean used in drawing overlappign characters.
#            Set through graphics state operators.  Default True."""
#     id_matrix = PdfMatrix(1, 0, 0, 1, 0, 0)
#     def __init__(self):
#         """Create a new TextState object with values initialed to their
#         respective defaults"""
#         self.c     = 0.0    # Char space
#         self.w     = 0.0    # Word space
#         self.h     = 1.0    # Horizontal text scale
#         self.l     = 0.0    # Text leading
#         self.f     = None   # Font
#         self.fs    = None   # Font scaling
#         self.mode  = 0      # Text render mode
#         self.rise  = 0.0    # Text rise
#         self.m     = self.id_matrix # Text Matrix
#         self.lm    = self.id_matrix # Line Matrix
# 
#     def reset_m(self):
#         """Reset the text matrix to the identity"""
#         self.m  = self.id_matrix
# 
#     def reset_lm(self):
#         """Reset the line matrix to the general text matrix"""
#         self.lm = copy.copy(self.m)


from ..pdf_operation             import PdfOperation
from ...exc                      import PdfError
from ...renderer.renderer_states import TextState
"""
Text Object operations - Reference p. 405
"""


def opcode_BT(renderer):
    """Begin a new text object, initializing the text and line metrices"""
    if renderer.in_text:
        raise PdfError('Cannot being a new text object without ending the previous')
    renderer.in_text = True

# 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/exc.py
# class PdfError(Exception):
#     """Generic PDF exception"""
#     pass
# 
# Path: gymnast/renderer/renderer_states.py
# class TextState(object):
#     """Renderer text state.  Has all of the various text rendering parameters
#     described on pp. 396-404 in the Reference (without the leading T).
# 
#     Attributes (all units are in text space units):
#         m:  The current text matrix
#         lm: Text matrix at the start of the current line
#         c: Charcter spacing - Amount of extra space between characters before
#            scaling by T_h.  Default 0.
#         w: Word spacing - Extra space (pre-T_h) added on encountering a space.
#            Default 0.
#         h: Horizontal scaling - Scaling factor applied to character width and
#            horizontal spacing (i.e., T_c and T_w).  Default 1.
#            N.B.: The associated Tz operator sets this to its operand divided by
#            100.
#         l: Leading - Vertical distance between the baselines of adjacent text
#            lines. Default 0.
#         f: Text font - The name of the current font in the current resource
#            dictionary.  No default value.
#         fs: Text font size - Scaling factor applied to the font in all
#             directions.  No default value.
#         mode: Text rendering mode - Determines text shading, outlining, when
#               rendering text.  Default 0 (solid fill, no stroke).
#         rise: Text rise - Vertical offset from the baseline at which to draw
#               the text.  Positive values result in superscript, negative in
#               subsctipt. Default 0.
#         k: Text knockout - Boolean used in drawing overlappign characters.
#            Set through graphics state operators.  Default True."""
#     id_matrix = PdfMatrix(1, 0, 0, 1, 0, 0)
#     def __init__(self):
#         """Create a new TextState object with values initialed to their
#         respective defaults"""
#         self.c     = 0.0    # Char space
#         self.w     = 0.0    # Word space
#         self.h     = 1.0    # Horizontal text scale
#         self.l     = 0.0    # Text leading
#         self.f     = None   # Font
#         self.fs    = None   # Font scaling
#         self.mode  = 0      # Text render mode
#         self.rise  = 0.0    # Text rise
#         self.m     = self.id_matrix # Text Matrix
#         self.lm    = self.id_matrix # Line Matrix
# 
#     def reset_m(self):
#         """Reset the text matrix to the identity"""
#         self.m  = self.id_matrix
# 
#     def reset_lm(self):
#         """Reset the line matrix to the general text matrix"""
#         self.lm = copy.copy(self.m)


# Path: gymnast/pdf_operation/operations/text_objects.py
from ..pdf_operation             import PdfOperation
from ...exc                      import PdfError
from ...renderer.renderer_states import TextState

"""
Text Object operations - Reference p. 405
"""


def opcode_BT(renderer):
    """Begin a new text object, initializing the text and line metrices"""
    if renderer.in_text:
        raise PdfError('Cannot being a new text object without ending the previous')
    renderer.in_text = True

    renderer.ts.m  = TextState.id_matrix