Merge pull request #114 from EmbroidePy/1.4.28

Maintenance
pull/117/head 1.4.28
tatarize 2021-03-02 16:12:07 -08:00 zatwierdzone przez GitHub
commit e8bec2e035
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
65 zmienionych plików z 1755 dodań i 1294 usunięć

Wyświetl plik

@ -1 +0,0 @@
name = "pyembroidery"

Wyświetl plik

@ -23,8 +23,10 @@
# contents = compoundfiles.CompoundFileReader(f).open('Contents')
# contents.seek(4) # file size
# art = BytesIO(zlib.decompress(bytes([swizzle(b) for b in contents.read()])))
# while True:
# b = read_int_8(art)
# if b is None or b == -1:
# break
# print('%02X' % b)
# with open('file.bin', 'bw') as f:
# while True:
# b = read_int_8(art)
# if b is None or b == -1:
# break
# f.write(bytearray(chr(b), 'utf-8'))
# print('%02X' % b)

Wyświetl plik

@ -1,8 +1,8 @@
from .ReadHelper import read_int_16le, read_int_8, signed8, signed16
from .ReadHelper import read_int_8, read_int_16le, signed8, signed16
# Do you even embroider .bro?
def read_bro_stitches(f, out):
count = 0
while True:

Wyświetl plik

@ -5,9 +5,9 @@ READ_FILE_IN_TEXT_MODE = True
def read(f, out, settings=None):
count = int(f.readline())
for i in range(0,count):
for i in range(0, count):
line = f.readline()
splits = line.split(',')
splits = line.split(",")
thread = EmbThread()
thread.catalog_number = splits[0]
thread.set_color(int(splits[1]), int(splits[2]), int(splits[3]))

Wyświetl plik

@ -7,9 +7,9 @@ def write(pattern, f, settings=None):
write_string_utf8(f, "%d\r\n" % len(pattern.threadlist))
index = 0
for thread in pattern.threadlist:
write_string_utf8(f, "%d,%d,%d,%d\r\n" % (
index,
thread.get_red(),
thread.get_green(),
thread.get_blue()))
write_string_utf8(
f,
"%d,%d,%d,%d\r\n"
% (index, thread.get_red(), thread.get_green(), thread.get_blue()),
)
index += 1

Wyświetl plik

@ -5,13 +5,14 @@ READ_FILE_IN_TEXT_MODE = True
def read(f, out, settings=None):
import csv
csv_reader = csv.reader(f, delimiter=',')
csv_reader = csv.reader(f, delimiter=",")
command_dict = get_command_dictionary()
for row in csv_reader:
if len(row) == 0:
continue
if "*" in row[0]:
split = row[2].split(' ')
split = row[2].split(" ")
command = command_dict[split[0]]
for sp in split[1:]:
if sp[0] == "n":
@ -35,7 +36,12 @@ def read(f, out, settings=None):
out.metadata(row[1], row[2])
elif "$" in row[0]:
thread_add = {}
if len(row) == 7 and len(row[2]) <= 3 and len(row[3]) <= 3 and len(row[4]) <= 3:
if (
len(row) == 7
and len(row[2]) <= 3
and len(row[3]) <= 3
and len(row[4]) <= 3
):
# This is an embroidermodder csv file, I changed the colors and added more details.
# [THREAD_NUMBER], [RED], [GREEN], [BLUE], [DESCRIPTION], [CATALOG_NUMBER]\"\n");
thread_add["rgb"] = (int(row[2]), int(row[3]), int(row[4]))

Wyświetl plik

@ -13,8 +13,8 @@ def csv(f, values):
string = ""
for v in values:
if len(string) > 0:
string += ','
string += ('\"%s\"' % v)
string += ","
string += '"%s"' % v
write_string_utf8(f, string + "\n")
@ -38,19 +38,19 @@ def write_data(pattern, f):
width = extends[2] - extends[0]
height = extends[3] - extends[1]
csv(f, ('#', '[VAR_NAME]', '[VAR_VALUE]'))
csv(f, ("#", "[VAR_NAME]", "[VAR_VALUE]"))
count_stitches = pattern.count_stitches()
csv(f, ('>', 'STITCH_COUNT:', str(count_stitches)))
csv(f, (">", "STITCH_COUNT:", str(count_stitches)))
count_threads = pattern.count_color_changes()
csv(f, ('>', 'THREAD_COUNT:', str(count_threads)))
csv(f, (">", "THREAD_COUNT:", str(count_threads)))
count_set_needles = pattern.count_needle_sets()
csv(f, ('>', 'NEEDLE_COUNT:', str(count_set_needles)))
csv(f, ('>', 'EXTENTS_LEFT:', str(extends[0])))
csv(f, ('>', 'EXTENTS_TOP:', str(extends[1])))
csv(f, ('>', 'EXTENTS_RIGHT:', str(extends[2])))
csv(f, ('>', 'EXTENTS_BOTTOM:', str(extends[3])))
csv(f, ('>', 'EXTENTS_WIDTH:', str(width)))
csv(f, ('>', 'EXTENTS_HEIGHT:', str(height)))
csv(f, (">", "NEEDLE_COUNT:", str(count_set_needles)))
csv(f, (">", "EXTENTS_LEFT:", str(extends[0])))
csv(f, (">", "EXTENTS_TOP:", str(extends[1])))
csv(f, (">", "EXTENTS_RIGHT:", str(extends[2])))
csv(f, (">", "EXTENTS_BOTTOM:", str(extends[3])))
csv(f, (">", "EXTENTS_WIDTH:", str(width)))
csv(f, (">", "EXTENTS_HEIGHT:", str(height)))
stitch_counts = {}
for s in pattern.stitches:
@ -67,56 +67,50 @@ def write_data(pattern, f):
name = "COMMAND_" + names[the_key]
except (IndexError, KeyError):
name = "COMMAND_UNKNOWN_" + str(the_key)
csv(f, (
'>',
name,
str(the_value)
))
csv(f, (">", name, str(the_value)))
write_string_utf8(f, "\n")
def write_metadata(pattern, f):
if len(pattern.extras) > 0:
csv(f, (
'#',
'[METADATA_NAME]',
'[METADATA]'
))
csv(f, ("#", "[METADATA_NAME]", "[METADATA]"))
for the_key, the_value in pattern.extras.items():
if isinstance(the_value, tuple):
the_value = "\n" + get_graphic_as_string(the_value)
csv(f, (
'@',
str(the_key),
str(the_value)
))
csv(f, ("@", str(the_key), str(the_value)))
write_string_utf8(f, "\n")
def write_threads(pattern, f):
if len(pattern.threadlist) > 0:
csv(f, (
'#',
'[THREAD_NUMBER]',
'[HEX_COLOR]',
'[DESCRIPTION]',
'[BRAND]',
'[CATALOG_NUMBER]',
'[DETAILS]',
'[WEIGHT]'
))
csv(
f,
(
"#",
"[THREAD_NUMBER]",
"[HEX_COLOR]",
"[DESCRIPTION]",
"[BRAND]",
"[CATALOG_NUMBER]",
"[DETAILS]",
"[WEIGHT]",
),
)
for i, thread in enumerate(pattern.threadlist):
csv(f, (
'$',
str(i),
thread.hex_color(),
thread.description,
thread.brand,
thread.catalog_number,
thread.details,
thread.weight,
))
csv(
f,
(
"$",
str(i),
thread.hex_color(),
thread.description,
thread.brand,
thread.catalog_number,
thread.details,
thread.weight,
),
)
write_string_utf8(f, "\n")
@ -137,17 +131,20 @@ def decoded_name(names, data):
def write_stitches_displacement(pattern, f):
names = get_common_name_dictionary()
csv(f, (
'#',
'[STITCH_INDEX]',
'[STITCH_TYPE]',
'[X]',
'[Y]',
'[DX]',
'[DY]',
'[R]',
'[ANGLE]'
))
csv(
f,
(
"#",
"[STITCH_INDEX]",
"[STITCH_TYPE]",
"[X]",
"[Y]",
"[DX]",
"[DY]",
"[R]",
"[ANGLE]",
),
)
current_x = 0
current_y = 0
@ -155,69 +152,53 @@ def write_stitches_displacement(pattern, f):
name = decoded_name(names, stitch[2])
dx = stitch[0] - current_x
dy = stitch[1] - current_y
csv(f, (
'*',
str(i),
name,
str(stitch[0]),
str(stitch[1]),
str(dx),
str(dy),
str(distance(dx, dy)),
str(angle(dx, dy))
))
csv(
f,
(
"*",
str(i),
name,
str(stitch[0]),
str(stitch[1]),
str(dx),
str(dy),
str(distance(dx, dy)),
str(angle(dx, dy)),
),
)
current_x = stitch[0]
current_y = stitch[1]
def write_stitches_deltas(pattern, f):
names = get_common_name_dictionary()
csv(f, (
'#',
'[STITCH_INDEX]',
'[STITCH_TYPE]',
'[X]',
'[Y]',
'[DX]',
'[DY]'
))
csv(f, ("#", "[STITCH_INDEX]", "[STITCH_TYPE]", "[X]", "[Y]", "[DX]", "[DY]"))
current_x = 0
current_y = 0
for i, stitch in enumerate(pattern.stitches):
name = decoded_name(names, stitch[2])
dx = stitch[0] - current_x
dy = stitch[1] - current_y
csv(f, (
'*',
str(i),
name,
str(stitch[0]),
str(stitch[1]),
str(dx),
str(dy)
))
csv(f, ("*", str(i), name, str(stitch[0]), str(stitch[1]), str(dx), str(dy)))
current_x = stitch[0]
current_y = stitch[1]
def write_stitches(pattern, f):
names = get_common_name_dictionary()
csv(f, (
'#',
'[STITCH_INDEX]',
'[STITCH_TYPE]',
'[X]',
'[Y]'
))
csv(f, ("#", "[STITCH_INDEX]", "[STITCH_TYPE]", "[X]", "[Y]"))
for i, stitch in enumerate(pattern.stitches):
name = decoded_name(names, stitch[2])
csv(f, (
'*',
str(i),
name,
str(stitch[0]),
str(stitch[1]),
))
csv(
f,
(
"*",
str(i),
name,
str(stitch[0]),
str(stitch[1]),
),
)
def write(pattern, f, settings=None):

Wyświetl plik

@ -63,7 +63,9 @@ def read_barudan_dat(f, out):
if dx != 0 or dy != 0:
out.move(dx, dy)
continue
if command == 0x08: # ww, stop file had proper A8 rather than E8 and displacement
if (
command == 0x08
): # ww, stop file had proper A8 rather than E8 and displacement
# C00 Stop
out.stop()
if dx != 0 or dy != 0:

Wyświetl plik

@ -40,12 +40,8 @@ def process_header_info(out, prefix, value):
elif prefix == "CP":
out.metadata("copyright", value)
elif prefix == "TC":
values = [x.strip() for x in value.split(',')]
out.add_thread({
"hex": values[0],
"description": value[1],
"catalog": value[2]
})
values = [x.strip() for x in value.split(",")]
out.add_thread({"hex": values[0], "description": value[1], "catalog": value[2]})
else:
out.metadata(prefix, value)
@ -54,12 +50,14 @@ def dst_read_header(f, out):
header = f.read(512)
start = 0
for i, element in enumerate(header):
if element == 13 or element == 10 or element == '\n' or element == '\r': # 13 =='\r', 10 = '\n'
if (
element == 13 or element == 10 or element == "\n" or element == "\r"
): # 13 =='\r', 10 = '\n'
end = i
data = header[start:end]
start = end
try:
line = data.decode('utf8').strip()
line = data.decode("utf8").strip()
if len(line) > 3:
process_header_info(out, line[0:2].strip(), line[3:].strip())
except UnicodeDecodeError: # Non-utf8 information. See #83
@ -94,9 +92,9 @@ def dst_read_stitches(f, out, settings=None):
clipping = True
trim_distance = None
if settings is not None:
count_max = settings.get('trim_at', count_max)
count_max = settings.get("trim_at", count_max)
trim_distance = settings.get("trim_distance", trim_distance)
clipping = settings.get('clipping', clipping)
clipping = settings.get("clipping", clipping)
if trim_distance is not None:
trim_distance *= 10 # Pixels per mm. Native units are 1/10 mm.
out.interpolate_trims(count_max, trim_distance, clipping)

