T168_111\appl\Parser\Zpl2:第14~17

Zpl2Image.c   、、、、、、、、、、、、、、、、、、、、

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

#define ZPL2IMAGE_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 <stdio.h>
#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 "..\Parser.h"
#include "..\ParserUtil.h"
#include "Zpl2Util.h"
#include "Zpl2Field.h"
#include "Zpl2Object.h"
#include "Zpl2Control.h"
#include "Zpl2Image.h"

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

#if defined(ZPL2)

#define CHECK_TYPE_A        0x80
#define CHECK_TYPE_Y        0x81
#define CHECK_TYPE_11        0x82
#define CHECK_TYPE_LEN25    0x83
#define CHECK_TYPE_39        0x84
#define CHECK_TYPE_128        0x85

#define    NARROW_LEVEL        6

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

typedef enum
{
    INTERP_DEF_FONT,
    INTERP_OCR_FONT,
    INTERP_SET_FONT,
}_eInterpFont;

typedef struct
{
    CHAR                 Type;
    BARCODEFUNC            PreviewBarcode;
    BARCODEFUNC            OutBarcode;
    SHORT                Check;
    _eInterpFont         InterpFont;
    CONST WORD            *pEraseWidth;
    WORD                Shift;
}_ZplBarcodeInfo;

/******************************************************************************
 *                                                                            *
 *             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     *
 *                                                                            *
 ******************************************************************************/

CONST _ZplBarcodeInfo sZplBarcodeTab[] =
{  
    {BARCODE_CODE11,        PreviewCode11,        Code11,        CHECK_TYPE_11,        INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_INTERLEAVE25,    PreviewCode25,        Code25,        CHECK_TYPE_Y,        INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_CODE39,        PreviewCode39,        Code39,        CHECK_TYPE_39,        INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_CODE49,        _NULL,                _NULL,        0,                    INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_PLANET_CODE,    _NULL,                _NULL,        0,                    INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_EAN8,            PreviewEan8,        Ean8,        0,                    INTERP_OCR_FONT,    WidthEan8,    FALSE},
    {BARCODE_UPCE,            PreviewUpce,        Upce,        CHECK_TYPE_Y,        INTERP_OCR_FONT,    WidthUpce,    TRUE},
    {BARCODE_CODE93,        PreviewCode93,        Code93,        CHECK_TYPE_Y,        INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_CODE128,        PreviewCode128,        Code128,    CHECK_TYPE_128,        INTERP_SET_FONT,    _NULL,        FALSE},
    {BARCODE_EAN128,        PreviewEan128,        Ean128,        CHECK_TYPE_128,        INTERP_SET_FONT,    _NULL,        FALSE},
    {BARCODE_EAN13,            PreviewEan13,        Ean13,        0,                    INTERP_OCR_FONT,    WidthEan13,    TRUE},
    {BARCODE_INDUSTRIAL25,    _NULL,                _NULL,        0,                    INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_STANDARD25,    _NULL,                _NULL,        0,                    INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_ANSI_CODABAR,    PreviewCodabar,        Codabar,    CHECK_TYPE_Y,        INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_LOGMARS,        _NULL,                _NULL,        0,                    INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_MSI,            PreviewCodemsi,        Codemsi,    CHECK_TYPE_A,        INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_PLESSEY,        PreviewCodePlessey,    CodePlessey,CHECK_TYPE_Y,        INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_UPC_EAN,        PreviewCodeEanExt,    CodeEanExt,    CHECK_TYPE_LEN25,    INTERP_OCR_FONT,    _NULL,        FALSE},
    {BARCODE_TLC39,            _NULL,                _NULL,        0,                    INTERP_DEF_FONT,    _NULL,        FALSE},
    {BARCODE_UPCA,            PreviewUpca,        Upca,        CHECK_TYPE_Y,        INTERP_OCR_FONT,    WidthUpca,    TRUE},
    {BARCODE_POSTNET,        PreviewPost,        Post,        0,                    INTERP_DEF_FONT,    _NULL,        FALSE},
    {_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     *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *
 * Function:
 *        
 *
 * Description: 
 *        
 *
 * Input:
 *      None.
 *
 * Output:
 *      None.
 *
 ******************************************************************************/

STATIC _Axis GetFieldAxis(_Field *pField, SHORT Width, SHORT Height, INT Rotation)
{
    _Axis sAxis = pField->Origin;

    if (pField->Typeset)
    {
        if (Rotation == 0)
            sAxis.Y -= Height;
        else if (Rotation == 90)
            sAxis.X += Height;
        else if (Rotation == 180)
            sAxis.Y += Height;
        else if (Rotation == 270)
            sAxis.X -= Height;
    }
    else
    {
        if (Rotation == 90)
            sAxis.X += Height;
        else if (Rotation == 180)
        {
            sAxis.X += Width;
            sAxis.Y += Height;
        }
        else if (Rotation == 270)
            sAxis.Y += Width;
    }

    return sAxis;
}

STATIC _Axis GetTextFieldAxis(_Field *pField, _TextAttr *pTextAttr)
{
    _FieldBlock *pBlock = &pField->Block;
    SHORT RealHeight = pTextAttr->iRealHeight;
    SHORT Width, Height;
    _Axis sAxis;

    // download bitmap fonts only had half the real height
    if (pTextAttr->iAdjustLine)
        RealHeight /= 2;

    Width = pTextAttr->iRealWidth;
    Height = RealHeight;

    if (pField->Parameter.Direction == 'R')    // reverse printing (right to left)
    {
        Width = RealHeight;
        Height = pTextAttr->iRealWidth;
    }
    if (pBlock->Use)
        Width = pBlock->Width;
    if (pField->Typeset)
        Height = pTextAttr->iBaseLine;
    if (pBlock->Use && pField->Typeset)
        Height += RealHeight * (pBlock->Line - 1);

    sAxis = GetFieldAxis(pField, Width, Height, pTextAttr->iRotation);

    // adjust download bitmap font position
    if (pTextAttr->iRotation == 0)
        sAxis.Y -= pTextAttr->iAdjustLine;
    else if (pTextAttr->iRotation == 90)
        sAxis.X += pTextAttr->iAdjustLine;
    else if (pTextAttr->iRotation == 180)
        sAxis.Y += pTextAttr->iAdjustLine;
    else if (pTextAttr->iRotation == 270)
        sAxis.X -= pTextAttr->iAdjustLine;

    return sAxis;
}

STATIC VOID TextJustification(_Field *pField, _TextAttr *pTextAttr)
{
    _FieldBlock *pBlock = &pField->Block;
    SHORT Width = pTextAttr->iRealWidth;
    SHORT Rotation = pTextAttr->iRotation;
    SHORT Adjust = 0;

    if (pBlock->Use && pBlock->Width > Width)
    {
        if (pBlock->Justification == 'C')
            Adjust = (pBlock->Width - Width) >> 1;
        else if (pBlock->Justification == 'R')
            Adjust = pBlock->Width - Width;

        if (Rotation == 0)
            pTextAttr->sCoord.iX += Adjust;
        else if (Rotation == 90)
            pTextAttr->sCoord.iY += Adjust;
        else if (Rotation == 180)
            pTextAttr->sCoord.iX -= Adjust;
        else if (Rotation == 270)
            pTextAttr->sCoord.iY -= Adjust;
    }
}

STATIC VOID SetTypesetOrigin(_Axis *pAxis, SHORT Width, SHORT Height, INT Rotation)
{
    switch (Rotation)
    {
        case 0:
            TypesetOrigin.X = pAxis->X + Width;
            TypesetOrigin.Y = pAxis->Y + Height;
            break;
        case 90:
            TypesetOrigin.X = pAxis->X - Height;
            TypesetOrigin.Y = pAxis->Y + Width;
            break;
        case 180:
            TypesetOrigin.X = pAxis->X - Width;
            TypesetOrigin.Y = pAxis->Y - Height;
            break;
        case 270:
            TypesetOrigin.X = pAxis->X + Height;
            TypesetOrigin.Y = pAxis->Y - Width;
            break;
    }
}

STATIC VOID SetFontSpecify(_FieldFont *pFont)
{
    SHORT Width = 0, Height = 0;

    if (SearchScalableFont(pFont->File.Name))
        strcpy(strchr(pFont->File.Name, '.'), ".TTF");
    if (!GetFontSize(pFont->File.Name, LANG_ZPL, &Width, &Height))
    {
        pFont->File = *FontIdentifier(FieldDef.Font.ID);
        if (SearchScalableFont(pFont->File.Name))
            strcpy(strchr(pFont->File.Name, '.'), ".TTF");
        GetFontSize(pFont->File.Name, LANG_ZPL, &Width, &Height);
    }

    if (pFont->Height == 0 && pFont->Width == 0)    // not specified
    {
        pFont->Height = FieldDef.Font.Height;
        pFont->Width = FieldDef.Font.Width;
    }

    if (IsScalableFont(pFont->File.Name))
    {
        if (pFont->Height == 0)                // Height is not specified
            pFont->Height = pFont->Width;
        if (pFont->Width == 0)                // Width is not specified
            pFont->Width = pFont->Height;

        // Scalable Accepted Values: 10 to 32000
        if (pFont->Height < 10 || pFont->Height > 32000)
            pFont->Height = 10;

        // Scalable Accepted Values: 10 to 32000
        if (pFont->Width < 10 || pFont->Width > 32000)
            pFont->Width = 10;
    }
    else
    {
        if (Width && Height)
        {
            if (pFont->Height == 0)            // Height is not specified
                pFont->Height = ((pFont->Width + Width / 2) / Width) * Height;
            if (pFont->Width == 0)            // Width is not specified
                pFont->Width = ((pFont->Height + Height / 2) / Height) * Width;
        }
    }
}

STATIC VOID SetBarcodeHuman(_BarCodeAttr *pAttr, _ZplBarcodeInfo *pInfo, _Field *pField)
{
    _FieldBarcode *pBarcode = &pField->Draw.Barcode;

    STATIC CHAR FontName[16];

    pAttr->iHuman =  0;
    pAttr->pFont = (BYTE *)FontName;
    pAttr->FontWidth = 0;
    pAttr->FontHeight = 0;
    pAttr->FontHoriMulti = 1;
    pAttr->FontVertMulti = 1;
    pAttr->AboveCode = FALSE;

    if (Whether(pBarcode->Above))
        pAttr->AboveCode = TRUE;

    if (Whether(pBarcode->Interp))
        pAttr->iHuman =  2;

    // Ean serial barcode
    if (pInfo->InterpFont == INTERP_OCR_FONT)
    {
        sprintf(FontName, "@%d", pBarcode->Width - 1);
    }
    else if (pInfo->InterpFont == INTERP_SET_FONT && pField->FontSet)
    {
        _FieldFont Font = pField->Draw.Font;

        SetFontSpecify(&Font);
        strcpy(FontName, Font.File.Name);

        if (Whether(pBarcode->Interp))
            pAttr->iHuman = 1;

        pAttr->FontHoriMulti = Font.Width;
        pAttr->FontVertMulti = Font.Height;
    }
    else
    {
        strcpy(FontName, "A.FNT");
        pAttr->FontHoriMulti = pBarcode->Width * 5;
        pAttr->FontVertMulti = pBarcode->Width * 9;
    }
}

STATIC _ZplBarcodeInfo *GetBarcodeInfo(CHAR Type)
{
    INT i = 0;

    while (sZplBarcodeTab[i].Type)
    {
        if (sZplBarcodeTab[i].Type == Type)
            return (_ZplBarcodeInfo *)(&sZplBarcodeTab[i]);
        i++;
    }
    return _NULL;
}

STATIC CHAR *GetBarcodeExp(_FieldBarcode *pBarcode, CHAR *pData)
{
    STATIC CHAR BarcodeData[MAX_CONTENT + 1];

    if (pBarcode->Type == BARCODE_CODABLOCK && pBarcode->Mode == 'A')
    {
        sprintf(BarcodeData, "L%s", pData);
        return (CHAR *)BarcodeData;
    }
    if (pBarcode->Type == BARCODE_ANSI_CODABAR)
    {
        sprintf(BarcodeData, "%c%s%c", pBarcode->ParamChar1, pData, pBarcode->ParamChar2);
        return (CHAR *)BarcodeData;
    }
    return pData;
}

STATIC INT GetBarcodeCheck(_ZplBarcodeInfo *pInfo, _FieldBarcode *pBarcode, CHAR *pData)
{
    if (pInfo->Check == CHECK_TYPE_Y)
        return Whether(pBarcode->Check);
    if (pInfo->Check == CHECK_TYPE_11)
    {
        if (Whether(pBarcode->Check))
            return 2;
        return 1;
    }
    if (pInfo->Check == CHECK_TYPE_A)
    {
        if (pBarcode->Check == 'A')
            return 2;
        if (pBarcode->Check == 'B')
            return 0;
        if (pBarcode->Check == 'C')
            return 1;
        if (pBarcode->Check == 'D')
            return 3;
        return 0;
    }
    if (pInfo->Check == CHECK_TYPE_LEN25)
    {
        if (strlen(pData) <= 2)
            return 2;
        return 5;
    }
    if (pInfo->Check == CHECK_TYPE_39)
        return (Whether(pBarcode->Check) ? 3 : 2);
    if (pInfo->Check == CHECK_TYPE_128)
    {
        if (Whether(pBarcode->Check) && pBarcode->Mode != 'D')
            return 'U';
        if (pBarcode->Mode == 'U')
            return 'U';
        if (pBarcode->Mode == 'N')
            return 1;
        return 0;
    }

    return pInfo->Check;
}

STATIC VOID StoreDrawArea(_DrawArea *pDrawArea, INT X, INT Y, INT Width, INT Height, INT Rotation)
{
    switch (Rotation)
    {
        case 0:
        {
            pDrawArea->Origin.X = X;
            pDrawArea->Origin.Y = Y;
            pDrawArea->Width = Width;
            pDrawArea->Height = Height;
            break;
        }
        case 90:
        {
            pDrawArea->Origin.X = X - Height;
            pDrawArea->Origin.Y = Y;
            pDrawArea->Width = Height;
            pDrawArea->Height = Width;
            break;
        }
        case 180:
        {
            pDrawArea->Origin.X = X - Width;
            pDrawArea->Origin.Y = Y - Height;
            pDrawArea->Width = Width;
            pDrawArea->Height = Height;
            break;
        }
        case 270:
        {
            pDrawArea->Origin.X = X;
            pDrawArea->Origin.Y = Y - Width;
            pDrawArea->Width = Height;
            pDrawArea->Height = Width;
            break;
        }
        default:
            break;
    }
    if (pDrawArea->Origin.X < 0)
        pDrawArea->Origin.X = 0;
    if (pDrawArea->Origin.Y < 0)
        pDrawArea->Origin.Y = 0;
}

STATIC VOID StoreBarcodeDrawArea(_DrawArea *pDrawArea, _BarCodeAttr *pAttr, _ZplBarcodeInfo *pInfo)
{
    INT Height, Width, Shift;

    // normal barcode
    if (pInfo->pEraseWidth == _NULL)
    {
        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;

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

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

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

                pDrawArea->Origin.X = pAttr->sCoord.iX - Height;
                pDrawArea->Origin.Y = pAttr->sCoord.iY - pAttr->TotalWidth - Shift;
                pDrawArea->Width = pAttr->TotalHeight;
                pDrawArea->Height = Width;
                break;
            }
            default:
                break;
        }
    }
    else
    {
        Shift = 0;
        if (pAttr->iHuman)
        {
            Width = pInfo->pEraseWidth[NARROW_LEVEL + (pAttr->iNarrow - 1)];
            Height = pAttr->iHeight + ((pAttr->iNarrow + 1) << 3);
            if (pInfo->Shift)
                Shift = (pAttr->iNarrow << 3);
        }
        else
        {
            Width = pInfo->pEraseWidth[pAttr->iNarrow - 1];
            Height = pAttr->iHeight;
        }

        switch (pAttr->iRotation)
        {
            case 0:
            {
                pDrawArea->Origin.X = pAttr->sCoord.iX - Shift;
                pDrawArea->Origin.Y = pAttr->sCoord.iY;
                pDrawArea->Width = Width;
                pDrawArea->Height = Height;
                break;
            }
            case 90:
            {
                pDrawArea->Origin.X = pAttr->sCoord.iX - Height;
                pDrawArea->Origin.Y = pAttr->sCoord.iY - Shift;
                pDrawArea->Width = Height;
                pDrawArea->Height = Width;
                break;
            }
            case 180:
            {
                pDrawArea->Origin.X = pAttr->sCoord.iX - Width + Shift;
                pDrawArea->Origin.Y = pAttr->sCoord.iY - Height;
                pDrawArea->Width = Width;
                pDrawArea->Height = Height;
                break;
            }
            case 270:
            {
                pDrawArea->Origin.X = pAttr->sCoord.iX;
                pDrawArea->Origin.Y = pAttr->sCoord.iY - Width + Shift;
                pDrawArea->Width = Height;
                pDrawArea->Height = Width;
                break;
            }
        }
    }
    if (pDrawArea->Origin.X < 0)
        pDrawArea->Origin.X = 0;
    if (pDrawArea->Origin.Y < 0)
        pDrawArea->Origin.Y = 0;
}

