|
CUPS rastertoql filter
1.0.4
Filter for the Brother QL family of label printers
|
Common routines to deal with QL label printers. More...
Macros | |
| #define | BIT(x) (1 << (x)) |
| #define | QL_NO_COMPRESSION 0x00 |
| #define | QL_TIFF_COMPRESSION 0x02 |
| #define | QL_BI_COLOR 0x01 |
| #define | QL_CUT_AT_END 0x08 |
| #define | QL_HIGH_RESOLUTION 0x40 |
| #define | QL_AUTO_CUT 0x40 |
| #define | QL_CUT_EACH_LABEL 0 |
| #define | QL_WHAT_IS_BIT_0 0x01 |
| #define | QL_MEDIA_ENTRY_VALID 0x02 |
| #define | QL_WIDTH_ENTRY_VALID 0x04 |
| #define | QL_LENGTH_ENTRY_VALID 0x08 |
| #define | QL_RASTER_ENTRY_VALID 0x10 |
| #define | QL_HIGH_PRINT_QUALITY 0x40 |
| #define | QL_RECOVER_ENTRY_VALID 0x80 |
| #define | QL_MEDIA_TYPE_CONTINUOUS 0xa |
| #define | QL_MEDIA_TYPE_DIE_CUT 0xb |
| #define | QL_QUALITY_PRINT 0x40 |
| #define | QL_FAST_PRINT 0x00 |
Functions | |
| void | transform_to_monochrome (size_t input_cnt, const signed short input[input_cnt], unsigned char *data) |
| static int | ql_page_print (struct qldriver *ql) |
| static int | ql_last_page_print (struct qldriver *ql) |
| static int | ql_compression_setup (struct qldriver *ql, unsigned mode) |
| int | ql_auto_powerdown (struct qldriver *ql, unsigned short time_out) |
| int | ql_auto_powerup (struct qldriver *ql, unsigned short mode) |
| int | ql_reset (struct qldriver *ql) |
| static int | ql_invalidate_and_initialize (struct qldriver *ql) |
| static int | ql_extended_mode_set (struct qldriver *ql, unsigned value) |
| static int | ql_cut_mode_set (struct qldriver *ql, unsigned mode) |
| static int | ql_cut_on_label_n (struct qldriver *ql, unsigned cut_on_page) |
| static int | ql_notification_disable (struct qldriver *ql) |
| static int | ql_dynamic_mode (struct qldriver *ql) |
| static int | ql_define_tape_margins (struct qldriver *ql, uint16_t margins) |
| static int | ql_print_information (struct qldriver *ql, int media_type, int media_width, int media_length, int raster, int start_page, int quality) |
| int | ql_job_header_generate (struct qldriver *ql) |
| int | ql_job_footer_generate (struct qldriver *ql) |
| int | ql_page_header_generate (struct qldriver *ql, int first_time) |
Common routines to deal with QL label printers.
| #define BIT | ( | x | ) | (1 << (x)) |
Just a helper to write more readable code
| #define QL_AUTO_CUT 0x40 |
Bit to setup the printer into "auto cut" mode. Used in the ql_cut_mode_set() function as its mode parameter
| #define QL_BI_COLOR 0x01 |
Bit to setup the printer into bi-colour print mode. Used in the ql_extended_mode_set() function as its value parameter
| #define QL_CUT_AT_END 0x08 |
Bit to setup the printer into "cut when job is finished" mode. Used in the ql_extended_mode_set() function as its value parameter
| #define QL_CUT_EACH_LABEL 0 |
Default value for the ql_cut_on_label_n() function to define "cut each single label" To be used as its cut_on_page parameter.
| #define QL_FAST_PRINT 0x00 |
Always use with bi-colour printing (according to the datasheet)
| #define QL_HIGH_PRINT_QUALITY 0x40 |
| #define QL_HIGH_RESOLUTION 0x40 |
Bit to setup the printer into "high resolution" mode. E.g. 600 DPI in vertical direction. Used in the ql_extended_mode_set() function as its value parameter
| #define QL_LENGTH_ENTRY_VALID 0x08 |
| #define QL_MEDIA_ENTRY_VALID 0x02 |
| #define QL_MEDIA_TYPE_CONTINUOUS 0xa |
| #define QL_MEDIA_TYPE_DIE_CUT 0xb |
| #define QL_NO_COMPRESSION 0x00 |
Value to signal the printer, the print data will be sent without any compression. Used in the ql_compression_setup() function as its mode parameter
| #define QL_QUALITY_PRINT 0x40 |
never use while bi-colour printing (according to the datasheet)
| #define QL_RASTER_ENTRY_VALID 0x10 |
| #define QL_RECOVER_ENTRY_VALID 0x80 |
I found a hint. When set, it means: only print on labels of matching size
| #define QL_TIFF_COMPRESSION 0x02 |
Value to signal the printer, the print data will be sent in TIFF compression. Used in the ql_compression_setup() function as its mode parameter
| #define QL_WHAT_IS_BIT_0 0x01 |
Unknown meaning in the #print_inform::valid member
| #define QL_WIDTH_ENTRY_VALID 0x04 |
| int ql_auto_powerdown | ( | struct qldriver * | ql, |
| unsigned short | time_out | ||
| ) |
Set the printer's auto power down behaviour if it is idle
| [in] | ql | Full job description |
| [in] | time_out | Time out when idle to enter power down mode |
time_out can be:
If the printer enters the power down mode, it disconnects itself from the USB and can be re-enabled manually only with its local power button. This is a really bad idea for remote printers.
| int ql_auto_powerup | ( | struct qldriver * | ql, |
| unsigned short | mode | ||
| ) |
Set the printer's power up behaviour when connecting to external power
| [in] | ql | Full job description |
| [in] | mode | Power On mode |
mode can be:
|
static |
Setup the line data compression mode
| [in] | ql | Full job description |
| [in] | mode | Compression more, one of QL_NO_COMPRESSION or QL_TIFF_COMPRESSION |
| 0 | On success |
| Negative | Error code from the ql_printer_data_send() call |
|
static |
Setup "various mode"
| [in] | ql | Full job description |
| [in] | mode | Cutter mode, '0' or QL_AUTO_CUT |
| 0 | On success |
| Negative | Error code from the ql_printer_data_send() call |
|
static |
Setup the label count when to cut
| [in] | ql | Full job description |
| [in] | cut_on_page | Auto cut after this amount of pages (can be QL_CUT_EACH_LABEL for cut every label) |
| 0 | On success |
| Negative | Error code from the ql_printer_data_send() call |
|
static |
Setup the margins (top and bottom) to be used for this print
| [in] | ql | Full job description |
| [in] | margins | Top and bottom margins [dots] TODO maybe better in mm? |
| 0 | On success |
| Negative | Error code from the ql_printer_data_send() call |
Continuous tape:
cut cut
-----------|--------------------------------------------|--------------
| | | | | |
----->| | |<------- printable area ----------->| | |<---------
| | | | | |
-----------|--------------------------------------------|--------------
|<->|<->| < margins margins > |<->|<->|
Die-cut labels (assumption, but was wrong!):
cut cut
-----------|--------------------------------------------|-------------------
-------+ | +------------------------------------+ | +---------------
| | | | | |
------>| | |<---------- printable area -------->| | |<--------------
| | | | | |
-------+ | +------------------------------------+ | +---+-----------
-----------|--------------------------------------------|-------------------
Die-cut labels, margin handling (reality):
cut cut
-----------|--------------------------------------------|-------------------
-------+ | +------------------------------------+ | +---------------
| | | | | | | |
------>| | | |<------- printable area ----->| | | |<--------------
| | | | | | | |
-------+ | +------------------------------------+ | +---+-----------
-----------|--------------------------------------------|-------------------
|<->|<>| < margins margins > |<>|<->|
^---- implicit margin added by the printer
^------- implicit margin added by the printer
*
|
static |
Configure the printer to a sepcifc "dynamic mode"
| [in] | ql | Full job description |
| 0 | On success |
| Negative | Error code from the ql_printer_data_send() call |
For some QL models this has to be done at most once per run-time. The printer operates in this mode until it is turned off again. But read the note below!
|
static |
Send expanded mode
| [in] | ql | Full job description |
| [in] | value | Ored list of of QL_BI_COLOR, QL_CUT_AT_END or QL_HIGH_RESOLUTION |
| 0 | On success |
| Negative | Error code from the ql_printer_data_send() call |
|
static |
Start a new print job from the printer's point of view
| [in] | ql | Full job description |
| 0 | On success |
| Negative | Error code from the ql_printer_data_send() call |
To be sent at the beginning of a new print job or if the current processing has to be stopped at the printer's side.
From the datasheet: "If data transmission is to be stopped midway, send the “initialize” command after sending the “invalidate” command for the appropriate number of bytes to return to the receiving state, where the print buffer is cleared."
| int ql_job_footer_generate | ( | struct qldriver * | ql | ) |
Send the footer commands after a print job
| [in] | ql | Full job description |
Called once per print job at the end. But only:
| int ql_job_header_generate | ( | struct qldriver * | ql | ) |
Send the heading commands to setup the printer prior a print job
| [in] | ql | Full job description |
Called once per print job at the beginning
|
static |
Finish the current print job
| [in] | ql | Full job description |
| 0 | On success |
| Negative | Error code from the ql_printer_data_send() call |
This code is to be sent after the last page to finish the whole print job.
|
static |
Disable the printer's notification capability
| [in] | ql | Full job description |
| 0 | On success |
| Negative | Error code from the ql_printer_data_send() call |
We do not have a real back channel, so we can't recieve its data
| int ql_page_header_generate | ( | struct qldriver * | ql, |
| int | first_time | ||
| ) |
| [in] | ql | Full job description |
| [in] | first_time | Flag if called the first time in a print job |
| 0 | On success |
| -ENODEV | Device seems gone (e.g. channel to the next stage is gone) |
Called once per page at the beginning
Deal with QL_FAST_PRINT/QL_QUALITY_PRINT for monochrome use case
Do the QL_QUALITY_PRINT and QL_HIGH_RESOLUTION bits depend on each other?
Deal with auto cut setting and when to cut (and if the printer has a cutter). To make it simple: only "cut at end" and "cut each" should be supported
|
static |
Finish the current page
| [in] | ql | Full job description |
| 0 | On success |
| Negative | Error code from the ql_printer_data_send() call |
This code is to be sent after a page.
It seems, this command is only to be sent, if more than one page in one job should be printed. If the job contains only one page, the ql_last_page_print() is enough to do the right thing.
|
static |
Send information about the job or the next page
| [in] | ql | Full job description |
| [in] | media_type | QL_MEDIA_TYPE_CONTINUOUS or QL_MEDIA_TYPE_DIE_CUT, negative value for not defined |
| [in] | media_width | Width of the to be printed medium in [mm], negative value for not defined |
| [in] | media_length | Length of the to be printed media in [mm] ('0' for continuous roll), negative value for not defined |
| [in] | raster | Count of rasterlines of one "page", negative value for not defined |
| [in] | start_page | '0' for the first page, '1' for continuous page |
| [in] | quality | QL_QUALITY_PRINT or QL_FAST_PRINT |
| 0 | On success |
| Negative | Error code from the ql_printer_data_send() call |
The manual encodes this info (as an example):
into:
1b 69 7A 8F 0B 1D 5A DF 03 00 00 00 00
^^___ Starting page
^^_^^_^^_^^______ 991 raster lines ~83 mm
^^__________________ 90 mm length
^^_____________________ 29 mm width
^^________________________ Media type: die cut
^^___________________________ 8F: 10x0 1111
^_ ????
^__ Media type valid
^___ Width valid
^____ Length valid
^______ Raster invalid (vague interpretation!)
^________ fast print
^_________ RecoveryFor the DK1201 roll (die-cut 29 mm x 90 mm label), the QL800 datasheet defines:
| int ql_reset | ( | struct qldriver * | ql | ) |
Initialize/reset the printer
| [in] | ql | Full job description |
| 0 | On success |
| Negative | Error code from the ql_printer_data_send() call |
This command can also be used every time to terminate a current print
| void transform_to_monochrome | ( | size_t | input_cnt, |
| const signed short | input[input_cnt], | ||
| unsigned char * | data | ||
| ) |
Convert an array of signed shorts into a monochrome pattern (one signed short into one bit)
| [in] | input_cnt | Count of pixel in input |
| [in] | input | Where to get the quantized input data |
| [out] | data | Where to store the converted output data |
1.8.17