#include "embdata.h"

EmbData::EmbData()
{
    m_pEmbDs16Head = new DataDs16FileHead();
    m_tabelColorNum = 0;
    m_pColor = NULL;
    m_extractContours.clear();//花样轮廓数据              清除字节数组的
    memset(m_needleColorTable,0,TOTAL_NEEDLE_NUM*sizeof(s16));
    memset(m_sequinColorTable,-1,SEQUIN_NUM*sizeof(s16));
    memset(m_beadColorTable,-1,BEAD_NUM*sizeof(s16));

    clear();
}

EmbData::~EmbData()
{
    clear();
    if(m_pEmbDs16Head != NULL)
    {
        delete m_pEmbDs16Head;
    }
}

void EmbData::clear()
{
    m_maxX = 0;
    m_minX = 0;
    m_maxY = 0;
    m_minY = 0;

    m_spaceX = 0;
    m_spaceY = 0;

    m_beginX = 0;
    m_beginY = 0;

    m_penX = 0;
    m_penY = 0;

    m_enFlag = 0;
    m_offsetX = 0;
    m_offsetY = 0;

    m_dataAbsList.clear();
    m_embDs16Data.clear();
    m_embDatEndList.clear();
    m_arrayAbsList.clear();

    m_greyColorBeg = 0;
    m_greyColorEnd = 0;

    m_editedflag = 0;
    m_filePath.clear();
    m_factor = 0;
    m_extractContours.clear();

    m_convertSkipStepSize = 32000;//取u16范围中的一个较大值
    m_jumpStepSize = 100;
    m_dsDataStepUnit = 1;

    memset(m_pEmbDs16Head,0,sizeof(DataDs16FileHead));
    memset(&m_patternParaStruct,0,sizeof(PatternParaStruct));
}

void EmbData::initColor(int cnum, QRgb *pColor)
{
    m_tabelColorNum = cnum;
    m_pColor = pColor;
}

QByteArray & EmbData::getDsDat()
{
    //qDebug()<<"m_editedflag"<<m_editedflag;
    if(m_editedflag != 0)
    {
        createEmbDs16FromAbs();
    }

    return m_embDs16Data;
}

//检查起针和末针的x坐标是否一致，如果相差0.5mm以上绗绣机是不能绣作的，需要重新打版
bool EmbData::checkFirstEndNeedle()
{
    int size = m_embDs16Data.size();
    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(m_embDs16Data.data());
    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("dat dataBegin err");
        return false;
    }
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return false;
    }

    int firstX = pDsHead->beginX;
    int endX = pDsHead->beginX;
    Ds16Item * ds16DataPtr = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
    for(int i = 0; i < stepsize; i++)
    {
        if(ds16DataPtr->ctrl == DATA_EMB ||
                ds16DataPtr->ctrl == DATA_JUMP ||
                ds16DataPtr->ctrl == DATA_OFFSET)
        {
            endX += ds16DataPtr->dx;
        }
        ds16DataPtr++;
    }
    if(abs(endX-firstX) >= 50)//大于0.5mm
    {
        return false;
    }
    else if(abs(endX-firstX) > 0 && abs(endX-firstX) < 50)
    {
        ds16DataPtr--;
        s16 num = 0;//避免陷入死循环
        while(1)
        {
            if(ds16DataPtr->ctrl == DATA_EMB ||
                    ds16DataPtr->ctrl == DATA_JUMP ||
                    ds16DataPtr->ctrl == DATA_OFFSET)
            {
                break;
            }
            else
            {
                ds16DataPtr--;
            }
            num++;
            if(num > stepsize)
            {
                break;
            }
        }
        int dx = endX - firstX;
        ds16DataPtr->dx -= dx;

        m_pEmbDs16Head = (DataDs16FileHead *)m_embDs16Data.data();
        m_pEmbDs16Head->dataChecksum = calcCheckSum32((u8 *)(m_embDs16Data.data()+sizeof(DataDs16FileHead)) , m_pEmbDs16Head->dataSize);	// 数据累加校验和
        m_pEmbDs16Head->checkCrc = calcCrc16((u8 *)(m_pEmbDs16Head), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验，（6个字段分别为：文件名称，字节数，项个数，每项字节数，每块字节数，数据累加和的CRC校验值）

#if(1)
        //保存成ds16文件
        QString ds16FilePath = m_filePath + ".ds16";
        QFile file(ds16FilePath);

        if(file.exists())//存在ds16文件
        {
            QFile::remove(ds16FilePath);
        }

        if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        {
            qDebug() << "open file fail when wirte, path =" << m_filePath;
            return -1;
        }
        else
        {
            file.write(m_embDs16Data);
#ifdef Q_OS_LINUX
            system("sync");
#endif
            file.close();
        }
#endif
    }
    return true;
}

//设置数据区文件头的fileid，计算完以后的fileid再设置进来
void EmbData::setDsDatHeadFileID(u32 fileid)
{
    if(m_pEmbDs16Head != NULL)
    {
        m_pEmbDs16Head->fileid = fileid;
        if((u32)m_embDs16Data.size() > sizeof(DataDs16FileHead))
        {
            memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head, sizeof(DataDs16FileHead));
        }
    }
}

//得到绝对坐标的maxXY和minXY
void EmbData::getAbsDatRangeXY()
{
    m_minX = S32_MAX;
    m_maxX = S32_MIN;
    m_minY = S32_MAX;
    m_maxY = S32_MIN;

    int ptnum = m_dataAbsList.size();

    double ax, ay;
    int minx, miny, maxx, maxy;

    for (int i = 0; i < ptnum; i++)
    {
        const QByteArray & ary = m_dataAbsList.at(i);
        int size = ary.size();
        if (size <= (int)sizeof(DataDs16FileHead))
        {
            qDebug("ary%d data less then head size", i);
            continue;   // 下一个
        }
        DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());

        int datasize = size - sizeof(DataDs16FileHead);
        if (datasize <= 0)
        {
            qDebug("absdat dataBegin err");
            return;
        }
        int stepsize = datasize/sizeof(DsAbsItem);
        if (stepsize <= 0)
        {
            qDebug("absdat data size err");
            return;
        }
        DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
        DsAbsItem * absDataPtr = pData;
        //-----

        int begx = pDsHead->beginX;
        int begy = pDsHead->beginY;

        minx = S32_MAX;
        maxx = S32_MIN;
        miny = S32_MAX;
        maxy = S32_MIN;

        // 数据区
        for (int j = 0; j < stepsize; j++)
        {
            ax = absDataPtr->ax + begx;
            ay = absDataPtr->ay + begy;

            if (minx > ax) { minx = ax;}
            if (maxx < ax) { maxx = ax;}
            if (miny > ay) { miny = ay;}
            if (maxy < ay) { maxy = ay;}

            absDataPtr++;
        }

        if (m_minX > minx) { m_minX = minx; }
        if (m_minX > maxx) { m_minX = maxx; }
        if (m_maxX < minx) { m_maxX = minx; }
        if (m_maxX < maxx) { m_maxX = maxx; }
        if (m_minY > miny) { m_minY = miny; }
        if (m_minY > maxy) { m_minY = maxy; }
        if (m_maxY < miny) { m_maxY = miny; }
        if (m_maxY < maxy) { m_maxY = maxy; }
    }
}