STATIC BOOL DrawAZTEC(_Field *pField, _FieldData *pData, _DrawArea *pDrawArea)
{
    _FieldBarcode *pBarcode = &pField->Draw.Barcode;
    _AztecAttr sAztecAttr;
    _Axis sAxis;

    sAztecAttr.psImageBuffer = &sImageBuffer;
    sAztecAttr.Rotate = ToDegree(pBarcode->Orientation);

    sAztecAttr.ModuleSize   = pBarcode->Columns;
    sAztecAttr.ErrorControl = pBarcode->ParamNum1;
    sAztecAttr.FlagChar     = Whether(pBarcode->ParamChar1);
    sAztecAttr.MenuSymbol   = Whether(pBarcode->ParamChar2);
    sAztecAttr.MultiSymbol  = pBarcode->Rows;
    sAztecAttr.Reverse      = 0;
    sAztecAttr.ExpLen       = pData->Length;
    sAztecAttr.pExp         = (BYTE *)pData->Content;
    sAztecAttr.pID          = (BYTE *)pBarcode->FieldID;
    sAztecAttr.ePutWay      = ToPutWay(pField->Reverse);    

    // Preview AZTEC
    ImpAztec(&sAztecAttr, FALSE);

    sAxis = GetFieldAxis(pField, sAztecAttr.TotalWidth, sAztecAttr.TotalHeight, sAztecAttr.Rotate);
    sAztecAttr.sCoord.iX = XAxis(sAxis.X);
    sAztecAttr.sCoord.iY = YAxis(sAxis.Y);

    ImpAztec(&sAztecAttr, TRUE);

    SetTypesetOrigin(&sAxis, sAztecAttr.TotalWidth, sAztecAttr.TotalHeight, sAztecAttr.Rotate);

    StoreDrawArea(pDrawArea, sAztecAttr.sCoord.iX, sAztecAttr.sCoord.iY,
                    sAztecAttr.TotalWidth , sAztecAttr.TotalHeight, sAztecAttr.Rotate);
    return TRUE;
}

STATIC BOOL DrawPDF417(_Field *pField, _FieldData *pData, _DrawArea *pDrawArea)
{
    _FieldBarcode *pBarcode = &pField->Draw.Barcode;
    _FieldData Data = *pData;
    _PDFAttr sPDFAttr;
    _Axis sAxis;
    INT i;

    // Special Considerations for ^FD When Using PDF417
    for (i = 1; i < Data.Length; i++)
    {
        // \& = carriage return/line feed
        if (memcmp(Data.Content + (i - 1), "\\&", 2) == 0)
            memcpy(Data.Content + (i - 1), "\r\n", 2);

        // \\ = backslash (\)
        if (memcmp(Data.Content + (i - 1), "\\\\", 2) == 0)
            memmove(Data.Content + i, Data.Content + (i + 1), --Data.Length - i);
    }
    Data.Content[Data.Length] = '\0';

    sPDFAttr.psImageBuffer = &sImageBuffer;
    sPDFAttr.iWLimit = 0;
    sPDFAttr.iHLimit = 0;
    if (pBarcode->ParamNum1 == 0)    // not specified
        sPDFAttr.iHLimit = FieldDef.Barcode.Height;
    sPDFAttr.Rotate  = ToDegree(pBarcode->Orientation);
    sPDFAttr.iEccL   = pBarcode->ParamNum2;
    sPDFAttr.iNarrow = pBarcode->Width;
    sPDFAttr.iHeight = pBarcode->ParamNum1;
    sPDFAttr.iMaxRow = pBarcode->Rows;
    sPDFAttr.iMaxCol = pBarcode->Columns;
    sPDFAttr.iCenter = 0;
    sPDFAttr.iHuman  = 0;
    sPDFAttr.iTruncation = Whether(pBarcode->ParamChar1);
    sPDFAttr.eLanguage = LANG_ZPL;
    sPDFAttr.ePutWay = ToPutWay(pField->Reverse);
    sPDFAttr.pExp = (BYTE *)Data.Content;
    sPDFAttr.ExpLen = Data.Length;

    PreviewPDF(&sPDFAttr);

    sAxis = GetFieldAxis(pField, sPDFAttr.TotalWidth, sPDFAttr.TotalHeight, sPDFAttr.Rotate);
    sPDFAttr.sCoord.iX = XAxis(sAxis.X);
    sPDFAttr.sCoord.iY = YAxis(sAxis.Y);

    PDF(&sPDFAttr);

    SetTypesetOrigin(&sAxis, sPDFAttr.TotalWidth, sPDFAttr.TotalHeight, sPDFAttr.Rotate);

    StoreDrawArea(pDrawArea, sPDFAttr.sCoord.iX, sPDFAttr.sCoord.iY,
                    sPDFAttr.TotalWidth , sPDFAttr.TotalHeight, sPDFAttr.Rotate);
    return TRUE;
}

