Skip to content

Commit 9ade138

Browse files
committed
rastertolabel: Add support for Munbyn ITPP941 label printers
The implementation has been tested to generate the same output as the Munbyn MacOS driver version 1.2.5. The only tested device is a 203 dpi label printer. Support for 300 dpi printers (ITPP941P) has been implemented but not tested. Some Rollo and Beeprt printers might be supported as well, considering that they all are using the same closed-source Linux filter for CUPS, called rastertolabelbeeprt in some packages. The PPD files for those printers set cupsModelNumber to 20. This implementation is using the same value.
1 parent bfdcaad commit 9ade138

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

filter/rastertolabel.c

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,31 @@
5050
#define ZEBRA_ZPL 0x12 /* Zebra ZPL-based printers */
5151
#define ZEBRA_CPCL 0x13 /* Zebra CPCL-based printers */
5252

53+
#define BEEPRT 0x14 /* Beeprt, Rollo, Munbyn */
54+
5355
#define INTELLITECH_PCL 0x20 /* Intellitech PCL-based printers */
5456

5557

58+
/*
59+
* Macros...
60+
*/
61+
62+
#define div_round_up(a,b) (((a) + (b) - 1) / (b))
63+
64+
65+
/*
66+
* Enumerations...
67+
*/
68+
69+
enum media_tracking_e /**** Media tracking types ****/
70+
{
71+
MEDIA_TRACKING_GAP, /* Track by gap in labels */
72+
MEDIA_TRACKING_BLINE, /* Track by black line */
73+
MEDIA_TRACKING_CONTINUOUS, /* Disable tracking */
74+
};
75+
typedef enum media_tracking_e media_tracking_t;
76+
77+
5678
/*
5779
* Globals...
5880
*/
@@ -130,6 +152,9 @@ Setup(ppd_file_t *ppd) /* I - PPD file */
130152
case ZEBRA_CPCL :
131153
break;
132154

155+
case BEEPRT :
156+
break;
157+
133158
case INTELLITECH_PCL :
134159
/*
135160
* Send a PCL reset sequence.
@@ -304,6 +329,114 @@ StartPage(ppd_file_t *ppd, /* I - PPD file */
304329
printf("PAGE-HEIGHT %u\r\n", header->cupsHeight);
305330
break;
306331

