def _add_rounded_rectangles(self, a):
     """Add a few rounded rectangles with different border radii."""
     y1, y2 = 360, 410
     xs = [10, 60, 110]
     rxs = [5, 10, 15]
     rys = [5, 5, 15]
     for x1, rx, ry in zip(xs, rxs, rys):
         x2 = x1 + 40
         location = Location(x1=x1, y1=y1, x2=x2, y2=y2, page=0)
         content_stream = ContentStream([
             Save(),
             StrokeColor(1, 0, 0),
             FillColor(0, 1, 0),
         ])
         add_rounded_rectangle(
             stream=content_stream,
             x=x1,
             y=y1,
             width=(x2 - x1),
             height=(y2 - y1),
             rx=rx,
             ry=ry,
         )
         content_stream.extend([
             StrokeAndFill(),
             Restore(),
         ])
         appearance = Appearance(appearance_stream=content_stream, )
         a.add_annotation('square', location, appearance)
Beispiel #2
0
    def make_appearance_stream(self):
        A = self._appearance
        L = self._location

        stream = ContentStream([
            Save(),
            BeginText(),
            FillColor(*A.fill[:3]),
            Font(PDF_ANNOTATOR_FONT, A.font_size),
        ])

        graphics_state = A.get_graphics_state()
        if graphics_state.has_content():
            stream.add(CSGraphicsState(GRAPHICS_STATE_NAME))

        # Actually draw the text inside the rectangle
        stream.extend(
            get_text_commands(
                L.x1,
                L.y1,
                L.x2,
                L.y2,
                text=A.content,
                font_size=A.font_size,
                wrap_text=A.wrap_text,
                align=A.text_align,
                baseline=A.text_baseline,
                line_spacing=A.line_spacing,
            ))
        stream.extend([
            EndText(),
            Restore(),
        ])

        return stream
Beispiel #3
0
 def make_default_appearance(self):
     """Returns a DA string for the text object, e.g. '1 0 0 rg /Helv 12 Tf'
     """
     A = self._appearance
     stream = ContentStream([
         FillColor(*A.fill[:3]),
         Font(PDF_ANNOTATOR_FONT, A.font_size),
     ])
     return stream.resolve()
    def _add_explicit_text_annotation(self, a):
        x1, y1, x2, y2 = 110, 310, 200, 350
        font_size = 4

        content_stream = ContentStream([
            Save(),
            BeginText(),
            FillColor(0, 0, 0),
            Font('MyFontyFont', font_size),
        ])
        content_stream.extend(
            get_text_commands(
                x1,
                y1,
                x2,
                y2,
                text=(r'Twas brilling and the slithy toves \n'
                      r'Did gyre and gimbel in the wabe \n'
                      r'All mimsy were the borogroves \n'
                      r'And the mome raths outgrabe \n'),
                font_size=font_size,
                wrap_text=True,
                align=constants.TEXT_ALIGN_LEFT,
                baseline=constants.TEXT_BASELINE_TOP,
                line_spacing=1.2,
            ))
        content_stream.extend([
            EndText(),
            Restore(),
        ])

        appearance = Appearance(
            appearance_stream=content_stream,
            fonts={'MyFontyFont': FreeText.make_font_object()},
        )
        a.add_annotation(
            'square',
            location=Location(x1=x1, y1=y1, x2=x2, y2=y2, page=0),
            appearance=appearance,
        )
Beispiel #5
0
def set_appearance_state(stream, A):
    """Update the graphics command stream to reflect appearance properties.

    :param ContentStream stream: current content stream
    :param Appearance A: appearance object
    """
    # Add in the `gs` command, which will execute the named graphics state from
    # the Resources dict, and set CA and/or ca values. The annotations
    # themselves will need to ensure that the proper ExtGState object is
    # present in the Resources dict.
    graphics_state = A.get_graphics_state()
    if graphics_state.has_content():
        stream.add(CSGraphicsState(GRAPHICS_STATE_NAME))

    stream.extend([
        StrokeColor(*A.stroke_color[:3]),
        StrokeWidth(A.stroke_width),
    ])

    # TODO support more color spaces - CMYK and GrayScale
    if A.fill is not None:
        stream.add(FillColor(*A.fill[:3]))
Beispiel #6
0
 def test_commands_get_number_formatting(self):
     # Regression test to make sure that all commands that output number
     # have sane formatting.
     stream = ContentStream([
         StrokeWidth(0.0),
         StrokeColor(0.0, 0.0, 0.0),
         FillColor(0.0, 0.0, 0.0),
         Rect(0.0, 0.0, 0.0, 0.0),
         Move(0.0, 0.0),
         Line(0.0, 0.0),
         Bezier(0.0, 0.0, 0.0, 0.0, 0.0, 0.0),
         CTM([0.0, 0.0, 0.0, 0.0, 0.0, 0.0]),
         TextMatrix([0.0, 0.0, 0.0, 0.0, 0.0, 0.0]),
     ]).resolve()
     assert stream == ('0 w '
                       '0 0 0 RG '
                       '0 0 0 rg '
                       '0 0 0 0 re '
                       '0 0 m '
                       '0 0 l '
                       '0 0 0 0 0 0 c '
                       '0 0 0 0 0 0 cm '
                       '0 0 0 0 0 0 Tm')