STATIC BOOL DrawCodaBlock(_Field *pField, _FieldData *pData, _DrawArea *pDrawArea)
{
    _FieldBarcode *pBarcode = &pField->Draw.Barcode;
    _ZplBarcodeInfo *pBarcodeInfo = _NULL;
    _BarCodeAttr sBarcodeAttr;
    _BarAttr sBarAttr;
    _Axis sAxis;
    SHORT Height;

    pBarcode->Check = 0;
    if (pBarcode->Mode == 'A')
        pBarcodeInfo = GetBarcodeInfo(BARCODE_CODE39);
    if (pBarcode->Mode == 'E')
        pBarcodeInfo = GetBarcodeInfo(BARCODE_EAN128);
    if (pBarcode->Mode == 'F')
        pBarcodeInfo = GetBarcodeInfo(BARCODE_CODE128);

    if (pBarcodeInfo == _NULL)
        return FALSE;

    sBarcodeAttr.psImageBuffer = &sImageBuffer;
    sBarcodeAttr.FontWidth = 0;
    sBarcodeAttr.FontHeight = 0;
    sBarcodeAttr.FontHoriMulti = 1;
    sBarcodeAttr.FontVertMulti = 1;
    sBarcodeAttr.AboveCode = FALSE;
    sBarcodeAttr.iNarrow = pBarcode->Width;
    sBarcodeAttr.iWide = pBarcode->Width * pBarcode->Ratio;
    sBarcodeAttr.iHeight = pBarcode->ParamNum1 - pBarcode->Width;
    sBarcodeAttr.iHuman =  0;
    sBarcodeAttr.iRotation = ToDegree(pBarcode->Orientation);
    sBarcodeAttr.iCheck = GetBarcodeCheck(pBarcodeInfo, pBarcode, pData->Content);
    sBarcodeAttr.pFont = _NULL;
    sBarcodeAttr.pExp = (BYTE *)GetBarcodeExp(pBarcode, pData->Content);
    sBarcodeAttr.eLanguage = LANG_ZPL;
    sBarcodeAttr.ePutWay = ToPutWay(pField->Reverse);

    if (sBarcodeAttr.iHeight < pBarcode->Width)
        sBarcodeAttr.iHeight = pBarcode->Width;

    if (pBarcodeInfo->PreviewBarcode == _NULL)
        return FALSE;
    pBarcodeInfo->PreviewBarcode(&sBarcodeAttr);

    Height = sBarcodeAttr.TotalHeight + pBarcode->Width * 2;
    sAxis = GetFieldAxis(pField, sBarcodeAttr.TotalWidth, Height, sBarcodeAttr.iRotation);
    sBarcodeAttr.sCoord.iX = XAxis(sAxis.X);
    sBarcodeAttr.sCoord.iY = YAxis(sAxis.Y);

    if (sBarcodeAttr.iRotation == 0)
        sBarcodeAttr.sCoord.iY += pBarcode->Width;
    if (sBarcodeAttr.iRotation == 90)
        sBarcodeAttr.sCoord.iX -= pBarcode->Width;
    if (sBarcodeAttr.iRotation == 180)
        sBarcodeAttr.sCoord.iY -= pBarcode->Width;
    if (sBarcodeAttr.iRotation == 270)
        sBarcodeAttr.sCoord.iX += pBarcode->Width;

    if (pBarcodeInfo->OutBarcode == _NULL)
        return FALSE;
    pBarcodeInfo->OutBarcode(&sBarcodeAttr);

    sBarAttr.psImageBuffer = &sImageBuffer;
    sBarAttr.iType = ToPutWay(pField->Reverse) ? DRAW_REVERSE : DRAW_BAR;
    sBarAttr.sCoord.iX = XAxis(pField->Origin.X);
    sBarAttr.sCoord.iY = YAxis(pField->Origin.Y);
    sBarAttr.iWidth = pBarcode->Width;
    sBarAttr.iHeight = pBarcode->Width;
    if (sBarcodeAttr.iRotation == 0 || sBarcodeAttr.iRotation == 180)
        sBarAttr.iWidth = sBarcodeAttr.TotalWidth;
    if (sBarcodeAttr.iRotation == 90 || sBarcodeAttr.iRotation == 270)
        sBarAttr.iHeight = sBarcodeAttr.TotalWidth;
    DrawBar(&sBarAttr);

    if (sBarcodeAttr.iRotation == 0 || sBarcodeAttr.iRotation == 180)
        sBarAttr.sCoord.iY += Height - pBarcode->Width;
    if (sBarcodeAttr.iRotation == 90 || sBarcodeAttr.iRotation == 270)
        sBarAttr.sCoord.iX += Height - pBarcode->Width;
    DrawBar(&sBarAttr);

    SetTypesetOrigin(&sAxis, sBarcodeAttr.TotalWidth, Height, sBarcodeAttr.iRotation);

    StoreDrawArea(pDrawArea, sBarcodeAttr.sCoord.iX, sBarcodeAttr.sCoord.iY,
                    sBarcodeAttr.TotalWidth, Height, sBarcodeAttr.iRotation);
    return TRUE;
}

STATIC BOOL DrawMaxiCode(_Field *pField, _FieldData *pData, _DrawArea *pDrawArea)
{
    _FieldBarcode *pBarcode = &pField->Draw.Barcode;
    _MaxiAttr sMaxiAttr;
    _Axis sAxis;
    CHAR *pExp = pData->Content;
    CHAR Buffer[10];

    sMaxiAttr.psImageBuffer = &sImageBuffer;
    sMaxiAttr.iMode = pBarcode->Mode;
    sMaxiAttr.iClass = 0;
    sMaxiAttr.iCountry = 0;
    sMaxiAttr.iPost = 0;

    if (sMaxiAttr.iMode == 2 || sMaxiAttr.iMode == 3)
    {
        memset(Buffer, 0, sizeof(Buffer));

        // three-digit class of service
        strncpy(Buffer, pExp, 3);
        sMaxiAttr.iClass = atoi(Buffer);

        // three-digit country zip code
        strncpy(Buffer, pExp + 3, 3);
        sMaxiAttr.iCountry = atoi(Buffer);

        // get zip code
        if (sMaxiAttr.iMode == 2)
        {
            strncpy(Buffer, pExp + 6, 9);
            sMaxiAttr.iPost = atol(Buffer);
            pExp += 15;
        }
        else if (sMaxiAttr.iMode == 3)
        {
            memcpy((CHAR *)sMaxiAttr.abPost, pExp + 6, 6);
            pExp += 12;
        }
    }

    sMaxiAttr.ExpLen = pData->Length - (pExp - pData->Content);
    sMaxiAttr.pExp = (BYTE *)pExp;
    sMaxiAttr.eLanguage = LANG_ZPL;
    sMaxiAttr.ePutWay = ToPutWay(pField->Reverse);
    PreviewMaxi(&sMaxiAttr);

    sAxis = GetFieldAxis(pField, sMaxiAttr.TotalWidth, sMaxiAttr.TotalHeight, 0);
    sMaxiAttr.sCoord.iX = XAxis(sAxis.X);
    sMaxiAttr.sCoord.iY = YAxis(sAxis.Y);

    Maxi(&sMaxiAttr);

    SetTypesetOrigin(&sAxis, sMaxiAttr.TotalWidth, sMaxiAttr.TotalHeight, 0);
    
    StoreDrawArea(pDrawArea, sMaxiAttr.sCoord.iX, sMaxiAttr.sCoord.iY,
                    sMaxiAttr.TotalWidth , sMaxiAttr.TotalHeight, 0);
    return TRUE;
}

STATIC BOOL DrawMPDF417(_Field *pField, _FieldData *pData, _DrawArea *pDrawArea)
{
    _FieldBarcode *pBarcode = &pField->Draw.Barcode;
    _MPDFAttr sMPDFAttr;
    _Axis sAxis;

    sMPDFAttr.psImageBuffer = &sImageBuffer;
    sMPDFAttr.sCoord.iX = 0;
    sMPDFAttr.sCoord.iY = 0;
    sMPDFAttr.Rotate = ToDegree(pBarcode->Orientation);

    sMPDFAttr.Ecc = 0;
    sMPDFAttr.Cell = pBarcode->Width;
    sMPDFAttr.Height = pBarcode->Height;
    sMPDFAttr.Column = pBarcode->Mode + 5;

    sMPDFAttr.pExp = (BYTE *)pData->Content;
    sMPDFAttr.ExpLen = pData->Length;
    sMPDFAttr.eLanguage = LANG_ZPL;
    sMPDFAttr.ePutWay = ToPutWay(pField->Reverse);

    MPDF(&sMPDFAttr, TRUE);    

    sAxis = GetFieldAxis(pField, sMPDFAttr.TotalWidth, sMPDFAttr.TotalHeight, sMPDFAttr.Rotate);
    sMPDFAttr.sCoord.iX = XAxis(sAxis.X);
    sMPDFAttr.sCoord.iY = YAxis(sAxis.Y);

    MPDF(&sMPDFAttr, FALSE);

    SetTypesetOrigin(&sAxis, sMPDFAttr.TotalWidth, sMPDFAttr.TotalHeight, sMPDFAttr.Rotate);

    StoreDrawArea(pDrawArea, sMPDFAttr.sCoord.iX, sMPDFAttr.sCoord.iY,
                    sMPDFAttr.TotalWidth , sMPDFAttr.TotalHeight, sMPDFAttr.Rotate);
    return TRUE;
}

STATIC BOOL DrawQRCode(_Field *pField, _FieldData *pData, _DrawArea *pDrawArea)
{
    _FieldBarcode *pBarcode = &pField->Draw.Barcode;
    _Axis sAxis;
    _QRCodeAttr sQRCodeAttr;
//    INT Len;
//    CHAR *pSourceData;

    sQRCodeAttr.Rotate = 0;
    sQRCodeAttr.iModelNum = pBarcode->Mode;    
    sQRCodeAttr.MaskNum = 0x0f;
    sQRCodeAttr.MaskNum &= 0xfff0;
    sQRCodeAttr.MaskNum |= 7;
    sQRCodeAttr.psImageBuffer = &sImageBuffer;
    sQRCodeAttr.eLanguage = LANG_ZPL;
    sQRCodeAttr.ePutWay = ToPutWay(pField->Reverse);
    sQRCodeAttr.CellWidth = pBarcode->ParamNum1;
    sQRCodeAttr.bErrLV = 'L';
    sQRCodeAttr.bModel = 'A';

//    pSourceData = pData->Content;
//    Len = pData->Length;
//    while (*pSourceData != ',' && *pSourceData != '\0')
//    {
//        if (CheckChar(*pSourceData, "HQML"))
//            sQRCodeAttr.bErrLV = *pSourceData;
//        pSourceData += 1;
//        Len -= 1;
//        if (Len == 0)
//            break;
//    }
//
//    SendPrintf("\r\n Len1:%d", pData->Length );
//    SendPrintf("\r\n Exp1:%s", pData->Content );
//
//    SendPrintf("\r\n Len2:%d", Len );
//    SendPrintf("\r\n Exp2:%s", pSourceData );
//
//    sQRCodeAttr.pExp = (BYTE *)pSourceData;
//    sQRCodeAttr.ExpLen = Len;

    sQRCodeAttr.pExp = (BYTE *)pData->Content;
    sQRCodeAttr.ExpLen = pData->Length;

    PreviewQRCode(&sQRCodeAttr);

    sQRCodeAttr.pExp = (BYTE *)pData->Content;
    sQRCodeAttr.ExpLen = pData->Length;

    sAxis = GetFieldAxis(pField, sQRCodeAttr.TotalWidth, sQRCodeAttr.TotalHeight, sQRCodeAttr.Rotate);
    sQRCodeAttr.sCoord.iX = XAxis(sAxis.X);
    sQRCodeAttr.sCoord.iY = YAxis(sAxis.Y);
    QRCode(&sQRCodeAttr);

    SetTypesetOrigin(&sAxis, sQRCodeAttr.TotalWidth, sQRCodeAttr.TotalHeight, sQRCodeAttr.Rotate);
    StoreDrawArea(pDrawArea, sQRCodeAttr.sCoord.iX, sQRCodeAttr.sCoord.iY,
                    sQRCodeAttr.TotalWidth, sQRCodeAttr.TotalHeight, sQRCodeAttr.Rotate);
    return TRUE;
}

STATIC BOOL DrawRSS(_Field *pField, _FieldData *pData, _DrawArea *pDrawArea)
{
    _FieldBarcode *pBarcode = &pField->Draw.Barcode;
    _RSSAttr sRSSAttr;
    _Axis sAxis;

    sRSSAttr.psImageBuffer = &sImageBuffer;
    sRSSAttr.Rotate    = ToDegree(pBarcode->Orientation);

    sRSSAttr.sym       = pBarcode->Mode;        // symbology type in the RSS-14 family
    sRSSAttr.pixMult   = pBarcode->Columns;        // magnification factor    
    sRSSAttr.sepHt     = pBarcode->Rows;        // separator height 
    sRSSAttr.segWidth  = pBarcode->ParamNum2;    // the segment width (RSS expanded only)
    sRSSAttr.linHeight = pBarcode->ParamNum1;    // bar code height

    sRSSAttr.pExp      = (BYTE *)pData->Content;
    sRSSAttr.ExpLen    = pData->Length;
    sRSSAttr.ePutWay   = ToPutWay(pField->Reverse);

    PreviewRSS(&sRSSAttr);

    sAxis = GetFieldAxis(pField, sRSSAttr.TotalWidth, sRSSAttr.TotalHeight, sRSSAttr.Rotate);
    sRSSAttr.sCoord.iX = XAxis(sAxis.X);
    sRSSAttr.sCoord.iY = YAxis(sAxis.Y);

    RSS(&sRSSAttr);

    SetTypesetOrigin(&sAxis, sRSSAttr.TotalWidth, sRSSAttr.TotalHeight, sRSSAttr.Rotate);
    StoreDrawArea(pDrawArea, sRSSAttr.sCoord.iX, sRSSAttr.sCoord.iY,
                    sRSSAttr.TotalWidth, sRSSAttr.TotalHeight, sRSSAttr.Rotate);
    return TRUE;
}