332+
case BEEPRT :
333+
{
334+
unsigned dots_per_mm_x, dots_per_mm_y;
335+
unsigned width_mm, height_mm;
336+
int reference_x = 0;
337+
int reference_y = 0;
338+
int rotate = 0;
339+
media_tracking_t media_tracking = MEDIA_TRACKING_GAP;
340+
int gap_mark_height = 3;
341+
int gap_mark_offset = 0;
342+
int feed_offset = 0;
343+
int darkness = 8;
344+
int speed = 4;
345+
int autodotted = 0;
346+
347+
/*
348+
* Threat 203 dpi as exactly 8 dots per mm, 300 dpi as 12 dots per mm.
349+
*/
350+
dots_per_mm_x = div_round_up(10 * header->HWResolution[0], 254);
351+
dots_per_mm_y = div_round_up(10 * header->HWResolution[1], 254);
352+
353+
width_mm = div_round_up(header->cupsWidth, dots_per_mm_x);
354+
height_mm = div_round_up(header->cupsHeight, dots_per_mm_y);
355+
printf("SIZE %u mm,%u mm\r\n", width_mm, height_mm);
356+
357+
/* The typo is used in the PPD, but not in user visible strings */
358+
if ((choice = ppdFindMarkedChoice(ppd, "AdjustHoriaontal")) != NULL &&
359+
strcmp(choice->choice, "Default"))
360+
reference_x = atoi(choice->choice);
361+
362+
if ((choice = ppdFindMarkedChoice(ppd, "AdjustVertical")) != NULL &&
363+
strcmp(choice->choice, "Default"))
364+
reference_y = atoi(choice->choice);
365+
366+
if ((choice = ppdFindMarkedChoice(ppd, "Rotate")) != NULL &&
367+
strcmp(choice->choice, "Default"))
368+
rotate = atoi(choice->choice);
369+
370+
if ((choice = ppdFindMarkedChoice(ppd, "zeMediaTracking")) != NULL) {
371+
if (!strcmp(choice->choice, "BLine"))
372+
media_tracking = MEDIA_TRACKING_BLINE;
373+
else if (!strcmp(choice->choice, "Continuous"))
374+
media_tracking = MEDIA_TRACKING_CONTINUOUS;
375+
}
376+
377+
if ((choice = ppdFindMarkedChoice(ppd, "GapOrMarkHeight")) != NULL &&
378+
strcmp(choice->choice, "Default"))
379+
gap_mark_height = atoi(choice->choice);
380+
381+
if ((choice = ppdFindMarkedChoice(ppd, "GapOrMarkOffset")) != NULL &&
382+
strcmp(choice->choice, "Default"))
383+
gap_mark_offset = atoi(choice->choice);
384+
385+
if ((choice = ppdFindMarkedChoice(ppd, "FeedOffset")) != NULL &&
386+
strcmp(choice->choice, "Default"))
387+
feed_offset = atoi(choice->choice);
388+
389+
if ((choice = ppdFindMarkedChoice(ppd, "Darkness")) != NULL &&
390+
strcmp(choice->choice, "Default"))
391+
darkness = atoi(choice->choice);
392+
393+
if ((choice = ppdFindMarkedChoice(ppd, "zePrintRate")) != NULL &&
394+
strcmp(choice->choice, "Default"))
395+
speed = atoi(choice->choice);
396+
397+
if ((choice = ppdFindMarkedChoice(ppd, "Autodotted")) != NULL &&
398+
strcmp(choice->choice, "Default"))
399+
autodotted = atoi(choice->choice);
400+
401+
printf("REFERENCE %d,%d\r\n", (int)dots_per_mm_x * reference_x,
402+
(int)dots_per_mm_y * reference_y);
403+
printf("DIRECTION %u,0\r\n", rotate);
404+
405+
switch (media_tracking)
406+
{
407+
case MEDIA_TRACKING_GAP:
408+
printf("GAP %d mm,%d mm\r\n",
409+
gap_mark_height, gap_mark_offset);
410+
break;
411+
412+
case MEDIA_TRACKING_BLINE:
413+
printf("BLINE %d mm,%d mm\r\n",
414+
gap_mark_height, gap_mark_offset);
415+
break;
416+
417+
case MEDIA_TRACKING_CONTINUOUS:
418+
printf("GAP 0 mm,0 mm\r\n");
419+
break;
420+
}
421+
422+
printf("OFFSET %d mm\r\n", feed_offset);
423+
printf("DENSITY %u\r\n", darkness);
424+
printf("SPEED %u\r\n", speed);
425+
426+
if (autodotted)
427+
printf("SETC AUTODOTTED ON\r\n");
428+
else
429+
printf("SETC AUTODOTTED OFF\r\n");
430+
431+
printf("SETC PAUSEKEY ON\r\n");
432+
printf("SETC WATERMARK OFF\r\n");
433+
printf("CLS\r\n");
434+
435+
printf("BITMAP 0,0,%u,%u,1,", (header->cupsWidth + 7) >> 3,
436+
header->cupsHeight);
437+
}
438+
break;
439+
307440
case INTELLITECH_PCL :
308441
/*
309442
* Set the media size...
@@ -685,6 +818,10 @@ EndPage(ppd_file_t *ppd, /* I - PPD file */
685818
puts("PRINT\r");
686819
break;
687820

821+
case BEEPRT :
822+
puts("\nPRINT 1,1\r");
823+
break;
824+
688825
case INTELLITECH_PCL :
689826
printf("\033*rB"); /* End GFX */
690827
printf("\014"); /* Eject current page */
@@ -880,6 +1017,21 @@ OutputLine(ppd_file_t *ppd, /* I - PPD file */
8801017
}
8811018
break;
8821019

1020+
case BEEPRT :
1021+
/* Convert 8-bit grayscale to 1-bit black and white */
1022+
for (i = 0; i < header->cupsBytesPerLine;) {
1023+
unsigned char out = 0;
1024+
unsigned char mask = 0x80;
1025+
1026+
for (; mask != 0 && i < header->cupsBytesPerLine; mask >>= 1) {
1027+
if (Buffer[i ++] <= 200) /* arbitrary threshold */
1028+
out |= mask;
1029+
}
1030+
putchar(~out);
1031+
}
1032+
fflush(stdout);
1033+
break;
1034+
8831035
case INTELLITECH_PCL :
8841036
if (Buffer[0] ||
8851037
memcmp(Buffer, Buffer + 1, header->cupsBytesPerLine - 1))

0 commit comments

Comments
 (0)