// 添加锁针针步
int EmbData::addLockStitchs(int locktimes, int locksteps, int lockstepsize, int jumpStichs,int isColorlock)
{
    //    if (locktimes <= 0 || locksteps <= 0 || lockstepsize <= 0)
    //    {
    //        return -1;
    //    }

    if (locksteps <= 0 || lockstepsize <= 0)
    {
        return -1;
    }
    locktimes = 1;

    int size = m_embAbsData.size();
    if (size <= 0)
    {
        return -1;
    }

    QByteArray tgtdsdat;    // 添加后的绝对坐标数据
    tgtdsdat.clear();

    // 文件头
    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("dat size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;
    DsAbsItem * embDataPtr = pData;

    tgtdsdat.append((char*)pHead, sizeof(DataDs16FileHead));
    //pHead = (DataDs16FileHead *)(tgtdsdat.data());

    //第一针为刺绣针步的针数
    int firstEmb = 0;
    for (int j = 0; j < stepsize; j++)
    {
        if(embDataPtr->ctrl == DATA_EMB)
        {
            firstEmb = j;
            break;
        }
        embDataPtr++;
    }

    int runflag = 0;
    int jumpflag = 0;//连续跳针的次数
    int embSize = 0;
    for (int j = 0; j < stepsize; j++)
    {
        if (absDataPtr->ctrl == DATA_JUMP)
        {
            jumpflag++;
        }

        if (absDataPtr->ctrl == DATA_CHGND)
        {
            runflag = DATA_CHGND;
        }
        else if (absDataPtr->ctrl == DATA_EMB)//包括剪线后和换色后加锁针
        {
            if ((runflag == DATA_CHGND && isColorlock == 1) ||
                    (jumpflag >= jumpStichs && jumpStichs != 0) ||
                    firstEmb == j ||
                    runflag == DATA_CUTTRD)
            {
                // 添加锁针
                int findnext = 0;
                if (j > 0)
                {
                    DsAbsItem * prePtr = absDataPtr-1;     // 上一个点
                    if (prePtr->ctrl != DATA_EMB)
                    {
                        double dx = absDataPtr->ax - prePtr->ax;
                        double dy = absDataPtr->ay - prePtr->ay;
                        double len = sqrt(dx*dx + dy*dy);
                        if (len <= 0)
                        {
                            findnext = 1;
                        }
                        else
                        {
                            //判断需要锁针几针
                            int stitchNum = 0;
                            int totalOft = 0;
                            double totalLen = 0;
                            while(1)
                            {
                                DsAbsItem * prePtr = absDataPtr+totalOft-1;     // 上一个点
                                DsAbsItem * curPtr = absDataPtr+totalOft;     // 当前点

                                double dx = curPtr->ax - prePtr->ax;
                                double dy = curPtr->ay - prePtr->ay;
                                totalLen += sqrt(dx*dx + dy*dy);
                                totalOft++;
                                stitchNum++;

                                if(totalLen >= locksteps * lockstepsize)
                                {
                                    break;
                                }

                                if(curPtr == ((DsAbsItem *)(m_embAbsData.data() + m_embAbsData.length() - sizeof(DsAbsItem))))
                                {
                                    break;
                                }
                            }

                            DsAbsItem nitem;
                            memset(&nitem,0,sizeof(DsAbsItem));
                            u8 ctrl = absDataPtr->ctrl;
                            u8 attr = 0;    // absDataPtr->attr;
                            double arbase = absDataPtr->ar;
                            int totalStepNum = 0;
                            int lastStepNum = 0;

                            for (int k = 0; k < locktimes; k++)
                            {
                                for (int s = 0; s < stitchNum; s++)
                                {
                                    DsAbsItem * prePtr = absDataPtr+s-1;     // 上一个点
                                    DsAbsItem * curPtr = absDataPtr+s; // 当前点

                                    double dx = curPtr->ax - prePtr->ax;
                                    double dy = curPtr->ay - prePtr->ay;
                                    double len = sqrt(dx*dx + dy*dy);

                                    double stepSize = 0;
                                    int stepNum = len / lockstepsize;

                                    if(stepNum == 1)
                                    {
                                        stepSize = len;
                                    }
                                    else
                                    {
                                        if((int)len % lockstepsize != 0)
                                        {
                                            stepNum += 1;
                                        }
                                        stepSize = len / stepNum;
                                    }

                                    if(s == stitchNum-1)//最后一个针步
                                    {
                                        stepNum = locksteps - totalStepNum;
                                        lastStepNum = stepNum;
                                        stepSize = lockstepsize;
                                    }

                                    double adx = (stepSize) * dx / len;
                                    double ady = (stepSize) * dy / len;

                                    double axbase = prePtr->ax;
                                    double aybase = prePtr->ay;

                                    for(int step = 1; step <= stepNum; step++)
                                    {
                                        nitem.ctrl = ctrl;
                                        nitem.attr = attr;
                                        nitem.ax = axbase + adx*step;
                                        nitem.ay = aybase + ady*step;
                                        nitem.ar = arbase;
                                        tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
                                    }
                                    totalStepNum += stepNum;
                                }

                                for (int s = stitchNum-1; s >= 0; s--)
                                {
                                    DsAbsItem * prePtr = absDataPtr+s-1;     // 上一个点
                                    DsAbsItem * curPtr = absDataPtr+s; // 当前点

                                    double dx = curPtr->ax - prePtr->ax;
                                    double dy = curPtr->ay - prePtr->ay;
                                    double len = sqrt(dx*dx + dy*dy);

                                    double stepSize = 0;
                                    int stepNum = len / lockstepsize;

                                    if(stepNum == 1)
                                    {
                                        stepSize = len;
                                    }
                                    else
                                    {
                                        if((int)len % lockstepsize != 0)
                                        {
                                            stepNum += 1;
                                        }
                                        stepSize = len / stepNum;
                                    }

                                    if(s == stitchNum-1)//最后一个针步
                                    {
                                        stepNum = lastStepNum;
                                        stepSize = lockstepsize;
                                    }

                                    double adx = (stepSize) * dx / len;
                                    double ady = (stepSize) * dy / len;

                                    double axbase = prePtr->ax;
                                    double aybase = prePtr->ay;

                                    for(int step = stepNum-1; step >= 0; step--)
                                    {
                                        nitem.ctrl = ctrl;
                                        nitem.attr = attr;
                                        nitem.ax = axbase + adx*step;
                                        nitem.ay = aybase + ady*step;
                                        nitem.ar = arbase;
                                        tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    findnext = 1;
                }

                if (findnext != 0)
                {
                    int nst = 1;
                    do
                    {
                        if (j+nst < stepsize)
                        {
                            DsAbsItem * nextPtr = absDataPtr+nst;     // 下一个点
                            if (nextPtr->ctrl == DATA_EMB)
                            {
                                double dx = nextPtr->ax - absDataPtr->ax;
                                double dy = nextPtr->ay - absDataPtr->ay;
                                double len = sqrt(dx*dx + dy*dy);
                                if (len <= 0)
                                {
                                    nst++;
                                    continue;
                                }

                                //判断需要锁针几针
                                int stitchNum = 0;
                                int totalOft = 0;
                                double totalLen = 0;
                                while(1)
                                {
                                    DsAbsItem * prePtr = nextPtr+totalOft-1;     // 上一个点
                                    DsAbsItem * curPtr = nextPtr+totalOft;     // 当前点

                                    double dx = curPtr->ax - prePtr->ax;
                                    double dy = curPtr->ay - prePtr->ay;
                                    totalLen += sqrt(dx*dx + dy*dy);
                                    totalOft++;
                                    stitchNum++;

                                    if(totalLen >= locksteps * lockstepsize)
                                    {
                                        break;
                                    }

                                    if(curPtr == ((DsAbsItem *)(m_embAbsData.data() + m_embAbsData.length() - sizeof(DsAbsItem))))
                                    {
                                        break;
                                    }
                                }

                                DsAbsItem nitem;
                                memset(&nitem,0,sizeof(DsAbsItem));
                                u8 ctrl = absDataPtr->ctrl;
                                u8 attr = 0;    // absDataPtr->attr;
                                double arbase = absDataPtr->ar;
                                int totalStepNum = 0;
                                int lastStepNum = 0;

                                for (int k = 0; k < locktimes; k++)
                                {
                                    for (int s = 0; s < stitchNum; s++)
                                    {
                                        DsAbsItem * prePtr = nextPtr+s-1;     // 上一个点
                                        DsAbsItem * curPtr = nextPtr+s; // 当前点

                                        double dx = curPtr->ax - prePtr->ax;
                                        double dy = curPtr->ay - prePtr->ay;
                                        double len = sqrt(dx*dx + dy*dy);

                                        double stepSize = 0;
                                        int stepNum = len / lockstepsize;

                                        if(stepNum == 1)
                                        {
                                            stepSize = len;
                                        }
                                        else
                                        {
                                            if((int)len % lockstepsize != 0)
                                            {
                                                stepNum += 1;
                                            }
                                            stepSize = len / stepNum;
                                        }

                                        if(s == stitchNum-1)//最后一个针步
                                        {
                                            stepNum = locksteps - totalStepNum;
                                            lastStepNum = stepNum;
                                            stepSize = lockstepsize;
                                        }

                                        double adx = (stepSize) * dx / len;
                                        double ady = (stepSize) * dy / len;

                                        double axbase = prePtr->ax;
                                        double aybase = prePtr->ay;

                                        for(int step = 1; step <= stepNum; step++)
                                        {
                                            nitem.ctrl = ctrl;
                                            nitem.attr = attr;
                                            nitem.ax = axbase + adx*step;
                                            nitem.ay = aybase + ady*step;
                                            nitem.ar = arbase;
                                            tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
                                        }
                                        totalStepNum += stepNum;
                                    }

                                    for (int s = stitchNum-1; s >= 0; s--)
                                    {
                                        DsAbsItem * prePtr = nextPtr+s-1;     // 上一个点
                                        DsAbsItem * curPtr = nextPtr+s; // 当前点

                                        double dx = curPtr->ax - prePtr->ax;
                                        double dy = curPtr->ay - prePtr->ay;
                                        double len = sqrt(dx*dx + dy*dy);

                                        double stepSize = 0;
                                        int stepNum = len / lockstepsize;

                                        if(stepNum == 1)
                                        {
                                            stepSize = len;
                                        }
                                        else
                                        {
                                            if((int)len % lockstepsize != 0)
                                            {
                                                stepNum += 1;
                                            }
                                            stepSize = len / stepNum;
                                        }

                                        if(s == stitchNum-1)//最后一个针步
                                        {
                                            stepNum = lastStepNum;
                                            stepSize = lockstepsize;
                                        }

                                        double adx = (stepSize) * dx / len;
                                        double ady = (stepSize) * dy / len;

                                        double axbase = prePtr->ax;
                                        double aybase = prePtr->ay;

                                        for(int step = stepNum-1; step >= 0; step--)
                                        {
                                            nitem.ctrl = ctrl;
                                            nitem.attr = attr;
                                            nitem.ax = axbase + adx*step;
                                            nitem.ay = aybase + ady*step;
                                            nitem.ar = arbase;
                                            tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
                                        }
                                    }
                                }
                                break;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }while(1);
                }
            }
            runflag = 1;
        }
        else if (absDataPtr->ctrl == DATA_CUTTRD)
        {
            runflag = DATA_CUTTRD;
        }
        else
        {
            if(absDataPtr->ctrl == DATA_EMB)
            {
                runflag = 0;//混合绣时需要改这里
            }
        }

        //结束前或剪线前或换色前或连续jumpStichs针跳针前加锁针
        if (absDataPtr->ctrl == DATA_END ||
                absDataPtr->ctrl == DATA_NULL ||
                j == stepsize-1 ||
                absDataPtr->ctrl == DATA_CUTTRD ||
                (absDataPtr->ctrl == DATA_CHGND && isColorlock == 1)||
                ((jumpflag >= jumpStichs && jumpStichs != 0) && absDataPtr->ctrl != DATA_JUMP))
        {
            int embFlag = 1;
            DsAbsItem * prePtrItem;
            u8 ctl;
            if(absDataPtr == pData)
            {
                embFlag = -1;//向前无绣花针步
            }
            else
            {
                //结束前或剪线前加锁针
                prePtrItem = absDataPtr-1;     // 上一个点
                ctl = prePtrItem->ctrl;
                while(ctl != DATA_EMB)
                {
                    if(prePtrItem == pData)//起始地址
                    {
                        embFlag = -1;//向前无绣花针步
                        break;
                    }

                    prePtrItem--;
                    ctl = prePtrItem->ctrl;
                    if(prePtrItem == pData)//起始地址
                    {
                        embFlag = -1;//向前无绣花针步
                        break;
                    }
                }
            }

            if(embFlag != -1)
            {
                DsAbsItem * prePtr1 = prePtrItem-1;
                ctl = prePtr1->ctrl;
#if(0)
                if(ctl != DATA_EMB)//非连续两针绣花不加锁针
                {
                    return -1;
                }
#endif

                double dx = prePtr1->ax - prePtrItem->ax;
                double dy = prePtr1->ay - prePtrItem->ay;
                double len = sqrt(dx*dx + dy*dy);
                int nst = 1;
                while (len <= 0)
                {
                    nst++;
                    DsAbsItem * prePtrNst = prePtrItem-nst;
                    dx = prePtrNst->ax - prePtrItem->ax;
                    dy = prePtrNst->ay - prePtrItem->ay;
                    len = sqrt(dx*dx + dy*dy);
                    if(prePtrNst == pData)
                    {
                        break;
                    }
                }

                //判断需要锁针几针
                int stitchNum = 0;
                int totalOft = 0;
                double totalLen = 0;
                while(1)
                {
                    DsAbsItem * prePtr = prePtrItem-totalOft-1;     // 上一个点
                    DsAbsItem * curPtr = prePtrItem-totalOft;     // 当前点

                    double dx = curPtr->ax - prePtr->ax;
                    double dy = curPtr->ay - prePtr->ay;
                    totalLen += sqrt(dx*dx + dy*dy);
                    totalOft++;
                    stitchNum++;

                    if(totalLen >= locksteps * lockstepsize)
                    {
                        break;
                    }

                    if(curPtr == ((DsAbsItem *)(m_embAbsData.data() + m_embAbsData.length() - sizeof(DsAbsItem))))
                    {
                        break;
                    }
                }

                DsAbsItem nitem;
                memset(&nitem,0,sizeof(DsAbsItem));
                u8 ctrl = prePtrItem->ctrl;
                u8 attr = 0;
                double arbase = prePtrItem->ar;
                int totalStepNum = 0;
                int lastStepNum = 0;

                for (int k = 0; k < locktimes; k++)
                {
                    for (int s = 0; s < stitchNum; s++)
                    {
                        DsAbsItem * prePtr = prePtrItem-s-1;     // 上一个点
                        DsAbsItem * curPtr = prePtrItem-s; // 当前点

                        double dx = prePtr->ax - curPtr->ax;
                        double dy = prePtr->ay - curPtr->ay;
                        double len = sqrt(dx*dx + dy*dy);

                        double stepSize = 0;
                        int stepNum = len / lockstepsize;

                        if(stepNum == 1)
                        {
                            stepSize = len;
                        }
                        else
                        {
                            if((int)len % lockstepsize != 0)
                            {
                                stepNum += 1;
                            }
                            stepSize = len / stepNum;
                        }

                        if(s == stitchNum-1)//最后一个针步
                        {
                            stepNum = locksteps - totalStepNum;
                            lastStepNum = stepNum;
                            stepSize = lockstepsize;
                        }

                        double adx = (stepSize) * dx / len;
                        double ady = (stepSize) * dy / len;

                        double axbase = curPtr->ax;
                        double aybase = curPtr->ay;

                        for(int step = 1; step <= stepNum; step++)
                        {
                            nitem.ctrl = ctrl;
                            nitem.attr = attr;
                            nitem.ax = axbase + adx*step;
                            nitem.ay = aybase + ady*step;
                            nitem.ar = arbase;
                            tgtdsdat.insert(embSize,(char*)(&nitem), sizeof(DsAbsItem));
                            embSize += sizeof(DsAbsItem);
                        }
                        totalStepNum += stepNum;
                    }

                    for (int s = stitchNum-1; s >= 0; s--)
                    {
                        DsAbsItem * prePtr = prePtrItem-s-1;     // 上一个点
                        DsAbsItem * curPtr = prePtrItem-s; // 当前点

                        double dx = prePtr->ax - curPtr->ax;
                        double dy = prePtr->ay - curPtr->ay;
                        double len = sqrt(dx*dx + dy*dy);

                        double stepSize = 0;
                        int stepNum = len / lockstepsize;

                        if(stepNum == 1)
                        {
                            stepSize = len;
                        }
                        else
                        {
                            if((int)len % lockstepsize != 0)
                            {
                                stepNum += 1;
                            }
                            stepSize = len / stepNum;
                        }

                        if(s == stitchNum-1)//最后一个针步
                        {
                            stepNum = lastStepNum;
                            stepSize = lockstepsize;
                        }

                        double adx = (stepSize) * dx / len;
                        double ady = (stepSize) * dy / len;

                        double axbase = curPtr->ax;
                        double aybase = curPtr->ay;

                        for(int step = stepNum-1; step >= 0; step--)
                        {
                            nitem.ctrl = ctrl;
                            nitem.attr = attr;
                            nitem.ax = axbase + adx*step;
                            nitem.ay = aybase + ady*step;
                            nitem.ar = arbase;
                            tgtdsdat.insert(embSize,(char*)(&nitem), sizeof(DsAbsItem));
                            embSize += sizeof(DsAbsItem);
                        }
                    }
                }

                //连续jumpStichs针跳针前加锁针 ,锁针后加剪线
                if((jumpflag >= jumpStichs && jumpStichs != 0) && absDataPtr->ctrl != DATA_JUMP)
                {
                    DsAbsItem item;
                    memset(&item,0,sizeof(DsAbsItem));
                    //tgtdsdat.data()是首地址 + tgtdsdat 总针数 - 一个结构体的大小
                    memcpy((char*)&item,tgtdsdat.data()+tgtdsdat.size()-jumpflag*sizeof(DsAbsItem),sizeof(DsAbsItem));
                    item.ctrl = DATA_CUTTRD;
                    tgtdsdat.insert(embSize,(char*)(&item), sizeof(DsAbsItem));
                }
            }
        }

        if (absDataPtr->ctrl != DATA_JUMP)
        {
            jumpflag = 0;
        }

        tgtdsdat.append((char*)absDataPtr, sizeof(DsAbsItem));

        if(absDataPtr->ctrl == DATA_EMB)//记录最后一针为刺绣的针步
        {
            embSize = tgtdsdat.size();
        }

        absDataPtr++;
    }

    m_embAbsData.clear();
    m_embAbsData = tgtdsdat;

    m_editedflag = 1;
    return 0;
}

#define MERGEANGLE      PI/180*60*10000 //60度
int EmbData::mergeMinStep(u16 minStep, int mergeStep)
{
    if(minStep <= 0)
    {
        return 0;
    }

    int size = m_embAbsData.size();
    if (size <= 0)
    {
        return -1;
    }

    QList<DsAbsItem> minStepPointList;
    minStepPointList.clear();

    u8 ctrlByte = 0;
    s32 dx, dy, dr;//相对
    u16 len;
    int actx, acty, actr;

    QByteArray tgtdsdat;    // 添加后的绝对坐标数据
    tgtdsdat.clear();

    // 文件头
    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("dat size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;
    actx = absDataPtr->ax;
    acty = absDataPtr->ay;
    actr = absDataPtr->ar;

    tgtdsdat.append((char*)pHead, sizeof(DataDs16FileHead));
    //pHead = (DataDs16FileHead *)(tgtdsdat.data());

    //合并小针步
    for (int j = 0; j < stepsize; j++)
    {
        ctrlByte = absDataPtr->ctrl;
        dx = absDataPtr->ax - actx;
        dy = absDataPtr->ay - acty;
        dr = absDataPtr->ar - actr;
        len = sqrt(dx*dx + dy*dy);

        while (dr < -PI10000)
        {
            dr += PI20000;
        }
        while (dr > PI10000)
        {
            dr -= PI20000;
        }

        if(ctrlByte == DATA_EMB)//等于绣花针步才合并
        {
            if (len == 0)
            {
                absDataPtr++;
                continue;       // 过滤空针
            }

            if(len <= minStep && (abs(dr) < MERGEANGLE))
            {
                minStepPointList.append(*absDataPtr);

                actx = absDataPtr->ax;
                acty = absDataPtr->ay;
                actr = absDataPtr->ar;
                absDataPtr++;
                continue;
            }
            else
            {
                QList<DsAbsItem> outList;
                outList.clear();

                DsAbsItem * prePtr = absDataPtr-1;
                DsAbsItem * pprePtr = absDataPtr-2;
                u32 clen = sqrt((prePtr->ax - pprePtr->ax)*(prePtr->ax - pprePtr->ax) + (prePtr->ay - pprePtr->ay)*(prePtr->ay - pprePtr->ay));

                //上一针步为小针步且当前针步非小针步
                //将小针步点按针步参数进行拟合
                if(clen <= minStep && len > minStep)
                {
                    minStepPointList.append(*absDataPtr);

                    getCurvePointFillLine(minStepPointList,mergeStep,outList);
                    for(int m = 0; m < outList.size(); m++)
                    {
                        tgtdsdat.append((char*)(&outList[m]), sizeof(DsAbsItem));
                    }

                    minStepPointList.clear();

                    actx = absDataPtr->ax;
                    acty = absDataPtr->ay;
                    actr = absDataPtr->ar;
                    absDataPtr++;
                    continue;
                }

                //当前针步dr大于等于过滤度数且上一针步为小针步
                if(abs(dr) >= MERGEANGLE && clen <= minStep)
                {
                    if(minStepPointList.size() <=1)
                    {
                        if(minStepPointList.size() ==1)
                        {
                            tgtdsdat.append((char*)(&minStepPointList[0]), sizeof(DsAbsItem));
                        }
                    }
                    else
                    {
                        getCurvePointFillLine(minStepPointList,mergeStep,outList);
                        for(int m = 0; m < outList.size(); m++)
                        {
                            tgtdsdat.append((char*)(&outList[m]), sizeof(DsAbsItem));
                        }
                    }
                }
                minStepPointList.clear();
            }
        }

        actx = absDataPtr->ax;
        acty = absDataPtr->ay;
        actr = absDataPtr->ar;
        tgtdsdat.append((char*)(absDataPtr), sizeof(DsAbsItem));

        absDataPtr++;
    }

    m_embAbsData.clear();
    m_embAbsData = tgtdsdat;

    m_editedflag = 1;
    return 0;
}

void EmbData::appendAEmbAbsFile(QString filePath, QByteArray array, int mirror)
{
    m_extractContours = array;
    m_filePath = filePath;
    convertAbsDat(array,mirror);//是否镜像、旋转、缩放的转换
    m_dataAbsList.append(array);
    m_editedflag = 1;
}

void EmbData::appendACombEmbFile(QString filePath)
{
    m_filePath = filePath;
    QList <QByteArray> dataList;
    dataList = getDataList(filePath);

    for(int i = 0 ; i < dataList.size() ; i++)
    {
        m_dataAbsList.append(dataList[i]);
    }
    m_editedflag = 1;
}

int EmbData::removeAEmbFile(int idx)
{
    if (idx < 0)
    {
        m_dataAbsList.clear();
    }
    else
    {
        if (idx < m_dataAbsList.size())
        {
            m_dataAbsList.removeAt(idx);
        }
    }

    m_editedflag = 1;
    return 0;
}

int EmbData::saveAsCombFile(QString fullpathname,QString name)
{
    if (fullpathname.isEmpty())
    {
        return -2;
    }

    int count = m_dataAbsList.count();

    if(count <= 0)
    {
        return -2;
    }

    QByteArray fileheadary;  //组合文件头的数据
    fileheadary.clear();
    fileheadary.append((char*)&count,sizeof(u32));  //总的文件数

    for(int i = 0 ; i < count ; i++)
    {
        //将每个文件的字节数写入文件头中
        int filesize = m_dataAbsList.at(i).size();

        if(filesize <= 0)
        {
            return -2;
        }

        fileheadary.append((char*)&filesize,sizeof(u32));
    }

    //计算文件头的大小，如果不足256要补全
    int headsize = fileheadary.size();
    int size = sizeof(CombHead);
    if(headsize < size)
    {
        int addsize = size - headsize;
        int addary = 0;  //补全为0

        //补全过程
        int step = addsize / sizeof(u32);

        for(int j = 0 ; j < step ; j++)
        {
            fileheadary.append((char*)&addary,sizeof(u32));
        }
    }

    //写入文件
    QFile writefile(fullpathname);
    if(writefile.open(QIODevice::WriteOnly) == false)
    {
        return -1;
        qDebug()<<"fullpathname write fail"<<fullpathname;
    }

    writefile.write(fileheadary);//写入文件头

    QByteArray fileary;  //组合文件的数据
    for(int j = 0; j < m_dataAbsList.size(); j++)
    {
        fileary.clear();

        //修改文件名
        DataDs16FileHead * pDsHead = (DataDs16FileHead *)(m_dataAbsList[j].data());
        memset(pDsHead->fileName,0,sizeof(pDsHead->fileName));
        QByteArray array = name.toLocal8Bit().data();
        int asize = array.length();
        memcpy(pDsHead->fileName, array, asize);   // 文件名称

        fileary.append(m_dataAbsList.at(j));
        writefile.write(fileary); //写入文件头体
    }
    writefile.close();

#ifdef Q_OS_LINUX
    system("sync");
#endif

    return 0;
}



int EmbData::getPattenNum()
{
    return m_dataAbsList.size();
}

void EmbData::setAbsDat(QByteArray & dat)
{
    m_embAbsData = dat;
}

QByteArray &  EmbData::getAbsDat(void)
{
    return m_embAbsData;
}

QByteArray EmbData::getColorTable()
{
    int colornum = 0;
    QByteArray colortab;
    colortab.clear();

    if (m_editedflag != 0)
    {
        createEmbDs16FromAbs();
    }

    if (m_embDs16Data.size() > (int)sizeof(DataDs16FileHead))
    {
        // 文件头
        DataDs16FileHead * pDsHead = (DataDs16FileHead *)(m_embDs16Data.data());
        colornum = pDsHead->colorNum;
        colortab.append((char*)(pDsHead->switchTable), colornum);
    }

    return colortab;
}

int EmbData::getAFileDs16Range(int idx, int &beg, int &end)
{
    if (m_editedflag != 0)
    {
        createEmbDs16FromAbs();
    }

    int num = m_embDatEndList.size();
    int allnum = m_dataAbsList.size();

    if(num != allnum)
    {
        m_editedflag = 1;

        createEmbDs16FromAbs();

        num = m_embDatEndList.size();
    }

    beg = 0;
    end = 0;

    if (idx < 0)
    {
        return -1;
    }

    if (idx == 0)
    {
        beg = 0;
    }
    else
    {
        beg = m_embDatEndList.at(idx-1);
    }

    end = m_embDatEndList.at(idx);

    return 0;
}

int EmbData::getPosInfoFromNeedleIdx(int stitchIdx, int &posx, int &posy, int & posr,int &colorIdx)
{
    if (m_editedflag != 0)
    {
        createEmbDs16FromAbs();
    }

    posx = 0;
    posy = 0;
    colorIdx = 0;

    // 文件头
    int size = m_embDs16Data.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("m_embDs16Data data less then head size");
        return -1;
    }

    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(m_embDs16Data.data());

    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return -1;
    }

    Ds16Item * ds16DataPtr;
    Ds16Item * pData = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = pData;

    posx = pDsHead->beginX;
    posy = pDsHead->beginY;
    posr = pDsHead->beginR;

    if (stitchIdx <= 0)
    {
        return 0;
    }

    if (stitchIdx > datasize)
    {
        stitchIdx = datasize;
    }

    int dx, dy, dr;
    u8 ctrl, attr;

    for (int i = 0; i < stitchIdx; i++)
    {
        ctrl = ds16DataPtr->ctrl;
        attr = ds16DataPtr->attr;
        dx = ds16DataPtr->dx;
        dy = ds16DataPtr->dy;
        dr = ds16DataPtr->dr;

        if (ctrl == DATA_CHGND)
        {
            colorIdx++;
        }

        if ((attr&0x80) != 0)
        {
            dx *= -1;
        }

        if ((attr&0x40) != 0)
        {
            dy *= -1;
        }

        posx += dx;
        posy += dy;
        posr += dr;

        ds16DataPtr++;
    }

    return 0;
}

int EmbData::getPosInfoFromColorIdx(int &stitchIdx, int &posx, int &posy, int & posr, int colorIdx)
{
    if (m_editedflag != 0)
    {
        createEmbDs16FromAbs();
    }

    posx = 0;
    posy = 0;
    stitchIdx = 0;
    int cidx = 0;

    // 文件头
    int size = m_embDs16Data.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("m_embDs16Data data less then head size");
        return -1;
    }

    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(m_embDs16Data.data());

    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return -1;
    }

    Ds16Item * ds16DataPtr;
    Ds16Item * pData = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = pData;

    posx = pDsHead->beginX;
    posy = pDsHead->beginY;
    posr = pDsHead->beginR;

    if (colorIdx <= 0)
    {
        return -1;
    }

    //当前颜色索引大于总的颜色数时，针数索引等于总针数
    if(colorIdx >= ((int)pDsHead->colorNum))
    {
        stitchIdx = stepsize;
        return 0;
    }

    int dx, dy, dr;
    u8 ctrl, attr;

    cidx = 0;
    for (int i = 0; i < stepsize; i++)
    {
        if (cidx == colorIdx)
        {
            stitchIdx = i;
            break;
        }

        ctrl = ds16DataPtr->ctrl;
        attr = ds16DataPtr->attr;
        dx = ds16DataPtr->dx;
        dy = ds16DataPtr->dy;
        dr = ds16DataPtr->dr;

        if (ctrl == DATA_CHGND)
        {
            cidx++;

            //最后一针为换色码时针数索引等于总针数减1
            if(i == (stepsize - 1))
            {
                stitchIdx = i;
            }
        }

        if ((attr&0x80) != 0)
        {
            dx *= -1;
        }

        if ((attr&0x40) != 0)
        {
            dy *= -1;
        }

        posx += dx;
        posy += dy;
        posr += dr;

        ds16DataPtr++;
    }

    return 0;
}

int EmbData::getNeedleIdxFromColorIdx(int & needleIdx, int colorIdx, u8 & stepCtrl)
{
    if (m_editedflag != 0)
    {
        createEmbDs16FromAbs();
    }

    needleIdx = 0;
    int cidx = 0;
    s16 flag = 0;

    // 文件头
    int size = m_embDs16Data.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("m_embDs16Data data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return -1;
    }

    Ds16Item * ds16DataPtr;
    Ds16Item * pData = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = pData;

    if (colorIdx <= 0)
    {
        return -1;
    }

    u8 ctrl;
    //stepCtrl = DATA_EMB;

    cidx = 1;
    for (int i = 0; i < stepsize; i++)
    {
        ctrl = ds16DataPtr->ctrl;

        if(i == 0)
        {
            stepCtrl = ctrl;
        }

        if (ctrl == DATA_CHGND)
        {
            cidx++;
        }

        if (cidx == colorIdx)
        {
            if(flag == 0)
            {
                needleIdx = i+1;
            }
            //针步属性等于缝纫，冲孔，绣花，毛巾环式，毛巾链式
            if(ctrl == DATA_SEWING ||
                    ctrl == DATA_PUNCH ||
                    ctrl == DATA_EMB ||
                    ctrl == DATA_LASER ||
                    ctrl == DATA_CHENILLE ||
                    ctrl == DATA_CHAIN ||
                    ctrl == DATA_COIL ||
                    ctrl == DATA_SAWTOOTH ||
                    ctrl == DATA_RIBBON
                    )
            {
                stepCtrl = ctrl;
                break;
            }
            flag = 1;
        }

        ds16DataPtr++;
    }

    return 0;
}

int EmbData::getNeedleIdxFromTowelHighIdx(int &needleIdx, int highIdx, u8 &stepCtrl)
{
    if (m_editedflag != 0)
    {
        createEmbDs16FromAbs();
    }

    needleIdx = 0;
    int hidx = 0;
    s16 flag = 0;

    // 文件头
    int size = m_embDs16Data.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("m_embDs16Data data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return -1;
    }

    Ds16Item * ds16DataPtr;
    Ds16Item * pData = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = pData;

    if (highIdx <= 0)
    {
        return -1;
    }

    u8 ctrl;
    //stepCtrl = DATA_EMB;

    hidx = 1;
    for (int i = 0; i < stepsize; i++)
    {
        ctrl = ds16DataPtr->ctrl;

        if(i == 0)
        {
            stepCtrl = ctrl;
        }

        if (ctrl == DATA_TOWELHIGH)
        {
            hidx++;
        }

        if (hidx == highIdx)
        {
            if(flag == 0)
            {
                needleIdx = i+1;
            }
            //针步属性等于缝纫，冲孔，绣花，毛巾环式，毛巾链式
            if(ctrl == DATA_SEWING ||
                    ctrl == DATA_PUNCH ||
                    ctrl == DATA_EMB ||
                    ctrl == DATA_LASER ||
                    ctrl == DATA_CHENILLE ||
                    ctrl == DATA_CHAIN ||
                    ctrl == DATA_COIL ||
                    ctrl == DATA_SAWTOOTH ||
                    ctrl == DATA_RIBBON
                    )
            {
                stepCtrl = ctrl;
                break;
            }
            flag = 1;
        }

        ds16DataPtr++;
    }

    return 0;
}

void EmbData::setDs16ColorOfTable(u8 *table)
{
    if(m_pEmbDs16Head != NULL)
    {
        s16 absNumber = m_dataAbsList.size();

        if(absNumber <= 0){return;}
        QByteArray ary = m_dataAbsList.at(0);
        DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
        s16 colorNum = pDsHead->colorNum;

        QByteArray ctable;
        ctable.resize(absNumber*colorNum);//可能超过512个色序
        memset(ctable.data(),0,ctable.size());

        for(s16 i = 0; i < absNumber; i++)
        {
            memcpy(ctable.data()+i*colorNum,table,colorNum);
        }

        memcpy(m_pEmbDs16Head->switchTable,ctable.data(),sizeof(m_pEmbDs16Head->switchTable));//将新的色序表重新写入文件头

        if((u32)m_embDs16Data.size() > sizeof(m_pEmbDs16Head))
        {
            memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head, sizeof(DataDs16FileHead));
        }
    }
}

void EmbData::setNeedleColorTable(int colorIdx, int colorvalue)
{
    if(colorIdx > TOTAL_NEEDLE_NUM - 1)
    {
        return;
    }
    m_needleColorTable[colorIdx] = colorvalue;
}

void EmbData::setBeadColorTable(int colorIdx, int colorvalue)
{
    if(colorIdx > BEAD_NUM - 1)
    {
        return;
    }
    m_beadColorTable[colorIdx] = colorvalue;
}

void EmbData::setSequinColorTable(int colorIdx, int colorvalue)
{
    if(colorIdx > SEQUIN_NUM - 1)
    {
        return;
    }
    m_sequinColorTable[colorIdx] = colorvalue;
}

//这个函数没有用到
PatternParaStruct EmbData::getPatternParaStruct(QString path)
{
    PatternParaStruct patternPara;
    memset(&patternPara,0,sizeof(PatternParaStruct));

    QString ds16FilePath = path + ".ds16";
    QFile file(ds16FilePath);
    if(file.exists())//存在ds16文件
    {
        if(file.open(QIODevice::ReadOnly))
        {
            QByteArray ary = file.readAll();

            if(ary.size() > 0)
            {
                DataFileHead ds16Head;
                memset(&ds16Head,0,sizeof(DataFileHead));
                memcpy(&ds16Head,ary.data(),sizeof(DataFileHead));

                patternPara.rotateStyle = ds16Head.rotateStyle;    //旋转式样
                patternPara.rotateAngle = ds16Head.rotateAngle;    //旋转角度
                patternPara.xZoom = ds16Head.xZoom;                //X向倍率
                patternPara.yZoom = ds16Head.yZoom;                //Y向倍率
                patternPara.repeatStyle = ds16Head.repeatStyle;    //反复方式
                patternPara.priority = ds16Head.priority;          //优先次序
                patternPara.xRepeatNum = ds16Head.xRepeatNum;      //X向反复次数
                patternPara.yRepeatNum = ds16Head.yRepeatNum;      //Y向反复次数
                patternPara.xRepeatSpace = ds16Head.xRepeatSpace;  //X向反复间距
                patternPara.yRepeatSpace = ds16Head.yRepeatSpace;  //Y向反复间距
                patternPara.xCompensate = ds16Head.xCompensate;    //X向补偿
                patternPara.yCompensate = ds16Head.yCompensate;    //Y向补偿
            }
        }
        file.close();
    }

    return patternPara;
}

//设置花样参数结构体
void EmbData::setPatternParaStruct(PatternParaStruct paraStruct)
{
    memcpy(&m_patternParaStruct,&paraStruct,sizeof(PatternParaStruct));
}

//设置起始点
void EmbData::setStartPosition(int x, int y, int st,u8 workHead)
{
    if(st == 0){}
    if(m_pEmbDs16Head == NULL){return;}
    if(m_embDs16Data.size() <= 0){return;}

    //旧的起始点坐标
    int oldBeginX = m_pEmbDs16Head->beginX;
    int oldBeginY = m_pEmbDs16Head->beginY;

    m_pEmbDs16Head->anchorX = x;
    m_pEmbDs16Head->anchorY = y;
    m_pEmbDs16Head->beginX = x;
    m_pEmbDs16Head->beginY = y;
    m_pEmbDs16Head->begHead = workHead;

    //新的起始点坐标与旧的起始点坐标的差值
    int cx =  x - oldBeginX;
    int cy =  y - oldBeginY;

    //重新计算最大最小XY
    double maxX = m_pEmbDs16Head->maxX + cx;
    double minX = m_pEmbDs16Head->minX + cx;
    double maxY = m_pEmbDs16Head->maxY + cy;
    double minY = m_pEmbDs16Head->minY + cy;

    //将最大最小值写入文件头
    m_pEmbDs16Head->maxX = maxX;
    m_pEmbDs16Head->minX = minX;
    m_pEmbDs16Head->maxY = maxY;
    m_pEmbDs16Head->minY = minY;

    //修复偶尔点击中间按钮花样消失的bug
    m_maxX = maxX;
    m_minX = minX;
    m_maxY = maxY;
    m_minY = minY;
    memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head,sizeof(DataDs16FileHead));

    m_beginX = m_pEmbDs16Head->beginX;
    m_beginY = m_pEmbDs16Head->beginY;
#if(0)
    QString suffix = ".ds16";
    QString dsFilePath = m_filePath + suffix;
    QFile file(dsFilePath);

    if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        qDebug() << "open file fail when wirte, path =" << m_filePath;
        return;
    }
    else
    {
        file.write(m_embDs16Data);
        file.close();
    }
#endif
}

//需要插入跳针的针步大小
void EmbData::setConvertSkipStepSize(u16 stepSize ,u16 jumpStepSize)
{
    if(stepSize <= 0){return;}
    if(jumpStepSize <= 0){return;}
    m_jumpStepSize = jumpStepSize;
    m_convertSkipStepSize = stepSize;
}

  //0.01mm或0.1mm（教学一体机为步进电机，针步精度为0.1mm，需要将数据除以10）
void EmbData::setDataStepUnit(u16 stepUnit)
{
    if(stepUnit <= 0){return;}
    m_dsDataStepUnit = stepUnit;
}
	
int EmbData::modifyStepAngle(u16 mode)
{
    if(mode <= 0)
    {
        return -1;
    }

    int ptnum = 0;
    int index = 0;
    int idxend = 0;

    ptnum = m_dataAbsList.size();//文件绝对位置列表的大小
    if (ptnum <= 0)
    {
        return 0;
    }

    index = 0;
    idxend = ptnum;

    for (int i = index; i < idxend; i++)
    {
        // 文件头
        const QByteArray & ary = m_dataAbsList.at(i);
        int size = ary.size();
        if (size <= (int)sizeof(DataDs16FileHead))
        {
            qDebug("ary%d data less then head size", i);
            continue;
        }

        int datasize = size - sizeof(DataDs16FileHead);
        int stepsize = datasize/sizeof(DsAbsItem);
        if (stepsize <= 0)
        {
            qDebug("dat data size err");
            continue;
        }

        DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
        DsAbsItem * absDataPtr = pData;

        int flag = 0;
        double preAr = 0;
        DsAbsItem * tempDataPtr;

        // 数据转换
        for (int j = 0; j < stepsize; j++)
        {
            if(absDataPtr->ctrl == DATA_JUMP && absDataPtr != pData)//非第一个针步且为跳针
            {
                tempDataPtr = absDataPtr;
                tempDataPtr--;//上一针
                if(tempDataPtr->ctrl != DATA_JUMP)//上一针步不为跳针
                {
                    tempDataPtr++;//当前针
                    preAr = tempDataPtr->ar;
                    flag = 1;
                }

                if(flag == 1)
                {
                    absDataPtr++;
                    continue;
                }
            }

            if(flag == 1)
            {
                absDataPtr->ar = preAr;

                absDataPtr++;
                flag = 0;
                continue;
            }
            absDataPtr++;
        }
    }

    m_editedflag = 1;

    return 1;
}

void EmbData::setMcRepeatEmb(DataFileHead fileHead)
{
    if(m_pEmbDs16Head != NULL)
    {
        m_pEmbDs16Head->xRepeatNums = fileHead.mcXRepeatNum;
        m_pEmbDs16Head->yRepeatNums = fileHead.mcYRepeatNum;
        m_pEmbDs16Head->xRepeatDistance = fileHead.mcXRepeatSpace;
        m_pEmbDs16Head->yRepeatDistance = fileHead.mcYRepeatSpace;
        if(fileHead.mcPriority == 0)//0是横向，1是纵向(u8类型)
        {
            u8 ch = 0xBF;
            m_pEmbDs16Head->offsetEn &= ch;    //bit6
        }
        else if(fileHead.mcPriority == 1)//0是横向，1是纵向(u8类型)
        {
            u8 ch = 0x40;
            m_pEmbDs16Head->offsetEn |= ch;    //bit6
        }

        if((u32)m_embDs16Data.size() > sizeof(DataDs16FileHead))
        {
            memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head, sizeof(DataDs16FileHead));
        }
    }
}

//设置 偏移点XY
void EmbData::setOffsetXYData(s32 EnFlag,s32 offsetX,s32 offsetY)
{
    m_enFlag = EnFlag;  //中间数据的偏移点X
    m_offsetX = offsetX;  //中间数据的偏移点X
    m_offsetY = offsetY;  //中间数据的偏移点X
}

//设置xy分别补偿
int EmbData::setNeedleXYCompensation(double valueX,double valueY)
{
    int ptnum = 0;
    int index = 0;
    int idxend = 0;

    //针步补偿又加了让绣品变细的功能  -rq

    //    if(value <= 0)
    //    {
    //        return 0;
    //    }

    ptnum = m_dataAbsList.size();//文件绝对位置列表的大小
    if (ptnum <= 0)
    {
        return 0;
    }

    index = 0;
    idxend = ptnum;

    for (int i = index; i < idxend; i++)
    {
        // 文件头
        const QByteArray & ary = m_dataAbsList.at(i);
        int size = ary.size();
        if (size <= (int)sizeof(DataDs16FileHead))
        {
            qDebug("ary%d data less then head size", i);
            continue;
        }

        int datasize = size - sizeof(DataDs16FileHead);
        int stepsize = datasize/sizeof(DsAbsItem);
        if (stepsize <= 0)
        {
            qDebug("dat data size err");
            continue;
        }

        DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
        DsAbsItem * absDataPtr = pData;

        int flag = 0;
        double lbx,lby;
        lbx = lby = 0;
        // 数据转换
        for (int j = 0; j < stepsize; j++)
        {
            double bx,by,cx,cy,nx,ny;
            bx = by = cx = cy = nx = ny = 0;

            if(j < stepsize - 1 && j != 0)
            {
                bx = lbx;
                by = lby;

                cx = absDataPtr->ax;
                cy = absDataPtr->ay;

                absDataPtr++;
                nx = absDataPtr->ax;
                ny = absDataPtr->ay;

                absDataPtr--;

                if((cx> nx && cx > bx )||
                        (cx < nx && cx < bx)||
                        (cy> ny && cy > by )||
                        (cy < ny && cy < by))
                {
                    flag = 1;
                }
            }

            lbx = cx;
            lby = cy;

            //下一点的x或y坐标小于当前点的坐标，证明针步是相反的
            double x1,y1,x2,y2,x3,y3;
            x1 = y1 = x2 = y2 = x3 = y3 = 0;

            if(flag == 1)
            {
                x1 = bx;
                y1 = by;
                x2 = cx;
                y2 = cy;
                x3 = nx;
                y3 = ny;

                double angle1 = getAngle(x1,y1,x2,y2);
                double angle2 = getAngle(x2,y2,x3,y3) + 180.0;
                if (angle2 >= 360)
                {
                    angle2 = angle2 - 360;
                }
                double angle3 = (angle1 + angle2) / 2.0;

                if(abs(angle1 - angle2) > 180)//跨坐标系时需要做此判断
                {
                    angle3 = 180 - angle3;
                }

                //qDebug()<<"angle1"<<angle1<<"angle2"<<angle2<<"angle3"<<angle3;

                x2 = x2 + valueX * cos(angle3/(180/M_PI));//cos中需要使用弧度值
                y2 = y2 + valueY * sin(angle3/(180/M_PI));//sin中需要使用弧度值
                //qDebug()<<"x2"<<x2<<"y2"<<y2;

                absDataPtr->ax = x2;
                absDataPtr->ay = y2;
                //qDebug()<<"absDataPtr"<<absDataPtr->ax<<absDataPtr->ay;
            }

            absDataPtr++;
            flag = 0;
        }
    }

    m_editedflag = 1;

    return 1;
}

double EmbData::getAngle(double x1, double y1, double x2, double y2)
{
    double angle;
    if(x1 == x2)
    {
        if(y2 > y1)
        {
            angle = 90.0;
        }
        else
        {
            angle = 270.0;
        }
    }
    else if (y1 == y2)
    {
        if(x1 > x2)
        {
            angle = 180.0;
        }
        else
        {
            angle = 0.0;
        }
    }
    else
    {
        angle = atan((y2 - y1)*1.0 / (x2 - x1) *1.0)*180/M_PI;

        if(angle < 0)
        {
            if(x1 > x2)
            {
                angle = angle + 180.0;
            }
            else
            {
                angle = angle + 360.0;
            }
        }
        else
        {
            if(x1 > x2)
            {
                angle = angle + 180.0;
            }
        }
    }

    return angle;
}

int EmbData::setDatSizeChange(int dsx, int dsy, int idx)
{
    int ptnum = 0;
    int index = 0;
    int idxend = 0;

    //因为帽绣机要有100%以下的缩放倍率，所以将  dsx <= 0 && dsy <= 0，改为以下 -rq
    if (dsx == 0 && dsy == 0)
    {
        return 0;
    }

    ptnum =  m_dataAbsList.size();
    if (ptnum <= 0)
    {
        return 0;
    }
    if (idx < 0)
    {
        index = 0;
        idxend = ptnum;
    }
    else
    {
        index = idx;
        idxend = idx + 1;
    }

    for (int i = index; i < idxend; i++)
    {
        // 文件头
        const QByteArray & ary = m_dataAbsList.at(i);
        int size = ary.size();
        if (size <= (int)sizeof(DataDs16FileHead))
        {
            qDebug("ary%d data less then head size", i);
            continue;
        }

        int datasize = size - sizeof(DataDs16FileHead);
        int stepsize = datasize/sizeof(DsAbsItem);
        if (stepsize <= 0)
        {
            qDebug("dat data size err");
            continue;
        }

        DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());

        DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
        DsAbsItem * absDataPtr = pData;

        int width = 0;
        int height = 0;

        if(idx == -1)   //整体缩放
        {
            width  = m_maxX - m_minX;
            height = m_maxY - m_minY;
        }
        else
        {
            width  = pDsHead->maxX - pDsHead->minX;
            height = pDsHead->maxY - pDsHead->minY;
        }

        double nw = dsx / 100.00 * width;
        double nh = dsy / 100.00 * height;

        double factorx,factory;
        if (width != 0)
        {
            factorx = (double)(width + nw)/(double)width;
        }
        else
        {
            factorx = 1;
        }

        if (height != 0)
        {
            factory = (double)(height + nh)/(double)height;
        }
        else
        {
            factory = 1;
        }

        if (idx == -1)   //整体缩放,起始点也要缩放
        {
            double centerx = (m_maxX + m_minX)/2;
            double centery = (m_maxY + m_minY)/2;

            double rx = (pDsHead->beginX - centerx) * factorx;
            double ry = (pDsHead->beginY - centery) * factory;

            double beginx = rx + centerx;
            double beginy = ry + centery;

            beginx += (beginx>0?(beginx!=0?1:0):-1) * (0.500001);
            beginy += (beginy>0?(beginy!=0?1:0):-1) * (0.500001);
        }

        // 数据缩放
        for (int j = 0; j < stepsize; j++)
        {
            double ax = absDataPtr->ax;
            double ay = absDataPtr->ay;

            ax *= factorx;
            ay *= factory;

            absDataPtr->ax = ax;
            absDataPtr->ay = ay;

            absDataPtr++;
        }
    }

    m_editedflag = 1;

    return 1;
}