STATIC BOOL DrawDMatrix(_Field *pField, _FieldData *pData, _DrawArea *pDrawArea)
{
    _FieldBarcode *pBarcode = &pField->Draw.Barcode;
    _Axis sAxis;
    _DMatrixAttr sDmatrixAttr;
    WORD XCells, YCells;

    sDmatrixAttr.psImageBuffer = &sImageBuffer;
    sDmatrixAttr.FormatID = pBarcode->Mode;
    sDmatrixAttr.EccType = LCN_ECCTYPE_ECC200;
    sDmatrixAttr.CtrlChr = pBarcode->ParamChar1;
    sDmatrixAttr.CellWidth = 0;
    sDmatrixAttr.Xcells = 0;
    sDmatrixAttr.Ycells = 0;
    sDmatrixAttr.Human = 0;
    sDmatrixAttr.Rotate = ToDegree(pBarcode->Orientation);
    sDmatrixAttr.WLimit = 0;
    sDmatrixAttr.HLimit = 0;
    sDmatrixAttr.eLanguage = LANG_ZPL;
    sDmatrixAttr.ePutWay = ToPutWay(pField->Reverse);

    if (pBarcode->Height > 10)
    {
        sDmatrixAttr.CellWidth = 0;
        sDmatrixAttr.HLimit = pBarcode->Height;
    }
    else
    {
        sDmatrixAttr.CellWidth = pBarcode->Height;
        sDmatrixAttr.HLimit = 0;
    }

    if (pBarcode->Columns == 0)
    {
        XCells = ChkXcellDMX((BYTE)sDmatrixAttr.EccType , pBarcode->Columns);
        sDmatrixAttr.Xcells = XCells;            
    }
    else
    {
        ChkXYcellDMX((BYTE)sDmatrixAttr.EccType, pBarcode->Columns , pBarcode->Rows, &XCells, &YCells);
        sDmatrixAttr.Ycells = YCells;
    }
    sDmatrixAttr.pExp = (BYTE *)pData->Content;
    sDmatrixAttr.ExpLen = pData->Length;
    
    PreviewDmatrix(&sDmatrixAttr);

    sAxis = GetFieldAxis(pField, sDmatrixAttr.TotalWidth, sDmatrixAttr.TotalHeight, sDmatrixAttr.Rotate);
    sDmatrixAttr.sCoord.iX = XAxis(sAxis.X);
    sDmatrixAttr.sCoord.iY = YAxis(sAxis.Y);
    Dmatrix(&sDmatrixAttr);

    SetTypesetOrigin(&sAxis, sDmatrixAttr.TotalWidth, sDmatrixAttr.TotalHeight, sDmatrixAttr.Rotate);
    
    StoreDrawArea(pDrawArea, sDmatrixAttr.sCoord.iX, sDmatrixAttr.sCoord.iY,
                    sDmatrixAttr.TotalWidth, sDmatrixAttr.TotalHeight, sDmatrixAttr.Rotate);
    return TRUE;
}

STATIC _Axis DrawBlock(_Field *pField, _FieldData *pData, _TextAttr *pTextAttr)
{
    _FieldBlock *pBlock = &pField->Block;
    _Axis sAxis = GetTextFieldAxis(pField, pTextAttr);
    CHAR Content[MAX_CONTENT + 1];
    CHAR Saved[MAX_CONTENT + 1];
    INT Length = 0;
    INT Output = 0;
    INT Remain = 0;
    INT Line   = 1;
    INT Index  = 0;

    while (Index < pData->Length)
    {
        CHAR Data = *(pData->Content + Index);
        CHAR Next = *(pData->Content + Index + 1);

        Index += 1;

        // special functions
        if (Data == '\\')
        {
            // carriage return / line feed
            if (Next == '&')
            {
                Output = 1;
                Index += 1;
            }
            // backslash (\)
            else if (Next == '\\')
            {
                Content[Length++] = '\\';
                Index += 1;
            }
        }

        // remove leading spaces
        else if (Length != 0 || Data != ' ')
            Content[Length++] = Data;

        if (Output == 0 && Length != 0 && Content[Length - 1] != ' ')
        {
            // preview the length of text contains hyphen (-)
            Content[Length] = '-';    // hyphen
            Content[Length + 1] = '\0';
            pTextAttr->ExpLength = Length + 1;
            pTextAttr->pExp = (BYTE *)Content;
            PreviewText(pTextAttr);

            // hanging indent of the second and remaining lines
            if (Line != 1)
                pTextAttr->iRealWidth += pBlock->HangingIndent;

            if (pTextAttr->iRealWidth > pBlock->Width)
            {
                INT Backup = Length;

                // find the last space character
                while (Length && Content[Length - 1] != ' ')
                    Length -= 1;

                if (Length == 0)
                {
                    Length = Backup;

                    // if this is end of text
                    if (Index == pData->Length || Next == ' ')
                    {
                        // preview the length of text without hyphen (-)
                        Content[Length] = '\0';
                        pTextAttr->ExpLength = Length;
                        pTextAttr->pExp = (BYTE *)Content;
                        PreviewText(pTextAttr);
                    }
                    if (pTextAttr->iRealWidth > pBlock->Width && Length > 1)
                    {
                        Remain = 1;
                        memcpy(Saved, Content + Length - Remain, Remain);
                        Content[Length - 1] = '-';    // hyphen
                    }
                }
                else
                {
                    Remain = Backup - Length;
                    memcpy(Saved, Content + Length, Remain);
                }
                Output = 1;
            }
        }

        if (Output)
        {
            if (Length != 0)
            {
                Content[Length] = '\0';
                pTextAttr->sCoord.iX = XAxis(sAxis.X);
                pTextAttr->sCoord.iY = YAxis(sAxis.Y);
                pTextAttr->ExpLength = Length;
                pTextAttr->pExp = (BYTE *)Content;
                PreviewText(pTextAttr);
                TextJustification(pField, pTextAttr);
                OutText(pTextAttr);

                Length = Remain;
                memcpy(Content, Saved, Length);
                Remain = 0;
            }
            if (pBlock->Line > Line)
            {
                SHORT RealHeight = pTextAttr->iRealHeight;

                // download bitmap fonts only had half the real height
                if (pTextAttr->iAdjustLine)
                    RealHeight /= 2;

                if (pTextAttr->iRotation == 0)
                    sAxis.Y += RealHeight + pBlock->Space;
                else if (pTextAttr->iRotation == 90)
                    sAxis.X -= RealHeight + pBlock->Space;
                else if (pTextAttr->iRotation == 180)
                    sAxis.Y -= RealHeight + pBlock->Space;
                else if (pTextAttr->iRotation == 270)
                    sAxis.X += RealHeight + pBlock->Space;

                Line += 1;
            }
            else
                        {
                            Length = 0;
                            Content[0] = '\0';
                            break;
                        }
            Output = 0;
        }
    }
    if (Length != 0)
    {
        Content[Length] = '\0';
        pTextAttr->sCoord.iX = XAxis(sAxis.X);
        pTextAttr->sCoord.iY = YAxis(sAxis.Y);
        pTextAttr->ExpLength = Length;
        pTextAttr->pExp = (BYTE *)Content;
        PreviewText(pTextAttr);
        TextJustification(pField, pTextAttr);
        OutText(pTextAttr);
    }
    return sAxis;
}

STATIC BOOL DrawFont(_Field *pField, _FieldData *pData, _DrawArea *pDrawArea)
{
    _FieldFont Font = pField->Draw.Font;
    _FieldBlock *pBlock = &pField->Block;
    _TextAttr sTextAttr;
    _Axis sAxis;
    INT Rotation;
    SHORT Width;
    SHORT Height;

    if (!pData->Length)
        return FALSE;

    SetFontSpecify(&Font);

    // Copy Text setting
    sTextAttr.iDirection = sTextAttr.iRotation = ToDegree(Font.Orientation);
    sTextAttr.iHoriMulti = Font.Width;
    sTextAttr.iVertMulti = Font.Height;
    sTextAttr.ExpLength  = pData->Length;
    sTextAttr.pExp       = (BYTE *)pData->Content;
    sTextAttr.pFont      = (BYTE *)Font.File.Name;
    sTextAttr.eLanguage  = LANG_ZPL;
    sTextAttr.ePutWay    = ToPutWay(pField->Reverse);

    if (pField->Parameter.Direction == 'V')    // vertical printing (top to bottom)
        sTextAttr.iDirection = (sTextAttr.iDirection +  90) % 360;
    if (pField->Parameter.Direction == 'R')    // reverse printing (right to left)
        sTextAttr.iDirection = (sTextAttr.iDirection + 180) % 360;

    sTextAttr.psImageBuffer = &sImageBuffer;

    PreviewText(&sTextAttr);

    if (pBlock->Use)
    {
        sAxis = DrawBlock(pField, pData, &sTextAttr);
    }
    else
    {
        sAxis = GetTextFieldAxis(pField, &sTextAttr);

        sTextAttr.sCoord.iX = XAxis(sAxis.X);
        sTextAttr.sCoord.iY = YAxis(sAxis.Y);

        OutText(&sTextAttr);
    }

    Rotation = sTextAttr.iRotation;
    Width = sTextAttr.iRealWidth;
    Height = sTextAttr.iRealHeight;
    if (pField->Parameter.Direction == 'R')    // reverse printing (right to left)
    {
        Rotation = (sTextAttr.iRotation + 90) % 360;
        Width = sTextAttr.iRealHeight;
        Height = sTextAttr.iRealWidth;
    }

    SetTypesetOrigin(&sAxis, sTextAttr.iRealWidth, sTextAttr.iBaseLine + sTextAttr.iAdjustLine, Rotation);
    StoreDrawArea(pDrawArea, sTextAttr.sCoord.iX, sTextAttr.sCoord.iY, Width, Height, Rotation);
    return TRUE;
}

