Ejemplo n.º 1
0
    def draw_box(self, progress_tracker=None):
        if not self.check_paper_layout():
            return None

        tuckbox_dimensions = ['width', 'height', 'depth']
        paper_dimensions = ['width', 'height']
        if ((not all(dimension in self.tuckbox for dimension in tuckbox_dimensions)) or
            (not all(dimension in self.paper for dimension in paper_dimensions))):
            return None

        # How much white space on the sides
        margin_height = (self.paper['height'] - self.pattern_height()) / 2
        margin_width = (self.paper['width'] - self.pattern_width()) / 2

        # Main box draw
        draw = Drawing()
        draw.scale(POINT_PER_MM, POINT_PER_MM)
        draw.stroke_color = Color('black')
        draw.stroke_width = RESOLUTION / (200 * POINT_PER_MM)
        draw.fill_opacity = 0
        draw.translate(margin_width,
                       margin_height + self.lip_size() + self.tuckbox['depth'])
        draw.push()

        # Finger holds draw
        finger_draw = Drawing(draw)
        finger_draw.fill_opacity = 1
        finger_draw.fill_color = Color('white')
        finger_draw.push()

        # Dashed draw
        dashed_draw = Drawing(draw)
        dash_array = [min(self.tuckbox['depth'], self.tuckbox['width'],
                          self.tuckbox['height'])/13] * 2
        dashed_draw.stroke_color = Color('rgb(100,100,100)')
        dashed_draw.fill_opacity = 0
        dashed_draw.stroke_width = RESOLUTION / (300 * POINT_PER_MM)
        dashed_draw.stroke_dash_array = dash_array
        dashed_draw.stroke_dash_offset = 1

        # Folding guides draw
        folding_guides_draw = Drawing()
        folding_guides_draw.scale(POINT_PER_MM, POINT_PER_MM)
        folding_guides_draw.stroke_color = Color('black')
        folding_guides_draw.stroke_width = RESOLUTION / (200 * POINT_PER_MM)

        back_draw = Drawing(draw)
        back_dashed_draw = Drawing(dashed_draw)
        back_folding_guides_draw = Drawing(folding_guides_draw)

        if progress_tracker is not None:
            progress_tracker(5)

        two_openings = 'two_openings' in self.options and self.options['two_openings']
        two_pages = 'two_pages' in self.options and self.options['two_pages']

        dash_array = [min(self.tuckbox['depth'], self.tuckbox['width'],
                          self.tuckbox['height'])/13] * 2

        #
        # Draw the box (or the first page)
        #
        self.draw_front(draw, dashed_draw, two_openings)

        if two_pages:
            offset_left_to_back = self.tuckbox['depth']
        else:
            offset_left_to_back = self.tuckbox['depth']*2 + self.tuckbox['width']

        self.draw_back(offset_left_to_back, back_draw, back_dashed_draw, finger_draw, two_openings)

        if two_pages:
            back_draw.polyline([(self.tuckbox['depth'], 0),
                           (self.tuckbox['depth'] * 0.2, 0),
                           (self.tuckbox['depth'] * 0.2, self.tuckbox['height']),
                           (self.tuckbox['depth'], self.tuckbox['height'])])
            draw.line((self.tuckbox['depth']*2 + self.tuckbox['width'], 0),
                      (self.tuckbox['depth']*2 + self.tuckbox['width'], self.tuckbox['height']))

        if progress_tracker is not None:
            progress_tracker(10)

        # Create the image
        image = Image(width=math.ceil(self.paper['width'] * POINT_PER_MM),
                      height=math.ceil(self.paper['height'] * POINT_PER_MM),
                      background=Color('white'))
        image.resolution = RESOLUTION
        image.unit = 'pixelsperinch'

        if two_pages:
            image2 = Image(width=math.ceil(self.paper['width'] * POINT_PER_MM),
                        height=math.ceil(self.paper['height'] * POINT_PER_MM),
                        background=Color('white'))
            image2.resolution = RESOLUTION
            image2.unit = 'pixelsperinch'
        else:
            image2 = image

        # Draw the faces
        self.draw_faces(image, progress_tracker, with_back = not two_pages)
        if two_pages:
            self.draw_faces(image2, progress_tracker, only_back=True)

        # Draw the lip(s)
        lip = self.draw_lip(top=True)
        if lip is not None:
            image.composite(lip,
                            math.floor((margin_width + self.tuckbox['depth']) * POINT_PER_MM),
                            math.floor((margin_height) * POINT_PER_MM))

        if two_openings:
            lip = self.draw_lip(bottom=True)
            if lip is not None:
                image.composite(lip,
                                math.floor((margin_width + self.tuckbox['depth']) * POINT_PER_MM),
                                math.floor((margin_height + self.tuckbox['depth']*2 + self.lip_size() + self.tuckbox['height']) * POINT_PER_MM))

        if progress_tracker is not None:
            progress_tracker(80)

        # Draw all the lines over
        draw.draw(image)
        back_draw.draw(image2)

        finger_draw.draw(image2)
        self.draw_watermark(image)
        if two_pages:
            self.draw_watermark(image2)

        if progress_tracker is not None:
            progress_tracker(90)

        if "folds_dashed" in self.options and self.options["folds_dashed"]:
            dashed_draw.draw(image)
            back_dashed_draw.draw(image2)

        if "folding_guides" in self.options and self.options["folding_guides"]:
            front_vertical_folds = [margin_width + self.tuckbox['depth'],
                              margin_width +
                              self.tuckbox['depth'] + self.tuckbox['width']]
            if not two_pages:
                front_vertical_folds.extend([margin_width +
                                       self.tuckbox['depth']*2 + self.tuckbox['width'],
                                       margin_width + self.tuckbox['depth']*2 + self.tuckbox['width']*2])

            back_vertical_folds = [margin_width + self.tuckbox['depth'],
                                  margin_width +
                                  self.tuckbox['depth'] + self.tuckbox['width']]

            front_horizontal_folds = [margin_height + self.lip_size(),
                                margin_height + self.lip_size() +
                                self.tuckbox['depth'],
                                margin_height + self.lip_size() +
                                self.tuckbox['depth'] + self.tuckbox['height']]

            if two_openings:
                front_horizontal_folds.append(margin_height + self.lip_size() +
                                        self.tuckbox['depth'] * 2 + self.tuckbox['height'])
                back_horizontal_folds = []
            else:
                back_horizontal_folds = [margin_height + self.lip_size() +
                                        self.tuckbox['depth'] + self.tuckbox['height']]

            self.draw_folds(folding_guides_draw, front_vertical_folds, front_horizontal_folds, margin_height, margin_width)
            self.draw_folds(back_folding_guides_draw, back_vertical_folds, back_horizontal_folds, margin_height, margin_width)

            folding_guides_draw.draw(image)
            back_folding_guides_draw.draw(image2)

        if progress_tracker is not None:
            progress_tracker(100)

        if not two_pages:
            image2 = None

        return image, image2