int EmbData::setMirror(int mirror, int idx)
{
    int ptnum = 0;
    int index = 0;
    int idxend = 0;

    if (mirror == 0)    // 0, 无镜像; 1, 水平镜像; 2, 垂直镜像; 3, 水平和垂直镜像
    {
        return 0;
    }

    int mirrorx = 1;
    int mirrory = 1;
    int mirrorr = 0;
    int mirrorrdir = 0;

    if(mirror == 1 || mirror == 3)
    {
        mirrorx = -1;
    }
    if(mirror == 2 || mirror == 3)
    {
        mirrory = -1;
    }

    if(mirror == 1)
    {
        mirrorr = 1*PI*10000;
        mirrorrdir = -1;
    }
    else if (mirror == 2)
    {
        mirrorr = 2*PI*10000;
        mirrorrdir = -1;
    }
    else if (mirror == 3)
    {
        mirrorr = 1*PI*10000;
        mirrorrdir = 1;
    }

    ptnum =  m_dataAbsList.size();
    if (ptnum <= 0)
    {
        return 0;
    }
    if (idx < 0)
    {
        index = 0;
        idxend = ptnum;
    }
    else
    {
        index = idx;
        idxend = idx + 1;
    }

    for (int i = index; i < idxend; i++)
    {
        // 文件头
        const QByteArray & ary = m_dataAbsList.at(i);
        int size = ary.size();
        if (size <= (int)sizeof(DataDs16FileHead))
        {
            qDebug("ary%d data less then head size", i);
            continue;
        }

        int datasize = size - sizeof(DataDs16FileHead);
        int stepsize = datasize/sizeof(DsAbsItem);
        if (stepsize <= 0)
        {
            qDebug("dat data size err");
            continue;
        }

        DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());

        //beginR的旋转
        double br = pDsHead->beginR;
        if (mirrorrdir > 0)
        {
            br = br + mirrorr;
        }
        else if (mirrorrdir < 0)
        {
            br = mirrorr - br;
        }

        while (br > 2*PI * 10000)
        {
            br -= 2*PI * 10000;
        }
        while (br < -2*PI * 10000)
        {
            br += 2*PI * 10000;
        }
        pDsHead->beginR = br;

        DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
        DsAbsItem * absDataPtr = pData;

        // 数据镜像
        for (int j = 0; j < stepsize; j++)
        {
            double ax = absDataPtr->ax;
            double ay = absDataPtr->ay;
            double ar = absDataPtr->ar;

            int rx = ax * mirrorx;
            int ry = ay * mirrory;

            if (mirrorrdir > 0)
            {
                ar = ar + mirrorr;
            }
            else if (mirrorrdir < 0)
            {
                ar = mirrorr - ar;
            }

            while (ar > 2*PI * 10000)
            {
                ar -= 2*PI * 10000;
            }
            while (ar < -2*PI * 10000)
            {
                ar += 2*PI * 10000;
            }

            absDataPtr->ax = rx;
            absDataPtr->ay = ry;
            absDataPtr->ar = ar;

            absDataPtr++;
        }
    }

    m_editedflag = 1;
    return 1;
}

int EmbData::setRotate(int dr, int idx)
{
    int ptnum = 0;
    int index = 0;
    int idxend = 0;
    double rr = (dr * PI / 180) * 10000;

    if (dr == 0 || dr == 360)
    {
        return 0;
    }

    ptnum =  m_dataAbsList.size();
    if (ptnum <= 0)
    {
        return 0;
    }
    if (idx < 0)
    {
        index = 0;
        idxend = ptnum;
    }
    else
    {
        index = idx;
        idxend = idx + 1;
    }

    double angle, sina, cosa;

#if (1)

    // 因为计算三角函数有问题，现在只支持 1度，10度，90度
    switch(dr)
    {
    case 1:
        sina = 0.01745240643728351281941897851632;
        cosa = 0.99984769515639123915701155881391;
        break;
    case 10:
        sina = 0.17364817766693034885171662676931;
        cosa = 0.98480775301220805936674302458952;
        break;
    case 90:
        sina = 1;
        cosa = 0;
        break;
    case -1:
        sina = -0.01745240643728351281941897851632;
        cosa = 0.99984769515639123915701155881391;
        break;
    case -10:
        sina = -0.17364817766693034885171662676931;
        cosa = 0.98480775301220805936674302458952;
        break;
    case -90:
        sina = -1;
        cosa = 0;
        break;
    default:
        angle = (dr * PI) / 180.0;
        sina = (double)qSin(angle);
        cosa = (double)qCos(angle);
        break;
    }

#else

    angle = (dr * PI) / 180.0;
    sina = (double)qSin(angle);
    cosa = (double)qCos(angle);
#endif

    for (int i = index; i < idxend; i++)
    {
        // 文件头
        const QByteArray & ary = m_dataAbsList.at(i);
        int size = ary.size();
        if (size <= (int)sizeof(DataDs16FileHead))
        {
            qDebug("ary%d data less then head size", i);
            continue;
        }

        int datasize = size - sizeof(DataDs16FileHead);
        int stepsize = datasize/sizeof(DsAbsItem);
        if (stepsize <= 0)
        {
            qDebug("dat data size err");
            continue;
        }
        DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());

        //beginR的旋转
        double br = pDsHead->beginR + rr;
        while (br > 2*PI * 10000)
        {
            br -= 2*PI * 10000;
        }
        while (br < -2*PI * 10000)
        {
            br += 2*PI * 10000;
        }
        pDsHead->beginR = br;


        double cx;
        double cy;

        int rx, ry; //这里以前是double类型，因为有的图形旋转后尺寸会加0.1，所以改为int类型
        double rcx, rcy;

        if (idx == -1)  // 整体旋转
        {
            cx = (m_maxX + m_minX)/2.0;
            cy = (m_maxY + m_minY)/2.0;

            rx = (pDsHead->beginX - cx);
            ry = (pDsHead->beginY - cy);
        }
        else
        {
            cx = pDsHead->beginX;
            cy = pDsHead->beginY;

            rx = 0;
            ry = 0;
        }

        rcx = (rx*cosa - ry*sina);
        rcy = (rx*sina + ry*cosa);

        double beginx = (rcx + cx);
        double beginy = (rcy + cy);

        beginx += (beginx>0?(beginx!=0?1:0):-1) * (0.500001);
        beginy += (beginy>0?(beginy!=0?1:0):-1) * (0.500001);

        DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
        DsAbsItem * absDataPtr = pData;

        // 数据旋转
        for (int j = 0; j < stepsize; j++)
        {
            // 变换前点坐标
            double ax = absDataPtr->ax + rx;
            double ay = absDataPtr->ay + ry;
            double ar = absDataPtr->ar + rr;

            while (ar > 2*PI * 10000)
            {
                ar -= 2*PI * 10000;
            }
            while (ar < -2*PI * 10000)
            {
                ar += 2*PI * 10000;
            }
            // 变换后点的坐标
            double rax = (ax*cosa - ay*sina);
            double ray = (ax*sina + ay*cosa);

            absDataPtr->ax = rax - rcx;
            absDataPtr->ay = ray - rcy;
            absDataPtr->ar =  ar;
            absDataPtr++;
        }
    }

    m_editedflag = 1;

    return 1;
}

int EmbData::setToMiddle(int idx)
{
    int ptnum = 0;
    int index = 0;
    int idxend = 0;

    ptnum =  m_dataAbsList.size();
    if (ptnum <= 0)
    {
        return 0;
    }
    if (idx < 0)
    {
        index = 0;
        idxend = ptnum;
    }
    else
    {
        index = idx;
        idxend = idx + 1;
    }

    for (int i = index; i < idxend; i++)
    {
        // 文件头
        const QByteArray & ary = m_dataAbsList.at(i);
        int size = ary.size();
        if (size <= (int)sizeof(DataDs16FileHead))
        {
            qDebug("ary%d data less then head size", i);
            continue;
        }

        int datasize = size - sizeof(DataDs16FileHead);
        int stepsize = datasize/sizeof(DsAbsItem);
        if (stepsize <= 0)
        {
            qDebug("dat data size err");
            continue;
        }

        DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());

        if(idx == -1)
        {
            int centerx = 0 - (m_maxX + m_minX)/2;
            int centery = 0 - (m_maxY + m_minY)/2;

            int beginx = pDsHead->beginX + centerx;
            int beginy = pDsHead->beginY + centery;

            pDsHead->beginX = beginx;
            pDsHead->beginY = beginy;
        }
        else
        {
            pDsHead->beginX = 0;
            pDsHead->beginY = 0;
        }
    }

    m_editedflag = 1;

    return 0;
}

int EmbData::setDatMove(int dx, int dy, int idx)
{
    int ptnum = 0;
    int index = 0;
    int idxend = 0;

    if (dx == 0 && dy == 0)
    {
        return 0;
    }

    ptnum =  m_dataAbsList.size();
    if (ptnum <= 0)
    {
        return 0;
    }
    if (idx < 0)
    {
        index = 0;
        idxend = ptnum;
    }
    else
    {
        index = idx;
        idxend = idx + 1;
    }

    for (int i = index; i < idxend; i++)
    {
        // 文件头
        const QByteArray & ary = m_dataAbsList.at(i);
        int size = ary.size();
        if (size <= (int)sizeof(DataDs16FileHead))
        {
            qDebug("ary%d data less then head size", i);
            continue;
        }

        int datasize = size - sizeof(DataDs16FileHead);
        int stepsize = datasize/sizeof(DsAbsItem);
        if (stepsize <= 0)
        {
            qDebug("dat data size err");
            continue;
        }

        DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());

        int beginx = pDsHead->beginX;
        int beginy = pDsHead->beginY;

        pDsHead->beginX = beginx + dx;
        pDsHead->beginY = beginy + dy;
    }

    m_editedflag = 1;

    return 0;
}