STATIC BOOL DrawBarcode(_Field *pField, _FieldData *pData, _DrawArea *pDrawArea)
{
    _FieldBarcode *pBarcode = &pField->Draw.Barcode;
    _ZplBarcodeInfo *pBarcodeInfo;
    _BarCodeAttr sBarcodeAttr;
    _Axis sAxis;

    if (pBarcode->Type == BARCODE_AZTEC)
        return DrawAZTEC(pField, pData, pDrawArea);
    if (pBarcode->Type == BARCODE_PDF417)
        return DrawPDF417(pField, pData, pDrawArea);
    if (pBarcode->Type == BARCODE_CODABLOCK)
        return DrawCodaBlock(pField, pData, pDrawArea);
    if (pBarcode->Type == BARCODE_UPS_MAXICODE)
        return DrawMaxiCode(pField, pData, pDrawArea);
    if (pBarcode->Type == BARCODE_MICRO_PDF417)
        return DrawMPDF417(pField, pData, pDrawArea);
    if (pBarcode->Type == BARCODE_QR_CODE)
        return DrawQRCode(pField, pData, pDrawArea);
    if (pBarcode->Type == BARCODE_RSS)
        return DrawRSS(pField, pData, pDrawArea);
    if (pBarcode->Type == BARCODE_DATA_MATRIX)
        return DrawDMatrix(pField, pData, pDrawArea);
    if ((pBarcodeInfo = GetBarcodeInfo(pBarcode->Type)) == _NULL)
        return FALSE;

    sBarcodeAttr.iHeight = pBarcode->Height;
    sBarcodeAttr.iRotation = ToDegree(pBarcode->Orientation);
    sBarcodeAttr.iNarrow = pBarcode->Width;
    sBarcodeAttr.iWide = pBarcode->Width * pBarcode->Ratio;
    sBarcodeAttr.iCheck = GetBarcodeCheck(pBarcodeInfo, pBarcode, pData->Content);
    sBarcodeAttr.pExp = (BYTE *)GetBarcodeExp(pBarcode, pData->Content);

    SetBarcodeHuman(&sBarcodeAttr, pBarcodeInfo, pField);

    sBarcodeAttr.eLanguage = LANG_ZPL;
    sBarcodeAttr.ePutWay = ToPutWay(pField->Reverse);
    sBarcodeAttr.psImageBuffer = &sImageBuffer;

    if (pBarcodeInfo->PreviewBarcode == _NULL)
        return FALSE;

    pBarcodeInfo->PreviewBarcode(&sBarcodeAttr);

    sAxis = GetFieldAxis(pField, sBarcodeAttr.TotalWidth, sBarcodeAttr.TotalHeight, sBarcodeAttr.iRotation);
    sBarcodeAttr.sCoord.iX = XAxis(sAxis.X);
    sBarcodeAttr.sCoord.iY = YAxis(sAxis.Y);

    if (pBarcodeInfo->OutBarcode == _NULL)
        return FALSE;

    pBarcodeInfo->OutBarcode(&sBarcodeAttr);

    SetTypesetOrigin(&sAxis, sBarcodeAttr.TotalWidth, sBarcodeAttr.TotalHeight, sBarcodeAttr.iRotation);
    StoreBarcodeDrawArea(pDrawArea, &sBarcodeAttr, pBarcodeInfo);
    return TRUE;
}

STATIC BOOL DrawGraphic(_Field *pField)
{
    _FieldGraphic *pGraphic = &pField->Draw.Graphic;
    _DiagonalAttr sDiagonalAttr;
    _FrameAttr sFrameAttr;
    _Axis sAxis;
    INT Type;

    if (ToPutWay(pField->Reverse) == PUT_XOR)
        Type = DRAW_REVERSE;
    else if (pGraphic->Color == 'W')
        Type = DRAW_ERASE;
    else
        Type = DRAW_BAR;

    sAxis = GetFieldAxis(pField, pGraphic->Width, pGraphic->Height, 0);
    SetTypesetOrigin(&sAxis, pGraphic->Width, pGraphic->Height, 0);

    // draw diagonal GD
    if ((pGraphic->Diagonal == 'L') || (pGraphic->Diagonal == '/'))
    {
        sDiagonalAttr.psImageBuffer = &sImageBuffer;
        sDiagonalAttr.iType = Type;
        sDiagonalAttr.Direction = DIAGONAL_VERTICAL;
        sDiagonalAttr.sCoord1.iX = XAxis(sAxis.X);
        sDiagonalAttr.sCoord1.iY = YAxis(sAxis.Y);
        sDiagonalAttr.sCoord2.iX = XAxis(sAxis.X) + pGraphic->Width - 1;
        sDiagonalAttr.sCoord2.iY = YAxis(sAxis.Y) + pGraphic->Height - 1;
        sDiagonalAttr.iThickness = pGraphic->Thickness;
        DrawDiagonal(&sDiagonalAttr);
    }
    // draw diagonal GD
    else if ((pGraphic->Diagonal == 'R') || (pGraphic->Diagonal == '\\'))
    {
        sDiagonalAttr.psImageBuffer = &sImageBuffer;
        sDiagonalAttr.iType = Type;
        sDiagonalAttr.Direction = DIAGONAL_VERTICAL;
        sDiagonalAttr.sCoord1.iX = XAxis(sAxis.X) + pGraphic->Width - 1;
        sDiagonalAttr.sCoord1.iY = YAxis(sAxis.Y);
        sDiagonalAttr.sCoord2.iX = XAxis(sAxis.X);
        sDiagonalAttr.sCoord2.iY = YAxis(sAxis.Y) + pGraphic->Height - 1;
        sDiagonalAttr.iThickness = pGraphic->Thickness;
        DrawDiagonal(&sDiagonalAttr);
    }
    // draw ellipse
    else if (pGraphic->RadiusX != pGraphic->RadiusY)    
    {
        sFrameAttr.psImageBuffer = &sImageBuffer;
        sFrameAttr.iType = Type;
        sFrameAttr.sCoord.iX = XAxis(sAxis.X);
        sFrameAttr.sCoord.iY = YAxis(sAxis.Y);
        sFrameAttr.iWidth = pGraphic->Width;
        sFrameAttr.iHeight = pGraphic->Height;
        sFrameAttr.iThickness = pGraphic->Thickness;
        sFrameAttr.iRadius = (pGraphic->RadiusX) < (pGraphic->RadiusY) 
                            ? (pGraphic->RadiusX) : (pGraphic->RadiusY);
        DrawFrame(&sFrameAttr);
    }
    // draw box, circle
    else
    {
        sFrameAttr.psImageBuffer = &sImageBuffer;
        sFrameAttr.iType = Type;
        sFrameAttr.sCoord.iX = XAxis(sAxis.X);
        sFrameAttr.sCoord.iY = YAxis(sAxis.Y);
        sFrameAttr.iWidth = pGraphic->Width;
        sFrameAttr.iHeight = pGraphic->Height;
        sFrameAttr.iThickness = pGraphic->Thickness;
        sFrameAttr.iRadius = (pGraphic->RadiusX) < (pGraphic->RadiusY) 
                            ? (pGraphic->RadiusX) : (pGraphic->RadiusY);
        DrawFrame(&sFrameAttr);
    }
    return TRUE;
}

STATIC BOOL DrawImage(_Field *pField)
{
    _FieldImage    *pImage = &pField->Draw.Image;
    _FileHandle *Handle;
    _ImgBuf Image;
    _Axis sAxis = {0, 0};
    SHORT Height, Width, ByteWidth;
    BYTE *pLineBuf;
    _ePutWay PutWay = ToPutWay(pField->Reverse);
    INT Rotate = 0;
    INT X, Y;
    INT    state = FALSE;
    INT LimitHeight;
    INT i, j;

    if (pImage->Type == IMAGE_MOVE)
        Rotate = ToDegree(FieldDef.Orientation);

    if (pImage->File.Device == _NULL)
    {
        // Device Default Value: search priority(R:, E:, B:, and A:)
        if ((Handle = Fopen(ToFileDevice(MemoryAlias.R), pImage->File.Name, "r")) == _NULL)
        if ((Handle = Fopen(ToFileDevice(MemoryAlias.E), pImage->File.Name, "r")) == _NULL)
        if ((Handle = Fopen(ToFileDevice(MemoryAlias.B), pImage->File.Name, "r")) == _NULL)
        if ((Handle = Fopen(ToFileDevice(MemoryAlias.A), pImage->File.Name, "r")) == _NULL)
            return state;
    }
    else if ((Handle = Fopen(ToFileDevice(pImage->File.Device), pImage->File.Name, "r")) == _NULL)
        return state;

    Fread(&Height, sizeof(SHORT), 1, Handle);
    Fread(&Width,  sizeof(SHORT), 1, Handle);
    Height = le16_to_cpu(Height);
    Width  = le16_to_cpu(Width);
    ByteWidth = (Width + 7) / 8;
    LimitHeight = 8;
    if (Height == 0 || Width == 0)
        return state;

    if (pImage->Type != IMAGE_LOAD)
        sAxis = GetFieldAxis(pField, Width * pImage->MultiX, Height * pImage->MultiY, 0);

    if (Rotate == 0 || Rotate == 180)
        SetTypesetOrigin(&sAxis, Width * pImage->MultiX, Height * pImage->MultiY, 0);
    else if (Rotate == 90 || Rotate == 270)
        SetTypesetOrigin(&sAxis, Height * pImage->MultiY, Width * pImage->MultiX, 0);

    X = XAxis(sAxis.X);
    Y = YAxis(sAxis.Y);

    if (Rotate == 90)
        X += Height * pImage->MultiY;
    else if (Rotate == 180)
        Y += Height * pImage->MultiY;

    Image.iWidth = Width * pImage->MultiX;
    Image.iByteWidth = (Image.iWidth + 7) / 8;

    if (Image.pBuffer = malloc(Image.iByteWidth * pImage->MultiY * LimitHeight))
    {
        if (pLineBuf = malloc(ByteWidth))
        {
            for (i = Height; i > 0; i -= LimitHeight)
            {
                if (i < LimitHeight)
                    LimitHeight = i;

                Image.iHeight = pImage->MultiY * LimitHeight;
                for (j = 0; j < LimitHeight; j++)
                {
                    Fread(pLineBuf, sizeof(BYTE), ByteWidth, Handle);
                    LineMultiple(pLineBuf, Image.pBuffer + Image.iByteWidth * pImage->MultiY * j,
                        Width, pImage->MultiX, pImage->MultiY, 0);
                }
                if (Rotate == 90)
                    X -= Image.iHeight;
                else if (Rotate == 180)
                    Y -= Image.iHeight;

                PutImage(&sImageBuffer, &Image, X, Y, Rotate, PutWay);

                if (Rotate == 0)
                    Y += Image.iHeight;
                else if (Rotate == 270)
                    X += Image.iHeight;
            }
            state = TRUE;
            free(pLineBuf);
        }
        free(Image.pBuffer);
    }
    Fclose(Handle);

    return state;
}

BOOL OutField(_Field *pField, _FieldData *pData, _DrawArea *pDrawArea)
{
    BOOL state = FALSE;
    int i;

    // blank format
    if (pField->DrawType == DRAW_FONT && !pData->Length)
        return state;

    ReloadWaitTime();

    if (pField->DrawType == DRAW_FONT)
        state = DrawFont(pField, pData, pDrawArea);
    else if (pField->DrawType == DRAW_BARCODE)
        state = DrawBarcode(pField, pData, pDrawArea);
    else if (pField->DrawType == DRAW_GRAPHIC)
        state = DrawGraphic(pField);
    else if (pField->DrawType == DRAW_IMAGE)
        state = DrawImage(pField);

    return state;
}

BOOL GraphicField(CHAR Type, LONG BinaryCount, LONG GraphicCount, LONG RowByte)
{
    _ePutWay PutWay = ToPutWay(Field.Reverse);
    _ObjDecode Decode;
    _ImgBuf Image;
    _Axis sAxis;
    SHORT Height, Width, Multiple;
    BYTE *Buffer;
    INT X, Y;
    INT Len, Row;
    INT state = TRUE;

    Height = GraphicCount / RowByte;
    Width  = RowByte * 8;
    Multiple = (MeasureUnit == 'D') ? ConvertDPI : 1;
    if ((Buffer = malloc(RowByte * (Multiple * Multiple + 1))) == _NULL)
        return FALSE;

    sAxis = GetFieldAxis(&Field, Width * Multiple, Height * Multiple, 0);
    SetTypesetOrigin(&sAxis, Width * Multiple, Height * Multiple, 0);

    X = XAxis(sAxis.X);
    Y = YAxis(sAxis.Y);

    Image.pBuffer = Buffer + RowByte;
    Image.iHeight = Multiple;
    Image.iWidth  = Width * Multiple;
    Image.iByteWidth = RowByte * Multiple;

    ReloadWaitTime();

    // ASCII hexadecimal
    if (Type == 'A')
    {
        memset(Buffer, 0, RowByte);
        if (!ObjectDecodeInit(&Decode))
            state = FALSE;
        for (Len = 0; state && Len < Height; Len++)
        {
            if (ObjectDecoding(&Decode, Buffer, RowByte) != RowByte)
                state = FALSE;
            LineMultiple(Buffer, Image.pBuffer, Width, Multiple, Multiple, 0);
            if (state)
                PutImage(&sImageBuffer, &Image, X, Y + Multiple * Len, 0, PutWay);
        }
        if (!ObjectDecodeExit(&Decode))
            state = FALSE;
    }

    // binary
    else if (Type == 'B')
    {
        for (Len = 0; Len < Height; Len++)
        {
            for (Row = 0; Row < RowByte; Row++)
                *(Buffer + Row) = ZebraNextByte(NEXT_ANY);
            LineMultiple(Buffer, Image.pBuffer, Width, Multiple, Multiple, 0);
            PutImage(&sImageBuffer, &Image, X, Y + Multiple * Len, 0, PutWay);
        }
    }

    // not support compressed binary
    else if (Type == 'C')
    {
        for (Len = 0; Len < BinaryCount; Len++)
            ZebraNextByte(NEXT_ANY);
        state = FALSE;
    }

    free(Buffer);

    return state;
}