Wyświetl plik

@ -56,7 +56,9 @@ def encode_record(x, y, flags):
b0 += bit(1)
x += 1
if x != 0:
raise ValueError("The dx value given to the writer exceeds maximum allowed.")
raise ValueError(
"The dx value given to the writer exceeds maximum allowed."
)
if y > 40:
b2 += bit(5)
y -= 81
@ -88,7 +90,9 @@ def encode_record(x, y, flags):
b0 += bit(6)
y += 1
if y != 0:
raise ValueError("The dy value given to the writer exceeds maximum allowed.")
raise ValueError(
"The dy value given to the writer exceeds maximum allowed."
)
elif flags == COLOR_CHANGE:
b2 = 0b11000011
elif flags == STOP:
@ -104,7 +108,9 @@ def write(pattern, f, settings=None):
extended_header = False
trim_at = 3
if settings is not None:
extended_header = settings.get("extended header", extended_header) # deprecated, use version="extended"
extended_header = settings.get(
"extended header", extended_header
) # deprecated, use version="extended"
version = settings.get("version", "default")
if version == "extended":
extended_header = True
@ -147,13 +153,14 @@ def write(pattern, f, settings=None):
write_string_utf8(f, "CP:%s\r" % meta_copyright)
if len(pattern.threadlist) > 0:
for thread in pattern.threadlist:
write_string_utf8(f, "TC:%s,%s,%s\r" %
(thread.hex_color(),
thread.description,
thread.catalog_number))
f.write(b'\x1a')
write_string_utf8(
f,
"TC:%s,%s,%s\r"
% (thread.hex_color(), thread.description, thread.catalog_number),
)
f.write(b"\x1a")
for i in range(f.tell(), DSTHEADERSIZE):
f.write(b'\x20') # space
f.write(b"\x20") # space
stitches = pattern.stitches
xx = 0
@ -169,10 +176,10 @@ def write(pattern, f, settings=None):
yy += dy
if data == TRIM:
delta = -4
f.write(encode_record(-delta/2, -delta/2, JUMP))
for p in range(1,trim_at-1):
f.write(encode_record(-delta / 2, -delta / 2, JUMP))
for p in range(1, trim_at - 1):
f.write(encode_record(delta, delta, JUMP))
delta = -delta
f.write(encode_record(delta/2, delta/2, JUMP))
f.write(encode_record(delta / 2, delta / 2, JUMP))
else:
f.write(encode_record(dx, dy, data))

Wyświetl plik

@ -5,7 +5,10 @@ def expand(data, uncompressed_size=None):
def compress(data):
size = len(data)
return bytearray([(size >> 0) & 0xFF, (size >> 8) & 0xFF, 0x02, 0xA0, 0x01, 0xFE]) + data
return (
bytearray([(size >> 0) & 0xFF, (size >> 8) & 0xFF, 0x02, 0xA0, 0x01, 0xFE])
+ data
)
class Huffman:
@ -19,7 +22,7 @@ class Huffman:
"""Build an index huffman table based on the lengths. lowest index value wins in a tie."""
self.table_width = max(self.lengths)
self.table = []
size = (1 << self.table_width)
size = 1 << self.table_width
for bit_length in range(1, self.table_width + 1):
size /= 2.0
for len_index in range(0, len(self.lengths)):
@ -75,7 +78,9 @@ class EmbCompress:
m = self.pop(3)
if m != 7:
return m
for q in range(0, 13): # max read is 16 bit, 3 bits already used. It can't exceed 16-3
for q in range(
0, 13
): # max read is 16 bit, 3 bits already used. It can't exceed 16-3
s = self.pop(1)
if s == 1:
m += 1
@ -171,8 +176,10 @@ class EmbCompress:
self.input_data = input_data
output_data = []
self.block_elements = -1
bits_total = (len(input_data) * 8)
while bits_total > self.bit_position and (uncompressed_size is None or len(output_data) <= uncompressed_size):
bits_total = len(input_data) * 8
while bits_total > self.bit_position and (
uncompressed_size is None or len(output_data) <= uncompressed_size
):
character = self.get_token()
if character <= 255: # literal.
output_data.append(character)
@ -184,7 +191,7 @@ class EmbCompress:
position = len(output_data) - back
if back > length:
# Entire lookback is already within output data.
output_data += output_data[position:position + length]
output_data += output_data[position : position + length]
else:
# Will read & write the same data at some point.
for i in range(position, position + length):

Wyświetl plik