//按色通常并转换为ds16数据
void EmbData::createSameColorEmbDs16Dat(int num)
{
    QByteArray absDsDat;
    absDsDat.clear();

    // 文件头
    int size = m_embDs16Data.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("m_embDs16Data data less then head size");
        return;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = 0;
    stepsize = datasize/sizeof(Ds16Item);

    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return;
    }

    //改变色序表的颜色排序，按色排序
    int totalColorNum = m_pEmbDs16Head->colorNum/num;
    int tableSize = sizeof(m_pEmbDs16Head->switchTable);
    u8 cTable[tableSize];
    memset(cTable,0,tableSize);

    for(int i = 0; i < totalColorNum; i++)
    {
        for(int j = 0; j < num; j++)
        {
            cTable[i*num+j] = m_pEmbDs16Head->switchTable[i];
        }
    }
    memset(m_pEmbDs16Head->switchTable,0,tableSize);
    memcpy(m_pEmbDs16Head->switchTable,cTable,tableSize);//将新的色序表重新写入文件头

    absDsDat.append((char*)m_pEmbDs16Head,sizeof(DataDs16FileHead));

    if(m_dataAbsList.size() < num)
    {
        return;
    }

    DsAbsItem absItem;
    double datposx, datposy;
    datposx = m_pEmbDs16Head->beginX;
    datposy = m_pEmbDs16Head->beginY;

    Ds16Item * ds16DataPtr;
    Ds16Item * pData = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = pData;

    //将ds16数据相对坐标转为绝对坐标
    for (int i = 0; i < stepsize; i++)
    {
        u8 ctrl,attr;
        u8 ds16Action[2];
        double dx,dy,dr;

        ctrl = ds16DataPtr->ctrl;
        attr = ds16DataPtr->attr;
        ds16Action[0] = ds16DataPtr->action[0];
        ds16Action[1] = ds16DataPtr->action[1];
        dx = ds16DataPtr->dx;
        dy = ds16DataPtr->dy;
        dr = ds16DataPtr->dr;

        if ((attr & 0x80) != 0)
        {
            dx *= -1;
        }
        if ((attr & 0x40) != 0)
        {
            dy *= -1;
        }

        datposx += dx;
        datposy += dy;

        absItem.ctrl = ctrl;
        absItem.attr = attr;

        //亮片和散珠
        //亮片
        for(s16 i = 0; i < 8; i++)
        {
            u8 ch = ds16Action[0] >> i;
            if(ch != 0)
            {
                u8 action1 = ch + 0x01;
                absItem.action = action1;
                break;
            }
        }

        //散珠
        for(s16 i = 0; i < 8; i++)
        {
            u8 ch = ds16Action[1] >> i;
            if(ch != 0)
            {
                u8 action2 = ch + 0x11;
                absItem.action = action2;
                break;
            }
        }

        absItem.ax = datposx;
        absItem.ay = datposy;
        absItem.ar = dr;

        absDsDat.append((char*)(&absItem), sizeof(DsAbsItem));
        ds16DataPtr++;
    }

    //以下为截取每个图元相同的颜色数据放在一起
    QByteArray sameColorAbsDat;
    sameColorAbsDat.clear();
    sameColorAbsDat.append((char*)m_pEmbDs16Head,sizeof(DataDs16FileHead));

    DsAbsItem * pAbsData = (DsAbsItem *)(absDsDat.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDsDataPtr = pAbsData;
    int curColorNum = 1;

    size = absDsDat.size();
    datasize = size - sizeof(DataDs16FileHead);
    stepsize = datasize/sizeof(DsAbsItem);

    for (int i = 0; i < stepsize; i++)
    {
        if(curColorNum > totalColorNum)
        {
            break;
        }

        u8 ctrl = absDsDataPtr->ctrl;

        //首个图元的换色码不添加
        if (ctrl != DATA_CHGND)
        {
            sameColorAbsDat.append((char*)(absDsDataPtr), sizeof(DsAbsItem));
        }

        DsAbsItem item;

        if (ctrl == DATA_CHGND)
        {
            for(int n = 1; n < num; n++)
            {
                DsAbsItem * aDataPtr = (DsAbsItem *)(absDsDat.data() + sizeof(DataDs16FileHead));

                int colorSel = curColorNum + n * totalColorNum + 1;
                int colorIdx = 1;
                int flag = 0;

                for (int j = 0; j < stepsize; j++)
                {
                    if(aDataPtr->ctrl == DATA_CHGND)
                    {
                        flag = 0;
                        colorIdx++;
                    }

                    if(colorIdx > colorSel)
                    {
                        break;
                    }

                    if(colorIdx == colorSel)
                    {
                        if(aDataPtr->ctrl != DATA_CHGND)
                        {
                            //每个图形的单个图元切换到下一个图形同色图元前加一个换色码
                            if(flag == 0)
                            {
                                DsAbsItem citem;
                                memset(&citem,0,sizeof(DsAbsItem));
                                citem.ctrl = DATA_OFFSET;
                                citem.action = 0;
                                citem.attr = 0x00;
                                citem.ax = aDataPtr->ax;//换色x、y坐标等于第一个运针的坐标
                                citem.ay = aDataPtr->ay;
                                citem.ar = 0;
                                sameColorAbsDat.append((char*)(&citem), sizeof(DsAbsItem));

                                citem.ctrl = DATA_CHGND;
                                citem.action = 0;
                                citem.attr = 0x00;
                                citem.ax = 0;//换色x、y坐标等于第一个运针的坐标
                                citem.ay = 0;
                                citem.ar = 0;
                                sameColorAbsDat.append((char*)(&citem), sizeof(DsAbsItem));
                                flag = 1;
                            }
                            sameColorAbsDat.append((char*)(aDataPtr), sizeof(DsAbsItem));

                            //相同颜色图元后面换色码的xy坐标
                            item.ax = aDataPtr->ax;//换色x、y坐标等于图元最后运针的坐标
                            item.ay = aDataPtr->ay;
                        }
                    }
                    aDataPtr++;
                }
            }

            //在相同颜色图元的最后一个后面加换色码
            item.ctrl = DATA_CHGND;
            item.attr = 0x00;
            item.action = 0;
            item.ar = 0;
            sameColorAbsDat.append((char*)(&item), sizeof(DsAbsItem));

            curColorNum++;
        }
        absDsDataPtr++;

#if(0)
        //测试用
        if(curColorNum == 2)
        {
            break;
        }
#endif

    }

#if(1)
    curColorNum = 0;
    //以下代码为按色排序数据的绝对坐标转换为相对坐标
    QByteArray dsDat;
    dsDat.clear();
    dsDat.append((char*)m_pEmbDs16Head,sizeof(DataDs16FileHead));
    int cSize = sameColorAbsDat.size() - sizeof(DataDs16FileHead);
    int cStepsize = cSize/sizeof(DsAbsItem);

    DsAbsItem * pDsData = (DsAbsItem *)(sameColorAbsDat.data() + sizeof(DataDs16FileHead));
    DsAbsItem * dsDataPtr = pDsData;
    dsDataPtr = pDsData;

    double prex = m_pEmbDs16Head->beginX;
    double prey = m_pEmbDs16Head->beginY;
    double curx,cury;
    curx = cury = 0;
    int jumpNeedleNum = 0;

    for (int i = 0; i < cStepsize; i++)
    {
        Ds16Item ds16item;

        int ddx,ddy;
        s16 sx,sy;

        ds16item.ctrl = dsDataPtr->ctrl;
        ds16item.attr = dsDataPtr->attr;

        //添加出亮片和散珠动作
        //action1是0x20代表散珠或亮片动作
        if((dsDataPtr->action & 0x20) == 0x20)
        {
            if(((dsDataPtr->action << 8) >= 0x01) && ((dsDataPtr->action << 8) <= 0x0F))//亮片
            {
                u8 ch = (dsDataPtr->action << 8) - 0x01;
                ds16item.action[0] = 0x01 << ch;
            }
            if(((dsDataPtr->action << 8) >= 0x11) && ((dsDataPtr->action << 8) <= 0x1F))//散珠
            {
                u8 ch = (dsDataPtr->action << 8) - 0x11;
                ds16item.action[1] = 0x01 << ch;
            }
        }

        curx = dsDataPtr->ax;
        cury = dsDataPtr->ay;

        ddx = curx - prex;
        ddy = cury - prey;

        if(ds16item.ctrl == DATA_JUMP)
        {
            jumpNeedleNum++;
        }

        if(ds16item.ctrl == DATA_CHGND)
        {
            curColorNum++;
        }

        sx = ddx;//带符号值
        sy = ddy;
        ds16item.dx = sx;
        ds16item.dy = sy;
        dsDat.append((char*)(&ds16item), sizeof(Ds16Item));

        prex = curx;
        prey = cury;

        dsDataPtr++;
    }

    m_embDs16Data.clear();
    m_embDs16Data.append(dsDat);

    //修改文件头
    size = m_embDs16Data.size();
    datasize = size - sizeof(DataDs16FileHead);
    QByteArray tgtdsdat;
    tgtdsdat.clear();
    tgtdsdat.append(m_embDs16Data.mid(sizeof(DataDs16FileHead),datasize));

    m_pEmbDs16Head->colorNum = curColorNum;
    m_pEmbDs16Head->dataSize = datasize;
    m_pEmbDs16Head->itemNums = datasize/sizeof(Ds16Item);
    m_pEmbDs16Head->dataChecksum = calcCheckSum32((u8 *)(tgtdsdat.data()) , m_pEmbDs16Head->dataSize);	// 数据累加校验和
    m_pEmbDs16Head->checkCrc = calcCrc16((u8 *)(m_pEmbDs16Head), HEAD_FIX_INFO_LEN);          // 前面6个字段的CRC校验，（6个字段分别为：文件名称，字节数，项个数，每项字节数，每块字节数，数据累加和的CRC校验值）
    m_pEmbDs16Head->jumpNeedleNum = jumpNeedleNum;//跳针数
#endif

#if(1)
    //保存成ds16文件
    QString ds16FilePath = m_filePath + ".ds16";
    QFile file(ds16FilePath);

    if(file.exists())//存在ds16文件
    {
        QFile::remove(ds16FilePath);
    }

    if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        qDebug() << "open file fail when wirte, path =" << m_filePath;
        return;
    }
    else
    {
        file.write(m_embDs16Data);
        file.close();
    }
#endif

}

//生成边框刺绣的数据
QString EmbData::createBorderEmbData(QString filePath)
{
    QByteArray borderDs16Array;
    borderDs16Array.clear();

    if(m_embDs16Data.length() <= 0)
    {
        return borderDs16Array;
    }

    s16 stepZoom = 0;//针步放大

    double width = m_pEmbDs16Head->maxX - m_pEmbDs16Head->minX;//宽度
    double height = m_pEmbDs16Head->maxY - m_pEmbDs16Head->minY;//高度

    double zoomWidth = width + stepZoom;//放大后的宽度
    double zoomHeight = height + stepZoom;//放大后的高度

    double factor, temp;

    factor = zoomWidth / width;      //缩放系数
    temp = zoomHeight / height;    //缩放系数

    if (temp >= factor)     // 使用较大的缩放系数
    {
        factor = temp;
    }

    double maxX = m_pEmbDs16Head->maxX * factor;//放大范围
    double minX = m_pEmbDs16Head->minX * factor;
    double maxY = m_pEmbDs16Head->maxY * factor;
    double minY = m_pEmbDs16Head->minY * factor;

    m_maxX = maxX;//放大范围
    m_minX = minX;
    m_maxY = maxY;
    m_minY = minY;

    double middleX = (m_maxX + m_minX)/2.0;
    double middleY = (m_maxY + m_minY)/2.0;

    Ds16Item ds16Item;
    memset((char*)&ds16Item,0,sizeof(Ds16Item));

    int bx,by,ex,ey;
    bx = by = ex = ey = 0;

    //矩形边框下横线
    bx = m_maxX; by = m_maxY; ex = m_minX; ey = m_maxY;
    splitBorderStitchAndAdd(borderDs16Array,bx,by,ex,ey);

    //矩形边框右横线
    bx = m_minX; by = m_maxY; ex = m_minX; ey = m_minY;
    splitBorderStitchAndAdd(borderDs16Array,bx,by,ex,ey);

    //矩形边框上横线
    bx = m_minX; by = m_minY; ex = m_maxX; ey = m_minY;
    splitBorderStitchAndAdd(borderDs16Array,bx,by,ex,ey);

    //矩形边框左横线
    bx = m_maxX; by = m_minY; ex = m_maxX; ey = m_maxY;
    splitBorderStitchAndAdd(borderDs16Array,bx,by,ex,ey);

    //矩形边框下横线左侧到下横线中心点
    bx = m_maxX; by = m_maxY; ex = middleX; ey = m_maxY;
    splitBorderStitchAndAdd(borderDs16Array,bx,by,ex,ey);

    //矩形边框下横线中心点到上横线中心点
    bx = middleX; by = m_maxY; ex = middleX; ey = m_minY;
    splitBorderStitchAndAdd(borderDs16Array,bx,by,ex,ey);

    //矩形边框上横线中心点到矩形中心点
    bx = middleX; by = m_minY; ex = middleX; ey = middleY;
    splitBorderStitchAndAdd(borderDs16Array,bx,by,ex,ey);

    //矩形边框中心点到左横线中心点
    bx = middleX; by = middleY; ex = m_maxX; ey = middleY;
    splitBorderStitchAndAdd(borderDs16Array,bx,by,ex,ey);

    //矩形边框左横线中心点到右横线中心点
    bx = m_maxX; by = middleY; ex = m_minX; ey = middleY;
    splitBorderStitchAndAdd(borderDs16Array,bx,by,ex,ey);

    //将相对坐标转换为绝对坐标
    QByteArray borderAbsArray;
    borderAbsArray.clear();

    int nums = borderDs16Array.length() / sizeof(Ds16Item);
    Ds16Item * dataBeg = (Ds16Item *)((borderDs16Array.data()));
    Ds16Item * dataPtr = dataBeg;

    DsrStep absItemDat;
    memset((char*)&absItemDat,0,sizeof(DsrStep));
    int ax = 0;
    int ay = 0;

    int dx,dy;
    u8 ctrl,attr;

    //第一针插入0，0
    absItemDat.ctrl = DATA_EMB;
    absItemDat.attr = 0;
    absItemDat.dx = 0;
    absItemDat.dy = 0;
    borderAbsArray.append((char*)&absItemDat,sizeof(DsrStep));

    for(int i = 0; i < nums; i++)
    {
        ctrl = dataPtr->ctrl;
        attr = dataPtr->attr;
        dx = dataPtr->dx;
        dy = dataPtr->dy;

        ax += dx;
        ay += dy;

        absItemDat.ctrl = ctrl;
        absItemDat.attr = attr;
        absItemDat.dx = ax;
        absItemDat.dy = ay;

        borderAbsArray.append((char*)&absItemDat,sizeof(DsrStep));
        dataPtr++;
    }

    //添加结束码
    absItemDat.ctrl = DATA_END;
    absItemDat.attr = 0;
    borderAbsArray.append((char*)&absItemDat,sizeof(DsrStep));

    //生成文件头
    DsrHead dsrHead;
    memset((char*)&dsrHead,0,sizeof(DsrHead));

    //    memcpy((char*)&dsrHead,(char*)m_pEmbDs16Head,sizeof(DsrHead));

    int itemNums = borderAbsArray.length() / sizeof(DsrStep);
    DsrStep firstStep;
    memcpy((char*)&firstStep,(char*)borderAbsArray.data(),sizeof(DsrStep));
    //重新生成文件头
    float ver = DSR_VERSION_5;
    dsrHead.verCode = *((DWORD*)(&ver));
    dsrHead.stitches = itemNums;
    dsrHead.xyUnit = 1;
    dsrHead.rangePx = m_maxX;
    dsrHead.rangePy = m_maxY;
    dsrHead.rangeNx = m_minX;
    dsrHead.rangeNy = m_minY;
    dsrHead.startX = m_maxX;
    dsrHead.startY = m_maxY;
    dsrHead.anchorX = 0;
    dsrHead.anchorY = 0;
    dsrHead.begWorkHead = m_pEmbDs16Head->begHead;
    dsrHead.dataBegin = sizeof(DsrHead);
    dsrHead.stepSize = itemNums*sizeof(DsrStep);    // 数据字节数
    memset(dsrHead.switchTable,2,sizeof(dsrHead.switchTable));//花版边框刺绣色序都默认2针位
    borderAbsArray.insert(0,(char*)&dsrHead,sizeof(DsrHead));

#if(1)
    //保存成dsr文件
    QString dsrFilePath = filePath + "border.dsr";
    QFile file(dsrFilePath);

    if(file.exists())//存在dsr文件
    {
        QFile::remove(dsrFilePath);
    }

    if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        qDebug() << "open file fail when wirte, path =" << filePath;
        dsrFilePath.clear();
        return dsrFilePath;
    }
    else
    {
        file.write(borderAbsArray);
#ifdef Q_OS_LINUX
        system("sync");
#endif
        file.close();
    }
#endif
    return dsrFilePath;
}