#endif

Zpl2Image.h   、、、、、、、、、、、、、、、、、、、、、、、、

#ifndef ZPL2IMAGE_H

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

#define ZPL2IMAGE_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         *
 *                                                                            *
 ******************************************************************************/

/* None */

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

#include "Zpl2Type.h"

#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 DRAW_NULL                0
#define DRAW_FONT                'A'
#define DRAW_BARCODE            'B'
#define DRAW_GRAPHIC            'G'
#define DRAW_IMAGE                'I'

#define BARCODE_AZTEC            '0'
#define BARCODE_CODE11            '1'
#define BARCODE_INTERLEAVE25    '2'
#define BARCODE_CODE39            '3'
#define BARCODE_CODE49            '4'
#define BARCODE_PLANET_CODE        '5'
#define BARCODE_PDF417            '7'
#define BARCODE_EAN8            '8'
#define BARCODE_UPCE            '9'
#define BARCODE_CODE93            'A'
#define BARCODE_CODABLOCK        'B'
#define BARCODE_CODE128            'C'
#define BARCODE_EAN128            'c'
#define BARCODE_UPS_MAXICODE    'D'
#define BARCODE_EAN13            'E'
#define BARCODE_MICRO_PDF417    'F'
#define BARCODE_INDUSTRIAL25    'I'
#define BARCODE_STANDARD25        'J'
#define BARCODE_ANSI_CODABAR    'K'
#define BARCODE_LOGMARS            'L'
#define BARCODE_MSI                'M'
#define BARCODE_PLESSEY            'P'
#define BARCODE_QR_CODE            'Q'
#define BARCODE_RSS                'R'
#define BARCODE_UPC_EAN            'S'
#define BARCODE_TLC39            'T'
#define BARCODE_UPCA            'U'
#define BARCODE_DATA_MATRIX        'X'
#define BARCODE_POSTNET            'Z'

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

/******************************************************************************
 *                                                                            *
 *    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 ZPL2IMAGE_C
#define EXTERN 
#else
#define EXTERN extern
#endif

/******************************************************************************
 *                                                                            *
 *       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                    *
 *                                                                            *
 ******************************************************************************/

BOOL OutField(_Field *, _FieldData *, _DrawArea *);
BOOL GraphicField(CHAR, LONG, LONG, LONG);

#undef EXTERN

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

#endif

Zpl2Object.c   、、、、、、、、、、、、、、、、、、、、、、、、、、

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

#define ZPL2OBJECT_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 "XLED.h"
#include "XKey.h"
#include "XTimer.h"
#include "XDisplay.h"
#include "XFileSys.h"
#include "XFunction.h"
#include "..\Parser.h"
#include "..\ParserUtil.h"
#include "zlib\zlib.h"
#include "Zpl2Util.h"
#include "Zpl2Control.h"
#include "Zpl2Object.h"

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

#if defined(ZPL2)

/******************************************************************************
 *                                                                            *
 *                        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     *
 *                                                                            *
 ******************************************************************************/

/* Base-64 decoding.  This represents binary data as printable ASCII
** characters.  Three 8-bit binary bytes are turned into four 6-bit
** values, like so:
**
**   [11111111]  [22222222]  [33333333]
**
**   [111111] [112222] [222233] [333333]
**
** Then the 6-bit values are represented using the characters "A-Za-z0-9+/".
*/
STATIC CONST CHAR Base64Tab[96] =
{
//    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
//    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
    -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
//    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
//    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
//    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
//    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
//    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
//    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
//    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
//    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
};

#if defined(TPH_DPI_200)
STATIC _ObjFile sFontMap[] =
{
/* 0 */    {'Z',    "0.FNT"},
/* 1 */    {_NULL,    ""},
/* 2 */    {_NULL,    ""},
/* 3 */    {_NULL,    ""},
/* 4 */    {_NULL,    ""},
/* 5 */    {_NULL,    ""},
/* 6 */    {_NULL,    ""},
/* 7 */    {_NULL,    ""},
/* 8 */    {_NULL,    ""},
/* 9 */    {_NULL,    ""},
/* A */    {'Z',    "A.FNT"},
/* B */    {'Z',    "B.FNT"},
/* C */    {'Z',    "D.FNT"},
/* D */    {'Z',    "D.FNT"},
/* E */    {'Z',    "E8.FNT"},
/* F */    {'Z',    "F.FNT"},
/* G */    {'Z',    "G.FNT"},
/* H */    {'Z',    "H8.FNT"},
/* I */    {_NULL,    ""},
/* J */    {_NULL,    ""},
/* K */    {_NULL,    ""},
/* L */    {_NULL,    ""},
/* M */    {_NULL,    ""},
/* N */    {_NULL,    ""},
/* O */    {_NULL,    ""},
/* P */    {'Z',    "P.FNT"},
/* Q */    {'Z',    "Q.FNT"},
/* R */    {'Z',    "R.FNT"},
/* S */    {'Z',    "S.FNT"},
/* Y */    {'Z',    "T.FNT"},
/* U */    {'Z',    "U.FNT"},
/* V */    {'Z',    "V.FNT"},
/* W */    {_NULL,    ""},
/* X */    {_NULL,    ""},
/* Y */    {_NULL,    ""},
/* Z */    {_NULL,    ""},
};

#elif defined(TPH_DPI_300) ||  defined(TPH_DPI_600)
STATIC _ObjFile sFontMap[] =
{
/* 0 */    {'Z',    "0.FNT"},
/* 1 */    {_NULL,    ""},
/* 2 */    {_NULL,    ""},
/* 3 */    {_NULL,    ""},
/* 4 */    {_NULL,    ""},
/* 5 */    {_NULL,    ""},
/* 6 */    {_NULL,    ""},
/* 7 */    {_NULL,    ""},
/* 8 */    {_NULL,    ""},
/* 9 */    {_NULL,    ""},
/* A */    {'Z',    "A.FNT"},
/* B */    {'Z',    "B.FNT"},
/* C */    {'Z',    "D.FNT"},
/* D */    {'Z',    "D.FNT"},
/* E */    {'Z',    "E12.FNT"},
/* F */    {'Z',    "F.FNT"},
/* G */    {'Z',    "G.FNT"},
/* H */    {'Z',    "H12.FNT"},
/* I */    {_NULL,    ""},
/* J */    {_NULL,    ""},
/* K */    {_NULL,    ""},
/* L */    {_NULL,    ""},
/* M */    {_NULL,    ""},
/* N */    {_NULL,    ""},
/* O */    {_NULL,    ""},
/* P */    {'Z',    "P.FNT"},
/* Q */    {'Z',    "Q.FNT"},
/* R */    {'Z',    "R.FNT"},
/* S */    {'Z',    "S.FNT"},
/* Y */    {'Z',    "T.FNT"},
/* U */    {'Z',    "U.FNT"},
/* V */    {'Z',    "V.FNT"},
/* W */    {_NULL,    ""},
/* X */    {_NULL,    ""},
/* Y */    {_NULL,    ""},
/* Z */    {_NULL,    ""},
};

#endif

/******************************************************************************
 *                                                                            *
 *    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     *
 *                                                                            *
 ******************************************************************************/

/*
 * Do base-64 decoding on a string. Ignore any non-base64 bytes.
 * Return the actual number of bytes generated. The decoded size will
 * be at most 3/4 the size of the encoded, and may be smaller if there
 * are padding characters (blanks, newlines).
 */
STATIC BOOL DecodeBase64(_ObjDecode *dec)
{
    STATIC CHAR code;
    CHAR last;

    while (1)
    {
        last = code;
        do    do    // Avoiding the caret (^) and tilde (~) characters.
                if (CheckChar(code = ZebraNextByte(NEXT_ANY), dec->prefix))
                {
                    BackByte(code);
                    code = last;
                    return FALSE;
                }
            while (code < 32);
        while ((code = Base64Tab[code - 32]) == (CHAR)-1);

        switch ((dec->step)++)
        {
            case 1:
                dec->data = ((last << 2) | ((code & 0x30) >> 4));
                return TRUE;
            case 2:
                dec->data = (((last & 0xf) << 4) | ((code & 0x3c) >> 2));
                return TRUE;
            case 3:
                dec->step = 0;
                dec->data = (((last & 0x03) << 6) | code);
                return TRUE;
        }
    }
}

_ObjFile *FontIdentifier(CHAR id)
{
    if (isdigit(id))
        return &sFontMap[id - '0'];
    if (isupper(id))
        return &sFontMap[id - 'A' + 10];

    return sFontMap;
}

VOID ObjectDelete(CHAR device, CHAR *name)
{
    ErasingFile(ToFileDevice(device), name);
}

VOID TransferObject(_ObjFile *pSource, _ObjFile *pDest)
{
#if defined(LCD_MODEL)
    SetDisplayStatus(DIS_DOWNLOADING);
#endif

#if defined(MONO_LED)
    StartPeriodFunc(FlashLED2);
#elif defined(POLY_LED)
    StartPeriodFunc(FlashGreenLED);
#endif

    CopyFile(ToFileDevice(pSource->Device), pSource->Name,
                ToFileDevice(pDest->Device), pDest->Name);

#if defined(MONO_LED)
    CancelPeriodFunc(FlashLED2);
    ShowLED(HID_LED_IDLE, HID_LED_ON, HID_LED_IDLE);
#elif defined(POLY_LED)
    CancelPeriodFunc(FlashGreenLED);
    ShowLED(HID_LED_GREEN);
#endif

#if defined(LCD_MODEL)
    ClrDisplayStatus(DIS_DOWNLOADING);
#endif
}

STATIC VOID ObjectFail(_ObjFile *pFile, BOOL warn)
{
    Remove(ToFileDevice(pFile->Device), pFile->Name);
    if (warn)
        MemoryFailed();
}

STATIC BOOL CharCode(WORD *Code)
{
    CHAR data;

    do    data = ZebraNextByte(NEXT_ANY);
    while (CheckSeparate(data) != SEP_PREFIX && data != '#');

    if (data != '#')
        return FALSE;

    *Code = (ToHex(ZebraNextByte(NEXT_ANY)) << 12)
          | (ToHex(ZebraNextByte(NEXT_ANY)) << 8)
          | (ToHex(ZebraNextByte(NEXT_ANY)) << 4)
          |  ToHex(ZebraNextByte(NEXT_ANY));

    data = ZebraNextByte(NEXT_ANY);
    if (data != '.')
        return FALSE;

    return TRUE;
}

STATIC BOOL CharNumber(SHORT *num)
{
    CHAR buf[16];
    CHAR data;
    INT i;

    data = ZebraNextByte(NEXT_ANY);

    i = 0;
    while (CheckSeparate(data) == SEP_NULL && data != '.')
    {
        if ((isdigit(data) || data == '-') && i < 15)
            buf[i++] = data;
        data = ZebraNextByte(NEXT_ANY);
    }
    buf[i] = '\0';

    if (data != '.')
        return FALSE;

    *num = atoi(buf);

    return TRUE;
}

