kopia lustrzana https://github.com/EmbroidePy/pyembroidery
541 wiersze
18 KiB
Python
541 wiersze
18 KiB
Python
import struct
|
|
import zlib
|
|
from math import sqrt
|
|
|
|
from .EmbConstant import *
|
|
from .EmbThread import EmbThread
|
|
|
|
SEQUIN_CONTINGENCY = CONTINGENCY_SEQUIN_STITCH
|
|
FULL_JUMP = True
|
|
|
|
# Static characters for writing to image.
|
|
characters = {
|
|
"0": [
|
|
[9, 9, 4, 1, 0, 1, 5, 9, 9],
|
|
[9, 3, 0, 0, 0, 0, 0, 5, 9],
|
|
[7, 0, 1, 7, 9, 6, 0, 0, 9],
|
|
[4, 0, 5, 9, 9, 9, 4, 0, 6],
|
|
[3, 0, 8, 9, 9, 9, 6, 0, 4],
|
|
[2, 0, 9, 5, 0, 6, 8, 0, 3],
|
|
[2, 0, 9, 4, 0, 6, 8, 0, 3],
|
|
[2, 0, 9, 9, 9, 9, 8, 0, 3],
|
|
[3, 0, 8, 9, 9, 9, 6, 0, 4],
|
|
[4, 0, 5, 9, 9, 9, 4, 0, 6],
|
|
[7, 0, 1, 7, 9, 6, 0, 0, 8],
|
|
[9, 3, 0, 0, 0, 0, 0, 5, 9],
|
|
[9, 9, 4, 1, 0, 1, 5, 9, 9],
|
|
],
|
|
"1": [
|
|
[9, 8, 5, 2, 0, 1, 9, 9, 9],
|
|
[9, 1, 0, 0, 0, 1, 9, 9, 9],
|
|
[9, 2, 4, 7, 1, 1, 9, 9, 9],
|
|
[9, 9, 9, 9, 1, 1, 9, 9, 9],
|
|
[9, 9, 9, 9, 1, 1, 9, 9, 9],
|
|
[9, 9, 9, 9, 1, 1, 9, 9, 9],
|
|
[9, 9, 9, 9, 1, 1, 9, 9, 9],
|
|
[9, 9, 9, 9, 1, 1, 9, 9, 9],
|
|
[9, 9, 9, 9, 1, 1, 9, 9, 9],
|
|
[9, 9, 9, 9, 1, 1, 9, 9, 9],
|
|
[9, 9, 9, 9, 1, 1, 9, 9, 9],
|
|
[9, 3, 0, 0, 0, 0, 0, 0, 3],
|
|
[9, 3, 0, 0, 0, 0, 0, 0, 3],
|
|
],
|
|
"2": [
|
|
[8, 5, 2, 1, 1, 2, 6, 9, 9],
|
|
[4, 0, 0, 0, 0, 0, 0, 4, 9],
|
|
[5, 4, 7, 8, 8, 5, 0, 0, 8],
|
|
[9, 9, 9, 9, 9, 9, 3, 0, 7],
|
|
[9, 9, 9, 9, 9, 9, 3, 0, 9],
|
|
[9, 9, 9, 9, 9, 8, 0, 4, 9],
|
|
[9, 9, 9, 9, 8, 1, 2, 9, 9],
|
|
[9, 9, 9, 8, 2, 2, 9, 9, 9],
|
|
[9, 9, 8, 1, 2, 9, 9, 9, 9],
|
|
[9, 8, 1, 2, 9, 9, 9, 9, 9],
|
|
[7, 1, 2, 9, 9, 9, 9, 9, 9],
|
|
[3, 0, 0, 0, 0, 0, 0, 0, 6],
|
|
[3, 0, 0, 0, 0, 0, 0, 0, 6],
|
|
],
|
|
"3": [
|
|
[9, 6, 2, 1, 1, 2, 6, 9, 9],
|
|
[5, 0, 0, 0, 0, 0, 0, 4, 9],
|
|
[6, 3, 7, 8, 9, 6, 1, 0, 8],
|
|
[9, 9, 9, 9, 9, 9, 3, 0, 8],
|
|
[9, 9, 9, 9, 8, 6, 1, 1, 9],
|
|
[9, 9, 4, 0, 0, 0, 2, 8, 9],
|
|
[9, 9, 4, 0, 0, 0, 2, 8, 9],
|
|
[9, 9, 9, 9, 8, 6, 1, 1, 8],
|
|
[9, 9, 9, 9, 9, 9, 5, 0, 6],
|
|
[9, 9, 9, 9, 9, 9, 5, 0, 5],
|
|
[3, 5, 7, 9, 8, 6, 1, 0, 7],
|
|
[2, 0, 0, 0, 0, 0, 0, 3, 9],
|
|
[8, 4, 2, 0, 1, 2, 5, 9, 9],
|
|
],
|
|
"4": [
|
|
[9, 9, 9, 9, 7, 0, 0, 7, 9],
|
|
[9, 9, 9, 9, 2, 1, 0, 7, 9],
|
|
[9, 9, 9, 5, 2, 4, 0, 7, 9],
|
|
[9, 9, 8, 1, 7, 4, 0, 7, 9],
|
|
[9, 9, 3, 4, 9, 4, 0, 7, 9],
|
|
[9, 6, 1, 9, 9, 4, 0, 7, 9],
|
|
[8, 1, 6, 9, 9, 4, 0, 7, 9],
|
|
[4, 3, 9, 9, 9, 4, 0, 7, 9],
|
|
[0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
[0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
[9, 9, 9, 9, 9, 4, 0, 7, 9],
|
|
[9, 9, 9, 9, 9, 4, 0, 7, 9],
|
|
[9, 9, 9, 9, 9, 4, 0, 7, 9],
|
|
],
|
|
"5": [
|
|
[7, 0, 0, 0, 0, 0, 0, 5, 9],
|
|
[7, 0, 0, 0, 0, 0, 0, 5, 9],
|
|
[7, 0, 5, 9, 9, 9, 9, 9, 9],
|
|
[7, 0, 5, 9, 9, 9, 9, 9, 9],
|
|
[7, 0, 1, 1, 0, 2, 6, 9, 9],
|
|
[7, 0, 0, 0, 0, 0, 0, 5, 9],
|
|
[7, 4, 7, 9, 8, 4, 0, 0, 9],
|
|
[9, 9, 9, 9, 9, 9, 3, 0, 6],
|
|
[9, 9, 9, 9, 9, 9, 5, 0, 6],
|
|
[9, 9, 9, 9, 9, 9, 3, 0, 6],
|
|
[3, 5, 8, 9, 8, 5, 0, 0, 9],
|
|
[2, 0, 0, 0, 0, 0, 0, 6, 9],
|
|
[8, 4, 1, 0, 1, 2, 7, 9, 9],
|
|
],
|
|
"6": [
|
|
[9, 9, 7, 2, 1, 0, 3, 8, 9],
|
|
[9, 6, 0, 0, 0, 0, 0, 3, 9],
|
|
[8, 0, 0, 4, 8, 9, 6, 4, 9],
|
|
[5, 0, 4, 9, 9, 9, 9, 9, 9],
|
|
[3, 0, 8, 9, 9, 9, 9, 9, 9],
|
|
[2, 1, 8, 3, 0, 1, 3, 8, 9],
|
|
[2, 2, 2, 0, 0, 0, 0, 1, 8],
|
|
[2, 0, 2, 7, 9, 8, 2, 0, 5],
|
|
[3, 0, 7, 9, 9, 9, 7, 0, 3],
|
|
[4, 0, 7, 9, 9, 9, 7, 0, 3],
|
|
[7, 0, 2, 7, 9, 8, 2, 0, 5],
|
|
[9, 3, 0, 0, 0, 0, 0, 1, 8],
|
|
[9, 9, 4, 1, 0, 1, 3, 8, 9],
|
|
],
|
|
"7": [
|
|
[2, 0, 0, 0, 0, 0, 0, 0, 5],
|
|
[2, 0, 0, 0, 0, 0, 0, 0, 7],
|
|
[9, 9, 9, 9, 9, 9, 3, 2, 9],
|
|
[9, 9, 9, 9, 9, 8, 0, 5, 9],
|
|
[9, 9, 9, 9, 9, 4, 0, 8, 9],
|
|
[9, 9, 9, 9, 9, 1, 3, 9, 9],
|
|
[9, 9, 9, 9, 6, 0, 6, 9, 9],
|
|
[9, 9, 9, 9, 2, 1, 9, 9, 9],
|
|
[9, 9, 9, 7, 0, 4, 9, 9, 9],
|
|
[9, 9, 9, 3, 0, 8, 9, 9, 9],
|
|
[9, 9, 8, 0, 2, 9, 9, 9, 9],
|
|
[9, 9, 5, 0, 6, 9, 9, 9, 9],
|
|
[9, 9, 1, 0, 9, 9, 9, 9, 9],
|
|
],
|
|
"8": [
|
|
[9, 8, 3, 1, 0, 1, 4, 8, 9],
|
|
[8, 1, 0, 0, 0, 0, 0, 1, 9],
|
|
[5, 0, 3, 8, 9, 7, 2, 0, 6],
|
|
[5, 0, 7, 9, 9, 9, 5, 0, 6],
|
|
[7, 0, 3, 8, 9, 7, 2, 1, 8],
|
|
[9, 7, 2, 0, 0, 0, 2, 7, 9],
|
|
[9, 5, 1, 0, 0, 0, 1, 6, 9],
|
|
[6, 0, 3, 8, 9, 7, 2, 0, 7],
|
|
[2, 0, 9, 9, 9, 9, 7, 0, 4],
|
|
[2, 0, 9, 9, 9, 9, 7, 0, 3],
|
|
[3, 0, 3, 8, 9, 7, 2, 0, 4],
|
|
[7, 0, 0, 0, 0, 0, 0, 1, 8],
|
|
[9, 8, 3, 1, 0, 1, 4, 8, 9],
|
|
],
|
|
"9": [
|
|
[9, 7, 3, 0, 0, 2, 6, 9, 9],
|
|
[7, 0, 0, 0, 0, 0, 0, 5, 9],
|
|
[3, 0, 4, 8, 9, 7, 1, 0, 9],
|
|
[1, 0, 9, 9, 9, 9, 5, 0, 6],
|
|
[1, 1, 9, 9, 9, 9, 5, 0, 5],
|
|
[3, 0, 4, 8, 9, 7, 1, 0, 4],
|
|
[7, 0, 0, 0, 0, 0, 3, 0, 4],
|
|
[9, 7, 2, 0, 1, 4, 7, 0, 4],
|
|
[9, 9, 9, 9, 9, 9, 5, 0, 5],
|
|
[9, 9, 9, 9, 9, 9, 2, 0, 7],
|
|
[9, 3, 7, 9, 8, 3, 0, 2, 9],
|
|
[9, 1, 0, 0, 0, 0, 0, 7, 9],
|
|
[9, 7, 2, 0, 1, 3, 8, 9, 9],
|
|
],
|
|
"-": [
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[9, 9, 1, 0, 0, 0, 3, 9, 9],
|
|
[9, 9, 1, 0, 0, 0, 3, 9, 9],
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
],
|
|
"m": [
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[9, 9, 9, 9, 9, 9, 9, 9, 9],
|
|
[0, 5, 2, 1, 7, 6, 1, 2, 8],
|
|
[0, 1, 0, 0, 1, 1, 0, 0, 3],
|
|
[0, 2, 9, 4, 0, 4, 8, 2, 1],
|
|
[0, 5, 9, 6, 0, 7, 9, 4, 1],
|
|
[0, 5, 9, 6, 0, 7, 9, 4, 0],
|
|
[0, 5, 9, 6, 0, 7, 9, 4, 0],
|
|
[0, 5, 9, 6, 0, 7, 9, 4, 0],
|
|
[0, 5, 9, 6, 0, 7, 9, 4, 0],
|
|
[0, 5, 9, 6, 0, 7, 9, 4, 0],
|
|
[0, 5, 9, 6, 0, 7, 9, 4, 0],
|
|
],
|
|
}
|
|
|
|
|
|
def write_png(buf, width, height):
|
|
"""
|
|
Writes PNG file to disk. Buffer must be RGBA * width * height
|
|
"""
|
|
width_byte_4 = width * 4
|
|
raw_data = b"".join(
|
|
b"\x00" + buf[span : span + width_byte_4]
|
|
for span in range(0, height * width * 4, width_byte_4)
|
|
)
|
|
|
|
def png_pack(png_tag, data):
|
|
chunk_head = png_tag + data
|
|
return (
|
|
struct.pack("!I", len(data))
|
|
+ chunk_head
|
|
+ struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head))
|
|
)
|
|
|
|
return b"".join(
|
|
[
|
|
b"\x89PNG\r\n\x1a\n",
|
|
png_pack(b"IHDR", struct.pack("!2I5B", width, height, 8, 6, 0, 0, 0)),
|
|
png_pack(b"IDAT", zlib.compress(raw_data, 9)),
|
|
png_pack(b"IEND", b""),
|
|
]
|
|
)
|
|
|
|
|
|
class PngBuffer:
|
|
def __init__(self, width, height):
|
|
self.width = int(width + 3)
|
|
self.height = int(height + 3)
|
|
self.buf = bytearray(4 * self.width * self.height)
|
|
self.line_width = 3
|
|
self.fancy = True
|
|
self._red = 0
|
|
self._green = 0
|
|
self._blue = 0
|
|
self._alpha = 0
|
|
self._distance_from_black = 0
|
|
self._gradient_shade_ends = 0.65
|
|
self._gradient_shade_edge = 1.1
|
|
self._gradient_shade_center = 1.55
|
|
self._gradient_color_position1 = 0.40
|
|
self._gradient_color_position2 = 0.50
|
|
self._gradient_color_position3 = 0.70
|
|
|
|
def modify_gradient(
|
|
self,
|
|
gradient_shade_ends=0.65,
|
|
gradient_shade_edge=1.1,
|
|
gradient_shade_center=1.55,
|
|
gradient_color_position1=0.40,
|
|
gradient_color_position2=0.50,
|
|
gradient_color_position3=0.70,
|
|
):
|
|
self._gradient_shade_ends = gradient_shade_ends
|
|
self._gradient_shade_edge = gradient_shade_edge
|
|
self._gradient_shade_center = gradient_shade_center
|
|
self._gradient_color_position1 = gradient_color_position1
|
|
self._gradient_color_position2 = gradient_color_position2
|
|
self._gradient_color_position3 = gradient_color_position3
|
|
|
|
def set_color(self, r, g, b, a=255):
|
|
self._red = r
|
|
self._green = g
|
|
self._blue = b
|
|
self._alpha = a
|
|
rmean = int(r / 2)
|
|
self._distance_from_black = sqrt(
|
|
(((512 + rmean) * r * r) >> 8) + 4 * g * g + (((767 - rmean) * b * b) >> 8)
|
|
)
|
|
|
|
def gradient(self, position_in_line):
|
|
"""
|
|
This function gives different value scales between 0 and 1 which are used to multiply
|
|
all the components of the color to create a darker value. This generally works save for
|
|
black which is already (0,0,0) and can't increase value.
|
|
"""
|
|
if (
|
|
position_in_line <= self._gradient_color_position1
|
|
): # start_of_grdient -> Position 1
|
|
from_shade = self._gradient_shade_ends
|
|
to_shade = self._gradient_shade_edge
|
|
range = self._gradient_color_position1 - 0 # Range of transition
|
|
amount = (position_in_line - 0) * (1 / range)
|
|
|
|
# light to extra_light
|
|
elif (
|
|
position_in_line <= self._gradient_color_position2
|
|
): # Position 1 -> Position 2.
|
|
from_shade = self._gradient_shade_edge
|
|
to_shade = self._gradient_shade_center
|
|
range = self._gradient_color_position2 - self._gradient_color_position1
|
|
amount = (position_in_line - self._gradient_color_position1) * (1 / range)
|
|
|
|
# center of gradient
|
|
|
|
# extra_light to light
|
|
elif (
|
|
position_in_line <= self._gradient_color_position3
|
|
): # Position 2 -> Position 3
|
|
from_shade = self._gradient_shade_center
|
|
to_shade = self._gradient_shade_edge
|
|
range = self._gradient_color_position3 - self._gradient_color_position2
|
|
amount = (position_in_line - self._gradient_color_position2) * (1 / range)
|
|
|
|
# light to dark
|
|
elif position_in_line <= 1: # Position 3 -> end_of_gradient
|
|
from_shade = self._gradient_shade_edge
|
|
to_shade = self._gradient_shade_ends
|
|
range = 1 - self._gradient_color_position3
|
|
amount = (position_in_line - self._gradient_color_position3) * (1 / range)
|
|
else:
|
|
raise ValueError("Did not occur within line.")
|
|
v = amount * (to_shade - from_shade) + from_shade
|
|
return max(min(v, 1.0), 0.0)
|
|
|
|
def background(self, red, green, blue, alpha):
|
|
for i in range(0, len(self.buf), 4):
|
|
self.buf[i] = red
|
|
self.buf[i + 1] = green
|
|
self.buf[i + 2] = blue
|
|
self.buf[i + 3] = alpha
|
|
|
|
def plot(self, x, y, v=None, a=None):
|
|
"""
|
|
Plot a particular point in the canvas.
|
|
:param x: x position to plot
|
|
:param y: y position to plot
|
|
:param v: value scale of particular color (0-1)
|
|
:param a: alpha to set for this particular plot if not self.alpha
|
|
:return:
|
|
"""
|
|
a = int(a) if a is not None else self._alpha
|
|
if v is None:
|
|
v = 1.0
|
|
try:
|
|
x += 1
|
|
y += 1
|
|
pos = (self.width * y) + x
|
|
idx = pos * 4
|
|
background_a = self.buf[idx + 3]
|
|
|
|
# get rgb and check if close to black and make off dark gray
|
|
# this makes black have highlights
|
|
if self._distance_from_black < 15:
|
|
r = 35
|
|
g = 35
|
|
b = 35
|
|
r = r * v
|
|
g = g * v
|
|
b = b * v
|
|
# end of check and make gray
|
|
else:
|
|
r = self._red * v
|
|
g = self._green * v
|
|
b = self._blue * v
|
|
if 0 > r:
|
|
r = 0
|
|
if 0 > g:
|
|
g = 0
|
|
if 0 > b:
|
|
b = 0
|
|
if r > 255:
|
|
r = 255
|
|
if g > 255:
|
|
g = 255
|
|
if b > 255:
|
|
b = 255
|
|
if background_a != 0 and a != 255:
|
|
s_alpha = a / 255.0
|
|
s_background_a = background_a / 255.0
|
|
one_minus_salpha = 1 - s_alpha
|
|
|
|
background_r = self.buf[idx]
|
|
background_g = self.buf[idx + 1]
|
|
background_b = self.buf[idx + 2]
|
|
r = r * s_alpha + one_minus_salpha * background_r
|
|
g = g * s_alpha + one_minus_salpha * background_g
|
|
b = b * s_alpha + one_minus_salpha * background_b
|
|
a = (s_alpha + one_minus_salpha * s_background_a) * 255
|
|
self.buf[idx] = int(r)
|
|
self.buf[idx + 1] = int(g)
|
|
self.buf[idx + 2] = int(b)
|
|
self.buf[idx + 3] = (
|
|
int(a) - 4
|
|
) # remove just a little opacity for background color tint show thru
|
|
except IndexError:
|
|
pass
|
|
|
|
def draw_line(self, x0, y0, x1, y1):
|
|
dy = y1 - y0 # BRESENHAM LINE DRAW ALGORITHM
|
|
dx = x1 - x0
|
|
if dy < 0:
|
|
dy = -dy
|
|
step_y = -1
|
|
else:
|
|
step_y = 1
|
|
odx = abs(dx)
|
|
ody = abs(dy)
|
|
if dx < 0:
|
|
dx = -dx
|
|
step_x = -1
|
|
else:
|
|
step_x = 1
|
|
i = 0
|
|
if dx > dy:
|
|
dy <<= 1 # dy is now 2*dy
|
|
dx <<= 1
|
|
fraction = dy - (dx >> 1) # same as 2*dy - dx
|
|
self.line_for_point(x0, y0, False, odx, i)
|
|
i += 1
|
|
|
|
while x0 != x1:
|
|
if fraction >= 0:
|
|
y0 += step_y
|
|
fraction -= dx # same as fraction -= 2*dx
|
|
x0 += step_x
|
|
fraction += dy # same as fraction += 2*dy
|
|
self.line_for_point(x0, y0, False, odx, i)
|
|
i += 1
|
|
else:
|
|
dy <<= 1 # dy is now 2*dy
|
|
dx <<= 1 # dx is now 2*dx
|
|
fraction = dx - (dy >> 1)
|
|
self.line_for_point(x0, y0, True, ody, i)
|
|
i += 1
|
|
while y0 != y1:
|
|
if fraction >= 0:
|
|
x0 += step_x
|
|
fraction -= dy
|
|
y0 += step_y
|
|
fraction += dx
|
|
self.line_for_point(x0, y0, True, ody, i)
|
|
|
|
def line_for_point(self, x, y, dy, max_pos, index):
|
|
w = self.line_width
|
|
left = w >> 1
|
|
right = w - left
|
|
if self.fancy:
|
|
v = self.gradient(index / max_pos)
|
|
else:
|
|
v = 1.0
|
|
if dy:
|
|
for pos in range(-left, right):
|
|
self.plot(x + pos, y, v)
|
|
else:
|
|
for pos in range(-left, right):
|
|
self.plot(x, y + pos, v)
|
|
|
|
def draw_text(self, x, y, string, rotate=False):
|
|
for c in string:
|
|
m = characters[c]
|
|
for cx in range(len(m[0])):
|
|
for cy in range(len(m)):
|
|
v = m[cy][cx]
|
|
if v == 9:
|
|
continue
|
|
if rotate:
|
|
gx = x + (len(m) - cy) + 1
|
|
gy = y + cx + 2
|
|
else:
|
|
gx = x + cx + 2
|
|
gy = y + cy + 2
|
|
pos = (self.width * gy) + gx
|
|
idx = pos * 4
|
|
a2 = (9.0 - v) / 9.0
|
|
r = (1.0 - a2) * self.buf[idx]
|
|
g = (1.0 - a2) * self.buf[idx + 1]
|
|
b = (1.0 - a2) * self.buf[idx + 2]
|
|
a1 = self.buf[idx + 3] / 255.0
|
|
a = a2 + a1 * (1.0 - a2)
|
|
try:
|
|
self.buf[idx] = int(r)
|
|
self.buf[idx + 1] = int(g)
|
|
self.buf[idx + 2] = int(b)
|
|
self.buf[idx + 3] = int(a * 255)
|
|
except IndexError:
|
|
pass
|
|
if rotate:
|
|
y += 11
|
|
else:
|
|
x += 11
|
|
|
|
|
|
def draw_guides(draw_buff, extends):
|
|
width = int(extends[2] - extends[0])
|
|
height = int(extends[3] - extends[1])
|
|
draw_buff.set_color(0, 0, 0, 255)
|
|
draw_buff.line_width = 1
|
|
min_x = int(extends[0])
|
|
min_y = int(extends[1])
|
|
points = 50
|
|
draw_buff.draw_text(0, 0, "mm")
|
|
for x in range(points - (min_x % points), width - 30, points):
|
|
if x < 30:
|
|
continue
|
|
draw_buff.draw_text(x, 0, str(int((x + min_x) / 10)), rotate=True)
|
|
draw_buff.draw_line(x, 0, x, 30)
|
|
for y in range(points - (min_y % points), height - 30, points):
|
|
if y < 30:
|
|
continue
|
|
draw_buff.draw_text(0, y, str(int((y + min_y) / 10)))
|
|
draw_buff.draw_line(0, y, 30, y)
|
|
|
|
|
|
def write(pattern, f, settings=None):
|
|
guides = settings.get("guides", False)
|
|
extends = pattern.bounds()
|
|
pattern.translate(-extends[0], -extends[1])
|
|
width = int(extends[2] - extends[0])
|
|
height = int(extends[3] - extends[1])
|
|
draw_buff = PngBuffer(width, height)
|
|
draw_buff.fancy = settings.get("fancy", False)
|
|
if settings is not None:
|
|
background = settings.get("background")
|
|
if background is not None:
|
|
b = EmbThread()
|
|
b.set(background)
|
|
draw_buff.background(b.get_red(), b.get_green(), b.get_blue(), 0xFF)
|
|
linewidth = settings.get("linewidth")
|
|
if linewidth is not None and isinstance(linewidth, int):
|
|
draw_buff.line_width = linewidth
|
|
|
|
for stitchblock in pattern.get_as_stitchblock():
|
|
block = stitchblock[0]
|
|
thread = stitchblock[1]
|
|
draw_buff.set_color(
|
|
thread.get_red(), thread.get_green(), thread.get_blue(), 255
|
|
)
|
|
last_x = None
|
|
last_y = None
|
|
for stitch in block:
|
|
x = int(stitch[0])
|
|
y = int(stitch[1])
|
|
if last_x is not None:
|
|
draw_buff.draw_line(last_x, last_y, x, y)
|
|
last_x = x
|
|
last_y = y
|
|
|
|
if guides:
|
|
draw_guides(draw_buff, extends)
|
|
|
|
f.write(write_png(draw_buff.buf, draw_buff.width, draw_buff.height))
|