//生成开位线绣的数据
QByteArray EmbData::createOpenLineEmbData(QList<OpenLineNode> &list)
{
    QByteArray openLineDs16Array;
    openLineDs16Array.clear();

    Ds16Item ds16Item;
    memset((char*)&ds16Item,0,sizeof(Ds16Item));

    int bx,by,ex,ey;
    bx = by = ex = ey = 0;

    int minX = S32_MAX;
    int maxX = S32_MIN;
    int minY = S32_MAX;
    int maxY = S32_MIN;

    for(int i = 0; i < list.size(); i++)
    {
        int x = list[i].nodeX;
        int y = list[i].nodeY;

        if(i == 0)
        {
            bx = x;
            by = y;
        }

        if(x != 0 || y != 0)
        {
            ex = x; ey = y;
            splitBorderStitchAndAdd(openLineDs16Array,bx,by,ex,ey);
        }

        if(x == 0 && y == 0)
        {
            break;
        }

        bx = ex;
        by = ey;

        if (bx < minX) { minX = bx; }
        if (bx > maxX) { maxX = bx; }
        if (by < minY) { minY = by; }
        if (by > maxY) { maxY = by; }
    }

    //将相对坐标转换为绝对坐标
    QByteArray openLineAbsArray;
    openLineAbsArray.clear();

    int nums = openLineDs16Array.length() / sizeof(Ds16Item);
    Ds16Item * dataBeg = (Ds16Item *)((openLineDs16Array.data()));
    Ds16Item * dataPtr = dataBeg;

    DsAbsItem absItemDat;
    memset((char*)&absItemDat,0,sizeof(DsAbsItem));
    int ax = 0;
    int ay = 0;

    int dx,dy;
    u8 ctrl,attr;

    //第一针插入0，0
    absItemDat.ctrl = DATA_EMB;
    absItemDat.attr = 0;
    absItemDat.ax = 0;
    absItemDat.ay = 0;
    openLineAbsArray.append((char*)&absItemDat,sizeof(DsAbsItem));

    for(int i = 0; i < nums; i++)
    {
        ctrl = dataPtr->ctrl;
        attr = dataPtr->attr;
        dx = dataPtr->dx;
        dy = dataPtr->dy;

        ax += dx;
        ay += dy;

        absItemDat.ctrl = ctrl;
        absItemDat.attr = attr;
        absItemDat.ax = ax;
        absItemDat.ay = ay;

        openLineAbsArray.append((char*)&absItemDat,sizeof(DsAbsItem));
        dataPtr++;
    }

    //添加结束码
    absItemDat.ctrl = DATA_END;
    absItemDat.attr = 0;
    openLineAbsArray.append((char*)&absItemDat,sizeof(DsAbsItem));

    //生成文件头
    DataDs16FileHead ds16Head;
    memcpy((char*)&ds16Head,(char*)m_pEmbDs16Head,sizeof(DataDs16FileHead));

    int itemNums = openLineAbsArray.length() / sizeof(DsAbsItem);
    DsAbsItem firstStep;
    memcpy((char*)&firstStep,(char*)openLineAbsArray.data(),sizeof(DsAbsItem));
    //重新生成文件头
    ds16Head.colorNum = 1;
    ds16Head.jumpNeedleNum = 0;
    ds16Head.maxX = maxX;
    ds16Head.maxY = maxY;
    ds16Head.minX = minX;
    ds16Head.minY = minY;
    ds16Head.anchorX = 0;
    ds16Head.anchorY = 0;
    ds16Head.beginX = list[0].nodeX;
    ds16Head.beginY = list[0].nodeY;
    ds16Head.itemNums = itemNums;
    ds16Head.dataSize = itemNums*sizeof(DsAbsItem);    // 数据字节数
    ds16Head.bytesPerItem = sizeof(DsAbsItem);           // 每项占的字节数
    ds16Head.dataChecksum = calcCheckSum32((u8 *)(openLineAbsArray.data()) , ds16Head.dataSize);;	// 数据累加校验和
    ds16Head.checkCrc = calcCrc16((u8 *)(&ds16Head), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验，（6个字段分别为：文件名称，字节数，项个数，每项字节数，每块字节数，数据累加和的CRC校验值）
    ds16Head.fileid = ds16Head.checkCrc;
    memset(ds16Head.switchTable,0,sizeof(ds16Head.switchTable));
    //ds16Head.switchTable[0] = 1; //设置色序(色序为0时使用当前针杆绣作)
    openLineAbsArray.insert(0,(char*)&ds16Head,sizeof(DataDs16FileHead));

    return openLineAbsArray;
}

//
// 涂格子子程序,将X,Y为中心,范围r内的格子填上数值:1
void EmbData::PaintedGrid(QVector<QVector<char> >& visited,int x,int y,int r)
{
    int i;
    for (i=(x-r); i<=(x+r);i++)
    {
        visited[i][y-r] = 1;
        visited[i][y+r] = 1;
    }
    for (i=(y-r); i<=(y+r);i++)
    {
        visited[x-r][i] = 1;
        visited[x+r][i] = 1;
    }
}

// 绘制直线
void EmbData::PaintedLine(QVector<QVector<char> >& visited, int begx, int begy, int endx, int endy,int zoom,int vectorH,int vectorV)
{
    int x, y, dx, dy;
    int incx, incy, balance;

    if (((begx-zoom) > 0) && ((begx+zoom) < vectorH) &&
            ((begy-zoom) > 0) && ((begy+zoom) < vectorV) &&
            ((endx-zoom) > 0) && ((endx+zoom) < vectorH) &&
            ((endy-zoom) > 0) && ((endy+zoom) < vectorV) &&
            1)
    {
    }
    else
    {
        qDebug() << "error beginX=" << begx
                 << ",beginY=" << begy
                 << ",endX=" << endx
                 << ",endY=" << endy
                    ;
        return;
    }

    if (begx == endx)
    {// 竖线
        x = begx;
        if (endy >= begy)
        {
            for (y=begy;y<=endy;y++)
            {
                PaintedGrid(visited, x, y, zoom);
            }
        }
        else
        {
            for (y=endy;y<=begy;y++)
            {
                PaintedGrid(visited, x, y, zoom);
            }
        }
    }
    else if (begy == endy)
    {// 横线
        y = begy;
        if (endx >= begx)
        {
            for (x=begx;x<=endx;x++)
            {
                PaintedGrid(visited, x, y, zoom);
            }
        }
        else
        {
            for (x=endx;x<=begx;x++)
            {
                PaintedGrid(visited, x, y, zoom);
            }
        }
    }
    else
    {// 斜线
        if (endx >= begx)
        {
            dx = endx - begx;
            incx = 1;
        }
        else
        {
            dx = begx - endx;
            incx = -1;
        }

        if (endy >= begy)
        {
            dy = endy - begy;
            incy = 1;
        }
        else
        {
            dy = begy - endy;
            incy = -1;
        }

        x = begx;
        y = begy;

        if (dx >= dy)
        {
            dy <<= 1;
            balance = dy - dx;
            dx <<= 1;

            while(x != endx)
            {
                PaintedGrid(visited, x, y, zoom);
                if (balance >= 0)
                {
                    y += incy;
                    balance -= dx;
                }

                balance += dy;
                x += incx;
            }

            PaintedGrid(visited, x, y, zoom);
        }
        else
        {
            dx <<= 1;
            balance = dx - dy;
            dy <<= 1;

            while (y != endy)
            {
                PaintedGrid(visited, x, y, zoom);

                if (balance >= 0)
                {
                    x += incx;
                    balance -= dy;
                }

                balance += dx;
                y += incy;
            }

            PaintedGrid(visited, x, y, zoom);
        }
    }
}

// 寻找下一个点
// 方向
//        8 1 2
//        7 0 3
//        6 5 4
OutLineItem EmbData::FindNextPos(QVector<QVector<char> >& visited,OutLineItem pos)
{
    OutLineItem nextPos;
    memset(&nextPos,0,sizeof(OutLineItem));

    QVector<OutLineItem> posList(8);    // 外围8个点

    if (pos.dir == 1)
    {// 12点方向
        posList[0].x = pos.x+1;     posList[0].y = pos.y-1;     posList[0].dir = 6;     posList[0].var = visited[pos.x+1][pos.y-1];
        posList[1].x = pos.x+1;     posList[1].y = pos.y+0;     posList[1].dir = 7;     posList[1].var = visited[pos.x+1][pos.y+0];
        posList[2].x = pos.x+1;     posList[2].y = pos.y+1;     posList[2].dir = 8;     posList[2].var = visited[pos.x+1][pos.y+1];
        posList[3].x = pos.x+0;     posList[3].y = pos.y+1;     posList[3].dir = 1;     posList[3].var = visited[pos.x+0][pos.y+1];
        posList[4].x = pos.x-1;     posList[4].y = pos.y+1;     posList[4].dir = 2;     posList[4].var = visited[pos.x-1][pos.y+1];
        posList[5].x = pos.x-1;     posList[5].y = pos.y+0;     posList[5].dir = 3;     posList[5].var = visited[pos.x-1][pos.y+0];
        posList[6].x = pos.x-1;     posList[6].y = pos.y-1;     posList[6].dir = 4;     posList[6].var = visited[pos.x-1][pos.y-1];
        posList[7].x = pos.x+0;     posList[7].y = pos.y-1;     posList[7].dir = 5;     posList[7].var = visited[pos.x+0][pos.y-1];
    }
    else if (pos.dir == 2)
    {// 1点方向
        posList[0].x = pos.x+1;     posList[0].y = pos.y+0;     posList[0].dir = 7;     posList[0].var = visited[pos.x+1][pos.y+0];
        posList[1].x = pos.x+1;     posList[1].y = pos.y+1;     posList[1].dir = 8;     posList[1].var = visited[pos.x+1][pos.y+1];
        posList[2].x = pos.x+0;     posList[2].y = pos.y+1;     posList[2].dir = 1;     posList[2].var = visited[pos.x+0][pos.y+1];
        posList[3].x = pos.x-1;     posList[3].y = pos.y+1;     posList[3].dir = 2;     posList[3].var = visited[pos.x-1][pos.y+1];
        posList[4].x = pos.x-1;     posList[4].y = pos.y+0;     posList[4].dir = 3;     posList[4].var = visited[pos.x-1][pos.y+0];
        posList[5].x = pos.x-1;     posList[5].y = pos.y-1;     posList[5].dir = 4;     posList[5].var = visited[pos.x-1][pos.y-1];
        posList[6].x = pos.x+0;     posList[6].y = pos.y-1;     posList[6].dir = 5;     posList[6].var = visited[pos.x+0][pos.y-1];
        posList[7].x = pos.x+1;     posList[7].y = pos.y-1;     posList[7].dir = 6;     posList[7].var = visited[pos.x+1][pos.y-1];
    }
    else if (pos.dir == 3)
    {// 3点方向
        posList[0].x = pos.x+1;     posList[0].y = pos.y+1;     posList[0].dir = 8;     posList[0].var = visited[pos.x+1][pos.y+1];
        posList[1].x = pos.x+0;     posList[1].y = pos.y+1;     posList[1].dir = 1;     posList[1].var = visited[pos.x+0][pos.y+1];
        posList[2].x = pos.x-1;     posList[2].y = pos.y+1;     posList[2].dir = 2;     posList[2].var = visited[pos.x-1][pos.y+1];
        posList[3].x = pos.x-1;     posList[3].y = pos.y+0;     posList[3].dir = 3;     posList[3].var = visited[pos.x-1][pos.y+0];
        posList[4].x = pos.x-1;     posList[4].y = pos.y-1;     posList[4].dir = 4;     posList[4].var = visited[pos.x-1][pos.y-1];
        posList[5].x = pos.x+0;     posList[5].y = pos.y-1;     posList[5].dir = 5;     posList[5].var = visited[pos.x+0][pos.y-1];
        posList[6].x = pos.x+1;     posList[6].y = pos.y-1;     posList[6].dir = 6;     posList[6].var = visited[pos.x+1][pos.y-1];
        posList[7].x = pos.x+1;     posList[7].y = pos.y+0;     posList[7].dir = 7;     posList[7].var = visited[pos.x+1][pos.y+0];
    }
    else if (pos.dir == 4)
    {// 5点方向
        posList[0].x = pos.x+0;     posList[0].y = pos.y+1;     posList[0].dir = 1;     posList[0].var = visited[pos.x+0][pos.y+1];
        posList[1].x = pos.x-1;     posList[1].y = pos.y+1;     posList[1].dir = 2;     posList[1].var = visited[pos.x-1][pos.y+1];
        posList[2].x = pos.x-1;     posList[2].y = pos.y+0;     posList[2].dir = 3;     posList[2].var = visited[pos.x-1][pos.y+0];
        posList[3].x = pos.x-1;     posList[3].y = pos.y-1;     posList[3].dir = 4;     posList[3].var = visited[pos.x-1][pos.y-1];
        posList[4].x = pos.x+0;     posList[4].y = pos.y-1;     posList[4].dir = 5;     posList[4].var = visited[pos.x+0][pos.y-1];
        posList[5].x = pos.x+1;     posList[5].y = pos.y-1;     posList[5].dir = 6;     posList[5].var = visited[pos.x+1][pos.y-1];
        posList[6].x = pos.x+1;     posList[6].y = pos.y+0;     posList[6].dir = 7;     posList[6].var = visited[pos.x+1][pos.y+0];
        posList[7].x = pos.x+1;     posList[7].y = pos.y+1;     posList[7].dir = 8;     posList[7].var = visited[pos.x+1][pos.y+1];
    }
    else if (pos.dir == 5)
    {// 6点方向
        posList[0].x = pos.x-1;     posList[0].y = pos.y+1;     posList[0].dir = 2;     posList[0].var = visited[pos.x-1][pos.y+1];
        posList[1].x = pos.x-1;     posList[1].y = pos.y+0;     posList[1].dir = 3;     posList[1].var = visited[pos.x-1][pos.y+0];
        posList[2].x = pos.x-1;     posList[2].y = pos.y-1;     posList[2].dir = 4;     posList[2].var = visited[pos.x-1][pos.y-1];
        posList[3].x = pos.x+0;     posList[3].y = pos.y-1;     posList[3].dir = 5;     posList[3].var = visited[pos.x+0][pos.y-1];
        posList[4].x = pos.x+1;     posList[4].y = pos.y-1;     posList[4].dir = 6;     posList[4].var = visited[pos.x+1][pos.y-1];
        posList[5].x = pos.x+1;     posList[5].y = pos.y+0;     posList[5].dir = 7;     posList[5].var = visited[pos.x+1][pos.y+0];
        posList[6].x = pos.x+1;     posList[6].y = pos.y+1;     posList[6].dir = 8;     posList[6].var = visited[pos.x+1][pos.y+1];
        posList[7].x = pos.x+0;     posList[7].y = pos.y+1;     posList[7].dir = 1;     posList[7].var = visited[pos.x+0][pos.y+1];
    }
    else if (pos.dir == 6)
    {// 7点方向
        posList[0].x = pos.x-1;     posList[0].y = pos.y+0;     posList[0].dir = 3;     posList[0].var = visited[pos.x-1][pos.y+0];
        posList[1].x = pos.x-1;     posList[1].y = pos.y-1;     posList[1].dir = 4;     posList[1].var = visited[pos.x-1][pos.y-1];
        posList[2].x = pos.x+0;     posList[2].y = pos.y-1;     posList[2].dir = 5;     posList[2].var = visited[pos.x+0][pos.y-1];
        posList[3].x = pos.x+1;     posList[3].y = pos.y-1;     posList[3].dir = 6;     posList[3].var = visited[pos.x+1][pos.y-1];
        posList[4].x = pos.x+1;     posList[4].y = pos.y+0;     posList[4].dir = 7;     posList[4].var = visited[pos.x+1][pos.y+0];
        posList[5].x = pos.x+1;     posList[5].y = pos.y+1;     posList[5].dir = 8;     posList[5].var = visited[pos.x+1][pos.y+1];
        posList[6].x = pos.x+0;     posList[6].y = pos.y+1;     posList[6].dir = 1;     posList[6].var = visited[pos.x+0][pos.y+1];
        posList[7].x = pos.x-1;     posList[7].y = pos.y+1;     posList[7].dir = 2;     posList[7].var = visited[pos.x-1][pos.y+1];
    }
    else if (pos.dir == 7)
    {// 9点方向
        posList[0].x = pos.x-1;     posList[0].y = pos.y-1;     posList[0].dir = 4;     posList[0].var = visited[pos.x-1][pos.y-1];
        posList[1].x = pos.x+0;     posList[1].y = pos.y-1;     posList[1].dir = 5;     posList[1].var = visited[pos.x+0][pos.y-1];
        posList[2].x = pos.x+1;     posList[2].y = pos.y-1;     posList[2].dir = 6;     posList[2].var = visited[pos.x+1][pos.y-1];
        posList[3].x = pos.x+1;     posList[3].y = pos.y+0;     posList[3].dir = 7;     posList[3].var = visited[pos.x+1][pos.y+0];
        posList[4].x = pos.x+1;     posList[4].y = pos.y+1;     posList[4].dir = 8;     posList[4].var = visited[pos.x+1][pos.y+1];
        posList[5].x = pos.x+0;     posList[5].y = pos.y+1;     posList[5].dir = 1;     posList[5].var = visited[pos.x+0][pos.y+1];
        posList[6].x = pos.x-1;     posList[6].y = pos.y+1;     posList[6].dir = 2;     posList[6].var = visited[pos.x-1][pos.y+1];
        posList[7].x = pos.x-1;     posList[7].y = pos.y+0;     posList[7].dir = 3;     posList[7].var = visited[pos.x-1][pos.y+0];
    }
    else if (pos.dir == 8)
    {// 11点方向
        posList[0].x = pos.x+0;     posList[0].y = pos.y-1;     posList[0].dir = 5;     posList[0].var = visited[pos.x+0][pos.y-1];
        posList[1].x = pos.x+1;     posList[1].y = pos.y-1;     posList[1].dir = 6;     posList[1].var = visited[pos.x+1][pos.y-1];
        posList[2].x = pos.x+1;     posList[2].y = pos.y+0;     posList[2].dir = 7;     posList[2].var = visited[pos.x+1][pos.y+0];
        posList[3].x = pos.x+1;     posList[3].y = pos.y+1;     posList[3].dir = 8;     posList[3].var = visited[pos.x+1][pos.y+1];
        posList[4].x = pos.x+0;     posList[4].y = pos.y+1;     posList[4].dir = 1;     posList[4].var = visited[pos.x+0][pos.y+1];
        posList[5].x = pos.x-1;     posList[5].y = pos.y+1;     posList[5].dir = 2;     posList[5].var = visited[pos.x-1][pos.y+1];
        posList[6].x = pos.x-1;     posList[6].y = pos.y+0;     posList[6].dir = 3;     posList[6].var = visited[pos.x-1][pos.y+0];
        posList[7].x = pos.x-1;     posList[7].y = pos.y-1;     posList[7].dir = 4;     posList[7].var = visited[pos.x-1][pos.y-1];
    }
    else
    {// 数据错误
        return nextPos;
    }

    // 找到第一个有效的数据返回
    for (int i=0;i<8;i++)
    {
        if (posList[i].var == 1)
        {
            nextPos.x= posList[i].x;
            nextPos.y= posList[i].y;
            nextPos.dir= posList[i].dir;
            break;
        }
    }

    return nextPos;
}


// 得到所有列表内花样范围
int EmbData::getDataListRange(QList <QByteArray> *datList,double &minX,double &maxX,double &minY,double &maxY)
{
    double dx,dy;
    if (datList->size() <= 0)
    {
        return -1;
    }

    minX = S32_MAX;
    maxX = S32_MIN;
    minY = S32_MAX;
    maxY = S32_MIN;
    DataDs16FileHead *pHead = new DataDs16FileHead;

    for (int i = 0; i < datList->size(); i++)
    {
        // 文件头
        int size = datList->at(i).size();
        if (size <= (int)sizeof(DataDs16FileHead))
        {
            qDebug("ary%d data less then head size", i);
            continue;
        }

        int datasize = size - sizeof(DataDs16FileHead);
        int stepsize = datasize/sizeof(DsAbsItem);
        if (stepsize <= 0)
        {
            qDebug("dat data size err");
            continue;
        }

        memcpy(pHead,datList->at(i).data(),sizeof(DataDs16FileHead));

        qDebug() << "getDataListRange i =" << i
                 << ",anchorX=" << pHead->anchorX
                 << ",anchorY=" << pHead->anchorY
                 << ",beginX=" << pHead->beginX
                 << ",beginY=" << pHead->beginY
                    ;

        dx = pHead->beginX - m_pEmbDs16Head->beginX;
        dy = pHead->beginY - m_pEmbDs16Head->beginY;

        DsAbsItem * absDataPtr = (DsAbsItem *)(datList->at(i).data() + sizeof(DataDs16FileHead));
        // 数据转换
        for (int j = 0; j < stepsize; j++)
        {
            minX = qMin(minX, (absDataPtr->ax+dx));
            maxX = qMax(maxX, (absDataPtr->ax+dx));
            minY = qMin(minY, (absDataPtr->ay+dy));
            maxY = qMax(maxY, (absDataPtr->ay+dy));

            absDataPtr++;
        }
    }

    delete pHead;

    return 0;
}

//生成花样轮廓文件
// outlineStep: 针步(1mm~6mm)
// outlineZoom: 距边(1mm~20mm)
void EmbData::createPatternOutlineFile(int outlineStep,int outlineZoom,int outlineShape)
{
    int i,j;
    int rst = 0;
    int factor = 100;   //将针步数据缩小100倍，变成mm单位


    if (outlineStep < 1)    {outlineStep = 1;}      // 最小1mm 针步
    if (outlineStep > 6)    {outlineStep = 6;}      // 最大6mm 针步
    if (outlineZoom < 1)    {outlineZoom = 1;}      // 最小1mm 间距
    if (outlineZoom > 20)   {outlineZoom = 20;}     // 最大20mm 间距


    //扩充针步并求最大最小值
    qDebug() << "getDataListRange i =" << 0
             << ",anchorX=" << m_pEmbDs16Head->anchorX
             << ",anchorY=" << m_pEmbDs16Head->anchorY
             << ",beginX=" << m_pEmbDs16Head->beginX
             << ",beginY=" << m_pEmbDs16Head->beginY
                ;

    double minX,maxX,minY,maxY;
    rst = getDataListRange(&m_dataAbsList,minX,maxX,minY,maxY);     // 得到文件范围

    if (rst != 0)
    {
        return;
    }
    else
    {
        qDebug() << "getDataListRange minX=" << (int)(minX)/factor
                 << ",maxX=" << (int)(maxX)/factor
                 << ",minY=" << (int)(minY)/factor
                 << ",maxY=" << (int)(maxY)/factor
                 << ",Step=" << outlineStep
                 << ",Zoom=" << outlineZoom
                 << ",Shape=" << outlineShape
                    ;
    }

    int vectorH = (int)(maxX - minX)/factor + (outlineZoom * 2) + 10;     // 图形宽度+轮廓间距*2+边缘算法预留
    int vectorV = (int)(maxY - minY)/factor + (outlineZoom * 2) + 10;

    int basicH = outlineZoom + 5 - ((int)(minX)/factor);     // X基准
    int basicV = outlineZoom + 5 - ((int)(minY)/factor);     // Y基准

    QVector<QVector<char> > visited(vectorH, QVector<char>(vectorV,0));//数据点

    qDebug() << "getDataListRange vectorH=" << vectorH
             << ",vectorV=" << vectorV
             << ",basicH=" << basicH
             << ",basicV=" << basicV
                ;

    // 将坐标点添加到网格中，包括点与点连线上的点
    DataDs16FileHead *pHead = new DataDs16FileHead;
    for (i = 0; i < m_dataAbsList.size(); i++)
    {
        double dx,dy;
        int beginX,beginY,endX,endY;

        // 文件头
        const QByteArray & ary = m_dataAbsList.at(i);
        int size = ary.size();
        if (size <= (int)sizeof(DataDs16FileHead))
        {
            qDebug("ary%d data less then head size", i);
            continue;
        }

        int datasize = size - sizeof(DataDs16FileHead);
        int stepsize = datasize/sizeof(DsAbsItem);
        if (stepsize <= 0)
        {
            qDebug("dat data size err");
            continue;
        }

        memcpy(pHead, ary.data(), sizeof(DataDs16FileHead));
        dx = pHead->beginX - m_pEmbDs16Head->beginX;
        dy = pHead->beginY - m_pEmbDs16Head->beginY;

        // 填充点到网格
        DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
        DsAbsItem * absDataPtr = pData;

        beginX = (int)(absDataPtr->ax+dx)/factor + basicH;
        beginY = (int)(absDataPtr->ay+dy)/factor + basicV;

        if (i != 0)
        {// 将前一个花板最后一针和当前花板第一针连起来.
            PaintedLine(visited, beginX, beginY, endX, endY,outlineZoom,vectorH,vectorV);   // 在网格中绘制直线
        }

        for (j = 0; j < stepsize; j++)
        {
            absDataPtr++;
            if ((absDataPtr->ctrl != DSR_NULL) &&       	// 文件结束
                    (absDataPtr->ctrl != DSR_PAUSE) &&          // 暂停
                    (absDataPtr->ctrl != DATA_CUTTRD) &&        // 剪线
                    (absDataPtr->ctrl != DSR_ANGLE) &&          // 拐点
                    (absDataPtr->ctrl != DSR_CHGND) &&      	// 换色
                    (absDataPtr->ctrl != DSR_END) &&            // 结束码
                    (absDataPtr->ctrl != DSR_TOWELHIGH) &&      // 毛巾高度
                    1 )
            {
                endX = (int)(absDataPtr->ax+dx)/factor + basicH;
                endY = (int)(absDataPtr->ay+dy)/factor + basicV;

                PaintedLine(visited, beginX, beginY, endX, endY,outlineZoom,vectorH,vectorV);   // 在网格中绘制直线
                beginX = endX;
                beginY = endY;
            }
        }
    }
    delete pHead;

    QVector<OutLineItem> OutlinePos(vectorH*vectorV);// 轮廓数据点
    int finded = 0;

    // 寻找轮廓上第一个点
    for (j = 1; j < (vectorV-1); j++)
    {
        for (i = 1; i < (vectorH-1); i++)
        {
            if (visited[i][j] == 1)
            {
                finded = 1;             // 找到起始点
                OutlinePos[0].x = i;
                OutlinePos[0].y = j;
                OutlinePos[0].dir = 1;  // 第一针12点方向
                break;
            }
        }

        if (finded == 1)
        {
            break;
        }
    }

    if (finded == 0)
    {// 数据错误
        rst = -1;
        return;
    }

    //    qDebug() << "firstPos x=" << OutlinePos[0].x << ",y=" << OutlinePos[0].y;

    // 顺时针寻找外轮廓
    int lineIdx = 1;    // 索引
    for (lineIdx = 1; lineIdx < (vectorH*vectorV); lineIdx++)
    {
        OutlinePos[lineIdx] = FindNextPos(visited,OutlinePos[lineIdx-1]);
        if ((OutlinePos[lineIdx].x == OutlinePos[0].x) &&
                (OutlinePos[lineIdx].y == OutlinePos[0].y) &&
                1 )
        {// 起始点和终点重合,外轮廓曲线闭合,跳出循环
            lineIdx++;
            break;
        }
        else if ((OutlinePos[lineIdx].x == 0) &&
                 (OutlinePos[lineIdx].y == 0) &&
                 1 )
        {// 没有找到下一个点,查找失败,跳出循环
            rst = -1;
            break;
        }
    }

    if(rst != 0)
    {// 数据错误
        return;
    }

    /*
    for (i=0;i<lineIdx;i++)
    {// 打印原始轮廓数据
        qDebug() << "OutlinePos[" << i << "]=" << OutlinePos[i].x << "," << OutlinePos[i].y;
    }
    */

    //将坐标点加入到outLineArray中
    QByteArray outLineArray;
    outLineArray.clear();

    DsrStep dsrStep;
    memset(&dsrStep, 0, sizeof(DsrStep));

    int dsrMinX = S32_MAX;
    int dsrMaxX = S32_MIN;
    int dsrMinY = S32_MAX;
    int dsrMaxY = S32_MIN;

    for (i=0; i<=outlineStep; i++)
    {// 在轮廓数据后加上分割针步数量的针步,用来防止分割针步时溢出
        OutlinePos[lineIdx+i].x = OutlinePos[lineIdx-1].x;
        OutlinePos[lineIdx+i].y = OutlinePos[lineIdx-1].y;
    }

    //第一针插入0，0
    //    dsrStep.ctrl = DSR_EMB;
    //    outLineArray.append((char*)&dsrStep,sizeof(DsrStep));

    //将counterList坐标转换为DsrStep格式
    for(i = 0; i < (lineIdx+outlineStep);)
    {
        int ddx = ((OutlinePos[i+outlineStep].x - OutlinePos[i].x)) * factor;
        int ddy = ((OutlinePos[i+outlineStep].y - OutlinePos[i].y)) * factor;
        double tar = atan2(ddy,ddx);

        dsrStep.ctrl = DSR_EMB;
        dsrStep.dx = (OutlinePos[i].x - basicH) * factor;
        dsrStep.dy = (OutlinePos[i].y - basicV) * factor;
        dsrStep.dr = (tar * 10000+0.5*(tar>0?1:-1));

        outLineArray.append((char*)&dsrStep,sizeof(DsrStep));

        dsrMinX = qMin(dsrMinX, dsrStep.dx);
        dsrMaxX = qMax(dsrMaxX, dsrStep.dx);
        dsrMinY = qMin(dsrMinY, dsrStep.dy);
        dsrMaxY = qMax(dsrMaxY, dsrStep.dy);

        i += outlineStep;
    }

    //加入结束码
    DsrStep endDsr;
    memset(&endDsr, 0, sizeof(DsrStep));
    endDsr.ctrl = DATA_END_OLD;
    outLineArray.append((char*)&endDsr,sizeof(DsrStep));

    //生成文件头
    DsrHead dsrHead;
    memset(&dsrHead,0,sizeof(DsrHead));

    float ver = DSR_VERSION_5;
    dsrHead.verCode = *((DWORD*)(&ver));
    dsrHead.stitches = outLineArray.size()/sizeof(DsrStep);
    dsrHead.xyUnit = 1;
    dsrHead.rangePx = dsrMaxX;
    dsrHead.rangeNx = dsrMinX;
    dsrHead.rangePy = dsrMaxY;
    dsrHead.rangeNy = dsrMinY;
    dsrHead.anchorX = m_pEmbDs16Head->anchorX;
    dsrHead.anchorY = m_pEmbDs16Head->anchorY;
    dsrHead.startX = m_pEmbDs16Head->beginX;
    dsrHead.startY = m_pEmbDs16Head->beginY;
    dsrHead.begWorkHead = 0;
    dsrHead.dataBegin = sizeof(DsrHead);

    outLineArray.insert(0,(char*)&dsrHead,sizeof(DsrHead));

    QString path = m_filePath + "-outLine.dsr";
    QFile::remove(path);
    QString pathDs16 = m_filePath + "-outLine.dsr.ds16";
    QFile::remove(pathDs16);
    QString pathFcg = m_filePath + "-outLine.dsr.fcg";
    QFile::remove(pathFcg);
    QString pathPng = m_filePath + "-outLine.dsr.preview.png";
    QFile::remove(pathPng);

    QFile wrfile(path);
    if(!wrfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        return;
    }
    else
    {
        wrfile.write(outLineArray);
        wrfile.close();
    }
}

//分割针步并添加
void EmbData::splitBorderStitchAndAdd(QByteArray &dat, int bx, int by, int ex, int ey)
{
    s16 XDir = 1;//x坐标方向是否取反
    s16 YDir = 1;//y坐标方向是否取反

    s16 outlineStep = 4 * OUTLINESTEPFACTOR;//针步大小

    int cx = ex - bx;
    int cy = ey - by;

    int flag = 0;
    if(abs(cx) > sqrt(S32_MAX/2) || abs(cy) > sqrt(S32_MAX/2))
    {
        cx /= 100;//除以100防止cx的平方超出int的最大范围
        cy /= 100;//除以100防止cx的平方超出int的最大范围
        flag = 1;
    }

    //判断xy为正数还是负数
    s16 facX = 0;
    s16 facY = 0;
    if(cx < 0){facX = -1;}
    if(cy < 0){facY = -1;}
    if(cx > 0){facX = 1;}
    if(cy > 0){facY = 1;}

    int len = 0;

    if(flag == 1)
    {
        len = (sqrt(cx*cx + cy*cy))*100;//针步长度(上边除了100，所以这里乘以100)
    }
    else
    {
        len = sqrt(cx*cx + cy*cy);
    }

    int splitStepNum = len / outlineStep;//针步分为几小针步

    Ds16Item ds16Item;
    memset((char*)&ds16Item,0,sizeof(Ds16Item));

    //不为0通过合成算xy
    if(facX != 0 && facY != 0)
    {
        int step = sqrt(outlineStep * outlineStep / 2);
        outlineStep = step;
    }

    for(int i = 0 ; i < splitStepNum; i++)
    {
        ds16Item.ctrl = DATA_EMB;
        ds16Item.attr = 0;
        ds16Item.dx = outlineStep * facX * XDir;
        ds16Item.dy = outlineStep * facY * YDir;
        dat.append((char*)(&ds16Item), sizeof(Ds16Item));
    }

    int lastStep = len % outlineStep;//最后剩余针步大小

    //不为0通过合成算xy
    if(facX != 0 && facY != 0)
    {
        int lstep = sqrt(lastStep * lastStep / 2);
        lastStep = lstep;
    }

    if(lastStep > 0)
    {
        ds16Item.ctrl = DATA_EMB;
        ds16Item.attr = 0;
        ds16Item.dx = lastStep * facX * XDir;
        ds16Item.dy = lastStep * facY * YDir;
        dat.append((char*)(&ds16Item), sizeof(Ds16Item));
    }
}

//此函数转换传入的绝对坐标值，是否取镜像及反复时数据之间的间距
void EmbData::convertAbsDat(QByteArray &dat, int mirror)
{
    //无镜像、xy间距、角度旋转、缩放比例都为0时数据无需转换
    if(mirror == 0 &&
            m_spaceX == 0 &&
            m_spaceY == 0 )
    {
        return;
    }

    int size = dat.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("data less then head size");
        return;
    }
    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(dat.data());
    memset(pDsHead->switchTable,0,COLORTABLE_NUM);//色序表全部置零

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("dat dataBegin err");
        return;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("dat data size err");
        return;
    }
    DsAbsItem * pData = (DsAbsItem *)(dat.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;
    //--------

    //镜像数值不为0---开始
    // mirror 0, 无镜像; 1, 水平镜像; 2, 垂直镜像; 3, 水平和垂直镜像
    int mirrorx = 1;
    int mirrory = 1;
    int mirrorr = 1;

    if(mirror == 1 || mirror == 3)
    {
        mirrorx = -1;
        mirrorr = -1;
    }
    if(mirror == 2 || mirror == 3)
    {
        mirrory = -1;
        mirrorr = -1;
    }

    // 镜像文件头转换
    if(mirror != 0)
    {
        pDsHead->beginX = pDsHead->beginX * mirrorx;
        pDsHead->beginY = pDsHead->beginY * mirrory;
    }

    // 镜像或列表间距不为0
    if(mirror != 0 || m_spaceX != 0 || m_spaceY != 0)
    {
        //图形先居中，起始点在加上偏移
        int centerx = (m_maxX + m_minX)/2;
        int centery = (m_maxY + m_minY)/2;

        int rx = (pDsHead->beginX - centerx) * mirrorx;
        int ry = (pDsHead->beginY - centery) * mirrory;

        int beginx = rx + centerx;
        int beginy = ry + centery;

        //用下面两行代码，否则反复方式为Y轴对称或XY对称时不对
        pDsHead->beginX = beginx + m_spaceX;
        pDsHead->beginY = beginy + m_spaceY;
    }
    //镜像数值不为0---结束

    absDataPtr = pData;

    //镜像有变换时运动步才转换
    double dx, dy, dr;

    if(mirror != 0)
    {
        for (int i = 0; i < stepsize; i++)
        {
            // 读入一个针步数据
            dx = absDataPtr->ax;
            dy = absDataPtr->ay;
            dr = absDataPtr->ar;

            //镜像不为0
            if(mirror != 0)
            {
                dx = dx * mirrorx;
                dy = dy * mirrory;
                dr = dr * mirrorr;
            }

            absDataPtr->ax = dx;
            absDataPtr->ay = dy;
            absDataPtr->ar = dr;

            absDataPtr++;
        }
    }

    return;
}