Beispiel #7
0
 def test_content_stream(self):
     # Basically a smoke test for all the simple functions of ContentStream
     cs = ContentStream([Save(), StrokeWidth(2)])
     cs.add(StrokeColor(0, 0, 0))
     cs.add(FillColor(1, 0, 0))
     cs.extend([
         Move(10, 10),
         Line(20, 20),
         Bezier(30, 30, 40, 40, 50, 50),
         Rect(50, 50, 10, 10),
     ])
     cs = ContentStream.join(
         cs,
         ContentStream([
             Close(),
             StrokeAndFill(),
             Stroke(),
             Fill(),
             Restore(),
         ]))
     assert cs.resolve() == ('q 2 w 0 0 0 RG 1 0 0 rg 10 10 m 20 20 l '
                             '30 30 40 40 50 50 c 50 50 10 10 re '
                             'h B S f Q')
Beispiel #8
0
 def test_tuple_commands(self):
     assert StrokeColor(1, 2, 3) == StrokeColor(1, 2, 3)
     assert Text('Hello') == Text('Hello')
     assert StrokeColor(1, 2, 3) != FillColor(1, 2, 3)
Beispiel #9
0
    def test_equality(self):
        assert ContentStream() == ContentStream()

        cs1 = ContentStream([Save(), FillColor(1, 0, 0)])
        cs2 = ContentStream([Save(), FillColor(1, 0, 0)])
        assert cs1 == cs2
Beispiel #10
0
class TestContentStream(TestCase):
    # a list of (ContentStream, stream_string) pairs for testing parse/resolve
    FIXTURES = [
        (ContentStream([
            CTM([1, 0, 0, 1, 0, 0]),
            Font('Helvetica', 12),
            TextMatrix([1, 0, 0, 1, 20, 50]),
            BeginText(),
            Text('Sure, why not?'),
            EndText(),
        ]), ('1 0 0 1 0 0 cm /Helvetica 12 Tf '
             '1 0 0 1 20 50 Tm BT '
             '(Sure, why not?) Tj ET')),
        (ContentStream([
            Save(),
            StrokeWidth(2),
            StrokeColor(0, 0, 0),
            FillColor(1, 0, 0),
            Move(10, 10),
            Line(20, 20),
            Bezier(30, 30, 40, 40, 50, 50),
            Rect(50, 50, 10, 10),
            Close(),
            StrokeAndFill(),
            Stroke(),
            Fill(),
            Restore(),
        ]), ('q 2 w 0 0 0 RG 1 0 0 rg 10 10 m 20 20 l '
             '30 30 40 40 50 50 c 50 50 10 10 re '
             'h B S f Q')),
    ]

    def test_equality(self):
        assert ContentStream() == ContentStream()

        cs1 = ContentStream([Save(), FillColor(1, 0, 0)])
        cs2 = ContentStream([Save(), FillColor(1, 0, 0)])
        assert cs1 == cs2

    def test_content_stream_not_equal_to_string(self):
        assert ContentStream() != ''
        assert ContentStream([Save()]) != 'q'

    def test_resolve(self):
        for cs, stream_string in self.FIXTURES:
            assert cs.resolve() == stream_string

    def test_content_stream(self):
        # Basically a smoke test for all the simple functions of ContentStream
        cs = ContentStream([Save(), StrokeWidth(2)])
        cs.add(StrokeColor(0, 0, 0))
        cs.add(FillColor(1, 0, 0))
        cs.extend([
            Move(10, 10),
            Line(20, 20),
            Bezier(30, 30, 40, 40, 50, 50),
            Rect(50, 50, 10, 10),
        ])
        cs = ContentStream.join(
            cs,
            ContentStream([
                Close(),
                StrokeAndFill(),
                Stroke(),
                Fill(),
                Restore(),
            ]))
        assert cs.resolve() == ('q 2 w 0 0 0 RG 1 0 0 rg 10 10 m 20 20 l '
                                '30 30 40 40 50 50 c 50 50 10 10 re '
                                'h B S f Q')

    def test_text_content_stream(self):
        cs = ContentStream([
            CTM([1, 0, 0, 1, 0, 0]),
            Font('Helvetica', 12),
            TextMatrix([1, 0, 0, 1, 20, 50]),
            BeginText(),
            Text('Sure, why not?'),
            EndText(),
        ])
        assert cs.resolve() == ('1 0 0 1 0 0 cm /Helvetica 12 Tf '
                                '1 0 0 1 20 50 Tm BT '
                                '(Sure, why not?) Tj ET')

    def test_transform_move(self):
        transformed = Move(1, 1).transform([2, 0, 0, 2, 5, 10]).resolve()
        assert transformed == '7 12 m'

    def test_transform_line(self):
        transformed = Line(1, 1).transform([2, 0, 0, 2, 5, 10]).resolve()
        assert transformed == '7 12 l'

    def test_transform_rect(self):
        transformed = Rect(1, 1, 2, 2).transform([2, 0, 0, 2, 5, 10]).resolve()
        assert transformed == '7 12 4 4 re'

    def test_transform_bezier(self):
        transformed = Bezier(1, 1, 2, 2, 3,
                             3).transform([2, 0, 0, 2, 5, 10], ).resolve()
        assert transformed == '7 12 9 14 11 16 c'

    def test_transform_content_stream(self):
        cs = ContentStream([
            Save(),
            Move(1, 1),
            Restore(),
        ])
        transformed = cs.transform([2, 0, 0, 2, 5, 10]).resolve()
        assert transformed == 'q 7 12 m Q'