Ver Fonte

Add Card Grid Generator

This plugin will create a grid of guides and/or cropmarks based on a
given card and bleed size. The number of rows and columns can be
specified, or the plugin can simply work out the maximum possible cards
for the given document.
cinaeco há 4 anos atrás
pai
commit
be8cb5827c

+ 8 - 0
card_grid_generator.desktop

@@ -0,0 +1,8 @@
+[Desktop Entry]
+Type=Service
+ServiceTypes=Krita/PythonPlugin
+X-KDE-Library=card_grid_generator
+X-Python-2-Compatible=false
+X-Krita-Manual=Manual.html
+Name=Card Grid Generator
+Comment=Creates guide and cropmark grids for a given dimension of card.

+ 23 - 0
card_grid_generator/Manual.html

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--BBD's Krita Script Starter, Feb 2018 -->
+<head><title>Extension Template Documentation</title>
+</head>
+<body>
+<h3>Box Generator documentation</h3>
+
+This creates artificial "bleed" on the edges of a given layer, but simply
+cloning the edges outward. This is mainly used for printing double sided print
+and play card games. Defaults to 2mm bleed on all sides.
+
+<h3>Usage</h3>
+
+Run the generator after the desired paint layer is selected. Bleed amount can be
+specified in millimetres, inches and pixels. "Offset" allows the use of pixel
+lines other than the edge. A -1 offset means bleed will be copied from 1 line
+just inside the edge, -2 means 2 lines in, etc.
+
+</body>
+</html>

+ 3 - 0
card_grid_generator/__init__.py

@@ -0,0 +1,3 @@
+from .card_grid_generator_extension import CardGridGenerator
+
+Krita.instance().addExtension(CardGridGenerator(Krita.instance()))

+ 204 - 0
card_grid_generator/card_grid_generator_extension.py