QList<QByteArray> EmbData::getDataList(QString name)
{
    QList<QByteArray> dataList;
    dataList.clear();

    QString fileName = name;
    if(fileName.isEmpty())
    {
        return dataList;
    }

    QFile readFile(fileName);
    if(!readFile.open(QIODevice::ReadOnly))
    {
        return dataList;
    }

    QByteArray allary = readFile.readAll();

    int datasize = allary.size();
    if(datasize <= 0)
    {
        return dataList;
    }

    CombHead * pCombHead = (CombHead *)(allary.data());
    int fileCount = pCombHead->totalFilesNum;  //总的文件数

    if(fileCount <= 0)
    {
        return dataList;
    }

    //将数据存放到列表中
    int index = sizeof(CombHead);
    for(int i = 0 ; i < fileCount ; i++)
    {
        QByteArray oneFileData;
        oneFileData.clear();

        //得到每个文件数据长度
        int fileSize = pCombHead->fileByte[i];

        //得到每个文件的数据
        oneFileData.append(allary.mid(index,fileSize));

        //        int aa = onefiledata.size();
        index = index + fileSize;

        DataDs16FileHead * pDsHead = (DataDs16FileHead *)(oneFileData.data());

        // 添加文件头
        pDsHead->beginX = pDsHead->beginX + m_spaceX;
        pDsHead->beginY = pDsHead->beginY + m_spaceY;

        dataList.append(oneFileData);
    }

    readFile.close();

    return dataList;
}

//生成DS16数据
int EmbData::createEmbDs16FromAbs()
{
#if(0)
    QString ds16FilePath = m_filePath + ".ds16";
    QFile file(ds16FilePath);

    if(file.exists())//存在ds16文件
    {
        if(!file.open(QIODevice::ReadOnly))
        {
            qDebug() << "open file fail when read, path =" << m_filePath;
            return -1;
        }

        m_embDs16Data = file.readAll();
        file.close();

        if(m_embDs16Data.size() <= 0)
        {
            return -1;
        }

        memcpy(m_pEmbDs16Head, m_embDs16Data.data(), sizeof(DataDs16FileHead));   // 文件名称

        m_minX = m_pEmbDs16Head->minX;
        m_maxX = m_pEmbDs16Head->maxX;
        m_minY = m_pEmbDs16Head->minY;
        m_maxY = m_pEmbDs16Head->maxY;
        m_beginX = m_pEmbDs16Head->beginX;
        m_beginY = m_pEmbDs16Head->beginY;

        m_editedflag = 0;

        return 0;
    }
#endif

    if (m_editedflag != 0)
    {
        m_minX = S32_MAX;
        m_maxX = S32_MIN;
        m_minY = S32_MAX;
        m_maxY = S32_MIN;

        int ptnum = m_dataAbsList.size();
        m_embDs16Data.clear();
        m_embDatEndList.clear();

        QString name;

        QByteArray tgtdsdat;
        tgtdsdat.clear();

        u8 ctrlByte;
        u8 attrByte;
        WORD actionWord;	//附加动作
        s32 dx, dy, dr;//相对
        u16 len;
        double ax, ay, ar;//绝对
        int actx, acty, actr;
        int ddx, ddy,ddr;
        double x1,y1,x2,y2;
        x1 = y1 = x2 = y2 = 0;

        int beginx, beginy,beginr;
        u8 workHead = 0;
        int minx, miny, maxx, maxy;
        int colornum = 1;// 颜色数
        int towelHighNum = 0;
        int jumpNeedleNum = 0;//跳针数
        int first = 1;//第一个图元的第一针
        actx = 0;
        acty = 0;
        actr =0;
        beginx = 0;
        beginy = 0;
        beginr = 0;
        double totalR = 0;//累加的绝对角度

        int totalstepsize = 0;
        memset(m_pEmbDs16Head,0,sizeof(DataDs16FileHead));

        for (int i = 0; i < ptnum; i++)
        {
            const QByteArray & ary = m_dataAbsList.at(i);
            int size = ary.size();
            if (size <= (int)sizeof(DataDs16FileHead))
            {
                qDebug("ary%d data less then head size", i);
                continue;   // 下一个
            }
            DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
            //dsr,dst的中间数据
            workHead = pDsHead->begHead;

            //offsetEn的处理已经在dsr，dst转中间数据时处理
            m_enFlag = pDsHead->offsetEn;  //发给主控的ds16数据 offsetEn  =  存在dsr，dst中间数据 offsetEn
            m_offsetX = pDsHead->offsetX;
            m_offsetY = pDsHead->offsetY;

            int datasize = size - sizeof(DataDs16FileHead);
            if (datasize <= 0)
            {
                qDebug("absdat dataBegin err");
                return -1;
            }
            int stepsize = datasize/sizeof(DsAbsItem);
            if (stepsize <= 0)
            {
                qDebug("absdat data size err");
                return -1;
            }
            DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
            DsAbsItem * absDataPtr = pData;  //中间数据针步

            // 文件名称
            QString str = QString::fromLocal8Bit(pDsHead->fileName);
            name = str;
            //str.sprintf("%s", pDsHead->fileName);
            //name += " ";
            //name += str;

            pDsHead->beginX /= m_dsDataStepUnit;
            pDsHead->beginY /= m_dsDataStepUnit;

            //花样拼接是起始点间的间距
            int begx = pDsHead->beginX;
            int begy = pDsHead->beginY;

            minx = begx;
            maxx = begx;
            miny = begy;
            maxy = begy;

            // 数据区
            for (int j = 0; j < stepsize; j++)
            {
                Ds16Item ds16Item;
                memset(&ds16Item,0,sizeof(Ds16Item));//清空ds16针步

                if(i != 0 && j == 0)//反复时非第一个花样第一针应是偏移
                {
                    // 添加偏移
                    ctrlByte = DATA_OFFSET;
                }
                else
                {
                    ctrlByte = absDataPtr->ctrl;
                }

                attrByte = absDataPtr->attr;//绝对数据的属性字节
                actionWord = absDataPtr->action;

                absDataPtr->ax /= m_dsDataStepUnit;
                absDataPtr->ay /= m_dsDataStepUnit;

                ax = absDataPtr->ax+pDsHead->beginX;//绝对数据的X位置 + 起始点
                ay = absDataPtr->ay+pDsHead->beginY;
                ar = absDataPtr->ar;

                // 轮廓
                if (minx > ax) { minx = ax; }
                if (maxx < ax) { maxx = ax; }
                if (miny > ay) { miny = ay; }
                if (maxy < ay) { maxy = ay; }

                if (first != 0)//first = 1第一个图元的第一针
                {
                    beginx = pDsHead->beginX;
                    beginy = pDsHead->beginY;
                    beginr = ar;
                    actx = pDsHead->beginX;
                    acty = pDsHead->beginY;
                    actr = beginr;

                    ddx = absDataPtr->ax;
                    ddy = absDataPtr->ay;
                    //让ddr等于0，因为在datafiledsr中将beginR置为0而非第一针的角度，所以不应该用 absDataPtr->ar - pDsHead->beginR
                    //如果beginR等于第一针的角度，那么第一针的ddr就应该是0
                    ddr = 0;

                    //过滤掉空针
                    if(ddx == 0 && ddy == 0)
                    {
                        actx += ddx;
                        acty += ddy;
                        actr += ddr;
                        absDataPtr++;
                        first = 0;//第一个图元的第一针

                        continue;
                    }
                }
                else
                {
                    ddx = ax - actx;//计算相对位置
                    ddy = ay - acty;
                    ddr = ar - actr;
                }

                if( ctrlByte == DATA_END    ||
                        ctrlByte == DATA_PAUSE  ||
                        ctrlByte == DATA_CHGND  ||
                        ctrlByte == DATA_CUTTRD ||
                        ctrlByte == DATA_ANGLE  ||
                        ctrlByte == DATA_TOWELHIGH   ||
                        0 )
                {
                    ddx = 0;
                    ddy = 0;
                    ddr = 0;
                }

                dx = ddx;//保存相对位置
                dy = ddy;
                dr = ddr;

                actx += ddx;//记录绝对位置
                acty += ddy;
                actr += ddr;

                while (dr < -PI10000)
                {
                    dr += PI20000;
                }
                while (dr > PI10000)
                {
                    dr -= PI20000;
                }

                //过滤掉运针空针
                if(ddx== 0 && ddy == 0 && ddr == 0 && ctrlByte == DATA_EMB && ((actionWord & 0x20) == 0))
                {
                    absDataPtr++;
                    qDebug()<<"This is a empty needle"<<j<<ddr;
                    continue;
                }

                if (ctrlByte == DATA_END || ctrlByte == DATA_NULL)
                {
                    if (i == ptnum - 1)     // 最后一个图
                    {
                        dx = dy = dr = len = 0;
                        // 增加剪线
                        ds16Item.ctrl = DATA_CUTTRD;
                        ds16Item.attr = 0;
                        ds16Item.action[0] = 0;
                        ds16Item.action[1] = 0;
                        ds16Item.dx = dx;
                        ds16Item.dy = dy;
                        ds16Item.dr = dr;
                        ds16Item.len = len;
                        memset(ds16Item.rev,0,sizeof(ds16Item.rev));

                        tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));
                        totalstepsize++;
                    }
                    else
                    {
                        ctrlByte = DATA_CUTTRD;     // 改为剪线
                    }
                }

                //如果dx或dy数值太大时，平方会超出double范围，所以先都除以100再乘以10000
                double xyLen = sqrt((dx/100.0*dx/100.0)*10000.0+ (dy/100.0*dy/100.0)*10000.0);
                double maxStep = m_convertSkipStepSize;//参数
                double splitVal = 0;//跳针针步大小
                int result = 0;//分为几步
                if(xyLen >= maxStep || dx > S16_MAX || dx < S16_MIN || dy > S16_MAX || dy < S16_MIN)
                {
                    s16 addx,addy;
                    double tremainder =fmod(xyLen, m_jumpStepSize);//取余
                    result = xyLen/m_jumpStepSize;
                    splitVal = m_jumpStepSize;
                    x1 = ax;
                    y1 = ay;
                    x2 = ax;
                    y2 = ay;
                    if(j != 0)
                    {
                        absDataPtr--;
                        x1 = absDataPtr->ax+begx;
                        y1 = absDataPtr->ay+begy;
                        absDataPtr++;
                    }

                    if(i != 0 || (i == 0 && j == 0))
                    {
                        x2 += dx;
                        y2 += dy;
                    }
                    s16 stepNum = result;
                    if(tremainder != 0)
                    {
                        stepNum += 1;
                    }
                    double k = (y2-y1)/(x2-x1);
                    double r = atan(k);
                    double stepX = 0;
                    double stepY = 0;
                    double stepDr = 0;
                    addx = 0;
                    addy = 0;

                    for(int m = 0; m < stepNum; m++)//还有不能整分的一步
                    {
                        stepX = 0;
                        stepY = 0;
                        stepDr = 0;
                        memset(&ds16Item,0,sizeof(Ds16Item));//初始化结构体

                        if(m == stepNum-1 && tremainder > 0)//最后一步
                        {
                            splitVal = tremainder;//不平分
                        }
                        stepX = splitVal * cos(r);
                        stepY = splitVal * sin(r);

                        //stepX = cos(r) * splitVal;
                        if((dx < 0 && stepX > 0) || (dx > 0 && stepX < 0))
                        {
                            stepX = 0 - stepX;
                        }

                        //stepY = sin(r) * splitVal;
                        if((dy < 0 && stepY > 0) || (dy > 0 && stepY < 0))
                        {
                            stepY = 0 - stepY;
                        }

                        //绣花针步,大针步转换为跳针
                        if(ctrlByte == DATA_EMB)//功能码等于绣花数据
                        {
                            if(m == stepNum - 1)//等于最后一针的时候
                            {
                                ds16Item.ctrl = ctrlByte;
                            }
                            else
                            {
                                ds16Item.ctrl = DATA_JUMP;//跳针
                            }
                        }
                        else
                        {
                            ds16Item.ctrl = ctrlByte;
                        }
                        if(m == 0)
                        {
                            stepDr = dr;
                        }
                        len = sqrt(stepX*stepX + stepY*stepY);
                        ds16Item.attr = attrByte;
                        ds16Item.action[0] = 0;
                        ds16Item.action[1] = 0;
                        ds16Item.dx = qRound(stepX);//四舍五入
                        ds16Item.dy = qRound(stepY);

                        if (m == stepNum-1)
                        {// 最后一针,消除累计误差
                            ds16Item.dx = dx - addx;
                            ds16Item.dy = dy - addy;
                        }
                        else
                        {
                            addx += ds16Item.dx;
                            addy += ds16Item.dy;
                        }

                        len = sqrt(ds16Item.dx*ds16Item.dx + ds16Item.dy*ds16Item.dy);
                        ds16Item.dr = stepDr;
                        ds16Item.len = len;
                        memset(ds16Item.rev,0,sizeof(ds16Item.rev));
                        tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));
                        totalstepsize++;
                    }
                }
                else
                {
                    len = sqrt(dx*dx + dy*dy);

                    ds16Item.ctrl = ctrlByte;
                    ds16Item.attr = attrByte;

                    memcpy(ds16Item.action,&actionWord,sizeof(actionWord));

                    ds16Item.dx = dx;
                    ds16Item.dy = dy;
                    ds16Item.dr = dr;
                    ds16Item.len = len;
                    memset(ds16Item.rev,0,sizeof(ds16Item.rev));
                    tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));//ds16针步
                    totalstepsize++;
                }

                if(i != 0 && j == 0)//反复时非第一个花样第一针改为偏移后再加换色码和一针正常针步
                {
                    // 添加换色
                    memset(&ds16Item,0,sizeof(Ds16Item));
                    ds16Item.ctrl = DATA_CHGND;
                    tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));
                    totalstepsize++;
                    colornum++;

                    // 添加第一针针步
                    memset(&ds16Item,0,sizeof(Ds16Item));
                    ds16Item.ctrl = absDataPtr->ctrl;
                    tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));
                    totalstepsize++;
                }

                //                if(totalstepsize >= 0 && totalstepsize <= 100)
                //                {
                //                    qDebug()<<"absDataPtr.ar"<<absDataPtr->ar<<"ds16Item.dr"<<ds16Item.dr;
                //                }

                if (ctrlByte == DATA_CHGND)
                {
                    colornum++;
                }

                if (ctrlByte == DATA_TOWELHIGH)
                {
                    towelHighNum++;
                }

                if (ctrlByte == DATA_JUMP)
                {
                    jumpNeedleNum++;//跳针总数加1
                }

                totalR += ds16Item.dr;

                absDataPtr++;
                first = 0;//第一针

                x1 = ax;
                y1 = ay;
            }

            // 添加色序表
            int cidx, cnum;
            cnum = colornum;
            if (cnum > EMB_BF_SW_ND)
            {
                cnum = EMB_BF_SW_ND;
            }

            cidx = m_pEmbDs16Head->colorNum;
            if (cidx < 0)
            {
                cidx = 0;
            }
            if (cidx > EMB_BF_SW_ND)
            {
                cidx = EMB_BF_SW_ND;
            }
            if (cidx + cnum > EMB_BF_SW_ND)
            {
                cnum = EMB_BF_SW_ND - cidx;
            }

            if(i != 0)//反复时非第一个花样后的偏移后的换色码色序和第一图元的第一个换色码相同
            {
                cidx++;
                memcpy(&(m_pEmbDs16Head->switchTable[cidx]), pDsHead->switchTable, 1);
            }
            memcpy(&(m_pEmbDs16Head->switchTable[cidx]), pDsHead->switchTable, cnum);

            if (m_minX > minx) { m_minX = minx; }
            if (m_minX > maxx) { m_minX = maxx; }
            if (m_maxX < minx) { m_maxX = minx; }
            if (m_maxX < maxx) { m_maxX = maxx; }
            if (m_minY > miny) { m_minY = miny; }
            if (m_minY > maxy) { m_minY = maxy; }
            if (m_maxY < miny) { m_maxY = miny; }
            if (m_maxY < maxy) { m_maxY = maxy; }

            m_pEmbDs16Head->colorNum = cnum;          // 颜色数增加
            m_embDatEndList.append(totalstepsize);
        }

        // 针数
        int newstepnum = tgtdsdat.size() / sizeof(Ds16Item);

        if (newstepnum > 0)
        {
            // 修改文件头
            int namelen = name.size();
            if (namelen > HEAD_NAME_STR_LEN)
            {
                namelen = HEAD_NAME_STR_LEN;
            }

            QByteArray array = name.toLocal8Bit().data();
            int asize = array.length();
            memcpy(m_pEmbDs16Head->fileName, array, asize);   // 文件名称
            m_pEmbDs16Head->dataSize = newstepnum*sizeof(Ds16Item);    // 数据字节数
            m_pEmbDs16Head->itemNums = newstepnum;                    // 数据项个数
            m_pEmbDs16Head->bytesPerItem = sizeof(Ds16Item);           // 每项占的字节数
            m_pEmbDs16Head->bytesPerBlk = MAX_EXDP_LEN;               // 数据内容划分块大小
            m_pEmbDs16Head->dataChecksum = calcCheckSum32((u8 *)(tgtdsdat.data()) , m_pEmbDs16Head->dataSize);	// 数据累加校验和
            m_pEmbDs16Head->checkCrc = calcCrc16((u8 *)(m_pEmbDs16Head), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验，（6个字段分别为：文件名称，字节数，项个数，每项字节数，每块字节数，数据累加和的CRC校验值）
            m_pEmbDs16Head->begHead = workHead;//花样当前的工作机头(发给下位机的ds16数据)   //workHead是中间数据
            m_pEmbDs16Head->fileid = m_pEmbDs16Head->checkCrc;

            m_pEmbDs16Head->anchorX = beginx;                  // 定位点坐标X
            m_pEmbDs16Head->anchorY = beginy;                  // 定位点坐标Y, 设置为0，作为基准
            m_pEmbDs16Head->beginX = beginx;              // 数据起点坐标X
            m_pEmbDs16Head->beginY = beginy;              // 数据起点坐标Y
            m_pEmbDs16Head->beginR = beginr;              // 数据起点坐标R  //-rq
            m_pEmbDs16Head->minX = m_minX;
            m_pEmbDs16Head->maxX = m_maxX;
            m_pEmbDs16Head->minY = m_minY;
            m_pEmbDs16Head->maxY = m_maxY;                // 轮廓范围，使用重新计算之后的值

            m_pEmbDs16Head->offsetEn = m_enFlag;
            m_pEmbDs16Head->offsetX = m_offsetX;//ds16头文件的偏移点XY    赋值
            m_pEmbDs16Head->offsetY = m_offsetY;

            m_pEmbDs16Head->jumpNeedleNum = jumpNeedleNum;//跳针数
            m_pEmbDs16Head->towelHighNum = towelHighNum;//毛巾高度码数目
            m_beginX = beginx;
            m_beginY = beginy;
            m_beginR = beginr;
            // 添加文件头
            m_embDs16Data.append((char*)m_pEmbDs16Head, sizeof(DataDs16FileHead));//ds16头文件存在ds16中
            // 添加文件数据
            m_embDs16Data.append(tgtdsdat);
        }

#if(1)
        //保存成ds16文件
        QString ds16FilePath = m_filePath + ".ds16";
        QFile file(ds16FilePath);

        if(file.exists())//存在ds16文件
        {
            QFile::remove(ds16FilePath);
        }

        if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        {
            qDebug() << "open file fail when wirte, path =" << m_filePath;
            return -1;
        }
        else
        {
            file.write(m_embDs16Data);
#ifdef Q_OS_LINUX
            system("sync");
#endif
            file.close();
        }
#endif
    }

    m_editedflag = 0;

    return 0;
}

