Exemple #1
0
    def __init__(self, specification, drawing_callable, pages_to_draw=None, border=False, shade_missing=False):
        """
        Parameters
        ----------
        specification: labels.Specification instance
            The sizes etc of the label sheets.
        drawing_callable: callable
            A function (or other callable object) to call to draw an individual
            label. It will be given four parameters specifying the label. In
            order, these are a `reportlab.graphics.shapes.Drawing` instance to
            draw the label on, the width of the label, the height of the label,
            and the object to draw. The dimensions will be in points, the unit
            of choice for ReportLab.
        pages_to_draw: list of positive integers, default None
            The list pages to actually draw labels on. This is intended to be
            used with the preview methods to avoid drawing labels that will
            never be displayed. A value of None means draw all pages.
        border: Boolean, default False
            Whether or not to draw a border around each label.
        shade_missing: Boolean or ReportLab colour, default False
            Whether or not to shade missing labels (those specified through the
            partial_pages method). False means leave the labels unshaded. If a
            ReportLab colour is given, the labels will be shaded in that colour.
            A value of True will result in the missing labels being shaded in
            the hex colour 0xBBBBBB (a medium-light grey).

        Notes
        -----
        If you specify a pages_to_draw list, pages not in that list will be
        blank since the drawing function will not be called on that page. This
        could have a side-affect if you rely on the drawing function modifying
        some global values. For example, in the nametags.py and preview.py demo
        scripts, the colours for each label are picked by a pseduo-random number
        generator. However, in the preview script, this generator is not
        advanced and so the colours on the last page differ between the preview
        and the actual output.

        """
        # Save our arguments.
        specification._calculate()
        self.specs = deepcopy(specification)
        self.drawing_callable = drawing_callable
        self.pages_to_draw = pages_to_draw
        self.border = border
        if shade_missing == True:
            self.shade_missing = colors.HexColor(0xBBBBBB)
        else:
            self.shade_missing = shade_missing

        # Set up some internal variables.
        self._lw = self.specs.label_width * mm
        self._lh = self.specs.label_height * mm
        self._cr = self.specs.corner_radius * mm
        self._dw = (self.specs.label_width - self.specs.left_padding - self.specs.right_padding) * mm
        self._dh = (self.specs.label_height - self.specs.top_padding - self.specs.bottom_padding) * mm
        self._lp = self.specs.left_padding * mm
        self._bp = self.specs.bottom_padding * mm
        self._pr = self.specs.padding_radius * mm
        self._used = {}
        self._pages = []
        self._current_page = None

        # Page information.
        self._pagesize = (float(self.specs.sheet_width * mm), float(self.specs.sheet_height * mm))
        self._numlabels = [self.specs.rows, self.specs.columns]
        self._position = [1, 0]
        self.label_count = 0
        self.page_count = 0

        # Background image.
        if self.specs.background_image:
            self._bgimage = deepcopy(self.specs.background_image)

            # Different classes are scaled in different ways...
            if isinstance(self._bgimage, Image):
                self._bgimage.x = 0
                self._bgimage.y = 0
                self._bgimage.width = self._pagesize[0]
                self._bgimage.height = self._pagesize[1]
            elif isinstance(self._bgimage, Drawing):
                self._bgimage.shift(0, 0)
                self._bgimage.scale(self._pagesize[0] / self._bgimage.width, self._pagesize[1] / self._bgimage.height)
            else:
                raise ValueError("Unhandled background type.")

        # Background from a filename.
        elif self.specs.background_filename:
            self._bgimage = Image(0, 0, self._pagesize[0], self._pagesize[1], self.specs.background_filename)

        # No background.
        else:
            self._bgimage = None

        # Borders and clipping paths. We need two clipping paths; one for the
        # label as a whole (which is identical to the border), and one for the
        # available drawing area (i.e., after taking the padding into account).
        # This is necessary because sometimes the drawing area can extend
        # outside the border at the corners, e.g., if there is left padding
        # only and no padding radius, then the 'available' area corners will be
        # square and go outside the label corners if they are rounded.

        # Copy some properties to a local scope.
        h, w, r = float(self._lh), float(self._lw), float(self._cr)

        # Create the border from a path. If the corners are not rounded, skip
        # adding the arcs.
        border = ArcPath()
        if r:
            border.moveTo(w - r, 0)
            border.addArc(w - r, r, r, -90, 0)
            border.lineTo(w, h - r)
            border.addArc(w - r, h - r, r, 0, 90)
            border.lineTo(r, h)
            border.addArc(r, h - r, r, 90, 180)
            border.lineTo(0, r)
            border.addArc(r, r, r, 180, 270)
            border.closePath()
        else:
            border.moveTo(0, 0)
            border.lineTo(w, 0)
            border.lineTo(w, h)
            border.lineTo(0, h)
            border.closePath()

        # Set the properties and store.
        border.isClipPath = 0
        border.strokeWidth = 1
        border.strokeColor = colors.black
        border.fillColor = None
        self._border = border

        # Clip path for the label is the same as the border.
        self._clip_label = deepcopy(border)
        self._clip_label.isClipPath = 1
        self._clip_label.strokeColor = None
        self._clip_label.fillColor = None

        # If there is no padding (i.e., the drawable area is the same as the
        # label area) then we can just use the label clip path for the drawing
        # clip path.
        if (self._dw == self._lw) and (self._dh == self._lh):
            self._clip_drawing = self._clip_label

        # Otherwise we have to generate a separate path.
        else:
            h, w, r = float(self._dh), float(self._dw), float(self._pr)
            clip = ArcPath()
            if r:
                clip.moveTo(w - r, 0)
                clip.addArc(w - r, r, r, -90, 0)
                clip.lineTo(w, h - r)
                clip.addArc(w - r, h - r, r, 0, 90)
                clip.lineTo(r, h)
                clip.addArc(r, h - r, r, 90, 180)
                clip.lineTo(0, r)
                clip.addArc(r, r, r, 180, 270)
                clip.closePath()
            else:
                clip.moveTo(0, 0)
                clip.lineTo(w, 0)
                clip.lineTo(w, h)
                clip.lineTo(0, h)
                clip.closePath()

            # Set the clipping properties.
            clip.isClipPath = 1
            clip.strokeColor = None
            clip.fillColor = None
            self._clip_drawing = clip