@ -8,8 +8,8 @@ class Transcoder:
def __init__(self, settings=None):
if settings is None:
settings = {}
self.max_stitch = settings.get("max_stitch", float('inf'))
self.max_jump = settings.get("max_jump", float('inf'))
self.max_stitch = settings.get("max_stitch", float("inf"))
self.max_jump = settings.get("max_jump", float("inf"))
self.full_jump = settings.get("full_jump", False)
self.round = settings.get("round", False)
self.needle_count = settings.get("needle_count", 5)
@ -22,7 +22,9 @@ class Transcoder:
self.sequin_contingency = CONTINGENCY_SEQUIN_JUMP
else:
self.sequin_contingency = CONTINGENCY_SEQUIN_UTILIZE
self.sequin_contingency = settings.get("sequin_contingency", self.sequin_contingency)
self.sequin_contingency = settings.get(
"sequin_contingency", self.sequin_contingency
)
self.writes_speeds = settings.get("writes_speeds", True)
self.explicit_trim = settings.get("explicit_trim", False)
@ -39,8 +41,9 @@ class Transcoder:
if self.tie_off_contingency is False:
self.tie_off_contingency = CONTINGENCY_TIE_OFF_NONE
self.long_stitch_contingency = \
settings.get("long_stitch_contingency", CONTINGENCY_LONG_STITCH_JUMP_NEEDLE)
self.long_stitch_contingency = settings.get(
"long_stitch_contingency", CONTINGENCY_LONG_STITCH_JUMP_NEEDLE
)
self.matrix = EmbMatrix()
translate = settings.get("translate", None)
@ -106,7 +109,12 @@ class Transcoder:
command = change[0]
flags = command & COMMAND_MASK
if current_index == 0:
if flags == STITCH or flags == SEW_TO or flags == NEEDLE_AT or flags == SEQUIN_EJECT:
if (
flags == STITCH
or flags == SEW_TO
or flags == NEEDLE_AT
or flags == SEQUIN_EJECT
):
current_index = 1
if flags == SET_CHANGE_SEQUENCE:
thread = change[1]
@ -126,7 +134,13 @@ class Transcoder:
change_sequence = {}
lookahead_index = 0
change_sequence[0] = [None, None, None, None]
for flags, thread, needle, order, current_index in self.get_as_thread_change_sequence_events():
for (
flags,
thread,
needle,
order,
current_index,
) in self.get_as_thread_change_sequence_events():
if flags == SET_CHANGE_SEQUENCE:
if order is None:
try:
@ -368,7 +382,7 @@ class Transcoder:
def lookahead_stitch(self):
"""Looks forward from current position and
determines if anymore stitching will occur."""
determines if anymore stitching will occur."""
source = self.source_pattern.stitches
for pos in range(self.position, len(source)):
stitch = source[pos]
@ -423,10 +437,15 @@ class Transcoder:
self.source_pattern.stitches[self.position - 1]
)
flags = b[2]
if flags == STITCH or flags == NEEDLE_AT or \
flags == SEW_TO or flags == SEQUIN_EJECT:
self.lock_stitch(self.needle_x, self.needle_y,
b[0], b[1], self.max_stitch)
if (
flags == STITCH
or flags == NEEDLE_AT
or flags == SEW_TO
or flags == SEQUIN_EJECT
):
self.lock_stitch(
self.needle_x, self.needle_y, b[0], b[1], self.max_stitch
)
except IndexError:
pass # must be an island stitch. jump-stitch-jump
@ -437,10 +456,15 @@ class Transcoder:
self.source_pattern.stitches[self.position + 1]
)
flags = b[2]
if flags == STITCH or flags == NEEDLE_AT or \
flags == SEW_TO or flags == SEQUIN_EJECT:
self.lock_stitch(self.needle_x, self.needle_y,
b[0], b[1], self.max_stitch)
if (
flags == STITCH
or flags == NEEDLE_AT
or flags == SEW_TO
or flags == SEQUIN_EJECT
):
self.lock_stitch(
self.needle_x, self.needle_y, b[0], b[1], self.max_stitch
)
except IndexError:
pass # must be an island stitch. jump-stitch-jump
@ -497,7 +521,7 @@ class Transcoder:
def sew_to(self, new_x, new_y):
"""Stitches to a specific location, with the emphasis on sewing.
Subdivides long stitches into additional stitches.
Subdivides long stitches into additional stitches.
"""
x0 = self.needle_x
y0 = self.needle_y
@ -637,11 +661,10 @@ class Transcoder:
p = oriented(x, y, anchor_x, anchor_y, max_length)
anchor_x = p[0]
anchor_y = p[1]
for amount in (.33, .66, .33, 0):
transcode.append([
towards(x, anchor_x, amount),
towards(y, anchor_y, amount),
STITCH])
for amount in (0.33, 0.66, 0.33, 0):
transcode.append(
[towards(x, anchor_x, amount), towards(y, anchor_y, amount), STITCH]
)
def distance_squared(x0, y0, x1, y1):

Wyświetl plik

@ -123,5 +123,5 @@ def get_common_name_dictionary():
OPTION_EXPLICIT_TRIM: "OPTION_EXPLICIT_TRIM",
CONTINGENCY_LONG_STITCH_NONE: "CONTINGENCY_LONG_STITCH_NONE",
CONTINGENCY_LONG_STITCH_JUMP_NEEDLE: "CONTINGENCY_LONG_STITCH_JUMP_NEEDLE",
CONTINGENCY_LONG_STITCH_SEW_TO: "CONTINGENCY_LONG_STITCH_SEW_TO"
CONTINGENCY_LONG_STITCH_SEW_TO: "CONTINGENCY_LONG_STITCH_SEW_TO",
}

Wyświetl plik

@ -106,7 +106,7 @@ class EmbMatrix:
return [
v0[0] * m[0] + v0[1] * m[3] + 1 * m[6],
v0[0] * m[1] + v0[1] * m[4] + 1 * m[7],
v0[2]
v0[2],
]
except IndexError:
return [
@ -114,10 +114,7 @@ class EmbMatrix:
v0[0] * m[1] + v0[1] * m[4] + 1 * m[7]
# Must not have had a 3rd element.
]
return [
v0 * m[0] + v1 * m[3] + 1 * m[6],
v0 * m[1] + v1 * m[4] + 1 * m[7]
]
return [v0 * m[0] + v1 * m[3] + 1 * m[6], v0 * m[1] + v1 * m[4] + 1 * m[7]]
def apply(self, v):
m = self.m
@ -128,26 +125,17 @@ class EmbMatrix:
@staticmethod
def get_identity():
return \
1, 0, 0, \
0, 1, 0, \
0, 0, 1 # identity
return 1, 0, 0, 0, 1, 0, 0, 0, 1 # identity
@staticmethod
def get_scale(sx, sy=None):
if sy is None:
sy = sx
return \
sx, 0, 0, \
0, sy, 0, \
0, 0, 1
return sx, 0, 0, 0, sy, 0, 0, 0, 1
@staticmethod
def get_translate(tx, ty):
return \
1, 0, 0, \
0, 1, 0, \
tx, ty, 1
return 1, 0, 0, 0, 1, 0, tx, ty, 1
@staticmethod
def get_rotate(theta):
@ -155,10 +143,7 @@ class EmbMatrix:
theta *= tau / 360
ct = math.cos(theta)
st = math.sin(theta)
return \
ct, st, 0, \
-st, ct, 0, \
0, 0, 1
return ct, st, 0, -st, ct, 0, 0, 0, 1
@staticmethod
def matrix_multiply(m0, m1):
@ -171,4 +156,5 @@ class EmbMatrix:
m1[3] * m0[2] + m1[4] * m0[5] + m1[5] * m0[8],
m1[6] * m0[0] + m1[7] * m0[3] + m1[8] * m0[6],
m1[6] * m0[1] + m1[7] * m0[4] + m1[8] * m0[7],
m1[6] * m0[2] + m1[7] * m0[5] + m1[8] * m0[8]]
m1[6] * m0[2] + m1[7] * m0[5] + m1[8] * m0[8],
]

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,8 +1,9 @@
def build_unique_palette(thread_palette, threadlist):
"""Turns a threadlist into a unique index list with the thread palette"""
chart = [None] * len(thread_palette) # Create a lookup chart.
for thread in set(threadlist): # for each unique color, move closest remaining thread to lookup chart.
for thread in set(
threadlist
): # for each unique color, move closest remaining thread to lookup chart.
index = thread.find_nearest_color_index(thread_palette)
if index is None:
break # No more threads remain in palette
@ -45,21 +46,17 @@ def build_nonrepeat_palette(thread_palette, threadlist):
def find_nearest_color_index(find_color, values):
if isinstance(find_color, EmbThread):
find_color = find_color.color
red = (find_color >> 16) & 0xff
green = (find_color >> 8) & 0xff
blue = find_color & 0xff
red = (find_color >> 16) & 0xFF
green = (find_color >> 8) & 0xFF
blue = find_color & 0xFF
closest_index = None
current_closest_value = float("inf")
for current_index, t in enumerate(values):
if t is None:
continue
dist = color_distance_red_mean(
red,
green,
blue,
t.get_red(),
t.get_green(),
t.get_blue())
red, green, blue, t.get_red(), t.get_green(), t.get_blue()
)
if dist <= current_closest_value: # <= choose second if they tie.
current_closest_value = dist
closest_index = current_index
@ -67,13 +64,11 @@ def find_nearest_color_index(find_color, values):
def color_rgb(r, g, b):
return int(((r & 255) << 16) |
((g & 255) << 8) |
(b & 255))
return int(((r & 255) << 16) | ((g & 255) << 8) | (b & 255))
def color_hex(hex_string):
h = hex_string.lstrip('#')
h = hex_string.lstrip("#")
size = len(h)
if size == 6 or size == 8:
return int(h[:6], 16)
@ -81,22 +76,31 @@ def color_hex(hex_string):
return int(h[0] + h[0] + h[1] + h[1] + h[2] + h[2], 16)
def color_distance_red_mean(
r1, g1, b1,
r2, g2, b2):
def color_distance_red_mean(r1, g1, b1, r2, g2, b2):
red_mean = int(round((r1 + r2) / 2))
r = int(r1 - r2)
g = int(g1 - g2)
b = int(b1 - b2)
return (((512 + red_mean) * r * r) >> 8) + 4 * g * g + \
(((767 - red_mean) * b * b) >> 8)
return (
(((512 + red_mean) * r * r) >> 8)
+ 4 * g * g
+ (((767 - red_mean) * b * b) >> 8)
)
# See the very good color distance paper:
# https://www.compuphase.com/cmetric.htm
class EmbThread:
def __init__(self, thread=None, description=None, catalog_number=None, details=None, brand=None, chart=None, weight=None):
def __init__(
self,
thread=None,
description=None,
catalog_number=None,
details=None,
brand=None,
chart=None,
weight=None,
):
self.color = 0x000000
self.description = description # type: str
self.catalog_number = catalog_number # type: str
@ -135,10 +139,16 @@ class EmbThread:
return self.color & 0xFFFFFF == other & 0xFFFFFF
try:
if isinstance(other, basestring):
return self.color & 0xFFFFFF == EmbThread.parse_string_color(other) & 0xFFFFFF
return (
self.color & 0xFFFFFF
== EmbThread.parse_string_color(other) & 0xFFFFFF
)
except NameError:
if isinstance(other, str):
return self.color & 0xFFFFFF == EmbThread.parse_string_color(other) & 0xFFFFFF
return (
self.color & 0xFFFFFF
== EmbThread.parse_string_color(other) & 0xFFFFFF
)
if not isinstance(other, EmbThread):
return False
if self.color & 0xFFFFFF != other.color & 0xFFFFFF:
@ -188,9 +198,7 @@ class EmbThread:
return find_nearest_color_index(int(self.color), values)
def hex_color(self):
return "#%02x%02x%02x" % (
self.get_red(), self.get_green(), self.get_blue()
)
return "#%02x%02x%02x" % (self.get_red(), self.get_green(), self.get_blue())
def set_hex_color(self, hex_string):
self.color = color_hex(hex_string)
@ -225,9 +233,11 @@ class EmbThread:
if isinstance(color, int):
self.color = color
elif isinstance(color, tuple) or isinstance(color, list):
self.color = (color[0] & 0xFF) << 16 | \
(color[1] & 0xFF) << 8 | \
(color[2] & 0xFF)
self.color = (
(color[0] & 0xFF) << 16
| (color[1] & 0xFF) << 8
| (color[2] & 0xFF)
)
else:
try:
if isinstance(color, basestring):
@ -258,6 +268,7 @@ class EmbThread:
def parse_string_color(color):
if color == "random":
import random
return random.randint(0, 0xFFFFFF)
if color[0:1] == "#":
return color_hex(color[1:])
@ -408,7 +419,7 @@ class EmbThread:
"white": color_rgb(255, 255, 255),
"whitesmoke": color_rgb(245, 245, 245),
"yellow": color_rgb(255, 255, 0),
"yellowgreen": color_rgb(154, 205, 50)
"yellowgreen": color_rgb(154, 205, 50),
}
return color_dict.get(color.lower(), 0x000000)
# return color or black.

Wyświetl plik

@ -31,7 +31,7 @@ def get_thread_set():
EmbThreadHus("#ff52b5", "Dark Pink", "010"),
EmbThreadHus("#ffc6de", "Light Pink", "012"),
EmbThreadHus("#523100", "Dark Brown", "027"),
EmbThreadHus("#b5a584", "Light Brown", "029")
EmbThreadHus("#b5a584", "Light Brown", "029"),
]
@ -43,4 +43,3 @@ class EmbThreadHus(EmbThread):
self.catalog_number = catalog_number
self.brand = "Hus"
self.chart = "Hus"

Wyświetl plik

@ -3,85 +3,85 @@ from .EmbThread import EmbThread
def get_thread_set():
return [
None, #EmbThreadJef(0x000000, "Placeholder", "000"),
None, # EmbThreadJef(0x000000, "Placeholder", "000"),
EmbThreadJef(0x000000, "Black", "002"),
EmbThreadJef(0xffffff, "White", "001"),
EmbThreadJef(0xffff17, "Yellow", "204"),
EmbThreadJef(0xff6600, "Orange", "203"),
EmbThreadJef(0x2f5933, "Olive Green", "219"),
EmbThreadJef(0xFFFFFF, "White", "001"),
EmbThreadJef(0xFFFF17, "Yellow", "204"),
EmbThreadJef(0xFF6600, "Orange", "203"),
EmbThreadJef(0x2F5933, "Olive Green", "219"),
EmbThreadJef(0x237336, "Green", "226"),
EmbThreadJef(0x65c2c8, "Sky", "217"),
EmbThreadJef(0xab5a96, "Purple", "208"),
EmbThreadJef(0xf669a0, "Pink", "201"),
EmbThreadJef(0xff0000, "Red", "225"),
EmbThreadJef(0xb1704e, "Brown", "214"),
EmbThreadJef(0x0b2f84, "Blue", "207"),
EmbThreadJef(0xe4c35d, "Gold", "003"),
EmbThreadJef(0x481a05, "Dark Brown", "205"),
EmbThreadJef(0xac9cc7, "Pale Violet", "209"),
EmbThreadJef(0xfcf294, "Pale Yellow", "210"),
EmbThreadJef(0xf999b7, "Pale Pink", "211"),
EmbThreadJef(0xfab381, "Peach", "212"),
EmbThreadJef(0xc9a480, "Beige", "213"),
EmbThreadJef(0x65C2C8, "Sky", "217"),
EmbThreadJef(0xAB5A96, "Purple", "208"),
EmbThreadJef(0xF669A0, "Pink", "201"),
EmbThreadJef(0xFF0000, "Red", "225"),
EmbThreadJef(0xB1704E, "Brown", "214"),
EmbThreadJef(0x0B2F84, "Blue", "207"),
EmbThreadJef(0xE4C35D, "Gold", "003"),
EmbThreadJef(0x481A05, "Dark Brown", "205"),
EmbThreadJef(0xAC9CC7, "Pale Violet", "209"),
EmbThreadJef(0xFCF294, "Pale Yellow", "210"),
EmbThreadJef(0xF999B7, "Pale Pink", "211"),
EmbThreadJef(0xFAB381, "Peach", "212"),
EmbThreadJef(0xC9A480, "Beige", "213"),
EmbThreadJef(0x970533, "Wine Red", "215"),
EmbThreadJef(0xa0b8cc, "Pale Sky", "216"),
EmbThreadJef(0x7fc21c, "Yellow Green", "218"),
EmbThreadJef(0xe5e5e5, "Silver Gray", "220"),
EmbThreadJef(0x889b9b, "Gray", "221"),
EmbThreadJef(0x98d6bd, "Pale Aqua", "227"),
EmbThreadJef(0xb2e1e3, "Baby Blue", "228"),
EmbThreadJef(0x368ba0, "Powder Blue", "229"),
EmbThreadJef(0x4f83ab, "Bright Blue", "230"),
EmbThreadJef(0x386a91, "Slate Blue", "231"),
EmbThreadJef(0xA0B8CC, "Pale Sky", "216"),
EmbThreadJef(0x7FC21C, "Yellow Green", "218"),
EmbThreadJef(0xE5E5E5, "Silver Gray", "220"),
EmbThreadJef(0x889B9B, "Gray", "221"),
EmbThreadJef(0x98D6BD, "Pale Aqua", "227"),
EmbThreadJef(0xB2E1E3, "Baby Blue", "228"),
EmbThreadJef(0x368BA0, "Powder Blue", "229"),
EmbThreadJef(0x4F83AB, "Bright Blue", "230"),
EmbThreadJef(0x386A91, "Slate Blue", "231"),
EmbThreadJef(0x071650, "Navy Blue", "232"),
EmbThreadJef(0xf999a2, "Salmon Pink", "233"),
EmbThreadJef(0xf9676b, "Coral", "234"),
EmbThreadJef(0xe3311f, "Burnt Orange", "235"),
EmbThreadJef(0xe2a188, "Cinnamon", "236"),
EmbThreadJef(0xb59474, "Umber", "237"),
EmbThreadJef(0xe4cf99, "Blond", "238"),
EmbThreadJef(0xffcb00, "Sunflower", "239"),
EmbThreadJef(0xe1add4, "Orchid Pink", "240"),
EmbThreadJef(0xc3007e, "Peony Purple", "241"),
EmbThreadJef(0x80004b, "Burgundy", "242"),
EmbThreadJef(0xF999A2, "Salmon Pink", "233"),
EmbThreadJef(0xF9676B, "Coral", "234"),
EmbThreadJef(0xE3311F, "Burnt Orange", "235"),
EmbThreadJef(0xE2A188, "Cinnamon", "236"),
EmbThreadJef(0xB59474, "Umber", "237"),
EmbThreadJef(0xE4CF99, "Blond", "238"),
EmbThreadJef(0xFFCB00, "Sunflower", "239"),
EmbThreadJef(0xE1ADD4, "Orchid Pink", "240"),
EmbThreadJef(0xC3007E, "Peony Purple", "241"),
EmbThreadJef(0x80004B, "Burgundy", "242"),
EmbThreadJef(0x540571, "Royal Purple", "243"),
EmbThreadJef(0xb10525, "Cardinal Red", "244"),
EmbThreadJef(0xcae0c0, "Opal Green", "245"),
EmbThreadJef(0xB10525, "Cardinal Red", "244"),
EmbThreadJef(0xCAE0C0, "Opal Green", "245"),
EmbThreadJef(0x899856, "Moss Green", "246"),
EmbThreadJef(0x5c941a, "Meadow Green", "247"),
EmbThreadJef(0x5C941A, "Meadow Green", "247"),
EmbThreadJef(0x003114, "Dark Green", "248"),
EmbThreadJef(0x5dae94, "Aquamarine", "249"),
EmbThreadJef(0x4cbf8f, "Emerald Green", "250"),
EmbThreadJef(0x5DAE94, "Aquamarine", "249"),
EmbThreadJef(0x4CBF8F, "Emerald Green", "250"),
EmbThreadJef(0x007772, "Peacock Green", "251"),
EmbThreadJef(0x595b61, "Dark Gray", "252"),
EmbThreadJef(0xfffff2, "Ivory White", "253"),
EmbThreadJef(0xb15818, "Hazel", "254"),
EmbThreadJef(0xcb8a07, "Toast", "255"),
EmbThreadJef(0x986c80, "Salmon", "256"),
EmbThreadJef(0x98692d, "Cocoa Brown", "257"),
EmbThreadJef(0x4d3419, "Sienna", "258"),
EmbThreadJef(0x4c330b, "Sepia", "259"),
EmbThreadJef(0x33200a, "Dark Sepia", "260"),
EmbThreadJef(0x523a97, "Violet Blue", "261"),
EmbThreadJef(0x0d217e, "Blue Ink", "262"),
EmbThreadJef(0x1e77ac, "Sola Blue", "263"),
EmbThreadJef(0xb2dd53, "Green Dust", "264"),
EmbThreadJef(0xf33689, "Crimson", "265"),
EmbThreadJef(0xde649e, "Floral Pink", "266"),
EmbThreadJef(0x595B61, "Dark Gray", "252"),
EmbThreadJef(0xFFFFF2, "Ivory White", "253"),
EmbThreadJef(0xB15818, "Hazel", "254"),
EmbThreadJef(0xCB8A07, "Toast", "255"),
EmbThreadJef(0x986C80, "Salmon", "256"),
EmbThreadJef(0x98692D, "Cocoa Brown", "257"),
EmbThreadJef(0x4D3419, "Sienna", "258"),
EmbThreadJef(0x4C330B, "Sepia", "259"),
EmbThreadJef(0x33200A, "Dark Sepia", "260"),
EmbThreadJef(0x523A97, "Violet Blue", "261"),
EmbThreadJef(0x0D217E, "Blue Ink", "262"),
EmbThreadJef(0x1E77AC, "Sola Blue", "263"),
EmbThreadJef(0xB2DD53, "Green Dust", "264"),
EmbThreadJef(0xF33689, "Crimson", "265"),
EmbThreadJef(0xDE649E, "Floral Pink", "266"),
EmbThreadJef(0x984161, "Wine", "267"),
EmbThreadJef(0x4c5612, "Olive Drab", "268"),
EmbThreadJef(0x4c881f, "Meadow", "269"),
EmbThreadJef(0xe4de79, "Mustard", "270"),
EmbThreadJef(0xcb8a1a, "Yellow Ocher", "271"),
EmbThreadJef(0xcba21c, "Old Gold", "272"),
EmbThreadJef(0xff9805, "Honey Dew", "273"),
EmbThreadJef(0xfcb257, "Tangerine", "274"),
EmbThreadJef(0xffe505, "Canary Yellow", "275"),
EmbThreadJef(0xf0331f, "Vermilion", "202"),
EmbThreadJef(0x1a842d, "Bright Green", "206"),
EmbThreadJef(0x386cae, "Ocean Blue", "222"),
EmbThreadJef(0xe3c4b4, "Beige Gray", "223"),
EmbThreadJef(0xe3ac81, "Bamboo", "224")
EmbThreadJef(0x4C5612, "Olive Drab", "268"),
EmbThreadJef(0x4C881F, "Meadow", "269"),
EmbThreadJef(0xE4DE79, "Mustard", "270"),
EmbThreadJef(0xCB8A1A, "Yellow Ocher", "271"),
EmbThreadJef(0xCBA21C, "Old Gold", "272"),
EmbThreadJef(0xFF9805, "Honey Dew", "273"),
EmbThreadJef(0xFCB257, "Tangerine", "274"),
EmbThreadJef(0xFFE505, "Canary Yellow", "275"),
EmbThreadJef(0xF0331F, "Vermilion", "202"),
EmbThreadJef(0x1A842D, "Bright Green", "206"),
EmbThreadJef(0x386CAE, "Ocean Blue", "222"),
EmbThreadJef(0xE3C4B4, "Beige Gray", "223"),
EmbThreadJef(0xE3AC81, "Bamboo", "224"),
]

Wyświetl plik

@ -3,7 +3,7 @@ from .EmbThread import EmbThread
def get_thread_set():
return [
None, # EmbThreadPec(0, 0, 0, "Unknown", "0"),
None, # EmbThreadPec(0, 0, 0, "Unknown", "0"),
EmbThreadPec(14, 31, 124, "Prussian Blue", "1"),
EmbThreadPec(10, 85, 163, "Blue", "2"),
EmbThreadPec(0, 135, 119, "Teal Green", "3"),
@ -67,7 +67,7 @@ def get_thread_set():
EmbThreadPec(227, 243, 91, "Fresh Green", "61"),
EmbThreadPec(255, 153, 0, "Orange", "62"),
EmbThreadPec(255, 240, 141, "Cream Yellow", "63"),
EmbThreadPec(255, 200, 200, "Applique", "64")
EmbThreadPec(255, 200, 200, "Applique", "64"),
]

Wyświetl plik

@ -45,7 +45,7 @@ def get_thread_set():
EmbThreadShv(0, 0, 0, "Black", "39"),
EmbThreadShv(0, 0, 0, "Black", "40"),
EmbThreadShv(232, 63, 0, "Dark Orange", "41"),
EmbThreadShv(255, 102, 122, "Dark Pink", "42")
EmbThreadShv(255, 102, 122, "Dark Pink", "42"),
]

Wyświetl plik

@ -27,16 +27,16 @@ def write(pattern, f, settings=None):
elif data == JUMP:
delta_x = dx & 0xFF
delta_y = -dy & 0xFF
f.write(b'\x80\x04')
f.write(b"\x80\x04")
f.write(bytes(bytearray([delta_x, delta_y])))
elif data == TRIM:
f.write(b'\x80\x80\x07\x00')
f.write(b"\x80\x80\x07\x00")
continue
elif data == COLOR_CHANGE:
f.write(b'\x80\x01\x00\x00')
f.write(b"\x80\x01\x00\x00")
continue
elif data == STOP:
f.write(b'\x80\x01\x00\x00')
f.write(b"\x80\x01\x00\x00")
continue
elif data == END:
pass

Wyświetl plik

@ -3,47 +3,44 @@ def parse(f):
code = ""
value = ""
command_map = {}
ord_a = ord('a')
ord_A = ord('A')
ord_z = ord('z')
ord_Z = ord('Z')
ord_a = ord("a")
ord_A = ord("A")
ord_z = ord("z")
ord_Z = ord("Z")
while True:
byte = f.read(1)
if byte is None:
break
if len(byte) == 0:
break
is_end = byte == b'\n' or byte == b'\r'
is_end = byte == b"\n" or byte == b"\r"
if comment is not None:
if byte == b')' or is_end:
command_map['comment'] = comment
if byte == b")" or is_end:
command_map["comment"] = comment
comment = None
if not is_end:
continue
else:
try:
comment += byte.decode('utf8')
comment += byte.decode("utf8")
except UnicodeDecodeError:
pass # skip utf8 fail
continue
if byte == b'(':
if byte == b"(":
comment = ""
continue
elif byte == b';':
elif byte == b";":
comment = ""
continue
elif byte == b'\t':
elif byte == b"\t":
continue
elif byte == b' ':
elif byte == b" ":
continue
elif byte == b'/' and len(code) == 0:
elif byte == b"/" and len(code) == 0:
continue
b = ord(byte)
if ord('0') <= b <= ord('9') \
or byte == b'+' \
or byte == b'-' \
or byte == b'.':
value += byte.decode('utf8')
if ord("0") <= b <= ord("9") or byte == b"+" or byte == b"-" or byte == b".":
value += byte.decode("utf8")
continue
if ord_A <= b <= ord_Z:
@ -73,29 +70,29 @@ def read(f, out, settings=None):
flip_y = -1 # Assumes the Gcode is flip_y, -1 is flip, 1 is normal
scale = 10.0 # Initially assume mm mode G20.
for gc in parse(f):
if 'comment' in gc:
comment = gc['comment']
if 'Thread' in comment:
if "comment" in gc:
comment = gc["comment"]
if "Thread" in comment:
split = comment.split(" ")
out.add_thread(split[1])
if 'g' in gc:
if 'x' in gc and 'y' in gc and gc['g'] == 0.0 or gc['g'] == 1.0:
if "g" in gc:
if "x" in gc and "y" in gc and gc["g"] == 0.0 or gc["g"] == 1.0:
if absolute_mode:
out.stitch_abs(gc['x'] * scale * flip_x, gc['y'] * scale * flip_y)
out.stitch_abs(gc["x"] * scale * flip_x, gc["y"] * scale * flip_y)
else:
out.stitch(gc['x'] * scale * flip_x, gc['y'] * scale * flip_y)
out.stitch(gc["x"] * scale * flip_x, gc["y"] * scale * flip_y)
continue
if gc['g'] == 21.0 or gc['g'] == 71.0:
if gc["g"] == 21.0 or gc["g"] == 71.0:
scale = 10.0 # g20 is mm mode. 10 1/10th mm in a mm.
elif gc['g'] == 20.0 or gc['g'] == 70.0:
elif gc["g"] == 20.0 or gc["g"] == 70.0:
scale = 254 # g20 is inch mode. 254 1/10th mm in an inch.
elif gc['g'] == 90.0:
elif gc["g"] == 90.0:
absolute_mode = True
elif gc['g'] == 91.0:
elif gc["g"] == 91.0:
absolute_mode = False
if 'm' in gc:
v = gc['m']
if "m" in gc:
v = gc["m"]
if v == 30 or v == 2:
out.end()
elif v == 0 or v == 1:

Wyświetl plik

@ -12,14 +12,14 @@ def write_data(pattern, f):
count_stitches = pattern.count_stitches()
count_threads = pattern.count_color_changes()
write_string_utf8(f, '(STITCH_COUNT: %d)\n' % count_stitches)
write_string_utf8(f, '(THREAD_COUNT: %d)\n' % count_threads)
write_string_utf8(f, '(EXTENTS_LEFT: %.3f)\n' % bounds[0])
write_string_utf8(f, '(EXTENTS_TOP: %.3f)\n' % bounds[1])
write_string_utf8(f, '(EXTENTS_RIGHT: %.3f)\n' % bounds[2])
write_string_utf8(f, '(EXTENTS_BOTTOM: %.3f)\n' % bounds[3])
write_string_utf8(f, '(EXTENTS_WIDTH: %.3f)\n' % width)
write_string_utf8(f, '(EXTENTS_HEIGHT: %.3f)\n' % height)
write_string_utf8(f, "(STITCH_COUNT: %d)\n" % count_stitches)
write_string_utf8(f, "(THREAD_COUNT: %d)\n" % count_threads)
write_string_utf8(f, "(EXTENTS_LEFT: %.3f)\n" % bounds[0])
write_string_utf8(f, "(EXTENTS_TOP: %.3f)\n" % bounds[1])
write_string_utf8(f, "(EXTENTS_RIGHT: %.3f)\n" % bounds[2])
write_string_utf8(f, "(EXTENTS_BOTTOM: %.3f)\n" % bounds[3])
write_string_utf8(f, "(EXTENTS_WIDTH: %.3f)\n" % width)
write_string_utf8(f, "(EXTENTS_HEIGHT: %.3f)\n" % height)
stitch_counts = {}
for s in pattern.stitches:
@ -37,7 +37,7 @@ def write_data(pattern, f):
name = "COMMAND_" + names[the_key]
except (IndexError, KeyError):
name = "COMMAND_UNKNOWN_" + str(the_key)
write_string_utf8(f, '(%s: %d)\n' % (name, the_value))
write_string_utf8(f, "(%s: %d)\n" % (name, the_value))
def write_metadata(pattern, f):
@ -45,28 +45,32 @@ def write_metadata(pattern, f):
for the_key, the_value in pattern.extras.items():
try:
if isinstance(the_value, basestring):
write_string_utf8(f, '(%s: %s)\n' % (the_key, the_value))
write_string_utf8(f, "(%s: %s)\n" % (the_key, the_value))
except NameError:
if isinstance(the_value, str):
write_string_utf8(f, '(%s: %s)\n' % (the_key, the_value))
write_string_utf8(f, "(%s: %s)\n" % (the_key, the_value))
def write_threads(pattern, f):
if len(pattern.threadlist) > 0:
for i, thread in enumerate(pattern.threadlist):
write_string_utf8(f, '(Thread%d: %s %s %s %s)\n' % (
i,
thread.hex_color(),
thread.description,
thread.brand,
thread.catalog_number,
))
write_string_utf8(
f,
"(Thread%d: %s %s %s %s)\n"
% (
i,
thread.hex_color(),
thread.description,
thread.brand,
thread.catalog_number,
),
)
def write(pattern, f, settings=None):
if settings is None:
settings = {}
increment_value = settings.get('stitch_z_travel', 10.0)
increment_value = settings.get("stitch_z_travel", 10.0)
write_data(pattern, f)
write_metadata(pattern, f)
write_threads(pattern, f)
@ -78,7 +82,7 @@ def write(pattern, f, settings=None):
cmd = decode_embroidery_command(stitch[2])
command = cmd[0]
if command == STITCH:
write_string_utf8(f, 'G00 X%.3f Y%.3f\nG00 Z%.1f\n' % (x, y, z))
write_string_utf8(f, "G00 X%.3f Y%.3f\nG00 Z%.1f\n" % (x, y, z))
z += increment_value
continue
elif command == JUMP:
@ -86,12 +90,12 @@ def write(pattern, f, settings=None):
elif command == TRIM:
continue
elif command == COLOR_CHANGE:
write_string_utf8(f, 'M00\n')
write_string_utf8(f, "M00\n")
continue
elif command == STOP:
write_string_utf8(f, 'M00\n')
write_string_utf8(f, "M00\n")
continue
elif command == END:
write_string_utf8(f, 'M30\n')
write_string_utf8(f, "M30\n")
continue
break # Code shouldn't reach this point.

Wyświetl plik

@ -1,6 +1,6 @@
from .EmbCompress import expand
from .EmbThreadHus import get_thread_set
from .ReadHelper import signed8, signed16, read_int_32le, read_int_16le, read_string_8
from .ReadHelper import read_int_16le, read_int_32le, read_string_8, signed8, signed16
def read(f, out, settings=None):
@ -36,7 +36,9 @@ def read(f, out, settings=None):
x_decompressed = expand(x_compressed, number_of_stitches)
y_decompressed = expand(y_compressed, number_of_stitches)
stitch_count = min(len(command_decompressed), len(x_decompressed), len(y_decompressed))
stitch_count = min(
len(command_decompressed), len(x_decompressed), len(y_decompressed)
)
for i in range(0, stitch_count):
cmd = command_decompressed[i]

Wyświetl plik

@ -1,5 +1,5 @@
from .EmbThread import EmbThread
from .ReadHelper import read_int_32be, read_int_16be
from .ReadHelper import read_int_16be, read_int_32be
def read(f, out, settings=None):
@ -21,12 +21,12 @@ def read(f, out, settings=None):
for j in range(0, len(byte_data)):
b = byte_data[j]
if b == 0:
thread.description = byte_data[:j].decode('utf8')
byte_data = byte_data[j+1:]
thread.description = byte_data[:j].decode("utf8")
byte_data = byte_data[j + 1 :]
break
for j in range(0, len(byte_data)):
b = byte_data[j]
if b == 0:
thread.chart = byte_data[:j].decode('utf8')
thread.chart = byte_data[:j].decode("utf8")
break
out.add_thread(thread)

Wyświetl plik

@ -1,4 +1,4 @@
from .WriteHelper import write_int_8, write_int_32be, write_int_16be, write_string_utf8
from .WriteHelper import write_int_8, write_int_16be, write_int_32be, write_string_utf8
ENCODE = False
@ -25,7 +25,9 @@ def write(pattern, f, settings=None):
chart = thread.chart
if chart is None:
chart = "Unknown"
write_int_16be(f, 11 + len(details) + len(chart)) # 2 + 2 + 1 + 1 + 1 + 2 + d + 1 + c + 1 = 11 + d + c
write_int_16be(
f, 11 + len(details) + len(chart)
) # 2 + 2 + 1 + 1 + 1 + 2 + d + 1 + c + 1 = 11 + d + c
write_int_16be(f, index) # record index
index += 1
write_int_8(f, thread.get_red())

Wyświetl plik

@ -34,14 +34,14 @@ def read_jef_stitches(f, out, settings=None):
count_max = None
trim_distance = 3.0
if settings is not None:
count_max = settings.get('trim_at', count_max)
count_max = settings.get("trim_at", count_max)
trims = settings.get("trims", trims)
trim_distance = settings.get("trim_distance", trim_distance)
clipping = settings.get('clipping', clipping)
clipping = settings.get("clipping", clipping)
if trims and count_max is None:
count_max = 3
if trim_distance is not None:
trim_distance *= 10 # Pixels per mm. Native units are 1/10 mm.
trim_distance *= 10 # Pixels per mm. Native units are 1/10 mm.
out.interpolate_trims(count_max, trim_distance, clipping)

Wyświetl plik

@ -1,9 +1,9 @@
import datetime
from .EmbThread import build_nonrepeat_palette
from .EmbConstant import *
from .EmbThread import build_nonrepeat_palette
from .EmbThreadJef import get_thread_set
from .WriteHelper import write_string_utf8, write_int_32le, write_int_8
from .WriteHelper import write_int_8, write_int_32le, write_string_utf8
SEQUIN_CONTINGENCY = CONTINGENCY_SEQUIN_JUMP
FULL_JUMP = True
@ -23,10 +23,10 @@ def write(pattern, f, settings=None):
trims = False
command_count_max = 3
date_string = datetime.datetime.today().strftime('%Y%m%d%H%M%S')
date_string = datetime.datetime.today().strftime("%Y%m%d%H%M%S")
if settings is not None:
trims = settings.get("trims", trims)
command_count_max = settings.get('trim_at', command_count_max)
command_count_max = settings.get("trim_at", command_count_max)
date_string = settings.get("date", date_string)
pattern.fix_color_count()
@ -47,7 +47,7 @@ def write(pattern, f, settings=None):
point_count += 2
elif data == TRIM:
if trims:
point_count += (2 * command_count_max)
point_count += 2 * command_count_max
elif data == COLOR_CHANGE:
point_count += 2
elif data == END:
@ -110,22 +110,22 @@ def write(pattern, f, settings=None):
write_int_8(f, -dy)
continue
elif data == COLOR_CHANGE:
f.write(b'\x80\x01')
f.write(b"\x80\x01")
write_int_8(f, dx)
write_int_8(f, -dy)
continue
elif data == TRIM:
if trims: # command trim.
f.write(b'\x80\x02\x00\x00' * command_count_max)
f.write(b"\x80\x02\x00\x00" * command_count_max)
continue
elif data == JUMP:
f.write(b'\x80\x02')
f.write(b"\x80\x02")
write_int_8(f, dx)
write_int_8(f, -dy)
continue
elif data == END:
break
f.write(b'\x80\x10')
f.write(b"\x80\x10")
def get_jef_hoop_size(width, height):

Wyświetl plik

@ -1,4 +1,4 @@
from .ReadHelper import signed8, read_int_32le
from .ReadHelper import read_int_32le, signed8
def read_jpx_stitches(f, out):
@ -40,9 +40,6 @@ def read(f, out, settings=None):
color_index = read_int_32le(f)
if color_index is None:
break
out.add_thread({
"color": "random",
"name": "JPX index " + str(color_index)
})
out.add_thread({"color": "random", "name": "JPX index " + str(color_index)})
f.seek(stitch_start_position, 0)
read_jpx_stitches(f, out)

Wyświetl plik

@ -2,8 +2,8 @@ from .EmbFunctions import *
from .EmbThread import EmbThread
def decoded_command(command_dict,name):
split = name.split(' ')
def decoded_command(command_dict, name):
split = name.split(" ")
command = command_dict[split[0]]
for sp in split[1:]:
if sp[0] == "n":
@ -20,11 +20,12 @@ def decoded_command(command_dict,name):
def read(f, out, settings=None):
import json
json_object = json.load(f)
command_dict = get_command_dictionary()
stitches = json_object['stitches']
extras = json_object['extras']
threadlist = json_object['threadlist']
stitches = json_object["stitches"]
extras = json_object["extras"]
threadlist = json_object["threadlist"]
for t in threadlist:
color = t["color"]
thread = EmbThread(color)
@ -36,11 +37,5 @@ def read(f, out, settings=None):
thread.weight = t["weight"]
out.add_thread(thread)
for s in stitches:
out.stitches.append(
[
s[0],
s[1],
decoded_command(command_dict, s[2])
]
)
out.extras.update(extras)
out.stitches.append([s[0], s[1], decoded_command(command_dict, s[2])])
out.extras.update(extras)

Wyświetl plik

@ -21,6 +21,7 @@ def decoded_name(names, data):
def write(pattern, f, settings=None):
import json
names = get_common_name_dictionary()
metadata = {}
@ -42,11 +43,13 @@ def write(pattern, f, settings=None):
"details": thread.details,
"brand": thread.brand,
"chart": thread.chart,
"weight": thread.weight
"weight": thread.weight,
}
for thread in pattern.threadlist
],
"stitches": [[s[0], s[1], str(decoded_name(names, s[2]))] for s in pattern.stitches],
"extras": metadata
"stitches": [
[s[0], s[1], str(decoded_name(names, s[2]))] for s in pattern.stitches
],
"extras": metadata,
}
json.dump(json_normal, f, indent=4)

Wyświetl plik

@ -1,4 +1,4 @@
from .ReadHelper import read_int_8, read_int_32le, read_int_24le, signed24
from .ReadHelper import read_int_8, read_int_24le, read_int_32le, signed24
MAX_SIZE_CONVERSION_RATIO = 1.235

Wyświetl plik

@ -10,7 +10,7 @@ def read(f, out, settings=None):
if len(byte) != 2:
break
x = byte[0] & 0x1F
y = - (byte[1] & 0x1F)
y = -(byte[1] & 0x1F)
x *= MIT_SIZE_CONVERSION_RATIO
y *= MIT_SIZE_CONVERSION_RATIO
if byte[0] & 0b10000000:

Wyświetl plik

@ -1,5 +1,11 @@
from .EmbThread import EmbThread
from .ReadHelper import read_int_8, read_int_24be, read_int_24le, read_int_16le, signed24
from .ReadHelper import (
read_int_8,
read_int_16le,
read_int_24be,
read_int_24le,
signed24,
)
PC_SIZE_CONVERSION_RATIO = 5.0 / 3.0

Wyświetl plik

@ -1,4 +1,4 @@
from .ReadHelper import read_int_8, read_int_24be, signed24, read_int_16be
from .ReadHelper import read_int_8, read_int_16be, read_int_24be, signed24
PC_SIZE_CONVERSION_RATIO = 5.0 / 3.0

Wyświetl plik

@ -1,5 +1,11 @@
from .EmbThread import EmbThread
from .ReadHelper import read_int_8, read_int_24be, read_int_24le, read_int_16le, signed24
from .ReadHelper import (
read_int_8,
read_int_16le,
read_int_24be,
read_int_24le,
signed24,
)
PC_SIZE_CONVERSION_RATIO = 5.0 / 3.0

Wyświetl plik

@ -1,5 +1,11 @@
from .EmbThread import EmbThread
from .ReadHelper import read_int_8, read_int_24be, read_int_24le, read_int_16le, signed24
from .ReadHelper import (
read_int_8,
read_int_16le,
read_int_24be,
read_int_24le,
signed24,
)
PC_SIZE_CONVERSION_RATIO = 5.0 / 3.0

Wyświetl plik

@ -1,44 +1,234 @@
from math import floor
blank = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
0x08, 0x00, 0x00, 0x00, 0x00, 0x10,
0x04, 0x00, 0x00, 0x00, 0x00, 0x20,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x02, 0x00, 0x00, 0x00, 0x00, 0x40,
0x04, 0x00, 0x00, 0x00, 0x00, 0x20,
0x08, 0x00, 0x00, 0x00, 0x00, 0x10,
0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0xF0,
0xFF,
0xFF,
0xFF,
0xFF,
0x0F,
0x08,
0x00,
0x00,
0x00,
0x00,
0x10,
0x04,
0x00,
0x00,
0x00,
0x00,
0x20,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x02,
0x00,
0x00,
0x00,
0x00,
0x40,
0x04,
0x00,
0x00,
0x00,
0x00,
0x20,
0x08,
0x00,
0x00,
0x00,
0x00,
0x10,
0xF0,
0xFF,
0xFF,
0xFF,
0xFF,
0x0F,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
]
@ -55,15 +245,9 @@ def draw(points, graphic, stride=6):
for point in points:
try:
try:
graphic_mark_bit(graphic,
int(point.x),
int(point.y),
stride)
graphic_mark_bit(graphic, int(point.x), int(point.y), stride)
except AttributeError:
graphic_mark_bit(graphic,
int(point[0]),
int(point[1]),
stride)
graphic_mark_bit(graphic, int(point[0]), int(point[1]), stride)
except IndexError:
pass
@ -114,15 +298,19 @@ def draw_scaled(extends, points, graphic, stride, buffer=5):
for point in points:
try:
try:
graphic_mark_bit(graphic,
int(floor((point.x * scale) + translate_x)),
int(floor((point.y * scale) + translate_y)),
stride)
graphic_mark_bit(
graphic,
int(floor((point.x * scale) + translate_x)),
int(floor((point.y * scale) + translate_y)),
stride,
)
except AttributeError:
graphic_mark_bit(graphic,
int(floor((point[0] * scale) + translate_x)),
int(floor((point[1] * scale) + translate_y)),
stride)
graphic_mark_bit(
graphic,
int(floor((point[0] * scale) + translate_x)),
int(floor((point[1] * scale) + translate_y)),
stride,
)
except IndexError:
pass
@ -153,12 +341,11 @@ def get_graphic_as_string(graphic, one="#", zero=" "):
graphic = bytearray(graphic)
list_string = [
one if (byte >> i) & 1 else zero
for byte in graphic
for i in range(0, 8)
one if (byte >> i) & 1 else zero for byte in graphic for i in range(0, 8)
]
bit_stride = 8 * stride
bit_length = 8 * len(graphic)
return '\n'.join(
''.join(list_string[m:m + bit_stride])
for m in range(0, bit_length, bit_stride))
return "\n".join(
"".join(list_string[m : m + bit_stride])
for m in range(0, bit_length, bit_stride)
)

Wyświetl plik

@ -1,5 +1,5 @@
from .EmbThreadPec import get_thread_set
from .ReadHelper import read_string_8, read_int_8, read_int_24le
from .ReadHelper import read_int_8, read_int_24le, read_string_8
JUMP_CODE = 0x10
TRIM_CODE = 0x20
@ -38,13 +38,9 @@ def read_pec(f, out, pes_chart=None):
byte_size = pec_graphic_byte_stride * pec_graphic_icon_height
read_pec_graphics(f,
out,
byte_size,
pec_graphic_byte_stride,
count_colors + 1,
threads
)
read_pec_graphics(
f, out, byte_size, pec_graphic_byte_stride, count_colors + 1, threads
)
def read_pec_graphics(f, out, size, stride, count, values):
@ -102,14 +98,14 @@ def map_pec_colors(colorbytes, out, chart, values):
def signed12(b):
b &= 0xFFF
if b > 0x7FF:
return - 0x1000 + b
return -0x1000 + b
else:
return b
def signed7(b):
if b > 63:
return - 128 + b
return -128 + b
else:
return b

Wyświetl plik

@ -1,9 +1,14 @@
from .EmbThread import build_unique_palette
from .EmbConstant import *
from .EmbThread import build_unique_palette
from .EmbThreadPec import get_thread_set
from .PecGraphics import get_blank, draw_scaled
from .WriteHelper import write_int_8, write_int_16le, write_int_16be, \
write_int_24le, write_string_utf8
from .PecGraphics import draw_scaled, get_blank
from .WriteHelper import (
write_int_8,
write_int_16be,
write_int_16le,
write_int_24le,
write_string_utf8,
)
SEQUIN_CONTINGENCY = CONTINGENCY_SEQUIN_JUMP
FULL_JUMP = True
@ -22,7 +27,7 @@ PEC_ICON_HEIGHT = 38
def write(pattern, f, settings=None):
pattern.fix_color_count()
pattern.interpolate_stop_as_duplicate_color()
f.write(bytes("#PEC0001".encode('utf8')))
f.write(bytes("#PEC0001".encode("utf8")))
write_pec(pattern, f)
@ -40,7 +45,7 @@ def write_pec(pattern, f, threadlist=None):
def write_pec_header(pattern, f, threadlist):
name = pattern.get_metadata("name", "Untitled")
write_string_utf8(f, "LA:%-16s\r" % name[:8])
f.write(b'\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\xFF\x00')
f.write(b"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\xFF\x00")
write_int_8(f, int(PEC_ICON_WIDTH / 8)) # PEC BYTE STRIDE
write_int_8(f, int(PEC_ICON_HEIGHT)) # PEC ICON HEIGHT
@ -52,15 +57,15 @@ def write_pec_header(pattern, f, threadlist):
current_thread_count = len(color_index_list)
if current_thread_count != 0:
f.write(b'\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20')
f.write(b"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20")
add_value = current_thread_count - 1
color_index_list.insert(0, add_value)
f.write(bytes(bytearray(color_index_list)))
else:
f.write(b'\x20\x20\x20\x20\x64\x20\x00\x20\x00\x20\x20\x20\xFF')
f.write(b"\x20\x20\x20\x20\x64\x20\x00\x20\x00\x20\x20\x20\xFF")
for i in range(current_thread_count, 463):
f.write(b'\x20') # 520
f.write(b"\x20") # 520
return color_index_list, rgb_list
@ -69,9 +74,9 @@ def write_pec_block(pattern, f, extends):
height = extends[3] - extends[1]
stitch_block_start_position = f.tell()
f.write(b'\x00\x00')
f.write(b"\x00\x00")
write_int_24le(f, 0) # Space holder.
f.write(b'\x31\xff\xf0')
f.write(b"\x31\xff\xf0")
write_int_16le(f, int(round(width)))
write_int_16le(f, int(round(height)))
write_int_16le(f, 0x1E0)
@ -135,18 +140,14 @@ def pec_encode(pattern, f):
if data == STITCH:
if jumping:
if dx != 0 and dy != 0:
f.write(b'\x00\x00')
f.write(b"\x00\x00")
jumping = False
if -64 < dx < 63 and -64 < dy < 63:
f.write(bytes(bytearray([dx & MASK_07_BIT, dy & MASK_07_BIT])))
else:
dx = encode_long_form(dx)
dy = encode_long_form(dy)
data = [
(dx >> 8) & 0xFF,
dx & 0xFF,
(dy >> 8) & 0xFF,
dy & 0xFF]
data = [(dx >> 8) & 0xFF, dx & 0xFF, (dy >> 8) & 0xFF, dy & 0xFF]
f.write(bytes(bytearray(data)))
continue
elif data == JUMP:
@ -155,22 +156,23 @@ def pec_encode(pattern, f):
dx = flag_trim(dx)
dy = encode_long_form(dy)
dy = flag_trim(dy)
f.write(bytes(bytearray([
(dx >> 8) & 0xFF,
dx & 0xFF,
(dy >> 8) & 0xFF,
dy & 0xFF
])))
f.write(
bytes(
bytearray(
[(dx >> 8) & 0xFF, dx & 0xFF, (dy >> 8) & 0xFF, dy & 0xFF]
)
)
)
continue
elif data == COLOR_CHANGE:
if jumping:
f.write(b'\x00\x00')
f.write(b"\x00\x00")
jumping = False
f.write(b'\xfe\xb0')
f.write(b"\xfe\xb0")
if color_two:
f.write(b'\x02')
f.write(b"\x02")
else:
f.write(b'\x01')
f.write(b"\x01")
color_two = not color_two
continue
elif data == STOP:
@ -178,5 +180,5 @@ def pec_encode(pattern, f):
elif data == TRIM:
continue
elif data == END:
f.write(b'\xff')
f.write(b"\xff")
break

Wyświetl plik

@ -1,6 +1,12 @@
from .EmbThread import EmbThread
from .PecReader import read_pec
from .ReadHelper import read_string_8, read_int_8, read_int_32le, read_int_24be, read_int_16le
from .ReadHelper import (
read_int_8,
read_int_16le,
read_int_24be,
read_int_32le,
read_string_8,
)
def read(f, out, settings=None):

Wyświetl plik

@ -1,8 +1,14 @@
from .EmbConstant import *
from .EmbThreadPec import get_thread_set
from .PecWriter import write_pec
from .WriteHelper import write_string_utf8, write_int_32le, write_int_24le, write_int_16le, write_int_8, \
write_float_32le
from .WriteHelper import (
write_float_32le,
write_int_8,
write_int_16le,
write_int_24le,
write_int_32le,
write_string_utf8,
)
SEQUIN_CONTINGENCY = CONTINGENCY_SEQUIN_JUMP
FULL_JUMP = True
@ -30,7 +36,7 @@ def write(pattern, f, settings=None):
version = settings.get("version", version)
truncated = settings.get("truncated", False)
if isinstance(version, str):
if version.endswith('t'):
if version.endswith("t"):
truncated = True
version = float(version[:-1])
version = float(version)
@ -48,7 +54,7 @@ def write(pattern, f, settings=None):
def write_truncated_version_1(pattern, f):
write_string_utf8(f, PES_VERSION_1_SIGNATURE)
f.write(b'\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
f.write(b"\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
write_pec(pattern, f)
@ -154,7 +160,7 @@ def write_pes_header_v1(f, distinct_block_objects):
def write_pes_header_v6(pattern, f, chart, distinct_block_objects):
write_int_16le(f, 0x01) # 0 = 100x100, 130x180 hoop
f.write(b'02') # This is an 2-digit ascii number.
f.write(b"02") # This is an 2-digit ascii number.
write_pes_string_8(f, pattern.get_metadata("name", None))
write_pes_string_8(f, pattern.get_metadata("category", None))
write_pes_string_8(f, pattern.get_metadata("author", None))
@ -301,7 +307,7 @@ def write_pes_sewsegheader(f, left, top, right, bottom):
write_int_16le(f, 0)
write_int_16le(f, int(width))
write_int_16le(f, int(height))
f.write(b'\x00\x00\x00\x00\x00\x00\x00\x00')
f.write(b"\x00\x00\x00\x00\x00\x00\x00\x00")
placeholder_needs_section_data = f.tell()
# sections

Wyświetl plik

@ -1,6 +1,6 @@
from .EmbThreadPec import get_thread_set
from .PecReader import read_pec_stitches
from .ReadHelper import read_int_8, read_int_32le, read_int_16le
from .ReadHelper import read_int_8, read_int_16le, read_int_32le
def read(f, out, settings=None):

Wyświetl plik

@ -1,6 +1,6 @@
from .EmbThreadPec import get_thread_set
from .PecReader import read_pec_stitches, read_pec_graphics
from .ReadHelper import read_int_8, read_int_32le, read_int_16le
from .PecReader import read_pec_graphics, read_pec_stitches
from .ReadHelper import read_int_8, read_int_16le, read_int_32le
def read(f, out, settings=None):
@ -16,13 +16,9 @@ def read(f, out, settings=None):
return # File terminated before expected end.
out.add_thread(threadset[color_index % len(threadset)])
byte_size = pec_graphic_byte_stride * pec_graphic_icon_height
read_pec_graphics(f,
out,
byte_size,
pec_graphic_byte_stride,
color_count,
out.threadlist
)
read_pec_graphics(
f, out, byte_size, pec_graphic_byte_stride, color_count, out.threadlist
)
f.seek(0x2B, 0)
pec_add = read_int_8(f) # Size of pre-graphics, post copyright header.
f.seek(4, 1) # 0x30, graphics end size.
@ -36,4 +32,3 @@ def read(f, out, settings=None):
f.seek(color_count2 + 0x1D, 1) # 1D toto back
read_pec_stitches(f, out)
out.interpolate_duplicate_color_as_stop()

Wyświetl plik

@ -2,10 +2,10 @@ from .ReadHelper import read_int_8, read_int_16le
def find_extends(stitches):
min_x = float('inf')
min_y = float('inf')
max_x = -float('inf')
max_y = -float('inf')
min_x = float("inf")
min_y = float("inf")
max_x = -float("inf")
max_y = -float("inf")
for stitch in stitches:
if stitch[0] > max_x:

Wyświetl plik

@ -1,5 +1,5 @@
from .EmbConstant import *
from .WriteHelper import write_string_utf8, write_int_8, write_int_16le
from .WriteHelper import write_int_8, write_int_16le, write_string_utf8
MAX_STITCH_DISTANCE = 70
MAX_PERMITTED_STITCHES = 100
@ -38,10 +38,12 @@ def write(pattern, f, settings=None):
write_string_utf8(f, "#PMV0001")
header = "...................................."
write_string_utf8(f, header[0:36])
f.write(b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00')
f.write(
b"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00"
)
write_int_16le(f, point_count)
write_int_16le(f, point_count * 2)
@ -83,8 +85,7 @@ def write(pattern, f, settings=None):
continue
write_int_16le(f, 0)
write_int_16le(f, 256)
f.write(b'\x00\x00\x00\x00\x05\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x02\x00')
f.write(b"\x00\x00\x00\x00\x05\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x02\x00")
write_int_16le(f, 256)
write_int_8(f, 0)
write_int_8(f, 0)
@ -93,18 +94,34 @@ def write(pattern, f, settings=None):
width_range = max_y - min_y
write_width_lookup_table(f, width_range)
write_int_16le(f, 0x12)
f.write(b'\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00')
f.write(b"\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00")
def write_length_lookup_table(f, length_range):
# I've not solved this for how they are actually made, writing a something that should work.
write_values = [(0, 0), (10, 71), (20, 143), (40, 214), (60, 286), (80, 357),
(100, 429), (120, 500), (140, 571), (160, 714), (180, 786), (200, 857),
(250, 1000), (300, 1286), (350, 1429), (400, 1571), (450, 1786), (500, 2000)]
write_values = [
(0, 0),
(10, 71),
(20, 143),
(40, 214),
(60, 286),
(80, 357),
(100, 429),
(120, 500),
(140, 571),
(160, 714),
(180, 786),
(200, 857),
(250, 1000),
(300, 1286),
(350, 1429),
(400, 1571),
(450, 1786),
(500, 2000),
]
steps = len(write_values)
write_int_8(f, steps-1) # (500, 2000)
write_int_8(f, steps - 1) # (500, 2000)
write_int_8(f, steps)
for value in write_values:
length_at_step = value[0]
@ -123,7 +140,7 @@ def write_width_lookup_table(f, width_range):
steps = 15
second_max = 28000.0 / float(width_range)
second_step = second_max / float(steps - 1)
write_int_8(f, steps-1)
write_int_8(f, steps - 1)
write_int_8(f, steps)
for i in range(0, steps):
width_at_step = 50 * i

Wyświetl plik

@ -8,190 +8,212 @@ SEQUIN_CONTINGENCY = CONTINGENCY_SEQUIN_STITCH
FULL_JUMP = True
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]]
"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):
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))
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 (
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'')])
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:
@ -353,16 +375,18 @@ def write(pattern, f, settings=None):
min_x = extends[0]
min_y = extends[1]
points = 50
draw_buff.draw_text(0, 0, 'mm')
for x in range(points-(min_x % points), width - 30, points):
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):
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)
f.write(write_png(bytes(bytearray(draw_buff.buf)), draw_buff.width, draw_buff.height))
f.write(
write_png(bytes(bytearray(draw_buff.buf)), draw_buff.width, draw_buff.height)
)

Wyświetl plik

@ -34,4 +34,4 @@ write_xxx = EmbPattern.write_xxx
write_svg = EmbPattern.write_svg
write_png = EmbPattern.write_png
write = EmbPattern.static_write
is_str = EmbPattern.is_str
is_str = EmbPattern.is_str

Wyświetl plik

@ -8,7 +8,7 @@ def signed8(b):
def signed16(v):
v &= 0xFFFF
if v > 0x7FFF:
return - 0x10000 + v
return -0x10000 + v
else:
return v
@ -16,7 +16,7 @@ def signed16(v):
def signed24(v):
v &= 0xFFFFFF
if v > 0x7FFFFF:
return - 0x1000000 + v
return -0x1000000 + v
else:
return v
@ -60,39 +60,45 @@ def read_int_16be(stream):
def read_int_24le(stream):
b = bytearray(stream.read(3))
if len(b) == 3:
return (b[0] & 0xFF) + ((b[1] & 0xFF) << 8) + \
((b[2] & 0xFF) << 16)
return (b[0] & 0xFF) + ((b[1] & 0xFF) << 8) + ((b[2] & 0xFF) << 16)
return None
def read_int_24be(stream):
b = bytearray(stream.read(3))
if len(b) == 3:
return (b[2] & 0xFF) + ((b[1] & 0xFF) << 8) + \
((b[0] & 0xFF) << 16)
return (b[2] & 0xFF) + ((b[1] & 0xFF) << 8) + ((b[0] & 0xFF) << 16)
return None
def read_int_32le(stream):
b = bytearray(stream.read(4))
if len(b) == 4:
return (b[0] & 0xFF) + ((b[1] & 0xFF) << 8) + \
((b[2] & 0xFF) << 16) + ((b[3] & 0xFF) << 24)
return (
(b[0] & 0xFF)
+ ((b[1] & 0xFF) << 8)
+ ((b[2] & 0xFF) << 16)
+ ((b[3] & 0xFF) << 24)
)
return None
def read_int_32be(stream):
b = bytearray(stream.read(4))
if len(b) == 4:
return (b[3] & 0xFF) + ((b[2] & 0xFF) << 8) + \
((b[1] & 0xFF) << 16) + ((b[0] & 0xFF) << 24)
return (
(b[3] & 0xFF)
+ ((b[2] & 0xFF) << 8)
+ ((b[1] & 0xFF) << 16)
+ ((b[0] & 0xFF) << 24)
)
return None
def read_string_8(stream, length):
byte = stream.read(length)
try:
return byte.decode('utf8')
return byte.decode("utf8")
except UnicodeDecodeError:
return None # Must be > 128 chars.
@ -100,6 +106,6 @@ def read_string_8(stream, length):
def read_string_16(stream, length):
byte = stream.read(length)
try:
return byte.decode('utf16')
return byte.decode("utf16")
except UnicodeDecodeError:
return None

Wyświetl plik

@ -36,4 +36,4 @@ def read(f, out, settings=None):
out.add_thread(threads[index])
f.seek(0x1D78, 0)
read_sew_stitches(f, out);
read_sew_stitches(f, out)

Wyświetl plik

@ -2,8 +2,14 @@ import math
from .EmbConstant import *
from .EmbThreadShv import get_thread_set
from .ReadHelper import read_int_16be, read_int_32be, \
read_int_8, read_string_8, signed16, signed8
from .ReadHelper import (
read_int_8,
read_int_16be,
read_int_32be,
read_string_8,
signed8,
signed16,
)
def read(f, out, settings=None):

Wyświetl plik

@ -1,4 +1,4 @@
from .ReadHelper import read_int_16be, read_int_8, signed8, signed16
from .ReadHelper import read_int_8, read_int_16be, signed8, signed16
def read(f, out, settings=None):

Wyświetl plik

@ -5,8 +5,8 @@ from .EmbConstant import CONTINGENCY_SEQUIN_STITCH
SEQUIN_CONTINGENCY = CONTINGENCY_SEQUIN_STITCH
# technically I could use svg to draw a sequin as a 2 element circle path.
FULL_JUMP = False # just drops all jumps anyway.
MAX_JUMP_DISTANCE = float('inf')
MAX_STITCH_DISTANCE = float('inf')
MAX_JUMP_DISTANCE = float("inf")
MAX_STITCH_DISTANCE = float("inf")
NAME_SVG = "svg"
ATTR_VERSION = "version"
@ -39,11 +39,9 @@ def create_svg_dom(pattern):
height = extends[3] - extends[1]
root.set(ATTR_WIDTH, str(width))
root.set(ATTR_HEIGHT, str(height))
viewbox = \
str(extends[0]) + " " + \
str(extends[1]) + " " + \
str(width) + " " + \
str(height)
viewbox = (
str(extends[0]) + " " + str(extends[1]) + " " + str(width) + " " + str(height)
)
root.set(ATTR_VIEWBOX, viewbox)
for stitchblock in pattern.get_as_stitchblock():

Wyświetl plik

@ -1,5 +1,5 @@
from .EmbThread import EmbThread
from .ReadHelper import signed8, read_int_8, read_int_24be
from .ReadHelper import read_int_8, read_int_24be, signed8
def read(f, out, settings=None):

Wyświetl plik

@ -28,7 +28,12 @@ def write_mimic(pattern, f):
if (flags & COMMAND_MASK) == COLOR_CHANGE:
color += 1
flags = emb_mod_convert[(flags & COMMAND_MASK)]
txt_line = "%.1f,%.1f color:%i flags:%s\n" % (xx / 10.0, yy / 10.0, color, flags)
txt_line = "%.1f,%.1f color:%i flags:%s\n" % (
xx / 10.0,
yy / 10.0,
color,
flags,
)
write_string_utf8(f, txt_line)
@ -43,7 +48,13 @@ def write_normal(pattern, f):
if (flags & COMMAND_MASK) == COLOR_CHANGE:
color = pattern.get_thread_or_filler(color_index).color
named_command = names[(flags & COMMAND_MASK)]
txt_line = "%.1f,%.1f color:%i command:%s flags:%i\n" % (xx, yy, color, named_command, flags)
txt_line = "%.1f,%.1f color:%i command:%s flags:%i\n" % (
xx,
yy,
color,
named_command,
flags,
)
write_string_utf8(f, txt_line)

Wyświetl plik

@ -60,7 +60,9 @@ def read_u01_stitches(f, out):
if dx != 0 or dy != 0:
out.move(dx, dy)
continue
if command == 0x08: # ww, stop file had proper A8 rather than E8 and displacement
if (
command == 0x08
): # ww, stop file had proper A8 rather than E8 and displacement
# C00 Stop
out.stop()
if dx != 0 or dy != 0:

Wyświetl plik

@ -13,7 +13,7 @@ def write(pattern, f, settings=None):
stitches = pattern.stitches
stitch_count = len(stitches)
for i in range(0, 0x80):
f.write(b'0')
f.write(b"0")
if stitch_count == 0:
return
extends = pattern.bounds()
@ -28,7 +28,7 @@ def write(pattern, f, settings=None):
write_int_16le(f, int(last_stitch[0]))
write_int_16le(f, -int(last_stitch[1]))
for i in range(f.tell(), 0x100):
f.write(b'\x00')
f.write(b"\x00")
xx = 0
yy = 0
trigger_fast = False
@ -87,4 +87,4 @@ def write(pattern, f, settings=None):
f.write(bytes(bytearray([cmd, delta_y, delta_x])))
elif data == END:
break
f.write(b'\xF8\x00\x00')
f.write(b"\xF8\x00\x00")

Wyświetl plik

@ -1,6 +1,13 @@
from .EmbThread import EmbThread
from .ReadHelper import read_int_16be, read_int_8, read_int_32be, read_int_24be, read_signed, read_string_8, \
read_string_16
from .ReadHelper import (
read_int_8,
read_int_16be,
read_int_24be,
read_int_32be,
read_signed,
read_string_8,
read_string_16,
)
def read_vp3_string_16(stream):
@ -24,7 +31,7 @@ def skip_vp3_string(stream):
def signed32(b):
b &= 0xFFFFFFFF
if b > 0x7FFFFFFF:
return - 0x100000000 + b
return -0x100000000 + b
else:
return b
@ -34,7 +41,7 @@ def signed16(b0, b1):
b1 &= 0xFF
b = (b0 << 8) | b1
if b > 0x7FFF:
return - 0x10000 + b
return -0x10000 + b
else:
return b
@ -46,7 +53,7 @@ def read(f, out, settings=None):
f.seek(7, 1)
skip_vp3_string(f) # "" comments and note string.
f.seek(32, 1)
center_x = (signed32(read_int_32be(f)) / 100)
center_x = signed32(read_int_32be(f)) / 100
center_y = -(signed32(read_int_32be(f)) / 100)
f.seek(27, 1)
skip_vp3_string(f) # ""
@ -65,7 +72,7 @@ def vp3_read_colorblock(f, out, center_x, center_y):
distance_to_next_block_050 = read_int_32be(f)
block_end_position = distance_to_next_block_050 + f.tell()
start_position_x = (signed32(read_int_32be(f)) / 100)
start_position_x = signed32(read_int_32be(f)) / 100
start_position_y = -(signed32(read_int_32be(f)) / 100)
abs_x = start_position_x + center_x
abs_y = start_position_y + center_y

Wyświetl plik

@ -1,6 +1,12 @@
from .EmbConstant import *
from .WriteHelper import write_int_8, write_int_24be, \
write_int_32be, write_int_16be, write_string_utf8, write_string
from .WriteHelper import (
write_int_8,
write_int_16be,
write_int_24be,
write_int_32be,
write_string,
write_string_utf8,
)
SEQUIN_CONTINGENCY = CONTINGENCY_SEQUIN_JUMP
FULL_JUMP = False
@ -63,7 +69,7 @@ def write(pattern, f, settings=None):
def write_file(pattern, f):
f.write(b'\x00\x02\x00')
f.write(b"\x00\x02\x00")
placeholder_distance_end_of_file_block_020 = f.tell()
write_int_32be(f, 0) # placeholder
# This refers to the end of the final block, not entire bytes.
@ -104,7 +110,7 @@ def write_file(pattern, f):
def write_design_block(f, extends, colorblocks):
f.write(b'\x00\x03\x00')
f.write(b"\x00\x03\x00")
placeholder_distance_end_of_design_block_030 = f.tell()
write_int_32be(f, 0)
@ -133,14 +139,14 @@ def write_design_block(f, extends, colorblocks):
write_int_32be(f, int(height) * 100)
vp3_write_string_16(f, "") # This is notes and settings string.
f.write(b'\x64\x64') # write_int_16be(f, 25700)
f.write(b"\x64\x64") # write_int_16be(f, 25700)
# maybe b'dd', maybe 100, 100
write_int_32be(f, 4096) # b'\x00\x00\x10\x00'
write_int_32be(f, 0) # b'\x00\x00\x00\x00'
write_int_32be(f, 0) # b'\x00\x00\x10\x00'
write_int_32be(f, 4096) # b'\x00\x00\x10\x00'
f.write(b'xxPP\x01\x00')
f.write(b"xxPP\x01\x00")
vp3_write_string_16(f, "Produced by Software Ltd")
@ -156,7 +162,7 @@ def write_design_block(f, extends, colorblocks):
def write_vp3_colorblock(f, first, center_x, center_y, stitches, thread):
f.write(b'\x00\x05\x00')
f.write(b"\x00\x05\x00")
placeholder_distance_end_of_color_block_050 = f.tell()
write_int_32be(f, 0)
@ -193,9 +199,9 @@ def write_vp3_colorblock(f, first, center_x, center_y, stitches, thread):
def vp3_write_thread(f, thread):
f.write(b'\x01\x00') # Single color, no transition.
f.write(b"\x01\x00") # Single color, no transition.
write_int_24be(f, thread.color)
f.write(b'\x00\x00\x00\x05\x28') # no parts, no length, Rayon 40-weight
f.write(b"\x00\x00\x00\x05\x28") # no parts, no length, Rayon 40-weight
if thread.catalog_number is not None:
vp3_write_string_8(f, thread.catalog_number)
else:
@ -212,11 +218,11 @@ def vp3_write_thread(f, thread):
def write_stitches_block(f, stitches, first_pos_x, first_pos_y):
# The 0, x, 0 bytes come before placeholders
f.write(b'\x00\x01\x00')
f.write(b"\x00\x01\x00")
placeholder_distance_to_end_of_stitches_block_010 = f.tell()
write_int_32be(f, 0) # placeholder
f.write(b'\x0A\xF6\x00')
f.write(b"\x0A\xF6\x00")
last_x = first_pos_x
last_y = first_pos_y
@ -228,13 +234,13 @@ def write_stitches_block(f, stitches, first_pos_x, first_pos_y):
if flags == END:
# This is a trim command. The machine does not autotrim.
# Consequently writers tend to add this explicit trim command.
f.write(b'\x80\x03')
f.write(b"\x80\x03")
break
elif flags == COLOR_CHANGE:
# Colorchange commands divided the pattern into colorblocks.
continue
elif flags == TRIM:
f.write(b'\x80\x03')
f.write(b"\x80\x03")
continue
elif flags == SEQUIN_MODE:
continue
@ -255,8 +261,8 @@ def write_stitches_block(f, stitches, first_pos_x, first_pos_y):
write_int_8(f, dx)
write_int_8(f, dy)
else:
f.write(b'\x80\x01')
f.write(b"\x80\x01")
write_int_16be(f, dx)
write_int_16be(f, dy)
f.write(b'\x80\x02')
f.write(b"\x80\x02")
vp3_patch_byte_offset(f, placeholder_distance_to_end_of_stitches_block_010)

Wyświetl plik

@ -3,70 +3,102 @@ import struct
def write_int_array_8(stream, int_array):
for value in int_array:
v = bytes(bytearray([
value & 0xFF,
]))
v = bytes(
bytearray(
[
value & 0xFF,
]
)
)
stream.write(v)
def write_int_8(stream, value):
v = bytes(bytearray([
value & 0xFF,
]))
v = bytes(
bytearray(
[
value & 0xFF,
]
)
)
stream.write(v)
def write_int_16le(stream, value):
v = bytes(bytearray([
(value >> 0) & 0xFF,
(value >> 8) & 0xFF,
]))
v = bytes(
bytearray(
[
(value >> 0) & 0xFF,
(value >> 8) & 0xFF,
]
)
)
stream.write(v)
def write_int_16be(stream, value):
v = bytes(bytearray([
(value >> 8) & 0xFF,
(value >> 0) & 0xFF,
]))
v = bytes(
bytearray(
[
(value >> 8) & 0xFF,
(value >> 0) & 0xFF,
]
)
)
stream.write(v)
def write_int_24le(stream, value):
v = bytes(bytearray([
(value >> 0) & 0xFF,
(value >> 8) & 0xFF,
(value >> 16) & 0xFF,
]))
v = bytes(
bytearray(
[
(value >> 0) & 0xFF,
(value >> 8) & 0xFF,
(value >> 16) & 0xFF,
]
)
)
stream.write(v)
def write_int_24be(stream, value):
v = bytes(bytearray([
(value >> 16) & 0xFF,
(value >> 8) & 0xFF,
(value >> 0) & 0xFF,
]))
v = bytes(
bytearray(
[
(value >> 16) & 0xFF,
(value >> 8) & 0xFF,
(value >> 0) & 0xFF,
]
)
)
stream.write(v)
def write_int_32le(stream, value):
v = bytes(bytearray([
(value >> 0) & 0xFF,
(value >> 8) & 0xFF,
(value >> 16) & 0xFF,
(value >> 24) & 0xFF
]))
v = bytes(
bytearray(
[
(value >> 0) & 0xFF,
(value >> 8) & 0xFF,
(value >> 16) & 0xFF,
(value >> 24) & 0xFF,
]
)
)
stream.write(v)
def write_int_32be(stream, value):
v = bytes(bytearray([
(value >> 24) & 0xFF,
(value >> 16) & 0xFF,
(value >> 8) & 0xFF,
(value >> 0) & 0xFF
]))
v = bytes(
bytearray(
[
(value >> 24) & 0xFF,
(value >> 16) & 0xFF,
(value >> 8) & 0xFF,
(value >> 0) & 0xFF,
]
)
)
stream.write(v)
@ -74,7 +106,7 @@ def write_float_32le(stream, value):
stream.write(struct.pack("<f", float(value)))
def write_string(stream, string, encoding='utf8'):
def write_string(stream, string, encoding="utf8"):
# python 2,3 code
try:
stream.write(bytes(string).encode(encoding))
@ -85,6 +117,6 @@ def write_string(stream, string, encoding='utf8'):
def write_string_utf8(stream, string):
# python 2,3 code
try:
stream.write(bytes(string).encode('utf8'))
stream.write(bytes(string).encode("utf8"))
except TypeError:
stream.write(bytes(string, 'utf8'))
stream.write(bytes(string, "utf8"))

Wyświetl plik

@ -1,11 +1,11 @@
from .EmbThread import EmbThread
from .ReadHelper import read_int_16le, read_int_8, read_int_32be, signed8, signed16
from .ReadHelper import read_int_8, read_int_16le, read_int_32be, signed8, signed16
# 7F 08 00 00 is color change.
# 7F 01 xx yy is unstitched.
# 7F 7F 02 14 is end.
def read(f, out, settings=None):
f.seek(0x27, 1)
num_of_colors = read_int_16le(f)

Wyświetl plik

@ -53,7 +53,7 @@ def write_xxx_header_a(pattern, f):
write_int_16le(f, int(-stitches[-1][1])) # correct
for i in range(0, 0x85):
write_int_8(f, 0x00)
f.write(b'XXX')
f.write(b"XXX")
for i in range(0, 0x39):
write_int_8(f, 0x00)
write_int_16le(f, 0x20)

Wyświetl plik

@ -1,4 +1,4 @@
from .ReadHelper import signed8, read_int_32le
from .ReadHelper import read_int_32le, signed8
def read_zhs_stitches(f, out):

Wyświetl plik

@ -1,12 +1,12 @@
name = "pyembroidery"
# items available at the top level (e.g. pyembroidery.read)
from .PyEmbroidery import *
from .EmbConstant import *
from .EmbFunctions import *
from .EmbPattern import EmbPattern
from .EmbMatrix import EmbMatrix
from .EmbPattern import EmbPattern
from .EmbThread import EmbThread
# items available in a sub-heirarchy (e.g. pyembroidery.PecGraphics.get_graphic_as_string)
from .PecGraphics import get_graphic_as_string
from .PecGraphics import get_graphic_as_string
from .PyEmbroidery import *

Wyświetl plik

@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup(
name="pyembroidery",
version="1.4.27",
version="1.4.28",
author="Tatarize",
author_email="tatarize@gmail.com",
description="Embroidery IO library",