STATIC VOID ConvLineData(BYTE *dst, SHORT dstLen, BYTE *src, SHORT srcLen, SHORT offset)
{
    INT shiftByte = abs(offset) / 8;
    INT shiftBit  = abs(offset) % 8;
    INT dstCnt = 0;
    INT srcCnt = 0;
    BYTE data;

    if (offset >= 0)
    {
        while (dstCnt < dstLen && dstCnt < shiftByte)
            *(dst + dstCnt++) = 0;

        data = 0;
        while (dstCnt < dstLen)
        {
            *(dst + dstCnt) = data << (8 - shiftBit);
            data = (srcCnt < srcLen) ? *(src + srcCnt++) : 0;
            *(dst + dstCnt++) |= data >> shiftBit;
        }
    }
    else
    {
        srcCnt += shiftByte;
        data = (srcCnt < srcLen) ? *(src + srcCnt++) : 0;
        while (dstCnt < dstLen)
        {
            *(dst + dstCnt) = data << shiftBit;
            data = (srcCnt < srcLen) ? *(src + srcCnt++) : 0;
            *(dst + dstCnt++) |= data >> (8 - shiftBit);
        }
    }
}

STATIC SHORT SaveFontTable(BYTE *pTable, WORD CharCode, LONG Offset)
{
    *pTable++ = (BYTE)(CharCode & 0xff);
    *pTable++ = (BYTE)(CharCode >> 8);
    *pTable++ = (BYTE)(Offset & 0xff);
    *pTable++ = (BYTE)((Offset >> 8) & 0xff);
    *pTable++ = (BYTE)((Offset >> 16) & 0xff);
    *pTable++ = (BYTE)((Offset >> 24) & 0xff);
    return 6;
}

STATIC BOOL CompareEndFormat(CHAR Data, CHAR *BackData, SHORT *BackLen)
{
    STATIC SHORT index = 0;

    *BackLen = 0;
    if ((index == 0 && Data == ETX_CHAR) || (index == 2 && Data == 'Z'))
    {
        index = 0;
        return TRUE;
    }
    else if ((index == 0 && (Data == CaretChar || Data == RS_CHAR))
        || (index == 1 && Data == 'X'))
    {
        *(BackData + index++) = Data;
    }
    else
    {
        *(BackData + index++) = Data;
        *BackLen = index;
        index = 0;
    }
    return FALSE;
}

BOOL DownloadBitmapFont(_ObjFile *pFile, SHORT MaxHeight, SHORT MaxWidth,
    SHORT BaseLine, SHORT SpaceWidth, SHORT CharNum)
{
    _FileHandle *Handle;
    BYTE *pFontTable;
    BYTE FontHead[32] =
    {
        'B',  0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    };
    SHORT TableSize = (CharNum + 1) * 6;
    SHORT TabIndex = 0;
    LONG DataOffset = 0;
    INT state;
    INT len, i;

    if ((pFontTable = malloc(TableSize)) == _NULL)
        return FALSE;

#if defined(LCD_MODEL)
    SetDisplayStatus(DIS_DOWNLOADING);
#endif

#if defined(MONO_LED)
    StartPeriodFunc(FlashLED2);
#elif defined(POLY_LED)
    StartPeriodFunc(FlashGreenLED);
#endif

    Remove(ToFileDevice(pFile->Device), pFile->Name);
    Handle = Fopen(ToFileDevice(pFile->Device), pFile->Name, "w");
    state = _NULL;

    // Double of Font Height
    MaxHeight *= 2;

    // 5-6 : Font Height
    FontHead[5] = (BYTE)(MaxHeight & 0xff);
    FontHead[6] = (BYTE)(MaxHeight >> 8);
    // 7-8 : Font Width
    FontHead[7] = (BYTE)(MaxWidth & 0xff);
    FontHead[8] = (BYTE)(MaxWidth >> 8);
    // 15-16 : Font Character Total
    FontHead[15] = (BYTE)((CharNum + 1) & 0xff);
    FontHead[16] = (BYTE)((CharNum + 1) >> 8);
    // 23-24 : Base Line of ZPL
    FontHead[23] = (BYTE)((BaseLine) & 0xff);
    FontHead[24] = (BYTE)((BaseLine) >> 8);

    // Write Font File Head
    for (len = 0; len < sizeof(FontHead); len++)
    {
        if (state != END_OF_FILE)
            state = Fputc((INT)*(FontHead + len), Handle);
    }
    DataOffset += len;

    // Skip Font Table
    for (len = 0; len < TableSize; len++)
    {
        if (state != END_OF_FILE)
            state = Fputc(0xff, Handle);
    }
    DataOffset += len;

    // Create Space Character
    TabIndex += SaveFontTable(pFontTable + TabIndex, 0x20, DataOffset);

    // Write Space Width
    state = Fputc((INT)(SpaceWidth & 0xff), Handle);
    state = Fputc((INT)(SpaceWidth >> 8), Handle);
    DataOffset += 2;

    // Write Space Data
    for (len = 0; len < (SpaceWidth + 7) / 8 * MaxHeight; len++)
    {
        if (state != END_OF_FILE)
            state = Fputc(0x00, Handle);
    }
    DataOffset += len;

    for (i = 0; i < CharNum; i++)
    {
        WORD Code;
        SHORT Height, Width, OffsetX, OffsetY, RealWidth;
        SHORT RowByte, RealWidthByte, RealHeight;
        BYTE *pLine, *pWrite;

        state = END_OF_FILE;
        if (!CharCode(&Code))
            break;
        if (!CharNumber(&Height))
            break;
        if (!CharNumber(&Width))
            break;
        if (!CharNumber(&OffsetX))
            break;
        if (!CharNumber(&OffsetY))
            break;
        if (!CharNumber(&RealWidth))
            break;

        RowByte = (Width + 7) / 8;
        RealWidthByte = (RealWidth + 7) / 8;

        TabIndex += SaveFontTable(pFontTable + TabIndex, Code, DataOffset);

        // Write Font Width
        state = Fputc((INT)(RealWidth & 0xff), Handle);
        state = Fputc((INT)(RealWidth >> 8), Handle);
        DataOffset += 2;

        // Write Font Data
        for (len = 0; len < (MaxHeight / 2 - OffsetY) * RealWidthByte; len++)
        {
            if (state != END_OF_FILE)
                state = Fputc(0x00, Handle);
        }
        DataOffset += len;

        RealHeight = len / RealWidthByte + Height;

        if ((pWrite = malloc(RealWidthByte)) == _NULL)
            break;

        if (pLine = malloc(RowByte))
        {
            _ObjDecode Decode;

            memset(pLine, 0, RowByte);

            if (ObjectDecodeInit(&Decode))
            {
                while (Height)
                {
                    if (ObjectDecoding(&Decode, pLine, RowByte) != RowByte)
                        break;
                    ConvLineData(pWrite, RealWidthByte, pLine, RowByte, OffsetX);
                    for (len = 0; len < RealWidthByte; len++)
                    {
                        if (state != END_OF_FILE)
                            state = Fputc((INT)*(pWrite + len), Handle);
                    }
                    DataOffset += len;
                    Height -= 1;
                }
                if (!ObjectDecodeExit(&Decode))
                    state = END_OF_FILE;
            }
            if (Height)
                state = END_OF_FILE;

            free(pLine);
        }
        free(pWrite);

        if (Height)
            break;

        for (len = 0; len < (MaxHeight - RealHeight) * RealWidthByte; len++)
        {
            if (state != END_OF_FILE)
                state = Fputc(0x00, Handle);
        }
        DataOffset += len;
    }

    // Write Font Table
    if (state != END_OF_FILE)
    {
        Fseek(Handle, sizeof(FontHead), SEEK_SET);
        for (i = 0; i < TableSize; i++)
            state = Fputc((INT)*(pFontTable + i), Handle);
    }

    Fclose(Handle);

    if (state == END_OF_FILE)
        ObjectFail(pFile, TRUE);

#if defined(MONO_LED)
    CancelPeriodFunc(FlashLED2);
    ShowLED(HID_LED_IDLE, HID_LED_ON, HID_LED_IDLE);
#elif defined(POLY_LED)
    CancelPeriodFunc(FlashGreenLED);
    ShowLED(HID_LED_GREEN);
#endif

#if defined(LCD_MODEL)
    ClrDisplayStatus(DIS_DOWNLOADING);
#endif

    free(pFontTable);
    return ((state == END_OF_FILE) ? FALSE : TRUE);
}

BOOL DownloadFormat(_ObjFile *pFile)
{
    INT state;
    _FileHandle *Handle;
    CHAR buf[3];
    SHORT s, len;

#if defined(LCD_MODEL)
    SetDisplayStatus(DIS_DOWNLOADING);
#endif

#if defined(MONO_LED)
    StartPeriodFunc(FlashLED2);
#elif defined(POLY_LED)
    StartPeriodFunc(FlashGreenLED);
#endif

    Remove(ToFileDevice(pFile->Device), pFile->Name);
    Handle = Fopen(ToFileDevice(pFile->Device), pFile->Name, "w");
    state = _NULL;

    while (1)
    {
        if (CompareEndFormat(ZebraNextByte(NEXT_ANY), buf, &len))
            break;

        for (s = 0; s < len; s++)
        {
            if (state != END_OF_FILE)
                state = Fputc((INT)buf[s], Handle);
        }
    }
    Fclose(Handle);

    if (state == END_OF_FILE)
        ObjectFail(pFile, TRUE);

#if defined(MONO_LED)
    CancelPeriodFunc(FlashLED2);
    ShowLED(HID_LED_IDLE, HID_LED_ON, HID_LED_IDLE);
#elif defined(POLY_LED)
    CancelPeriodFunc(FlashGreenLED);
    ShowLED(HID_LED_GREEN);
#endif

#if defined(LCD_MODEL)
    ClrDisplayStatus(DIS_DOWNLOADING);
#endif

    return ((state == END_OF_FILE) ? FALSE : TRUE);
}

BOOL DownloadGraphic(_ObjFile *pFile, LONG TotalByte, SHORT RowByte)
{
    _FileHandle *Handle;
    _ObjDecode Decode;
    SHORT Height, Width;
    BYTE Buffer[TPH_WIDTH_BYTE];
    INT state;
    INT len;

    if (!ObjectDecodeInit(&Decode))
        return FALSE;

#if defined(LCD_MODEL)
    SetDisplayStatus(DIS_DOWNLOADING);
#endif

#if defined(MONO_LED)
    StartPeriodFunc(FlashLED2);
#elif defined(POLY_LED)
    StartPeriodFunc(FlashGreenLED);
#endif

    Remove(ToFileDevice(pFile->Device), pFile->Name);
    Handle = Fopen(ToFileDevice(pFile->Device), pFile->Name, "w");

    Height = TotalByte / RowByte;
    Width = RowByte * 8;

    state = Fputc((INT)(Height & 0xff), Handle);    // Low byte
    state = Fputc((INT)(Height >> 8), Handle);        // High byte
    state = Fputc((INT)(Width & 0xff), Handle);        // Low byte
    state = Fputc((INT)(Width >> 8), Handle);        // High byte

    memset(Buffer, 0, sizeof(Buffer));

    for (len = 0; len < Height; len++)
    {
        if (ObjectDecoding(&Decode, Buffer, RowByte) != RowByte)
            break;
        if (state != END_OF_FILE)
        {
            if (Fwrite(Buffer, sizeof(BYTE), RowByte, Handle) != RowByte)
                state = END_OF_FILE;
        }
    }
    if (!ObjectDecodeExit(&Decode))
        state = END_OF_FILE;

    Fclose(Handle);

    if (state == END_OF_FILE)
        ObjectFail(pFile, len == Height);

#if defined(MONO_LED)
    CancelPeriodFunc(FlashLED2);
    ShowLED(HID_LED_IDLE, HID_LED_ON, HID_LED_IDLE);
#elif defined(POLY_LED)
    CancelPeriodFunc(FlashGreenLED);
    ShowLED(HID_LED_GREEN);
#endif

#if defined(LCD_MODEL)
    ClrDisplayStatus(DIS_DOWNLOADING);
#endif

    return ((state == END_OF_FILE) ? FALSE : TRUE);
}