@@ -0,0 +1,204 @@
+from krita import Extension
+from PyQt5.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QComboBox, QCheckBox, QPushButton
+from PyQt5.QtCore import Qt, QByteArray
+from math import floor
+
+class CardGridGenerator(Extension):
+
+    def __init__(self, parent):
+        super().__init__(parent)
+
+    # Krita.instance() exists, so do any setup work
+    def setup(self):
+        pass
+
+    # called after setup(self)
+    def createActions(self, window):
+        # Create menu item in Tools > Scripts.
+        action = window.createAction("cardgridgen", "Card Grid Generator")
+        action.triggered.connect(self.card_grid_generator)
+
+    def card_grid_generator(self):
+        # Dialog creation.
+        newDialog = QDialog()
+        newDialog.setWindowTitle("Card Grid Generator")
+        layout = QVBoxLayout()
+        newDialog.setLayout(layout)
+
+
+        # Description row.
+        desc = QLabel('Creates a grid of guides and cropmarks for a given card size.')
+        desc.setAlignment(Qt.AlignCenter)
+        row0 = QHBoxLayout()
+        row0.addWidget(desc)
+        layout.addLayout(row0)
+
+        # Card dimension row.
+        self.widthInput = QLineEdit('750')
+        self.heightInput = QLineEdit('1050')
+        self.unitInput = QComboBox()
+        self.unitInput.addItems( ['px', 'mm', 'inch'] )
+        row1 = QHBoxLayout()
+        row1.addWidget(QLabel('Card size: W:'))
+        row1.addWidget(self.widthInput)
+        row1.addWidget(QLabel(' x H:'))
+        row1.addWidget(self.heightInput)
+        row1.addWidget(self.unitInput)
+        layout.addLayout(row1)
+
+        # Bleed dimension row. Also, guides or cropmarks selection.
+        self.bleedInput = QLineEdit('24')
+        self.guidesCheck = QCheckBox('Guides')
+        self.guidesCheck.setChecked(True)
+        self.cropmarksCheck = QCheckBox('Cropmarks')
+        self.cropmarksCheck.setChecked(True)
+        row2 = QHBoxLayout()
+        row2.addWidget(QLabel('Bleed size:'))
+        row2.addWidget(self.bleedInput)
+        row2.addWidget(self.guidesCheck)
+        row2.addWidget(self.cropmarksCheck)
+        layout.addLayout(row2)
+
+        # How many cards row.
+        self.rowsInput = QLineEdit('0')
+        self.colsInput = QLineEdit('0')
+        self.maxCheck = QCheckBox('Max Possible')
+        self.maxCheck.setChecked(True)
+        row3 = QHBoxLayout()
+        row3.addWidget(QLabel('Grid: Columns:'))
+        row3.addWidget(self.colsInput)
+        row3.addWidget(QLabel('Rows:'))
+        row3.addWidget(self.rowsInput)
+        row3.addWidget(self.maxCheck)
+        layout.addLayout(row3)
+
+        # Do It row.
+        goButton = QPushButton("Create Card Grid")
+        goButton.setIcon( Krita.instance().icon('animation_play') )
+        row4 = QHBoxLayout()
+        row4.addWidget(goButton)
+        layout.addLayout(row4)
+
+        # Hook up the actions.
+        goButton.clicked.connect( self.generateCardGrid )
+
+        # Show the dialog.
+        newDialog.exec_()
+
+
+    ##########
+    # Slots
+    ##########
+
+    # Actually generates the card grid!
+    def generateCardGrid(self, e):
+
+        doc = Krita.instance().activeDocument()
+
+        # If there is no open document, create a new one (A4 300ppi).
+        if not doc:
+            doc = Krita.instance().createDocument(3508, 2480, "Card Grid", "RGBA", "U8", "", 300.0)
+            Krita.instance().activeWindow().addView(doc)
+
+        # Document dimensions.
+        docWidth = doc.width()
+        docHeight = doc.height()
+
+        # Card dimensions with bleed.
+        bleedSize = int(self.bleedInput.text())
+        cardWidth = int(self.widthInput.text())
+        cardHeight = int(self.heightInput.text())
+        cardBledWidth = cardWidth + bleedSize * 2
+        cardBledHeight = cardHeight + bleedSize * 2
+
+        # Determine layout.
+        colCount = 0
+        rowCount = 0
+        if self.maxCheck.checkState():
+            # Create the maximum-possible card layout
+            colCount = floor(docWidth / cardBledWidth)
+            rowCount = floor(docHeight / cardBledHeight)
+        else:
+            # Create card layout according to user specified rows and columns.
+            colCount = int(self.colsInput.text())
+            rowCount = int(self.rowsInput.text())
+
+        # Calculate offset for centering.
+        # Remainder pixels of row and column, divide by 2.
+        # Bias odd pixel calculations to top left via floor.
+        widthOffset = floor((docWidth - colCount * cardBledWidth) / 2)
+        heightOffset = floor((docHeight - rowCount * cardBledHeight) / 2)
+
+        # Create xSet and ySet (remember, both bleed + edge dimensions).
+        # Also create Cards-Only sets for cropmarks.
+        xSet = [widthOffset]
+        ySet = [heightOffset]
+        xSetCardsOnly = []
+        ySetCardsOnly = []
+
+        for i in range(colCount):
+            base = widthOffset + i * cardBledWidth
+            bleed1 = base + bleedSize
+            card = bleed1 + cardWidth
+            bleed2 = card + bleedSize
+            # Cut down the number of guides if there is no bleed.
+            xSet += [bleed1, card, bleed2] if bleedSize > 0 else [card]
+            xSetCardsOnly += [bleed1, card] if bleedSize > 0 else [card]
+
+        for i in range(rowCount):
+            base = heightOffset + i * cardBledHeight
+            bleed1 = base + bleedSize
+            card = bleed1 + cardHeight
+            bleed2 = card + bleedSize
+            # Cut down the number of guides if there is no bleed.
+            ySet +=[bleed1, card, bleed2] if bleedSize > 0 else [card]
+            ySetCardsOnly += [bleed1, card] if bleedSize > 0 else [card]
+
+        xSet.sort()
+        ySet.sort()
+
+        # Create guides. dump xSet ySet into guide functions.
+        if self.guidesCheck.checkState():
+            vList = doc.verticalGuides()
+            hList = doc.horizontalGuides()
+            vList.clear()
+            hList.clear()
+            doc.setVerticalGuides(xSet)
+            doc.setHorizontalGuides(ySet)
+            doc.setGuidesLocked(True)
+            doc.setGuidesVisible(True)
+
+        # Create cropmarks.
+        if self.cropmarksCheck.checkState():
+
+            # Cropmarks will be on a new layer.
+            layer = doc.createNode('CardGridCropmarks', 'paintLayer')
+            root = doc.rootNode()
+            root.addChildNode(layer, None)
+
+            # Create vertical cropmarks.
+            blackPixel = b'\x00\x00\x00\xff'
+            cropMarkWidth = 2
+            cropMarkHeight = 48
+            cropMark = QByteArray(blackPixel * cropMarkWidth * cropMarkHeight)
+            for x in xSetCardsOnly:
+                # top
+                y = ySet[0] - cropMarkHeight
+                layer.setPixelData(cropMark, x - 1, y, cropMarkWidth, cropMarkHeight)
+                # bottom
+                layer.setPixelData(cropMark, x - 1, ySet[-1], cropMarkWidth, cropMarkHeight)
+
+            # Create horizontal cropmarks.
+            cropMarkWidth = 48
+            cropMarkHeight = 2
+            cropMark = QByteArray(blackPixel * cropMarkWidth * cropMarkHeight)
+            for y in ySetCardsOnly:
+                # left
+                x = xSet[0] - cropMarkWidth
+                layer.setPixelData(cropMark, x, y - 1, cropMarkWidth, cropMarkHeight)
+                # right
+                layer.setPixelData(cropMark, xSet[-1], y - 1, cropMarkWidth, cropMarkHeight)
+
+            # Refresh the view, or the cropmarks will not be immediately shown.
+            doc.refreshProjection()
+