Skip to content

Commit c15f926

Browse files
authored
Merge pull request #88 from EmbroidePy/tatarize-colorblock
Colorblock correction
2 parents fdb2c64 + e234df4 commit c15f926

File tree

5 files changed

+199
-23
lines changed

5 files changed

+199
-23
lines changed

pyembroidery/DstReader.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,18 @@ def process_header_info(out, prefix, value):
5252

5353
def dst_read_header(f, out):
5454
header = f.read(512)
55-
try:
56-
header_string = header.decode('utf8')
57-
for line in [x.strip() for x in header_string.split('\r')]:
58-
if len(line) > 3:
59-
process_header_info(out, line[0:2].strip(), line[3:].strip())
60-
except UnicodeDecodeError: # The header contains non-utf8 information and omitted. See #83
61-
pass
55+
start = 0
56+
for i, element in enumerate(header):
57+
if element == 13 or element == 10 or element == '\n' or element == '\r': # 13 =='\r', 10 = '\n'
58+
end = i
59+
data = header[start:end]
60+
start = end
61+
try:
62+
line = data.decode('utf8').strip()
63+
if len(line) > 3:
64+
process_header_info(out, line[0:2].strip(), line[3:].strip())
65+
except UnicodeDecodeError: # Non-utf8 information. See #83
66+
continue
6267

6368

6469
def dst_read_stitches(f, out, settings=None):

pyembroidery/EmbPattern.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -312,18 +312,41 @@ def get_as_command_blocks(self):
312312
yield self.stitches[last_pos:]
313313

314314
def get_as_colorblocks(self):
315+
"""
316+
Returns a generator for colorblocks. Color blocks defined with color_breaks will have
317+
the command omitted whereas color blocks delimited with color_change will end with the
318+
color_change command, and if delimited with needle_set, the blocks will begin the new
319+
color block with the needle_set.
320+
"""
315321
thread_index = 0
316-
last_pos = 0
322+
colorblock_start = 0
323+
317324
for pos, stitch in enumerate(self.stitches):
318325
command = stitch[2] & COMMAND_MASK
319-
if command != COLOR_CHANGE and command != NEEDLE_SET:
326+
if command == COLOR_BREAK:
327+
if colorblock_start != pos:
328+
thread = self.get_thread_or_filler(thread_index)
329+
thread_index += 1
330+
yield self.stitches[colorblock_start:pos-1], thread
331+
colorblock_start = pos + 1
320332
continue
333+
if command == COLOR_CHANGE:
334+
thread = self.get_thread_or_filler(thread_index)
335+
thread_index += 1
336+
yield self.stitches[colorblock_start:pos+1], thread
337+
colorblock_start = pos+1
338+
continue
339+
if command == NEEDLE_SET and colorblock_start != pos:
340+
thread = self.get_thread_or_filler(thread_index)
341+
thread_index += 1
342+
yield self.stitches[colorblock_start:pos-1], thread
343+
colorblock_start = pos-1
344+
continue
345+
346+
347+
if colorblock_start != len(self.stitches):
321348
thread = self.get_thread_or_filler(thread_index)
322-
thread_index += 1
323-
yield (self.stitches[last_pos:pos], thread)
324-
last_pos = pos
325-
thread = self.get_thread_or_filler(thread_index)
326-
yield (self.stitches[last_pos:], thread)
349+
yield (self.stitches[colorblock_start:], thread)
327350

328351
def get_as_stitches(self):
329352
"""pos, x, y, command, v1, v2, v3"""