Exemple #2
0
    def __init__(self, specification, drawing_callable, pages_to_draw=None,
            border=False, shade_missing=False, direction="across"):
        """
        Parameters
        ----------
        specification: labels.Specification instance
            The sizes etc of the label sheets.
        drawing_callable: callable
            A function (or other callable object) to call to draw an individual
            label. It will be given four parameters specifying the label. In
            order, these are a `reportlab.graphics.shapes.Drawing` instance to
            draw the label on, the width of the label, the height of the label,
            and the object to draw. The dimensions will be in points, the unit
            of choice for ReportLab.
        pages_to_draw: list of positive integers, default None
            The list pages to actually draw labels on. This is intended to be
            used with the preview methods to avoid drawing labels that will
            never be displayed. A value of None means draw all pages.
        border: Boolean, default False
            Whether or not to draw a border around each label.
        shade_missing: Boolean or ReportLab colour, default False
            Whether or not to shade missing labels (those specified through the
            partial_pages method). False means leave the labels unshaded. If a
            ReportLab colour is given, the labels will be shaded in that colour.
            A value of True will result in the missing labels being shaded in
            the hex colour 0xBBBBBB (a medium-light grey).
        direction: String, either "across" or "down" to indication the order
            labels will be assigned. Default is across.

        Notes
        -----
        If you specify a pages_to_draw list, pages not in that list will be
        blank since the drawing function will not be called on that page. This
        could have a side-affect if you rely on the drawing function modifying
        some global values. For example, in the nametags.py and preview.py demo
        scripts, the colours for each label are picked by a pseduo-random number
        generator. However, in the preview script, this generator is not
        advanced and so the colours on the last page differ between the preview
        and the actual output.

        """
        # Save our arguments.
        specification._calculate()
        self.specs = deepcopy(specification)
        self.drawing_callable = drawing_callable
        self.pages_to_draw = pages_to_draw
        self.border = border
        if shade_missing == True:
            self.shade_missing = colors.HexColor(0xBBBBBB)
        else:
            self.shade_missing = shade_missing

        # Set up some internal variables.
        self._lw = self.specs.label_width * mm
        self._lh = self.specs.label_height * mm
        self._cr = self.specs.corner_radius * mm
        self._dw = (self.specs.label_width - self.specs.left_padding - self.specs.right_padding) * mm
        self._dh = (self.specs.label_height - self.specs.top_padding - self.specs.bottom_padding) * mm
        self._lp = self.specs.left_padding * mm
        self._bp = self.specs.bottom_padding * mm
        self._pr = self.specs.padding_radius * mm
        self._used = {}
        self._pages = []
        self._current_page = None

        # Page information.
        self._pagesize = (float(self.specs.sheet_width*mm), float(self.specs.sheet_height*mm))
        self._numlabels = (self.specs.rows, self.specs.columns)
        self._position = None
        self.label_count = 0
        self.page_count = 0
        if direction == "vertical":
            self._positionIteratorFunc = specification.verticalPosIterator
        else:
            self._positionIteratorFunc = specification.horizontalPosIterator

        # Background image.
        if self.specs.background_image:
            self._bgimage = deepcopy(self.specs.background_image)

            # Different classes are scaled in different ways...
            if isinstance(self._bgimage, Image):
                self._bgimage.x = 0
                self._bgimage.y = 0
                self._bgimage.width = self._pagesize[0]
                self._bgimage.height = self._pagesize[1]
            elif isinstance(self._bgimage, Drawing):
                self._bgimage.shift(0, 0)
                self._bgimage.scale(self._pagesize[0]/self._bgimage.width, self._pagesize[1]/self._bgimage.height)
            else:
                raise ValueError("Unhandled background type.")

        # Background from a filename.
        elif self.specs.background_filename:
            self._bgimage = Image(0, 0, self._pagesize[0], self._pagesize[1], self.specs.background_filename)

        # No background.
        else:
            self._bgimage = None

        # Borders and clipping paths. We need two clipping paths; one for the
        # label as a whole (which is identical to the border), and one for the
        # available drawing area (i.e., after taking the padding into account).
        # This is necessary because sometimes the drawing area can extend
        # outside the border at the corners, e.g., if there is left padding
        # only and no padding radius, then the 'available' area corners will be
        # square and go outside the label corners if they are rounded.

        # Copy some properties to a local scope.
        h, w, r = float(self._lh), float(self._lw), float(self._cr)

        # Create the border from a path. If the corners are not rounded, skip
        # adding the arcs.
        border = ArcPath()
        if r:
            border.moveTo(w - r, 0)
            border.addArc(w - r, r, r, -90, 0)
            border.lineTo(w, h - r)
            border.addArc(w - r, h - r, r, 0, 90)
            border.lineTo(r, h)
            border.addArc(r, h - r, r, 90, 180)
            border.lineTo(0, r)
            border.addArc(r, r, r, 180, 270)
            border.closePath()
        else:
            border.moveTo(0, 0)
            border.lineTo(w, 0)
            border.lineTo(w, h)
            border.lineTo(0, h)
            border.closePath()

        # Set the properties and store.
        border.isClipPath = 0
        border.strokeWidth = 1
        border.strokeColor = colors.black
        border.fillColor = None
        self._border = border

        # Clip path for the label is the same as the border.
        self._clip_label = deepcopy(border)
        self._clip_label.isClipPath = 1
        self._clip_label.strokeColor = None
        self._clip_label.fillColor = None

        # If there is no padding (i.e., the drawable area is the same as the
        # label area) then we can just use the label clip path for the drawing
        # clip path.
        if (self._dw == self._lw) and (self._dh == self._lh):
            self._clip_drawing = self._clip_label

        # Otherwise we have to generate a separate path.
        else:
            h, w, r = float(self._dh), float(self._dw), float(self._pr)
            clip = ArcPath()
            if r:
                clip.moveTo(w - r, 0)
                clip.addArc(w - r, r, r, -90, 0)
                clip.lineTo(w, h - r)
                clip.addArc(w - r, h - r, r, 0, 90)
                clip.lineTo(r, h)
                clip.addArc(r, h - r, r, 90, 180)
                clip.lineTo(0, r)
                clip.addArc(r, r, r, 180, 270)
                clip.closePath()
            else:
                clip.moveTo(0, 0)
                clip.lineTo(w, 0)
                clip.lineTo(w, h)
                clip.lineTo(0, h)
                clip.closePath()

            # Set the clipping properties.
            clip.isClipPath = 1
            clip.strokeColor = None
            clip.fillColor = None
            self._clip_drawing = clip
