T168_111\appl\Parser\Dpl文件:中间5个独立文件

DplFuncSysLv.c  、、、、、、、、、、、、、、、、、、、、、、

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define DPLFUNCSYSLV_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <time.h>
#include <string.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XRTC.h"
#include "XAppVer.h"
#include "XFunction.h"
#include "..\ParserUtil.h"
#include "DplCtrlCode.h"
#include "DplConfig.h"
#include "DplUtil.h"
#include "DplModule.h"
#include "DplLabel.h"
#include "DplFunc.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#if defined(DPL)

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

//------------------------------------------------------------------------------
// Extended System-Level Command Functions ( DplFuncExtSysLv.c )
//------------------------------------------------------------------------------

_CmdEntry DplExtSysLvEntry[] =
{
     {"}",            Ext_Cal},        // Calibration (Non-Display Models only)
    {"a",            Ext_a},            // Direct Mode - Generic Read/Write Interface
    {"b",            Ext_b},            // Backfeed Time Delay
    {"C",            Ext_C},            // Get Configuration
    {"c",            Ext_c},            // Configuration Set
    {"D",            Ext_D},            // Database Configuration (Non-Display Models only)
    {"d",            Ext_d},            // Set File as Factory Default
    {"E",            Ext_E},            // Character Encoding
    {"F",            Ext_F},            // Select Factory Defaults (Display-Equipped and EX2 Models only)
    {"f",            Ext_f},            // Set Present Distance
    {"J",            Ext_J},            // Assign Communication Port (MCL Command)
    {"I",            Ext_I},            // GPIO Input
    {"I",            Ext_M},            // Memory Configuration (Non-Display Models only)
    {"n",            Ext_n},            // NIC Reset
    {"O",            Ext_O},            // GPIO Output
    {"p",            Ext_p},            // Module Protection
    {"Q",            Ext_Q},            // Query Memory Configuration
    {"q",            Ext_q},            // Query Memory Configuration (Display-Equipped Models only)
    {"R",            Ext_R},            // Reset Memory Configuration
    {"r",            Ext_r},            // Resettable Counter Reset
    {"S",            Ext_S},            // Memory Configuration, Scalable Font Cache
    {"t",            Ext_t},            // Direct Mode - HF [13.56 MHz] ISO15693 Tag Interface
    {"u",            Ext_u},            // Direct Mode - UHF Interface
    {"V",            Ext_V},            // Verifier Enable/Disable
    {"W",            Ext_W},            // Memory Configuration, Printable Label Width
    {"x",            Ext_x},            // Delete Configuration File
    {"Z",            Ext_Z},            // Immediately Set Parameter
    {(CHAR *)_NULL,    _NULL}
};

//------------------------------------------------------------------------------
// Label Formatting Command Functions ( DplFuncLabFmt.c )
//------------------------------------------------------------------------------

_CmdEntry DplLabFmtEntry[] =
{
    {":",            Lab_Cut},        // Set Cut By Amount
    {"A",            Lab_A},            // Set Format Attribute
    {"B",            Lab_B},            // Bar Code Magnification
    {"C",            Lab_C},            // Set Column Offset Amount
    {"c",            Lab_c},            // Set Cut By Amount
    {"D",            Lab_D},            // Set Dot Size Width and Height
    {"E",            Lab_E},            // Terminate Label Formatting Mode and Print Label
    {"e",            Lab_e},            // Recall Printer Configuration
    {"F",            Lab_F},            // Advanced Format Attributes
    {"f",            Lab_f},            // Set Present Speed
    {"G",            Lab_G},            // Place Data in Global Register
    {"H",            Lab_H},            // Enter Heat Setting
    {"J",            Lab_J},            // Justification
    {"M",            Lab_M},            // Select Mirror Mode
    {"m",            Lab_m},            // Set Metric Mode
    {"n",            Lab_n},            // Set Inch (Imperial) Mode
    {"P",            Lab_P},            // Set Print Speed
    {"p",            Lab_p},            // Set Backfeed Speed
    {"Q",            Lab_Q},            // Set Quantity of Labels to Print
    {"R",            Lab_R},            // Set Row Offset Amount
    {"r",            Lab_r},            // Recall Stored Label Format
    {"S",            Lab_S},            // Set Feed Speed
    {"s",            Lab_s},            // Store Label Format in Module
    {"T",            Lab_T},            // Set Field Data Line Terminator
    {"U",            Lab_U},            // Mark Previous Field as a String Replacement Field
    {"X",            Lab_X},            // Terminate Label Formatting Mode
    {"y",            Lab_y},            // Select Font Symbol Set
    {"z",            Lab_z},            // Zero (O) Conversion to "0"
    {"+",            Lab_IncNum},    // Make Last Field Entered Increment Numeric
    {">",            Lab_IncAlpha},    // Make Last Field Entered Increment Alphanumeric
    {"(",            Lab_IncHex},    // Make Last Field Entered Increment Hexadecimal
    {"-",            Lab_DecNum},    // Make Last Field Entered Decrement Numeric
    {"<",            Lab_DecAlpha},    // Make Last Field Entered Decrement Alphanumeric
    {")",            Lab_DecHex},    // Make Last Field Entered Decrement Hexadecimal
    {(CHAR *)_NULL,    _NULL}
};

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/


/******************************************************************************
 *
 * DPL Commands:
 *        Set Time and Date
 *
 * Description:
 *        This command sets the time and date. The initial setting of the date
 *        will be stored in the printer's internal inch counter. This date can
 *        be verified by printing a Configuration Label.
 *
 * Syntax:
 *        <STX>AwmmddyyyyhhMMjjj
 *
 * Where:
 *        w    - 1 digit  for day of week; 1 = Monday; 7 = Sunday
 *        mm   - 2 digits for month
 *        dd   - 2 digits for day
 *        yyyy - 4 digits for year
 *        hh   - 2 digits for hour in 24 hour format
 *        MM   - 2 digits for minutes
 *        jjj  - 3 digits for Julian date (numerical day of the year) / constant
 *
 ******************************************************************************/