int EmbData::reCalcDataChecksum()
{
    return 0;
}

QByteArray EmbData::intTo2ByteArray(s16 value)
{
    QByteArray ba;
    ba.resize(2);
    ba[0] = (uchar)(0x000000ff & value);
    ba[1] = (uchar)((0x0000ff00 & value) >> 8);
    return ba;
}

//绘制针数索引的跟踪笔
void EmbData::drawNeedleIdxPen(int x, int y, QPainter &painter)
{
    //贴图的xy和画笔的xy值相同
    m_penX = x;
    m_penY = y;

    m_penPix = m_canvas.copy(x-20,y-30,40,40);//复制画笔区域未绘制笔之前的图像

    QPen pen;
    QColor color;

    //绘制深灰色画笔
    pen.setWidth(2);
    color.setRgb(60,60,60);//深灰色
    pen.setColor(color);
    painter.setPen(pen);

    painter.drawLine(x-4, y-28, x-4, y-8);//画左"|"
    painter.drawLine(x+4, y-28, x+4, y-8); //画右"|"
    painter.drawEllipse(x-1, y-10, 2, 2);//画中心"°"
    painter.drawLine(x-4, y-8, x, y);//画左"\"(笔尖)
    painter.drawLine(x+4, y-8, x, y); //画右"/"(笔尖)

    //绘制深红色画笔
    pen.setWidth(1);
    color.setRgb(174,60,64);//深红色
    pen.setColor(color);
    painter.setPen(pen);

    painter.drawLine(x-3, y-28, x-3, y-8);//画左"|"
    painter.drawLine(x+5, y-28, x+5, y-8); //画右"|"
    painter.drawEllipse(x-2, y-12, 3, 3);//画中心"°"
    painter.drawLine(x-3, y-8, x, y);//画左"\"(笔尖)
    painter.drawLine(x+5, y-8, x, y); //画右"/"(笔尖)
}

//擦除针数索引的跟踪笔
void EmbData::eraseNeedleIdxPen(QPainter &painter)
{
    //贴图的xy和画笔的xy值相同
    painter.drawPixmap(m_penX-20,m_penY-30,m_penPix);
}

//绘制散珠或亮片
void EmbData::drawBeadOrSequin(QPainter &painter,u8 action, int bx, int by, int ex, int ey, QRgb beadColor, s16 grey)
{
    int cr ;

    //if(gradientFlag == 1)//色序设定界面的预览图不带渐变效果，也不画散珠和亮片
    {
        if((action >= 0x01) && (action <= 0x0F))//亮片
        {
            s16 idx = action - 1;
            s16 size = sizeof(m_sequinColorTable) / sizeof(s16);
            QPen npen;

            cr = BEADRADIUS / m_factor;

            if(grey != COLOR_GREY)//非灰图
            {
                if(idx < size)
                {
                    if(m_sequinColorTable[idx] != -1)
                    {
                        npen.setColor(m_pColor[m_sequinColorTable[idx]]);
                    }
                    else
                    {
                        npen.setColor(m_pColor[idx]);
                    }
                }
                else
                {
                    npen.setColor(beadColor);
                }
            }
            else
            {
                npen.setColor(beadColor);
            }

            npen.setWidth(2);
            painter.setPen(npen);
            painter.drawEllipse(ex-cr,ey-cr,cr*2,cr*2);
            painter.drawEllipse((ex-cr)+cr/2+cr*0.3,(ey-cr)+cr/2+cr*0.3,cr*0.7,cr*0.7);
        }
        if((action >= 0x11) && (action <= 0x1F))//散珠
        {
            s16 idx = action - 0x11;
            s16 size = sizeof(m_beadColorTable) / sizeof(s16);
            QPen npen;

            cr = sqrt((bx-ex)*(bx-ex) + (by-ey)*(by-ey)) / 2.2 ;        // 动态显示散珠的直径
            if (cr < 2)
            {
                cr = 2;
            }

            if(grey != COLOR_GREY)//非灰图
            {
                if(idx < size)
                {
                    if(m_beadColorTable[idx] != -1)
                    {
                        npen.setColor(m_pColor[m_beadColorTable[idx]]);
                    }
                    else
                    {
                        npen.setColor(m_pColor[idx]);
                    }
                }
                else
                {
                    npen.setColor(beadColor);
                }
            }
            else
            {
                npen.setColor(beadColor);
            }

            npen.setWidth(cr);
            painter.setPen(npen);
            painter.drawEllipse((bx+ex)/2-(cr*0.626),(by+ey)/2-(cr*0.626),cr*1.25,cr*1.25);
            npen.setWidth(2);
            painter.setPen(npen);
        }
    }
}

//设置视图尺寸(透明背景)
int EmbData::setViewInfo(int width, int height)
{
    //    if (m_viewWidth != width ||
    //        m_viewHight != height)
    {
        if (width <= EMB_PREVIEW_SIDE*2 || height <= EMB_PREVIEW_SIDE*2)
        {
            return -1;
        }
        m_viewWidth = width;
        m_viewHight = height;
        m_canvas = QPixmap(m_viewWidth, m_viewHight);
        m_canvas.fill(Qt::transparent);//用透明色填充
        //memset(m_canvas.bits(), 0x00, m_canvas.byteCount());
    }
    return 0;
}

//设置视图(带背景图片背景)
void EmbData::setViewInfo(QPixmap pix)
{
    m_canvas = pix;
}

//重新重置ds16数据(换色点击取消后数据会变为单个图元的原数据，
//若图形经过变换数据会不对，主界面保存了最后的数据，
//若点击换色并取消后恢复为主界面最后保存的数据即可)
void EmbData::reSetEmbData(QByteArray ary)
{
    if(ary.size() <= 0)
    {
        return;
    }
    m_embDs16Data.clear();
    m_embDs16Data.append(ary);
    //文件头也恢复为默认
    memcpy(m_pEmbDs16Head, m_embDs16Data.data(), sizeof(DataDs16FileHead));   // 文件名称
}

void EmbData::reSetEmbDataRange(int maxX, int minX, int maxY, int minY)
{
    m_maxX = maxX;
    m_minX = minX;
    m_maxY = maxY;
    m_minY = minY;
}

//重置数据
void EmbData::setEmbData(int redraw)
{
    createDispFromEmbDs16Dat(m_embDs16Data);
    if (redraw != 0)
    {
        drawImageByDispFile(-1);
    }
}

void EmbData::setDispMode(EmbData::DISP_MODE dispmode, int redraw, int gradientFlag)
{
    m_dispMode = dispmode;
    if(redraw != 0)
    {
        drawImageByDispFile(gradientFlag);
    }
}

void EmbData::setDrawMode(EmbData::DRAW_MODE drawmode)
{
    m_drawMode = drawmode;
}

void EmbData::setGreyAreaRange(int begin, int end)
{
    m_greyColorBeg = begin;
    m_greyColorEnd = end;
}

//设置区域显示参数
void EmbData::setDispAreaRange(int begin, int end, int redraw)
{
    m_showColorBeg = begin;
    m_showColorEnd = end;

    if (redraw != 0)
    {
        drawImageByDispFile(-1);
    }
}

//设置进度显示数据
void EmbData::setExecIndex(int index)
{
    m_stitchIndex = index;

    if (m_dispMode == DISP_EXECING)
    {
        drawImageByDispFile(-1);
    }
}

void EmbData::reDraw()
{
    drawImageByDispFile(-1);
}

//创建显示用的数据（为了快速显示）
int EmbData::createDispFromEmbDs16Dat(QByteArray &ds16dat)
{
    DispItem dispItem;
    m_dispDat.clear();//显示绘图用的数据（需要转换）

    //    DsAbsItem absItem;//用于轮廓提取的绝对坐标值
    //    m_ds16ToAbsDat.clear();//用于轮廓提取的绝对坐标值

    m_stitchIndex = 0;
    m_dispIndex = 0;

    // ds16数据
    int size = ds16dat.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("16 data less then head size");
        return -1;
    }
    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ds16dat.data());
    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("dat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return -1;
    }

    Ds16Item * ds16DataPtr;
    Ds16Item * pData = (Ds16Item *)(ds16dat.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = pData;

    // 图形显示区域
    int width = m_canvas.width();//留4个像素的边
    int height = m_canvas.height();//留4个像素的边
    if (width <= EMB_PREVIEW_SIDE*2 || height <= EMB_PREVIEW_SIDE*2)
    {
        qDebug("preview img too small");
        return -1;
    }

    //留边(否则实时跟踪笔会画出界)
    int viewSide = EMB_PREVIEW_SIDE;
    if(m_drawMode == DRAW_PREVIEW)
    {
        viewSide = 20;//预览模式时整区域留20像素绘制(原色显示)
    }
    int dpminx = viewSide;
    int dpmaxx = width - viewSide;
    int dpminy = viewSide;
    int dpmaxy = height - viewSide;

    //1:1显示无需留边
    //    int dpminx = 0;
    //    int dpmaxx = width;
    //    int dpminy = 0;
    //    int dpmaxy = height;

    // 计算缩放系数
    double factor, temp;
    if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0)
    {
        return -1;
    }

    factor = (double)(fabs(m_maxX-m_minX)) / (dpmaxx - dpminx);      // 按框尺寸x计算的缩放系数
    temp =   (double)(fabs(m_maxY-m_minY)) / (dpmaxy - dpminy);      // 按框尺寸y计算的缩放系数

    if (temp >= factor)     // 使用较大的缩放系数
    {
        factor = temp;
    }

    m_factor = factor;

    // 计算显示参数，按照图形的实际位置显示（数据坐标零点对应图形中心）
    int dpx = (int)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX)/factor)/2);
    int dpy = (int)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2);

    // 显示花样图形
    u8 ctrlByte;
    u8 attrByte;
    int dx;
    int dy;
    int dr;
    int colorIdx;
    int oldcolor;

    double datposx, datposy, datposr;
    int curx, cury, prex, prey, curr;
    curx = cury = prex = prey = curr = 0;

    //用起始点绘制
    datposx = pDsHead->beginX;
    datposy = pDsHead->beginY;
    datposr = pDsHead->beginR;

    //    absItem.ctrl = 0;
    //    absItem.attr = 0;
    //    absItem.ax = datposx;
    //    absItem.ay = datposy;
    //    absItem.ar = 0;
    //m_ds16ToAbsDat.append((char*)(&absItem), sizeof(DsAbsItem));

    curx = (datposx) / factor + dpx;
    cury = (datposy) / factor + dpy;

    if (EMB_SHOWDIRX == -1)
    {
        curx = width - curx;
    }
    if (EMB_SHOWDIRY == -1)
    {
        cury = height - cury;
    }

    colorIdx = 0;
    oldcolor = -1;
    QRgb embcolor = 0;

    for (int i = 0; i < stepsize; i++)
    {
        prex = curx;
        prey = cury;

        // 读入一个针步数据
        ctrlByte = ds16DataPtr->ctrl;
        attrByte = ds16DataPtr->attr;
        dx = ds16DataPtr->dx;
        dy = ds16DataPtr->dy;
        dr = ds16DataPtr->dr;

        datposx += dx;
        datposy += dy;
        datposr += dr;

        //未经缩放的绝对坐标值，用于花样轮廓的提取
        //        absItem.ctrl = ctrlByte;
        //        absItem.attr = attrByte;
        //        absItem.ax = datposx;
        //        absItem.ay = datposy;
        //        absItem.ar = 0;
        //m_ds16ToAbsDat.append((char*)(&absItem), sizeof(DsAbsItem));

        curx = (datposx) / factor + dpx;
        cury = (datposy) / factor + dpy;

        if (EMB_SHOWDIRX == -1)
        {
            curx = width - curx;
        }
        if (EMB_SHOWDIRY == -1)
        {
            cury = height - cury;
        }
        if (oldcolor != colorIdx)
        {
            //int cidx = pDsHead->switchTable[colorIdx % EMB_BF_SW_ND];
            int nidx = pDsHead->switchTable[colorIdx];

            //将色序表的索引减去缝纫或冲孔对应的针杆起始数，为了使颜色与针杆设置的颜色一致
            //实际色序表不变
            if(nidx > EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM + SEW_NEEDLE_NUM +RIBBON_NEEDLE_NUM+TOWEL_NEEDLE_NUM+CHAIN_NEEDLE_NUM+COIL_NEEDLE_NUM+REV2_NEEDLE_NUM+SAWTOOTH_NEEDLE_NUM+REV3_NEEDLE_NUM)//激光针杆
            {
                nidx -= (EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM + SEW_NEEDLE_NUM +RIBBON_NEEDLE_NUM+TOWEL_NEEDLE_NUM+CHAIN_NEEDLE_NUM+COIL_NEEDLE_NUM+REV2_NEEDLE_NUM+SAWTOOTH_NEEDLE_NUM+REV3_NEEDLE_NUM);
            }
            if(nidx > EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM + SEW_NEEDLE_NUM +RIBBON_NEEDLE_NUM+TOWEL_NEEDLE_NUM+CHAIN_NEEDLE_NUM+COIL_NEEDLE_NUM+REV2_NEEDLE_NUM)//锯齿针杆
            {
                nidx -= (EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM + SEW_NEEDLE_NUM +RIBBON_NEEDLE_NUM+TOWEL_NEEDLE_NUM+CHAIN_NEEDLE_NUM+COIL_NEEDLE_NUM+REV2_NEEDLE_NUM);
            }
            if(nidx > EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM + SEW_NEEDLE_NUM +RIBBON_NEEDLE_NUM+TOWEL_NEEDLE_NUM+CHAIN_NEEDLE_NUM)//缠绕针杆
            {
                nidx -= (EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM + SEW_NEEDLE_NUM +RIBBON_NEEDLE_NUM+TOWEL_NEEDLE_NUM+CHAIN_NEEDLE_NUM);
            }
            if(nidx > EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM + SEW_NEEDLE_NUM +RIBBON_NEEDLE_NUM+TOWEL_NEEDLE_NUM)//链式针杆
            {
                nidx -= (EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM + SEW_NEEDLE_NUM +RIBBON_NEEDLE_NUM+TOWEL_NEEDLE_NUM);
            }
            if(nidx > EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM + SEW_NEEDLE_NUM +RIBBON_NEEDLE_NUM)//毛巾针杆
            {
                nidx -= (EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM + SEW_NEEDLE_NUM +RIBBON_NEEDLE_NUM);
            }
            if(nidx > EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM+SEW_NEEDLE_NUM)//盘带针杆
            {
                nidx -= (EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM+SEW_NEEDLE_NUM);
            }
            if(nidx > EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM)//缝纫针杆
            {
                nidx -= (EMB_NEEDLE_NUM + PUNCH_NEEDLE_NUM);
            }
            else if(nidx > EMB_NEEDLE_NUM)//冲孔针杆
            {
                nidx -= EMB_NEEDLE_NUM;
            }

            int cidx;
            if(nidx <= 0)
            {
                cidx = 0;//未设置过色序时颜色索引默认为0
                //cidx = (colorIdx % NEEDLE_NUM) % EMB_BF_SW_ND;
            }
            else
            {
                cidx = m_needleColorTable[nidx - 1] % EMB_BF_SW_ND;
            }

            int cnum = m_tabelColorNum;
            cnum /= sizeof(QRgb);
            if (cnum > EMB_BF_SW_ND)
            {
                cnum = EMB_BF_SW_ND;
            }
            if (cnum != 0)
            {
                cidx %= cnum;
                QRgb * pColor = m_pColor;
                if(pColor != NULL)
                {
                    embcolor = (pColor[cidx]);
                }
                else
                {
                    embcolor = 0;
                }
            }
            else
            {
                embcolor = 0;
            }

            oldcolor = colorIdx;
        }

        if (ctrlByte == DATA_CHGND)    // 换色
        {
            colorIdx++;
        }

        while(datposr >= PI10000)
        {
            datposr -= (PI20000-1);
        }
        while(datposr <= -PI10000)
        {
            datposr += (PI20000-1);
        }

        curr = datposr;

        dispItem.ctrl = ctrlByte;
        dispItem.attr = attrByte;
        dispItem.bx = prex;
        dispItem.by = prey;
        dispItem.ex = curx;
        dispItem.ey = cury;
        dispItem.ar = curr;
        dispItem.rgb = embcolor;
        memcpy(&dispItem.action,ds16DataPtr->action,sizeof(dispItem.action));

        m_dispDat.append((char*)(&dispItem), sizeof(DispItem));

        ds16DataPtr++;
    }

    qDebug("CreateDispFromEmbDs16, stepsize=%d", m_dispDat.size() / sizeof(DispItem));

    return 0;
}

#define DRAWDR 0

