Skip to content

Commit 1f98aeb

Browse files
committed
Allow setting font color individually per line
Signed-off-by: DL6ER <[email protected]>
1 parent 4693f23 commit 1f98aeb

7 files changed

Lines changed: 52 additions & 20 deletions

File tree

app/labeldesigner/label.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ def __init__(
8787
border_roundness=0,
8888
border_distance=(0, 0),
8989
border_color=(0, 0, 0),
90-
timestamp=0):
90+
timestamp=0,
91+
red_support=False):
9192
self._width = width
9293
self._height = height
9394
self.label_content = label_content
@@ -108,6 +109,7 @@ def __init__(
108109
self._border_color = border_color
109110
self._counter = 1
110111
self._timestamp = timestamp
112+
self._red_support = red_support
111113

112114
@property
113115
def label_content(self):
@@ -394,8 +396,6 @@ def _draw_text(self, img = None, bboxes = [], text_offset = (0, 0)):
394396

395397
# Iterate over lines of text
396398
for i, line in enumerate(self.text):
397-
color = self._fore_color
398-
399399
# Calculate spacing
400400
spacing = int(int(line['font_size'])*((int(line['line_spacing']) - 100) / 100)) if 'line_spacing' in line else 0
401401

@@ -419,6 +419,11 @@ def _draw_text(self, img = None, bboxes = [], text_offset = (0, 0)):
419419
else:
420420
raise ValueError(f"Unsupported alignment: {align}")
421421

422+
red_font = 'font_color' in line and line['font_color'] == 'red'
423+
# if red_font and not self._red_support:
424+
# raise ValueError("Red font is not supported on this label")
425+
color = (255, 0, 0) if red_font else (0, 0, 0)
426+
422427
if do_draw and 'font_inverted' in line and line['font_inverted']:
423428
# Draw a filled rectangle
424429
center_x = 0
@@ -437,7 +442,8 @@ def _draw_text(self, img = None, bboxes = [], text_offset = (0, 0)):
437442
shift = 0.1 * int(line['font_size'])
438443
y_min = bboxes[i][0][1] + text_offset[1] - shift
439444
y_max = bboxes[i][0][3] + text_offset[1] - shift
440-
draw.rectangle((min_bbox_x, y_min, max_bbox_x, y_max), fill=self._fore_color)
445+
draw.rectangle((min_bbox_x, y_min, max_bbox_x, y_max), fill=color)
446+
# Overwrite font color with white on colored background
441447
color = (255, 255, 255)
442448

443449
# Either calculate bbox or actually draw

app/labeldesigner/routes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ def get_uploaded_image(image):
289289
if len(line['text']) > 10_000:
290290
raise ValueError("Text is too long")
291291

292+
# if context['print_color'] == 'red' and not context['red_support']:
293+
# raise ValueError("Red font is not supported on this label")
292294
fore_color = (255, 0, 0) if context['print_color'] == 'red' else (0, 0, 0)
293295
border_color = (255, 0, 0) if context['border_color'] == 'red' else (0, 0, 0)
294296

app/labeldesigner/templates/labeldesigner.html

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,6 @@
4646
<span class="fas fa-ruler-vertical" aria-hidden="true"> Rotated
4747
</label>
4848
</div>
49-
50-
<div class="red-support">
51-
<label for="printColor" class="control-label input-group" style="margin-top: 10px; margin-bottom: 0">Print Color:</label>
52-
<div class="btn-group btn-group-toggle btn-block" data-toggle="buttons">
53-
<label class="btn btn-dark" id="print_color_black">
54-
<input type="radio" name="printColor" onchange="preview()" value="black" aria-label="Black">Black
55-
</label>
56-
<label class="btn btn-danger" id="print_color_red">
57-
<input type="radio" name="printColor" onchange="preview()" value="red" aria-label="Red">Red
58-
</label>
59-
</div>
60-
</div>
61-
6249
</div>
6350
<!-- class="card-body" -->
6451
</div>
@@ -127,6 +114,18 @@
127114
Invert text
128115
</label>
129116
</div>
117+
<div class="red-support">
118+
<label for="printColor" class="control-label input-group" style="margin-top: 10px; margin-bottom: 0">Print
119+
Color:</label>
120+
<div class="btn-group btn-group-toggle btn-block" data-toggle="buttons">
121+
<label class="btn btn-dark" id="print_color_black">
122+
<input type="radio" name="fontColor" onchange="preview()" value="black" aria-label="Black">Black
123+
</label>
124+
<label class="btn btn-danger" id="print_color_red">
125+
<input type="radio" name="fontColor" onchange="preview()" value="red" aria-label="Red">Red
126+
</label>
127+
</div>
128+
</div>
130129
</div>
131130
</div>
132131

app/static/js/main.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ function setFontSettingsPerLine() {
2323
font_size: $('#fontSize').val(),
2424
font_inverted: $('#fontInverted').is(':checked'),
2525
align: $('input[name=fontAlign]:checked').val(),
26-
line_spacing: $('input[name=lineSpacing]:checked').val()
26+
line_spacing: $('input[name=lineSpacing]:checked').val(),
27+
font_color: $('#fontColor').val()
2728
};
2829

2930
// Create lines in the <option> with id #lineSelect
@@ -111,6 +112,9 @@ $(document).ready(function () {
111112
$('input[name=lineSpacing][value="' + fs.line_spacing + '"]').prop('checked', true).parent().addClass('active');
112113
// Set font inversion
113114
$('#fontInverted').prop('checked', fs.font_inverted);
115+
// Set font color
116+
$('input[name=fontColor]').prop('checked', false).parent().removeClass('active');
117+
$('input[name=fontColor][value="' + fs.font_color + '"]').prop('checked', true).parent().addClass('active');
114118
});
115119

116120
// When the user changes the caret/selection in the textarea, update #lineSelect and font controls
@@ -401,7 +405,7 @@ function updatePrinterStatus() {
401405
if (printerPath) {
402406
printerPath.textContent = printer_status.path || 'Unknown';
403407
}
404-
if (printer_status['red_support'] === true && $('#labelSize option:selected').val().includes('red')) {
408+
if ($('#labelSize option:selected').val().includes('red')) {
405409
$(".red-support").show();
406410
} else {
407411
$('#print_color_black').prop('active', true);

tests/large_label.png

-3.9 KB
Loading

tests/red_text.png

3.99 KB
Loading

tests/test_labeldesigner_api.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,11 +567,32 @@ def test_invalid_http_methods(client, method):
567567
assert response.status_code == 405
568568

569569

570+
def test_print_red_text(client):
571+
data = EXAMPLE_FORMDATA.copy()
572+
data['text'] = json.dumps([
573+
{'font_family': 'DejaVu Sans', 'font_style': 'Regular', 'text': 'Red Text', 'font_size': '24', 'align': 'center', 'font_color': 'red'},
574+
{'font_family': 'DejaVu Sans', 'font_style': 'Regular', 'text': 'Red Text INVERTED', 'font_size': '24', 'align': 'center', 'font_inverted': True, 'font_color': 'red'}
575+
])
576+
response = client.post('/labeldesigner/api/preview', data=data)
577+
assert response.status_code == 200
578+
assert response.content_type in ['image/png']
579+
580+
# Check image
581+
verify_image(response.data, 'tests/red_text.png')
582+
583+
570584
def test_large_number_of_text_blocks(client):
571585
data = EXAMPLE_FORMDATA.copy()
572586
ALIGNS = ['center', 'left', 'right']
573587
data['text'] = json.dumps([
574-
{'font_family': 'DejaVu Sans', 'font_style': 'Regular', 'text': f'--- {i} ---', 'font_size': str(i + 1), 'align': ALIGNS[i % 3], 'font_inverted': bool(i % 2)} for i in range(100)
588+
{'font_family': 'DejaVu Sans',
589+
'font_style': 'Regular',
590+
'text': f'--- {i} ---',
591+
'font_size': str(i + 1),
592+
'align': ALIGNS[i % 3],
593+
'font_inverted': bool(i % 2),
594+
'font_color': 'red' if i % 5 == 0 else 'black'
595+
} for i in range(100)
575596
])
576597
response = client.post('/labeldesigner/api/preview', data=data)
577598
assert response.status_code == 200

0 commit comments

Comments
 (0)