Exemple #3
0
    def __init__(self, specification, drawing_callable, pages_to_draw=None, border=False, shade_missing=False):
        """
        Parameters
        ----------
        specification: labels.Specification instance
            The sizes etc of the label sheets.
        drawing_callable: callable
            A function (or other callable object) to call to draw an individual
            label. It will be given four parameters specifying the label. In
            order, these are a `reportlab.graphics.shapes.Drawing` instance to
            draw the label on, the width of the label, the height of the label,
            and the object to draw. The dimensions will be in points, the unit
            of choice for ReportLab.
        pages_to_draw: list of positive integers, default None
            The list pages to actually draw labels on. This is intended to be
            used with the preview methods to avoid drawing labels that will
            never be displayed. A value of None means draw all pages.
        border: Boolean, default False
            Whether or not to draw a border around each label.
        shade_missing: Boolean or ReportLab colour, default False
            Whether or not to shade missing labels (those specified through the
            partial_pages method). False means leave the labels unshaded. If a
            ReportLab colour is given, the labels will be shaded in that colour.
            A value of True will result in the missing labels being shaded in
            the hex colour 0xBBBBBB (a medium-light grey).

        Notes
        -----
        If you specify a pages_to_draw list, pages not in that list will be
        blank since the drawing function will not be called on that page. This
        could have a side-affect if you rely on the drawing function modifying
        some global values. For example, in the nametags.py and preview.py demo
        scripts, the colours for each label are picked by a pseduo-random number
        generator. However, in the preview script, this generator is not
        advanced and so the colours on the last page differ between the preview
        and the actual output.

        """
        # Save our arguments.
        specification._calculate()
        self.specs = deepcopy(specification)
        self.drawing_callable = drawing_callable
        self.pages_to_draw = pages_to_draw
        self.border = border
        if shade_missing == True:
            self.shade_missing = colors.HexColor(0xBBBBBB)
        else:
            self.shade_missing = shade_missing

        # Set up some internal variables.
        self._lw = self.specs.label_width * mm
        self._lh = self.specs.label_height * mm
        self._cr = self.specs.corner_radius * mm
        self._used = {}
        self._pages = []
        self._current_page = None

        # Page information.
        self._pagesize = (float(self.specs.sheet_width*mm), float(self.specs.sheet_height*mm))
        self._numlabels = [self.specs.rows, self.specs.columns]
        self._position = [1, 0]
        self.label_count = 0
        self.page_count = 0

        # Have to create the border from a path so we can use it as a clip path.
        border = ArcPath()

        # Copy some properties to a local scope.
        h, w, cr = float(self._lh), float(self._lw), float(self._cr)

        # If the border has rounded corners.
        if self._cr:
            border.moveTo(w - cr, 0)
            border.addArc(w - cr, cr, cr, -90, 0)
            border.lineTo(w, h - cr)
            border.addArc(w - cr, h - cr, cr, 0, 90)
            border.lineTo(cr, h)
            border.addArc(cr, h - cr, cr, 90, 180)
            border.lineTo(0, cr)
            border.addArc(cr, cr, cr, 180, 270)
            border.closePath()

        # No rounded corners.
        else:
            border.moveTo(0, 0)
            border.lineTo(w, 0)
            border.lineTo(w, h)
            border.lineTo(0, h)
            border.closePath()

        # Use it as a clip path.
        border.isClipPath = 1
        border.strokeColor = None
        border.fillColor = None

        # And done.
        self._border = border

        # The border doesn't show up if its part of a clipping path when
        # outputting to an image. If its needed, make a copy and turn the
        # clipping path off.
        if self.border:
            from copy import copy
            self._border_visible = copy(self._border)
            self._border_visible.isClipPath = 0
            self._border_visible.strokeWidth = 1
            self._border_visible.strokeColor = colors.black
        else:
            self._border_visible = None