INT Sys_A(VOID)
{
    STATIC CONST CHAR *WeekName[] =
        { "Sun","Mon","Tues","Wed","Thur","Fri","Sat" };
    STATIC CONST CHAR *MonthName[] =
        { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };

    LONG Num;
    struct tm gmt;
    time_t t;

    // w    - 1 digit  for day of week
    if (DmxGetNumber(&Num, 1) != 1)
        return _ERROR;
    gmt.tm_wday = (Num % 7);    // 1 = Monday, 7 = Sunday

    // mm   - 2 digits for month
    if (DmxGetNumber(&Num, 2) != 2)
        return _ERROR;
    gmt.tm_mon = (Num - 1);

    // dd   - 2 digits for day
    if (DmxGetNumber(&Num, 2) != 2)
        return _ERROR;
    gmt.tm_mday = Num;

    // yyyy - 4 digits for year
    if (DmxGetNumber(&Num, 4) != 4)
        return _ERROR;
    gmt.tm_year = (Num - 1900);

    // hh   - 2 digits for hour
    if (DmxGetNumber(&Num, 2) != 2)
        return _ERROR;
    gmt.tm_hour = Num;        // In 24 hour format

    // MM   - 2 digits for minutes
    if (DmxGetNumber(&Num, 2) != 2)
        return _ERROR;
    gmt.tm_min = Num;

    // jjj  - 3 digits for Julian date (numerical day of the year) / constant
    if (DmxGetNumber(&Num, 3) != 3)
        return _ERROR;
    gmt.tm_yday = Num;

    SendPrintf("%s. %s %d, %d, %d:%d%s, %03d\r",
        WeekName[gmt.tm_wday],
        MonthName[gmt.tm_mon],
        gmt.tm_mday,
        gmt.tm_year + 1900,
        (gmt.tm_hour % 12) ? (gmt.tm_hour % 12) : 12,
        gmt.tm_min,
        (gmt.tm_hour < 12) ? "AM" : "PM",
        gmt.tm_yday);

    t = mktime(&gmt);
    stime(&t);

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Enable Feedback Characters
 *
 * Description:
 *        This command enables the feedback ASCII hex characters to be returned
 *        from the printer following specific events after each completed batch
 *        of labels when using serial communications. The default value is 'Off'.
 *
 * Syntax:
 *        <STX>a
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_a(VOID)
{
    pDmxCfg->FeedbackMode = 'Y';
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Get Printer Time and Date Information
 *
 * Description:
 *        This command instructs the printer to retrieve its internal time and
 *        date information.
 *
 * Syntax:
 *        <STX>B
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_B(VOID)
{
    time_t t = time(_NULL);
    struct tm gmt = *gmtime(&t);

    // Printer response format: wmmddyyyyhhMMjjj<CR>
    SendPrintf("%01d%02d%02d%04d%02d%02d%03d\r",
        gmt.tm_wday ? gmt.tm_wday : 7,
        gmt.tm_mon + 1, gmt.tm_mday,
        gmt.tm_year + 1900,
        gmt.tm_hour,
        gmt.tm_min,
        gmt.tm_yday);

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Continuous Paper Length
 *
 * Description:
 *        This command sets the label size for applications using continuous media.
 *        It disables the top-of-form function performed by the Media Sensor. The
 *        sensor, however, continues to monitor paper-out conditions. See <STX>M.
 *
 * Syntax:
 *        <STX>cnnnn
 *
 * Where:
 *        nnnn - Specifies the length of the media feed for each label format, in
 *               inches/100 or millimeters/10 (see <STX>m).
 *
 ******************************************************************************/
INT Sys_c(VOID)
{
    LONG Num;

    if (DmxGetNumber(&Num, 4) != 4)
        return _ERROR;

    if (Num > 0)
    {
        pDmxCfg->ContinuousLabelLength = TransformDot(Num, pDmxCfg->UnitMeasure);
        pDmxCfg->SensorType = CONTINUOUS_SENSOR_TYPE;
        SelectSensorType(CONTINUOUS_SENSOR_TYPE);
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Double Buffer Mode (Non-Display Models only)
 *
 * Description:
 *        This command, available for backward compatibility, enables double buffer
 *        mode. When printing labels with incrementing, decrementing and replacement
 *        fields the printer will only erase and format those fields, leaving the
 *        rest of the label format untouched, and thus increasing throughput. This
 *        command is only active if the labels being printed are less than half the
 *        maximum size of the print buffer (see <STX>S).
 *
 * Syntax:
 *        <STX>d
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_d(VOID)
{
    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
        pDmxCfg->ImagingMode = MULTIPLE_LABEL;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Quantity For Stored Label
 *
 * Description:
 *        This command sets the number of labels for printing using the format
 *        currently in the print buffer. (The printer automatically stores the
 *        most recent format received in the buffer until the printer is reset
 *        or power is removed.) When used in conjunction with the <STX>G command,
 *        this will print the labels.
 *
 * Syntax:
 *        <STX>Ennnn
 *
 * Where:
 *        nnnn - A four-digit quantity, including leading zeros.
 *
 ******************************************************************************/
INT Sys_E(VOID)
{
    LONG Num;

    if (DmxGetNumber(&Num, 4) != 4)
        return _ERROR;

    LabelQuantity = Num;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Select Edge Sensor
 *
 * Description:
 *        This command enables transmissive (see-through) sensing for top-of-form
 *        detection of die-cut, and holed (or notched) media. This Media Sensor
 *        will detect a minimum gap of 0.1 inches (2.5 mm) between labels (see the
 *        Operator's Manual for media requirements). Use the <STX>O command to
 *        adjust the print position. This is the printer default setting at power-
 *        up or reset.
 *
 * Syntax:
 *        <STX>e
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_e(VOID)
{
    pDmxCfg->SensorType = EDGE_SENSOR_TYPE;
    SelectSensorType(EDGE_SENSOR_TYPE);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Form Feed
 *
 * Description:
 *        This commands the printer to form feed to the next start of print.
 *
 * Syntax:
 *        <STX>F
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_F(VOID)
{
    _PrintCfg cfg = *pPrintCfg;

    TransformPrintConfig(&cfg);
    if (pDmxCfg->SensorType == CONTINUOUS_SENSOR_TYPE)
        cfg.fPaperSize = (FLOAT)pDmxCfg->ContinuousLabelLength;
    FeedBatch(1, &cfg, TRUE, _NULL);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Form Stop Position (Backfeed Command)
 *
 * Description:
 *        This sets the stop position of the printed label, allowing the label to
 *        stop at a point past the start-ofprint position. When the next label
 *        format is sent, the printer motor reverses direction to retract the media
 *        to the start-of-print position. If quantities of more than one label are
 *        requested, the printer will operate without backfeeding. A backfeed will
 *        then only occur when printing has stopped for a few seconds.
 *
 *        Non-Display Models: The printer Option Control must be set (via the menu)
 *                            to 'Host' for this command to have effect.
 *
 *        Display-Equipped Models: This command is not honored, see <STX>Kf and <STX>Kc.
 *
 * Syntax:
 *        <STX>fnnn
 *
 * Where:
 *        nnn - Is a three-digit distance from the Media Sensor, in inches/100 or
 *              mm/10. This distance is independent of the start-of-print position
 *              (<STX>O), yet it must be greater than the start-of-print position to
 *              take effect.
 *
 ******************************************************************************/
INT Sys_f(VOID)
{
    LONG Num;

    // nnn - Is a three-digit distance
    if (DmxGetNumber(&Num, 3) != 3)
        return _ERROR;

    FormStopPosition = TransformDot(Num, pDmxCfg->UnitMeasure);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Print Last Label Format
 *
 * Description:
 *        This command prints a previously formatted label and restarts a canceled
 *        batch job following the last processed label. This is used when there is
 *        a label format in the buffer. The <STX>E command is used to enter the
 *        quantity. (If the <STX>E command is not used only one label will print.)
 *
 * Syntax:
 *        <STX>G
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_G(VOID)
{
    PrintLabelFormat(LabelQuantity);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Input Image Data
 *
 * Description:
 *        This command must precede image downloading from a host computer to the
 *        printer. The data that immediately follows the command string will be
 *        image data. If any of the 8-bit input formats are to be used, it is
 *        necessary to disable the Immediate Command interpreter by executing an
 *        <SOH>D command before issuing the <STX>I command. See Appendix O for
 *        more information. To print an image, see Generating Label Formats.
 *
 * Syntax:
 *        <STX>Iabfnn..n<CR>data
 *
 * Where:
 *        a     - Memory Module Bank Select (see Appendix K).
 *        b     - Data Type (optional), A or omit.
 *                 b Value:  Image Data Value Range:
 *                 - A       - ASCII Characters 0-9, A-F, (7 bit)
 *                 - omitted - 00-FF, (8 bit)
 *
 *        f     - Format Designator
 *                 f Designator: Format Type:
 *                 - F           -      7-bit Datamax image load file
 *                 - B           - .BMP 8-bit format (image flipped), black and white (B&W)
 *                 - b           - .BMP 8-bit format (image as received), B&W
 *                 - I           - .IMG 8-bit format (image flipped), B&W
 *                 - i           - .IMG 8-bit format (image as received), B&W
 *                 - P           - .PCX 8-bit format (image flipped), B&W
 *                 - p           - .PCX 8-bit format (image as received), B&W
 *
 *        nn..n - Up to 16 characters used as an image name.
 *        <CR>  - 0x0d terminates the name.
 *        data  - Image data
 *
 ******************************************************************************/
INT Sys_I(VOID)
{
    CHAR ModuleBank;
    CHAR DataType;
    CHAR FormatType;
    CHAR Name[17];

    // Memory Module Bank Select
    ModuleBank = DmxNextByte();

    // Data Type (optional)
    DataType = DmxNextByte();

    // Format Designator
    FormatType = DataType;
    if (DataType == 'A')
        FormatType = DmxNextByte();

    if (DmxGetString(Name, sizeof(Name)) > 16)
        return _ERROR;

    SaveImageFile(ModuleBank, Name, FormatType);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Scalable Font Downloading
 *
 * Description:
 *        The command structure for downloading TrueType (.TTF) scalable fonts
 *        (font files may be singlebyte or double-byte character systems) is as follows:
 *
 * Syntax:
 *        <STX>imtnnName<CR>xx..xdata...
 *
 * Where:
 *        m     - Memory Module Designator to save this font to; see Appendix K.
 *        t     - Type of scalable font being downloaded: T = TrueType
 *        nn    - Two-digit font reference ID. Valid range is 50-99, 9A-9Z, 9a-9z,
 *                (base 62 numbers).
 *        Name  - The title, up to 16 characters, for this font.
 *        <CR>  - 0x0d terminates the Name.
 *        xx..x - Eight-digit size of the font data, number of bytes, hexadecimal,
 *                padded with leading zeros.
 *        data  - The scalable font data.
 *
 ******************************************************************************/
INT Sys_i(VOID)
{
    CHAR MemoryModule;
    CHAR FontType;
    CHAR FontID[2];
    CHAR Name[17];

    // m     - Memory Module
    MemoryModule = DmxNextByte();

    // t     - Type of scalable font
    FontType = DmxNextByte();

    // nn    - Two-digit font reference ID
    if (!DmxGetAlpha(FontID, 2))
        return _ERROR;

    // Name  - The title, up to 16 characters, for this font
    if (DmxGetString(Name, sizeof(Name)) > 16)
        return _ERROR;

    DownloadScalableFont(MemoryModule, FontID, Name, FontType);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Pause for Each Label
 *
 * Description:
 *        This command causes the printer to pause after printing each label. It
 *        is intended for use with the peel mechanism or tear bar when the Present
 *        Sensor option is not installed. After removing the printed label, the
 *        PAUSE Key must be pushed in order to print the next label.
 *        (The printer must be reset to clear the <STX>J command.)
 *
 * Syntax:
 *        <STX>J
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_J(VOID)
{
    pDmxCfg->PauseMode = 'Y';
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Extended System-Level Commands
 *
 * Description:
 *        This is an expansion of the System-Level Command structure.
 *        See Extended System-Level Commands for more information.
 *
 * Syntax:
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_K(VOID)
{
    _CmdEntry *CmdEntry;
    CHAR data;

    data = DmxNextByte();
    if (CmdEntry = CheckSingleCommand(data, DplExtSysLvEntry))
        return CmdEntry->func();
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Test RS-232 Port
 *
 * Description:
 *        This command instructs the printer to transmit the Y character from the
 *        printer's RS-232 port.
*        (Failure to receive Y could indicate an interfacing problem.)
 *
 * Syntax:
 *        <STX>k
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_k(VOID)
{
    // Printer response: Y
    UartChar('Y');
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Enter Label Formatting Command Mode
 *
 * Description:
 *        This command switches the printer to the Label Formatting Command Mode.
 *        Once in this mode, the printer expects to receive Record Structures and
 *        Label Formatting Commands. Immediate, System-Level, and Font Loading
 *        commands will be ignored until the label formatting mode is terminated
*        with E, s, or X, (see Label Formatting Commands for additional information).
 *
 * Syntax:
 *        <STX>L
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_L(VOID)
{
    _CmdEntry *CmdEntry;
    CHAR data;
    INT Status;

    InitialLabelFormat();

    if (pDmxCfg->SensorType == CONTINUOUS_SENSOR_TYPE)
        SetContinuousPaperLength(pDmxCfg->ContinuousLabelLength);

    ReallocImageBuffer(&sImageBuffer, MIN(pDmxCfg->MaximumLength, HALF_IMAGE_LENGTH));
    ClearImageBuffer(&sImageBuffer);

    ClearLabelStore();

    LabFmtCmdMod = TRUE;
    while (LabFmtCmdMod)
    {
        Status = _ERROR;

        data = LabNextByte();

        // Set Count By Amount
        if (data == CtrlCode.CNT)
            Status = Lab_Cnt();

        // The Structure of a Record
        else if (data >= '1' && data <= '4')
            Status = Lab_Rec(data);

        // Label Formatting Command Functions
        else if (CmdEntry = CheckSingleCommand(data, DplLabFmtEntry))
            Status = CmdEntry->func();

        // Remove character
        else if (Status == _ERROR)
            Status = _SUCCESS;

        if (Status == _ERROR)
            LabRemoveUntilTerm();

        SetLabelTerminat();
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Maximum Label Length
 *
 * Description:
 *        This command instructs the printer move media this distance in search of
 *        the top-of-form (label edge, notch, black mark, etc.) before declaring a
 *        paper fault. A paper fault condition can occur if this setting is too close
 *        (within 0.1 inch [2.54 mm]) to the physical length of the label. Therefore,
 *        it is a good practice to set this command to 2.5 to 3 times the actual label
 *        length used. The minimum value should be at least 5" (127 mm).
 *
 * Syntax:
 *        <STX>Mnnnn
 *
 * Where:
 *        nnnn - Is a four-digit length, 0000-9999, in/100 or mm/10. Maximum
 *               setting is 9999 (99.99 inches or 2540 mm). The default setting is
 *               16 inches/ 406.4 mm
 *
 ******************************************************************************/
INT Sys_M(VOID)
{
    LONG Num;

    // nnn - Is a four-digit length
    if (DmxGetNumber(&Num, 4) != 4)
        return _ERROR;

    if (pDmxCfg->MaximumLengthIgnore == '0')
        pDmxCfg->MaximumLength = TransformDot(Num, pDmxCfg->UnitMeasure);

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Printer to Metric Mode
 *
 * Description:
 *        This command sets the printer to interpret measurements as metric values
 *        (e.g., <STX>c0100 will equal 10.0 mm). The default is Imperial (see <STX>n).
 *
 * Syntax:
 *        <STX>m
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_m(VOID)
{
    pDmxCfg->UnitMeasure = METRIC_MODE;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Printer to Imperial Mode
 *
 * Description:
 *        This command sets the printer to interpret measurements as inch values
 *        (e.g., <STX>c0100 will equal 1.00 inch). The printer defaults to this mode.
 *
 * Syntax:
 *        <STX>n
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_n(VOID)
{
    pDmxCfg->UnitMeasure = INCH_MODE;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Start of Print (SOP) Position
 *
 * Description:
 *        This command sets the point to begin printing relative to the top-of-form
 *        (the label's edge as detected by the Media Sensor). The printer will feed
 *        from the top-of-form to the value specified in this command to begin printing.
 *
 *        This value operates independently of the <STX>f command.
 *
 *        Non-Display Models: The printer Options Control must be set (via the menu)
 *                            to 'Host' for this command to have effect.
 *
 *        Display-Equipped Models: If SOP Emulation is set to 'enabled' (via the menu),
 *                                 this command sets the point where printing starts,
 *                                 emulating the selected legacy printer's distance,
 *                                 as measured between the media sensor and the print
 *                                 head burn line. In addition, regardless of the SOP
 *                                 Emulation setting, the start of print position can
 *                                 be fine-tuned via the menu:
 *                                 Menu Mode / Print Control / Custom Adjustments / Row Adjust.
 *
 * Syntax:
 *        <STX>Onnnn
 *
 * Where:
 *        nnnn - Is a four-digit offset value in inches/100 or mm/10. The "zero"
 *               setting is the default value, and settings below 50 are adjusted
 *               back to the default value.
 *
 *               Non-Display Models: the default setting is 0220 in Imperial Mode
 *                   (0559 in Metric Mode).
 *
 *               Display-Equipped Models: the default setting is 'Off' and the
 *                   printer assumes the natural start of print position.
 *
 ******************************************************************************/
INT Sys_O(VOID)
{
    LONG Num;

    // nnn - Is a four-digit offset value
    if (DmxGetNumber(&Num, 4) != 4)
        return _ERROR;

    StartOfPrint = TransformDot(Num, pDmxCfg->UnitMeasure);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Cycle Cutter
 *
 * Description:
 *        This command will cause the optional cutter mechanism to immediately
 *        perform a cut after all previously received commands are executed. The
 *        cutter must be installed, enabled and the interlock(s) closed for operation.
 *
 * Syntax:
 *        <STX>o
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_o(VOID)
{
    CutPaper();
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Hex Dump Mode
 *
 * Description:
 *        This command instructs the printer to assume Hex Dump Mode. Instead of a
 *        formatted product, data sent to the printer following this command will
 *        be printed in the raw ASCII format. To capture this data, labels must be
 *        at least four inches (102 mm) long and as wide as the maximum print width.
 *        This command has the same effect as turning the printer 'On' while pressing
 *        the FEED Key; however, no Configuration/Test Pattern label will be printed.
 *        To return to normal operation the printer must be manually reset.
 *
 * Syntax:
 *        <STX>P
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_P(VOID)
{
    HexDumpMode();
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Controlled Pause
 *
 * Description:
 *        The controlled pause command will cause the printer to pause only after all
 *        previously received commands are executed. This is often useful between
 *        label batches. (This command will not clear the pause condition, see <SOH>B).
 *
 * Syntax:
 *        <STX>p
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_p(VOID)
{
    ControlledPause();
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Clear All Modules
 *
 * Description:
 *        This command instructs the printer to clear all of the Flash and DRAM
 *        modules (see the Operator's Manual of the corresponding printer for
 *        applicable module options). All stored data will be destroyed.
 *
 * Syntax:
 *        <STX>Q
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_Q(VOID)
{
    ErasingFile(DRAM_DEVICE,  "*");
    ErasingFile(FLASH_DEVICE, "*");
    ErasingFile(CARD_DEVICE,  "*");
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Clear Module
 *
 * Description:
 *        This command clears the selected Flash or DRAM module. If a module is
 *        corrupted during normal operations (identifiable when the printer responds
 *        with a 'No Modules Available' message to a <STX>W command), it must be
 *        cleared. All stored data will be destroyed.
 *
 * Syntax:
 *        <STX>qa
 *
 * Where:
 *        a - Memory module designator, see Appendix K.
 *
 ******************************************************************************/
INT Sys_q(VOID)
{
    CHAR Module;

    // a - Memory module designator
    Module = DmxNextByte();

    ErasingFile(TransformFileDevice(Module),  "*");
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Ribbon Saver On/Off (Display-Equipped Models only)
 *
 * Description:
 *        This command enables the operation of the optional Ribbon Saver. It is the
 *        only command used to control the Ribbon Saver. Its operation is continuous
 *        when enabled. The printer must be set to thermal transfer (ribbon) printing
 *        mode then, during operation, the Ribbon Saver engages automatically,
 *        lifting when the minimum amount of label white space is exceeded.
 *
 * Syntax:
 *        <STX>Rx
 *
 * Where:
 *        x - Y - Enabled (Default = Menu selection.)
 *            N - Disabled
 *
 ******************************************************************************/
INT Sys_R(VOID)
{
    CHAR Saver;

    Saver = DmxNextByte();

    // Supported series
    if (DatamaxModel.Series == DMX_A_CLASS || DatamaxModel.Series == DMX_W_CLASS)
    {
        if (Saver == 'Y')
            Saver = EQUIPPED_AUTO;
        if (pDmxCfg->RibbonSaverEquipped != Saver)
        {
            pDmxCfg->RibbonSaverEquipped = Saver;
            SenseRibbonSaverOption(Saver);
        }
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Select Reflective Sensor
 *
 * Description:
 *        This command enables reflective (black mark) sensing for top-of-form
 *        detection of rolled butt-cut, and fan-fold or tag stocks with reflective
 *        marks on the underside. This Media Sensor will detect a minimum mark of
 *        0.1 inches (2.54 mm) between labels (see the Operator's Manual for media
 *        requirements). The end of the black mark determines the top of form.
 *        Use the <STX>O command to adjust the print position.
 *
 * Syntax:
 *        <STX>r
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_r(VOID)
{
    pDmxCfg->SensorType = REFLECTIVE_SENSOR_TYPE;
    SelectSensorType(REFLECTIVE_SENSOR_TYPE);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Feed Speed
 *
 * Description:
 *        This command controls the output rate of the media when the FEED Key is pressed.
 *
 * Syntax:
 *        <STX>Sn
 *
 * Where:
 *        n - Is a letter value (see Appendix L).
 *
 ******************************************************************************/
INT Sys_S(VOID)
{
    CHAR Speed;

    Speed = DmxNextByte();

    // Valid ranges
    if (Speed  >= DatamaxModel.FeedSpeed.Minimum &&
        Speed  <= DatamaxModel.FeedSpeed.Maximum)
        pDmxCfg->FeedSpeed = Speed;

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Single Buffer Mode (Non-Display Models only)
 *
 * Description:
 *        This command, available for backward compatibility, instructs the printer
 *        to use single buffer operation. In single buffer mode, the printer will
 *        erase and format all fields. This, in turn, decreases printer throughput
 *        when incrementing, decrementing, or replacement fields are used (see Label
 *        Formatting Commands). See <STX>d.
 *
 * Syntax:
 *        <STX>s
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_s(VOID)
{
    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
        pDmxCfg->ImagingMode = SINGLE_LABEL;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Print Quality Label
 *
 * Description:
 *        This command instructs the printer to produce a Print Quality label, a format
 *        comprised of different patterns and bar codes useful in printer setup.
 *        (On display-equipped models, this is also one of the Quick Test formats.)
 *        To capture all printed information, use the labels as wide as the maximum
 *        print width (see Appendix K) and at least four inches (102 mm) long.
 *
 * Syntax:
 *        <STX>T
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_T(VOID)
{
    // ... not finish
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Test DRAM Memory Module
 *
 * Description:
 *        This command tests the DRAM module. The printer returns a one-line message
 *        stating the module condition (no message is returned if a module is unavailable).
 *
 * Syntax:
 *        <STX>t
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_t(VOID)
{
    SendPrintf("Good\r");
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Label Format String Replacement Field
 *
 * Description:
 *        This command places new label data into format fields to build a label.
 *        Two options are available: Exact Length and Truncated Length.
 *        To easily keep track of fields, place all of the fields to be updated
 *        with the command at the beginning of the label format. A maximum of 99
 *        format fields can be updated. Fields are numbered consecutively 01 to 99
 *        in the order received.
 *
 * Exact Length Replacement Field Functions -
 *        The new data string must equal the original string length and contain
 *        valid data. When the dynamic data is shorter than the length of the
 *        originally defined data field, then field will be padded with blanks
 *        (or zero when the Format Record header specifies a numeric bar code).
 *
 * Syntax:
 *        <STX>Unnss..s<CR>
 *
 * Where:
 *        nn    - Is the format field number, 2 digits.
 *        ss..s - Is the new string data, followed by a <CR>
 *
 * Truncated Length Replacement Field Functions -
 *        A variant of the <STX>U command includes the truncate option 'T', where dynamic
 *        data shorter than the originally defined field length will not be padded and
 *        the original maximum field length is maintained for subsequent replacements.
 *
 * Syntax:
 *        <STX>UTnnss..s<CR>
 *
 * Where:
 *        nn    - Is the format field number, 2 digits.
 *        T     - Truncate option
 *        ss..s - Is the new string data, followed by a <CR>
 *
 ******************************************************************************/
INT Sys_U(VOID)
{
    _LabRecData RecData;
    CHAR Truncate;
    LONG Num;

    // T     - Truncate option
    Truncate = DmxNextByte();
    if (Truncate != 'T')
        DmxBackByte(Truncate);

    // nn    - Is the format field number, 2 digits.
    if (DmxGetNumber(&Num, 2) != 2)
        return _ERROR;

    // ss..s - Is the new string data, followed by a <CR>
    RecData.Length = DmxGetString(RecData.Content, sizeof(RecData.Content));

    ReplacePreviousField((INT)Num, Truncate, &RecData);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Software Switch Settings
 *
 * Description:
 *        This command controls the printer options, where the appropriate value
 *        allows the option(s) to be 'On' or 'Off'. Each option has a corresponding
 *        bit whose value is '1' when enabled. The tables below indicate the bit
 *        assignments and corresponding command value needed to enable the desired
 *        option(s).
 *
 *        Display-Equipped Models: Printer options are set by entering selections
 *                                 through the menu. The software setting command
 *                                 allows two of these option settings to be modified
 *                                 without returning to the menu.
 *
 * Syntax:
 *        <STX>Vn
 *
 * Where:
 *        n - Is a single digit ASCII numeric value from 0-F. The value of n is
 *            used to override the power-up option settings. Reset or power-up
 *            returns the printer to the original settings.
 *
 ******************************************************************************/
INT Sys_V(VOID)
{
    CHAR Cutter = EQUIPPED_DISABLE;
    CHAR PresentSensor = EQUIPPED_DISABLE;
    CHAR value;

    /*************************************
     * Bit Assignment | Printer Option   *
     *  0             |  Cutter          *
     *  1             |   N/A            *
     *  2             |  Present Sensor  *
     *  3             |   N/A            *
     *************************************/

    // n - Is a single digit ASCII numeric value from 0-F.
    value = DmxNextByte();

    if (value & (1 << 0))    // Cutter Option
    {
        if (DatamaxModel.Display == DISPLAY_EQUIPPED)
            Cutter = EQUIPPED_AUTO;
        if (DatamaxModel.Display == NON_DISPLAY)
            Cutter = EQUIPPED_ENABLE;
    }
    if (value & (1 << 2))    // Present Sensor Option
    {
        if (DatamaxModel.Display == DISPLAY_EQUIPPED)
            PresentSensor = EQUIPPED_AUTO;
        if (DatamaxModel.Display == NON_DISPLAY)
            PresentSensor = EQUIPPED_ENABLE;
    }
    if (pDmxCfg->CutterEquipped != Cutter)
    {
        pDmxCfg->CutterEquipped = Cutter;
        SenseCutterOption(Cutter);
    }
    if (pDmxCfg->PresentSensorEquipped != PresentSensor)
    {
        pDmxCfg->PresentSensorEquipped = PresentSensor;
        SensePresentSensorOption(PresentSensor);
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Request Firmware Version
 *
 * Description:
 *        This command causes the printer to send its version string (this data is
 *        the same as that printed on the configuration label). The version may be
 *        different from printer to printer.
 *
 * Syntax:
 *        <STX>v
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_v(VOID)
{
    SendPrintf("VER: %s - %s\r", DatamaxModel.Name, VerName, SrcRevName);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Request Memory Module Information
 *
 * Description:
 *        This command requests a memory module directory listing. Results may vary
 *        depending on printer class , model, or firmware version.
 *
 * Syntax:
 *        <STX>W[b][c]a
 *
 * Where:
 *        b s optional - list file size also
 *        c e optional - list file extension also
 *        a            - Data type:
 *                        F = Downloaded font
 *                        G = Graphic (Image)
 *                        L = Label format
 *                        C = Configuration file
 *                        X = Language file
 *                        N = Plug-in
 *                        M = Miscellaneous type file
 *                        f = Resident fonts
 *                        * = All types
 *
 ******************************************************************************/
INT Sys_W(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Test Flash Memory Module
 *
 * Description:
 *        This command tests the Flash memory module. The time for each test will
 *        vary from 20 to 120 seconds, depending upon the size of the module. All
 *        stored data will be destroyed. If no module is present, there will be no
 *        printer response.
 *
 * Syntax:
 *        <STX>wa
 *
 * Where:
 *        a - Module designator; see Appendix K.
 *
 ******************************************************************************/
INT Sys_w(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Default Module
 *
 * Description:
 *        This command, typically used prior to the loading of PCL-4 bit-mapped
 *        fonts (see Font Loading Commands), is designed to allow the user to
 *        select between modules when downloading information. The default module
 *        is one of the following:
 *          1. The first alpha designator of the existing modules if item 2 has not occurred.
 *          2. The module selected by this command.
 *
 * Syntax:
 *        <STX>Xa
 *
 * Where:
 *        a - Module designator; See Appendix K.
 *
 ******************************************************************************/
INT Sys_X(VOID)
{
    CHAR Module;

    // a - Module designator
    Module = DmxNextByte();

    pDmxCfg->DefaultModule = Module;
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Delete File from Module
 *
 * Description:
 *        This command removes a specific file from the specified module. The file
 *        name is removed from the module directory and thus the file cannot be
 *        accessed. The actual storage space occupied by the file is not released.
 *        To reclaim deleted file storage space use <STX>z to pack module.
 *
 * Syntax:
 *        <STX>xmtnn..n<CR>
 *
 * Where:
 *        m     - Module designator; see Appendix K.
 *        t     - The file type identification code:
 *                 G = Image file
 *                 L = Label format file
 *                 F = Downloaded bit-mapped font file
 *                 S = Downloaded scalable font file
 *                 C = Configuration file
 *                 X = Language file
 *                 N = Plug-in file
 *                 M = Miscellaneous file type
 *                 u = Unknown type - must use extension if applicable
 *        nn..n - The file to delete, where:
 *                 Font (bitmapped), the three character font identifier;
 *                 Font (scalable), the two character font identifier;
 *                 Graphic name, up to sixteen alphanumeric characters; and,
 *                 Label format name, up to sixteen alphanumeric characters.
 *
 ******************************************************************************/
INT Sys_x(VOID)
{
    CHAR Module;
    CHAR FileType;
    CHAR Name[17];

    // Module designator
    Module = DmxNextByte();

    // File type identification
    FileType = DmxNextByte();

    if (DmxGetString(Name, sizeof(Name)) > 16)
        return _ERROR;

    DeleteModuleFile(Module, Name, FileType);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Output Sensor Values
 *
 * Description:
 *        This command causes a sensor value response. When <STX>Y is received,
 *        the printer will respond with the digitally converted values of the
 *        internal analog sensors (see below). To repeat the display of values,
 *        send the printer a 'SPACE' character (20 hexadecimal); or, send <ESC>
 *        to terminate this function.
 *
 *        Non-Display Models: The printer must be in Test Mode for the command to
 *                            function. To enable the Test Mode see the <STX>KD command.
 *
 *        Display-Equipped Models: The printer must have Feedback Characters enabled
 *                                 for this command to function. (Feedback Mode
 *                                 [Characters] can be enabled via command or menu
 *                                 setting; see the <STX>KcFM command or the Operator's
 *                                 Manual for additional information).
 *
 * Syntax:
 *        <STX>Y
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_Y(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Select Font Symbol Set
 *
 * Description:
 *        This command selects the scalable font symbol set. The selected symbol
 *        set remains active until another symbol set is selected. See the <STX>KS
 *        command and Appendices E, I, and H for more information. Option dependant,
 *        and not all symbol sets can be used with all fonts.
 *
 * Syntax:
 *        <STX>ySxx
 *
 * Where:
 *        S  - Byte-size designation; see Appendix H:
 *              S = Single byte symbol sets.
 *              U = Double byte symbol sets.
 *        xx - Symbol set selection.
 *
 ******************************************************************************/
INT Sys_y(VOID)
{
    CHAR ByteSize;
    CHAR SymbolSet[2];

    // S  - Byte-size designation
    ByteSize = DmxNextByte();

    // xx - Symbol set selection
    if (!DmxGetAlpha(SymbolSet, 2))
        return _ERROR;

    if (pDmxCfg->DisableSymbolSet == 'N')
    {
        if (ByteSize == 'S' && DescribeSymbolSet(ByteSize, SymbolSet))
            memcpy(pDmxCfg->SingleByteSymbolSet, SymbolSet, 2);
        if (ByteSize == 'U' && DescribeSymbolSet(ByteSize, SymbolSet))
            memcpy(pDmxCfg->DoubleByteSymbolSet, SymbolSet, 2);
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Print Configuration Label
 *
 * Description:
 *        This command causes the printer to produce a Database Configuration Label.
 *        To capture all printed information, use the labels as wide as the maximum
 *        print width (see Appendix K) and at least four inches (102 mm) long.
 *
 * Syntax:
 *        <STX>Z
 *
 * Where:
 *
 ******************************************************************************/
INT Sys_Z(VOID)
{
    // ... not finish
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Pack Module
 *
 * Description:
 *        This command causes the printer to reclaim all storage space associated
 *        with all deleted files on the specified module (see <STX>X and <STX>x).
 *
 * Syntax:
 *        <STX>zm
 *
 * Where:
 *        m - The module identification character, see Appendix K.
 *
 ******************************************************************************/
INT Sys_z(VOID)
{
    CHAR Module;

    // m - The module identification character
    Module = DmxNextByte();

    // We have no need
    return _SUCCESS;
}

#endif

DplLabel.h 

#ifndef DPLLABEL_H

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define DPLLABEL_H

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#ifdef __cplusplus
extern "C" {            /* Assume C declarations for C++ */
#endif    /* __cplusplus */

/******************************************************************************
 *                                                                            *
 *                        G L O B A L   D E F I N E S                         *
 *                                                                            *
 ******************************************************************************/

#define LAB_FMT_ATTRIB_XOR            1
#define LAB_FMT_ATTRIB_TRANSPARENT    2
#define LAB_FMT_ATTRIB_OPAQUE        3
#define LAB_FMT_ATTRIB_INVERSE        5

#define RECORD_DATA_CONTENT            4071
#define GLOBAL_REGISTER_CONTENT        255

#define RECORD_HEADER_TOTAL            99
#define GLOBAL_REGISTER_TOTAL        24
#define LABEL_COUNTER_TOTAL            20

/******************************************************************************
 *                                                                            *
 *                 S T R U C T U R E   D E F I N I T I O N S                  *
 *                                                                            *
 ******************************************************************************/

typedef struct
{
    SHORT    CutByAmount;            //    :nnnn, cnn    : Set Cut By Amount
    SHORT    FormatAttrib;            //    An            : Set Format Attribute
    SHORT    BarcodeMag;                //    Bnn            : Bar Code Magnification
    SHORT    ColumnOffset;            //    Cnnnn        : Set Column Offset Amount
    SHORT    DotWidthMul;            //    Dwh            : Set Dot Size Width and Height
    SHORT    DotHeightMul;            //    Dwh            : Set Dot Size Width and Height
    CHAR    PresentSpeed;            //    fa            : Set Present Speed
    SHORT    HeatSetting;            //    Hnn            : Enter Heat Setting
    CHAR    Justification;            //    Ja            : Justification
    CHAR    MirrorMode;                //    M            : Select Mirror Mode
    CHAR    UnitMeasure;            //    m, n        : Set Metric Mode, Set Inch (Imperial) Mode
    CHAR    PrintSpeed;                //    Pa            : Set Print Speed
    CHAR    BackfeedSpeed;            //    pa            : Set Backfeed Speed
    LONG    Quantity;                //    Qnnnnn        : Set Quantity of Labels to Print
    SHORT    RowOffset;                //    Rnnnn        : Set Row Offset Amount
    CHAR    FeedSpeed;                //    Sa            : Set Feed Speed
    CHAR    Terminate;                //    Tnn            : Set Field Data Line Terminator
    CHAR    SingleByteSymbolSet[2];    //    ySxx        : Select Font Symbol Set
    CHAR    DoubleByteSymbolSet[2];    //    yUxx        : Select Font Symbol Set
    CHAR    ZeroConvert;            //    z            : Zero (O) Conversion to "0"
    SHORT    CounterByAmount;        //    ^nn            : Set Count By Amount
}_LabelParam;

typedef struct
{
    SHORT    WidthMul;
    SHORT    HeightMul;
    CHAR    ID[3];
    SHORT    Row;
    SHORT    Column;
    SHORT    FontHeight;
    SHORT    FontWidth;
}_LabFontField;

typedef struct
{
    CHAR    Expnad;
    SHORT    Wide;
    SHORT    Narrow;
    SHORT    Height;
    SHORT    Row;
    SHORT    Column;
}_LabBarcodeField;

typedef struct
{
    CHAR    Type;
    SHORT    Row;
    SHORT    Column;
    SHORT    Width;
    SHORT    Height;
    SHORT    TopThick;
    SHORT    SideThick;
    SHORT    FillPatern;
    SHORT    Radius;
}_LabGraphicField;

typedef struct
{
    SHORT    WidthMul;
    SHORT    HeightMul;
    SHORT    Row;
    SHORT    Column;
    CHAR    Name[17];
}_LabImageField;

typedef struct
{
    SHORT    X;
    SHORT    Y;
    SHORT    Width;
    SHORT    Height;
}_LabEraseBox;

typedef struct
{
    // Label Setting
    SHORT    FormatAttrib;
    SHORT    BarcodeMag;
    SHORT    DotWidthMul;
    SHORT    DotHeightMul;
    CHAR    MirrorMode;
    CHAR    Justification;
    CHAR    SingleByteSymbolSet[2];
    CHAR    DoubleByteSymbolSet[2];
    CHAR    ZeroConvert;

    // Record Header
    CHAR    Rotation;
    CHAR    Type;
    union
    {
        _LabFontField        Font;
        _LabBarcodeField    Barcode;
        _LabGraphicField    Graphic;
        _LabImageField        Image;
    }Field;

    // Erase Box
    _LabEraseBox    EraseBox;

}_LabRecHeader;

typedef struct
{
    SHORT    Length;
    CHAR    Content[RECORD_DATA_CONTENT + 1];
}_LabRecData;

typedef struct
{
    SHORT    Length;
    CHAR    Content[GLOBAL_REGISTER_CONTENT + 1];
}_LabGlbReg;

typedef struct
{
    CHAR    Type;
    CHAR    FillChar;
    LONG    Increment;
    _LabRecHeader    *pRecHeader;
    _LabGlbReg        Data;
}_LabCounter;

/******************************************************************************
 *                                                                            *
 *    G L O B A L   V A R I A B L E S   -   N O   I N I T I A L I Z E R S     *
 *                                                                            *
 ******************************************************************************/

#ifdef DPLLABFMT_C
#define EXTERN 
#else
#define EXTERN extern
#endif

EXTERN _LabelParam LabelParam;

EXTERN BYTE DplCodePage;
EXTERN BYTE DplRemapChar[256];

EXTERN _LabRecHeader RecordHeader[RECORD_HEADER_TOTAL];
EXTERN INT RecHdrNum;

EXTERN _LabGlbReg GlobalRegister[GLOBAL_REGISTER_TOTAL];
EXTERN INT GlbRegNum;

EXTERN _LabCounter LabelCounter[LABEL_COUNTER_TOTAL];
EXTERN INT LabCntNum;

/******************************************************************************
 *                                                                            *
 *       G L O B A L   V A R I A B L E S   -   I N I T I A L I Z E R S        *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *                   F U N C T I O N   P R O T O T Y P E S                    *
 *                                                                            *
 ******************************************************************************/

// Label Format Function ( DplLabFmt.c )
VOID InitialLabelFormat(VOID);
VOID SetLabelTerminat(VOID);
VOID PrintLabelFormat(INT);

// Label Field Function ( DplLabField.c )
VOID SaveLabelCounter(CHAR, CHAR, LONG, _LabRecData *);
VOID RunLabelCounter(VOID);
BOOL CheckLabelCounter(VOID);
VOID SaveRecordHeader(_LabRecHeader *);
VOID ReplacePreviousField(INT, CHAR, _LabRecData *);

// Label Image Function ( DplLabImg.c )
INT DrawRecord(_LabRecHeader *, _LabRecData *);
VOID EraseRecord(_LabEraseBox *, INT);

#undef EXTERN

#ifdef __cplusplus
}                       /* End of extern "C" { */
#endif    /* __cplusplus */

#endif

DplLabField.c   

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define DPLLABFIELD_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XGraphic.h"
#include "DplLabel.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#if defined(DPL)

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

STATIC _LabRecData CounterRecData;


STATIC VOID LabelCounterAddometer(CHAR *pData, INT Step)
{
    CHAR *pString;
    INT iLength;
    INT i;

    if (Step == 0)
        return;

    iLength = strlen((CHAR *)pData);
    pString = pData + iLength - 1;

    for (i = 0; i < iLength; i++)
    {
        if (isdigit(*pString))
          {
               *pString += Step % 10;
            if (*pString > '9')
            {
                   *pString -= 10;
                   Step = Step / 10 + 1;
            }
               else if (*pString < '0')
               {
                   *pString += 10;
                   Step = Step / 10 - 1;
               }
               else
                   Step /= 10;
        }
        else if (isupper(*pString))
        {
             *pString += Step % 26;
            if (*pString > 'Z')
            {
                *pString -= 26;
                Step = (Step - Step % 26) / 26 + 1;
            }
            else if (*pString < 'A')
            {
                *pString += 26;
                Step = Step / 26 - 1;
            }
             else
                 Step /= 26;
        }
        else if (islower(*pString))
        {
             *pString += Step % 26;
             if (*pString > 'z')
             {
                 *pString -= 26;
                 Step = (Step - Step % 26) / 26 + 1;
             }
               else if (*pString < 'a')
               {
                   *pString += 26;
                   Step = Step / 26 - 1;
               }
             else
                 Step /= 26;
        }
        else
            break;

        pString -= 1;
    }
}

STATIC VOID StepLabelCounter(_LabCounter *pCounter)
{
    LONG Inc;

    pCounter->Data.Content[pCounter->Data.Length] = '\0';

    Inc = pCounter->Increment;
    if (pCounter->Type == '-' || pCounter->Type == '<' || pCounter->Type == ')')
        Inc = 0 - Inc;

    LabelCounterAddometer(pCounter->Data.Content, Inc);
    pCounter->Data.Length = strlen(pCounter->Data.Content);
}

STATIC VOID DrawLabelCounter(_LabCounter *pCounter)
{
    memcpy(CounterRecData.Content, pCounter->Data.Content, pCounter->Data.Length);
    CounterRecData.Length = pCounter->Data.Length;
    CounterRecData.Content[CounterRecData.Length] = '\0';
    DrawRecord(pCounter->pRecHeader, &CounterRecData);
}

STATIC VOID EraseLabelCounter(_LabCounter *pCounter)
{
    EraseRecord(&pCounter->pRecHeader->EraseBox, DRAW_ERASE);
}

STATIC _LabRecHeader *GetLastRecordHeader(VOID)
{
    if (RecHdrNum)
        return &RecordHeader[RecHdrNum - 1];
    return _NULL;
}

VOID SaveLabelCounter(CHAR Type, CHAR FillChar, LONG Increment, _LabRecData *pData)
{
    _LabRecHeader *pRecHeader = GetLastRecordHeader();
    INT Length;

    if (LabCntNum < LABEL_COUNTER_TOTAL && pRecHeader)
    {
        LabelCounter[LabCntNum].Type = Type;
        LabelCounter[LabCntNum].FillChar = FillChar;
        LabelCounter[LabCntNum].Increment = Increment;
        LabelCounter[LabCntNum].pRecHeader = pRecHeader;

        Length = (pData->Length < GLOBAL_REGISTER_CONTENT) ? pData->Length : GLOBAL_REGISTER_CONTENT;
        memcpy(LabelCounter[LabCntNum].Data.Content, pData->Content, Length);
        LabelCounter[LabCntNum].Data.Length = Length;

        LabCntNum++;
    }
}

VOID RunLabelCounter(VOID)
{
    INT i;

    for (i = 0; i < LabCntNum; i++)
    {
        StepLabelCounter(&LabelCounter[i]);
        EraseLabelCounter(&LabelCounter[i]);
        DrawLabelCounter(&LabelCounter[i]);
    }
}

BOOL CheckLabelCounter(VOID)
{
    return (LabCntNum ? TRUE : FALSE);
}

VOID SaveRecordHeader(_LabRecHeader *pHeader)
{
    if (RecHdrNum < RECORD_HEADER_TOTAL)
    {
        RecordHeader[RecHdrNum] = *pHeader;
        RecHdrNum++;
    }
}

VOID ReplacePreviousField(INT Num, CHAR Truncate, _LabRecData *pRecData)
{
    _LabRecHeader *pRecHeader;

    if (Num >= 1 && Num <= RecHdrNum)
    {
        pRecHeader = &RecordHeader[Num - 1];
    
        if (Truncate != 'T')    // Exact Length Replacement Field
        {
            // ... not finish
        }
        EraseRecord(&pRecHeader->EraseBox, DRAW_ERASE);
        DrawRecord(pRecHeader, pRecData);
    }
}

#endif

DplLabFmt.c   

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define DPLLABFMT_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <stdlib.h>
#include <string.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XFunction.h"
#include "..\ParserUtil.h"
#include "DplCtrlCode.h"
#include "DplConfig.h"
#include "DplType.h"
#include "DplLabel.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#if defined(DPL)

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

VOID InitialLabelFormat(VOID)
{
    LabelParam.CutByAmount     = 0;
    LabelParam.FormatAttrib    = TransformLabFmtAttrib(pDmxCfg->FormatAttributes);
    LabelParam.BarcodeMag      = 1;
    LabelParam.ColumnOffset    = pDmxCfg->ColumnOffset;
    LabelParam.DotWidthMul     = 2;
    LabelParam.DotHeightMul    = 2;
    LabelParam.PresentSpeed    = pDmxCfg->FeedSpeed;
    LabelParam.HeatSetting     = pDmxCfg->Heat;
    LabelParam.Justification   = 'L';
    LabelParam.MirrorMode      = 'N';
    LabelParam.UnitMeasure     = pDmxCfg->UnitMeasure;
    LabelParam.PrintSpeed      = pDmxCfg->PrintSpeed;
    LabelParam.BackfeedSpeed   = pDmxCfg->ReverseSpeed;
    LabelParam.Quantity        = 1;
    LabelParam.RowOffset       = pDmxCfg->RowOffset;
    LabelParam.FeedSpeed       = pDmxCfg->FeedSpeed;
    LabelParam.Terminate       = CtrlCode.CR;
    LabelParam.ZeroConvert     = 'N';
    LabelParam.CounterByAmount = 1;

    memcpy(LabelParam.SingleByteSymbolSet, pDmxCfg->SingleByteSymbolSet, 2);
    memcpy(LabelParam.DoubleByteSymbolSet, pDmxCfg->DoubleByteSymbolSet, 2);

    // Initial Record Pool
    RecHdrNum = 0;

    // Clear Global Register
    GlbRegNum = 0;

    // Initial Amount Pool
    LabCntNum = 0;
}

VOID SetLabelTerminat(VOID)
{
    LabelParam.Terminate = CtrlCode.CR;
}

VOID PrintLabelFormat(INT Quantity)
{
    _PrintCfg LabCfg = *pPrintCfg;
    _ImgBuf TempImg;
    ULONG BatchNo = 0;
    INT  PrintQty, PrintCpy;
    LONG DspTotal, DspBase;

    TransformPrintConfig(&LabCfg);

    if (pDmxCfg->SensorType == CONTINUOUS_SENSOR_TYPE)
        LabCfg.ContinuePaperFeed = pDmxCfg->ContinuousLabelLength;
    if (LabCfg.SensorMode == CONTINUE_MODE_T && LabCfg.fPaperSize < sImageBuffer.iLastLine)
        LabCfg.SensorMode = FEED_CONTINUE_MODE;
    LabCfg.Speed = TransformSpeed(LabelParam.PrintSpeed);
    LabCfg.fDensity = TransformDensity(LabelParam.HeatSetting);
    LabCfg.CutterPieces = LabelParam.CutByAmount;

    PrintQty = Quantity;
    PrintCpy = LabelParam.CounterByAmount;

    if (!CheckLabelCounter())
        PrintCpy = PrintQty;

    DspTotal = PrintQty;
    while (PrintQty > 0)
    {
        if (PrintCpy > PrintQty)
            PrintCpy = PrintQty;

        DspBase = PrintQty - PrintCpy;
        BatchNo = PrintBatch(BatchNo, PrintCpy, &LabCfg, &sImageBuffer, TRUE, 0, DspTotal, DspBase, _NULL);
        if (BatchNo == 0)
            break;

        PrintQty -= PrintCpy;
        pPrintRec->LabelMilage += PrintCpy;

        TempImg = sImageBuffer;
        while (!AllocImageBuffer(&sImageBuffer))
            NutSleep(10);

        memcpy(sImageBuffer.pBuffer, TempImg.pBuffer, sImageBuffer.iByteWidth * sImageBuffer.iHeight);

        RunLabelCounter();
    }
}

#endif

DplLabImg.c   ///

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define DPLLABIMG_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XGraphic.h"
#include "..\ParserUtil.h"
#include "DplConfig.h"
#include "DplType.h"
#include "DplModule.h"
#include "DplLabel.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#if defined(DPL)

#define    NARROW_LEVEL        6

#define RS                    0x1E
#define DPLGS                0x1D
#define EOT                    0x04

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

typedef struct
{
    CHAR                 Type;
    BARCODEFUNC            PreviewBarcode;
    BARCODEFUNC            OutBarcode;
    SHORT                Check;
    BOOL                Human;
    CHAR                 *FontName;
    _eBarcodeFontType    FontType;
    CONST WORD            *pEraseWidth;
    BOOL                Shift;
}_BarcodeFeature;

typedef struct
{
    CHAR                Type;
    SHORT                WideBar;
    SHORT                NarrowBar;
    SHORT                Height;
}_BarcodeDefault;

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

STATIC CONST _BarcodeFeature sBarcodeFeatureTable[] = 
{
    {'A', PreviewCode39,     Code39,     2, 2, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'a', PreviewCode39,     Code39,     2, 0, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'B', PreviewUpca,       Upca,       0, 1, "@0",       BARCODE_OCR_FONT,    WidthUpca,  TRUE},
    {'b', PreviewUpca,       Upca,       0, 0, "@0",       BARCODE_OCR_FONT,    WidthUpca,  TRUE},
    {'C', PreviewUpce,       Upce,       0, 1, "@0",       BARCODE_OCR_FONT,    WidthUpce,  TRUE},
    {'c', PreviewUpce,       Upce,       0, 0, "@0",       BARCODE_OCR_FONT,    WidthUpce,  TRUE},
    {'D', PreviewCode25,     Code25,     0, 2, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'d', PreviewCode25,     Code25,     0, 0, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'E', PreviewCode128,    Code128,    1, 2, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'e', PreviewCode128,    Code128,    1, 0, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'F', PreviewEan13,      Ean13,      0, 1, "@0",       BARCODE_OCR_FONT,    WidthEan13, TRUE},
    {'f', PreviewEan13,      Ean13,      0, 0, "@0",       BARCODE_OCR_FONT,    WidthEan13, TRUE},
    {'G', PreviewEan8,       Ean8,       0, 1, "@0",       BARCODE_OCR_FONT,    WidthEan8,  FALSE},
    {'g', PreviewEan8,       Ean8,       0, 0, "@0",       BARCODE_OCR_FONT,    WidthEan8,  FALSE},
    {'H', PreviewCode39,     Code39,     3, 2, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'h', PreviewCode39,     Code39,     3, 0, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'I', PreviewCodabar,    Codabar,    0, 2, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'i', PreviewCodabar,    Codabar,    0, 0, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'J', PreviewCode25,     Code25,     1, 2, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'j', PreviewCode25,     Code25,     1, 0, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'K', PreviewCodemsi,    Codemsi,    0, 2, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'k', PreviewCodemsi,    Codemsi,    0, 0, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'L', PreviewCode25,     Code25,     1, 2, "2DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'l', PreviewCode25,     Code25,     1, 0, "2DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'M', PreviewCodeEanExt, CodeEanExt, 2, 2, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'m', PreviewCodeEanExt, CodeEanExt, 2, 0, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'N', PreviewCodeEanExt, CodeEanExt, 5, 2, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'n', PreviewCodeEanExt, CodeEanExt, 5, 0, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'O', PreviewCode93,     Code93,     0, 2, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'o', PreviewCode93,     Code93,     0, 0, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'p', PreviewPost,       Post,       0, 0, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'Q', PreviewEan128,     Ean128,     1, 2, "2DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'q', PreviewEan128,     Ean128,     1, 0, "2DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'R', PreviewEan128,     Ean128,     1, 2, "2DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'r', PreviewEan128,     Ean128,     1, 0, "2DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'S', PreviewEan128,     Ean128,     1, 2, "2DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'s', PreviewEan128,     Ean128,     1, 0, "2DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'T', _NULL, _NULL, 0, 0, _NULL, BARCODE_NOAMAL_FONT, _NULL, _NULL},
    {'t', _NULL, _NULL, 0, 0, _NULL, BARCODE_NOAMAL_FONT, _NULL, _NULL},
    {'v', _NULL, _NULL, 0, 0, _NULL, BARCODE_NOAMAL_FONT, _NULL, _NULL},
    {_NULL}
};

STATIC CONST _BarcodeFeature sExpandFeatureTable[] = 
{
    {'G', PreviewCode11,     Code11,     0, 2, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'g', PreviewCode11,     Code11,     0, 0, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'I', PreviewEan128,     Ean128,     0, 2, "2DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'J', PreviewCode128,    Code128,    0, 2, "1DMX.BMF", BARCODE_NOAMAL_FONT, _NULL,      FALSE},
    {'R', _NULL, _NULL, 0, 0, _NULL, BARCODE_NOAMAL_FONT, _NULL, _NULL},
    {'t', _NULL, _NULL, 0, 0, _NULL, BARCODE_NOAMAL_FONT, _NULL, _NULL},
    {_NULL}
};

#if defined(TPH_DPI_200)

STATIC CONST _BarcodeDefault sBarcodeDefaultTable[] = 
{
    {'A',    6,    2,    0.4 * TPH_DPI},    // Code 39
    {'B',    0,    3,    0.8 * TPH_DPI},    // UPC-A
    {'C',    0,    3,    0.8 * TPH_DPI},    // UPC-E
    {'D',    5,    2,    0.4 * TPH_DPI},    // Interleaved 2 of 5 (I2 of 5)
    {'E',    0,    2,    0.4 * TPH_DPI},    // Code 128
    {'F',    0,    3,    0.8 * TPH_DPI},    // EAN-13
    {'G',    0,    3,    0.8 * TPH_DPI},    // EAN-8
    {'H',    6,    2,    0.4 * TPH_DPI},    // HBIC
    {'I',    6,    3,    0.4 * TPH_DPI},    // Codabar
    {'J',    5,    2,    0.4 * TPH_DPI},    // Interleaved 2 of 5 w/ a modulo 10 checksum
    {'K',    5,    2,    0.4 * TPH_DPI},    // Plessey
    {'L',    5,    2,    1.3 * TPH_DPI},    // Interleaved 2 of 5 w/ modulo 10 checksum & bearer bars
    {'M',    0,    3,    0.9 * TPH_DPI},    // 2 digit UPC addendum
    {'N',    0,    3,    0.8 * TPH_DPI},    // 5 digit UPC addendum
    {'O',    6,    3,    0.4 * TPH_DPI},    // Code 93
    {'P',    1,    0,    0.08* TPH_DPI},    // Postnet
    {'Q',    0,    2,    1.4 * TPH_DPI},    // UCC/EAN 128
    {'R',    0,    2,    1.4 * TPH_DPI},    // UCC/EAN 128 K-Mart non-EDI
    {'S',    0,    2,    1.4 * TPH_DPI},    // UCC/EAN 128 Random Weight
    {'T',    0,    1,    0.8 * TPH_DPI},    // Telepen
    {'V',    0,    1,    0.5 * TPH_DPI},    // FIM
    {_NULL}
};

STATIC CONST _BarcodeDefault sExpandDefaultTable[] = 
{
    {'G',    5,    2,    0.5 * TPH_DPI},    // Code 11
    {'I',    0,    2,    0.5 * TPH_DPI},    // EAN 128 w/auto subset switching
    {'J',    0,    2,    0.4 * TPH_DPI},    // Code 128
    {'R',    0,    2,    1.4 * TPH_DPI},    // UCC/EAN Code 128 K-MART NON EDI
    {'T',    6,    2,    0.4 * TPH_DPI},    // TCIF Linked Bar Code 3 of 9 (TLC39)
    {_NULL}
};

#elif defined(TPH_DPI_300)

STATIC CONST _BarcodeDefault sBarcodeDefaultTable[] = 
{
    {'A',    9,    4,    0.4 * TPH_DPI},    // Code 39
    {'B',    0,    4,    0.8 * TPH_DPI},    // UPC-A
    {'C',    0,    4,    0.8 * TPH_DPI},    // UPC-E
    {'D',    9,    4,    0.4 * TPH_DPI},    // Interleaved 2 of 5 (I2 of 5)
    {'E',    0,    4,    0.4 * TPH_DPI},    // Code 128
    {'F',    0,    4,    0.8 * TPH_DPI},    // EAN-13
    {'G',    0,    4,    0.8 * TPH_DPI},    // EAN-8
    {'H',    9,    4,    0.4 * TPH_DPI},    // HBIC
    {'I',    9,    4,    0.4 * TPH_DPI},    // Codabar
    {'J',    9,    4,    0.4 * TPH_DPI},    // Interleaved 2 of 5 w/ a modulo 10 checksum
    {'K',    9,    4,    0.4 * TPH_DPI},    // Plessey
    {'L',    9,    4,    1.3 * TPH_DPI},    // Interleaved 2 of 5 w/ modulo 10 checksum & bearer bars
    {'M',    0,    4,    0.9 * TPH_DPI},    // 2 digit UPC addendum
    {'N',    0,    4,    0.8 * TPH_DPI},    // 5 digit UPC addendum
    {'O',    8,    4,    0.4 * TPH_DPI},    // Code 93
    {'P',    1,    0,    0.08* TPH_DPI},    // Postnet
    {'Q',    0,    4,    1.4 * TPH_DPI},    // UCC/EAN 128
    {'R',    0,    4,    1.4 * TPH_DPI},    // UCC/EAN 128 K-Mart non-EDI
    {'S',    0,    3,    1.4 * TPH_DPI},    // UCC/EAN 128 Random Weight
    {'T',    0,    1,    0.8 * TPH_DPI},    // Telepen
    {'V',    0,    1,    0.5 * TPH_DPI},    // FIM
    {_NULL}
};

STATIC CONST _BarcodeDefault sExpandDefaultTable[] = 
{
    {'G',    7,    3,    0.5 * TPH_DPI},    // Code 11
    {'I',    0,    4,    0.5 * TPH_DPI},    // EAN 128 w/auto subset switching
    {'J',    0,    4,    0.4 * TPH_DPI},    // Code 128
    {'R',    0,    2,    1.4 * TPH_DPI},    // UCC/EAN Code 128 K-MART NON EDI
    {'T',    9,    4,    0.4 * TPH_DPI},    // TCIF Linked Bar Code 3 of 9 (TLC39)
    {_NULL}
};

#elif defined(TPH_DPI_600)

STATIC CONST _BarcodeDefault sBarcodeDefaultTable[] = 
{
    {'A',    18,    6,    0.4 * TPH_DPI},    // Code 39
    {'B',    0,    9,    0.8 * TPH_DPI},    // UPC-A
    {'C',    0,    9,    0.8 * TPH_DPI},    // UPC-E
    {'D',    15,    6,    0.4 * TPH_DPI},    // Interleaved 2 of 5 (I2 of 5)
    {'E',    0,    6,    0.4 * TPH_DPI},    // Code 128
    {'F',    0,    9,    0.8 * TPH_DPI},    // EAN-13
    {'G',    0,    9,    0.8 * TPH_DPI},    // EAN-8
    {'H',    18,    6,    0.4 * TPH_DPI},    // HBIC
    {'I',    18,    6,    0.4 * TPH_DPI},    // Codabar
    {'J',    15,    6,    0.4 * TPH_DPI},    // Interleaved 2 of 5 w/ a modulo 10 checksum
    {'K',    15,    6,    0.4 * TPH_DPI},    // Plessey
    {'L',    15,    6,    1.3 * TPH_DPI},    // Interleaved 2 of 5 w/ modulo 10 checksum & bearer bars
    {'M',    0,    9,    0.9 * TPH_DPI},    // 2 digit UPC addendum
    {'N',    0,    9,    0.8 * TPH_DPI},    // 5 digit UPC addendum
    {'O',    18,    9,    0.4 * TPH_DPI},    // Code 93
    {'P',    1,    0,    0.08* TPH_DPI},    // Postnet
    {'Q',    0,    6,    1.4 * TPH_DPI},    // UCC/EAN 128
    {'R',    0,    6,    1.4 * TPH_DPI},    // UCC/EAN 128 K-Mart non-EDI
    {'S',    0,    6,    1.4 * TPH_DPI},    // UCC/EAN 128 Random Weight
    {'T',    0,    3,    0.8 * TPH_DPI},    // Telepen
    {'V',    0,    3,    0.5 * TPH_DPI},    // FIM
    {_NULL}
};

STATIC CONST _BarcodeDefault sExpandDefaultTable[] = 
{
    {'G',    14,    6,    0.5 * TPH_DPI},    // Code 11
    {'I',    0,    6,    0.5 * TPH_DPI},    // EAN 128 w/auto subset switching
    {'J',    0,    6,    0.4 * TPH_DPI},    // Code 128
    {'R',    0,    6,    1.4 * TPH_DPI},    // UCC/EAN Code 128 K-MART NON EDI
    {'T',    18,    6,    0.4 * TPH_DPI},    // TCIF Linked Bar Code 3 of 9 (TLC39)
    {_NULL}
};

#endif

STATIC CONST USHORT SmoothPointSizeTable[] = { 5,6,8,10,12,14,18,24,30,36,48 };

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

STATIC _LabRecData RecDataTemp;


STATIC SHORT TransformColumn(SHORT Column)
{
    Column = pDmxCfg->LabelWidth - Column;

#if defined(LEFT_ALIGN)    
    Column += (TPH_WIDTH_DOT - pDmxCfg->LabelWidth);
#else
    Column += (TPH_WIDTH_DOT - pDmxCfg->LabelWidth) >> 1;
#endif

    return Column;
}

STATIC SHORT TransformRow(SHORT Row)
{
    return Row;
}

STATIC _Coord FontJustification(SHORT Column, SHORT Row, SHORT Width, CHAR Rotation, CHAR Justification)
{
    _Coord sCoord;
    SHORT Shift;

    sCoord.iX = Column;
    sCoord.iY = Row;

    Shift = 0;
    if (Justification == 'R')
        Shift = Width;
    if (Justification == 'C')
        Shift = Width / 2;

    if (Rotation == '1')
        sCoord.iX -= Shift;
    if (Rotation == '2')
        sCoord.iY += Shift;
    if (Rotation == '3')
        sCoord.iX += Shift;
    if (Rotation == '4')
        sCoord.iY -= Shift;

    return sCoord;
}

STATIC GetWidthMulti(_LabRecHeader *pRecHeader)
{
    CHAR Rotation = pRecHeader->Rotation;
    if (Rotation == '1' || Rotation == '3')
        return LabelParam.DotWidthMul;
    return LabelParam.DotHeightMul;
}

STATIC GetHeightMulti(_LabRecHeader *pRecHeader)
{
    CHAR Rotation = pRecHeader->Rotation;
    if (Rotation == '1' || Rotation == '3')
        return LabelParam.DotHeightMul;
    return LabelParam.DotWidthMul;
}

STATIC _Coord GetCoordRecord(SHORT Column, SHORT Row, SHORT Height, CHAR Rotation)
{
    _Coord sCoord;

    sCoord.iX = TransformColumn(Column);
    sCoord.iY = TransformRow(Row);

    if (Rotation == '1')
        sCoord.iY += Height;
    if (Rotation == '2')
        sCoord.iX -= Height;
    if (Rotation == '3')
        sCoord.iY -= Height;
    if (Rotation == '4')
        sCoord.iX += Height;

    return sCoord;
}

STATIC _Coord GetCoordBarcode(_LabRecHeader *pRecHeader, _BarcodeFeature *pFeature, _BarCodeAttr *pAttr)
{
    _LabBarcodeField *pBarcode = &pRecHeader->Field.Barcode;
    _Coord sCoord;
    INT Height, Shift;

    sCoord.iX = TransformColumn(pBarcode->Column);
    sCoord.iY = TransformRow(pBarcode->Row);

    Height = pAttr->TotalHeight;
    Shift  = 0;
    if (pFeature->pEraseWidth && pAttr->iHuman)
    {
        Height += (pAttr->iNarrow << 3);
        if (pFeature->Shift)
            Shift = (pAttr->iNarrow << 3);
    }

    if (pRecHeader->Rotation == '1')
    {
        sCoord.iX -= Shift;
        sCoord.iY += Height;
    }
    if (pRecHeader->Rotation == '2')
    {
        sCoord.iX -= Height;
        sCoord.iY -= Shift;
    }
    if (pRecHeader->Rotation == '3')
    {
        sCoord.iX += Shift;
        sCoord.iY -= Height;
    }
    if (pRecHeader->Rotation == '4')
    {
        sCoord.iX += Height;
        sCoord.iY += Shift;
    }

    return sCoord;
}

STATIC _Coord GetCoordGraphic(SHORT Column, SHORT Row, SHORT Width, SHORT Height, CHAR Rotation)
{
    _Coord sCoord;

    sCoord.iX = TransformColumn(Column);
    sCoord.iY = TransformRow(Row);

    if (Rotation == '1')
        sCoord.iX -= Width;
    if (Rotation == '3')
    {
        sCoord.iX -= Width;
        sCoord.iY -= Height;
    }
    if (Rotation == '4')
        sCoord.iY -= Height;

    return sCoord;
}

STATIC _LabEraseBox GetRecordEraseBox(SHORT X, SHORT Y, SHORT Width, SHORT Height, SHORT Rotation)
{
    _LabEraseBox sEraseBox;
    
    switch (Rotation)
    {
        case 0:
        {
            sEraseBox.X = X;
            sEraseBox.Y = Y;
            sEraseBox.Width = Width;
            sEraseBox.Height = Height;
            break;
        }
        case 90:
        {
            sEraseBox.X = X - Height;
            sEraseBox.Y = Y;
            sEraseBox.Width = Height;
            sEraseBox.Height = Width;
            break;
        }
        case 180:
        {
            sEraseBox.X = X - Width;
            sEraseBox.Y = Y - Height;
            sEraseBox.Width = Width;
            sEraseBox.Height = Height;
            break;
        }
        case 270:
        {
            sEraseBox.X = X ;
            sEraseBox.Y = Y - Width;
            sEraseBox.Width = Height;
            sEraseBox.Height = Width;
            break;
        }
        default:
            break;
    }
    if (sEraseBox.X < 0)
        sEraseBox.X = 0;
    if (sEraseBox.Y < 0)
        sEraseBox.Y = 0;

    return sEraseBox;
}

STATIC _LabEraseBox GetBarcodeEraseBox(_BarcodeFeature *pFeature, _BarCodeAttr *pAttr)
{
    _LabEraseBox sEraseBox;
    INT Height, Width, Shift;

    if (pFeature->pEraseWidth)
    {
        Shift = 0;
        if (pAttr->iHuman)
        {
            Width = pFeature->pEraseWidth[NARROW_LEVEL + (pAttr->iNarrow - 1)];
            Height = pAttr->iHeight + ((pAttr->iNarrow + 1) << 3);
            if (pFeature->Shift)
                Shift = (pAttr->iNarrow << 3);
        }
        else
        {
            Width = pFeature->pEraseWidth[pAttr->iNarrow - 1];
            Height = pAttr->iHeight;
        }

        switch (pAttr->iRotation)
        {
            case 0:
            {
                sEraseBox.X = pAttr->sCoord.iX - Shift;
                sEraseBox.Y = pAttr->sCoord.iY;
                sEraseBox.Width = Width;
                sEraseBox.Height = Height;
                break;
            }
            case 90:
            {
                sEraseBox.X = pAttr->sCoord.iX - Height;
                sEraseBox.Y = pAttr->sCoord.iY - Shift;
                sEraseBox.Width = Height;
                sEraseBox.Height = Width;
                break;
            }
            case 180:
            {
                sEraseBox.X = pAttr->sCoord.iX - Width + Shift;
                sEraseBox.Y = pAttr->sCoord.iY - Height;
                sEraseBox.Width = Width;
                sEraseBox.Height = Height;
                break;
            }
            case 270:
            {
                sEraseBox.X = pAttr->sCoord.iX;
                sEraseBox.Y = pAttr->sCoord.iY - Width + Shift;
                sEraseBox.Width = Height;
                sEraseBox.Height = Width;
                break;
            }
        }
    }
    else
    {
        Width = pAttr->TotalWidth > pAttr->FontWidth ? pAttr->TotalWidth : pAttr->FontWidth;

        Height = 0;
        if (pAttr->iHuman != 0 && pAttr->AboveCode)
            Height = pAttr->FontHeight;

        Shift = Width - pAttr->TotalWidth;
        if (pAttr->iHuman == 2)
            Shift /= 2;

        switch (pAttr->iRotation)
        {
            case 0:
            {
                if (pAttr->iHuman == 1)
                    Shift = 0;

                sEraseBox.X = pAttr->sCoord.iX - Shift;
                sEraseBox.Y = pAttr->sCoord.iY - Height;
                sEraseBox.Width = Width;
                sEraseBox.Height = pAttr->TotalHeight;
                break;
            }
            case 90:
            {
                if (pAttr->iHuman == 1)
                    Shift = 0;

                sEraseBox.X = pAttr->sCoord.iX - pAttr->TotalHeight + Height;
                sEraseBox.Y = pAttr->sCoord.iY - Shift;
                sEraseBox.Width = pAttr->TotalHeight;
                sEraseBox.Height = Width;
                break;
            }
            case 180:
            {
                if (pAttr->iHuman == 3)
                    Shift = 0;

                sEraseBox.X = pAttr->sCoord.iX - pAttr->TotalWidth - Shift;
                sEraseBox.Y = pAttr->sCoord.iY - pAttr->TotalHeight + Height;
                sEraseBox.Width = Width;
                sEraseBox.Height = pAttr->TotalHeight;
                break;
            }
            case 270:
            {
                if (pAttr->iHuman == 3)
                    Shift = 0;

                sEraseBox.X = pAttr->sCoord.iX - Height;
                sEraseBox.Y = pAttr->sCoord.iY - pAttr->TotalWidth - Shift;
                sEraseBox.Width = pAttr->TotalHeight;
                sEraseBox.Height = Width;
                break;
            }
            default:
                break;
        }
    }

    if (sEraseBox.X < 0)
        sEraseBox.X = 0;
    if (sEraseBox.Y < 0)
        sEraseBox.Y = 0;

    return sEraseBox;
}

STATIC _BarcodeFeature *GetBarcodeFeature(CHAR Type, CONST _BarcodeFeature *pTable)
{
    while (pTable->Type)
    {
        if (Type == pTable->Type)
            return (_BarcodeFeature *)pTable;
        pTable++;
    }
    return (_BarcodeFeature *)_NULL;
}

STATIC _BarcodeDefault *GetBarcodeDefault(CHAR Type, CONST _BarcodeDefault *pTable)
{
    while (pTable->Type)
    {
        if (Type == pTable->Type)
            return (_BarcodeDefault *)pTable;
        pTable++;
    }
    return (_BarcodeDefault *)_NULL;
}

STATIC INT DrawRecInternalFont(_LabRecHeader *pRecHeader, _LabRecData *pRecData)
{
    STATIC CONST CHAR *FEName[]   = { "A0DMX.TTF", "50DMX.TTF" };
    STATIC CONST FLOAT FEWidth[]  = { 32, 42, 64,  86, 110, 110, 196 };
    STATIC CONST FLOAT FEHeight[] = { 40, 56, 95, 144, 188, 270, 330 };

    _LabFontField *pFont = &pRecHeader->Field.Font;
    _TextAttr sTextAttr;
    _Coord sCoord;
    CHAR FontName[12];

    DplCodePage = (pRecHeader->ZeroConvert == 'Y' ? 1 : 0);
    if (pRecHeader->Type == '7' || pRecHeader->Type == '8')
        DplCodePage = 0;

    FontName[0] = pRecHeader->Type;
    FontName[1] = '\0';
    strcat(FontName, "DMX.BMF");

    sTextAttr.psImageBuffer = &sImageBuffer;
    sTextAttr.iDirection = sTextAttr.iRotation = TransformDegree(pRecHeader->Rotation);
    sTextAttr.iHoriMulti = pFont->WidthMul  * GetWidthMulti(pRecHeader);
    sTextAttr.iVertMulti = pFont->HeightMul * GetHeightMulti(pRecHeader);
    sTextAttr.iDistance  = 0;
    sTextAttr.ExpLength  = pRecData->Length;
    sTextAttr.pExp       = (BYTE *)pRecData->Content;
    sTextAttr.pFont      = (BYTE *)FontName;
    sTextAttr.eLanguage  = LANG_DPL;
    sTextAttr.ePutWay    = TransformPutType(pRecHeader->FormatAttrib);

    if (pDmxCfg->FontEmulation == '1' || pDmxCfg->FontEmulation == '2')
    {
        if (pRecHeader->Type != '7' && pRecHeader->Type != '8')
        {
            strcpy(FontName, FEName[pDmxCfg->FontEmulation - '1']);
            sTextAttr.iHoriMulti *= FEWidth[pRecHeader->Type - '0']  * TPH_DPI / 720;
            sTextAttr.iVertMulti *= FEHeight[pRecHeader->Type - '0'] * TPH_DPI / 720;
            sTextAttr.iSymbolSet = *(SHORT *)pRecHeader->SingleByteSymbolSet;
        }
    }

    PreviewText(&sTextAttr);

    // Caculate Font Justification
    sCoord = FontJustification(pFont->Column, pFont->Row,
        sTextAttr.iRealWidth, pRecHeader->Rotation, pRecHeader->Justification);

    // Transform DPL coordinate to TSPL coordinate
    sTextAttr.sCoord = GetCoordRecord(sCoord.iX, sCoord.iY,
        sTextAttr.iRealHeight, pRecHeader->Rotation);

    OutText(&sTextAttr);

    pRecHeader->EraseBox = GetRecordEraseBox(sTextAttr.sCoord.iX, sTextAttr.sCoord.iY,
        sTextAttr.iRealWidth, sTextAttr.iRealHeight, sTextAttr.iRotation);

    if (pRecHeader->FormatAttrib == LAB_FMT_ATTRIB_INVERSE)
        EraseRecord(&pRecHeader->EraseBox, DRAW_REVERSE);

    return TRUE;
}

STATIC INT DrawRecExpandFont(_LabRecHeader *pRecHeader, _LabRecData *pRecData)
{
    _LabFontField *pFont = &pRecHeader->Field.Font;
    _TextAttr sTextAttr;
    _Coord sCoord;
    CHAR FontName[12];
    BOOL Scalable;
    INT Baseline;
    INT Num;

    SHORT WidthMul  = pFont->WidthMul  * GetWidthMulti(pRecHeader);
    SHORT HeightMul = pFont->HeightMul * GetHeightMulti(pRecHeader);

    STATIC CONST CHAR PC850[2] = {'P','M'};    // PC-850 Multilingual

    sTextAttr.psImageBuffer = &sImageBuffer;
    sTextAttr.iDirection = sTextAttr.iRotation = TransformDegree(pRecHeader->Rotation);
    sTextAttr.iDistance  = 0;
    sTextAttr.ExpLength  = pRecData->Length;
    sTextAttr.pExp       = (BYTE *)pRecData->Content;
    sTextAttr.pFont      = (BYTE *)FontName;
    sTextAttr.eLanguage  = LANG_DPL;
    sTextAttr.ePutWay    = TransformPutType(pRecHeader->FormatAttrib);

    // Smooth Font ID = 000 - 010
    if (pFont->ID[0] == '0')
    {
        Num = (pFont->ID[1] & 0xF) * 10 + (pFont->ID[2] & 0xF);
        if (Num >= sizeof(SmoothPointSizeTable))
            return FALSE;
        Num = (FLOAT)SmoothPointSizeTable[Num] * TPH_DPI / (FLOAT)72;
        sTextAttr.iHoriMulti = Num * WidthMul;
        sTextAttr.iVertMulti = Num * HeightMul;
        sTextAttr.iSymbolSet = *(SHORT *)pRecHeader->SingleByteSymbolSet;
        if (DatamaxModel.Series == DMX_E_CLASS ||
            DatamaxModel.Model == DMX_M4206 ||
            DatamaxModel.Model == DMX_M4206ND)
            sTextAttr.iSymbolSet = *(SHORT *)PC850;

        strcpy(FontName, "01DMX.TTF");
        Scalable = FALSE;
    }

    // Smooth Font ID = Ann
    else if (pFont->ID[0] == 'A')
    {
        Num = (pFont->ID[1] & 0xf) * 10 + (pFont->ID[2] & 0x0f);
        Num = (FLOAT)Num * TPH_DPI / (FLOAT)72;
        sTextAttr.iHoriMulti = Num * WidthMul;
        sTextAttr.iVertMulti = Num * HeightMul;
        sTextAttr.iSymbolSet = *(SHORT *)pRecHeader->SingleByteSymbolSet;
        if (DatamaxModel.Series == DMX_E_CLASS ||
            DatamaxModel.Model == DMX_M4206 ||
            DatamaxModel.Model == DMX_M4206ND)
            sTextAttr.iSymbolSet = *(SHORT *)PC850;

        strcpy(FontName, "01DMX.TTF");
        Scalable = FALSE;
    }

    // Downloaded Bit-Mapped Fonts
    else if (pFont->ID[0] >= '1' && pFont->ID[0] <= '9')
    {
        sTextAttr.iHoriMulti = WidthMul;
        sTextAttr.iVertMulti = HeightMul;

        // 100 - 999
        sprintf(FontName, "%c%c%c", pFont->ID[0], pFont->ID[1], pFont->ID[2]);
        strcat(FontName, "DMX.BMF");
        Scalable = FALSE;
    }
    
    // Single Byte Scalable Fonts
    else if (pFont->ID[0] == 'S')
    {
        sTextAttr.iHoriMulti = pFont->FontWidth  * WidthMul;
        sTextAttr.iVertMulti = pFont->FontHeight * HeightMul;
        sTextAttr.iSymbolSet = *(SHORT *)pRecHeader->SingleByteSymbolSet;

        // Resident   = S00, S01, SA0, SA1, SA2, SA3
        // Downloaded = S50 - S5z ... S90 - S9z
        sprintf(FontName, "%c%c", pFont->ID[1], pFont->ID[2]);
        strcat(FontName, "DMX.TTF");
        Scalable = TRUE;
    }
    
    // Double Byte Scalable Fonts
    else if (toupper(pFont->ID[0]) == 'U')
    {
        sTextAttr.iHoriMulti = pFont->FontWidth  * WidthMul;
        sTextAttr.iVertMulti = pFont->FontHeight * HeightMul;
        sTextAttr.iSymbolSet = *(SHORT *)pRecHeader->DoubleByteSymbolSet;

        // Resident   = U40, u40, UC0, uC0, UH0, uH0
        // Downloaded = U50 - U5z ... U90 - U9z,
        //              u50 - u5z ... u90 - u9z
        sprintf(FontName, "%c%c", pFont->ID[1], pFont->ID[2]);
        strcat(FontName, "DMX.TTF");
        Scalable = TRUE;
    }

    else
        return FALSE;

    PreviewText(&sTextAttr);

    Baseline = sTextAttr.iBaseLine;
    if (Scalable == FALSE)
        Baseline = sTextAttr.iRealHeight;

    // Caculate Font Justification
    sCoord = FontJustification(pFont->Column, pFont->Row, sTextAttr.iRealWidth,
        pRecHeader->Rotation, pRecHeader->Justification);

    // Transform DPL coordinate to TSPL coordinate
    sTextAttr.sCoord = GetCoordRecord(sCoord.iX, sCoord.iY, Baseline, pRecHeader->Rotation);

    OutText(&sTextAttr);

    pRecHeader->EraseBox = GetRecordEraseBox(sTextAttr.sCoord.iX, sTextAttr.sCoord.iY,
        sTextAttr.iRealWidth, sTextAttr.iRealHeight, sTextAttr.iRotation);

    if (pRecHeader->FormatAttrib == LAB_FMT_ATTRIB_INVERSE)
        EraseRecord(&pRecHeader->EraseBox, DRAW_REVERSE);

    return TRUE;
}

STATIC INT DrawRecBarcode(_LabRecHeader *pRecHeader, _LabRecData *pRecData)
{
    _LabBarcodeField *pBarcode = &pRecHeader->Field.Barcode;
    _BarcodeFeature *pFeature;
    _BarcodeDefault *pDefault;
    _BarCodeAttr sBarcodeAttr;
    CHAR FontName[FONT_NAME_MAX];

    if (pRecHeader->Type == 'W')
    {
        pFeature = GetBarcodeFeature(pBarcode->Expnad, sExpandFeatureTable);
        pDefault = GetBarcodeDefault(toupper(pBarcode->Expnad), sExpandDefaultTable);
    }
    else
    {
        pFeature = GetBarcodeFeature(pRecHeader->Type, sBarcodeFeatureTable);
        pDefault = GetBarcodeDefault(toupper(pRecHeader->Type), sBarcodeDefaultTable);
    }

    if (pFeature == _NULL || pDefault == _NULL || pFeature->OutBarcode == _NULL)
        return FALSE;

    sBarcodeAttr.psImageBuffer = &sImageBuffer;
    sBarcodeAttr.iRotation     = TransformDegree(pRecHeader->Rotation);
    sBarcodeAttr.iWide         = pBarcode->Wide   * GetWidthMulti(pRecHeader);
    sBarcodeAttr.iNarrow       = pBarcode->Narrow * GetWidthMulti(pRecHeader);
    sBarcodeAttr.iHeight       = pBarcode->Height;
    sBarcodeAttr.eLanguage     = LANG_DPL;
    sBarcodeAttr.ePutWay       = TransformPutType(pRecHeader->FormatAttrib);
    sBarcodeAttr.AboveCode     = FALSE;
    sBarcodeAttr.FontHoriMulti = 1;
    sBarcodeAttr.FontVertMulti = 1;
    sBarcodeAttr.iCheck        = pFeature->Check; 
    sBarcodeAttr.iHuman        = pFeature->Human; 
    sBarcodeAttr.pExp          = (BYTE *)pRecData->Content; 

    if (sBarcodeAttr.iWide == 0)
        sBarcodeAttr.iWide = pDefault->WideBar * GetWidthMulti(pRecHeader);
    if (sBarcodeAttr.iNarrow == 0)
        sBarcodeAttr.iNarrow = pDefault->NarrowBar * GetWidthMulti(pRecHeader);
    if (sBarcodeAttr.iHeight == 0)
        sBarcodeAttr.iHeight = pDefault->Height;

    if (pDefault->WideBar == 0)
        sBarcodeAttr.iWide = sBarcodeAttr.iNarrow;
    if (pDefault->NarrowBar == 0)
        sBarcodeAttr.iNarrow = sBarcodeAttr.iWide;

    strcpy(FontName, pFeature->FontName);
    sBarcodeAttr.pFont = (BYTE *)FontName;
    if (pFeature->FontType == BARCODE_OCR_FONT)
    {
        if (sBarcodeAttr.iNarrow > 10)
            FontName[1] += 9;
        else
            FontName[1] += sBarcodeAttr.iNarrow - 1 ;
    }

    pFeature->PreviewBarcode(&sBarcodeAttr);

    // Transform DPL coordinate to TSPL coordinate
    sBarcodeAttr.sCoord = GetCoordBarcode(pRecHeader, pFeature, &sBarcodeAttr);

    pFeature->OutBarcode(&sBarcodeAttr);

    pRecHeader->EraseBox = GetBarcodeEraseBox(pFeature, &sBarcodeAttr);

    return TRUE;
}

STATIC INT DrawRecMaxiCode(_LabRecHeader *pRecHeader, _LabRecData *pRecData)
{
    _LabBarcodeField *pBarcode = &pRecHeader->Field.Barcode;
    _MaxiAttr sMaxiAttr;
    _Coord sCoord;
    CHAR *pExp;
    INT DataLen;
    INT DigitLen;
    INT i;
    CHAR TempBuf[20];
    LONG lData;

    sMaxiAttr.eLanguage = LANG_DPL;
    sMaxiAttr.ePutWay = TransformPutType(pRecHeader->FormatAttrib);
    sMaxiAttr.psImageBuffer = &sImageBuffer;
    sMaxiAttr.iMode = 4;

    pExp = pRecData->Content;
    DataLen = pRecData->Length;

    if (pRecHeader->Type == 'u')
    {
        // ignore mode setting #2 or #3
        if (*pExp == '#')
        {
            pExp += 2;
            DataLen -= 2;
        }
        if (*pExp == '[')
        {
            sMaxiAttr.iMode = 4;
            memcpy(RecDataTemp.Content, pExp, DataLen);
            RecDataTemp.Length = DataLen;
            RecDataTemp.Content[RecDataTemp.Length] = '\0';
        }
        else
        {
            //Check Post code
            i = 0;
            DigitLen = 0;
            while (*(pExp + i) != DPLGS)
            {
                TempBuf[i] = *(pExp + i);
                if (isdigit(*(pExp + i)))
                    DigitLen += 1;
                i++;
                if (i > 9)
                    return FALSE;
            }

            TempBuf[i] = '\0';
            if (i == DigitLen)
            {
                lData = atol(TempBuf);
                if (lData <= 99999)
                    sMaxiAttr.iPost = lData * 10000;
                else
                    sMaxiAttr.iPost = lData;
                sMaxiAttr.iMode    = 2;
            }
            else if (i <= 6) 
            {
                memcpy(sMaxiAttr.abPost, TempBuf, i);
                memset(&sMaxiAttr.abPost[i],' ', 6 - i);
                sMaxiAttr.abPost[6] = '\0';
                sMaxiAttr.iMode = 3;
            }
            else
                return FALSE;

            pExp += i + 1;
            DataLen -= i + 1;

            i = 0;
            DigitLen = 0;
            // Check Country code
            while (*(pExp + i) != DPLGS)
            {
                TempBuf[i] = *(pExp + i);
                if (isdigit(*(pExp + i)))
                    DigitLen += 1;
                i++;
                if (i > 3)
                    return FALSE;
            }
            TempBuf[i] = '\0';
            sMaxiAttr.iCountry = atol(TempBuf);

            pExp += i + 1;
            DataLen -= i + 1;
            
            i = 0;
            DigitLen = 0;
            // Check Class
            while (*(pExp + i) != DPLGS)
            {
                TempBuf[i] = *(pExp + i);
                if (isdigit(*(pExp + i)))
                    DigitLen += 1;
                i++;
                if (i > 3)
                    return FALSE;
            }
            TempBuf[i] = '\0';
            sMaxiAttr.iClass = atol(TempBuf);

            pExp += i + 1;
            DataLen -= i + 1;
            
            memcpy(RecDataTemp.Content, pExp, DataLen);
            RecDataTemp.Length = DataLen;
            RecDataTemp.Content[RecDataTemp.Length] = '\0';
        }
    }
    else
    {
        // check Post code
        i = 0;
        while(isdigit(*(pExp + i)))
            i++;

        if (i > 6)
        {
            i = i - 6;
            memcpy(TempBuf, pExp, i);
            TempBuf[i]= '\0';
            lData = atol(TempBuf);
            if (lData <= 99999)
                sMaxiAttr.iPost = lData * 10000;            
            else
                sMaxiAttr.iPost = lData;            
            sMaxiAttr.iMode    = 2;
        }
        else
        {
            memcpy(sMaxiAttr.abPost, TempBuf, 6);
            sMaxiAttr.abPost[6] = '\0';
            sMaxiAttr.iMode = 3;
            i = 6;
        }
        pExp += i;
        DataLen -= i;

        // country code
        memcpy(TempBuf, pExp, 3);
        TempBuf[3]= '\0';
        lData = atol(TempBuf);
        sMaxiAttr.iCountry = atol(TempBuf);

        pExp += 3;
        DataLen -= 3;

        // class code
        memcpy(TempBuf, pExp, 3);
        TempBuf[3]= '\0';
        lData = atol(TempBuf);
        sMaxiAttr.iClass = atol(TempBuf);

        pExp += 3;
        DataLen -= 3;

        memcpy(RecDataTemp.Content, pExp, DataLen);
        RecDataTemp.Length = DataLen;
        RecDataTemp.Content[RecDataTemp.Length] = '\0';
    }
    sMaxiAttr.pExp = (BYTE *)RecDataTemp.Content;
    sMaxiAttr.ExpLen = RecDataTemp.Length;

    PreviewMaxi(&sMaxiAttr);

    sMaxiAttr.sCoord = GetCoordGraphic(pBarcode->Column, pBarcode->Row,
        sMaxiAttr.TotalWidth, sMaxiAttr.TotalHeight, pRecHeader->Rotation);

    pRecHeader->EraseBox = GetRecordEraseBox(sMaxiAttr.sCoord.iX, sMaxiAttr.sCoord.iY,
        sMaxiAttr.TotalWidth, sMaxiAttr.TotalHeight, 0);

    Maxi(&sMaxiAttr);
    return TRUE;
}

STATIC INT DrawRecPDF417(_LabRecHeader *pRecHeader, _LabRecData *pRecData)
{
    _LabBarcodeField *pBarcode = &pRecHeader->Field.Barcode;
    _PDFAttr sPDFAttr;
    _Coord sCoord;
    CHAR *pExp;
    SHORT Num;

    sPDFAttr.eLanguage = LANG_DPL;
    sPDFAttr.ePutWay = TransformPutType(pRecHeader->FormatAttrib);
    sPDFAttr.Rotate = TransformDegree(pRecHeader->Rotation);
    sPDFAttr.psImageBuffer = &sImageBuffer;
    sPDFAttr.iHuman = 0;
    sPDFAttr.iWLimit = 0;
    sPDFAttr.iHLimit = 0;
    sPDFAttr.iMaxCol = 0;
    sPDFAttr.iMaxRow = 0;
    sPDFAttr.iHRatio = 0;
    sPDFAttr.iWRatio = 0;
    sPDFAttr.iNarrow = pBarcode->Wide   * GetWidthMulti(pRecHeader);
    sPDFAttr.iHeight = pBarcode->Narrow * GetHeightMulti(pRecHeader);
    sPDFAttr.iCenter = 0;

    if (sPDFAttr.iNarrow == 0)
        sPDFAttr.iNarrow = 2 * GetWidthMulti(pRecHeader);
    if (sPDFAttr.iHeight == 0)
        sPDFAttr.iHeight = 6 * GetHeightMulti(pRecHeader);

    pExp = pRecData->Content;

    // 1-character specifying a normal or truncated bar code (T to truncate, F for normal).
    if (toupper(*pExp) == 'T')
        sPDFAttr.iTruncation = 1;
    else
        sPDFAttr.iTruncation = 0;
    pExp++;

    // 1-digit security level ranging from 0 to 8.
    if ((*pExp >= '0') && (*pExp <= '8'))
        sPDFAttr.iEccL = *pExp - '0';
    else
        sPDFAttr.iEccL = 1;
    pExp++;

     // 2-digit aspect ratio specified as a fraction, with the first digit being the numerator
    // and the second digit the denominator. Use "00" for the default ratio of 1:2. Valid
    // range is from "00" to "99."
    if (isdigit(*pExp) && isdigit(*(pExp + 1)))
    {
        sPDFAttr.iHRatio = (*pExp - '0');
        sPDFAttr.iWRatio = (*(pExp + 1) - '0');
    }
    pExp += 2;

    // 2-digit number specifying the number of rows requested. Use "00" to let the printer
    // find the best fit. Valid range is from "03" to "90". Row values less than 3 are set to
    // 3, while row values greater than 90 are set to 90.
    if (isdigit(*pExp) && isdigit(*(pExp + 1)))
    {
        Num = (*pExp - '0') * 10 + (*(pExp + 1) - '0');
        if (Num > 90)
            Num = 90;
        sPDFAttr.iMaxRow = Num;
    }
    pExp += 2;

    // 2-digit number specifying the number of columns requested. Use "00" to let the
    // printer find the best fit. Valid range is from "01" to "30". Column values greater
    // than 30 are set to 30.
    if (isdigit(*pExp) && isdigit(*(pExp + 1)))
    {
        Num = (*pExp - '0') * 10 + (*(pExp + 1) - '0');
        if (Num > 30)
            Num = 30;
        sPDFAttr.iMaxCol = Num;
    }
    pExp += 2;

    memcpy(RecDataTemp.Content, pRecData->Content + 8, pRecData->Length - 8);
    RecDataTemp.Length = pRecData->Length - 8;
    RecDataTemp.Content[RecDataTemp.Length] = '\0';

    sPDFAttr.pExp = (BYTE *)RecDataTemp.Content;
    sPDFAttr.ExpLen = RecDataTemp.Length;

    PreviewPDF(&sPDFAttr);

    sPDFAttr.sCoord = GetCoordRecord(pBarcode->Column, pBarcode->Row,
        sPDFAttr.TotalHeight, pRecHeader->Rotation);

    pRecHeader->EraseBox = GetRecordEraseBox(sPDFAttr.sCoord.iX, sPDFAttr.sCoord.iY,
        sPDFAttr.TotalWidth, sPDFAttr.TotalHeight, sPDFAttr.Rotate);

    PDF(&sPDFAttr);
    return TRUE;
}

STATIC INT DrawRecDMatrix(_LabRecHeader *pRecHeader, _LabRecData *pRecData)
{
    _LabBarcodeField *pBarcode = &pRecHeader->Field.Barcode;
    _DMatrixAttr sDMatrixAttr;
    _Coord sCoord;
    CHAR *pExp;
    SHORT Num;
    CHAR TempBuf[4];
    LONG lData;
    BOOL Ecc200;

    sDMatrixAttr.psImageBuffer = &sImageBuffer;
    sDMatrixAttr.FormatID = 0x01;
    sDMatrixAttr.EccType = LCN_ECCTYPE_ECC200;
    sDMatrixAttr.CtrlChr = 0;
    sDMatrixAttr.CellWidth = 4 * LabelParam.DotWidthMul;
    sDMatrixAttr.Xcells = 0;
    sDMatrixAttr.Ycells = 0;
    sDMatrixAttr.Human = 0;
    sDMatrixAttr.Rotate = TransformDegree(pRecHeader->Rotation);
    sDMatrixAttr.WLimit = 0;
    sDMatrixAttr.HLimit = 0;
    sDMatrixAttr.ExpLen = 0;
    sDMatrixAttr.eLanguage = LANG_DPL;
    sDMatrixAttr.ePutWay = TransformPutType(pRecHeader->FormatAttrib);

    if (pBarcode->Narrow)
        sDMatrixAttr.CellWidth = pBarcode->Narrow * LabelParam.DotWidthMul;

    pExp = pRecData->Content;
    // Skip ECC 200 uses Reed-Solomon error correction.
    memcpy(TempBuf, pExp, 3);
    TempBuf[3] = '\0';
    if (atol(TempBuf) == 200)
        Ecc200 = TRUE;
    else
        Ecc200 = FALSE;
        
    pExp += 3;    
    // Skip Fixed value, not used
    pExp += 1;    
    // A 3 digit even number (or 000) of rows requested.
    memcpy(TempBuf, pExp, 3);
    TempBuf[3] = '\0';
    if (Ecc200)
        sDMatrixAttr.Xcells = atol(TempBuf);
    pExp += 3;

    // A 3 digit even number (or 000) of columns requested.
    memcpy(TempBuf, pExp, 3);
    TempBuf[3] = '\0';
    if (Ecc200)
        sDMatrixAttr.Ycells = atol(TempBuf);

    memcpy(RecDataTemp.Content, pRecData->Content + 10, pRecData->Length - 10);
    RecDataTemp.Length = pRecData->Length - 10;
    RecDataTemp.Content[RecDataTemp.Length] = '\0';

    sDMatrixAttr.pExp = (BYTE *)RecDataTemp.Content;
    sDMatrixAttr.ExpLen = RecDataTemp.Length;

    PreviewDmatrix(&sDMatrixAttr);

    sDMatrixAttr.sCoord = GetCoordRecord(pBarcode->Column, pBarcode->Row,
        sDMatrixAttr.TotalHeight, pRecHeader->Rotation);

    pRecHeader->EraseBox = GetRecordEraseBox(sDMatrixAttr.sCoord.iX, sDMatrixAttr.sCoord.iY,
        sDMatrixAttr.TotalWidth, sDMatrixAttr.TotalHeight, sDMatrixAttr.Rotate);

    Dmatrix(&sDMatrixAttr);
    return TRUE;
}

STATIC INT DrawRecQRCode(_LabRecHeader *pRecHeader, _LabRecData *pRecData)
{
    _LabBarcodeField *pBarcode = &pRecHeader->Field.Barcode;
    _QRCodeAttr sQRCodeAttr;
    CHAR *pExp;
    INT DataLen;

    sQRCodeAttr.psImageBuffer = &sImageBuffer;
    sQRCodeAttr.CellWidth = pBarcode->Narrow * LabelParam.DotWidthMul;
    sQRCodeAttr.Rotate    = TransformDegree(pRecHeader->Rotation);
    sQRCodeAttr.iModelNum = 0x01;
    sQRCodeAttr.MaskNum   = 0x07;
    sQRCodeAttr.bErrLV    = 'M';
    sQRCodeAttr.bModel    = 'A';
    sQRCodeAttr.eLanguage = LANG_DPL;
    sQRCodeAttr.ePutWay   = TransformPutType(pRecHeader->FormatAttrib);

    if (sQRCodeAttr.CellWidth == 0)
        sQRCodeAttr.CellWidth = 1;

    if (pBarcode->Expnad == 'd')
    {
        memcpy(RecDataTemp.Content, pRecData->Content, pRecData->Length);
        RecDataTemp.Length = pRecData->Length;
        RecDataTemp.Content[RecDataTemp.Length] = '\0';
    }
    else
    {
        pExp = pRecData->Content;
        DataLen = pRecData->Length;

        while (1)
        {
            if ((*pExp == '1') || (*pExp == '2'))
            {
                sQRCodeAttr.iModelNum = *pExp - '0';
                pExp++;
                DataLen--;
            }
            if (*pExp == ',')
            {
                pExp++;
                DataLen--;
                break;
            }
            if ((*pExp == 'H') || (*pExp == 'Q') || (*pExp == 'M') || (*pExp == 'L'))
            {
                sQRCodeAttr.bErrLV = *pExp;
                pExp++;
                DataLen--;
                if (*pExp >= '0' && *pExp <= '8')
                {
                    sQRCodeAttr.MaskNum = *pExp - '0';
                    pExp++;
                    DataLen--;
                }
                if ((*pExp == 'A') || (*pExp == 'M'))
                {
                    sQRCodeAttr.bModel = *pExp;
                    pExp++;
                    DataLen--;
                }
            }
            pExp += 1;
            DataLen -= 1;
            break;
        }
    }

    sQRCodeAttr.pExp = (BYTE *)RecDataTemp.Content;
    sQRCodeAttr.ExpLen = RecDataTemp.Length;

    PreviewQRCode(&sQRCodeAttr);

    sQRCodeAttr.sCoord = GetCoordRecord(pBarcode->Column, pBarcode->Row,
        sQRCodeAttr.TotalHeight, pRecHeader->Rotation);

    pRecHeader->EraseBox = GetRecordEraseBox(sQRCodeAttr.sCoord.iX, sQRCodeAttr.sCoord.iY,
        sQRCodeAttr.TotalWidth, sQRCodeAttr.TotalHeight, sQRCodeAttr.Rotate);

    QRCode(&sQRCodeAttr);
    return TRUE;
}

STATIC INT DrawRecAztec(_LabRecHeader *pRecHeader, _LabRecData *pRecData)
{
    _LabBarcodeField *pBarcode = &pRecHeader->Field.Barcode;
    _AztecAttr sAztecAttr;
    _Coord sCoord;
    CHAR TempBuf[4];

    sAztecAttr.ePutWay      = TransformPutType(pRecHeader->FormatAttrib);
    sAztecAttr.Rotate       = TransformDegree(pRecHeader->Rotation);

    sAztecAttr.ModuleSize   = 4 * LabelParam.DotWidthMul;
    sAztecAttr.ErrorControl = 0;
    sAztecAttr.FlagChar     = 0;
    sAztecAttr.MenuSymbol   = 0;
    sAztecAttr.MultiSymbol  = 1;
    sAztecAttr.Reverse      = 0;

    if (pBarcode->Wide)
        sAztecAttr.ModuleSize = pBarcode->Wide * LabelParam.DotWidthMul;

    // Extended Channel Interpretation (ECI) mode
    if (pRecData->Content[0] == '1')
        sAztecAttr.FlagChar = 1;

    // Error Correction (EC) / Amount
    memcpy(TempBuf, pRecData->Content + 1, 3);
    TempBuf[3] = '\0';
    sAztecAttr.ErrorControl = atoi(TempBuf);

    memcpy(RecDataTemp.Content, pRecData->Content + 4, pRecData->Length - 4);
    RecDataTemp.Length = pRecData->Length - 4;
    RecDataTemp.Content[RecDataTemp.Length] = '\0';

    sAztecAttr.pExp   = (BYTE *)RecDataTemp.Content;
    sAztecAttr.ExpLen = RecDataTemp.Length;
    sAztecAttr.pID    = _NULL;

    sAztecAttr.psImageBuffer = &sImageBuffer;

    if (!ImpAztec(&sAztecAttr, FALSE))
        return FALSE;

    sAztecAttr.sCoord = GetCoordRecord(pBarcode->Column, pBarcode->Row,
        sAztecAttr.TotalHeight, pRecHeader->Rotation);

    pRecHeader->EraseBox = GetRecordEraseBox(sAztecAttr.sCoord.iX, sAztecAttr.sCoord.iY,
        sAztecAttr.TotalWidth, sAztecAttr.TotalHeight, sAztecAttr.Rotate);

    if (!ImpAztec(&sAztecAttr, TRUE))
        return FALSE;

    return TRUE;
}

STATIC INT DrawRecLine(_LabRecHeader *pRecHeader)
{
    _LabGraphicField *pGraphic = &pRecHeader->Field.Graphic;
    _BarAttr sBarAttr;

    sBarAttr.psImageBuffer = &sImageBuffer;
    sBarAttr.iType   = TransformBarType(pRecHeader->FormatAttrib);
    sBarAttr.iWidth  = pGraphic->Width  ? pGraphic->Width  : 1;
    sBarAttr.iHeight = pGraphic->Height ? pGraphic->Height : 1;
    sBarAttr.sCoord  = GetCoordGraphic(pGraphic->Column, pGraphic->Row, 
        sBarAttr.iWidth, sBarAttr.iHeight, '1');
    DrawBar(&sBarAttr);
    return TRUE;
}

STATIC INT DrawRecBox(_LabRecHeader *pRecHeader)
{
    _LabGraphicField *pGraphic = &pRecHeader->Field.Graphic;
    _BarAttr sBarAttr;

    if (pGraphic->Width  < pGraphic->SideThick * 2 ||
        pGraphic->Height < pGraphic->TopThick  * 2)
        return DrawRecLine(pRecHeader);

    sBarAttr.psImageBuffer = &sImageBuffer;
    sBarAttr.iType = TransformBarType(pRecHeader->FormatAttrib);

    // Top
    sBarAttr.sCoord.iX = pGraphic->Column;
    sBarAttr.sCoord.iY = pGraphic->Row;
    sBarAttr.iWidth    = pGraphic->Width;
    sBarAttr.iHeight   = pGraphic->TopThick;
    sBarAttr.sCoord    = GetCoordGraphic(sBarAttr.sCoord.iX, sBarAttr.sCoord.iY,
        sBarAttr.iWidth, sBarAttr.iHeight, '1');
    DrawBar(&sBarAttr);

    // Bottom
    sBarAttr.sCoord.iX = pGraphic->Column;
    sBarAttr.sCoord.iY = (pGraphic->Row + pGraphic->Height - pGraphic->TopThick);
    sBarAttr.iWidth    = pGraphic->Width;
    sBarAttr.iHeight   = pGraphic->TopThick;
    sBarAttr.sCoord    = GetCoordGraphic(sBarAttr.sCoord.iX, sBarAttr.sCoord.iY,
        sBarAttr.iWidth, sBarAttr.iHeight, '1');
    DrawBar(&sBarAttr);
    
    // Left
    sBarAttr.sCoord.iX = pGraphic->Column;
    sBarAttr.sCoord.iY = (pGraphic->Row + pGraphic->TopThick);
    sBarAttr.iWidth    = pGraphic->SideThick;
    sBarAttr.iHeight   = (pGraphic->Height - pGraphic->TopThick * 2);
    sBarAttr.sCoord    = GetCoordGraphic(sBarAttr.sCoord.iX, sBarAttr.sCoord.iY,
        sBarAttr.iWidth, sBarAttr.iHeight, '1');
    DrawBar(&sBarAttr);

    // right
    sBarAttr.sCoord.iX = (pGraphic->Column + pGraphic->Width - pGraphic->SideThick);
    sBarAttr.sCoord.iY = (pGraphic->Row + pGraphic->TopThick);
    sBarAttr.iWidth    = pGraphic->SideThick;
    sBarAttr.iHeight   = (pGraphic->Height - pGraphic->TopThick * 2);
    sBarAttr.sCoord    = GetCoordGraphic(sBarAttr.sCoord.iX, sBarAttr.sCoord.iY,
        sBarAttr.iWidth, sBarAttr.iHeight, '1');
    DrawBar(&sBarAttr);

    return TRUE;
}

STATIC INT DrawRecPolygon(_LabRecHeader *pRecHeader)
{
    _LabGraphicField *pGraphic = &pRecHeader->Field.Graphic;
    _BarAttr sBarAttr;

    sBarAttr.psImageBuffer = &sImageBuffer;
    sBarAttr.sCoord   = GetCoordGraphic(pGraphic->Column, pGraphic->Row, 
        pGraphic->Width, pGraphic->Height, '1');

    sBarAttr.PutWay   = TransformPutType(pRecHeader->FormatAttrib);
    sBarAttr.iPattern = pGraphic->FillPatern;
    sBarAttr.iType    = DRAW_PATTERN;
    sBarAttr.iWidth   = pGraphic->Width;
    sBarAttr.iHeight  = pGraphic->Height;
    DrawBar(&sBarAttr);

    sBarAttr.iType    = DRAW_BAR;
    sBarAttr.iThin    = 1;
    DrawBox(&sBarAttr);
    return TRUE;
}

STATIC INT DrawRecCircle(_LabRecHeader *pRecHeader)
{
    _LabGraphicField *pGraphic = &pRecHeader->Field.Graphic;
    _CircleAttr sCircleAttr;

    sCircleAttr.psImageBuffer = &sImageBuffer;
    sCircleAttr.sCoord        = GetCoordGraphic(pGraphic->Column, pGraphic->Row, 0, 0, '1');
    sCircleAttr.CirclePart    = FULL_CIRCLE;
    sCircleAttr.PutWay        = TransformPutType(pRecHeader->FormatAttrib);
    sCircleAttr.iPattern      = pGraphic->FillPatern;
    sCircleAttr.iType         = DRAW_PATTERN;
    sCircleAttr.iRadius       = pGraphic->Radius;
    sCircleAttr.iThickness    = pGraphic->Radius;
    DrawCircle(&sCircleAttr);

    sCircleAttr.iType         = DRAW_BAR;
    sCircleAttr.iThickness    = 1;
    DrawCircle(&sCircleAttr);
    return TRUE;
}

STATIC INT DrawRecGraphic(_LabRecHeader *pRecHeader)
{
    _LabGraphicField *pGraphic = &pRecHeader->Field.Graphic;

    if (toupper(pGraphic->Type) == 'L')
        return DrawRecLine(pRecHeader);

    if (toupper(pGraphic->Type) == 'B')
        return DrawRecBox(pRecHeader);

    if (pGraphic->Type == 'P')
        return DrawRecPolygon(pRecHeader);

    if (pGraphic->Type == 'C')
        return DrawRecCircle(pRecHeader);

    return FALSE;
}

STATIC INT DrawRecImage(_LabRecHeader *pRecHeader)
{
    _LabImageField *pImage = &pRecHeader->Field.Image;
    _ePutWay PutWay = TransformPutType(pRecHeader->FormatAttrib);
    SHORT Column    = TransformColumn(pImage->Column);
    SHORT Row       = TransformRow(pImage->Row);
    SHORT WidthMul  = pImage->WidthMul  * GetWidthMulti(pRecHeader);
    SHORT HeightMul = pImage->HeightMul * GetHeightMulti(pRecHeader);

    LoadImageFile(pImage->Name, Column, Row, WidthMul, HeightMul, PutWay);
    return TRUE;
}

INT DrawRecord(_LabRecHeader *pRecHeader, _LabRecData *pRecData)
{
    // Internal Bit-Mapped Fonts
    if (pRecHeader->Type >= '0' && pRecHeader->Type <= '8')
        return DrawRecInternalFont(pRecHeader, pRecData);

    // Scalable Fonts, Smooth Font, and Downloaded Bit-Mapped Fonts
    if (pRecHeader->Type == '9')
        return DrawRecExpandFont(pRecHeader, pRecData);

    // Barcode
    if (toupper(pRecHeader->Type) >= 'A' && toupper(pRecHeader->Type) <= 'T')
        return DrawRecBarcode(pRecHeader, pRecData);

    // Maxicode
    if (toupper(pRecHeader->Type) == 'U')
        return DrawRecMaxiCode(pRecHeader, pRecData);

    // Barcode expansion
    if (pRecHeader->Type == 'W')
    {
        // DataMatix
        if (toupper(pRecHeader->Field.Barcode.Expnad) == 'C')
            return DrawRecDMatrix(pRecHeader, pRecData);

        // QR Code
        if (toupper(pRecHeader->Field.Barcode.Expnad) == 'D')
            return DrawRecQRCode(pRecHeader, pRecData);

        // Aztec
        if (toupper(pRecHeader->Field.Barcode.Expnad) == 'F')
            return DrawRecAztec(pRecHeader, pRecData);

        // Micro PDF417
        if (toupper(pRecHeader->Field.Barcode.Expnad) == 'Z')
            return FALSE;

        // RSS14
        if (pRecHeader->Field.Barcode.Expnad == 'K')
            return FALSE;

        // Barcode expansion
        return DrawRecBarcode(pRecHeader, pRecData);
    }

    // Graphic
    if (pRecHeader->Type == 'X')
        return DrawRecGraphic(pRecHeader);

    // Image
    if (pRecHeader->Type == 'Y')
        return DrawRecImage(pRecHeader);

    // PDF417
    if (toupper(pRecHeader->Type) == 'Z')
        return DrawRecPDF417(pRecHeader, pRecData);

    return FALSE;
}

VOID EraseRecord(_LabEraseBox *pBox, INT BarType)
{
    _BarAttr sBarAttr;

    sBarAttr.psImageBuffer = &sImageBuffer;
    sBarAttr.sCoord.iX = pBox->X;
    sBarAttr.sCoord.iY = pBox->Y;
    sBarAttr.iType     = BarType;
    sBarAttr.iWidth    = pBox->Width;
    sBarAttr.iHeight   = pBox->Height;
    DrawBar(&sBarAttr);
}

#endif

  • 18
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值