int EmbData::drawImageByDispFile(int gradientFlag)
{
    u8 ctrl;
    static int flagBug = 0;

    int gary = 0;
    int bx, by, ex, ey;
    bx = by = ex = ey = 0;
    int i;
    u8 actionWord[2];	//附加动作
    DispItem * pDispBuff = (DispItem *)m_dispDat.data();

    int size = m_dispDat.size();
    int stitchCount = size/sizeof(DispItem);

    if (gradientFlag == -1)
    {// 使用之前的设置
        gradientFlag = flagBug;
    }
    else
    {
        flagBug = gradientFlag;
    }

    if (stitchCount <= 0)
    {
        stitchCount = 0;
    }
    if (m_stitchIndex >= stitchCount)
    {
        m_stitchIndex = stitchCount - 1;
    }
    if (m_stitchIndex < 0)
    {
        m_stitchIndex = 0;
    }

    if (m_showColorBeg < 0)
    {
        m_showColorBeg = 0;
    }

    if (m_showColorEnd < 0)
    {
        m_showColorEnd = 0;
    }

    if (m_showColorBeg > m_showColorEnd)
    {
        int temp = m_showColorEnd;
        m_showColorEnd = m_showColorBeg;
        m_showColorBeg = temp;
    }

    DISP_MODE dispmode = m_dispMode;

#define SEG2_1  0.1
#define SEG2_2  1.0

    QPainter painter(&m_canvas);

    //填充透明色
    //    painter.setBrush(QColor(0,0,0,0));
    //    painter.drawRect(-10, -10, m_canvas.width()+EMB_PREVIEW_SIDE, m_canvas.height()+EMB_PREVIEW_SIDE);

    QRgb rgb, oldrgb;
    s16 ar;
    QPen pen;
    QColor color;
    QColor backColor1;
    QColor backColor2;
    QLinearGradient gradient;

    //初始值设置为3，灰度图用3，彩色图用2，
    //因为彩色做了渐变，如果用3灰图不能将彩色覆盖掉

    if(gradientFlag == 0)
    {
        pen.setWidth(4);
    }
    else
    {// 不显示渐变色,线宽变细
        pen.setWidth(1);
    }

    int first = 1;
    s16 jumpFlag = 0;//跳针标志
    oldrgb = 0;
    rgb = 0;

    if (dispmode == DISP_ALL_NORMAL ||        // 显示所有线迹（原色显示）
            dispmode == DISP_ALL_EXEC   ||        // 显示所有线迹（执行过的显示原色，其余显示灰色）
            0)
    {
        int tenThousand = 0;
        for (i = 0; i < stitchCount; i++)
        {
            tenThousand++;
            if(tenThousand == TENTHOUSANDNEEDLE)
            {
                tenThousand = 0;
                int idx = i / TENTHOUSANDNEEDLE;
                //每十万针主界面加载图片的进度条走一格
                emit siDrawNeedleIdx(idx);
            }

            ctrl = pDispBuff[i].ctrl;
            bx = pDispBuff[i].bx;
            by = pDispBuff[i].by;
            ex = pDispBuff[i].ex;
            ey = pDispBuff[i].ey;
            rgb = pDispBuff[i].rgb;
            ar = pDispBuff[i].ar;
            memcpy(actionWord,pDispBuff[i].action,sizeof(pDispBuff[i].action));

            if (ctrl == DATA_OFFSET ||
                    ctrl == DATA_JUMP ||
                    ctrl == DATA_CHGND)
            {
                if (ctrl == DATA_JUMP)
                {
                    //跳针标志置为1
                    jumpFlag = 1;
                }

                //跳针和换色不画线,注释与否影响跳针的渐变色，需更改（如菱形）
                //continue;
            }

            if (dispmode == DISP_ALL_EXEC) // 从开始到 m_stitchIndex 显示正常颜色的线迹（执行过），从 m_stitchIndex 结束显示灰色线迹（未执行）
            {
                if (i >= m_stitchIndex)
                {
                    gary = qGray(rgb);
                    //gary = gary/3 + 150;    // 颜色变淡
                    gary = COLOR_GREY;//纯灰
                    rgb = qRgb(gary, gary, gary);
                }
                else
                {
                    if(gradientFlag == 0)
                    {
                        gradient.setStart(bx,by);
                        gradient.setFinalStop(ex,ey);

                        //绣花跳针两针为一步，所以要将两针跳针每针分两段渐变，亮色部分拼接到一起
                        //实现一针渐变的效果(可参考菱形图效果)
                        if(jumpFlag == 1)
                        {
                            jumpFlag = 2;
                            //两段渐变
                            backColor2 = getBrightDec(color);
                            backColor1 = getBrightAdd(color);

                            //若跳针过滤掉应改为backColor1、backColor2顺序
                            gradient.setColorAt(SEG2_1,backColor2);
                            gradient.setColorAt(SEG2_2,backColor1);
                        }
                        else if (jumpFlag == 2)
                        {
                            jumpFlag = 0;
                            //两段渐变
                            backColor2 = getBrightDec(color);
                            backColor1 = getBrightAdd(color);

                            //若跳针过滤掉应改为backColor2、backColor1顺序
                            gradient.setColorAt(SEG2_1,backColor1);
                            gradient.setColorAt(SEG2_2,backColor2);
                        }
                        else
                        {
                            backColor2 = getBrightDec(color);
                            backColor1 = getBrightAdd(color);

                            gradient.setColorAt(0.1,backColor2);
                            gradient.setColorAt(0.5,backColor1);
                            gradient.setColorAt(1.0,backColor2);
                        }

                        painter.setRenderHint(QPainter::Antialiasing,true);
                        QBrush brush(gradient);
                        QPen npen(brush , 2);
                        painter.setPen(npen);
                    }
                }
            }

            if (oldrgb != rgb || first != 0)
            {
                color.setRgb(rgb);
                pen.setColor(color);
                painter.setPen(pen);
                oldrgb = rgb;
            }

            if(dispmode == DISP_ALL_NORMAL)//非灰度图时画图加渐变
            {
                if(gradientFlag == 0)
                {
                    gradient.setStart(bx,by);
                    gradient.setFinalStop(ex,ey);
                    //绣花跳针两针为一步，所以要将两针跳针每针分两段渐变，亮色部分拼接到一起
                    //实现一针渐变的效果(可参考菱形图效果)
                    if(jumpFlag == 1)
                    {
                        jumpFlag = 2;
                        //两段渐变
                        backColor2 = getBrightDec(color);
                        backColor1 = getBrightAdd(color);

                        //若跳针过滤掉应改为backColor1、backColor2顺序
                        gradient.setColorAt(SEG2_1,backColor2);
                        gradient.setColorAt(SEG2_2,backColor1);
                    }
                    else if (jumpFlag == 2)
                    {
                        jumpFlag = 0;
                        //两段渐变
                        backColor2 = getBrightDec(color);
                        backColor1 = getBrightAdd(color);

                        //若跳针过滤掉应改为backColor2、backColor1顺序
                        gradient.setColorAt(SEG2_1,backColor1);
                        gradient.setColorAt(SEG2_2,backColor2);
                    }
                    else
                    {
                        backColor2 = getBrightDec(color);
                        backColor1 = getBrightAdd(color);

                        gradient.setColorAt(0.1,backColor2);
                        gradient.setColorAt(0.5,backColor1);
                        gradient.setColorAt(1.0,backColor2);
                    }

                    painter.setRenderHint(QPainter::Antialiasing,true);
                    QBrush brush(gradient);
                    QPen npen(brush , 2);
                    painter.setPen(npen);
                }
            }

            //亮片或散珠动作
            if((actionWord[0] & 0x20) == 0x20)
            {
                drawBeadOrSequin(painter,actionWord[1],bx,by,ex,ey,rgb,gary);
            }

            painter.drawLine(bx, by, ex, ey);
            first = 0;

            if(ar == 0){}//为了去掉编译警告
#if(DRAWDR)
            double len = sqrt((double)(ex-bx)*(double)(ex-bx)+ (double)(ey-by)*(double)(ey-by));

            int mx = len * cos((PI10000-ar)/10000.0);
            int my = len * sin((PI10000-ar)/10000.0);
            QColor color = QColor(Qt::green);
            QPen pen;
            pen.setColor(color);
            painter.setPen(pen);
            painter.drawLine(bx, by, bx+mx, by+my);
            pen.setColor(QColor(Qt::red));
            painter.setPen(pen);
            painter.drawEllipse(bx+mx, by+my,2,2);
#endif
        }

        if (dispmode == DISP_ALL_EXEC && m_stitchIndex < stitchCount)
        {
            i = m_stitchIndex;

            ctrl = pDispBuff[i].ctrl;
            bx = pDispBuff[i].bx;
            by = pDispBuff[i].by;
            drawNeedleIdxPen(bx, by, painter);//绘制跟踪笔
            m_dispIndex = m_stitchIndex;            // 移动显示指针
        }
    }
    else if ( dispmode == DISP_ALL_AREA )          // 显示所有线迹（有效区域内的显示原色，其余显示灰色）
    {
        //显示为灰色
        for(int j = m_greyColorBeg; j < m_greyColorEnd; j++)
        {
            ctrl = pDispBuff[j].ctrl;
            bx = pDispBuff[j].bx;
            by = pDispBuff[j].by;
            ex = pDispBuff[j].ex;
            ey = pDispBuff[j].ey;
            rgb = pDispBuff[j].rgb;
            memcpy(actionWord,pDispBuff[j].action,sizeof(pDispBuff[j].action));

            gary = qGray(rgb);
            //gary = gary/3 + 150;    // 颜色变淡
            gary = COLOR_GREY;//纯灰
            rgb = qRgb(gary, gary, gary);

            color.setRgb(rgb);
            pen.setColor(color);
            painter.setPen(pen);

            //亮片或散珠动作
            if((actionWord[0] & 0x20) == 0x20)
            {
                drawBeadOrSequin(painter,actionWord[1],bx,by,ex,ey,rgb,gary);
            }

            painter.drawLine(bx, by, ex, ey);
        }

        //显示为原色
        for(int m = m_showColorBeg; m < m_showColorEnd; m++)
        {
            ctrl = pDispBuff[m].ctrl;
            bx = pDispBuff[m].bx;
            by = pDispBuff[m].by;
            ex = pDispBuff[m].ex;
            ey = pDispBuff[m].ey;
            rgb = pDispBuff[m].rgb;
            memcpy(actionWord,pDispBuff[m].action,sizeof(pDispBuff[m].action));

            color.setRgb(rgb);
            pen.setColor(color);
            painter.setPen(pen);

            //亮片或散珠动作
            if((actionWord[0] & 0x20) == 0x20)
            {
                drawBeadOrSequin(painter,actionWord[1],bx,by,ex,ey,rgb,gary);
            }

            painter.drawLine(bx, by, ex, ey);
        }
    }
    else if (dispmode == DISP_EXECING)   // 刷新部分线迹（缝纫中进度显示）
    {
        //qDebug()<<"m_stitchIndex"<<m_stitchIndex<<"m_dispIndex"<<m_dispIndex;

        if (m_stitchIndex != m_dispIndex)
        {
            eraseNeedleIdxPen(painter);//擦除跟踪笔

            // 显示针迹改变
            if (m_stitchIndex > m_dispIndex && m_stitchIndex < stitchCount)
            {
                i = m_dispIndex;

                while(i < m_stitchIndex)        // 显示为原线迹
                {
                    ctrl = pDispBuff[i].ctrl;
                    bx = pDispBuff[i].bx;
                    by = pDispBuff[i].by;
                    ex = pDispBuff[i].ex;
                    ey = pDispBuff[i].ey;
                    rgb = pDispBuff[i].rgb;
                    memcpy(actionWord,pDispBuff[i].action,sizeof(pDispBuff[i].action));

                    if (ctrl == DATA_OFFSET ||
                            ctrl == DATA_JUMP ||
                            ctrl == DATA_CHGND)
                    {
                        if (ctrl == DATA_JUMP)
                        {
                            //跳针标志置为1
                            jumpFlag = 1;
                        }

                        //跳针和换色不画线,注释与否影响跳针的渐变色，需更改（如菱形）
                        //i++;
                        //continue;
                    }

                    if (oldrgb != rgb || first != 0)
                    {
                        color.setRgb(rgb);
                        pen.setColor(color);
                        painter.setPen(pen);
                        oldrgb = rgb;

                        if(gradientFlag == 0)
                        {
                            gradient.setStart(bx,by);
                            gradient.setFinalStop(ex,ey);

                            //绣花跳针两针为一步，所以要将两针跳针每针分两段渐变，亮色部分拼接到一起
                            //实现一针渐变的效果(可参考菱形图效果)
                            if(jumpFlag == 1)
                            {
                                jumpFlag = 2;
                                //两段渐变
                                backColor2 = getBrightDec(color);
                                backColor1 = getBrightAdd(color);

                                //若跳针过滤掉应改为backColor1、backColor2顺序
                                gradient.setColorAt(SEG2_1,backColor2);
                                gradient.setColorAt(SEG2_2,backColor1);
                            }
                            else if(jumpFlag == 2)
                            {
                                jumpFlag = 0;
                                //两段渐变
                                backColor2 = getBrightDec(color);
                                backColor1 = getBrightAdd(color);

                                //若跳针过滤掉应改为backColor2、backColor1顺序
                                gradient.setColorAt(SEG2_1,backColor1);
                                gradient.setColorAt(SEG2_2,backColor2);
                            }
                            else
                            {
                                i--;
                                u8 bCtrl = pDispBuff[i].ctrl;

                                if(bCtrl != DATA_JUMP)//上一针不为跳针
                                {
                                    i++;

                                    backColor2 = getBrightDec(color);
                                    backColor1 = getBrightAdd(color);
                                    //三段渐变
                                    gradient.setColorAt(0.1,backColor2);
                                    gradient.setColorAt(0.5,backColor1);
                                    gradient.setColorAt(1.0,backColor2);
                                }
                                else
                                {
                                    i++;

                                    backColor2 = getBrightDec(color);
                                    backColor1 = getBrightAdd(color);
                                    //两段渐变
                                    gradient.setColorAt(0.1,backColor1);
                                    gradient.setColorAt(0.8,backColor2);
                                }
                            }

                            painter.setRenderHint(QPainter::Antialiasing,true);
                            QBrush brush(gradient);
                            QPen npen(brush , 2);
                            painter.setPen(npen);
                        }
                    }

                    //亮片或散珠动作
                    if((actionWord[0] & 0x20) == 0x20)
                    {
                        drawBeadOrSequin(painter,actionWord[1],bx,by,ex,ey,rgb,gary);
                    }
                    painter.drawLine(bx, by, ex, ey);
                    i++;
                }
            }
            else if (m_stitchIndex < m_dispIndex && m_dispIndex < stitchCount)
            {
                i = m_stitchIndex;

                while(i <= m_dispIndex)        // 显示为灰色线迹
                {
                    ctrl = pDispBuff[i].ctrl;
                    bx = pDispBuff[i].bx;
                    by = pDispBuff[i].by;
                    ex = pDispBuff[i].ex;
                    ey = pDispBuff[i].ey;
                    rgb = pDispBuff[i].rgb;
                    memcpy(actionWord,pDispBuff[i].action,sizeof(pDispBuff[i].action));

                    if (ctrl == DATA_OFFSET ||
                            ctrl == DATA_JUMP ||
                            ctrl == DATA_CHGND)
                    {
                        if (ctrl == DATA_JUMP)
                        {
                            //跳针标志置为1
                            jumpFlag = 1;
                        }

                        //跳针和换色不画线,注释与否影响跳针的渐变色，需更改（如菱形）
                        //i++;
                        //continue;
                    }

                    gary = qGray(rgb);
                    //gary = gary/3 + 150;    // 颜色变淡
                    gary = COLOR_GREY;//纯灰
                    rgb = qRgb(gary, gary, gary);

                    if (oldrgb != rgb || first != 0)
                    {
                        color.setRgb(rgb);
                        pen.setColor(color);
                        painter.setPen(pen);
                        oldrgb = rgb;
                    }

                    //亮片或散珠动作
                    if((actionWord[0] & 0x20) == 0x20)
                    {
                        drawBeadOrSequin(painter,actionWord[1],bx,by,ex,ey,rgb,gary);
                    }
                    painter.drawLine(bx, by, ex, ey);
                    i++;
                }
            }

            i = m_stitchIndex;

            ctrl = pDispBuff[i].ctrl;
            bx = pDispBuff[i].bx;
            by = pDispBuff[i].by;
            drawNeedleIdxPen(bx, by, painter);//绘制跟踪笔
            m_dispIndex = m_stitchIndex;            // 移动显示指针
        }
    }
    return 0;
}

//补光增加
QColor EmbData::getBrightAdd(QColor embcolor)
{
    QColor backColor;

    float rgbR = embcolor.red();//R值
    float rgbG = embcolor.green();//G值
    float rgbB = embcolor.blue();//B值

    float Y = 0.257 * rgbR + 0.504 * rgbG + 0.098 * rgbB + 16;
    float U = (-0.148) * rgbR - 0.291 * rgbG + 0.439 * rgbB +128;
    float V = 0.439 * rgbR - 0.368 * rgbG + 0.071 * rgbB + 128;

    Y = Y + 100;

    int R = 1.164*Y + 1.596 * V - 222.9;
    int G = 1.164*Y - 0.392 * U - 0.823 * V+ 135.6;
    int B = 1.164*Y + 2.017 * U- 276.8 ;

    if(R > 255)
    {
        R = 255;
    }
    else if (R < 0)
    {
        R = 0;
    }

    if(G > 255)
    {
        G = 255;
    }
    else if (G < 0)
    {
        G = 0;
    }

    if(B > 255)
    {
        B = 255;
    }
    else if (B < 0)
    {
        B = 0;
    }

    backColor.setRgb(R , G , B);

    return backColor;
}

//补光减少
QColor EmbData::getBrightDec(QColor embcolor)
{
    QColor backColor;

    float rgbR = embcolor.red();//R值
    float rgbG = embcolor.green();//G值
    float rgbB = embcolor.blue();//B值

    float Y = 0.257 * rgbR + 0.504 * rgbG + 0.098 * rgbB + 16;
    float U = (-0.148) * rgbR - 0.291 * rgbG + 0.439 * rgbB +128;
    float V = 0.439 * rgbR - 0.368 * rgbG + 0.071 * rgbB + 128;

    if( Y > 100.0)
    {
        Y = Y - 100.0;
    }
    else
    {
        Y = 16;
    }

    int R = 1.164*Y + 1.596 * V - 222.9;
    int G = 1.164*Y - 0.392 * U - 0.823 * V+ 135.6;
    int B = 1.164*Y + 2.017 * U- 276.8 ;

    if(R > 255)
    {
        R = 255;
    }
    else if (R < 0)
    {
        R = 0;
    }

    if(G > 255)
    {
        G = 255;
    }
    else if (G < 0)
    {
        G = 0;
    }

    if(B > 255)
    {
        B = 255;
    }
    else if (B < 0)
    {
        B = 0;
    }

    backColor.setRgb(R , G , B);

    return backColor;
}

void EmbData::getCurvePointFillLine(QList<DsAbsItem> &inList, double indRunLen, QList<DsAbsItem> &outList)
{
    DsAbsItem dPoint1, dPoint2, dPoint3;
    double dTatol, dLen1, dLen2, dSpace;
    long lSum, lCount;

    //计算总的线段长
    int iCountPoint = inList.size();
    if(iCountPoint <= 0)
    {
        return;
    }

    getTotalDistanceFillLine(&inList, dTatol);
    if(dTatol == 0)
        return;

    lSum = (long)round(dTatol / indRunLen + 0.1667);
    dSpace = dTatol / (double)lSum;
    if(lSum == 0)
        lSum = 1;

    dPoint1 = inList[0];
    outList.append(dPoint1);//添加第一个点
    dPoint2 = dPoint1;

    dLen1 = dSpace;
    dLen2 = 0;
    int i = 0;
    for(lCount = 0; lCount < lSum; lCount++)
    {
        while(i < inList.size()-1 && dLen2 < dLen1)
        {
            dLen1 -= dLen2;
            dPoint1 = dPoint2;
            i++;
            dPoint2 = inList[i];
            dLen2 = sqrt((dPoint1.ax - dPoint2.ax) * (dPoint1.ax - dPoint2.ax) + (dPoint1.ay - dPoint2.ay) * (dPoint1.ay - dPoint2.ay));
        }
        if(dLen1 < dLen2)
        {
            getPointInSectFillLine(dPoint1, dPoint2, dLen1, dPoint3);
        }
        else
        {
            dPoint3 = dPoint2;
        }
        outList.append(dPoint3);
        dLen2 -= dLen1;
        dLen1 = dSpace;
        dPoint1 = dPoint3;
    }
}

int EmbData::getTotalDistanceFillLine(QList<DsAbsItem> *pPointList, double &dTotal)
{
    DsAbsItem dPoint, dNext;
    double d;
    dTotal = 0;
    int i = 0;
    long lSum = (long)pPointList->count();
    if(lSum > 1)
    {
        while(i < pPointList->size())
        {
            dPoint = pPointList->at(i);
            i++;
            if(i < pPointList->size())
            {
                dNext = pPointList->at(i);
                d =  sqrt((dPoint.ax - dNext.ax) * (dPoint.ax - dNext.ax) + (dPoint.ay- dNext.ay) * (dPoint.ay- dNext.ay));
                dTotal += d;
            }
            else
            {
                break;
            }
        }
    }
    return 0;
}

bool EmbData::getPointInSectFillLine(const DsAbsItem &p1, const DsAbsItem &p2, const double &d, DsAbsItem &outp)
{
    bool bRes;
    DsAbsItem dpoint[3];

    dpoint[0] = p1;
    dpoint[1] = p2;
    dpoint[2] = outp;
    outp = dpoint[1];

    bRes = getPointAtSect(dpoint[0], dpoint[1], d, dpoint[2]);
    outp.ax = dpoint[2].ax;
    outp.ay = dpoint[2].ay;

    return bRes;
}

bool EmbData::getPointAtSect(const DsAbsItem &p1, const DsAbsItem &p2, const double &d, DsAbsItem &outp)
{
    double s = sqrt((p1.ax - p2.ax) * (p1.ax - p2.ax) + (p1.ay - p2.ay) * (p1.ay - p2.ay));
    if(fabs(s) < ZERO)
    {
        if(d < ZERO)
        {
            outp.ax = p1.ax;
            outp.ay = p1.ay;
        }
        return false;
    }
    outp.ax = (p2.ax - p1.ax) * d / s + p1.ax;
    outp.ay = (p2.ay - p1.ay) * d / s + p1.ay;

    return true;
}