Ejemplo n.º 2
0
    def draw_lip(self, top=False, bottom=False):
        if "back" not in self.faces:
            return None

        if not (top ^ bottom): # 1 and only 1 of top or bottom should be true
            return None

        # First draw a full mask with the lip shape
        lip_full_mask_image = Image(width=math.ceil(self.tuckbox['width'] * POINT_PER_MM),
                                    height=math.ceil(self.lip_size() * POINT_PER_MM))
        lip_full_draw = Drawing()

        lip_full_draw.scale(POINT_PER_MM, POINT_PER_MM)

        # This cannot be too "thin" or the floodfill later would spill over
        lip_full_draw.stroke_width = max(2 / POINT_PER_MM, RESOLUTION / (200 * POINT_PER_MM))

        lip_full_draw.fill_color = Color('white')
        lip_full_draw.color(0, 0, 'reset')
        lip_full_draw.draw(lip_full_mask_image)

        lip_full_draw.stroke_color = Color('black')

        # 1/2 left of lip
        lip_full_draw.bezier([(0, self.lip_size()),
                              (0, self.lip_size() - .75*self.lip_size()),
                              (.2 * self.tuckbox['width'],
                               self.lip_size() - self.lip_size()),
                              (.5 * self.tuckbox['width'], self.lip_size() - self.lip_size())])

        # 1/2 right of lip
        lip_full_draw.bezier([(self.tuckbox['width'], self.lip_size()),
                              (self.tuckbox['width'],
                               self.lip_size() - .75*self.lip_size()),
                              (.8 * self.tuckbox['width'],
                               self.lip_size() - self.lip_size()),
                              (.5 * self.tuckbox['width'], self.lip_size() - self.lip_size())])

        lip_full_draw.draw(lip_full_mask_image)

        lip_full_draw.fill_color = Color('black')
        lip_full_draw.border_color = Color('black')
        lip_full_draw.color(.5 * self.tuckbox['width'],
                            0.8*self.lip_size(), 'filltoborder')

        lip_full_draw.draw(lip_full_mask_image)

        if self.faces['back'][:1] == "#":
            lip_image = Image(width = lip_full_mask_image.width, height = lip_full_mask_image.height,
                            background = Color(self.faces['back']))
        else:
            # Prepare the front image
            angle = 180 if "back_angle" not in self.options else (self.options["back_angle"]+2)*90

            if bottom:
                angle = (angle + 180) % 360

            _, file_extension = os.path.splitext(self.faces['back'])
            tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=file_extension)
            self.resize_rotate_image(self.faces['back'], tmp_file.name, angle, math.ceil(self.tuckbox['width'] * POINT_PER_MM),
                            math.ceil(self.tuckbox['height'] * POINT_PER_MM))
            lip_image = Image(filename=tmp_file.name)
            lip_image.crop(top=lip_image.height - lip_full_mask_image.height)

        # u = image pixel
        # h = height
        # j = row
        # Radius of the hold is {self.tuckbox['width']*.1}
        # if value is 1 (or more_, it's white
        # Top is the tip of the lip, bottom is attached to the box
        # finger_hold_size_save is the row # at which it should be no attenuation below
        finger_hold_size_save = str(
            int(lip_image.height - math.ceil(self.tuckbox['width'] * POINT_PER_MM * 0.1)))
        lip_image = lip_image.fx(
            "j>"+finger_hold_size_save+"?u:1+(u-1)*(j/"+finger_hold_size_save+")")

        lip_image.composite(operator='lighten', image=lip_full_mask_image)

        if bottom:
            lip_image.rotate(180)

        return lip_image