BOOL DownloadObjects(_ObjFile *pFile, ULONG FileSize, CHAR Format)
{
    _FileHandle *Handle;
    _ObjDecode Decode;
    CHAR data;
    INT state;
    ULONG len;

    if (Format == OBJECT_ASCII && !ObjectDecodeInit(&Decode))
        return FALSE;

#if defined(LCD_MODEL)
    SetDisplayStatus(DIS_DOWNLOADING);
#endif

#if defined(MONO_LED)
    StartPeriodFunc(FlashLED2);
#elif defined(POLY_LED)
    StartPeriodFunc(FlashGreenLED);
#endif

    Remove(ToFileDevice(pFile->Device), pFile->Name);
    Handle = Fopen(ToFileDevice(pFile->Device), pFile->Name, "w");
    state = _NULL;

    // ASCII hexadecimal or ZB64
    if (Format == OBJECT_ASCII)
    {
        data = 0;
        for (len = 0; len < FileSize; len++)
        {
            if (ObjectDecoding(&Decode, (BYTE *) & data, sizeof(data)) != sizeof(data))
                break;
            if (state != END_OF_FILE)
                state = Fputc((INT)data, Handle);
        }
        if (!ObjectDecodeExit(&Decode))
            state = END_OF_FILE;
    }

    // binary
    else if (Format == OBJECT_BINARY)
    {
        for (len = 0; len < FileSize; len++)
        {
            data = ZebraNextByte(NEXT_ANY);
            if (state != END_OF_FILE)
                state = Fputc((INT)data, Handle);
        }
    }

    Fclose(Handle);

    if (state == END_OF_FILE)
        ObjectFail(pFile, len == FileSize);

#if defined(MONO_LED)
    CancelPeriodFunc(FlashLED2);
    ShowLED(HID_LED_IDLE, HID_LED_ON, HID_LED_IDLE);
#elif defined(POLY_LED)
    CancelPeriodFunc(FlashGreenLED);
    ShowLED(HID_LED_GREEN);
#endif

#if defined(LCD_MODEL)
    ClrDisplayStatus(DIS_DOWNLOADING);
#endif

    return ((state == END_OF_FILE) ? FALSE : TRUE);
}

BOOL ImageSave(_ObjFile *pFile, _ImgBuf *pImgBuf, SHORT Width)
{
    INT state;
    _FileHandle *Handle;
    SHORT OffsetX  = XAxis(0);
    SHORT OffsetY  = YAxis(0);
    SHORT ShiftBit = OffsetX % 8;
    SHORT RowByte  = (Width + 7) / 8;
    BYTE *pLine;
    BYTE data;
    INT col, row;

#if defined(LCD_MODEL)
    SetDisplayStatus(DIS_DOWNLOADING);
#endif

#if defined(MONO_LED)
    StartPeriodFunc(FlashLED2);
#elif defined(POLY_LED)
    StartPeriodFunc(FlashGreenLED);
#endif

    Remove(ToFileDevice(pFile->Device), pFile->Name);
    Handle = Fopen(ToFileDevice(pFile->Device), pFile->Name, "w");

    state = Fputc((INT)((pImgBuf->iHeight - OffsetY) & 0xff), Handle);    // Height - Low byte
    state = Fputc((INT)((pImgBuf->iHeight - OffsetY) >> 8), Handle);    // Height - High byte
    state = Fputc((INT)((RowByte * 8) & 0xff), Handle);                    // Width - Low byte
    state = Fputc((INT)((RowByte * 8) >> 8), Handle);                    // Width - High byte

    for (col = OffsetY; col < pImgBuf->iHeight; col++)
    {
        pLine = pImgBuf->pBuffer + pImgBuf->iByteWidth * col + OffsetX / 8;
        for (row = 0; row < RowByte; row++)
        {
            data = (*pLine << ShiftBit) | (*(pLine + 1) >> (8 - ShiftBit));
            if (state != END_OF_FILE)
                state = Fputc((INT)data, Handle);

            pLine += 1;
        }
    }
    Fclose(Handle);

    if (state == END_OF_FILE)
        ObjectFail(pFile, TRUE);

#if defined(MONO_LED)
    CancelPeriodFunc(FlashLED2);
    ShowLED(HID_LED_IDLE, HID_LED_ON, HID_LED_IDLE);
#elif defined(POLY_LED)
    CancelPeriodFunc(FlashGreenLED);
    ShowLED(HID_LED_GREEN);
#endif

#if defined(LCD_MODEL)
    ClrDisplayStatus(DIS_DOWNLOADING);
#endif

    return ((state == END_OF_FILE) ? FALSE : TRUE);
}

STATIC INT AsciiHexDecoding(_ObjDecode *dec, BYTE *buff, INT size)
{
    size <<= 1;

    while (size)
    {
        while (dec->len)
        {
            dec->len -= 1;
            if (dec->step & 0x1)
            {
                dec->nibble = (ToHex(dec->nibble) << 4) | ToHex(dec->data);
                *(buff + (dec->step >> 1)) = dec->nibble;
            }
            else
                dec->nibble = dec->data;

            if (++dec->step == size)
            {
                dec->step = 0;
                return (size >> 1);
            }
        }

        // Repetition of the previous line.
        if (dec->preline)
        {
            dec->preline = FALSE;
            dec->step = 0;
            return (size >> 1);
        }

        dec->data = ZebraNextByte(NEXT_ANY);

        // Avoiding the caret (^) and tilde (~) characters.
        if (CheckChar(dec->data, dec->prefix))
        {
            BackByte(dec->data);
            break;
        }

        else if (isxdigit(dec->data))
        {
            if (dec->repeat == 0)
                dec->repeat = 1;

            dec->len = dec->repeat;
            dec->repeat = 0;
        }

        // The following represent the repeat counts 1,2,3,4,5,....,19
        // on a subsequent hexadecimal value.
        else if (dec->data >= 'G' && dec->data <= 'Y')
            dec->repeat += (INT)(dec->data - 'F');

        // The numbers above represent the repeat counts 20, 40, 60, 80,....400
        // on a subsequent hexadecimal value.
        else if (dec->data >= 'g' && dec->data <= 'z')
            dec->repeat += (INT)(dec->data - 'f') * 20;

        // a comma (,) fills the line, to the right, with zeros (0) until the
        // specified line byte is filled.
        else if (dec->data == ',')
        {
            dec->data = '0';
            dec->len = size - dec->step;
            dec->repeat = 0;
        }

        // an exclamation mark (!) fills the line, to the right, with ones (1)
        // until the specified line byte is filled.
        else if (dec->data == '!')
        {
            dec->data = 'F';
            dec->len = size - dec->step;
            dec->repeat = 0;
        }

        // a colon (:) denotes repetition of the previous line.
        else if (dec->data == ':')
        {
            dec->preline = TRUE;
            dec->data = '0';
            if (dec->step)
                dec->len = size - dec->step;
            dec->repeat = 0;
        }
    }
    return 0;
}

BOOL ObjectDecodeInit(_ObjDecode *dec)
{
    CHAR buf[5];
    INT len = 0;

    // This has the added benefit of avoiding the caret (^) and tilde (~)
    // characters.
    PrefixRule(dec->prefix);

    // This is done by prefacing the new encodings with a header that
    // uniquely identifies them.
    while (len < 5)
    {
        buf[len++] = ZebraNextByte(NEXT_ANY);
        if (memcmp(buf, ":B64:", len) != 0 &&
            memcmp(buf, ":Z64:", len) != 0)
            break;
    }

    // Base64-only(B64)
    if (memcmp(buf, ":B64:", len) == 0)
        dec->type = DECODE_B64;    

    // LZ77/Base64(Z64)
    else if (memcmp(buf, ":Z64:", len) == 0)
        dec->type = DECODE_Z64;

    // ASCII hexadecimal
    else
    {
        while (len)
            BackByte(buf[--len]);
        dec->type = DECODE_HEX;
    }

    dec->preline = FALSE;
    dec->repeat  = 0;
    dec->step    = 0;
    dec->len     = 0;

    // LZ77/Base64(Z64)
    if (dec->type == DECODE_Z64)
    {
#ifdef ZLIB_COMPRESSION
        dec->strm.zalloc = (alloc_func)0;
        dec->strm.zfree  = (free_func)0;
        dec->strm.opaque = (voidpf)0;

        dec->strm.avail_in  = 0;
        dec->strm.avail_out = 0;

        if (inflateInit(&dec->strm) != Z_OK)
            return FALSE;
#else
        return FALSE;
#endif
    }

    return TRUE;
}

BOOL ObjectDecodeExit(_ObjDecode *dec)
{
    // LZ77/Base64(Z64)
    if (dec->type == DECODE_Z64)
    {
#ifdef ZLIB_COMPRESSION
        if (inflateEnd(&dec->strm) != Z_OK)
            return FALSE;
#else
        return FALSE;
#endif
    }
    return TRUE;
}

INT ObjectDecoding(_ObjDecode *dec, BYTE *buff, INT size)
{
    // Base64-only(B64)
    if (dec->type == DECODE_B64)
    {
        for (dec->len = 0; dec->len < size && DecodeBase64(dec); dec->len++)
            *(buff + dec->len) = dec->data;
        return dec->len;
    }

    // LZ77/Base64(Z64)
    if (dec->type == DECODE_Z64)
    {
#ifdef ZLIB_COMPRESSION
        dec->strm.next_out  = buff;
        dec->strm.avail_out = size;
        while (dec->strm.avail_out != 0)
        {
            if (dec->strm.avail_in == 0 && !DecodeBase64(dec))
                break;
            dec->strm.next_in  = (BYTE *) & dec->data;
            dec->strm.avail_in = sizeof(BYTE);
            if (inflate(&dec->strm, Z_NO_FLUSH) != Z_OK)
                break;
        }
        return (size - dec->strm.avail_out);
#else
        return 0;
#endif
    }

    // ASCII hexadecimal
    return AsciiHexDecoding(dec, buff, size);
}

#endif

Zpl2Object.h    、、、、、、、、、、、、、、、、、、

#ifndef ZPL2OBJECT_H

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

#define ZPL2OBJECT_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         *
 *                                                                            *
 ******************************************************************************/

/* None */

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

#include "Zpl2Type.h"

#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 OBJECT_ASCII            'A'
#define OBJECT_BINARY            'B'

#define DECODE_B64                'B'
#define DECODE_Z64                'Z'
#define DECODE_HEX                'H'

#define IMAGE_LOAD                'L'
#define IMAGE_MOVE                'M'
#define IMAGE_RECALL            'G'

#define SAVE_NULL                0
#define SAVE_PRINT                'Y'
#define SAVE_IMAGE                'N'

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

/******************************************************************************
 *                                                                            *
 *    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 ZPL2OBJECT_C
#define EXTERN 
#else
#define EXTERN extern
#endif

/******************************************************************************
 *                                                                            *
 *       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                    *
 *                                                                            *
 ******************************************************************************/

_ObjFile *FontIdentifier(CHAR);
VOID ObjectDelete(CHAR, CHAR *);
VOID TransferObject(_ObjFile *, _ObjFile *);
BOOL CompareEndFormat(CHAR, CHAR *, SHORT *);
BOOL DownloadBitmapFont(_ObjFile *, SHORT, SHORT, SHORT, SHORT, SHORT);
BOOL DownloadFormat(_ObjFile *);
BOOL DownloadGraphic(_ObjFile *, LONG, SHORT);
BOOL DownloadObjects(_ObjFile *, ULONG, CHAR);
BOOL ImageSave(_ObjFile *, _ImgBuf *, SHORT);
BOOL ObjectDecodeInit(_ObjDecode *);
BOOL ObjectDecodeExit(_ObjDecode *);
INT ObjectDecoding(_ObjDecode *, BYTE *, INT);

#undef EXTERN

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

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值