369 | 369 |
bool last_page_flag; /**< flag last page in ESC i z */
|
370 | 370 |
bool legacy_hires;
|
371 | 371 |
bool concat_pages; /**< remove interlabel margins */
|
|
372 |
float min_margin; /**< minimum top and bottom margin */
|
372 | 373 |
float margin; /**< top and bottom margin */
|
373 | 374 |
unsigned int page; /**< The current page number */
|
374 | 375 |
bool last_page; /**< This is the last page */
|
|
405 | 406 |
/* last_page_flag */ false,
|
406 | 407 |
/* legacy_hires */ false,
|
407 | 408 |
/* concat_pages */ false,
|
|
409 |
/* min_margin */ 0.0,
|
408 | 410 |
/* margin */ 0.0,
|
409 | 411 |
};
|
410 | 412 |
|
|
451 | 453 |
float max;
|
452 | 454 |
};
|
453 | 455 |
struct float_option float_options [] = {
|
|
456 |
{ "MinMargin", &options.min_margin, 0, FLT_MAX },
|
454 | 457 |
{ "Margin", &options.margin, 0, FLT_MAX },
|
455 | 458 |
{ }
|
456 | 459 |
};
|
|
853 | 856 |
putchar (ESC); putchar ('i'); putchar('A'); putchar (job_options->cut_label);
|
854 | 857 |
}
|
855 | 858 |
|
856 | |
unsigned feed = 0;
|
|
859 |
float margin = 0.0;
|
857 | 860 |
if (job_options->media != LABELS)
|
858 | |
feed = lrint (job_options->margin * pt2px);
|
|
861 |
margin += job_options->min_margin + job_options->margin;
|
|
862 |
unsigned feed = lrint (margin * pt2px);
|
859 | 863 |
putchar (ESC); putchar ('i'); putchar ('d');
|
860 | 864 |
putchar (feed & 0xff); putchar ((feed >> 8) & 0xff);
|
861 | 865 |
|
|
1367 | 1371 |
float top_distance_pt
|
1368 | 1372 |
= page_size_y - header->cupsImagingBBox [3];
|
1369 | 1373 |
top_empty_lines = lrint (top_distance_pt * pt2px [1]);
|
1370 | |
empty_lines += top_empty_lines;
|
|
1374 |
}
|
|
1375 |
|
|
1376 |
unsigned image_height_px = lrint (page_size_y * pt2px [1]);
|
|
1377 |
unsigned bot_empty_lines = 0;
|
|
1378 |
if (image_height_px >= top_empty_lines + cupsHeight)
|
|
1379 |
bot_empty_lines = image_height_px - top_empty_lines - cupsHeight;
|
|
1380 |
|
|
1381 |
/*
|
|
1382 |
* QL printers have a specific top and bottom margin that must be left blank
|
|
1383 |
* to allow printers to skip to the next label. For continuous-length tape,
|
|
1384 |
* this margin is defined as the minimum value allowed for the "ESC i d"
|
|
1385 |
* command as defined in the manuals; if a smaller value is passed, the
|
|
1386 |
* printer rounds that up. For die-cut labels, the margin is implicit (the
|
|
1387 |
* "ESC i d" command is always passed a value of 0). For most die-cut
|
|
1388 |
* labels, the margin is the same as the minimum continuous-length tape
|
|
1389 |
* margin, but there are a few exceptions.
|
|
1390 |
*
|
|
1391 |
* PT printers only support continuous-length tape. They are documented to
|
|
1392 |
* work like QL printers, but in practice, they all seem to allow a minimum
|
|
1393 |
* margin of 0 as well. The minimum margin still makes sure the tape is cut
|
|
1394 |
* in a blank space, so use the minimum margin amounts on those printers for
|
|
1395 |
* which we have a specification.
|
|
1396 |
*
|
|
1397 |
* Below, we ensure that printers for which a min_margin is defined will
|
|
1398 |
* always have a margin at lest that wide for continuous-length tape. For
|
|
1399 |
* die-cut labels, we assume that the page margins are equal to the implicit
|
|
1400 |
* margins. For page margins that are empty, we assume min_margin; in that
|
|
1401 |
* case, we'll end up skipping lines at the beginning and/or end of the
|
|
1402 |
* bitmap to allow for that minimum margin.
|
|
1403 |
*/
|
|
1404 |
unsigned top_skip = 0, bot_skip = 0;
|
|
1405 |
unsigned min_feed = lrint (job_options->min_margin * pt2px [1]);
|
|
1406 |
if (job_options->media == LABELS && top_empty_lines) {
|
|
1407 |
top_empty_lines = 0;
|
|
1408 |
} else if (top_empty_lines >= min_feed) {
|
|
1409 |
top_empty_lines -= min_feed;
|
|
1410 |
} else {
|
|
1411 |
top_skip = min_feed - top_empty_lines;
|
|
1412 |
top_empty_lines = 0;
|
|
1413 |
}
|
|
1414 |
if (job_options->media == LABELS && bot_empty_lines) {
|
|
1415 |
bot_empty_lines = 0;
|
|
1416 |
} else if (bot_empty_lines >= min_feed) {
|
|
1417 |
bot_empty_lines -= min_feed;
|
|
1418 |
} else {
|
|
1419 |
bot_skip = min_feed - bot_empty_lines;
|
|
1420 |
bot_empty_lines = 0;
|
1371 | 1421 |
}
|
1372 | 1422 |
|
1373 | 1423 |
progress.page = job_options->page;
|
1374 | 1424 |
progress.height = cupsHeight;
|
1375 | 1425 |
|
1376 | 1426 |
/* Generate and store actual page data */
|
|
1427 |
empty_lines += top_empty_lines;
|
1377 | 1428 |
int y;
|
1378 | 1429 |
for (y = 0; y < cupsHeight; y++) {
|
1379 | 1430 |
/* Feedback to the user */
|
|
1381 | 1432 |
/* Read one line of pixels */
|
1382 | 1433 |
if (cupsRasterReadPixels (ras, buffer, cupsBytesPerLine) < 1)
|
1383 | 1434 |
break; /* Escape if no pixels read */
|
|
1435 |
if (y < top_skip || y + bot_skip >= cupsHeight)
|
|
1436 |
continue;
|
1384 | 1437 |
bool nonempty_line =
|
1385 | 1438 |
generate_emit_line (buffer, emit_line_buffer, buflen, bytes_per_line,
|
1386 | 1439 |
right_padding_bytes, shift, do_mirror, xormask);
|
|
1398 | 1451 |
progress.completed = cupsHeight;
|
1399 | 1452 |
report_progress (0);
|
1400 | 1453 |
|
1401 | |
unsigned image_height_px = lrint (page_size_y * pt2px [1]);
|
1402 | |
unsigned bot_empty_lines;
|
1403 | |
if (image_height_px >= top_empty_lines + y)
|
1404 | |
bot_empty_lines = image_height_px - top_empty_lines - y;
|
1405 | |
else
|
1406 | |
bot_empty_lines = 0;
|
1407 | 1454 |
if (bot_empty_lines != 0 && !job_options->concat_pages)
|
1408 | 1455 |
empty_lines += bot_empty_lines;
|
1409 | 1456 |
return 0;
|