pyembroidery/EmbThread.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,35 @@ def color_distance_red_mean(
9696

9797
class EmbThread:
9898

99-
def __init__(self, thread=None):
99+
def __init__(self, thread=None, description=None, catalog_number=None, details=None, brand=None, chart=None, weight=None):
100100
self.color = 0x000000
101-
self.description = None # type: str
102-
self.catalog_number = None # type: str
103-
self.details = None # type: str
104-
self.brand = None # type: str
105-
self.chart = None # type: str
106-
self.weight = None # type: str
101+
self.description = description # type: str
102+
self.catalog_number = catalog_number # type: str
103+
self.details = details # type: str
104+
self.brand = brand # type: str
105+
self.chart = chart # type: str
106+
self.weight = weight # type: str
107107
# description, catalog_number, details, brand, chart, weight
108108
if thread is not None:
109109
self.set(thread)
110110

111+
def __repr__(self):
112+
parts = list()
113+
parts.append("thread='%s'" % self.hex_color())
114+
if self.description is not None:
115+
parts.append("description='%s'" % self.description)
116+
if self.catalog_number is not None:
117+
parts.append("catalog_number='%s'" % self.catalog_number)
118+
if self.details is not None:
119+
parts.append("details='%s'" % self.details)
120+
if self.brand is not None:
121+
parts.append("brand='%s'" % self.brand)
122+
if self.chart is not None:
123+
parts.append("chart='%s'" % self.chart)
124+
if self.weight is not None:
125+
parts.append("weight='%s'" % self.weight)
126+
return "EmbThread(%s)" % " ,".join(parts)
127+
111128
def __ne__(self, other):
112129
return not self.__eq__(other)
113130

setup.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name="pyembroidery",
8-
version="1.4.11",
8+
version="1.4.15",
99
author="Tatarize",
1010
author_email="[email protected]",
1111
description="Embroidery IO library",
@@ -16,7 +16,6 @@
1616
classifiers=(
1717
'Development Status :: 5 - Production/Stable',
1818
'Intended Audience :: Developers',
19-
"Programming Language :: Python :: 2.7",
2019
"Programming Language :: Python :: 3.6",
2120
"Programming Language :: Python :: 3.7",
2221
"License :: OSI Approved :: MIT License",

test/test_embpattern.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,135 @@ def test_write_csv_read_csv_encoded_command(self):
279279
print("csv-encoded: ", csv_pattern.stitches)
280280
self.assertEqual(encoded_command, csv_pattern.stitches[-1][2])
281281
self.addCleanup(os.remove, file1)
282+
283+
def test_issue_87(self):
284+
"""
285+
Initial test raised by issue 87.
286+
"""
287+
pattern = EmbPattern()
288+
stitches_1 = [[0, 1], [2, 3]]
289+
stitches_2 = [[4, 5], [6, 7]]
290+
pattern.add_block(stitches_1, 0xFF0000)
291+
pattern.add_block(stitches_2, 0x0000FF)
292+
self.assertEqual(len(list(pattern.get_as_colorblocks())), 2)
293+
294+
def test_issue_87_2(self):
295+
"""
296+
Tests a pattern arbitrarily starting with a color change.
297+
With two predefined blocks. The blocks should maintain their blockness.
298+
The color change should isolate 0 stitches, of an unknown color.
299+
:return:
300+
"""
301+
pattern = EmbPattern()
302+
stitches_1 = [[0, 1], [2, 3]]
303+
stitches_2 = [[4, 5], [6, 7]]
304+
305+
pattern.color_change()
306+
pattern.add_thread('random')
307+
pattern.add_block(stitches_1, 0xFF0000)
308+
pattern.add_block(stitches_2, 0x0000FF)
309+
blocks = list(pattern.get_as_colorblocks())
310+
# for q in blocks:
311+
# print(q)
312+
self.assertEqual(blocks[1][1].color, 0xFF0000)
313+
self.assertEqual(blocks[2][1].color, 0x0000FF)
314+
self.assertEqual(len(blocks), 3)
315+
316+
for block in blocks:
317+
stitch_block = block[0]
318+
for stitch in stitch_block:
319+
self.assertNotEqual(stitch[2], COLOR_BREAK)
320+
321+
pattern = EmbPattern()
322+
pattern.add_thread('random')
323+
pattern.color_change() # end block 1, empty
324+
pattern.add_thread(0xFF0000)
325+
pattern += stitches_1
326+
pattern.color_change() # end block 2
327+
pattern.add_thread(0x0000FF)
328+
pattern += stitches_2
329+
blocks = list(pattern.get_as_colorblocks())
330+
# end block 3, no explicit end.
331+
# for q in blocks:
332+
# print(q)
333+
self.assertEqual(blocks[0][0][-1][2], COLOR_CHANGE) # Color change ends the block.
334+
self.assertEqual(blocks[1][0][-1][2], COLOR_CHANGE) # Color change ends the block.
335+
self.assertEqual(blocks[1][1].color, 0xFF0000)
336+
self.assertEqual(blocks[2][1].color, 0x0000FF)
337+
self.assertEqual(len(blocks), 3)
338+
339+
def test_issue_87_3(self):
340+
"""
341+
Tests a pattern arbitrarily starting with a needle_set.
342+
With two predefined blocks. The blocks should maintain their blockness.
343+
The needle set should not contribute a block. Initial needle_set, only
344+
define a starting needle.
345+
:return:
346+
"""
347+
pattern = EmbPattern()
348+
pattern.needle_change()
349+
stitches_1 = [[0, 1], [2, 3]]
350+
stitches_2 = [[4, 5], [6, 7]]
351+
pattern.add_block(stitches_1, 0xFF0000)
352+
pattern.add_block(stitches_2, 0x0000FF)
353+
blocks = list(pattern.get_as_colorblocks())
354+
# for q in blocks:
355+
# print(q)
356+
self.assertEqual(blocks[0][1], 0xFF0000)
357+
self.assertEqual(blocks[1][1], 0x0000FF)
358+
self.assertEqual(len(blocks), 2)
359+
for block in blocks:
360+
stitch_block = block[0]
361+
for stitch in stitch_block:
362+
self.assertNotEqual(stitch[2], COLOR_BREAK)
363+
364+
pattern = EmbPattern()
365+
366+
pattern.needle_change() # start block 0
367+
pattern += stitches_1
368+
pattern += EmbThread(0xFF0000)
369+
370+
pattern.needle_change() # start block 1
371+
pattern += stitches_1
372+
pattern += EmbThread(0x0000FF)
373+
374+
pattern.needle_change() # start block 2
375+
pattern += EmbThread('random')
376+
377+
blocks = list(pattern.get_as_colorblocks())
378+
# for q in blocks:
379+
# print(q)
380+
# Mask is required here since needle_set automatically appends extended data.
381+
self.assertEqual(blocks[0][0][0][2] & COMMAND_MASK, NEEDLE_SET) # Needle_set starts the block.
382+
self.assertEqual(blocks[1][0][0][2] & COMMAND_MASK, NEEDLE_SET) # Needle_set starts the block.
383+
self.assertEqual(blocks[0][1], 0xFF0000)
384+
self.assertEqual(blocks[1][1], 0x0000FF)
385+
self.assertEqual(len(blocks), 3)
386+
387+
def test_issue_87_4(self):
388+
"""
389+
Tests a pattern arbitrarily starting with a color break.
390+
With two predefined blocks. The blocks should maintain their blockness.
391+
And ending with another arbitrary color break. This should give exactly
392+
2 blocks which were defined as prepended colorbreaks postpended color breaks
393+
are not to have an impact.
394+
:return:
395+
"""
396+
pattern = EmbPattern()
397+
pattern += COLOR_BREAK
398+
stitches_1 = [[0, 1], [2, 3]]
399+
stitches_2 = [[4, 5], [6, 7]]
400+
pattern.add_block(stitches_1, 0xFF0000)
401+
pattern.add_block(stitches_2, 0x0000FF)
402+
pattern += COLOR_BREAK
403+
blocks = list(pattern.get_as_colorblocks())
404+
# for q in blocks:
405+
# print(q)
406+
407+
for block in blocks:
408+
stitch_block = block[0]
409+
for stitch in stitch_block:
410+
self.assertNotEqual(stitch[2], COLOR_BREAK)
411+
self.assertEqual(blocks[0][1], 0xFF0000)
412+
self.assertEqual(blocks[1][1], 0x0000FF)
413+
self.assertEqual(len(list(pattern.get_as_colorblocks())), 2)

0 commit comments

Comments
 (0)