第一次提交

This commit is contained in:
华海艳 2024-02-06 14:19:53 +08:00
commit dadc1c2462
142 changed files with 48805 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*.d0fd913
*.user.*
boost/
spline_library/

141
NPlotter.pro Normal file
View File

@ -0,0 +1,141 @@
#-------------------------------------------------
#
# Project created by Qt5.9.1 2022-10-24T09:06:36
# created by HUAHAIYAN
#-------------------------------------------------
TEMPLATE = app
TARGET = NPotter
#INCLUDEPATH +=$$PWD/../boost/
#INCLUDEPATH +=$$PWD/../spline_library/
CONFIG += c++11
QT += core gui network
QT += serialport
QT += svg
QT += concurrent testlib #将类中的函数移到线程中
#用于zip的压缩和解压因为qt自带的zip是私有的所以工程会报警告若要消除警告可尝试第三方的zip库
QT += gui-private
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
OBJECTS_DIR += obj
MOC_DIR += moc
UI_DIR += forms
RCC_DIR += rccs
DEFINES += HAVE_CONFIG_H
SOURCES += \
main.cpp \
mainwindow.cpp \
printviewwindow.cpp \
datafile/hpgl/importhpgl.cpp \
datafile/hpgl/marker.cpp \
datafile/hpgl/vectorfont.cpp \
datafile/view/mygraphicsitem.cpp \
datafile/view/mygraphicsscene.cpp \
datafile/view/mygraphicsview.cpp \
printnumbersetdialog.cpp \
drawingsetdialog.cpp \
historydialog.cpp \
plottersetdialog.cpp \
startsetdialog.cpp \
machine/machine.cpp \
datafile/hpgl/plotbitmap.cpp \
datafile/qrencode/bitstream.c \
datafile/qrencode/mask.c \
datafile/qrencode/mmask.c \
datafile/qrencode/mqrspec.c \
datafile/qrencode/qrencode.c \
datafile/qrencode/qrinput.c \
datafile/qrencode/qrspec.c \
datafile/qrencode/rsecc.c \
datafile/qrencode/split.c \
machine/comm/comm.cpp \
machine/comm/crc16.cpp \
machine/comm/crc32.cpp \
printinfodialog.cpp \
datafile/dxf/dxfhelper.cpp \
datafile/dxf/dxfreader.cpp \
datafile/dxf/dxflib/dl_dxf.cpp \
datafile/dxf/dxflib/dl_writer_ascii.cpp \
addmachinedialog.cpp \
machine/bmp/bwbmp.cpp \
machine/bmp/creatprintbmp.cpp \
machine/tcp/qbindtcpsocket.cpp \
machine/tcp/tcpclient.cpp
FORMS += \
mainwidget.ui \
mainwindow.ui \
printviewwindow.ui \
printnumbersetdialog.ui \
drawingsetdialog.ui \
historydialog.ui \
plottersetdialog.ui \
startsetdialog.ui \
printinfodialog.ui \
addmachinedialog.ui
HEADERS += \
main.h \
mainwindow.h \
printviewwindow.h \
datafile/hpgl/importhpgl.h \
datafile/hpgl/marker.h \
datafile/hpgl/vectorfont.h \
datafile/view/mygraphicsitem.h \
datafile/view/mygraphicsscene.h \
datafile/view/mygraphicsview.h \
printnumbersetdialog.h \
drawingsetdialog.h \
historydialog.h \
plottersetdialog.h \
startsetdialog.h \
datafile/hpgl/typedef.h \
machine/machine.h \
datafile/hpgl/plotbitmap.h \
datafile/qrencode/bitstream.h \
datafile/qrencode/config.h \
datafile/qrencode/mask.h \
datafile/qrencode/mmask.h \
datafile/qrencode/mqrspec.h \
datafile/qrencode/qrencode.h \
datafile/qrencode/qrencode_inner.h \
datafile/qrencode/qrinput.h \
datafile/qrencode/qrspec.h \
datafile/qrencode/rsecc.h \
datafile/qrencode/split.h \
machine/comm/protocol.h \
machine/comm/comm.h \
machine/comm/typedef.h \
machine/comm/crc16.h \
machine/comm/crc32.h \
printinfodialog.h \
datafile/dxf/dxfhelper.h \
datafile/dxf/dxfreader.h \
datafile/dxf/dxflib/dl_attributes.h \
datafile/dxf/dxflib/dl_codes.h \
datafile/dxf/dxflib/dl_creationadapter.h \
datafile/dxf/dxflib/dl_creationinterface.h \
datafile/dxf/dxflib/dl_dxf.h \
datafile/dxf/dxflib/dl_entities.h \
datafile/dxf/dxflib/dl_exception.h \
datafile/dxf/dxflib/dl_extrusion.h \
datafile/dxf/dxflib/dl_global.h \
datafile/dxf/dxflib/dl_writer.h \
datafile/dxf/dxflib/dl_writer_ascii.h \
addmachinedialog.h \
machine/bmp/bwbmp.h \
machine/bmp/creatprintbmp.h \
machine/tcp/qbindtcpsocket.h \
machine/tcp/tcpclient.h \
machine/printinfo/mcfiles.h
RESOURCES += \
res.qrc

92
README.md Normal file
View File

@ -0,0 +1,92 @@
# NPlotter
## Getting started
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
## Add your files
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
```
cd existing_repo
git remote add origin http://192.168.2.195:8099/hmi/plotter/nplotter.git
git branch -M main
git push -uf origin main
```
## Integrate with your tools
- [ ] [Set up project integrations](http://192.168.2.195:8099/hmi/plotter/nplotter/-/settings/integrations)
## Collaborate with your team
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
## Test and Deploy
Use the built-in continuous integration in GitLab.
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
***
# Editing this README
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template.
## Suggestions for a good README
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## Name
Choose a self-explaining name for your project.
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
## License
For open source projects, say how it is licensed.
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.

70
addmachinedialog.cpp Normal file
View File

@ -0,0 +1,70 @@
#include "addmachinedialog.h"
#include "ui_addmachinedialog.h"
AddMachineDialog::AddMachineDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::AddMachineDialog)
{
ui->setupUi(this);
setWindowModality(Qt::ApplicationModal);
setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
QRegExp ipExp("(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)");
ui->lineEdit_ip->setValidator(new QRegExpValidator(ipExp, ui->lineEdit_ip));
}
AddMachineDialog::~AddMachineDialog()
{
delete ui;
}
void AddMachineDialog::on_pushButton_ok_clicked()
{
m_mcIp = ui->lineEdit_ip->text();
m_mcName = ui->lineEdit_name->text();
bool bl = true;
if(m_mcIp.isEmpty())
{
bl = false;
}
QStringList list = m_mcIp.split('.');
if(list.size() != 4)
{
bl = false;
}
for(const auto& num : list)
{
bool ok = false;
int temp = num.toInt(&ok);
if(!ok || temp < 0 || temp > 255)
{
bl = false;
}
}
if(bl == false)
{
QMessageBox::warning(this,
tr("Prompt"),
tr("Please enter the correct IP!"),//请输入正确的IP
QMessageBox::Ok);
return;
}
if(m_mcName.length() <= 0)
{
QMessageBox::warning(this,
tr("Prompt"),
tr("Please enter the correct machine name!"),//请输入正确的机器名称!
QMessageBox::Ok);
return;
}
done(1);
}
void AddMachineDialog::on_pushButton_cancel_clicked()
{
done(0);
}

33
addmachinedialog.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef ADDMACHINEDIALOG_H
#define ADDMACHINEDIALOG_H
#include <QDialog>
#include <QMessageBox>
namespace Ui {
class AddMachineDialog;
}
class AddMachineDialog : public QDialog
{
Q_OBJECT
public:
explicit AddMachineDialog(QWidget *parent = 0);
~AddMachineDialog();
public:
inline QString getMcIp(){return m_mcIp;}
inline QString getMcName(){return m_mcName;}
private slots:
void on_pushButton_ok_clicked();
void on_pushButton_cancel_clicked();
private:
Ui::AddMachineDialog *ui;
QString m_mcIp;
QString m_mcName;
};
#endif // ADDMACHINEDIALOG_H

97
addmachinedialog.ui Normal file
View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AddMachineDialog</class>
<widget class="QDialog" name="AddMachineDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>338</width>
<height>153</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QPushButton" name="pushButton_ok">
<property name="geometry">
<rect>
<x>190</x>
<y>110</y>
<width>60</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Ok</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_cancel">
<property name="geometry">
<rect>
<x>260</x>
<y>110</y>
<width>60</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
<widget class="QLabel" name="label_ip">
<property name="geometry">
<rect>
<x>50</x>
<y>40</y>
<width>31</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>IP:</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_ip">
<property name="geometry">
<rect>
<x>90</x>
<y>40</y>
<width>191</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_name">
<property name="geometry">
<rect>
<x>50</x>
<y>70</y>
<width>31</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>Name:</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_name">
<property name="geometry">
<rect>
<x>90</x>
<y>70</y>
<width>191</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

662
bmp/bwbmp.cpp Normal file
View File

@ -0,0 +1,662 @@
#include "bwbmp.h"
#include <QFile>
#include <QDebug>
BWBmp::BWBmp()
{
}
int BWBmp::LoadBiBmp(QString filename)
{
m_bwDdat.clear();
m_prDdat.clear();
QFile file(filename);
int rslt = file.open(QFile::ReadOnly);
if (rslt == 0)
{
qDebug() << "open file error" << filename;
return -1;
}
m_bwDdat = file.readAll();
if (m_bwDdat.size() <= (int)sizeof(BitmapHead))
{
m_bwDdat.clear();
file.close();
qDebug() << "file size error, size=" << m_bwDdat.size();
return -2;
}
BitmapHead * pHead = (BitmapHead *)(m_bwDdat.data());
if ( (pHead->identifier != 0x4d42) ||
(pHead->bitDatOffset != 0x3E) ||
(pHead->biSize != 0x28) ||
(pHead->biPlanes != 0x01) ||
(pHead->biBitPerPixel != 0x01) ||
(pHead->biCompression != 0x00) ||
0 )
{
m_bwDdat.clear();
file.close();
qDebug() << "not bi bmp";
return -3;
}
file.close();
return 0;
}
int BWBmp::SavePrBmp(QString filename)
{
QFile file(filename);
int rslt = file.open(QFile::ReadWrite | QFile::Truncate);
if (rslt == 0)
{
qDebug() << "open file error" << filename;
return -1;
}
file.write(m_prDdat);
file.close();
return 0;
}
int BWBmp::Compress(int idx, int dir)
{
/*
300
+
__________________________________________________
| bit7 bit6 | bit5 bit4 bit3 bit2 bit1 bit0 |
--------------------------------------------------
| | |
--------------------------------------------------
| 0 0 | |
--------------------------------------------------
| 0 1 | 1 |
--------------------------------------------------
| 1 0 | 100 |
--------------------------------------------------
| 1 1 | 0 |
--------------------------------------------------
*/
if (dir < 0)
{
dir = -1;
}
else
{
dir = 1;
}
m_prDdat.clear();
if (m_bwDdat.isEmpty() == 1)
{
qDebug() << "bit dat empty";
return -1;
}
QByteArray tmppr;
tmppr.clear();
BitmapHead * pHead = (BitmapHead *)(m_bwDdat.data());
int width = pHead->biWidth;
int height = pHead->biHeight;
int widthBytes = (int)((width + 31) / 32) * 4;
if (widthBytes <= 0 || height < 1 || width > 0x1000000)
{
qDebug() << "bit dat error";
return -2;
}
const unsigned char * pBitDatBeg = (unsigned char *)(m_bwDdat.data() + pHead->bitDatOffset);
const unsigned char * pTmpDat;
if (dir == -1)
{
pBitDatBeg += widthBytes * (height -1);
}
const unsigned char * pBitDat = pBitDatBeg;
int * countBuff = new int [width];
if (countBuff == NULL)
{
qDebug() << "no enough memory";
return -3;
}
memset(countBuff, 0, sizeof(int)*width);
unsigned char tmpdat, mod;
int datsta = -1;
int count0 = 0;
int count1 = 0;
int i, j, k, l;
for (i = 0; i < height; i++) // 行计数
{
pTmpDat = pBitDat;
int countIdx = 0;
count0 = 0;
count1 = 0;
for (j = 0, k = 0; (j < widthBytes) && (k < width); j++) // 行内扫描检测出每段连续0和1的个数
{
tmpdat = *pTmpDat++;
//qDebug()<<j+i*widthBytes<<" "<<tmpdat;
mod = 0x80;
if((width - k) <= 8)
{
// tmpdat = tmpdat >> (8 - (width - k ));
}
for (mod = 0x80; (mod != 0) && (k < width); k++, mod /= 2)
{
if ((tmpdat & mod) == 0)
{
if (datsta == 1)
{
count1 |= 0x80000000;
countBuff[countIdx] = count1;
countIdx++;
count1 = 0;
}
datsta = 0;
count0++;
}
else
{
if (datsta == 0)
{
countBuff[countIdx] = count0;
countIdx++;
count0 = 0;
}
datsta = 1;
count1++;
}
}
}
if (count0 != 0)
{
countBuff[countIdx] = count0;
countIdx++;
count0 = 0;
}
if (count1 != 0)
{
count1 |= 0x80000000;
countBuff[countIdx] = count1;
countIdx++;
count1 = 0;
}
int psta = 0;
int pcount = 0;
unsigned char tgtdat = 0, pmod = 0x20, nums;
for (l = 0; l < countIdx; l++) // 分析数据,生成压缩数据
{
if ((countBuff[l] & 0x80000000) != 0)
{
count1 = countBuff[l] & 0xfffffff;
while (count1 != 0)
{
if (psta == 0) // 当前状态是原始数据
{
if (pcount != 0)
{
while (count1 != 0 && pcount != 0)
{
tgtdat |= pmod;
pcount--;
count1--;
pmod *= 2;
}
if (pcount == 0) // 够一个位图
{
tgtdat &= 0x3f;
tmppr.append(tgtdat); // 添加
tgtdat = 0x00;
}
}
}
if (pcount == 0 && count1 != 0) //
{
while (count1 != 0)
{
if (count1 <= 6)
{
psta = 0x00; // 位图模式
tgtdat = psta;
pmod = 0x01;
pcount = 6;
break;
}
else
{
if (count1 > 64)
{
nums = 64;
}
else
{
nums = count1;
}
psta = 0x40;
tgtdat = psta;
tgtdat |= (nums & 0x3f);
tmppr.append(tgtdat); // 添加
//qDebug()<<tmppr.size()<<tgtdat;
count1 -= nums;
}
}
}
}
}
else
{
count0 = countBuff[l] & 0xfffffff;
while (count0 != 0)
{
if (psta == 0) // 当前状态是原始数据
{
if (pcount != 0)
{
while (count0 != 0 && pcount != 0)
{
tgtdat &= (~pmod);
pcount--;
count0--;
pmod *= 2;
}
if (pcount == 0) // 够一个位图
{
tgtdat &= 0x3f;
tmppr.append(tgtdat); // 添加
//qDebug()<<tmppr.size()<<tgtdat;
tgtdat = 0x00;
}
}
}
if (pcount == 0 && count0 != 0) //
{
while (count0 != 0)
{
if (count0 <= 6)
{
psta = 0x00; // 位图模式
tgtdat = psta;
pmod = 0x01;
pcount = 6;
break;
}
else
{
int muti = 1;
if (count0 >= 640)
{
nums = 64;
muti = 10;
psta = 0x80;
}
else if (count0 >= 64)
{
nums = (int)(count0/10);
muti = 10;
psta = 0x80;
}
else
{
nums = count0;
muti = 1;
psta = 0xC0;
}
tgtdat = psta;
tgtdat |= (nums & 0x3f);
tmppr.append(tgtdat); // 添加
//qDebug()<<tmppr.size()<<tgtdat;
count0 -= nums * muti;
}
}
}
}
}
}
if (psta == 0 && pcount != 0) // 不满一个位图的数据(小于6)
{
pcount = 0;
tgtdat &= 0x3f;
tmppr.append(tgtdat); // 添加
tgtdat = 0x00;
}
// 下一行
pBitDat += widthBytes * dir;
}
delete []countBuff;
// 添加文件头
CompBmpHead prHead;
memset(&prHead, 0, sizeof(CompBmpHead));
prHead.blkIdx = idx;
prHead.biHeight = pHead->biHeight;
prHead.biWidth = pHead->biWidth;
if (dir < 0)
{
prHead.compDir = 1;
}
else
{
prHead.compDir = 0;
}
unsigned int prsize = tmppr.size();
if (prsize >= pHead->biBitmapDatSize) // 压缩率不足
{
prHead.compType = 0; // 不压缩
prHead.datSize = pHead->biBitmapDatSize;
tmppr.clear();
pBitDat = pBitDatBeg;
for (i = 0; i < height; i++) // 行计数
{
tmppr.append((const char*)pBitDat, widthBytes);
pBitDat += widthBytes * dir;
}
}
else
{
prHead.compType = 1;
prHead.datSize = prsize;
}
m_prDdat.append((char*)(&prHead), sizeof(CompBmpHead));
m_prDdat.append(tmppr);
return 0;
}
int BWBmp::LoadPrBmp(QString filename)
{
m_fileName = filename;
m_rbwDdat.clear();
m_prDdat.clear();
QFile file(filename);
int rslt = file.open(QFile::ReadOnly);
if (rslt == 0)
{
qDebug() << "open file error" << filename;
return -1;
}
m_prDdat = file.readAll();
if (m_prDdat.size() <= 0)
{
file.close();
qDebug() << "file size error, size=" << m_prDdat.size();
m_prDdat.clear();
return -2;
}
file.close();
return 0;
}
int BWBmp::Unpress()
{
m_rbwDdat.clear();
QByteArray arrdat;
arrdat.clear();
QByteArray barr;
barr.clear();
int size = m_prDdat.size();
if (size < (int)sizeof(CompBmpHead))
{
qDebug() << "pr dat empty";
return -1;
}
CompBmpHead * pPrHead = (CompBmpHead *)(m_prDdat.data());
const unsigned char * pPrDdat = (unsigned char *)(m_prDdat.data() + sizeof(CompBmpHead));
size -= sizeof(CompBmpHead);
unsigned int biWidth = pPrHead->biWidth;
unsigned int biHeight = pPrHead->biHeight;
int widthBytes = (int)((biWidth + 31) / 32) * 4;
BitmapHead bmpHead;
memset(&bmpHead, 0, sizeof(BitmapHead));
bmpHead.identifier = 0x4d42; // BM
bmpHead.bitDatOffset = 0x3E;
bmpHead.biSize = 0x28;
bmpHead.biPlanes = 1;
bmpHead.biBitPerPixel = 1;
bmpHead.biCompression = 0;
bmpHead.biHResolution = 3780; // 水平分辨率, 像素/米
bmpHead.biVResolution = 3780; // 垂直分辨率, 像素/米
bmpHead.biColors = 2; // 颜色数
bmpHead.biImpColors = 2; // 重要颜色数
bmpHead.palette[0].color = 0x00ffffff;
bmpHead.palette[1].color = 0x00000000;
bmpHead.biWidth = biWidth; // 位图宽度,以像素为单位
bmpHead.biHeight = biHeight; // 位图高度,以像素为单位
bmpHead.biBitmapDatSize = widthBytes*biHeight; // 位图数据区的大小(字节数), 必须是4的整数倍
bmpHead.fileSize = bmpHead.bitDatOffset + bmpHead.biBitmapDatSize;
#define VAL_OUTBMP 0xff // 位图之外的默认数据
m_rbwDdat.append((char*)(&bmpHead), sizeof(BitmapHead));
unsigned char sdat = 0;
int count0,count1,flag;
count0 = count1 = 0;
flag = -1;
for(int i = 0; i < size; i++)
{
count0 = count1 = 0;
flag = -1;
sdat = pPrDdat[i];
if((sdat & 0xC0) == 0xC0) // 连续0
{
count0 = sdat & 0x3f;
if (count0 == 0)
{
count0 = 64;
}
flag = 0;
}
else
{
if((sdat & 0x40) == 0x40) // 连续1
{
count1 = sdat & 0x3f;
if (count1 == 0)
{
count1 = 64;
}
flag = 1;
}
else if((sdat & 0x80) == 0x80) // 连续10个0
{
count0 = (sdat & 0x3f ) * 10;
if (count0 == 0)
{
count0 = 640;
}
flag = 0;
}
else // 原始数据
{
//每行扫描时最后一个像素为原始数据时原始数据个数
int pcount = 6;
int val = arrdat.size() % biWidth;
int cnt = biWidth - val;
int cnt1 = abs((int)biWidth - ((int)widthBytes-1) * 8);
if(cnt >= cnt1)
{
pcount = 6;
}
else
{
if(cnt > 6)
{
pcount = 6;
}
else
{
pcount = cnt;
}
}
unsigned char sch = sdat & 0x3f; //够一个位图
unsigned char pmod = 0x01;
while (pcount != 0)
{
if((sch & pmod) != 0) // 为1
{
arrdat.append((char)0x01);
}
else // 为0
{
arrdat.append((char)0x00);
}
pcount--;
pmod *= 2;
}
continue;
}
}
int count = 0;
unsigned char ch = 0;
if(flag == 0)
{
count = count0;
ch = 0;
}
else if(flag == 1)
{
count = count1;
ch = 1;
}
for(int j = 0; j < count; j++)
{
arrdat.append(ch);
}
}
int num = 0;
unsigned int lst = ((biWidth/8)*8+8);
for(unsigned int n = 0; n < biHeight; n++)
{
for(int j = 0; j < widthBytes; j++)
{
unsigned int cnt = j*8;
unsigned char abyte = 0;
int idx = n*biWidth+j*8;
for(int i = 0; i < 8; i++, idx++, cnt++)
{
//qDebug()<<"idx"<<idx;
//qDebug()<<"ch"<<ch;
if (cnt < biWidth)
{
unsigned char ch = arrdat[idx];
if (ch != 0)
{
abyte |= (ch << (7-i));
}
}
else if(cnt >= lst)
{
abyte = VAL_OUTBMP; // 默认值
break;
}
else
{
abyte |= ((VAL_OUTBMP) >> (i)); // 默认值
break;
}
}
//if(abyte != 0)
{
//qDebug()<<num<<" "<<abyte;
}
m_rbwDdat.append(abyte);
num++;
}
}
return 0;
}
int BWBmp::SaveBiBmp(QString filename)
{
QFile file(filename);
int rslt = file.open(QFile::ReadWrite | QFile::Truncate);
if (rslt == 0)
{
qDebug() << "open file error" << filename;
return -1;
}
file.write(m_rbwDdat);
file.close();
return 0;
}
QByteArray BWBmp::getPrBmpDat()
{
return m_prDdat;
}

119
bmp/bwbmp.h Normal file
View File

@ -0,0 +1,119 @@
#ifndef BWBMP_H
#define BWBMP_H
#include <QString>
#include <QFileInfo>
#ifndef u8
#define u8 unsigned char
#endif
#ifndef u16
#define u16 unsigned short
#endif
#ifndef u32
#define u32 unsigned int
#endif
#pragma pack(push, 1) //设定为1字节对齐
// 位图的调色板
typedef union
{
u32 color;
struct
{
u8 rgbBlue;
u8 rgbGreen;
u8 rgbRed;
u8 rgbReserved;
}__attribute__ ((packed)) rgb;
} BmpRgbQuad;
// 位图文件头
typedef struct
{
u16 identifier; // 类型 一般为 "BM"
u32 fileSize; // 文件大小
u32 reserved; // 保留
u32 bitDatOffset; // 位图数据偏移,一般为 0x3E
u32 biSize; // 位图信息头大小, 一般为 0x28
u32 biWidth; // 位图宽度,以像素为单位
u32 biHeight; // 位图高度,以像素为单位
u16 biPlanes; // 位图的位面数必须为1
u16 biBitPerPixel; // 每个像素的位数, =1, 单色位图; =4, 16色; = 8, 256色; = 24 真彩色
u32 biCompression; // 位图压缩类型, =0, 不压缩BI_RGB; =1, BI_RLE8; = 2, BI_RLE4; = 3 BI_BITFIELDS; = 4, BI_JPEG; = 5, BI_PNG
u32 biBitmapDatSize;// 位图数据区的大小(字节数), 必须是4的整数倍
u32 biHResolution; // 水平分辨率, 像素/米
u32 biVResolution; // 垂直分辨率, 像素/米
u32 biColors; // 颜色数
u32 biImpColors; // 重要颜色数
BmpRgbQuad palette[2]; // 调色板
}__attribute__ ((packed)) BitmapHead;
// 压缩位图文件头
typedef struct
{
// 0
u32 fileId; // 整个位图文件标识
u32 blkIdx; // 当前位图块号(位图分块后的编号)
u32 datSize; // 本块位图数据区的大小(字节数)
u32 biWidth; // 本块位图有效宽度,以像素为单位
u32 biHeight; // 本块位图有效高度,以像素为单位
u32 dataChecksum; // 本块位图数据累加校验和
u32 begPos; // 本块位图起始位置(像素单位)
u32 endPos; // 本块位图结束位置(像素单位)
// 32
u8 compType; // 本块位图压缩类型, =0, 不压缩; =1, 按字节压缩;
u8 compDir; // 本块位图压缩方向, =0, 从上到下; =1, 从下到上;(喷墨方向)
// 34
u8 rev[64-2-34]; // 保留
// 62
u16 checkCrc; // 前面字段的CRC校验
}__attribute__ ((packed)) CompBmpHead;
#pragma pack(pop)
class BWBmp
{
public:
BWBmp();
public:
int LoadBiBmp(QString filename);
int SavePrBmp(QString filename);
int Compress(int idx = 0, int dir = 1);
int LoadPrBmp(QString filename);
int Unpress();
int SaveBiBmp(QString filename);
QByteArray getPrBmpDat();
private:
QByteArray m_bwDdat;
QByteArray m_prDdat;
QByteArray m_rbwDdat;
QString m_fileName;
};
#endif // BWBMP_H

130
bmp/creatprintbmp.cpp Normal file
View File

@ -0,0 +1,130 @@
#include "creatprintbmp.h"
CreatPrintBmp::CreatPrintBmp(QObject *parent) : QObject(parent)
{
m_savePath.clear();
m_mcIdx = 0;
}
CreatPrintBmp::~CreatPrintBmp()
{
}
void CreatPrintBmp::slotCreatBmp()
{
QPen pen;
pen.setWidth(1);
pen.setColor(QColor(Qt::black));
//将picture保存为多个宽度为2400像素的bmp
int num = m_picture.width() / PIXMAPWIDTH;
int lwidth = m_picture.width() % PIXMAPWIDTH;
int height = m_picture.height();
int offset = 0;
if(lwidth != 0)
{
num += 1;
}
QBitmap *pixmap = new QBitmap(PIXMAPWIDTH,height);
QPainter *pixPainter = new QPainter();
pixPainter->setPen(pen);
pixPainter->begin(pixmap);
for(int i = 0 ; i < num; i++)
{
pixmap->fill(Qt::white);//用白色填充
pixPainter->drawPicture(offset,0,m_picture);
offset -= PIXMAPWIDTH;
QString path = m_savePath+QString::number(i+1)+".bmp";
bool bls = pixmap->save(path);
while(bls == false)
{
bls = pixmap->save(path);
qDebug()<<"pixmap save failed";
}
//压缩位图
BWBmp bwBmp;
int rslt;
rslt = bwBmp.LoadBiBmp(path);
if (rslt != 0)
{
qDebug() << "open file error" << path;
break;
}
rslt = bwBmp.Compress();
if (rslt != 0)
{
qDebug() << "Compress error";
break;
}
rslt = bwBmp.SavePrBmp(path+".prbmp");
if (rslt != 0)
{
qDebug() << "save prbmp error";
break;
}
QByteArray dat = bwBmp.getPrBmpDat();
siCreatOneBmpFinished(m_mcIdx,(u8*)dat.data(),dat.size());
}
pixPainter->end();
bool bla = pixPainter->isActive();
while(bla == true)
{
bla = pixPainter->isActive();
qDebug()<<"pixPainter isActive";
}
delete pixmap;
delete pixPainter;
}
void CreatPrintBmp::setPicture(QPicture pic)
{
m_picture = pic;
}
void CreatPrintBmp::setPicture(QBitmap bitmap)
{
//将图片画在picture上
QPicture pic;
QPen pen;
pen.setWidth(1);//设置笔号
pen.setColor(QColor(Qt::black));
QPainter painter;
painter.begin(&pic);
painter.setPen(pen);
painter.drawPixmap(0,0,bitmap);
painter.end();
m_picture = pic;
}
void CreatPrintBmp::setSavePath(QString path)
{
m_savePath.clear();
m_savePath = path;
}
void CreatPrintBmp::setMcIdx(int idx)
{
m_mcIdx = idx;
}
QString CreatPrintBmp::getSavePath()
{
return m_savePath;
}

41
bmp/creatprintbmp.h Normal file
View File

@ -0,0 +1,41 @@
#ifndef CREATPRINTBMP_H
#define CREATPRINTBMP_H
#include <QObject>
#include <QPicture>
#include <QPainter>
#include <QPicture>
#include <QDebug>
#include <QFile>
#include <QBitmap>
#include "bwbmp.h"
#include "main.h"
class CreatPrintBmp : public QObject
{
Q_OBJECT
public:
explicit CreatPrintBmp(QObject *parent = NULL);
~CreatPrintBmp();
private:
QPicture m_picture;//绘图路径-线段
QString m_savePath;
int m_mcIdx;//机器索引
public:
void setPicture(QPicture pic);
void setPicture(QBitmap bitmap);
void setSavePath(QString path);
void setMcIdx(int idx);
QString getSavePath();
signals:
void siCreatOneBmpFinished(int mcIdx,u8 *dat,int datSize);
public slots:
void slotCreatBmp();
};
#endif // CREATPRINTBMP_H

BIN
datafile/dxf.zip Normal file

Binary file not shown.

520
datafile/dxf/dxfhelper.cpp Normal file
View File

@ -0,0 +1,520 @@
#include "dxfhelper.h"
#include "dxfreader.h"
#include <QImage>
#include <QPainter>
DxfHelper::DxfHelper()
{
}
double norm(double x, double y)
{
return sqrt(x * x + y * y);
}
QList<QVector3D> DxfHelper::expandPolygon(QList<QVector3D> polygon, float expand)
{
QList<QVector3D> new_polygon;
int len = polygon.length();
if(len<3||qFuzzyIsNull(expand)) return polygon;
bool repeatFlag = false;
if(polygon.first()==polygon.back()) {
repeatFlag = true;
polygon.removeLast();
len = polygon.length();
}
int convertNum = 0;
for (int i = 0; i < len; i++)
{
QVector3D p = polygon[i];
QVector3D p1 = polygon[i == 0 ? len - 1 : i - 1];
QVector3D p2 = polygon[i == len - 1 ? 0 : i + 1];
float v1x = p1.x() - p.x();
float v1y = p1.y() - p.y();
float n1 = norm(v1x, v1y);
float vv1x = v1x / n1;
float vv1y = v1y / n1;
float v2x = p2.x() - p.x();
float v2y = p2.y() - p.y();
float n2 = norm(v2x, v2y);
float vv2x = v2x / n2;
float vv2y = v2y / n2;
float vectorLen = -expand / sqrt((1 - (vv1x * vv2x + vv1y * vv2y)) / 2.0f);
float judge = v1x * v2y - v2x * v1y;
if (judge < 0) vectorLen *= -1;
if (judge < 0) convertNum++;
float vx = vv1x + vv2x;
float vy = vv1y + vv2y;
vectorLen = vectorLen / norm(vx, vy);
vx *= vectorLen;
vy *= vectorLen;
new_polygon.append(QVector3D(vx + p.x(), vy + p.y(), 0));
}
if(convertNum==len) {
new_polygon.clear();
for (int i = 0; i < len; i++)
{
QVector3D p = polygon[i];
QVector3D p1 = polygon[i == 0 ? len - 1 : i - 1];
QVector3D p2 = polygon[i == len - 1 ? 0 : i + 1];
float v1x = p1.x() - p.x();
float v1y = p1.y() - p.y();
float n1 = norm(v1x, v1y);
float vv1x = v1x / n1;
float vv1y = v1y / n1;
float v2x = p2.x() - p.x();
float v2y = p2.y() - p.y();
float n2 = norm(v2x, v2y);
float vv2x = v2x / n2;
float vv2y = v2y / n2;
float vectorLen = -expand / sqrt((1 - (vv1x * vv2x + vv1y * vv2y)) / 2.0f);
float vx = vv1x + vv2x;
float vy = vv1y + vv2y;
vectorLen = vectorLen / norm(vx, vy);
vx *= vectorLen;
vy *= vectorLen;
new_polygon.append(QVector3D(vx + p.x(), vy + p.y(), 0));
}
}
if(repeatFlag) new_polygon.append(new_polygon.first());
return new_polygon;
}
bool DxfHelper::generateDxf(const QString &fileName)
{
// currentPos = QPointF(QRandomGenerator::global()->bounded(9999.99), QRandomGenerator::global()->bounded(9999.99));
currentPos = QPointF(9999.99, 9999.99);
vertexIndex = 0;
controlIndex = 0;
dxfPaths.clear();
DxfReader dxfReader(fileName);
for(auto d: dxfReader.dxfText) {
//qDebug() << "text data:" << d.text.c_str() << d.angle << d.style.c_str() << d.height;
}
for(auto d: dxfReader.dxfLinetypes) {
//qDebug() << "linetypes data:" << d.name.c_str() << d.flags << d.pattern << d.description.c_str() << d.patternLength << d.numberOfDashes;
}
QVector<QPointF> linepath;
for(auto d: dxfReader.dxfLines) {
//qDebug() << "line data:" << d.x1 << d.y1 << d.z1 << "," << d.x2 << d.y2 << d.z2;
if(currentPos!=QPointF(d.x1, d.y1)) {
if(!linepath.isEmpty()) {
QList<QVector3D> linelist;
foreach(auto point, linepath) linelist.append(QVector3D(point));
linepath.clear();
linelist = expandPolygon(linelist, expandOffset);
foreach(QVector3D point, linelist) {
double x = point.x();
double y = point.y();
linepath.append(QPointF(x, y));
currentPos = QPointF(x, y);
}
dxfPaths.append(linepath);
linepath.clear();
}
linepath.append(QPointF(d.x1, d.y1));
linepath.append(QPointF(d.x2, d.y2));
currentPos = QPointF(d.x2, d.y2);
} else {
linepath.append(QPointF(d.x2, d.y2));
currentPos = QPointF(d.x2, d.y2);
}
}
if(!linepath.isEmpty()) {
QList<QVector3D> linelist;
foreach(auto point, linepath) linelist.append(QVector3D(point));
linepath.clear();
linelist = expandPolygon(linelist, expandOffset);
foreach(QVector3D point, linelist) {
double x = point.x();
double y = point.y();
linepath.append(QPointF(x, y));
currentPos = QPointF(x, y);
}
dxfPaths.append(linepath);
linepath.clear();
}
for(auto d: dxfReader.dxfArcs) {
//qDebug() << "arcs data:" << d.cx << d.cy << d.cz << d.angle1 << d.angle2 << d.radius;
double cx = d.cx;
double cy = d.cy;
// double cz = d.cz;
double angle1 = d.angle1;
double angle2 = d.angle2;
double radius = d.radius;
radius = radius + expandOffset;
QPainterPath path;
double startXPos = cx + cos(abs(angle1)*M_PI/180)*radius;
double startYPos = cy + sin(abs(angle1)*M_PI/180)*radius;
path.moveTo(startXPos, startYPos);
double angleStart ,anglePassed;
angleStart = angle1;
if(angleStart>=180) angleStart = angleStart-360;
anglePassed = angleStart-angle2;
if(angleStart<180) angleStart = -angleStart;
if(anglePassed<-360) anglePassed = anglePassed+360;
QRectF rect(cx-radius, cy-radius, 2*radius, 2*radius);
path.arcTo(rect, angleStart, anglePassed);
QVector<QPointF> arcpath;
for(double i = 0; i <= 1; i += 0.003) { // TODO: 步长随图片大小调整
QPointF point = path.pointAtPercent(i);
double x = point.x();
double y = point.y();
arcpath.append(point);
currentPos=QPointF(x, y);
}
dxfPaths.append(arcpath);
// dxfPathList.append(path);
}
for(auto d: dxfReader.dxfCircles) {
//qDebug() << "circle data:" << d.cx << d.cy << d.cz << d.radius;
double cx = d.cx;
double cy = d.cy;
// double cz = d.cz;
double radius = d.radius;
radius = radius + expandOffset;
QPainterPath path;
path.moveTo(cx+radius, cy);
path.arcTo(cx-radius, cy-radius, 2*radius, 2*radius, 0, 360);
QVector<QPointF> circlepath;
for(double i = 0; i <= 1; i += 0.003) { // TODO: 步长随图片大小调整
QPointF point = path.pointAtPercent(i);
double x = point.x();
double y = point.y();
circlepath.append(point);
currentPos=QPointF(x, y);
}
dxfPaths.append(circlepath);
// dxfPathList.append(path);
}
for(auto d: dxfReader.dxfEllipses) { // 起点角度要×ratio
//qDebug() << "ellipses data:" << d.cx << d.cy << d.cz << d.mx << d.my << d.mz << d.ratio << d.angle1 << d.angle2;
double cx = d.cx;
double cy = d.cy;
// double cz = d.cz;
double mx = d.mx;
double my = d.my;
// double mz = d.mz;
double ratio = d.ratio;
double angle1 = d.angle1;
double angle2 = d.angle2;
double rab = sqrt((cx- mx)*(cx - mx) +(cy - my)*(cy - my));
double resy = (expandOffset*(my-cy))/rab + my;
double resx = (expandOffset*(mx-cx))/rab + mx;
mx = resx;
my = resy;
QPainterPath path;
double angle_1 = angle1;
double angle_2 = angle2;
while(angle_1>=3.14&&angle_2>=6.28) {
angle_1 -= M_PI;
angle_2 -= M_PI;
}
angle_1 = angle_1*180/M_PI;
angle_2 = angle_2*180/M_PI;
double angleStart ,anglePassed;
angleStart = angle_1;
if(angleStart>=180) angleStart = angleStart-360;
anglePassed = angleStart-angle_2;
if(angleStart<180) angleStart = -angleStart;
if(anglePassed<-360) anglePassed = anglePassed+360;
if(abs(anglePassed)<1) anglePassed = 360;
double c_x = cx;
double c_y = cy;
double dl = sqrt(mx*mx+my*my);
double ds = dl*ratio;
double rx;
double ry;
if(qFuzzyIsNull(mx)) {
rx = ds; ry = dl;
angleStart += 90;
} else {
rx = dl; ry = ds;
}
double angle=angleStart;
if(angle<0) angle=-angle;
else if(angle>=0) angle = 360-angle;
//if(!qFuzzyCompare(abs(anglePassed),360)) angle *= ratio;
if(!qFuzzyCompare(float(anglePassed),(float)360)) angle *= ratio;
double a=qDegreesToRadians(angle);
double R=rx*ry/sqrt(pow(rx*sin(a),2)+pow(ry*cos(a),2)); //计算对应角度的半径
double startXPos=c_x+R*cos(a);
double startYPos=c_y+R*sin(a);
path.moveTo(startXPos, startYPos);
//qDebug() << c_x << c_y << rx << ry << angleStart << anglePassed << angle;
path.arcTo(c_x-rx, c_y-ry, 2*rx, 2*ry, angleStart, anglePassed);
QVector<QPointF> ellipsepath;
for(double i = 0; i <= 1; i += 0.003) { // TODO: 步长随图片大小调整
QPointF point = path.pointAtPercent(i);
double x = point.x();
double y = point.y();
ellipsepath.append(point);
currentPos=QPointF(x, y);
}
dxfPaths.append(ellipsepath);
// dxfPathList.append(path);
}
for(auto d: dxfReader.dxfPolylines) {
//qDebug() << "polylines data:" << d.m << d.n << d.flags << d.number << d.elevation;
QList<QVector3D> pointlist;
QVector<QPointF> path;
for(unsigned int i = 0; i < d.number; i++) {
double x = dxfReader.dxfVertexs.at(vertexIndex).x;
double y = dxfReader.dxfVertexs.at(vertexIndex).y;
double z = dxfReader.dxfVertexs.at(vertexIndex).z;
pointlist.append(QVector3D(x, y, z));
vertexIndex++;
}
pointlist = expandPolygon(pointlist, expandOffset);
foreach(QVector3D point, pointlist) {
double x = point.x();
double y = point.y();
path.append(QPointF(x, y));
currentPos = QPointF(x, y);
}
if(d.flags) {
double x = pointlist.first().x();
double y = pointlist.first().y();
path.append(QPointF(x, y));
currentPos = QPointF(x, y);
}
dxfPaths.append(path);
}
// for(auto d: dxfReader.dxfVertexs) {
// qDebug() << "vertexs data:" << d.x << d.y << d.z << d.bulge;
// }
for(auto d: dxfReader.dxfPoints) {
//qDebug() << "points data:" << d.x << d.y << d.z;
QVector<QPointF> path;
path.append(QPointF(d.x, d.y));
dxfPaths.append(path);
currentPos = QPointF(d.x, d.y);
}
for(auto d: dxfReader.dxfSplines) {
//qDebug() << "splines data:" << d.nFit << d.flags << d.degree << d.nKnots << d.nControl << d.tangentEndX << d.tangentEndY << d.tangentEndZ << d.tangentStartX << d.tangentStartY << d.tangentStartZ;
std::vector<QVector2D> pointList;
for(unsigned int i = 0; i < d.nControl; i++) {
int x = dxfReader.dxfControlPoints.at(controlIndex).x;
int y = dxfReader.dxfControlPoints.at(controlIndex).y;
pointList.push_back(QVector2D(x, y));
currentPos = QPointF(x, y);
controlIndex++;
}
QList<QVector3D> templist;
foreach(auto point, pointList) templist.append(point);
templist = expandPolygon(templist, expandOffset);
QVector<QVector2D> inputList;
foreach(auto point, templist) inputList.append(point.toVector2D());
inputList.push_front(inputList.first());
inputList.push_back(inputList.back());
// std::vector<QVector2D> finalList(inputList.begin(), inputList.end());
// SplineHelper splineHelper(finalList, TypeCubicBSpline);
// auto splinePath = splineHelper.getSplinePath();
// dxfPaths.append(splinePath);
}
// for(auto d: dxfReader.dxfControlPoints) {
// qDebug() << "control points data:" << d.w << d.x << d.y << d.z;
// }
// for(auto d: dxfReader.dxfXLines) {
// qDebug() << "XLines data:" << d.bx << d.by << d.bz << d.dx << d.dy << d.dz;
// }
// for(auto d: dxfReader.dxfRays) {
// qDebug() << "rays data:" << d.bx << d.by << d.bz << d.dx << d.dy << d.dz;
// }
// for(auto d: dxfReader.dxfFitPoints) {
// qDebug() << "fit points data:" << d.x << d.y << d.z;
// }
// for(auto d: dxfReader.dxfHatchs) {
// qDebug() << "hatchs data:" << d.angle << d.scale << d.solid << d.originX << d.originY << d.pattern.c_str() << d.numLoops;
// }
// for(auto d: dxfReader.dxfHatchLoops) {
// qDebug() << "hatchLoops data:" << d.numEdges;
// }
// for(auto d: dxfReader.dxfHatchEdges) {
// qDebug() << "hatchEdges data:" << d.cx << d.cy << d.mx << d.my << d.x1 << d.y1 << d.x2 << d.y2 << d.ccw << d.nFit << d.ratio << d.angle1 << d.angle2 << d.degree << d.nKnots << d.radius << d.defined << d.weights << d.nControl << d.periodic << d.rational << d.vertices << d.fitPoints << d.endTangentX << d.endTangentY << d.endTangentY << d.controlPoints << d.startTangentX << d.startTangentY;
// }
return true;
}
void DxfHelper::matchDXFSize()
{
double minx = __DBL_MAX__;
double maxx = __DBL_MIN__;
double miny = __DBL_MAX__;
double maxy = __DBL_MIN__;
foreach (QVector<QPointF> path, dxfPaths) {
for(int i = 0; i < path.length(); i++) {
QPointF point = path.at(i);
double x = point.x();
double y = point.y();
if(x<minx) minx = x;
if(x>maxx) maxx = x;
if(y<miny) miny = y;
if(y>maxy) maxy = y;
}
}
int width = maxx - minx;
int height = maxy - miny;
imageSize = QSize(width, height);
dxfBorderList.clear();
dxfBorderList.append(minx);
dxfBorderList.append(miny);
dxfBorderList.append(maxx);
dxfBorderList.append(maxy);
}
QImage DxfHelper::generateDXFImage()
{
matchDXFSize();
double minx = dxfBorderList.at(0);
double miny = dxfBorderList.at(1);
int penwidth = imageSize.width()/400;
int border = penwidth;
QImage image((imageSize.width()+2*border), (imageSize.height()+2*border), QImage::Format_ARGB32);
image.fill(Qt::white);
QPainter p(&image);
p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); // 抗锯齿和使用平滑转换算法
QPen pen;
if(penwidth<1) penwidth = 1;
pen.setWidth(penwidth);
pen.setColor(Qt::black);
p.setPen(pen);
QPainterPath painterpath;
foreach (QVector<QPointF> path, dxfPaths) {
for(int i = 0; i < path.length(); i++) {
double x = path.at(i).x()-minx;
double y = path.at(i).y()-miny;
y = imageSize.height()-y;
x += border;
y += border;
QPointF point(x, y);
if(i == 0) painterpath.moveTo(point);
else painterpath.lineTo(point);
}
// dxfPathList.append(painterpath);
}
//qDebug() << "[" << __FILE__ << ":" << __LINE__ << "]\t"<< "dxf path length:" <<dxfPaths.length();
p.drawPath(painterpath);
p.end();
return image;
}
QList<double> DxfHelper::getDxfBorderList() const
{
return dxfBorderList;
}
QSize DxfHelper::getImageSize() const
{
return imageSize;
}
QList<QPainterPath> DxfHelper::getDxfPathList() const
{
return dxfPathList;
}
QVector<QVector<QPointF> > DxfHelper::getDxfPaths() const
{
return dxfPaths;
}
QList<DXFLine> DxfHelper::getDxfLineList() const
{
return dxfLineList;
}
QList<DXFRect> DxfHelper::getDxfRectList() const
{
return dxfRectList;
}
QList<DXFArc> DxfHelper::getDxfArcList() const
{
return dxfArcList;
}
QList<DXFCircle> DxfHelper::getDxfCircleList() const
{
return dxfCircleList;
}
QList<DXFEllipse> DxfHelper::getDxfEllipseList() const
{
return dxfEllipseList;
}
QList<DXFPolyline> DxfHelper::getDxfPolylineList() const
{
return dxfPolylineList;
}
QList<DXFSpline> DxfHelper::getDxfSplineList() const
{
return dxfSplineList;
}
void DxfHelper::setExpandOffset(double value)
{
expandOffset = value;
}

114
datafile/dxf/dxfhelper.h Normal file
View File

@ -0,0 +1,114 @@
#ifndef DXFHELPER_H
#define DXFHELPER_H
#include <QPointF>
//#include <QRandomGenerator>
#include <QDebug>
#include <QPainterPath>
#include <QtMath>
#include <QVector2D>
#include <QVector3D>
//#include <spline_library/splinehelper.h>
#include <QVector>
#include <QList>
//qRegisterMetaType<QVector<int> >("QVector<int>");
//qRegisterMetaType<QList>("QList");
struct DXFLine {
double x1;
double y1;
double z1;
double x2;
double y2;
double z2;
};
struct DXFRect {
QList<QVector3D> list;
};
struct DXFArc {
double cx;
double cy;
double cz;
double angle1;
double angle2;
double radius;
};
struct DXFCircle {
double cx;
double cy;
double cz;
double radius;
};
struct DXFEllipse {
double cx;
double cy;
double cz;
double mx;
double my;
double mz;
double angle1;
double angle2;
double ratio;
};
struct DXFPolyline {
double flags;
double number;
QList<QVector3D> list;
};
struct DXFSpline {
double nControl;
QList<QVector3D> controlPoints;
};
class DxfHelper
{
public:
DxfHelper();
QList<QVector3D> expandPolygon(QList<QVector3D> polygon, float expand);
bool generateDxf(const QString &fileName);
QVector<QVector<QPointF>> getDxfPaths() const;
QList<DXFLine> getDxfLineList() const;
QList<DXFRect> getDxfRectList() const;
QList<DXFArc> getDxfArcList() const;
QList<DXFCircle> getDxfCircleList() const;
QList<DXFEllipse> getDxfEllipseList() const;
QList<DXFPolyline> getDxfPolylineList() const;
QList<DXFSpline> getDxfSplineList() const;
void setExpandOffset(double value);
void matchDXFSize();
QImage generateDXFImage();
QList<QPainterPath> getDxfPathList() const;
QSize getImageSize() const;
QList<double> getDxfBorderList() const;
private:
QPointF currentPos;
unsigned int vertexIndex = 0;
unsigned int controlIndex = 0;
QVector<QVector<QPointF>> dxfPaths;
QList<QPainterPath> dxfPathList;
double expandOffset = 0;
QList<DXFLine> dxfLineList;
QList<DXFRect> dxfRectList;
QList<DXFArc> dxfArcList;
QList<DXFCircle> dxfCircleList;
QList<DXFEllipse> dxfEllipseList;
QList<DXFPolyline> dxfPolylineList;
QList<DXFSpline> dxfSplineList;
QList<double> dxfBorderList;
QSize imageSize;
};
#endif // DXFHELPER_H

View File

@ -0,0 +1,237 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_ATTRIBUTES_H
#define DL_ATTRIBUTES_H
#include "dl_global.h"
#include <string>
#include <vector>
#include "dl_codes.h"
/**
* Storing and passing around attributes. Attributes
* are the layer name, color, width and line type.
*
* @author Andrew Mustun
*/
class DXFLIB_EXPORT DL_Attributes {
public:
/**
* Default constructor.
*/
DL_Attributes() :
layer(""),
color(0),
color24(-1),
width(0),
linetype("BYLAYER"),
linetypeScale(1.0),
handle(-1),
inPaperSpace(false) {
}
/**
* Constructor for DXF attributes.
*
* @param layer Layer name for this entity or NULL for no layer
* (every entity should be on a named layer!).
* @param color Color number (0..256). 0 = BYBLOCK, 256 = BYLAYER.
* @param width Line thickness. Defaults to zero. -1 = BYLAYER,
* -2 = BYBLOCK, -3 = default width
* @param linetype Line type name or "BYLAYER" or "BYBLOCK". Defaults
* to "BYLAYER"
*/
DL_Attributes(const std::string& layer,
int color, int width,
const std::string& linetype,
double linetypeScale) :
layer(layer),
color(color),
color24(-1),
width(width),
linetype(linetype),
linetypeScale(linetypeScale),
handle(-1),
inPaperSpace(false) {
}
/**
* Constructor for DXF attributes.
*
* @param layer Layer name for this entity or NULL for no layer
* (every entity should be on a named layer!).
* @param color Color number (0..256). 0 = BYBLOCK, 256 = BYLAYER.
* @param color24 24 bit color (0x00RRGGBB, see DXF reference).
* @param width Line thickness. Defaults to zero. -1 = BYLAYER,
* -2 = BYBLOCK, -3 = default width
* @param linetype Line type name or "BYLAYER" or "BYBLOCK". Defaults
* to "BYLAYER"
*/
DL_Attributes(const std::string& layer,
int color, int color24, int width,
const std::string& linetype,
int handle=-1) :
layer(layer),
color(color),
color24(color24),
width(width),
linetype(linetype),
linetypeScale(1.0),
handle(handle),
inPaperSpace(false) {
}
/**
* Sets the layer. If the given pointer points to NULL, the
* new layer name will be an empty but valid string.
*/
void setLayer(const std::string& layer) {
this->layer = layer;
}
/**
* @return Layer name.
*/
std::string getLayer() const {
return layer;
}
/**
* Sets the color.
*
* @see DL_Codes, dxfColors
*/
void setColor(int color) {
this->color = color;
}
/**
* Sets the 24bit color.
*
* @see DL_Codes, dxfColors
*/
void setColor24(int color) {
this->color24 = color;
}
/**
* @return Color.
*
* @see DL_Codes, dxfColors
*/
int getColor() const {
return color;
}
/**
* @return 24 bit color or -1 if no 24bit color is defined.
*
* @see DL_Codes, dxfColors
*/
int getColor24() const {
return color24;
}
/**
* Sets the width.
*/
void setWidth(int width) {
this->width = width;
}
/**
* @return Width.
*/
int getWidth() const {
return width;
}
/**
* Sets the line type. This can be any string and is not
* checked to be a valid line type.
*/
void setLinetype(const std::string& linetype) {
this->linetype = linetype;
}
/**
* Sets the entity specific line type scale.
*/
void setLinetypeScale(double linetypeScale) {
this->linetypeScale = linetypeScale;
}
double getLinetypeScale() const {
return linetypeScale;
}
/**
* @return Line type.
*/
std::string getLinetype() const {
if (linetype.length()==0) {
return "BYLAYER";
} else {
return linetype;
}
}
void setHandle(int h) {
handle = h;
}
int getHandle() const {
return handle;
}
void setInPaperSpace(bool on) {
inPaperSpace = on;
}
bool isInPaperSpace() const {
return inPaperSpace;
}
private:
std::string layer;
int color;
int color24;
int width;
std::string linetype;
double linetypeScale;
int handle;
// DXF code 67 (true: entity in paper space, false: entity in model space (default):
bool inPaperSpace;
};
#endif
// EOF

View File

@ -0,0 +1,546 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
** Copyright (C) 2001 Robert J. Campbell Jr.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
/**
* Defines common DXF codes and constants.
*/
#ifndef DXF_CODES_H
#define DXF_CODES_H
#include "dl_global.h"
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//#if defined(__OS2__)||defined(__EMX__)
//#define strcasecmp(s,t) stricmp(s,t)
//#endif
//#if defined(_WIN32)
//#define strcasecmp(s,t) _stricmp(s,t)
//#endif
#ifdef _WIN32
#undef M_PI
#define M_PI 3.14159265358979323846
//#pragma warning(disable : 4800)
#endif
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
#define DL_DXF_MAXLINE 1024
#define DL_DXF_MAXGROUPCODE 1100
// used to mark invalid vectors:
//#define DL_DXF_MAXDOUBLE 1.0E+10
/**
* Codes for colors and DXF versions.
*/
class DXFLIB_EXPORT DL_Codes {
public:
/**
* Standard DXF colors.
*/
enum color {
black = 250,
green = 3,
red = 1,
brown = 15,
yellow = 2,
cyan = 4,
magenta = 6,
gray = 8,
blue = 5,
l_blue = 163,
l_green = 121,
l_cyan = 131,
l_red = 23,
l_magenta = 221,
l_gray = 252,
white = 7,
bylayer = 256,
byblock = 0
};
/**
* Version numbers for the DXF Format.
*/
enum version {
AC1009_MIN, // R12, minimalistic
AC1009, // R12
AC1012,
AC1014,
AC1015 // R2000
};
};
// Extended color palette:
// The first entry is only for direct indexing starting with [1]
// Color 1 is red (1,0,0)
const double dxfColors[][3] = {
{0,0,0}, // unused
{1,0,0}, // 1
{1,1,0},
{0,1,0},
{0,1,1},
{0,0,1},
{1,0,1},
{1,1,1}, // black or white
{0.5,0.5,0.5},
{0.75,0.75,0.75},
{1,0,0}, // 10
{1,0.5,0.5},
{0.65,0,0},
{0.65,0.325,0.325},
{0.5,0,0},
{0.5,0.25,0.25},
{0.3,0,0},
{0.3,0.15,0.15},
{0.15,0,0},
{0.15,0.075,0.075},
{1,0.25,0}, // 20
{1,0.625,0.5},
{0.65,0.1625,0},
{0.65,0.4063,0.325},
{0.5,0.125,0},
{0.5,0.3125,0.25},
{0.3,0.075,0},
{0.3,0.1875,0.15},
{0.15,0.0375,0},
{0.15,0.0938,0.075},
{1,0.5,0}, // 30
{1,0.75,0.5},
{0.65,0.325,0},
{0.65,0.4875,0.325},
{0.5,0.25,0},
{0.5,0.375,0.25},
{0.3,0.15,0},
{0.3,0.225,0.15},
{0.15,0.075,0},
{0.15,0.1125,0.075},
{1,0.75,0}, // 40
{1,0.875,0.5},
{0.65,0.4875,0},
{0.65,0.5688,0.325},
{0.5,0.375,0},
{0.5,0.4375,0.25},
{0.3,0.225,0},
{0.3,0.2625,0.15},
{0.15,0.1125,0},
{0.15,0.1313,0.075},
{1,1,0}, // 50
{1,1,0.5},
{0.65,0.65,0},
{0.65,0.65,0.325},
{0.5,0.5,0},
{0.5,0.5,0.25},
{0.3,0.3,0},
{0.3,0.3,0.15},
{0.15,0.15,0},
{0.15,0.15,0.075},
{0.75,1,0}, // 60
{0.875,1,0.5},
{0.4875,0.65,0},
{0.5688,0.65,0.325},
{0.375,0.5,0},
{0.4375,0.5,0.25},
{0.225,0.3,0},
{0.2625,0.3,0.15},
{0.1125,0.15,0},
{0.1313,0.15,0.075},
{0.5,1,0}, // 70
{0.75,1,0.5},
{0.325,0.65,0},
{0.4875,0.65,0.325},
{0.25,0.5,0},
{0.375,0.5,0.25},
{0.15,0.3,0},
{0.225,0.3,0.15},
{0.075,0.15,0},
{0.1125,0.15,0.075},
{0.25,1,0}, // 80
{0.625,1,0.5},
{0.1625,0.65,0},
{0.4063,0.65,0.325},
{0.125,0.5,0},
{0.3125,0.5,0.25},
{0.075,0.3,0},
{0.1875,0.3,0.15},
{0.0375,0.15,0},
{0.0938,0.15,0.075},
{0,1,0}, // 90
{0.5,1,0.5},
{0,0.65,0},
{0.325,0.65,0.325},
{0,0.5,0},
{0.25,0.5,0.25},
{0,0.3,0},
{0.15,0.3,0.15},
{0,0.15,0},
{0.075,0.15,0.075},
{0,1,0.25}, // 100
{0.5,1,0.625},
{0,0.65,0.1625},
{0.325,0.65,0.4063},
{0,0.5,0.125},
{0.25,0.5,0.3125},
{0,0.3,0.075},
{0.15,0.3,0.1875},
{0,0.15,0.0375},
{0.075,0.15,0.0938},
{0,1,0.5}, // 110
{0.5,1,0.75},
{0,0.65,0.325},
{0.325,0.65,0.4875},
{0,0.5,0.25},
{0.25,0.5,0.375},
{0,0.3,0.15},
{0.15,0.3,0.225},
{0,0.15,0.075},
{0.075,0.15,0.1125},
{0,1,0.75}, // 120
{0.5,1,0.875},
{0,0.65,0.4875},
{0.325,0.65,0.5688},
{0,0.5,0.375},
{0.25,0.5,0.4375},
{0,0.3,0.225},
{0.15,0.3,0.2625},
{0,0.15,0.1125},
{0.075,0.15,0.1313},
{0,1,1}, // 130
{0.5,1,1},
{0,0.65,0.65},
{0.325,0.65,0.65},
{0,0.5,0.5},
{0.25,0.5,0.5},
{0,0.3,0.3},
{0.15,0.3,0.3},
{0,0.15,0.15},
{0.075,0.15,0.15},
{0,0.75,1}, // 140
{0.5,0.875,1},
{0,0.4875,0.65},
{0.325,0.5688,0.65},
{0,0.375,0.5},
{0.25,0.4375,0.5},
{0,0.225,0.3},
{0.15,0.2625,0.3},
{0,0.1125,0.15},
{0.075,0.1313,0.15},
{0,0.5,1}, // 150
{0.5,0.75,1},
{0,0.325,0.65},
{0.325,0.4875,0.65},
{0,0.25,0.5},
{0.25,0.375,0.5},
{0,0.15,0.3},
{0.15,0.225,0.3},
{0,0.075,0.15},
{0.075,0.1125,0.15},
{0,0.25,1}, // 160
{0.5,0.625,1},
{0,0.1625,0.65},
{0.325,0.4063,0.65},
{0,0.125,0.5},
{0.25,0.3125,0.5},
{0,0.075,0.3},
{0.15,0.1875,0.3},
{0,0.0375,0.15},
{0.075,0.0938,0.15},
{0,0,1}, // 170
{0.5,0.5,1},
{0,0,0.65},
{0.325,0.325,0.65},
{0,0,0.5},
{0.25,0.25,0.5},
{0,0,0.3},
{0.15,0.15,0.3},
{0,0,0.15},
{0.075,0.075,0.15},
{0.25,0,1}, // 180
{0.625,0.5,1},
{0.1625,0,0.65},
{0.4063,0.325,0.65},
{0.125,0,0.5},
{0.3125,0.25,0.5},
{0.075,0,0.3},
{0.1875,0.15,0.3},
{0.0375,0,0.15},
{0.0938,0.075,0.15},
{0.5,0,1}, // 190
{0.75,0.5,1},
{0.325,0,0.65},
{0.4875,0.325,0.65},
{0.25,0,0.5},
{0.375,0.25,0.5},
{0.15,0,0.3},
{0.225,0.15,0.3},
{0.075,0,0.15},
{0.1125,0.075,0.15},
{0.75,0,1}, // 200
{0.875,0.5,1},
{0.4875,0,0.65},
{0.5688,0.325,0.65},
{0.375,0,0.5},
{0.4375,0.25,0.5},
{0.225,0,0.3},
{0.2625,0.15,0.3},
{0.1125,0,0.15},
{0.1313,0.075,0.15},
{1,0,1}, // 210
{1,0.5,1},
{0.65,0,0.65},
{0.65,0.325,0.65},
{0.5,0,0.5},
{0.5,0.25,0.5},
{0.3,0,0.3},
{0.3,0.15,0.3},
{0.15,0,0.15},
{0.15,0.075,0.15},
{1,0,0.75}, // 220
{1,0.5,0.875},
{0.65,0,0.4875},
{0.65,0.325,0.5688},
{0.5,0,0.375},
{0.5,0.25,0.4375},
{0.3,0,0.225},
{0.3,0.15,0.2625},
{0.15,0,0.1125},
{0.15,0.075,0.1313},
{1,0,0.5}, // 230
{1,0.5,0.75},
{0.65,0,0.325},
{0.65,0.325,0.4875},
{0.5,0,0.25},
{0.5,0.25,0.375},
{0.3,0,0.15},
{0.3,0.15,0.225},
{0.15,0,0.075},
{0.15,0.075,0.1125},
{1,0,0.25}, // 240
{1,0.5,0.625},
{0.65,0,0.1625},
{0.65,0.325,0.4063},
{0.5,0,0.125},
{0.5,0.25,0.3125},
{0.3,0,0.075},
{0.3,0.15,0.1875},
{0.15,0,0.0375},
{0.15,0.075,0.0938},
{0.33,0.33,0.33}, // 250
{0.464,0.464,0.464},
{0.598,0.598,0.598},
{0.732,0.732,0.732},
{0.866,0.866,0.866},
{1,1,1} // 255
}
;
// AutoCAD VERSION aliases
#define DL_VERSION_R12 DL_Codes::AC1009
#define DL_VERSION_LT2 DL_Codes::AC1009
#define DL_VERSION_R13 DL_Codes::AC1012 // not supported yet
#define DL_VERSION_LT95 DL_Codes::AC1012 // not supported yet
#define DL_VERSION_R14 DL_Codes::AC1014 // not supported yet
#define DL_VERSION_LT97 DL_Codes::AC1014 // not supported yet
#define DL_VERSION_LT98 DL_Codes::AC1014 // not supported yet
#define DL_VERSION_2000 DL_Codes::AC1015
#define DL_VERSION_2002 DL_Codes::AC1015
// DXF Group Codes:
// Strings
#define DL_STRGRP_START 0
#define DL_STRGRP_END 9
// Coordinates
#define DL_CRDGRP_START 10
#define DL_CRDGRP_END 19
// Real values
#define DL_RLGRP_START 38
#define DL_RLGRP_END 59
// Short integer values
#define DL_SHOGRP_START 60
#define DL_SHOGRP_END 79
// New in Release 13,
#define DL_SUBCLASS 100
// More coordinates
#define DL_CRD2GRP_START 210
#define DL_CRD2GRP_END 239
// Extended data strings
#define DL_ESTRGRP_START 1000
#define DL_ESTRGRP_END 1009
// Extended data reals
#define DL_ERLGRP_START 1010
#define DL_ERLGRP_END 1059
#define DL_Y8_COORD_CODE 28
#define DL_Z0_COORD_CODE 30
#define DL_Z8_COORD_CODE 38
#define DL_POINT_COORD_CODE 10
#define DL_INSERT_COORD_CODE 10
#define DL_CRD2GRP_START 210
#define DL_CRD2GRP_END 239
#define DL_THICKNESS 39
#define DL_FIRST_REAL_CODE THICKNESS
#define DL_LAST_REAL_CODE 59
#define DL_FIRST_INT_CODE 60
#define DL_ATTFLAGS_CODE 70
#define DL_PLINE_FLAGS_CODE 70
#define DL_LAYER_FLAGS_CODE 70
#define DL_FLD_LEN_CODE 73 // Inside ATTRIB resbuf
#define DL_LAST_INT_CODE 79
#define DL_X_EXTRU_CODE 210
#define DL_Y_EXTRU_CODE 220
#define DL_Z_EXTRU_CODE 230
#define DL_COMMENT_CODE 999
// Start and endpoints of a line
#define DL_LINE_START_CODE 10 // Followed by x coord
#define DL_LINE_END_CODE 11 // Followed by x coord
// Some codes used by blocks
#define DL_BLOCK_FLAGS_CODE 70 // An int containing flags
#define DL_BLOCK_BASE_CODE 10 // Origin of block definition
#define DL_XREF_DEPENDENT 16 // If a block contains an XREF
#define DL_XREF_RESOLVED 32 // If a XREF resolved ok
#define DL_REFERENCED 64 // If a block is ref'd in DWG
#define DL_XSCALE_CODE 41
#define DL_YSCALE_CODE 42
#define DL_ANGLE_CODE 50
#define DL_INS_POINT_CODE 10 // Followed by x of ins pnt
#define DL_NAME2_CODE 3 // Second appearance of name
// Some codes used by circle entities
#define DL_CENTER_CODE 10 // Followed by x of center
#define DL_RADIUS_CODE 40 // Followd by radius of circle
#define DL_COND_OP_CODE -4 // Conditional op,ads_ssget
// When using ads_buildlist you MUST use RTDXF0 instead of these
#define DL_ENTITY_TYPE_CODE 0 // Then there is LINE, 3DFACE..
#define DL_SES_CODE 0 // Start End String Code
#define DL_FILE_SEP_CODE 0 // File separator
#define DL_SOT_CODE 0 // Start Of Table
#define DL_TEXTVAL_CODE 1
#define DL_NAME_CODE 2
#define DL_BLOCK_NAME_CODE 2
#define DL_SECTION_NAME_CODE 2
#define DL_ENT_HAND_CODE 5 // What follows is hexa string
#define DL_TXT_STYLE_CODE 7 // Inside attributes
#define DL_LAYER_NAME_CODE 8 // What follows is layer name
#define DL_FIRST_XCOORD_CODE 10 // Group code x of 1st coord
#define DL_FIRST_YCOORD_CODE 20 // Group code y of 1st coord
#define DL_FIRST_ZCOORD_CODE 30 // Group code z of 1st coord
#define DL_L_START_CODE 10
#define DL_L_END_CODE 11
#define DL_TXTHI_CODE 40
#define DL_SCALE_X_CODE 41
#define DL_SCALE_Y_CODE 42
#define DL_SCALE_Z_CODE 43
#define DL_BULGE_CODE 42 // Used in PLINE verts for arcs
#define DL_ROTATION_CODE 50
#define DL_COLOUR_CODE 62 // What follows is a color int
#define DL_LTYPE_CODE 6 // What follows is a linetype
// Attribute flags
#define DL_ATTS_FOLLOW_CODE 66
#define DL_ATT_TAG_CODE 2
#define DL_ATT_VAL_CODE 1
#define DL_ATT_FLAGS_CODE 70 // 4 1 bit flags as follows...
#define DL_ATT_INVIS_FLAG 1
#define DL_ATT_CONST_FLAG 2
#define DL_ATT_VERIFY_FLAG 4 // Prompt and verify
#define DL_ATT_PRESET_FLAG 8 // No prompt and no verify
// PLINE defines
// Flags
#define DL_OPEN_PLINE 0x00
#define DL_CLOSED_PLINE 0x01
#define DL_POLYLINE3D 0x80
#define DL_PFACE_MESH 0x40
#define DL_PGON_MESH 0x10
// Vertices follow entity, required in POLYLINES
#define DL_VERTS_FOLLOW_CODE 66 // Value should always be 1
#define DL_VERTEX_COORD_CODE 10
// LAYER flags
#define DL_FROZEN 1
#define DL_FROZEN_BY_DEF 2
#define DL_LOCKED 4
#define DL_OBJECT_USED 64 // Object is ref'd in the dwg
#define DL_BLOCK_EN_CODE -2 // Block entity definition
#define DL_E_NAME -1 // Entity name
// Extended data codes
#define DL_EXTD_SENTINEL (-3)
#define DL_EXTD_STR 1000
#define DL_EXTD_APP_NAME 1001
#define DL_EXTD_CTL_STR 1002
#define DL_EXTD_LYR_STR 1003
#define DL_EXTD_CHUNK 1004
#define DL_EXTD_HANDLE 1005
#define DL_EXTD_POINT 1010
#define DL_EXTD_POS 1011
#define DL_EXTD_DISP 1012
#define DL_EXTD_DIR 1013
#define DL_EXTD_FLOAT 1040
#define DL_EXTD_DIST 1041
#define DL_EXTD_SCALE 1042
#define DL_EXTD_INT16 1070
#define DL_EXTD_INT32 1071
// UCS codes for use in ads_trans
#define DL_WCS_TRANS_CODE 0
#define DL_UCS_TRANS_CODE 1
#define DL_DCS_TRANS_CODE 2
#define DL_PCS_TRANS_CODE 3
#endif

View File

@ -0,0 +1,138 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_CREATIONADAPTER_H
#define DL_CREATIONADAPTER_H
#include "dl_global.h"
#include "dl_creationinterface.h"
/**
* An abstract adapter class for receiving DXF events when a DXF file is being read.
* The methods in this class are empty. This class exists as convenience for creating
* listener objects.
*
* @author Andrew Mustun
*/
class DXFLIB_EXPORT DL_CreationAdapter : public DL_CreationInterface {
public:
DL_CreationAdapter() {}
virtual ~DL_CreationAdapter() {}
virtual void processCodeValuePair(unsigned int, const std::string&) {}
virtual void endSection() {}
virtual void addLayer(const DL_LayerData&) {}
virtual void addLinetype(const DL_LinetypeData&) {}
virtual void addLinetypeDash(double) {}
virtual void addBlock(const DL_BlockData&) {}
virtual void endBlock() {}
virtual void addTextStyle(const DL_StyleData&) {}
virtual void addPoint(const DL_PointData&) {}
virtual void addLine(const DL_LineData&) {}
virtual void addXLine(const DL_XLineData&) {}
virtual void addRay(const DL_RayData&) {}
virtual void addArc(const DL_ArcData&) {}
virtual void addCircle(const DL_CircleData&) {}
virtual void addEllipse(const DL_EllipseData&) {}
virtual void addPolyline(const DL_PolylineData&) {}
virtual void addVertex(const DL_VertexData&) {}
virtual void addSpline(const DL_SplineData&) {}
virtual void addControlPoint(const DL_ControlPointData&) {}
virtual void addFitPoint(const DL_FitPointData&) {}
virtual void addKnot(const DL_KnotData&) {}
virtual void addInsert(const DL_InsertData&) {}
virtual void addMText(const DL_MTextData&) {}
virtual void addMTextChunk(const std::string&) {}
virtual void addText(const DL_TextData&) {}
virtual void addArcAlignedText(const DL_ArcAlignedTextData&) {}
virtual void addAttribute(const DL_AttributeData&) {}
virtual void addDimAlign(const DL_DimensionData&,
const DL_DimAlignedData&) {}
virtual void addDimLinear(const DL_DimensionData&,
const DL_DimLinearData&) {}
virtual void addDimRadial(const DL_DimensionData&,
const DL_DimRadialData&) {}
virtual void addDimDiametric(const DL_DimensionData&,
const DL_DimDiametricData&) {}
virtual void addDimAngular(const DL_DimensionData&,
const DL_DimAngularData&) {}
virtual void addDimAngular3P(const DL_DimensionData&,
const DL_DimAngular3PData&) {}
virtual void addDimOrdinate(const DL_DimensionData&,
const DL_DimOrdinateData&) {}
virtual void addLeader(const DL_LeaderData&) {}
virtual void addLeaderVertex(const DL_LeaderVertexData&) {}
virtual void addHatch(const DL_HatchData&) {}
virtual void addTrace(const DL_TraceData&) {}
virtual void add3dFace(const DL_3dFaceData&) {}
virtual void addSolid(const DL_SolidData&) {}
virtual void addImage(const DL_ImageData&) {}
virtual void linkImage(const DL_ImageDefData&) {}
virtual void addHatchLoop(const DL_HatchLoopData&) {}
virtual void addHatchEdge(const DL_HatchEdgeData&) {}
virtual void addXRecord(const std::string&) {}
virtual void addXRecordString(int, const std::string&) {}
virtual void addXRecordReal(int, double) {}
virtual void addXRecordInt(int, int) {}
virtual void addXRecordBool(int, bool) {}
virtual void addXDataApp(const std::string&) {}
virtual void addXDataString(int, const std::string&) {}
virtual void addXDataReal(int, double) {}
virtual void addXDataInt(int, int) {}
virtual void addDictionary(const DL_DictionaryData&) {}
virtual void addDictionaryEntry(const DL_DictionaryEntryData&) {}
virtual void endEntity() {}
virtual void addComment(const std::string&) {}
virtual void setVariableVector(const std::string&, double, double, double, int) {}
virtual void setVariableString(const std::string&, const std::string&, int) {}
virtual void setVariableInt(const std::string&, int, int) {}
virtual void setVariableDouble(const std::string&, double, int) {}
#ifdef DL_COMPAT
virtual void setVariableVector(const char*, double, double, double, int) {}
virtual void setVariableString(const char*, const char*, int) {}
virtual void setVariableInt(const char*, int, int) {}
virtual void setVariableDouble(const char*, double, int) {}
virtual void processCodeValuePair(unsigned int, char*) {}
virtual void addComment(const char*) {}
virtual void addMTextChunk(const char*) {}
#endif
virtual void endSequence() {}
};
#endif

View File

@ -0,0 +1,369 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_CREATIONINTERFACE_H
#define DL_CREATIONINTERFACE_H
#include "dl_global.h"
#include <string.h>
#include "dl_attributes.h"
#include "dl_codes.h"
#include "dl_entities.h"
#include "dl_extrusion.h"
/**
* Abstract class (interface) for the creation of new entities.
* Inherit your class which takes care of the entities in the
* processed DXF file from this interface.
*
* Double arrays passed to your implementation contain 3 double
* values for x, y, z coordinates unless stated differently.
*
* @author Andrew Mustun
*/
class DXFLIB_EXPORT DL_CreationInterface {
public:
DL_CreationInterface() {
extrusion = new DL_Extrusion;
}
virtual ~DL_CreationInterface() {
delete extrusion;
}
/**
* Called for every code / value tuple of the DXF file. The complete DXF file
* contents can be handled by the implemetation of this function.
*/
virtual void processCodeValuePair(unsigned int groupCode, const std::string& groupValue) = 0;
/**
* Called when a section (entity, table entry, etc.) is finished.
*/
virtual void endSection() = 0;
/**
* Called for every layer.
*/
virtual void addLayer(const DL_LayerData& data) = 0;
/**
* Called for every linetype.
*/
virtual void addLinetype(const DL_LinetypeData& data) = 0;
/**
* Called for every dash in linetype pattern
*/
virtual void addLinetypeDash(double length) = 0;
/**
* Called for every block. Note: all entities added after this
* command go into this block until endBlock() is called.
*
* @see endBlock()
*/
virtual void addBlock(const DL_BlockData& data) = 0;
/** Called to end the current block */
virtual void endBlock() = 0;
/** Called for every text style */
virtual void addTextStyle(const DL_StyleData& data) = 0;
/** Called for every point */
virtual void addPoint(const DL_PointData& data) = 0;
/** Called for every line */
virtual void addLine(const DL_LineData& data) = 0;
/** Called for every xline */
virtual void addXLine(const DL_XLineData& data) = 0;
/** Called for every ray */
virtual void addRay(const DL_RayData& data) = 0;
/** Called for every arc */
virtual void addArc(const DL_ArcData& data) = 0;
/** Called for every circle */
virtual void addCircle(const DL_CircleData& data) = 0;
/** Called for every ellipse */
virtual void addEllipse(const DL_EllipseData& data) = 0;
/** Called for every polyline start */
virtual void addPolyline(const DL_PolylineData& data) = 0;
/** Called for every polyline vertex */
virtual void addVertex(const DL_VertexData& data) = 0;
/** Called for every spline */
virtual void addSpline(const DL_SplineData& data) = 0;
/** Called for every spline control point */
virtual void addControlPoint(const DL_ControlPointData& data) = 0;
/** Called for every spline fit point */
virtual void addFitPoint(const DL_FitPointData& data) = 0;
/** Called for every spline knot value */
virtual void addKnot(const DL_KnotData& data) = 0;
/** Called for every insert. */
virtual void addInsert(const DL_InsertData& data) = 0;
/** Called for every trace start */
virtual void addTrace(const DL_TraceData& data) = 0;
/** Called for every 3dface start */
virtual void add3dFace(const DL_3dFaceData& data) = 0;
/** Called for every solid start */
virtual void addSolid(const DL_SolidData& data) = 0;
/** Called for every multi Text entity. */
virtual void addMText(const DL_MTextData& data) = 0;
/**
* Called for additional text chunks for MTEXT entities.
* The chunks come at 250 character in size each. Note that
* those chunks come <b>before</b> the actual MTEXT entity.
*/
virtual void addMTextChunk(const std::string& text) = 0;
/** Called for every text entity. */
virtual void addText(const DL_TextData& data) = 0;
/** Called for every arc aligned text entity. */
virtual void addArcAlignedText(const DL_ArcAlignedTextData& data) = 0;
/** Called for every block Attribute entity. */
virtual void addAttribute(const DL_AttributeData& data) = 0;
/**
* Called for every aligned dimension entity.
*/
virtual void addDimAlign(const DL_DimensionData& data,
const DL_DimAlignedData& edata) = 0;
/**
* Called for every linear or rotated dimension entity.
*/
virtual void addDimLinear(const DL_DimensionData& data,
const DL_DimLinearData& edata) = 0;
/**
* Called for every radial dimension entity.
*/
virtual void addDimRadial(const DL_DimensionData& data,
const DL_DimRadialData& edata) = 0;
/**
* Called for every diametric dimension entity.
*/
virtual void addDimDiametric(const DL_DimensionData& data,
const DL_DimDiametricData& edata) = 0;
/**
* Called for every angular dimension (2 lines version) entity.
*/
virtual void addDimAngular(const DL_DimensionData& data,
const DL_DimAngularData& edata) = 0;
/**
* Called for every angular dimension (3 points version) entity.
*/
virtual void addDimAngular3P(const DL_DimensionData& data,
const DL_DimAngular3PData& edata) = 0;
/**
* Called for every ordinate dimension entity.
*/
virtual void addDimOrdinate(const DL_DimensionData& data,
const DL_DimOrdinateData& edata) = 0;
/**
* Called for every leader start.
*/
virtual void addLeader(const DL_LeaderData& data) = 0;
/**
* Called for every leader vertex
*/
virtual void addLeaderVertex(const DL_LeaderVertexData& data) = 0;
/**
* Called for every hatch entity.
*/
virtual void addHatch(const DL_HatchData& data) = 0;
/**
* Called for every image entity.
*/
virtual void addImage(const DL_ImageData& data) = 0;
/**
* Called for every image definition.
*/
virtual void linkImage(const DL_ImageDefData& data) = 0;
/**
* Called for every hatch loop.
*/
virtual void addHatchLoop(const DL_HatchLoopData& data) = 0;
/**
* Called for every hatch edge entity.
*/
virtual void addHatchEdge(const DL_HatchEdgeData& data) = 0;
/**
* Called for every XRecord with the given handle.
*/
virtual void addXRecord(const std::string& handle) = 0;
/**
* Called for XRecords of type string.
*/
virtual void addXRecordString(int code, const std::string& value) = 0;
/**
* Called for XRecords of type double.
*/
virtual void addXRecordReal(int code, double value) = 0;
/**
* Called for XRecords of type int.
*/
virtual void addXRecordInt(int code, int value) = 0;
/**
* Called for XRecords of type bool.
*/
virtual void addXRecordBool(int code, bool value) = 0;
/**
* Called for every beginning of an XData section of the given application.
*/
virtual void addXDataApp(const std::string& appId) = 0;
/**
* Called for XData tuples.
*/
virtual void addXDataString(int code, const std::string& value) = 0;
/**
* Called for XData tuples.
*/
virtual void addXDataReal(int code, double value) = 0;
/**
* Called for XData tuples.
*/
virtual void addXDataInt(int code, int value) = 0;
/**
* Called for dictionary objects.
*/
virtual void addDictionary(const DL_DictionaryData& data) = 0;
/**
* Called for dictionary entries.
*/
virtual void addDictionaryEntry(const DL_DictionaryEntryData& data) = 0;
/**
* Called after an entity has been completed.
*/
virtual void endEntity() = 0;
/**
* Called for every comment in the DXF file (code 999).
*/
virtual void addComment(const std::string& comment) = 0;
/**
* Called for every vector variable in the DXF file (e.g. "$EXTMIN").
*/
virtual void setVariableVector(const std::string& key, double v1, double v2, double v3, int code) = 0;
/**
* Called for every string variable in the DXF file (e.g. "$ACADVER").
*/
virtual void setVariableString(const std::string& key, const std::string& value, int code) = 0;
/**
* Called for every int variable in the DXF file (e.g. "$ACADMAINTVER").
*/
virtual void setVariableInt(const std::string& key, int value, int code) = 0;
/**
* Called for every double variable in the DXF file (e.g. "$DIMEXO").
*/
virtual void setVariableDouble(const std::string& key, double value, int code) = 0;
#ifdef DL_COMPAT
virtual void setVariableVector(const char* key, double v1, double v2, double v3, int code) = 0;
virtual void setVariableString(const char* key, const char* value, int code) = 0;
virtual void setVariableInt(const char* key, int value, int code) = 0;
virtual void setVariableDouble(const char* key, double value, int code) = 0;
virtual void processCodeValuePair(unsigned int groupCode, char* groupValue) = 0;
virtual void addComment(const char* comment) = 0;
virtual void addMTextChunk(const char* text) = 0;
#endif
/**
* Called when a SEQEND occurs (when a POLYLINE or ATTRIB is done)
*/
virtual void endSequence() = 0;
/** Sets the current attributes for entities. */
void setAttributes(const DL_Attributes& attrib) {
attributes = attrib;
}
/** @return the current attributes used for new entities. */
DL_Attributes getAttributes() {
return attributes;
}
/** Sets the current attributes for entities. */
void setExtrusion(double dx, double dy, double dz, double elevation) {
extrusion->setDirection(dx, dy, dz);
extrusion->setElevation(elevation);
}
/** @return the current attributes used for new entities. */
DL_Extrusion* getExtrusion() {
return extrusion;
}
protected:
DL_Attributes attributes;
DL_Extrusion *extrusion;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,529 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_DXF_H
#define DL_DXF_H
#include "dl_global.h"
#include <limits>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <sstream>
#include <map>
#include "dl_attributes.h"
#include "dl_codes.h"
#include "dl_entities.h"
#include "dl_writer_ascii.h"
#ifdef _WIN32
#undef M_PI
#define M_PI 3.14159265358979323846
//#pragma warning(disable : 4800)
#endif
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
#ifndef DL_NANDOUBLE
#define DL_NANDOUBLE std::numeric_limits<double>::quiet_NaN()
#endif
class DL_CreationInterface;
class DL_WriterA;
#define DL_VERSION "3.17.0.0"
#define DL_VERSION_MAJOR 3
#define DL_VERSION_MINOR 17
#define DL_VERSION_REV 0
#define DL_VERSION_BUILD 0
#define DL_UNKNOWN 0
#define DL_LAYER 10
#define DL_BLOCK 11
#define DL_ENDBLK 12
#define DL_LINETYPE 13
#define DL_STYLE 20
#define DL_SETTING 50
#define DL_ENTITY_POINT 100
#define DL_ENTITY_LINE 101
#define DL_ENTITY_POLYLINE 102
#define DL_ENTITY_LWPOLYLINE 103
#define DL_ENTITY_VERTEX 104
#define DL_ENTITY_SPLINE 105
#define DL_ENTITY_KNOT 106
#define DL_ENTITY_CONTROLPOINT 107
#define DL_ENTITY_ARC 108
#define DL_ENTITY_CIRCLE 109
#define DL_ENTITY_ELLIPSE 110
#define DL_ENTITY_INSERT 111
#define DL_ENTITY_TEXT 112
#define DL_ENTITY_MTEXT 113
#define DL_ENTITY_DIMENSION 114
#define DL_ENTITY_LEADER 115
#define DL_ENTITY_HATCH 116
#define DL_ENTITY_ATTRIB 117
#define DL_ENTITY_IMAGE 118
#define DL_ENTITY_IMAGEDEF 119
#define DL_ENTITY_TRACE 120
#define DL_ENTITY_SOLID 121
#define DL_ENTITY_3DFACE 122
#define DL_ENTITY_XLINE 123
#define DL_ENTITY_RAY 124
#define DL_ENTITY_ARCALIGNEDTEXT 125
#define DL_ENTITY_SEQEND 126
#define DL_XRECORD 200
#define DL_DICTIONARY 210
/**
* Reading and writing of DXF files.
*
* This class can read in a DXF file and calls methods from the
* interface DL_EntityContainer to add the entities to the
* contianer provided by the user of the library.
*
* It can also be used to write DXF files to a certain extent.
*
* When saving entities, special values for colors and linetypes
* can be used:
*
* Special colors are 0 (=BYBLOCK) and 256 (=BYLAYER).
* Special linetypes are "BYLAYER" and "BYBLOCK".
*
* @author Andrew Mustun
*/
class DXFLIB_EXPORT DL_Dxf {
public:
DL_Dxf();
~DL_Dxf();
bool in(const std::string& file,
DL_CreationInterface* creationInterface);
bool readDxfGroups(FILE* fp,
DL_CreationInterface* creationInterface);
static bool getStrippedLine(std::string& s, unsigned int size,
FILE* stream, bool stripSpace = true);
bool readDxfGroups(std::stringstream& stream,
DL_CreationInterface* creationInterface);
bool in(std::stringstream &stream,
DL_CreationInterface* creationInterface);
static bool getStrippedLine(std::string& s, unsigned int size,
std::stringstream& stream, bool stripSpace = true);
static bool stripWhiteSpace(char** s, bool stripSpaces = true);
bool processDXFGroup(DL_CreationInterface* creationInterface,
int groupCode, const std::string& groupValue);
void addSetting(DL_CreationInterface* creationInterface);
void addLayer(DL_CreationInterface* creationInterface);
void addLinetype(DL_CreationInterface *creationInterface);
void addBlock(DL_CreationInterface* creationInterface);
void endBlock(DL_CreationInterface* creationInterface);
void addTextStyle(DL_CreationInterface* creationInterface);
void addPoint(DL_CreationInterface* creationInterface);
void addLine(DL_CreationInterface* creationInterface);
void addXLine(DL_CreationInterface* creationInterface);
void addRay(DL_CreationInterface* creationInterface);
void addPolyline(DL_CreationInterface* creationInterface);
void addVertex(DL_CreationInterface* creationInterface);
void addSpline(DL_CreationInterface* creationInterface);
void addArc(DL_CreationInterface* creationInterface);
void addCircle(DL_CreationInterface* creationInterface);
void addEllipse(DL_CreationInterface* creationInterface);
void addInsert(DL_CreationInterface* creationInterface);
void addTrace(DL_CreationInterface* creationInterface);
void add3dFace(DL_CreationInterface* creationInterface);
void addSolid(DL_CreationInterface* creationInterface);
void addMText(DL_CreationInterface* creationInterface);
void addText(DL_CreationInterface* creationInterface);
void addArcAlignedText(DL_CreationInterface* creationInterface);
void addAttribute(DL_CreationInterface* creationInterface);
DL_DimensionData getDimData();
void addDimLinear(DL_CreationInterface* creationInterface);
void addDimAligned(DL_CreationInterface* creationInterface);
void addDimRadial(DL_CreationInterface* creationInterface);
void addDimDiametric(DL_CreationInterface* creationInterface);
void addDimAngular(DL_CreationInterface* creationInterface);
void addDimAngular3P(DL_CreationInterface* creationInterface);
void addDimOrdinate(DL_CreationInterface* creationInterface);
void addLeader(DL_CreationInterface* creationInterface);
void addHatch(DL_CreationInterface* creationInterface);
void addHatchLoop();
void addHatchEdge();
bool handleHatchData(DL_CreationInterface* creationInterface);
void addImage(DL_CreationInterface* creationInterface);
void addImageDef(DL_CreationInterface* creationInterface);
void addComment(DL_CreationInterface* creationInterface, const std::string& comment);
void addDictionary(DL_CreationInterface* creationInterface);
void addDictionaryEntry(DL_CreationInterface* creationInterface);
bool handleXRecordData(DL_CreationInterface* creationInterface);
bool handleDictionaryData(DL_CreationInterface* creationInterface);
bool handleXData(DL_CreationInterface *creationInterface);
bool handleMTextData(DL_CreationInterface* creationInterface);
bool handleLWPolylineData(DL_CreationInterface* creationInterface);
bool handleSplineData(DL_CreationInterface* creationInterface);
bool handleLeaderData(DL_CreationInterface* creationInterface);
bool handleLinetypeData(DL_CreationInterface* creationInterface);
void endEntity(DL_CreationInterface* creationInterface);
void endSequence(DL_CreationInterface* creationInterface);
//int stringToInt(const char* s, bool* ok=NULL);
DL_WriterA* out(const char* file,
DL_Codes::version version=DL_VERSION_2000);
void writeHeader(DL_WriterA& dw);
void writePoint(DL_WriterA& dw,
const DL_PointData& data,
const DL_Attributes& attrib);
void writeLine(DL_WriterA& dw,
const DL_LineData& data,
const DL_Attributes& attrib);
void writeXLine(DL_WriterA& dw,
const DL_XLineData& data,
const DL_Attributes& attrib);
void writeRay(DL_WriterA& dw,
const DL_RayData& data,
const DL_Attributes& attrib);
void writePolyline(DL_WriterA& dw,
const DL_PolylineData& data,
const DL_Attributes& attrib);
void writeVertex(DL_WriterA& dw,
const DL_VertexData& data);
void writePolylineEnd(DL_WriterA& dw);
void writeSpline(DL_WriterA& dw,
const DL_SplineData& data,
const DL_Attributes& attrib);
void writeControlPoint(DL_WriterA& dw,
const DL_ControlPointData& data);
void writeFitPoint(DL_WriterA& dw,
const DL_FitPointData& data);
void writeKnot(DL_WriterA& dw,
const DL_KnotData& data);
void writeCircle(DL_WriterA& dw,
const DL_CircleData& data,
const DL_Attributes& attrib);
void writeArc(DL_WriterA& dw,
const DL_ArcData& data,
const DL_Attributes& attrib);
void writeEllipse(DL_WriterA& dw,
const DL_EllipseData& data,
const DL_Attributes& attrib);
void writeSolid(DL_WriterA& dw,
const DL_SolidData& data,
const DL_Attributes& attrib);
void writeTrace(DL_WriterA& dw,
const DL_TraceData& data,
const DL_Attributes& attrib);
void write3dFace(DL_WriterA& dw,
const DL_3dFaceData& data,
const DL_Attributes& attrib);
void writeInsert(DL_WriterA& dw,
const DL_InsertData& data,
const DL_Attributes& attrib);
void writeMText(DL_WriterA& dw,
const DL_MTextData& data,
const DL_Attributes& attrib);
void writeText(DL_WriterA& dw,
const DL_TextData& data,
const DL_Attributes& attrib);
void writeAttribute(DL_WriterA& dw,
const DL_AttributeData& data,
const DL_Attributes& attrib);
void writeDimStyleOverrides(DL_WriterA& dw,
const DL_DimensionData& data);
void writeDimAligned(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimAlignedData& edata,
const DL_Attributes& attrib);
void writeDimLinear(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimLinearData& edata,
const DL_Attributes& attrib);
void writeDimRadial(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimRadialData& edata,
const DL_Attributes& attrib);
void writeDimDiametric(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimDiametricData& edata,
const DL_Attributes& attrib);
void writeDimAngular(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimAngularData& edata,
const DL_Attributes& attrib);
void writeDimAngular3P(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimAngular3PData& edata,
const DL_Attributes& attrib);
void writeDimOrdinate(DL_WriterA& dw,
const DL_DimensionData& data,
const DL_DimOrdinateData& edata,
const DL_Attributes& attrib);
void writeLeader(DL_WriterA& dw,
const DL_LeaderData& data,
const DL_Attributes& attrib);
void writeLeaderVertex(DL_WriterA& dw,
const DL_LeaderVertexData& data);
void writeHatch1(DL_WriterA& dw,
const DL_HatchData& data,
const DL_Attributes& attrib);
void writeHatch2(DL_WriterA& dw,
const DL_HatchData& data,
const DL_Attributes& attrib);
void writeHatchLoop1(DL_WriterA& dw,
const DL_HatchLoopData& data);
void writeHatchLoop2(DL_WriterA& dw,
const DL_HatchLoopData& data);
void writeHatchEdge(DL_WriterA& dw,
const DL_HatchEdgeData& data);
int writeImage(DL_WriterA& dw,
const DL_ImageData& data,
const DL_Attributes& attrib);
void writeImageDef(DL_WriterA& dw, int handle,
const DL_ImageData& data);
void writeLayer(DL_WriterA& dw,
const DL_LayerData& data,
const DL_Attributes& attrib);
void writeLinetype(DL_WriterA& dw,
const DL_LinetypeData& data);
void writeAppid(DL_WriterA& dw, const std::string& name);
void writeBlock(DL_WriterA& dw,
const DL_BlockData& data);
void writeEndBlock(DL_WriterA& dw, const std::string& name);
void writeVPort(DL_WriterA& dw);
void writeStyle(DL_WriterA& dw, const DL_StyleData& style);
void writeView(DL_WriterA& dw);
void writeUcs(DL_WriterA& dw);
void writeDimStyle(DL_WriterA& dw,
double dimasz, double dimexe, double dimexo,
double dimgap, double dimtxt);
void writeBlockRecord(DL_WriterA& dw);
void writeBlockRecord(DL_WriterA& dw, const std::string& name);
void writeObjects(DL_WriterA& dw, const std::string& appDictionaryName = "");
void writeAppDictionary(DL_WriterA& dw);
int writeDictionaryEntry(DL_WriterA& dw, const std::string& name);
void writeXRecord(DL_WriterA& dw, int handle, int value);
void writeXRecord(DL_WriterA& dw, int handle, double value);
void writeXRecord(DL_WriterA& dw, int handle, bool value);
void writeXRecord(DL_WriterA& dw, int handle, const std::string& value);
void writeObjectsEnd(DL_WriterA& dw);
void writeComment(DL_WriterA& dw, const std::string& comment);
/**
* Converts the given string into a double or returns the given
* default valud (def) if value is NULL or empty.
*/
//static double toReal(const char* value, double def=0.0);
/**
* Converts the given string into an int or returns the given
* default valud (def) if value is NULL or empty.
*/
// static int toInt(const char* value, int def=0) {
// if (value!=NULL && value[0] != '\0') {
// return atoi(value);
// }
// return def;
// }
/**
* Converts the given string into a string or returns the given
* default valud (def) if value is NULL or empty.
*/
// static const char* toString(const char* value, const char* def="") {
// if (value!=NULL && value[0] != '\0') {
// return value;
// } else {
// return def;
// }
// }
static bool checkVariable(const char* var, DL_Codes::version version);
DL_Codes::version getVersion() {
return version;
}
int getLibVersion(const std::string &str);
static void test();
bool hasValue(int code) {
return values.count(code)==1;
}
int getIntValue(int code, int def) {
if (!hasValue(code)) {
return def;
}
return toInt(values[code]);
}
int toInt(const std::string& str) {
char* p;
return strtol(str.c_str(), &p, 10);
}
int getInt16Value(int code, int def) {
if (!hasValue(code)) {
return def;
}
return toInt16(values[code]);
}
int toInt16(const std::string& str) {
char* p;
return strtol(str.c_str(), &p, 16);
}
bool toBool(const std::string& str) {
char* p;
return (bool)strtol(str.c_str(), &p, 10);
}
std::string getStringValue(int code, const std::string& def) {
if (!hasValue(code)) {
return def;
}
return values[code];
}
double getRealValue(int code, double def) {
if (!hasValue(code)) {
return def;
}
return toReal(values[code]);
}
double toReal(const std::string& str) {
double ret;
// make sure the real value uses '.' not ',':
std::string str2 = str;
std::replace(str2.begin(), str2.end(), ',', '.');
// make sure c++ expects '.' not ',':
std::istringstream istr(str2);
//istr.imbue(std::locale("C"));
istr >> ret;
return ret;
}
private:
DL_Codes::version version;
std::string polylineLayer;
double* vertices;
int maxVertices;
int vertexIndex;
double* knots;
int maxKnots;
int knotIndex;
double* weights;
int weightIndex;
double* controlPoints;
int maxControlPoints;
int controlPointIndex;
double* fitPoints;
int maxFitPoints;
int fitPointIndex;
double* leaderVertices;
int maxLeaderVertices;
int leaderVertexIndex;
bool firstHatchLoop;
DL_HatchEdgeData hatchEdge;
std::vector<std::vector<DL_HatchEdgeData> > hatchEdges;
std::string xRecordHandle;
bool xRecordValues;
// Only the useful part of the group code
std::string groupCodeTmp;
// ...same as integer
unsigned int groupCode;
// Only the useful part of the group value
std::string groupValue;
// Current entity type
int currentObjectType;
// Value of the current setting
char settingValue[DL_DXF_MAXLINE+1];
// Key of the current setting (e.g. "$ACADVER")
std::string settingKey;
// Stores the group codes
std::map<int, std::string> values;
// First call of this method. We initialize all group values in
// the first call.
bool firstCall;
// Attributes of the current entity (layer, color, width, line type)
DL_Attributes attrib;
// library version. hex: 0x20003001 = 2.0.3.1
int libVersion;
// app specific dictionary handle:
unsigned long appDictionaryHandle;
// handle of standard text style, referenced by dimstyle:
unsigned long styleHandleStd;
};
#endif
// EOF

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
** Copyright (C) 2001 Robert J. Campbell Jr.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_EXCEPTION_H
#define DL_EXCEPTION_H
#include "dl_global.h"
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
/**
* Used for exception handling.
*/
class DXFLIB_EXPORT DL_Exception {}
;
/**
* Used for exception handling.
*/
class DXFLIB_EXPORT DL_NullStrExc : public DL_Exception {}
;
/**
* Used for exception handling.
*/
class DXFLIB_EXPORT DL_GroupCodeExc : public DL_Exception {
DL_GroupCodeExc(int gc=0) : groupCode(gc) {}
int groupCode;
};
#endif

View File

@ -0,0 +1,143 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_EXTRUSION_H
#define DL_EXTRUSION_H
#include "dl_global.h"
#include <math.h>
/**
* Extrusion direction.
*
* @author Andrew Mustun
*/
class DXFLIB_EXPORT DL_Extrusion {
public:
/**
* Default constructor.
*/
DL_Extrusion() {
direction = new double[3];
setDirection(0.0, 0.0, 1.0);
setElevation(0.0);
}
/**
* Destructor.
*/
~DL_Extrusion() {
delete[] direction ;
}
/**
* Constructor for DXF extrusion.
*
* @param direction Vector of axis along which the entity shall be extruded
* this is also the Z axis of the Entity coordinate system
* @param elevation Distance of the entities XY plane from the origin of the
* world coordinate system
*/
DL_Extrusion(double dx, double dy, double dz, double elevation) {
direction = new double[3];
setDirection(dx, dy, dz);
setElevation(elevation);
}
/**
* Sets the direction vector.
*/
void setDirection(double dx, double dy, double dz) {
direction[0]=dx;
direction[1]=dy;
direction[2]=dz;
}
/**
* @return direction vector.
*/
double* getDirection() const {
return direction;
}
/**
* @return direction vector.
*/
void getDirection(double dir[]) const {
dir[0]=direction[0];
dir[1]=direction[1];
dir[2]=direction[2];
}
/**
* Sets the elevation.
*/
void setElevation(double elevation) {
this->elevation = elevation;
}
/**
* @return Elevation.
*/
double getElevation() const {
return elevation;
}
/**
* Copies extrusion (deep copies) from another extrusion object.
*/
DL_Extrusion operator = (const DL_Extrusion& extru) {
setDirection(extru.direction[0], extru.direction[1], extru.direction[2]);
setElevation(extru.elevation);
return *this;
}
private:
double *direction;
double elevation;
};
#endif

View File

@ -0,0 +1,13 @@
#if defined(DXFLIB_DLL)
# ifdef _WIN32
# if defined(DXFLIB_LIBRARY)
# define DXFLIB_EXPORT __declspec(dllexport)
# else
# define DXFLIB_EXPORT __declspec(dllimport)
# endif
# else
# define DXFLIB_EXPORT
# endif
#else
# define DXFLIB_EXPORT
#endif

View File

@ -0,0 +1,654 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
** Copyright (C) 2001 Robert J. Campbell Jr.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_WRITER_H
#define DL_WRITER_H
#include "dl_global.h"
#ifndef _WIN32
#include <strings.h>
#endif
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <iostream>
#include <algorithm>
#include "dl_attributes.h"
#include "dl_codes.h"
/**
* Defines interface for writing low level DXF constructs to
* a file. Implementation is defined in derived classes that write
* to binary or ASCII files.
*
* Implements functions that write higher level constructs in terms of
* the low level ones.
*
* @todo Add error checking for string/entry length.
*/
class DXFLIB_EXPORT DL_Writer {
public:
/**
* @param version DXF version. Defaults to DL_VERSION_2002.
*/
DL_Writer(DL_Codes::version version) : m_handle(0x30) {
this->version = version;
modelSpaceHandle = 0;
paperSpaceHandle = 0;
paperSpace0Handle = 0;
}
virtual ~DL_Writer() {}
;
/** Generic section for section 'name'.
*
* <pre>
* 0
* SECTION
* 2
* name
* </pre>
*/
void section(const char* name) const {
dxfString(0, "SECTION");
dxfString(2, name);
}
/**
* Section HEADER
*
* <pre>
* 0
* SECTION
* 2
* HEADER
* </pre>
*/
void sectionHeader() const {
section("HEADER");
}
/**
* Section TABLES
*
* <pre>
* 0
* SECTION
* 2
* TABLES
* </pre>
*/
void sectionTables() const {
section("TABLES");
}
/**
* Section BLOCKS
*
* <pre>
* 0
* SECTION
* 2
* BLOCKS
* </pre>
*/
void sectionBlocks() const {
section("BLOCKS");
}
/**
* Section ENTITIES
*
* <pre>
* 0
* SECTION
* 2
* ENTITIES
* </pre>
*/
void sectionEntities() const {
section("ENTITIES");
}
/**
* Section CLASSES
*
* <pre>
* 0
* SECTION
* 2
* CLASSES
* </pre>
*/
void sectionClasses() const {
section("CLASSES");
}
/**
* Section OBJECTS
*
* <pre>
* 0
* SECTION
* 2
* OBJECTS
* </pre>
*/
void sectionObjects() const {
section("OBJECTS");
}
/**
* End of a section.
*
* <pre>
* 0
* ENDSEC
* </pre>
*/
void sectionEnd() const {
dxfString(0, "ENDSEC");
}
/**
* Generic table for table 'name' with 'num' entries:
*
* <pre>
* 0
* TABLE
* 2
* name
* 70
* num
* </pre>
*/
void table(const char* name, int num, int h=0) const {
dxfString(0, "TABLE");
dxfString(2, name);
if (version>=DL_VERSION_2000) {
if (h==0) {
handle();
}
else {
dxfHex(5, h);
}
dxfString(100, "AcDbSymbolTable");
}
dxfInt(70, num);
}
/** Table for layers.
*
* @param num Number of layers in total.
*
* <pre>
* 0
* TABLE
* 2
* LAYER
* 70
* num
* </pre>
*/
void tableLayers(int num) const {
table("LAYER", num, 2);
}
/** Table for line types.
*
* @param num Number of line types in total.
*
* <pre>
* 0
* TABLE
* 2
* LTYPE
* 70
* num
* </pre>
*/
void tableLinetypes(int num) const {
//linetypeHandle = 5;
table("LTYPE", num, 5);
}
/** Table for application id.
*
* @param num Number of registered applications in total.
*
* <pre>
* 0
* TABLE
* 2
* APPID
* 70
* num
* </pre>
*/
void tableAppid(int num) const {
table("APPID", num, 9);
}
/** Table for text style.
*
* @param num Number of text styles.
*
* <pre>
* 0
* TABLE
* 2
* STYLE
* 70
* num
* </pre>
*/
void tableStyle(int num) const {
table("STYLE", num, 3);
}
/**
* End of a table.
*
* <pre>
* 0
* ENDTAB
* </pre>
*/
void tableEnd() const {
dxfString(0, "ENDTAB");
}
/**
* End of the DXF file.
*
* <pre>
* 0
* EOF
* </pre>
*/
void dxfEOF() const {
dxfString(0, "EOF");
}
/**
* Comment.
*
* <pre>
* 999
* text
* </pre>
*/
void comment(const char* text) const {
dxfString(999, text);
}
/**
* Entity.
*
* <pre>
* 0
* entTypeName
* </pre>
*
* @return Unique handle or 0.
*/
void entity(const char* entTypeName) const {
dxfString(0, entTypeName);
if (version>=DL_VERSION_2000) {
handle();
}
}
/**
* Attributes of an entity.
*
* <pre>
* 8
* layer
* 62
* color
* 39
* width
* 6
* linetype
* </pre>
*/
void entityAttributes(const DL_Attributes& attrib) const {
// layer name:
dxfString(8, attrib.getLayer());
// R12 doesn't accept BYLAYER values. The value has to be missing
// in that case.
if (version>=DL_VERSION_2000 || attrib.getColor()!=256) {
dxfInt(62, attrib.getColor());
}
if (version>=DL_VERSION_2000 && attrib.getColor24()!=-1) {
dxfInt(420, attrib.getColor24());
}
if (version>=DL_VERSION_2000) {
dxfInt(370, attrib.getWidth());
}
if (version>=DL_VERSION_2000) {
dxfReal(48, attrib.getLinetypeScale());
}
std::string linetype = attrib.getLinetype();
std::transform(linetype.begin(), linetype.end(), linetype.begin(), ::toupper);
if (version>=DL_VERSION_2000 || linetype=="BYLAYER") {
dxfString(6, attrib.getLinetype());
}
}
/**
* Subclass.
*/
void subClass(const char* sub) const {
dxfString(100, sub);
}
/**
* Layer (must be in the TABLES section LAYER).
*
* <pre>
* 0
* LAYER
* </pre>
*/
void tableLayerEntry(unsigned long int h=0) const {
dxfString(0, "LAYER");
if (version>=DL_VERSION_2000) {
if (h==0) {
handle();
} else {
dxfHex(5, h);
}
dxfString(100, "AcDbSymbolTableRecord");
dxfString(100, "AcDbLayerTableRecord");
}
}
/**
* Line type (must be in the TABLES section LTYPE).
*
* <pre>
* 0
* LTYPE
* </pre>
*/
void tableLinetypeEntry(unsigned long int h=0) const {
dxfString(0, "LTYPE");
if (version>=DL_VERSION_2000) {
if (h==0) {
handle();
} else {
dxfHex(5, h);
}
//dxfHex(330, 0x5);
dxfString(100, "AcDbSymbolTableRecord");
dxfString(100, "AcDbLinetypeTableRecord");
}
}
/**
* Appid (must be in the TABLES section APPID).
*
* <pre>
* 0
* APPID
* </pre>
*/
void tableAppidEntry(unsigned long int h=0) const {
dxfString(0, "APPID");
if (version>=DL_VERSION_2000) {
if (h==0) {
handle();
} else {
dxfHex(5, h);
}
//dxfHex(330, 0x9);
dxfString(100, "AcDbSymbolTableRecord");
dxfString(100, "AcDbRegAppTableRecord");
}
}
/**
* Block (must be in the section BLOCKS).
*
* <pre>
* 0
* BLOCK
* </pre>
*/
void sectionBlockEntry(unsigned long int h=0) const {
dxfString(0, "BLOCK");
if (version>=DL_VERSION_2000) {
if (h==0) {
handle();
} else {
dxfHex(5, h);
}
//dxfHex(330, blockHandle);
dxfString(100, "AcDbEntity");
if (h==0x1C) {
dxfInt(67, 1);
}
dxfString(8, "0"); // TODO: Layer for block
dxfString(100, "AcDbBlockBegin");
}
}
/**
* End of Block (must be in the section BLOCKS).
*
* <pre>
* 0
* ENDBLK
* </pre>
*/
void sectionBlockEntryEnd(unsigned long int h=0) const {
dxfString(0, "ENDBLK");
if (version>=DL_VERSION_2000) {
if (h==0) {
handle();
} else {
dxfHex(5, h);
}
//dxfHex(330, blockHandle);
dxfString(100, "AcDbEntity");
if (h==0x1D) {
dxfInt(67, 1);
}
dxfString(8, "0"); // TODO: Layer for block
dxfString(100, "AcDbBlockEnd");
}
}
void color(int col=256) const {
dxfInt(62, col);
}
void linetype(const char *lt) const {
dxfString(6, lt);
}
void linetypeScale(double scale) const {
dxfReal(48, scale);
}
void lineWeight(int lw) const {
dxfInt(370, lw);
}
void coord(int gc, double x, double y, double z=0) const {
dxfReal(gc, x);
dxfReal(gc+10, y);
dxfReal(gc+20, z);
}
void coordTriplet(int gc, const double* value) const {
if (value) {
dxfReal(gc, *value++);
dxfReal(gc+10, *value++);
dxfReal(gc+20, *value++);
}
}
void resetHandle() const {
m_handle = 1;
}
/**
* Writes a unique handle and returns it.
*/
unsigned long handle(int gc=5) const {
// handle has to be hex
dxfHex(gc, m_handle);
return m_handle++;
}
/**
* @return Next handle that will be written.
*/
unsigned long getNextHandle() const {
return m_handle;
}
/**
* Increases handle, so that the handle returned remains available.
*/
unsigned long incHandle() const {
return m_handle++;
}
/**
* Sets the handle of the model space. Entities refer to
* this handle.
*/
void setModelSpaceHandle(unsigned long h) {
modelSpaceHandle = h;
}
unsigned long getModelSpaceHandle() {
return modelSpaceHandle;
}
/**
* Sets the handle of the paper space. Some special blocks refer to
* this handle.
*/
void setPaperSpaceHandle(unsigned long h) {
paperSpaceHandle = h;
}
unsigned long getPaperSpaceHandle() {
return paperSpaceHandle;
}
/**
* Sets the handle of the paper space 0. Some special blocks refer to
* this handle.
*/
void setPaperSpace0Handle(unsigned long h) {
paperSpace0Handle = h;
}
unsigned long getPaperSpace0Handle() {
return paperSpace0Handle;
}
/**
* Must be overwritten by the implementing class to write a
* real value to the file.
*
* @param gc Group code.
* @param value The real value.
*/
virtual void dxfReal(int gc, double value) const = 0;
/**
* Must be overwritten by the implementing class to write an
* int value to the file.
*
* @param gc Group code.
* @param value The int value.
*/
virtual void dxfInt(int gc, int value) const = 0;
/**
* Can be overwritten by the implementing class to write a
* bool value to the file.
*
* @param gc Group code.
* @param value The bool value.
*/
virtual void dxfBool(int gc, bool value) const {
dxfInt(gc, (int)value);
}
/**
* Must be overwritten by the implementing class to write an
* int value (hex) to the file.
*
* @param gc Group code.
* @param value The int value.
*/
virtual void dxfHex(int gc, int value) const = 0;
/**
* Must be overwritten by the implementing class to write a
* string to the file.
*
* @param gc Group code.
* @param value The string.
*/
virtual void dxfString(int gc, const char* value) const = 0;
/**
* Must be overwritten by the implementing class to write a
* string to the file.
*
* @param gc Group code.
* @param value The string.
*/
virtual void dxfString(int gc, const std::string& value) const = 0;
protected:
mutable unsigned long m_handle;
mutable unsigned long modelSpaceHandle;
mutable unsigned long paperSpaceHandle;
mutable unsigned long paperSpace0Handle;
/**
* DXF version to be created.
*/
DL_Codes::version version;
private:
};
#endif

View File

@ -0,0 +1,156 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
** Copyright (C) 2001 Robert J. Campbell Jr.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <stdio.h>
#include <string.h>
#include "dl_writer_ascii.h"
#include "dl_exception.h"
/**
* Closes the output file.
*/
void DL_WriterA::close() const {
m_ofile.close();
}
/**
* @retval true Opening file has failed.
* @retval false Otherwise.
*/
bool DL_WriterA::openFailed() const {
return m_ofile.fail();
}
/**
* Writes a real (double) variable to the DXF file.
*
* @param gc Group code.
* @param value Double value
*/
void DL_WriterA::dxfReal(int gc, double value) const {
char str[256];
if (version==DL_Codes::AC1009_MIN) {
sprintf(str, "%.6lf", value);
}
else {
sprintf(str, "%.16lf", value);
}
// fix for german locale:
strReplace(str, ',', '.');
// Cut away those zeros at the end:
bool dot = false;
int end = -1;
for (unsigned int i=0; i<strlen(str); ++i) {
if (str[i]=='.') {
dot = true;
end = i+2;
continue;
} else if (dot && str[i]!='0') {
end = i+1;
}
}
if (end>0 && end<(int)strlen(str)) {
str[end] = '\0';
}
dxfString(gc, str);
m_ofile.flush();
}
/**
* Writes an int variable to the DXF file.
*
* @param gc Group code.
* @param value Int value
*/
void DL_WriterA::dxfInt(int gc, int value) const {
m_ofile << (gc<10 ? " " : (gc<100 ? " " : "")) << gc << "\n" << value << "\n";
}
/**
* Writes a hex int variable to the DXF file.
*
* @param gc Group code.
* @param value Int value
*/
void DL_WriterA::dxfHex(int gc, int value) const {
char str[12];
sprintf(str, "%0X", value);
dxfString(gc, str);
}
/**
* Writes a string variable to the DXF file.
*
* @param gc Group code.
* @param value String
*/
void DL_WriterA::dxfString(int gc, const char* value) const {
if (value==NULL) {
#ifndef __GCC2x__
//throw DL_NullStrExc();
#endif
}
m_ofile << (gc<10 ? " " : (gc<100 ? " " : "")) << gc << "\n"
<< value << "\n";
}
void DL_WriterA::dxfString(int gc, const std::string& value) const {
m_ofile << (gc<10 ? " " : (gc<100 ? " " : "")) << gc << "\n"
<< value << "\n";
}
/**
* Replaces every occurence of src with dest in the null terminated str.
*/
void DL_WriterA::strReplace(char* str, char src, char dest) {
size_t i;
for (i=0; i<strlen(str); i++) {
if (str[i]==src) {
str[i] = dest;
}
}
}

View File

@ -0,0 +1,74 @@
/****************************************************************************
** Copyright (C) 2001-2013 RibbonSoft, GmbH. All rights reserved.
** Copyright (C) 2001 Robert J. Campbell Jr.
**
** This file is part of the dxflib project.
**
** This file is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** Licensees holding valid dxflib Professional Edition licenses may use
** this file in accordance with the dxflib Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.ribbonsoft.com for further details.
**
** Contact info@ribbonsoft.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#ifndef DL_WRITER_ASCII_H
#define DL_WRITER_ASCII_H
#include "dl_global.h"
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "dl_writer.h"
#include <fstream>
#include <string>
/**
* Implements functions defined in DL_Writer for writing low
* level DXF constructs to an ASCII format DXF file.
*
* @para fname File name of the file to be created.
* @para version DXF version. Defaults to DL_VERSION_2002.
*
* @todo What if \c fname is NULL? Or \c fname can't be opened for
* another reason?
*/
class DXFLIB_EXPORT DL_WriterA : public DL_Writer {
public:
DL_WriterA(const char* fname, DL_Codes::version version=DL_VERSION_2000)
: DL_Writer(version), m_ofile(fname) {}
virtual ~DL_WriterA() {}
bool openFailed() const;
void close() const;
void dxfReal(int gc, double value) const;
void dxfInt(int gc, int value) const;
void dxfHex(int gc, int value) const;
void dxfString(int gc, const char* value) const;
void dxfString(int gc, const std::string& value) const;
static void strReplace(char* str, char src, char dest);
private:
/**
* DXF file to be created.
*/
mutable std::ofstream m_ofile;
};
#endif

379
datafile/dxf/dxfreader.cpp Normal file
View File

@ -0,0 +1,379 @@
#include "dxfreader.h"
#include <QDebug>
DxfReader::DxfReader(const QString &fileName, QObject *parent)
: QObject(parent)
, fileName(fileName)
{
//QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
// 读取 dxf 文件
DL_Dxf *dxf = new DL_Dxf;
if (!dxf->in(std::string(fileName.toLocal8Bit()), this)) { // if file open failed
std::cerr << std::string(fileName.toLocal8Bit()) << " could not be opened.\n";
return;
}
delete dxf;
dxf = nullptr;
}
void DxfReader::addText(const DL_TextData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfText << data;
}
void DxfReader::addLine(const DL_LineData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfLines << data;
}
void DxfReader::addArc(const DL_ArcData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfArcs << data;
}
void DxfReader::addCircle(const DL_CircleData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfCircles << data;
}
void DxfReader::addEllipse(const DL_EllipseData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfEllipses << data;
}
void DxfReader::addPolyline(const DL_PolylineData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfPolylines << data;
}
void DxfReader::addPoint(const DL_PointData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfPoints << data;
}
void DxfReader::addSpline(const DL_SplineData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfSplines << data;
}
void DxfReader::addBlock(const DL_BlockData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfBlocks << data;
}
void DxfReader::endBlock()
{
}
void DxfReader::addLayer(const DL_LayerData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfLayers << data;
}
void DxfReader::addLinetype(const DL_LinetypeData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfLinetypes << data;
}
void DxfReader::addLinetypeDash(double length)
{
if(length < 0){}
}
void DxfReader::addXLine(const DL_XLineData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfXLines << data;
}
void DxfReader::addRay(const DL_RayData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfRays << data;
}
void DxfReader::addVertex(const DL_VertexData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfVertexs << data;
}
void DxfReader::addControlPoint(const DL_ControlPointData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfControlPoints << data;
}
void DxfReader::addFitPoint(const DL_FitPointData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfFitPoints << data;
}
void DxfReader::addKnot(const DL_KnotData &data)
{
if(data.k == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addInsert(const DL_InsertData &data)
{
if(data.angle == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addSolid(const DL_SolidData &data)
{
if(data.x == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addTrace(const DL_TraceData &data)
{
if(data.x == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addTextStyle(const DL_StyleData &data)
{
if(data.flags == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addMTextChunk(const std::string &text)
{
if(text.data() == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addMText(const DL_MTextData &data)
{
if(data.angle == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addArcAlignedText(const DL_ArcAlignedTextData &data)
{
if(data.alignment == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addAttribute(const DL_AttributeData &data)
{
if(data.angle == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addDimAlign(const DL_DimensionData &data, const DL_DimAlignedData &edata)
{
if(data.angle == 0){}
if(edata.epx1 == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addDimLinear(const DL_DimensionData &data, const DL_DimLinearData &edata)
{
if(data.angle == 0){}
if(edata.angle == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addDimRadial(const DL_DimensionData &data, const DL_DimRadialData &edata)
{
if(data.angle == 0){}
if(edata.dpx == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addDimDiametric(const DL_DimensionData &data, const DL_DimDiametricData &edata)
{
if(data.angle == 0){}
if(edata.dpx == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addDimAngular(const DL_DimensionData &data, const DL_DimAngularData &edata)
{
if(data.angle == 0){}
if(edata.dpx1 == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addDimAngular3P(const DL_DimensionData &data, const DL_DimAngular3PData &edata)
{
if(data.angle == 0){}
if(edata.dpx1 == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addDimOrdinate(const DL_DimensionData &data, const DL_DimOrdinateData &edata)
{
if(data.angle == 0){}
if(edata.dpx1 == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addLeader(const DL_LeaderData &data)
{
if(data.arrowHeadFlag == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addLeaderVertex(const DL_LeaderVertexData &data)
{
if(data.x == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addHatch(const DL_HatchData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfHatchs << data;
}
void DxfReader::addHatchLoop(const DL_HatchLoopData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfHatchLoops << data;
}
void DxfReader::addHatchEdge(const DL_HatchEdgeData &data)
{
//qDebug() << Q_FUNC_INFO;
dxfHatchEdges << data;
}
void DxfReader::addImage(const DL_ImageData &data)
{
if(data.brightness == 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::linkImage(const DL_ImageDefData &data)
{
if(data.file == ""){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addXRecord(const std::string &handle)
{
if(handle.length() <= 0){}
}
void DxfReader::addXRecordString(int code, const std::string &value)
{
if(code <= 0){}
if(value.length() <= 0){}
}
void DxfReader::addXRecordReal(int code, double value)
{
if(code <= 0){}
if(value <= 0){}
}
void DxfReader::addXRecordInt(int code, int value)
{
if(code <= 0){}
if(value <= 0){}
}
void DxfReader::addXRecordBool(int code, bool value)
{
if(code <= 0){}
if(value <= 0){}
}
void DxfReader::addXDataApp(const std::string &appId)
{
if(appId.length() <= 0){}
}
void DxfReader::addXDataString(int code, const std::string &value)
{
if(code <= 0){}
if(value.length() <= 0){}
}
void DxfReader::addXDataReal(int code, double value)
{
if(code <= 0){}
if(value <= 0){}
}
void DxfReader::addXDataInt(int code, int value)
{
if(code <= 0){}
if(value <= 0){}
}
void DxfReader::addDictionary(const DL_DictionaryData &data)
{
if(data.handle.length() <= 0){}
// qDebug() << Q_FUNC_INFO;
}
void DxfReader::addDictionaryEntry(const DL_DictionaryEntryData &data)
{
if(data.handle.length() <= 0){}
// qDebug() << Q_FUNC_INFO;
}
void DxfReader::setVariableVector(const std::string &key, double v1, double v2, double v3, int code)
{
if(key.length() <= 0){}
if(v1 <= 0){}
if(v2 <= 0){}
if(v3 <= 0){}
if(code <= 0){}
}
void DxfReader::setVariableString(const std::string &key, const std::string &value, int code)
{
if(key.length() <= 0){}
if(value.length() <= 0){}
if(code <= 0){}
}
void DxfReader::setVariableInt(const std::string &key, int value, int code)
{
if(key.length() <= 0){}
if(value <= 0){}
if(code <= 0){}
}
void DxfReader::setVariableDouble(const std::string &key, double value, int code)
{
if(key.length() <= 0){}
if(value <= 0){}
if(code <= 0){}
}
void DxfReader::add3dFace(const DL_3dFaceData &data)
{
if(data.thickness <= 0){}
//qDebug() << Q_FUNC_INFO;
}
void DxfReader::addComment(const std::string &comment)
{
if(comment.length() <= 0){}
}
void DxfReader::endSequence()
{
//qDebug() << Q_FUNC_INFO;
}

112
datafile/dxf/dxfreader.h Normal file
View File

@ -0,0 +1,112 @@
#ifndef DXFREADER_H
#define DXFREADER_H
#include <QObject>
#include <QTextCodec>
#include "dxflib/dl_dxf.h"
#include "dxflib/dl_creationadapter.h"
#include <QMetaType>
#include <QtCore/QList>
class DxfReader : public QObject, public DL_CreationAdapter
{
Q_OBJECT
public:
struct DxfText {
QString Text;
};
explicit DxfReader(const QString &fileName, QObject *parent = nullptr);
virtual void addText(const DL_TextData& data) override;
virtual void addLine(const DL_LineData& data) override;
virtual void addArc(const DL_ArcData& data) override;
virtual void addCircle(const DL_CircleData& data) override;
virtual void addEllipse(const DL_EllipseData& data) override;
virtual void addPolyline(const DL_PolylineData& data) override;
virtual void addPoint(const DL_PointData& data) override;
virtual void addSpline(const DL_SplineData& data) override;
virtual void addBlock(const DL_BlockData& data) override;
virtual void endBlock() override;
virtual void addLayer(const DL_LayerData& data) override;
virtual void addLinetype(const DL_LinetypeData& data) override;
virtual void addLinetypeDash(double length) override;
virtual void addXLine(const DL_XLineData& data) override;
virtual void addRay(const DL_RayData& data) override;
virtual void addVertex(const DL_VertexData& data) override;
virtual void addControlPoint(const DL_ControlPointData& data) override;
virtual void addFitPoint(const DL_FitPointData& data) override;
virtual void addKnot(const DL_KnotData& data) override;
virtual void addInsert(const DL_InsertData& data) override;
virtual void addSolid(const DL_SolidData& data) override;
virtual void addTrace(const DL_TraceData& data) override;
virtual void addTextStyle(const DL_StyleData& data) override;
virtual void addMTextChunk(const std::string& text) override;
virtual void addMText(const DL_MTextData& data) override;
virtual void addArcAlignedText(const DL_ArcAlignedTextData& data) override;
virtual void addAttribute(const DL_AttributeData& data) override;
virtual void addDimAlign(const DL_DimensionData& data, const DL_DimAlignedData& edata) override;
virtual void addDimLinear(const DL_DimensionData& data, const DL_DimLinearData& edata) override;
virtual void addDimRadial(const DL_DimensionData& data, const DL_DimRadialData& edata) override;
virtual void addDimDiametric(const DL_DimensionData& data, const DL_DimDiametricData& edata) override;
virtual void addDimAngular(const DL_DimensionData& data, const DL_DimAngularData& edata) override;
virtual void addDimAngular3P(const DL_DimensionData& data, const DL_DimAngular3PData& edata) override;
virtual void addDimOrdinate(const DL_DimensionData& data, const DL_DimOrdinateData& edata) override;
virtual void addLeader(const DL_LeaderData &data) override;
virtual void addLeaderVertex(const DL_LeaderVertexData &data) override;
virtual void addHatch(const DL_HatchData& data) override;
virtual void addHatchLoop(const DL_HatchLoopData& data) override;
virtual void addHatchEdge(const DL_HatchEdgeData& data) override;
virtual void addImage(const DL_ImageData &data) override;
virtual void linkImage(const DL_ImageDefData &data) override;
virtual void addXRecord(const std::string& handle) override;
virtual void addXRecordString(int code, const std::string& value) override;
virtual void addXRecordReal(int code, double value) override;
virtual void addXRecordInt(int code, int value) override;
virtual void addXRecordBool(int code, bool value) override;
virtual void addXDataApp(const std::string& appId) override;
virtual void addXDataString(int code, const std::string& value) override;
virtual void addXDataReal(int code, double value) override;
virtual void addXDataInt(int code, int value) override;
virtual void addDictionary(const DL_DictionaryData& data) override;
virtual void addDictionaryEntry(const DL_DictionaryEntryData& data) override;
virtual void setVariableVector(const std::string& key, double v1, double v2, double v3, int code) override;
virtual void setVariableString(const std::string& key, const std::string& value, int code) override;
virtual void setVariableInt(const std::string& key, int value, int code) override;
virtual void setVariableDouble(const std::string& key, double value, int code) override;
virtual void add3dFace(const DL_3dFaceData &data) override;
virtual void addComment(const std::string &comment) override;
virtual void endSequence() override;
QList<DL_LineData> dxfLines;
QList<DL_TextData> dxfText;
QList<DL_ArcData> dxfArcs;
QList<DL_CircleData> dxfCircles;
QList<DL_EllipseData> dxfEllipses;
QList<DL_PolylineData> dxfPolylines;
QList<DL_PointData> dxfPoints;
QList<DL_SplineData> dxfSplines;
QList<DL_BlockData> dxfBlocks;
QList<DL_VertexData> dxfVertexs;
QList<DL_LayerData> dxfLayers;
QList<DL_LinetypeData> dxfLinetypes;
QList<DL_XLineData> dxfXLines;
QList<DL_RayData> dxfRays;
QList<DL_ControlPointData> dxfControlPoints;
QList<DL_FitPointData> dxfFitPoints;
QList<DL_HatchData> dxfHatchs;
QList<DL_HatchLoopData> dxfHatchLoops;
QList<DL_HatchEdgeData> dxfHatchEdges;
private:
QString fileName;
};
#endif // DXFREADER_H

BIN
datafile/hpgl.7z Normal file

Binary file not shown.

2430
datafile/hpgl/importhpgl.cpp Normal file

File diff suppressed because it is too large Load Diff

268
datafile/hpgl/importhpgl.h Normal file
View File

@ -0,0 +1,268 @@
#ifndef IMPORTHPGL_H
#define IMPORTHPGL_H
#include <QObject>
#include <QPen>
#include <QPainter>
#include <QFont>
#include <QFile>
#include <QCoreApplication>
#include <QDir>
#include <QProcess>
#include <QStringList>
#include <QImage>
#include <QBitmap>
#include <qtextcodec.h>
#include "marker.h"
#include "plotbitmap.h"
#include "QtGui/private/qzipreader_p.h"
//#include "QtGui/private/qzipwriter_p.h"
#include "datafile/qrencode/qrencode.h"
#define DEFCMD_IN 0x8A //IN
#define DEFCMD_SP 0x7C //SP
#define DEFCMD_LT 0xE6 //LT 0:PS_SOLID; 1:PS_DASH; 2:PS_DOT; 3:PS_DASHDOT
#define DEFCMD_PG 0x97 //PG
#define DEFCMD_PU 0xB5 //PU 单个PU
#define DEFCMD_PD 0x3D //PD 单个PD
#define DEFCMD_LPU 0x5E //PU 连续PU
#define DEFCMD_LPD 0x3B //PD 连续PD
#define DEFCMD_DI 0x5B //AG 角度
#define DEFCMD_SI 0x5D //SI 64位双精度浮点
#define DEFCMD_FN 0x4B //FN 字体名
#define DEFCMD_LB 0x4D //LB
#define DEFCMD_BT 0x9A //BIT 位图
#define DEFCMD_CODE 0xE7 //CODE 条形码、二维码
#define DEFCMD_NULL 0x00 //NUll 空指令
#define DEFCMD_DRILL 0xD2 //DRILL 冲孔
#define DEFCMD_NOTCH 0xD3 //NOTCH 剪口
#define M_IDPMM 40.0
#define MMPIXELY (600/25.4)
#define PREVIEW_SIDE (10)
#define PREVIEW_WIDTH (240)
#define PREVIEW_HEIGHT (240)
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
#define PixelFormatIndexed 0x00010000 // Indexes into a palette
#define PixelFormatGDI 0x00020000 // Is a GDI-supported format
#define PixelFormat1bppIndexed (1 | ( 1 << 8) | PixelFormatIndexed | PixelFormatGDI)
struct SC
{
double dXMin;
double dXMax;
double dYMin;
double dYMax;
int nType;
double dLeft;
double dBottom;
};
class ImportHPGL : public QObject
{
Q_OBJECT
public:
explicit ImportHPGL(QObject *parent = 0);
virtual ~ImportHPGL();
signals:
public slots:
private:
//获得QR二维码版本
//输入参数nCount 字符个数
//返回参数QR二维码版本
int GetQRVesion(int nCount);
//样点旋转
//输入参数:
// ptPoint被旋转点,ptPointO旋转原点,dSinBeta,dCosBeta逆时针旋转角度的正余弦
//输出参数:
// ptPoint旋转后的值
void PointRotate(QPoint &ptPoint,QPoint ptPointO,double dSinBeta,double dCosBeta);
protected:
//分析S指令
//输入参数:
// pFile 切割数据文件
//输出参数:
// bEndOfFile =true 已到文件尾
//返回值:
// true 正确的G指令
// false 不正确的G指令
bool S_Code();
bool I_Code();
bool P_Code();
bool PU_Code();
bool PD_Code();
bool L_Code();
bool D_Code();
bool SC_Code();
bool C_Code();
//读取一个字符
//输出参数:
// *pChar 读取的字符
//返回值:
// 1 成功取得一个字符
// 0 失败
uint ReadChar(char* lpBuf);
//读取一个非空格、非回车、非换行的字符
//输入参数:
// pFile 切割数据文件
//输出参数:
// *pChar 读取的字符
//返回值:
// true 成功取得一个字符
// false 失败
bool GetChar(char *pChar);
//判断下一个非空格、非回车、非换行的字符是不是','
//输入参数:
// pFile 切割数据文件
//返回值:
// true 下一个非空格、非回车、非换行的字符是',', 并且已将','从文件中读出
// false 下一个非空格、非回车、非换行的字符不是',', 并且该字符没有从文件中读出
bool NextCharIsComma();
//取一个双精度浮点数
//输入参数:
// pFile 切割数据文件
//输出参数:
// dValue 取得的双精度浮点数
//返回值:
// true 成功取得一个双精度浮点数dValue
// false 失败
bool GetDoubleData(double &dValue);
//取一个整数
//输入参数:
// pFile 切割数据文件
//输出参数:
// iValue 取得的整数
//返回值:
// true 成功取得一个整数iValue
// false 失败
bool GetIntegerData(int &iValue);
//取坐标值
//输入参数:
// pFile 切割数据文件
//输出参数:
// ptPoint 坐标
//返回值:
// true 成功
// false 失败
bool GetCoordinate(QPoint &ptPoint);
//获得线的类型
//输入参数:
// pFile 切割数据文件
//输出参数:
// lineType 线型
//返回值:
// true 成功
// false 失败
bool GetLineType(LineType &lineType);
//查找一个指定的字符
//输入参数:
// pFile 切割数据文件
// cFind 指定的字符
//输出参数:
// strInfo 从开始位置到指定字符之前的内容(不包括最后的指定字符)
//返回值:
// true 成功取得一个字符
// false 失败
bool SearchChar(char cFind,QString &strInfo);
//将文件的读取位置移到下一个英文字母(26个英文字母)
//输入参数:
// pFile 切割数据文件
//输出参数:
// *pChar 读取的字符
//返回值:
// true 成功将文件的读取位置移到下一个英文字母
// false 失败
bool MoveToNextEnglishChar();
//将m_listXY加入到m_pMarker中,并将m_listXY清空
void AddPolylineToMarker();
void AddPoint2listXY(QPoint ptPoint);
int m_iDPMM; //长度数据单位:m_iDPMM(每毫米点)
int m_iPenNo; //当前的笔号
QPoint m_ptCurrentPos; //笔的当前位置,单位:(1/CMarker::m_iDPMM)毫米
LineType m_lineType;//当前线型
bool m_bPenUp;//当前刀具的状态 true:刀具状态为抬起 false刀具状态为落下
bool m_bPage;//是否识别到PG指令
Marker *m_pMarker; //当前使用的唛架,仅能在读文件时使用
double m_dScale; //读入文件时将切割数据文件的单位转换成内部数据单位时的比例
QPen m_penPen;//笔绘画笔
QPen m_cutPen;//切割画笔
QPen m_halfCutPen;//半透切割画笔
QList <QPoint> m_listXY; //还没有确定抬落刀的坐标
//QPainterPath m_polylinePainterPath;//绘图路径-线段
unsigned char m_chTerminator;//标志终结符,除了NULL LF ESC及;十进制分别为0,5,27,59;外的所有字符默认为ETX 十进制3
int m_nTerminatorMode;//模式0打印1不打印 默认值为1
double m_dTextHeight;//字的高度 单位cm
double m_dTextWidth;//字的宽度 单位cm
int m_nLableOrigin;//字符串相对于原点位置
double m_dTextAngle;//指定每行文本输出时相对于设备x轴的角度其单位为1/10度
QPoint m_ptP1;//解析IP指令中的坐标点
QPoint m_ptP2;//解析IP指令中的坐标点
SC m_sc;//解析SC指令
double m_dScaleX;//通过 IP和SC指令算出的缩放比例
double m_dScaleY;//通过 IP和SC指令算出的缩放比例
QPoint m_ptOrigin;//通过 IP和SC指令算出的原点
int m_nLength;//用于PG分页记录累计长度
char* m_pFileBuf;//存放从文件中读取的全部字符
int m_nCharCount;//已经读取的字符个数
int m_nFileLength;//文件长度
QString m_workPath;
bool m_bFontItalic; //文字斜体
int m_iFontSize; //字体榜数
QString m_strFontName;//字体名称
public:
//输入参数:
// pFile 需要读入的RS274D文件
// pMarker 解析到的数据保存到此唛架
//返回值:
// true 读入文件成功
// false 读入文件失败
bool Read(QString strPathName,Marker *pMarker);
bool Write(QString strPathName,Marker *pMarker);
//void creatPolylinePainterPath();//获得文件图形的范围
//QPainterPath GetPolylinePainterPath();
//int CreatePreviewImage(QString saveName,QImage * pImg = NULL, int saveflag = 0);
//初始化参数,读取参数前,需将参数值重置,避免造成参数值读取错误
void IniPara();
QPoint GetTextOrigin(QPoint pt,QString strText);
double GetTextAngle(double dX,double dY);
void SetScale();
bool IsSecretFile(QString strPatnName);
int BitMapDtat(QString strFileName,QString strSecretFile);
bool ReadSecretFile(QString stePathName,Marker *pMarker); // 打开位图文件
private slots:
//输入参数:
// bUp 刀的状态true抬起状态 false落下状态
// ptPoint 矢量字体中点阵中的一个坐标
void AddTextPointToLine(bool bUp,QPoint ptPoint);
};
#endif // IMPORTHPGL_H

261
datafile/hpgl/marker.cpp Normal file
View File

@ -0,0 +1,261 @@
#include "marker.h"
Marker::Marker(QObject *parent) :
QObject(parent)
{
m_iDPMM = 40;
m_listPolyline.clear();
m_nProducts = 0;
m_nActualMatchRegions = 0;
m_nMatchRegions = 0;
m_strProductCode = "";
}
Marker::~Marker()
{
}
Marker::Marker(const Marker &a): QObject()
{
m_iDPMM = a.m_iDPMM;
m_listPolyline.clear();
m_listPolyline.append(a.m_listPolyline);
m_nProducts = a.m_nProducts;
m_nActualMatchRegions = a.m_nActualMatchRegions;
m_nMatchRegions = a.m_nMatchRegions;
m_strProductCode = a.m_strProductCode;
}
Marker Marker::operator=(const Marker &a)
{
m_iDPMM = a.m_iDPMM;
m_listPolyline.clear();
m_listPolyline.append(a.m_listPolyline);
m_nProducts = a.m_nProducts;
m_nActualMatchRegions = a.m_nActualMatchRegions;
m_nMatchRegions = a.m_nMatchRegions;
m_strProductCode = a.m_strProductCode;
return *this;
}
void Marker::Initialize()
{
m_iDPMM = 40;
m_listPolyline.clear();
m_nProducts = 0;
m_nActualMatchRegions = 0;
m_nMatchRegions = 0;
m_strProductCode = "";
}
QRect Marker::GetRect()
{
QRect rect;
CRPPolyline RPPolyline;
rect.setRect(0,0,0,0);
for(int i = 0; i < m_listPolyline.size(); i++)
{
RPPolyline = m_listPolyline.at(i);
if (RPPolyline.m_nDrawingType == 0)
{
rect |= RectofPolyline(RPPolyline.m_listPoint);
}
else if (RPPolyline.m_nDrawingType == 3)
{
rect |= QRect(RPPolyline.m_text.m_ptPostLU,RPPolyline.m_text.m_ptPostRD);
}
else if (RPPolyline.m_nDrawingType == 1)
{
rect |= QRect(RPPolyline.m_bitmapInfo.m_ptAbPostLU,RPPolyline.m_bitmapInfo.m_ptAbPostRD);
}
}
return rect;
}
QRect Marker::RectofPolyline(const QList<QPoint> &listPoint)
{
if(listPoint.empty())
{
return QRect(0,0,0,0);
}
int iXMin = INT_MAX;
int iXMax = INT_MIN;
int iYMin = INT_MAX;
int iYMax = INT_MIN;
int iValueX;
int iValueY;
int iPointCount = listPoint.size();
for(int i = 0 ;i < iPointCount; i++)
{
iValueX = listPoint.at(i).x();
iValueY = listPoint.at(i).y();
if( iValueX > iXMax )
{
iXMax = iValueX;
}
if(iValueX < iXMin )
{
iXMin = iValueX;
}
if( iValueY > iYMax )
{
iYMax = iValueY;
}
if(iValueY < iYMin )
{
iYMin = iValueY;
}
}
return QRect(QPoint(iXMin,iYMin),QPoint(iXMax,iYMax));
}
double CNotch::angle_2(int startx, int starty, int endx, int endy)
{
//直线与X轴之间的夹角 X轴向量OE(1,0)
double dAngle = 0;
if((endx == startx) && (endy == starty))
{
return dAngle;
}
//求直线的向量坐标
double dX = endx - startx;
double dY = endy - starty;
dAngle = qAcos((dX)/(qSqrt(dX*dX + dY*dY)));
return dAngle;
}
void CNotch::CovertToOutputByOffset(int nOffSetX, int nOffsetY)
{
double a = 0;
double b = 0;
double c = 0;
//范围在[0,2pi)之间
double dAngle = angle_2(m_ptStart.x(),m_ptStart.y(),m_ptEnd.x(),m_ptEnd.y());
m_nAngle = dAngle*180.0/CONST_PI*100.0 + 0.5;
//double dX = m_ptEnd.x - m_ptStart.x;
//double dY = m_ptEnd.y - m_ptStart.y;
//double dLen = sqrt(dX*dX + dY*dY);
//m_ptCorrect.x = nOffSetY/dLen * dX + m_ptStart.x;
//m_ptCorrect.y = nOffsetY/dLen * dY + m_ptStart.y;
QPoint ptY;
ptY.setX(nOffsetY*cos(dAngle) + m_ptStart.x() + 0.5);
ptY.setY(nOffsetY*sin(dAngle) + m_ptStart.y() + 0.5);
if (nOffSetX == 0)
{
m_ptCorrect.setX(ptY.x());
m_ptCorrect.setY(ptY.y());
return;
}
int nX = m_ptEnd.x() - m_ptStart.x();
int nY = m_ptEnd.y() - m_ptStart.y();
if (nX == 0)
{
a = 0;
b = 1;
c = -ptY.y();
}
if (nY == 0)
{
a = 1;
b = 0;
c = -ptY.x();
}
double k = double(m_ptStart.x() - m_ptEnd.x())/double(m_ptEnd.y() - m_ptStart.y());
c = ptY.y() - k*ptY.x();
a = k;
b = -1;
int nRadius = abs(nOffSetX);
QPoint ptInter1;
QPoint ptInter2;
if (IntOfLineCircle(a,b,c,ptY.x(),ptY.y(),nRadius,ptInter1,ptInter2) == 2)
{
//向量
int nYv = ptInter1.y() - ptY.y();
int nXv = ptInter1.x() - ptY.x();
//判断该点在起点到终点连线的哪一侧?>0 右侧
if((nXv*nY -nYv*nX)>0)
{
if (nOffSetX > 0)//右侧
{
m_ptCorrect.setX(ptInter1.x());
m_ptCorrect.setY(ptInter1.y());
}
else
{
m_ptCorrect.setX(ptInter2.x());
m_ptCorrect.setY(ptInter2.y());
}
}
else
{
if (nOffSetX < 0)//左侧
{
m_ptCorrect.setX(ptInter1.x());
m_ptCorrect.setY(ptInter1.y());
}
else
{
m_ptCorrect.setX(ptInter2.x());
m_ptCorrect.setY(ptInter2.y());
}
}
}
}
int CNotch::IntOfLineCircle(double a, double b, double c, int xc, int yc, int nR, QPoint &lpptIntersection1, QPoint &lpptIntersection2)
{
//点:(x0,y0)
//线:Ax+By+C=0
//①距离=ABS(A*x0+B*y0+C) / SQRT(A*A+B*B)
double dis = 0;
dis = abs(a*xc+b*yc+c)/sqrt(a*a+b*b);
int rel = 0;
if(dis < nR)
{
rel = 0;
}
else if(dis == nR)
{
rel = 1;
}
else if(dis > nR)
{
double k = -a/b;
double b1 = 2*xc-2*k*(b-yc);
double sval = (b1/100.0)*(b1/100.0)*10000.0-4*a*c;
if(sval < 0)
{
qDebug()<<sval;
}
double tmp = sqrt(sval);
double x1 = (b1+tmp)/(2*a);
double y1 = k*x1+b;
double x2 = (b1-tmp)/(2*a);
double y2 = k*x2+b;
lpptIntersection1.setX(x1);
lpptIntersection1.setY(y1);
lpptIntersection2.setX(x2);
lpptIntersection2.setY(y2);
rel = 2;
}
return rel;
}

420
datafile/hpgl/marker.h Normal file
View File

@ -0,0 +1,420 @@
#ifndef MARKER_H
#define MARKER_H
#include <QObject>
#include <QPoint>
#include <QRect>
#include <QBitmap>
#include <QDebug>
#include <qmath.h>
#include <QList>
#include <QVector>
#define CONST_PI 3.14159265359
struct LineType
{
//具体参照HPGL英文版手册216页 当LT没有设置值时,线型为实线
bool bDefault;//LT是否设置值
int nLinetype;//线型 取值为-8~8 99 =0 实线 =1 虚线
int nPatternLength;//图案长度 缺省为P1、P2距离的4%
int nMode;//0相对模式 缺省值 解释为P1、P2距离的百分比 1绝对模式以毫米解释图案长度
};
class CBitmapInfo
{
public:
//原始读取的的坐标
QPoint m_ptPostLU; //位图的左上角在整个图中的XY位置
QPoint m_ptPostLD; //位图的左下角在整个图中的XY位置
QPoint m_ptPostRU; //位图的右上角在整个图中的XY位置
QPoint m_ptPostRD; //位图的右下角在整个图中的XY位置
//换算后的坐标
QPoint m_ptAbPostLU; //位图的左上角在整个图中的XY位置
QPoint m_ptAbPostLD; //位图的左下角在整个图中的XY位置
QPoint m_ptAbPostRU; //位图的右上角在整个图中的XY位置
QPoint m_ptAbPostRD; //位图的右下角在整个图中的XY位置
int m_iTransparent;//为1时则为透明显示; 为0则为非透明显示
int m_iBKColor;//背景颜色(在透明显示时背景颜色的点将不被显示)
int m_iWidth;// GDI+中BitmapData的Width,单位:像素
int m_iHeight;//GDI+中BitmapData的Height,单位:像素
int m_iStride;//GDI+中BitmapData的Stride(每行的字节数)
int m_iPixelFormat;//GDI+中BitmapData的PixelFormat
int m_iBytes;//int压缩后位图数据大小(字节数)
QBitmap m_pBitmap;//位图数据(压缩后的位图数据)
CBitmapInfo()
{
m_ptPostLU = QPoint(0,0);
m_ptPostLD = QPoint(0,0);
m_ptPostRU = QPoint(0,0);
m_ptPostRD = QPoint(0,0);
m_ptAbPostLU = QPoint(0,0);
m_ptAbPostLD = QPoint(0,0);
m_ptAbPostRU = QPoint(0,0);
m_ptAbPostRD = QPoint(0,0);
m_iTransparent = 0;
m_iBKColor = 0;
m_iWidth = 0;
m_iHeight = 0;
m_iStride = 0;
m_iPixelFormat = 1;
m_iBytes = 0;
//m_pBitmap = NULL;
}
~CBitmapInfo() {}
CBitmapInfo operator=(const CBitmapInfo &a)
{
m_ptPostLU = a.m_ptPostLU;
m_ptPostLD = a.m_ptPostLD;
m_ptPostRU = a.m_ptPostRU;
m_ptPostRD = a.m_ptPostRD;
m_ptAbPostLU = a.m_ptAbPostLU;
m_ptAbPostLD = a.m_ptAbPostLD;
m_ptAbPostRU = a.m_ptAbPostRU;
m_ptAbPostRD = a.m_ptAbPostRD;
m_iTransparent = a.m_iTransparent;
m_iBKColor = a.m_iBKColor;
m_iWidth = a.m_iWidth;
m_iHeight = a.m_iHeight;
m_iStride = a.m_iStride;
m_iPixelFormat = a.m_iPixelFormat;
m_iBytes = a.m_iBytes;
m_pBitmap = a.m_pBitmap;
return *this;
}
};
class CRPArc
{
public:
QPoint m_ptCenter;
int m_nRadius;
bool m_bCircle;//是圆还是圆弧1圆 0 :圆弧
QPoint m_ptStart;//圆弧起始点
QPoint m_ptEnd;//圆弧结束点
CRPArc()
{
m_bCircle = true;
}
~CRPArc() {}
CRPArc(CRPArc &a)
{
m_ptCenter = a.m_ptCenter;
m_nRadius = a.m_nRadius;
m_bCircle = a.m_bCircle;
m_ptStart = a.m_ptStart;
m_ptEnd = a.m_ptEnd;
}
CRPArc operator=(const CRPArc &a)
{
m_ptCenter = a.m_ptCenter;
m_nRadius = a.m_nRadius;
m_bCircle = a.m_bCircle;
m_ptStart = a.m_ptStart;
m_ptEnd = a.m_ptEnd;
return *this;
}
};
class CRPText
{
public:
QString m_strText;//字符串
QString m_strFontName;//字体名称
QPoint m_ptTextPos;//文字起点坐标
double m_dTextAngle;//文字角度
int m_nHeight;//文字高度
int m_nWidth;//文字宽度
int m_nWeight;//加粗
bool m_bItalic;//斜体
//文字坐标
QPoint m_ptPostLU; //文字的左上角在整个图中的XY位置
QPoint m_ptPostLD; //文字的左下角在整个图中的XY位置
QPoint m_ptPostRU; //文字的右上角在整个图中的XY位置
QPoint m_ptPostRD; //文字的右下角在整个图中的XY位置
CRPText()
{
m_strText = "";
m_strFontName = "";
m_ptTextPos = QPoint(0,0);
m_dTextAngle = 0;
m_nHeight = 0;
m_nWidth = 0;
m_nWeight = 0;
m_bItalic = false;
m_ptPostLU = QPoint(0,0);
m_ptPostLD = QPoint(0,0);
m_ptPostRU = QPoint(0,0);
m_ptPostRD = QPoint(0,0);
}
~CRPText() {}
CRPText(CRPText &a)
{
m_strText = a.m_strText;
m_strFontName = a.m_strFontName;
m_ptTextPos = a.m_ptTextPos;
m_dTextAngle = a.m_dTextAngle;
m_nHeight = a.m_nHeight;
m_nWidth = a.m_nWidth;
m_nWeight = a.m_nWeight;
m_bItalic = a.m_bItalic;
m_ptPostLU = a.m_ptPostLU;
m_ptPostLD = a.m_ptPostLD;
m_ptPostRU = a.m_ptPostRU;
m_ptPostRD = a.m_ptPostRD;
}
CRPText operator=( const CRPText &a)
{
m_strText = a.m_strText;
m_strFontName = a.m_strFontName;
m_ptTextPos = a.m_ptTextPos;
m_dTextAngle = a.m_dTextAngle;
m_nHeight = a.m_nHeight;
m_nWidth = a.m_nWidth;
m_nWeight = a.m_nWeight;
m_bItalic = a.m_bItalic;
m_ptPostLU = a.m_ptPostLU;
m_ptPostLD = a.m_ptPostLD;
m_ptPostRU = a.m_ptPostRU;
m_ptPostRD = a.m_ptPostRD;
return *this;
}
};
class CCode
{
public:
int m_nLX;//左上角X位置
int m_nLY;//左上角Y位置
int m_nSizeX;//X方向大小
int m_nSizeY;//Y方向大小
int m_nAngle;//角度(逆时针方向为正),单位0.01度
int m_nType;//类型(0条形码1二维码)
int m_nCount;//字符串个数(字符串的字节数)
QString m_strCode;//字符串
QBitmap *m_pBitmap;//生成的位图数据
CCode()
{
m_nLX = 0;
m_nLY = 0;
m_nSizeX = 0;
m_nSizeY = 0;
m_nAngle = 0;
m_nType = 0;
m_nCount = 0;
m_strCode = "";
}
~CCode() {}
CCode(CCode &a)
{
m_nLX = a.m_nLX;
m_nLY = a.m_nLY;
m_nSizeX = a.m_nSizeX;
m_nSizeY = a.m_nSizeY;
m_nAngle = a.m_nAngle;
m_nType = a.m_nType;
m_nCount = a.m_nCount;
m_strCode = a.m_strCode;
m_pBitmap = a.m_pBitmap;
}
CCode operator=(const CCode &a)
{
m_nLX = a.m_nLX;
m_nLY = a.m_nLY;
m_nSizeX = a.m_nSizeX;
m_nSizeY = a.m_nSizeY;
m_nAngle = a.m_nAngle;
m_nType = a.m_nType;
m_nCount = a.m_nCount;
m_strCode = a.m_strCode;
m_pBitmap = a.m_pBitmap;
return *this;
}
};
class CNotch
{
public:
QPoint m_ptStart;//剪口起点
QPoint m_ptEnd;//剪口终点
int m_nWidth;//剪口宽度
int m_nNotchType;//剪口类型
QPoint m_ptCorrect;//通过根据刀的X、Y偏移计算得出的实际落刀位置
int m_nAngle;//根据交口起点和终点计算得出的角度(逆时针方向为正),单位0.01度
double angle_2(int startx,int starty,int endx,int endy);
CNotch()
{
m_ptStart = QPoint(0,0);
m_ptEnd = QPoint(0,0);
m_nWidth = 0;;
m_nNotchType = 0;
m_ptCorrect = QPoint(0,0);
m_nAngle = 0;
}
~CNotch() {}
CNotch(CNotch &a)
{
m_ptStart = a.m_ptStart;
m_ptEnd = a.m_ptEnd;
m_nWidth = a.m_nWidth;
m_nNotchType = a.m_nNotchType;
m_ptCorrect = a.m_ptCorrect;
m_nAngle = a.m_nAngle;
}
CNotch operator=(const CNotch &a)
{
m_ptStart = a.m_ptStart;
m_ptEnd = a.m_ptEnd;
m_nWidth = a.m_nWidth;
m_nNotchType = a.m_nNotchType;
m_ptCorrect = a.m_ptCorrect;
m_nAngle = a.m_nAngle;
return *this;
}
void CovertToOutputByOffset(int nOffSetX,int nOffsetY);
int IntOfLineCircle(double a,double b,double c,int xc,int yc,int nR,QPoint &lpptIntersection1,QPoint &lpptIntersection2);
};
class CDrill
{
public:
QPoint m_pt;//冲孔的位置
int m_nDrillType;//冲孔类型
int m_nAngle;//冲孔的角度(逆时针方向为正),单位0.01度
CDrill()
{
m_pt = QPoint(0,0);
m_nDrillType = 0;;
m_nAngle = 0;
}
~CDrill() {}
CDrill(CDrill &a)
{
m_pt = a.m_pt;
m_nDrillType = a.m_nDrillType;
m_nAngle = a.m_nAngle;
}
CDrill operator=(const CDrill &a)
{
m_pt = a.m_pt;
m_nDrillType = a.m_nDrillType;
m_nAngle = a.m_nAngle;
return *this;
}
};
class CRPPolyline
{
public:
int m_nDrawingType;//0:直线 1:位图 2:圆 3:文字 4:条形码、二维码 5:钻孔 6:剪口
int m_nID;//标识切割线切割顺序 从0开始
int m_nPenNo;
bool m_bSelect;//是否处于选中状态true选中状态 false未选中状态
bool m_bPgEnd;//标识该切割线是该页的最后一条线
int m_nComType;//补偿类型 0 无补偿 1向右补偿 2向左补偿
CBitmapInfo m_bitmapInfo;
CRPArc m_circle;
CRPText m_text;
CCode m_code;
CDrill m_drill;
CNotch m_notch;
LineType m_lineType;
QList<QPoint> m_listPoint;
CRPPolyline()
{
m_nDrawingType = 0;
m_nID = 0;
m_nPenNo = 0;
m_bSelect = false;
m_bPgEnd = false;
m_lineType.bDefault = true;
m_listPoint.clear();
m_nComType = 0;
}
~CRPPolyline() {}
CRPPolyline(const CRPPolyline &a)
{
m_nDrawingType = a.m_nDrawingType;
m_nID = a.m_nID;
m_nPenNo = a.m_nPenNo;
m_bSelect = a.m_bSelect;
m_bPgEnd = a.m_bPgEnd;
m_lineType = a.m_lineType;
m_listPoint.clear();
m_listPoint.append(a.m_listPoint);
m_text = a.m_text;
m_nComType = a.m_nComType;
m_circle = a.m_circle;
m_text = a.m_text;
m_code = a.m_code;
m_notch = a.m_notch;
m_drill = a.m_drill;
m_bitmapInfo = a.m_bitmapInfo;
}
CRPPolyline operator=( const CRPPolyline &a)
{
m_nDrawingType = a.m_nDrawingType;
m_nID = a.m_nID;
m_nPenNo = a.m_nPenNo;
m_bSelect = a.m_bSelect;
m_bPgEnd = a.m_bPgEnd;
m_lineType = a.m_lineType;
m_listPoint.clear();
m_listPoint.append(a.m_listPoint);
m_text = a.m_text;
m_nComType = a.m_nComType;
m_circle = a.m_circle;
m_text = a.m_text;
m_code = a.m_code;
m_notch = a.m_notch;
m_drill = a.m_drill;
m_bitmapInfo = a.m_bitmapInfo;
return *this;
}
};
class Marker : public QObject
{
Q_OBJECT
public:
explicit Marker(QObject *parent = 0);
virtual ~Marker();
Marker(const Marker &a);
Marker operator=(const Marker &a);
void Initialize();
QRect GetRect();
QRect RectofPolyline(const QList <QPoint> &listPoint);
double m_iDPMM; //长度数据单位:m_iDPMM(每毫米点)
QList <CRPPolyline> m_listPolyline; //切割的点链,单位:1/m_iDPMM mm, X向右为正Y向上为正
int m_nProducts;
int m_nActualMatchRegions;
int m_nMatchRegions;
QString m_strProductCode;//产品型号
signals:
public slots:
};
#endif // MARKER_H

View File

@ -0,0 +1,89 @@
#include "plotbitmap.h"
PlotBitmap::PlotBitmap(QObject *parent) : QObject(parent)
{
}
//QBitmap PlotBitmap::Create1BPPBitmap(int bTransparent, int crBkColor, int iWidth, int iHeight, int iStride, int nPixFormat, char *pBmpData)
QBitmap PlotBitmap::Create1BPPBitmap(int iWidth,int iHeight,unsigned char *pBmpData)
{
if(pBmpData == NULL)
{
qDebug()<<"pBmpData == NULL";
}
QPen pen;
pen.setWidth(1);
pen.setColor(QColor(Qt::black));
//QImage::Format_RGBA8888 代表彩色图
QImage image = QImage(pBmpData, iWidth, iHeight, QImage::Format_RGBA8888);
//image.save("D:\\1.png");
QBitmap pixmap = QBitmap(iWidth,iHeight);
QPainter *pixPainter = new QPainter();
pixPainter->begin(&pixmap);
pixPainter->setPen(pen);
pixmap.fill(Qt::white);//用白色填充
pixPainter->drawImage(0,0,image);
//pixmap.save("D:\\1.bmp");
pixPainter->end();
#if(0)//转灰度图
QImage gimage = QImage();
uchar* pImageData1 = NULL,*pImageData2 = NULL;
pImageData1 = image.bits();
gimage = image.convertToFormat(QImage::Format_Indexed8);
QVector<QRgb> table;
for( int i = 0 ; i < 256 ; ++i )
{
table.append(qRgb(i,i,i));
}
gimage.setColorTable(table);
for(int i =0; i< gimage.width();i++)
{
for(int j=0; j< gimage.height();j++)
{
QRgb pix_value = gimage.pixel(i,j);
gimage.setPixel(i,j,qGray(pix_value));
}
}
pImageData2 = gimage.bits();
gimage.save("D:\\1.bmp");
#endif
if(pixPainter != NULL)
{
delete pixPainter;
}
return pixmap;
}
//设置unsigned char中某位的值
//dat 需要设置的unsigned char
//index 设置位
//val 设置值0或者1
void PlotBitmap::SetUncharBit(unsigned char &dat, int index, int val)
{
unsigned int bitmod = 0x01;
if(index >= 0 && index < 8)
{
bitmod <<= index;
if (val == 0)
{
dat &= ~bitmod;
}
else
{
dat |= bitmod;
}
}
}

View File

@ -0,0 +1,65 @@
#ifndef PLOTBITMAP_H
#define PLOTBITMAP_H
#include <QObject>
#include <QPainter>
#include <QBitmap>
#include <QFile>
#include <QDebug>
//#include <gdiplus.h>
//BMP文件头14字节
typedef struct /**** BMP file header structure ****/
{
unsigned short bfType; /* 类型 */
unsigned int bfSize; /* 整个bmp文件大小 */
unsigned short bfReserved1; /* Reserved */
unsigned short bfReserved2; /* ... */
unsigned int bfOffBits; /* 偏移数,位图文件头+位图信息头+调色板大小 */
} BmpHeader;
//位图信息头40字节
typedef struct /**** BMP file info structure ****/
{
unsigned int biSize; /* Size of info header */
int biWidth; /* Width of image */
int biHeight; /* Height of image */
unsigned short biPlanes; /* Number of color planes */
unsigned short biBitCount; /* Number of bits per pixel */
unsigned int biCompression; /* Type of compression to use */
unsigned int biSizeImage; /* Size of image data */
int biXPelsPerMeter; /* X pixels per meter */
int biYPelsPerMeter; /* Y pixels per meter */
unsigned int biClrUsed; /* Number of colors used */
unsigned int biClrImportant; /* Number of important colors */
} BmpInfo;
class PlotBitmap : public QObject
{
Q_OBJECT
public:
explicit PlotBitmap(QObject *parent = nullptr);
public:
//创建单色的位图
//输入参数:
// bTransparent 透明显示
// crBkColor 背景颜色(在透明显示时位图中颜色为crBkColor的点将不被显示在纸样上)
// iWidth 位图的宽,单位:像素
// iHeight 位图的高,单位:像素
// iStride 位图每行的字节数
// nPixFormat 位图点的格式(见GDI+中BitmapData类PixelFormat的定义)
// pBmpData 位图数据(保存数据的顺序是从左到右,从上到下)
//返回值:
// NULL 失败
// 非NULL 新生成的位图指针
//QBitmap Create1BPPBitmap(int bTransparent,int crBkColor,int iWidth,int iHeight,int iStride,int nPixFormat,char *pBmpData);
QBitmap Create1BPPBitmap(int iWidth,int iHeight,unsigned char *pBmpData);
void SetUncharBit(unsigned char & dat, int index, int val);
signals:
public slots:
};
#endif // PLOTBITMAP_H

107
datafile/hpgl/typedef.h Normal file
View File

@ -0,0 +1,107 @@
#ifndef TYPEDEF_H
#define TYPEDEF_H
//---------------------------------------------------------------
#ifndef NULL
#define NULL ((void *) 0)
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
//---------------------------------------------------------------
#define DATA_VALID 0x55AA
//---------------------------------------------------------------
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short int WORD;
typedef unsigned long int DWORD;
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned int u32;
typedef char s8;
typedef short int s16;
typedef int s32;
//---------------------------------------------------------------
#define U8_MAX ((u8)255)
#define S8_MAX ((s8)127)
#define S8_MIN ((s8)(-128))
#define U16_MAX ((u16)65535u)
#define S16_MAX ((s16)32767)
#define S16_MIN ((s16)(-32768))
#define U32_MAX ((u32)4294967295uL)
#define S32_MAX ((s32)2147483647uL)
#define S32_MIN ((s32)(-2147483648uL))
//---------------------------------------------------------------
#ifndef LOBYTE
#define LOBYTE(w) ((BYTE)(((WORD)(w)) & 0xff))
#endif
#ifndef HIBYTE
#define HIBYTE(w) ((BYTE)((((WORD)(w)) >> 8) & 0xff))
#endif
#ifndef LOWORD
#define LOWORD(l) ((WORD)(((DWORD)(l)) & 0xffff))
#endif
#ifndef HIWORD
#define HIWORD(l) ((WORD)((((DWORD)(l)) >> 16) & 0xffff))
#endif
#ifndef MAKEWORD
#define MAKEWORD(a, b) ((WORD)((BYTE)(a)) | (((WORD)((BYTE)(b))) << 8))
#endif
#ifndef MAKEDWORD
#define MAKEDWORD(a, b) ((DWORD)((WORD)(a)) | (((DWORD)((WORD)(b))) << 16))
#endif
#ifndef LOHFBYTE
#define LOHFBYTE(b) ((BYTE)((b) & 0x0f))
#endif
#ifndef HIHFBYTE
#define HIHFBYTE(b) ((BYTE)(((b) >> 4) & 0x0f))
#endif
#ifndef MAKEBYTE
#define MAKEBYTE(a, b) ((BYTE)((BYTE)((a) & 0x0f)) | ((BYTE)(((BYTE)((b) & 0x0f)) << 4)))
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
//---------------------------------------------------------------
#ifndef PI
#define PI 3.1415926535897932
#endif
#endif // TYPEDEF_H

View File

@ -0,0 +1,918 @@
#include "vectorfont.h"
#include <QFile>
#include <qmath.h>
#include "main.h"
VectorFont::VectorFont(QObject *parent) :
QObject(parent)
{
m_iDPMM = 40;
m_pChinese_char = NULL;
m_pEnglish_char = NULL;
m_nChinese_char_count = 0;
m_nEnglish_char_count = 0;
IniVectorFont();
}
VectorFont::~VectorFont()
{
if(m_pChinese_char != NULL)
{
delete []m_pChinese_char;
m_pChinese_char = NULL;
}
if(m_pEnglish_char != NULL)
{
delete []m_pEnglish_char;
m_pEnglish_char = NULL;
}
}
void VectorFont::IniVectorFont()
{
QFile fntFile;
QString strCharFileName;
BYTE byte[10];
int nCharCount_C;
int nCharCount_E;
CChinese_char Chinese_char1;
CEnglish_char English_char1;
int nCountChar;
QString appPath = QCoreApplication::applicationDirPath();
QChar separator = QChar('/');
if(!appPath.contains(separator)) // 判断分隔符
{
separator = QChar('\\');
}
m_workPath = appPath + separator;
strCharFileName = m_workPath + "english.fnt";
//qDebug()<< "strCharFileName" << strCharFileName;
fntFile.setFileName(strCharFileName);
if(!fntFile.open(QIODevice::ReadOnly))
{
qDebug() <<"english file open failed";
return;
}
fntFile.seek(0);
fntFile.read((char*)byte,10);
m_nInternalLeading_E=(int)((WORD)byte[0] | ((WORD)byte[1] << 8));
m_nHeight_E=(int)((WORD)byte[2] | ((WORD)byte[3] << 8));
m_nDescent_E=(int)((WORD)byte[4] | ((WORD)byte[5] << 8));
nCharCount_E=(int)((DWORD)byte[6] | ((DWORD)byte[7] << 8) | ((DWORD)byte[9] << 16) | ((DWORD)byte[9] << 24));
//m_aEnglish_char.clear();
m_pEnglish_char = new CEnglish_char[nCharCount_E];
m_nEnglish_char_count = nCharCount_E;
fntFile.seek(10);
nCountChar=nCharCount_E;
while (nCountChar > 0)
{
fntFile.read((char*)byte,10);
English_char1.m_wCharCode=(WORD)byte[0] | ((WORD)byte[1] << 8);
English_char1.m_wBytes=(WORD)byte[2] | ((WORD)byte[3] << 8);
English_char1.m_wWidth=(WORD)byte[4] | ((WORD)byte[5] << 8);
English_char1.m_dwPosition=(DWORD)byte[6] | ((DWORD)byte[7] << 8) | ((DWORD)byte[9] << 16) | ((DWORD)byte[9] << 24);
m_pEnglish_char[nCharCount_E-nCountChar] = English_char1;
//m_aEnglish_char.append(English_char1);
nCountChar--;
}
fntFile.close();
strCharFileName = m_workPath + "Hz.fnt";
//qDebug()<< "strCharFileName" << strCharFileName;
fntFile.setFileName(strCharFileName);
if(!fntFile.open(QIODevice::ReadOnly))
{
qDebug() <<"chinese file open failed";
return;
}
fntFile.seek(0);
fntFile.read((char*)byte,8);
m_nWidth_C=(int)((WORD)byte[0] | ((WORD)byte[1] << 8));
m_nHeight_C=(int)((WORD)byte[2] | ((WORD)byte[3] << 8));
nCharCount_C=(int)((DWORD)byte[4] | ((DWORD)byte[5] << 8) | ((DWORD)byte[6] << 16) | ((DWORD)byte[7] << 24));
//m_aChinese_char.clear();
m_pChinese_char = new CChinese_char[nCharCount_C];
m_nChinese_char_count = nCharCount_C;
fntFile.seek(8);
nCountChar=nCharCount_C;
while (nCountChar > 0)
{
fntFile.read((char*)byte,8);
Chinese_char1.m_wCharCode=(WORD)byte[0] | ((WORD)byte[1] << 8);
Chinese_char1.m_wBytes=(WORD)byte[2] | ((WORD)byte[3] << 8);
Chinese_char1.m_dwPosition=(DWORD)byte[4] | ((DWORD)byte[5] << 8) | ((DWORD)byte[6] << 16) | ((DWORD)byte[7] << 24);
m_pChinese_char[nCharCount_C-nCountChar] = Chinese_char1;
//m_aChinese_char.append(Chinese_char1);
nCountChar--;
}
fntFile.close();
m_dFontAngle = 0;
m_dFontHeight = 0.375 * 10 * m_iDPMM;
}
//输入参数:
// ptPointLU 显示字符串的左上角坐标(即TextOut(...)的x,y值)
// pbyData 字符的描述数据
// wBytes 字符的描述数据个数
// nLeft,nDown 字符的左下角坐标(即以英汉字库的公共单位及坐标水平绘制字符串时,字符的的左下角坐标)
// nFontScale 字库的长度比例
void VectorFont::PlotChar(QPoint ptPointLU,BYTE *pbyData,WORD wBytes,int nLeft,int nDown,int nFontScale)
{
BYTE byByteX,byByteY;
QPoint ptCurrentPos,ptCenter,ptPointS,ptPointE;
QPoint ptPoint1;
WORD wIndex1;
WORD wDirection,wLength;
BOOL bPenUp,bVerTextCommand,bClockwise;
WORD wRadius,wArcS,wSpan;
int nRadius;
double dAngleS,dAngleE,dAngleOffsetS,dAngleOffsetE;
double dx1,dy1,dx2,dy2,dxc,dyc,dr,dD,dH,dBulge;
double dCos,dSin;
double dLToDScale;
int nHeight;
if (wBytes == 0) return;
nHeight=(m_nInternalLeading_E + m_nHeight_E) * m_nHeight_E;
//nHeight=(m_nInternalLeading_E + m_nHeight_E) * m_nHeight_C; //之前
dLToDScale=(double)nHeight / m_dFontHeight;
m_dRake = m_dFontAngle/180.0*PI;
dCos=cos(m_dRake);
dSin=sin(m_dRake);
ptCurrentPos=QPoint(nLeft,nDown);
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
MoveTo(ptPoint1);
bVerTextCommand=false;
bPenUp=false;
wIndex1=0;
while (wIndex1 < wBytes) {
switch (pbyData[wIndex1]) {
case 0x0:
wIndex1++;
break;
case 0x1:
wIndex1++;
bPenUp=false;
break;
case 0x2:
wIndex1++;
bPenUp=true;
break;
case 0x3:
wIndex1++;
wIndex1++;
bVerTextCommand=false;
break;
case 0x4:
wIndex1++;
wIndex1++;
bVerTextCommand=false;
break;
case 0x5:
wIndex1++;
bPenUp=true;
break;
case 0x6:
wIndex1++;
bPenUp=true;
break;
case 0x7:
wIndex1++;
wIndex1++;
bPenUp=true;
break;
case 0x8:
if (bVerTextCommand) {
wIndex1=wIndex1+3;
}
else {
wIndex1++;
ptCurrentPos.setX(ptCurrentPos.x() + (char)pbyData[wIndex1] * nFontScale);
wIndex1++;
ptCurrentPos.setY(ptCurrentPos.y() + (char)pbyData[wIndex1] * nFontScale);
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
if (bPenUp)
MoveTo(ptPoint1);
else
LineTo(ptPoint1);
wIndex1++;
}
bVerTextCommand=false;
break;
case 0x9:
if (bVerTextCommand) {
wIndex1++;
byByteX=pbyData[wIndex1];
wIndex1++;
byByteY=pbyData[wIndex1];
while ((byByteX != 0) || (byByteY != 0)) {
wIndex1++;
byByteX=pbyData[wIndex1];
wIndex1++;
byByteY=pbyData[wIndex1];
}
wIndex1++;
}
else {
wIndex1++;
byByteX=pbyData[wIndex1];
wIndex1++;
byByteY=pbyData[wIndex1];
while ((byByteX != 0) || (byByteY != 0)) {
ptCurrentPos.setX(ptCurrentPos.x() + (char)byByteX * nFontScale);
ptCurrentPos.setY(ptCurrentPos.y() + (char)byByteY * nFontScale);
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
if (bPenUp)
MoveTo(ptPoint1);
else
LineTo(ptPoint1);
wIndex1++;
byByteX=pbyData[wIndex1];
wIndex1++;
byByteY=pbyData[wIndex1];
}
wIndex1++;
}
bVerTextCommand=false;
break;
case 0xA:
if (bVerTextCommand) {
wIndex1=wIndex1+3;
}
else {
wIndex1++;
wRadius=(WORD)pbyData[wIndex1];
wIndex1++;
if (((char)pbyData[wIndex1]) < 0) bClockwise=true;
else bClockwise=false;
wArcS=(WORD)pbyData[wIndex1];
wArcS=wArcS & 0x70;
wArcS=wArcS >> 4;
wSpan=(WORD)pbyData[wIndex1];
wSpan=wSpan & 0x7;
//计算圆心
ptCenter=ptCurrentPos;
ptCenter.setX(ptCenter.x() - ((double)wRadius * (double)nFontScale * cos((double)wArcS * 45.0 / 180.0 * 3.14159265359))+0.5);
ptCenter.setY(ptCenter.y() - ((double)wRadius * (double)nFontScale * sin((double)wArcS * 45.0 / 180.0 * 3.14159265359))+0.5);
dAngleS=(double)wArcS * 45.0 / 180.0 * 3.14159265359;
if (bClockwise) dAngleE=dAngleS - (double)wSpan * 45.0 / 180.0 * 3.14159265359;
else dAngleE=dAngleS + (double)wSpan * 45.0 / 180.0 * 3.14159265359;
if (bClockwise) {
ptPointS.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleE)+0.5);
ptPointS.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleE)+0.5);
ptPointE.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleS)+0.5);
ptPointE.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleS)+0.5);
ptCurrentPos=ptPointS;
}
else {
ptPointS.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleS)+0.5);
ptPointS.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleS)+0.5);
ptPointE.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleE)+0.5);
ptPointE.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleE)+0.5);
ptCurrentPos=ptPointE;
}
ptCenter=CPToLP(ptCenter,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointS=CPToLP(ptPointS,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointE=CPToLP(ptPointE,nHeight,ptPointLU,dSin,dCos,dLToDScale);
nRadius=(double)wRadius * (double)nFontScale / dLToDScale + 0.5;
Arc(ptCenter.x() - nRadius,ptCenter.y() - nRadius,
ptCenter.x() + nRadius,ptCenter.y() + nRadius,
ptPointS.x(),ptPointS.y(),ptPointE.x(),ptPointE.y());
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
MoveTo(ptPoint1);
wIndex1++;
}
bVerTextCommand=false;
break;
case 0xB:
if (bVerTextCommand) {
wIndex1=wIndex1+6;
}
else {
wIndex1++;
dAngleOffsetS=(double)((WORD)pbyData[wIndex1]);
wIndex1++;
dAngleOffsetE=(double)((WORD)pbyData[wIndex1]);
wIndex1++;
wRadius=(WORD)pbyData[wIndex1];
wRadius=wRadius << 8;
wIndex1++;
wRadius=wRadius | (WORD)pbyData[wIndex1];
wIndex1++;
if (((char)pbyData[wIndex1]) < 0) bClockwise=true;
else bClockwise=false;
wArcS=(WORD)pbyData[wIndex1];
wArcS=wArcS & 0x70;
wArcS=wArcS >> 4;
wSpan=(WORD)pbyData[wIndex1];
wSpan=wSpan & 0x7;
//计算圆心
ptCenter=ptCurrentPos;
ptCenter.setX(ptCenter.x() - (double)wRadius * (double)nFontScale * cos((double)wArcS * 45.0 / 180.0 * 3.14159265359)+0.5);
ptCenter.setY(ptCenter.y() - (double)wRadius * (double)nFontScale * sin((double)wArcS * 45.0 / 180.0 * 3.14159265359)+0.5);
dAngleS=(double)wArcS * 45.0;
dAngleS=dAngleOffsetS * 45.0 / 256.0 + dAngleS;
if (bClockwise) dAngleE=-(double)wSpan * 45.0;
else dAngleE=(double)wSpan * 45.0;
dAngleE=dAngleOffsetE * 45.0 / 256.0 + dAngleE;
dAngleE=dAngleOffsetE * 45.0 / 256.0 + dAngleE;
dAngleS=dAngleS / 180.0 * 3.14159265359;
dAngleE=dAngleE / 180.0 * 3.14159265359;
if (bClockwise) {
ptPointS.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleE)+0.5);
ptPointS.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleE)+0.5);
ptPointE.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleS)+0.5);
ptPointE.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleS)+0.5);
ptCurrentPos=ptPointS;
}
else {
ptPointS.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleS)+0.5);
ptPointS.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleS)+0.5);
ptPointE.setX(ptCenter.x() + (double)wRadius * (double)nFontScale * cos(dAngleE)+0.5);
ptPointE.setY(ptCenter.y() + (double)wRadius * (double)nFontScale * sin(dAngleE)+0.5);
ptCurrentPos=ptPointE;
}
ptCenter=CPToLP(ptCenter,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointS=CPToLP(ptPointS,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointE=CPToLP(ptPointE,nHeight,ptPointLU,dSin,dCos,dLToDScale);
nRadius=(double)wRadius * (double)nFontScale / dLToDScale + 0.5;
Arc(ptCenter.x() - nRadius,ptCenter.y() - nRadius,
ptCenter.x() + nRadius,ptCenter.y() + nRadius,
ptPointS.x(),ptPointS.y(),ptPointE.x(),ptPointE.y());
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
MoveTo(ptPoint1);
wIndex1++;
}
bVerTextCommand=false;
break;
case 0xC:
if (bVerTextCommand) {
wIndex1=wIndex1+4;
}
else {
wIndex1++;
dx1=(double)((char)pbyData[wIndex1]) * (double)nFontScale;
wIndex1++;
dy1=(double)((char)pbyData[wIndex1]) * (double)nFontScale;
wIndex1++;
dBulge=(double)((char)pbyData[wIndex1]);
if (((char)pbyData[wIndex1]) < 0) bClockwise=true;
else bClockwise=false;
dD=sqrt(dx1*dx1 + dy1*dy1);
dH=fabs(dBulge) * dD / 127.0 / 2.0;
if (((char)pbyData[wIndex1]) == 0) {
ptCurrentPos.setX(ptCurrentPos.x() + (int)dx1);
ptCurrentPos.setY(ptCurrentPos.y() - (int)dy1);
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
if (bPenUp) MoveTo(ptPoint1);
else LineTo(ptPoint1);
}
else {
if (bClockwise) {
dx2=-dy1;
dy2=dx1;
}
else {
dx2=dy1;
dy2=-dx1;
}
dx2=dx2 / dD * dH + dx1 / 2.0;
dy2=dy2 / dD * dH + dy1 / 2.0;
CircleCR(0.0,0.0,dx2,dy2,dx1,dy1,dxc,dyc,dr);
ptCenter.setX(ptCurrentPos.x() + dxc + 0.5);
ptCenter.setY(ptCurrentPos.y() + dyc + 0.5);
if (bClockwise)
{
ptPointS.setX(ptCurrentPos.x() + dx1 + 0.5);
ptPointS.setY(ptCurrentPos.y() + dy1 + 0.5 );
ptPointE=ptCurrentPos;
ptCurrentPos=ptPointS;
}
else
{
ptPointS=ptCurrentPos;
ptPointE.setX(ptCurrentPos.x() + dx1 + 0.5);
ptPointE.setY(ptCurrentPos.y() + dy1 + 0.5);
ptCurrentPos=ptPointE;
}
ptCenter=CPToLP(ptCenter,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointS=CPToLP(ptPointS,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointE=CPToLP(ptPointE,nHeight,ptPointLU,dSin,dCos,dLToDScale);
nRadius=dr / dLToDScale + 0.5;
Arc(ptCenter.x() - nRadius,ptCenter.y() - nRadius,ptCenter.x() + nRadius,ptCenter.y() + nRadius,
ptPointS.x(),ptPointS.y(),ptPointE.x(),ptPointE.y());
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
MoveTo(ptPoint1);
}
wIndex1++;
}
bVerTextCommand=false;
break;
case 0xD:
if (bVerTextCommand) {
wIndex1=wIndex1+4;
}
else {
wIndex1++;
while ((pbyData[wIndex1] != 0) || (pbyData[wIndex1+1] != 0)) {
dx1=(double)((char)pbyData[wIndex1]) * (double)nFontScale;
wIndex1++;
dy1=(double)((char)pbyData[wIndex1]) * (double)nFontScale;
wIndex1++;
dBulge=(double)((char)pbyData[wIndex1]);
if (((char)pbyData[wIndex1]) < 0) bClockwise=true;
else bClockwise=false;
dD=sqrt(dx1*dx1 + dy1*dy1);
dH=fabs(dBulge) * dD / 127.0 / 2.0;
if (((char)pbyData[wIndex1]) == 0) {
ptCurrentPos.setX(ptCurrentPos.x() + (int)dx1);
ptCurrentPos.setY(ptCurrentPos.y() - (int)dy1);
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
if (bPenUp)
MoveTo(ptPoint1);
else
LineTo(ptPoint1);
}
else {
if (bClockwise) {
dx2=-dy1;
dy2=dx1;
}
else {
dx2=dy1;
dy2=-dx1;
}
dx2=dx2 / dD * dH + dx1 / 2.0;
dy2=dy2 / dD * dH + dy1 / 2.0;
CircleCR(0.0,0.0,dx2,dy2,dx1,dy1,dxc,dyc,dr);
ptCenter.setX(ptCurrentPos.x() + dxc + 0.5);
ptCenter.setY(ptCurrentPos.y() + dyc + 0.5);
if (bClockwise)
{
ptPointS.setX(ptCurrentPos.x() + dx1 + 0.5);
ptPointS.setY(ptCurrentPos.y() + dy1 + 0.5);
ptPointE=ptCurrentPos;
ptCurrentPos=ptPointS;
}
else
{
ptPointS=ptCurrentPos;
ptPointE.setX(ptCurrentPos.x() + dx1 + 0.5);
ptPointE.setY(ptCurrentPos.y() + dy1 + 0.5);
ptCurrentPos=ptPointE;
}
ptCenter=CPToLP(ptCenter,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointS=CPToLP(ptPointS,nHeight,ptPointLU,dSin,dCos,dLToDScale);
ptPointE=CPToLP(ptPointE,nHeight,ptPointLU,dSin,dCos,dLToDScale);
nRadius=dr / dLToDScale + 0.5;
Arc(ptCenter.x() - nRadius,ptCenter.y() - nRadius,ptCenter.x() + nRadius,ptCenter.y() + nRadius,
ptPointS.x(),ptPointS.y(),ptPointE.x(),ptPointE.y());
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
MoveTo(ptPoint1);
}
wIndex1++;
}
}
bVerTextCommand=false;
break;
case 0xE:
bVerTextCommand=true;
wIndex1++;
break;
default:
if (bVerTextCommand) {
wIndex1++;
}
else {
wDirection=(WORD)(pbyData[wIndex1] % 16);
wLength=(WORD)(pbyData[wIndex1] / 16) * (WORD)nFontScale;
ptCurrentPos=GetNextCoodinate(wDirection,wLength,ptCurrentPos);
ptPoint1=CPToLP(ptCurrentPos,nHeight,ptPointLU,dSin,dCos,dLToDScale);
if (bPenUp) MoveTo(ptPoint1);
else LineTo(ptPoint1);
wIndex1++;
}
bVerTextCommand=false;
break;
}
}
}
QPoint VectorFont::CPToLP(QPoint ptCP,int nHeight,QPoint ptPointLU,double dSin,double dCos,double dScale)
{
double dx,dy;
QPoint ptPoint1;
dx=(double)ptCP.x();
dy=(double)ptCP.y()-(double)nHeight;
ptPoint1.setX(ptPointLU.x() + ((dx*dCos - dy*dSin) / dScale + 0.5));
ptPoint1.setY(ptPointLU.y() + ((dx*dSin + dy*dCos) / dScale + 0.5));
return ptPoint1;
}
//抬笔移动到点(x,y)
void VectorFont::MoveTo(long x, long y)
{
if(x == 0){}
if(y == 0){}
}
//抬笔移动到点ptPoint
void VectorFont::MoveTo(QPoint ptPoint)
{
emit siMoveTo(true,ptPoint);
}
//从当前位置画线到点(x,y),
void VectorFont::LineTo(long x, long y)
{
if(x == 0){}
if(y == 0){}
}
//从当前位置画线到点ptPoint
void VectorFont::LineTo(QPoint ptPoint)
{
emit siLineTo(false,ptPoint);
}
//从(x,y)点开始写字nCount为字节数
void VectorFont::TextOutString(int x, int y, const char* lpszString, int nCount)
{
QString strEnglish,strChinese;
QFile fileEnglish,fileChinese;
BYTE *pbyData;
int nLeft;
BYTE byByte1,byByte2;
WORD wCharCode;
int nIndex1,nIndex2,nIndex3,nIndex4;
bool bEnglishChar;
strEnglish = m_workPath + "english.fnt";
strChinese = m_workPath + "Hz.fnt";
fileEnglish.setFileName(strEnglish);
if(!fileEnglish.open(QIODevice::ReadOnly))
{
qDebug() <<"file open failed";
return;
}
fileChinese.setFileName(strChinese);
if(!fileChinese.open(QIODevice::ReadOnly))
{
qDebug() <<"file open failed";
return;
}
nLeft=0;
nIndex1=0;
while (nIndex1 < nCount)
{
pbyData=NULL;
byByte1=(BYTE)lpszString[nIndex1];
if ((byByte1 >= 128) && ((nIndex1+1) < nCount))
{
bEnglishChar=false;
nIndex1++;
byByte2=(BYTE)lpszString[nIndex1];
wCharCode=(((WORD)byByte1) << 8) | (WORD)byByte2;
nIndex2=0;
nIndex3=m_nChinese_char_count - 1;
if (m_pChinese_char[nIndex2].m_wCharCode == wCharCode) nIndex4=nIndex2;
else if (m_pChinese_char[nIndex3].m_wCharCode == wCharCode) nIndex4=nIndex3;
else nIndex4=(nIndex2 + nIndex3) / 2;
while (((nIndex3 - nIndex2) > 1) &&
(m_pChinese_char[nIndex4].m_wCharCode != wCharCode))
{
if (m_pChinese_char[nIndex4].m_wCharCode > wCharCode)
{
nIndex3=nIndex4;
if (nIndex2 > nIndex3) break;
nIndex4=(nIndex2 + nIndex3) / 2;
}
else
{
nIndex2=nIndex4;
if (nIndex2 > nIndex3) break;
nIndex4=(nIndex2 + nIndex3) / 2;
}
}
if ((m_pChinese_char[nIndex4].m_wCharCode == wCharCode) &&
(m_pChinese_char[nIndex4].m_wBytes > 0))
{
pbyData=new BYTE[m_pChinese_char[nIndex4].m_wBytes + 1];
fileChinese.seek(m_pChinese_char[nIndex4].m_dwPosition);
fileChinese.read((char*)pbyData,m_pChinese_char[nIndex4].m_wBytes);
}
}
else
{
bEnglishChar=true;
wCharCode=(WORD)byByte1;
nIndex2=0;
nIndex3=m_nEnglish_char_count - 1;
if (m_pEnglish_char[nIndex2].m_wCharCode == wCharCode) nIndex4=nIndex2;
else if (m_pEnglish_char[nIndex3].m_wCharCode == wCharCode) nIndex4=nIndex3;
else nIndex4=(nIndex2 + nIndex3) / 2;
while (((nIndex3 - nIndex2) > 1) &&
(m_pEnglish_char[nIndex4].m_wCharCode != wCharCode))
{
if (m_pEnglish_char[nIndex4].m_wCharCode > wCharCode)
{
nIndex3=nIndex4;
if (nIndex2 > nIndex3) break;
nIndex4=(nIndex2 + nIndex3) / 2;
}
else
{
nIndex2=nIndex4;
if (nIndex2 > nIndex3) break;
nIndex4=(nIndex2 + nIndex3) / 2;
}
}
if ((m_pEnglish_char[nIndex4].m_wCharCode == wCharCode) &&
(m_pEnglish_char[nIndex4].m_wBytes > 0)) {
pbyData=new BYTE[m_pEnglish_char[nIndex4].m_wBytes + 1];
fileEnglish.seek(m_pEnglish_char[nIndex4].m_dwPosition);
fileEnglish.read((char*)pbyData,m_pEnglish_char[nIndex4].m_wBytes);
}
}
if (pbyData != NULL)
{
if (bEnglishChar)
{
PlotChar(QPoint(x,y),pbyData,m_pEnglish_char[nIndex4].m_wBytes,nLeft,0,m_nHeight_C);
}
else
{
PlotChar(QPoint(x,y),pbyData,m_pChinese_char[nIndex4].m_wBytes,nLeft,0,m_nInternalLeading_E + m_nHeight_E);
}
delete []pbyData;
if (bEnglishChar) nLeft=nLeft + m_pEnglish_char[nIndex4].m_wWidth * m_nHeight_C;
else nLeft=nLeft + m_nWidth_C * (m_nInternalLeading_E + m_nHeight_E);
}
else
{
if (bEnglishChar) nLeft=nLeft + m_pEnglish_char[0].m_wWidth * m_nHeight_C;
else nLeft=nLeft + m_nWidth_C * (m_nInternalLeading_E + m_nHeight_E);
}
nIndex1++;
}
fileEnglish.close();
fileChinese.close();
}
//画弧从Start逆时针画到End
void VectorFont::Arc(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,
int nXStartArc,int nYStartArc,int nXEndArc,int nYEndArc)
{
double dXC,dYC,dRadius;
double dx,dy;
double dAngleS,dAngleE,dAngle,dStep;
double dCos,dSin;
int nCount;
dXC=((double)nLeftRect + (double)nRightRect) / 2.0;
dYC=((double)nTopRect + (double)nBottomRect) / 2.0;
dRadius=((double)nRightRect - (double)nLeftRect) / 2.0;
dAngleS=angle_2(dXC,dYC,(double)nXStartArc,(double)nYStartArc);
dAngleE=angle_2(dXC,dYC,(double)nXEndArc,(double)nYEndArc);
while (dAngleE >= dAngleS) dAngleE=dAngleE - 2.0 * PI;
if ((nXStartArc == nXEndArc) && (nYStartArc == nYEndArc))
{
dAngleS=0.0;
dAngleE=-2.0 * PI;
}
dSin=qSin(dAngleS);
dCos=qCos(dAngleS);
dx=dRadius * dCos + dXC;
dy=dRadius * dSin + dYC;
MoveTo(dx+0.5,dy+0.5);
nCount=120;
dStep=PI / 180.0 * (360.0 / (double)nCount); //3度
dAngle=dAngleS;
while (dAngle > dAngleE)
{
dAngle=dAngle - dStep;
if (dAngle < dAngleE) dAngle=dAngleE;
dSin=qSin(dAngle);
dCos=qCos(dAngle);
dx=dRadius * dCos + dXC;
dy=dRadius * dSin + dYC;
LineTo(dx+0.5,dy+0.5);
}
}
QPoint VectorFont::GetNextCoodinate(WORD wDirection,WORD wLength,QPoint ptPoint)
{
QPoint ptPoint1;
switch (wDirection) {
case 0:
ptPoint1.setX( ptPoint.x() + (int)wLength);
ptPoint1.setY(ptPoint.y());
break;
case 1:
ptPoint1.setX(ptPoint.x() + (int)wLength);
ptPoint1.setY(ptPoint.y() + (int)wLength/2);
break;
case 2:
ptPoint1.setX(ptPoint.x() + (int)wLength);
ptPoint1.setY(ptPoint.y() + (int)wLength);
break;
case 3:
ptPoint1.setX(ptPoint.x() + (int)wLength/2);
ptPoint1.setY(ptPoint.y() + (int)wLength);
break;
case 4:
ptPoint1.setX(ptPoint.x());
ptPoint1.setY(ptPoint.y() + (int)wLength);
break;
case 5:
ptPoint1.setX(ptPoint.x() - (int)wLength/2);
ptPoint1.setY(ptPoint.y() + (int)wLength);
break;
case 6:
ptPoint1.setX(ptPoint.x() - (int)wLength);
ptPoint1.setY(ptPoint.y() + (int)wLength);
break;
case 7:
ptPoint1.setX(ptPoint.x() - (int)wLength);
ptPoint1.setY(ptPoint.y() + (int)wLength/2);
break;
case 8:
ptPoint1.setX(ptPoint.x() - (int)wLength);
ptPoint1.setY(ptPoint.y());
break;
case 9:
ptPoint1.setX(ptPoint.x() - (int)wLength);
ptPoint1.setY(ptPoint.y() - (int)wLength/2);
break;
case 10:
ptPoint1.setX(ptPoint.x() - (int)wLength);
ptPoint1.setY(ptPoint.y() - (int)wLength);
break;
case 11:
ptPoint1.setX(ptPoint.x() - (int)wLength/2);
ptPoint1.setY(ptPoint.y() - (int)wLength);
break;
case 12:
ptPoint1.setX(ptPoint.x());
ptPoint1.setY(ptPoint.y() - (int)wLength);
break;
case 13:
ptPoint1.setX(ptPoint.x() + (int)wLength/2);
ptPoint1.setY(ptPoint.y() - (int)wLength);
break;
case 14:
ptPoint1.setX(ptPoint.x() + (int)wLength);
ptPoint1.setY(ptPoint.y() - (int)wLength);
break;
case 15:
ptPoint1.setX(ptPoint.x() + (int)wLength);
ptPoint1.setY(ptPoint.y() - (int)wLength/2);
break;
}
return ptPoint1;
}
//求两点确定的直线与X轴的夹角,在[0,2pi)之间
//输入参数:
// (startx,starty) 起点
// (endx,endy) 终点
//返回值:
// 夹角
double VectorFont::angle_2(int startx,int starty,int endx,int endy)
{
//直线与X轴之间的夹角 X轴向量OE(1,0)
double dAngle = 0;
if((endx == startx) && (endy == starty))
{
return dAngle;
}
//求直线的向量坐标
double dX = endx - startx;
double dY = endy - starty;
dAngle = qAcos((dX)/(qSqrt(dX*dX + dY*dY)));
return dAngle;
}
///////////////////////// 计算三点定圆时的圆心和半径 ///////////////////////////
// 输入参数:三个样点(x1,y1),(x2,y2),(x3,y3)
// 算法描述:
// 过(x1,y1),(x2,y2)的中点作垂线L1,
// 过(x2,y2),(x3,y3)的中点作垂线L2,
// 求L1,L2的交点.
// 输出参数:
// 如果不能形成圆返回false,
// 否则返回true其中圆心为(cx,cy),半径=cr.
// 按逆时针方向画弧时,如cr>0 则(x1,y1)是起点,(x3,y3)是终点,
// 如cr<0 则(x3,y3)是起点,(x1,y1)是终点.
// 特别说明:此处所说的逆时针是指显示器而言,如果对于对X向右为正,
// Y向上为正的坐标系来说此处是顺时针
//bool CircleCR(int x1,int y1,int x2,int y2,int x3,int y3,int& cx,int& cy,int& cr);
////////////////////////////////////////////////////////////////////////////////
bool VectorFont::CircleCR(double x1,double y1,double x2,double y2,double x3,double y3,double& cx,double& cy,double& cr)
{
double a1,b1,c1,a2,b2,c2;
if(((x1 ==x2) && (y1==y2)) || ((x1 ==x3) && (y1==y3)) || ((x2 ==x3) && (y2==y3)))
{
return false;
}
a1 = x1 - x2;
b1 = y1 - y2;
c1 = -a1 * (x1 + x2) / 2.0 - b1 * (y1 + y2)/2.0;
a2 = x3 - x2;
b2 = y3 - y2;
c2 = -a2 * (x2 + x3) / 2.0 - b2 * (y2 + y3)/2.0;
double D = a1*b2 - a2*b1;
if(D == 0)//两直线平行
{
return false;
}
cx = (b1*c2 - b2*c1)/D;
cy = (c1*a2 - c2*a1)/D;
//用圆心和其中一个点求距离得到半径:
cr = qSqrt((cx - x1)*(cx - x1) + (cy - y1)*(cy - y1));
return true;
}

132
datafile/hpgl/vectorfont.h Normal file
View File

@ -0,0 +1,132 @@
#ifndef VECTORFONT_H
#define VECTORFONT_H
#include <QObject>
#include <QPoint>
#include "typedef.h"
class CChinese_char
{
public:
WORD m_wCharCode;
WORD m_wBytes;
DWORD m_dwPosition;
CChinese_char()
{
m_wCharCode=0;
m_wBytes=0;
m_dwPosition=0;
}
CChinese_char(const CChinese_char &a)
{
m_wCharCode=a.m_wCharCode;
m_wBytes=a.m_wBytes;
m_dwPosition=a.m_dwPosition;
}
CChinese_char(WORD wCharCode,WORD wBytes,DWORD dwPosition)
{
m_wCharCode=wCharCode;
m_wBytes=wBytes;
m_dwPosition=dwPosition;
}
~CChinese_char() {}
CChinese_char operator=(const CChinese_char &a)
{
m_wCharCode=a.m_wCharCode;
m_wBytes=a.m_wBytes;
m_dwPosition=a.m_dwPosition;
return *this;
}
};
class CEnglish_char
{
public:
WORD m_wCharCode;
WORD m_wBytes;
WORD m_wWidth;
DWORD m_dwPosition;
CEnglish_char()
{
m_wCharCode=0;
m_wBytes=0;
m_wWidth=0;
m_dwPosition=0;
}
CEnglish_char(const CEnglish_char &a)
{
m_wCharCode=a.m_wCharCode;
m_wBytes=a.m_wBytes;
m_wWidth=a.m_wWidth;
m_dwPosition=a.m_dwPosition;
}
CEnglish_char(WORD wCharCode,WORD wBytes,WORD wWidth,DWORD dwPosition)
{
m_wCharCode=wCharCode;
m_wBytes=wBytes;
m_wWidth=wWidth;
m_dwPosition=dwPosition;
}
~CEnglish_char() {}
CEnglish_char operator=(const CEnglish_char &a)
{
m_wCharCode=a.m_wCharCode;
m_wBytes=a.m_wBytes;
m_wWidth=a.m_wWidth;
m_dwPosition=a.m_dwPosition;
return *this;
}
};
class VectorFont : public QObject
{
Q_OBJECT
public:
explicit VectorFont(QObject *parent = 0);
~VectorFont();
void IniVectorFont();
signals:
void siLineTo(bool bl,QPoint point);
void siMoveTo(bool bl,QPoint point);
public slots:
protected:
double m_iDPMM; //长度数据单位:m_iDPMM(每毫米点)
double m_dRake; //倾斜角(第1个字符原点到最后1个字符原点的连线的角度),单位:弧度
QString m_workPath;
//QList <CChinese_char> m_aChinese_char;
//QList <CEnglish_char> m_aEnglish_char;
CChinese_char *m_pChinese_char;
CEnglish_char *m_pEnglish_char;
int m_nChinese_char_count;
int m_nEnglish_char_count;
int m_nInternalLeading_E,m_nHeight_E,m_nDescent_E; //m_nHeight_E是windows中字体的Ascent-InternalLeading
int m_nHeight_C,m_nWidth_C;
public:
void PlotChar(QPoint ptPointLU,BYTE*pbyData,WORD wBytes,int nLeft,int nDown,int nFontScale);
QPoint CPToLP(QPoint ptCP,int nHeight,QPoint ptPointLU,double dSin,double dCos,double dScale);
void TextOutString(int x, int y, const char* lpszString, int nCount);
void Arc(int nLeftRect,int nTopRect,int nRightRect,int nBottomRect,int nXStartArc,int nYStartArc,int nXEndArc,int nYEndArc);
QPoint GetNextCoodinate(WORD wDirection,WORD wLength,QPoint ptPoint);
void MoveTo(QPoint ptPoint);
void MoveTo(long x,long y);
void LineTo(QPoint ptPoint);
void LineTo(long x,long y);
double angle_2(int startx,int starty,int endx,int endy);
bool CircleCR(double x1,double y1,double x2,double y2,double x3,double y3,double& cx,double& cy,double& cr);
double m_dFontHeight; //字的高度
double m_dFontAngle;//指定每行文本输出时相对于设备x轴的角度其单位为1/10度
};
#endif // VECTORFONT_H

4501
datafile/hpgl/vectorsqrt.cpp Normal file

File diff suppressed because it is too large Load Diff

135
datafile/hpgl/vectorsqrt.h Normal file
View File

@ -0,0 +1,135 @@
#ifndef VECTORSQRT_H
#define VECTORSQRT_H
#include <QObject>
#include <QFile>
#include "config/config.h"
#include "comm/datadef.h"
class VSqrtItem : public QObject
{
Q_OBJECT
public:
explicit VSqrtItem(QObject *parent = NULL);
VSqrtItem(const VSqrtItem & item);
public:
VSqrtItem& operator=(const VSqrtItem & item);
private:
void CopyData(const VSqrtItem & item);
public:
void InitVSItem();
public:
int m_sqrttype; // 图形类型, 1, 直线, 2, 圆弧; 3, 三次贝塞尔
double m_begx;
double m_begy; // 起点
double m_midx;
double m_midy; // 中间点1
double m_midx2;
double m_midy2; // 中间点2
double m_endx;
double m_endy; // 终点
public:
u32 m_code; // 数据类型
public:
int m_ownsteplock; // 专有步长和回针标志, != 0, 使用一下的步长和锁针参数. 否则,使用公共的参数
u32 m_stepSize; // 步长
u32 m_blockNum; // 起始锁针针数
u32 m_blockTimes; // 起始锁针次数
u32 m_blockjumps; // 起始跳过针数
u32 m_elockNum; // 结束锁针针数
u32 m_elockTimes; // 结束锁针次数
u32 m_elockjumps; // 结束跳过针数
};
class VectorSqrt : public QObject
{
Q_OBJECT
public:
DataFileHead m_fileHead; // 数据文件头描述
explicit VectorSqrt(QObject *parent = NULL);
~VectorSqrt();
VectorSqrt(const VectorSqrt & item);
public:
VectorSqrt& operator=(const VectorSqrt & item);
private:
void CopyData(const VectorSqrt & item);
public:
void InitVSqrt(QString name = QString());
public:
QString m_filename; // 名称
int m_anchorSel; // 定位点选择; 0, 和起点重合; 1图形的左下角; 2, 图形的右下角; 3, 图形的右上角; 4, 图形的左上角; 5, 图形的中心
public:
QList<VSqrtItem> m_vSqitItemList; // 图形列表
public:
// 针步和回针参数
u32 m_para_stepSize ; // 步长
u32 m_para_blockNum ; // 起始锁针针数
u32 m_para_blockTimes ; // 起始锁针次数
u32 m_para_blockjumps ; // 起始跳过针数
u32 m_para_elockNum ; // 结束锁针针数
u32 m_para_elockTimes ; // 结束锁针次数
u32 m_para_elockjumps ; // 结束跳过针数
public:
//这个过程应该放在不同的文件实现中而不是放在 VectorSqrt 这里生成数据中应该分离开
int CreateDs16FromSqrt(QByteArray & ds16Ary);
int CreateDs8FromDs16(const QByteArray & ds16Ary, QByteArray & ds8Ary);
int CreateDs4FromSqrt(QByteArray & ds4Ary);
int CreateDs2FromDs4(const QByteArray & ds4Ary, QByteArray & ds2Ary);
public:
void SetAnchor(int nX,int nY);
void SetBegin(int nX,int nY);
private:
int m_anchorX;//定位点X
int m_anchorY;//定位点Y
int m_beginX;//数据起点坐标X
int m_beginY;//数据起点坐标Y
signals:
public slots:
};
int GetDataMinMax(DataItem * pData, int nums, s32 & minx, s32 & miny, s32 & maxx, s32 & maxy);
// 图形算法
// 直线
int CalcLine(double x0, double y0, double x1, double y1, int * pactx, int * pacty, int stepSize, DataItem * pData, u8 type, s16 dr);
// 三点圆弧
int CalcCurve(double threex[], double threey[], int * pactx, int * pacty, int * pActAng, int stepSize, DataItem * pData, u8 type);
void Rotatec(double xin, double yin, double * px, double * py, double angle);
int ArcDir(const double x[], const double y[]);
int IsThreePointOnALine(const double threex[], const double threey[]);
int GetArcCenter(const double x[], const double y[], double * pxc, double * pyc, double * pr);
int GetArcRectAndAngle(const double x[], const double y[], double * minx, double * maxx, double * miny, double * maxy, double * startangle, double * endangle);
int GetArcMinMax(const double x[], const double y[], double * pminx, double * pmaxx, double * pminy, double * pmaxy);
s16 GetAngle(const double bx, const double by, const double ex, const double ey, int * pActAng);
// 三次贝塞尔
int GetBezierMinMax(const double x[], const double y[], double * pminx, double * pmaxx, double * pminy, double * pmaxy);
#endif // VECTORSQRT_H

View File

@ -0,0 +1,231 @@
/*
* qrencode - QR Code encoder
*
* Binary sequence class.
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bitstream.h"
#define DEFAULT_BUFSIZE (128)
BitStream *BitStream_new(void)
{
BitStream *bstream;
bstream = (BitStream *)malloc(sizeof(BitStream));
if(bstream == NULL) return NULL;
bstream->length = 0;
bstream->data = (unsigned char *)malloc(DEFAULT_BUFSIZE);
if(bstream->data == NULL) {
free(bstream);
return NULL;
}
bstream->datasize = DEFAULT_BUFSIZE;
return bstream;
}
#ifdef WITH_TESTS
BitStream *BitStream_newWithBits(size_t size, unsigned char *bits)
{
BitStream *bstream;
if(size == 0) return BitStream_new();
bstream = (BitStream *)malloc(sizeof(BitStream));
if(bstream == NULL) return NULL;
bstream->data = (unsigned char *)malloc(size);
if(bstream->data == NULL) {
free(bstream);
return NULL;
}
bstream->length = size;
bstream->datasize = size;
memcpy(bstream->data, bits, size);
return bstream;
}
#endif
static int BitStream_expand(BitStream *bstream)
{
unsigned char *data;
data = (unsigned char *)realloc(bstream->data, bstream->datasize * 2);
if(data == NULL) {
return -1;
}
bstream->data = data;
bstream->datasize *= 2;
return 0;
}
static void BitStream_writeNum(unsigned char *dest, size_t bits, unsigned int num)
{
unsigned int mask;
size_t i;
unsigned char *p;
p = dest;
mask = 1U << (bits - 1);
for(i = 0; i < bits; i++) {
if(num & mask) {
*p = 1;
} else {
*p = 0;
}
p++;
mask = mask >> 1;
}
}
static void BitStream_writeBytes(unsigned char *dest, size_t size, unsigned char *data)
{
unsigned char mask;
size_t i, j;
unsigned char *p;
p = dest;
for(i = 0; i < size; i++) {
mask = 0x80;
for(j = 0; j < 8; j++) {
if(data[i] & mask) {
*p = 1;
} else {
*p = 0;
}
p++;
mask = mask >> 1;
}
}
}
int BitStream_append(BitStream *bstream, BitStream *arg)
{
int ret;
if(arg == NULL) {
return -1;
}
if(arg->length == 0) {
return 0;
}
while(bstream->length + arg->length > bstream->datasize) {
ret = BitStream_expand(bstream);
if(ret < 0) return ret;
}
memcpy(bstream->data + bstream->length, arg->data, arg->length);
bstream->length += arg->length;
return 0;
}
int BitStream_appendNum(BitStream *bstream, size_t bits, unsigned int num)
{
int ret;
if(bits == 0) return 0;
while(bstream->datasize - bstream->length < bits) {
ret = BitStream_expand(bstream);
if(ret < 0) return ret;
}
BitStream_writeNum(bstream->data + bstream->length, bits, num);
bstream->length += bits;
return 0;
}
int BitStream_appendBytes(BitStream *bstream, size_t size, unsigned char *data)
{
int ret;
if(size == 0) return 0;
while(bstream->datasize - bstream->length < size * 8) {
ret = BitStream_expand(bstream);
if(ret < 0) return ret;
}
BitStream_writeBytes(bstream->data + bstream->length, size, data);
bstream->length += size * 8;
return 0;
}
unsigned char *BitStream_toByte(BitStream *bstream)
{
size_t i, j, size, bytes, oddbits;
unsigned char *data, v;
unsigned char *p;
size = BitStream_size(bstream);
if(size == 0) {
return NULL;
}
data = (unsigned char *)malloc((size + 7) / 8);
if(data == NULL) {
return NULL;
}
bytes = size / 8;
p = bstream->data;
for(i = 0; i < bytes; i++) {
v = 0;
for(j = 0; j < 8; j++) {
v = (unsigned char)(v << 1);
v |= *p;
p++;
}
data[i] = v;
}
oddbits = size & 7;
if(oddbits > 0) {
v = 0;
for(j = 0; j < oddbits; j++) {
v = (unsigned char)(v << 1);
v |= *p;
p++;
}
data[bytes] = (unsigned char)(v << (8 - oddbits));
}
return data;
}
void BitStream_free(BitStream *bstream)
{
if(bstream != NULL) {
free(bstream->data);
free(bstream);
}
}

View File

@ -0,0 +1,43 @@
/*
* qrencode - QR Code encoder
*
* Binary sequence class.
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef BITSTREAM_H
#define BITSTREAM_H
typedef struct {
size_t length;
size_t datasize;
unsigned char *data;
} BitStream;
extern BitStream *BitStream_new(void);
#ifdef WITH_TESTS
extern BitStream *BitStream_newWithBits(size_t size, unsigned char *bits);
#endif
extern int BitStream_append(BitStream *bstream, BitStream *arg);
extern int BitStream_appendNum(BitStream *bstream, size_t bits, unsigned int num);
extern int BitStream_appendBytes(BitStream *bstream, size_t size, unsigned char *data);
#define BitStream_size(__bstream__) (__bstream__->length)
#define BitStream_reset(__bstream__) (__bstream__->length = 0)
extern unsigned char *BitStream_toByte(BitStream *bstream);
extern void BitStream_free(BitStream *bstream);
#endif /* BITSTREAM_H */

102
datafile/qrencode/config.h Normal file
View File

@ -0,0 +1,102 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define if you have the iconv() function and it works. */
#undef HAVE_ICONV
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if using pthread is enabled. */
#undef HAVE_LIBPTHREAD
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if using libpng is enabled. */
#undef HAVE_PNG
/* Define to 1 if using SDL is enabled. */
#undef HAVE_SDL
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#undef LT_OBJDIR
/* Major version number */
#undef MAJOR_VERSION
#define MAJOR_VERSION 1
/* Micro version number */
#undef MICRO_VERSION
#define MICRO_VERSION 1
/* Minor version number */
#undef MINOR_VERSION
#define MINOR_VERSION 1
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
#define VERSION (char*)1
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to 'static' if no test programs will be compiled. */
#define STATIC_IN_RELEASE static
#undef WITH_TESTS

357
datafile/qrencode/mask.c Normal file
View File

@ -0,0 +1,357 @@
/*
* qrencode - QR Code encoder
*
* Masking.
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include "qrencode.h"
#include "qrspec.h"
#include "mask.h"
STATIC_IN_RELEASE int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level)
{
unsigned int format;
unsigned char v;
int i;
int blacks = 0;
format = QRspec_getFormatInfo(mask, level);
for(i = 0; i < 8; i++) {
if(format & 1) {
blacks += 2;
v = 0x85;
} else {
v = 0x84;
}
frame[width * 8 + width - 1 - i] = v;
if(i < 6) {
frame[width * i + 8] = v;
} else {
frame[width * (i + 1) + 8] = v;
}
format= format >> 1;
}
for(i = 0; i < 7; i++) {
if(format & 1) {
blacks += 2;
v = 0x85;
} else {
v = 0x84;
}
frame[width * (width - 7 + i) + 8] = v;
if(i == 0) {
frame[width * 8 + 7] = v;
} else {
frame[width * 8 + 6 - i] = v;
}
format= format >> 1;
}
return blacks;
}
/**
* Demerit coefficients.
* See Section 8.8.2, pp.45, JIS X0510:2004.
*/
#define N1 (3)
#define N2 (3)
#define N3 (40)
#define N4 (10)
#define MASKMAKER(__exp__) \
int x, y;\
int b = 0;\
\
for(y = 0; y < width; y++) {\
for(x = 0; x < width; x++) {\
if(*s & 0x80) {\
*d = *s;\
} else {\
*d = *s ^ ((__exp__) == 0);\
}\
b += (int)(*d & 1);\
s++; d++;\
}\
}\
return b;
static int Mask_mask0(int width, const unsigned char *s, unsigned char *d)
{
MASKMAKER((x+y)&1)
}
static int Mask_mask1(int width, const unsigned char *s, unsigned char *d)
{
MASKMAKER(y&1)
}
static int Mask_mask2(int width, const unsigned char *s, unsigned char *d)
{
MASKMAKER(x%3)
}
static int Mask_mask3(int width, const unsigned char *s, unsigned char *d)
{
MASKMAKER((x+y)%3)
}
static int Mask_mask4(int width, const unsigned char *s, unsigned char *d)
{
MASKMAKER(((y/2)+(x/3))&1)
}
static int Mask_mask5(int width, const unsigned char *s, unsigned char *d)
{
MASKMAKER(((x*y)&1)+(x*y)%3)
}
static int Mask_mask6(int width, const unsigned char *s, unsigned char *d)
{
MASKMAKER((((x*y)&1)+(x*y)%3)&1)
}
static int Mask_mask7(int width, const unsigned char *s, unsigned char *d)
{
MASKMAKER((((x*y)%3)+((x+y)&1))&1)
}
#define maskNum (8)
typedef int MaskMaker(int, const unsigned char *, unsigned char *);
static MaskMaker *maskMakers[maskNum] = {
Mask_mask0, Mask_mask1, Mask_mask2, Mask_mask3,
Mask_mask4, Mask_mask5, Mask_mask6, Mask_mask7
};
#ifdef WITH_TESTS
unsigned char *Mask_makeMaskedFrame(int width, unsigned char *frame, int mask)
{
unsigned char *masked;
masked = (unsigned char *)malloc((size_t)(width * width));
if(masked == NULL) return NULL;
maskMakers[mask](width, frame, masked);
return masked;
}
#endif
unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level)
{
unsigned char *masked;
if(mask < 0 || mask >= maskNum) {
errno = EINVAL;
return NULL;
}
masked = (unsigned char *)malloc((size_t)(width * width));
if(masked == NULL) return NULL;
maskMakers[mask](width, frame, masked);
Mask_writeFormatInformation(width, masked, mask, level);
return masked;
}
//static int n1;
//static int n2;
//static int n3;
//static int n4;
STATIC_IN_RELEASE int Mask_calcN1N3(int length, int *runLength)
{
int i;
int demerit = 0;
int fact;
for(i = 0; i < length; i++) {
if(runLength[i] >= 5) {
demerit += N1 + (runLength[i] - 5);
//n1 += N1 + (runLength[i] - 5);
}
if((i & 1)) {
if(i >= 3 && i < length-2 && (runLength[i] % 3) == 0) {
fact = runLength[i] / 3;
if(runLength[i-2] == fact &&
runLength[i-1] == fact &&
runLength[i+1] == fact &&
runLength[i+2] == fact) {
if(i == 3 || runLength[i-3] >= 4 * fact) {
demerit += N3;
//n3 += N3;
} else if(i+4 >= length || runLength[i+3] >= 4 * fact) {
demerit += N3;
//n3 += N3;
}
}
}
}
}
return demerit;
}
STATIC_IN_RELEASE int Mask_calcN2(int width, unsigned char *frame)
{
int x, y;
unsigned char *p;
unsigned char b22, w22;
int demerit = 0;
p = frame + width + 1;
for(y = 1; y < width; y++) {
for(x = 1; x < width; x++) {
b22 = p[0] & p[-1] & p[-width] & p [-width-1];
w22 = p[0] | p[-1] | p[-width] | p [-width-1];
if((b22 | (w22 ^ 1))&1) {
demerit += N2;
}
p++;
}
p++;
}
return demerit;
}
STATIC_IN_RELEASE int Mask_calcRunLengthH(int width, unsigned char *frame, int *runLength)
{
int head;
int i;
unsigned char prev;
if(frame[0] & 1) {
runLength[0] = -1;
head = 1;
} else {
head = 0;
}
runLength[head] = 1;
prev = frame[0];
for(i = 1; i < width; i++) {
if((frame[i] ^ prev) & 1) {
head++;
runLength[head] = 1;
prev = frame[i];
} else {
runLength[head]++;
}
}
return head + 1;
}
STATIC_IN_RELEASE int Mask_calcRunLengthV(int width, unsigned char *frame, int *runLength)
{
int head;
int i;
unsigned char prev;
if(frame[0] & 1) {
runLength[0] = -1;
head = 1;
} else {
head = 0;
}
runLength[head] = 1;
prev = frame[0];
for(i = 1; i < width; i++) {
if((frame[i * width] ^ prev) & 1) {
head++;
runLength[head] = 1;
prev = frame[i * width];
} else {
runLength[head]++;
}
}
return head + 1;
}
STATIC_IN_RELEASE int Mask_evaluateSymbol(int width, unsigned char *frame)
{
int x, y;
int demerit = 0;
int runLength[QRSPEC_WIDTH_MAX + 1];
int length;
demerit += Mask_calcN2(width, frame);
for(y = 0; y < width; y++) {
length = Mask_calcRunLengthH(width, frame + y * width, runLength);
demerit += Mask_calcN1N3(length, runLength);
}
for(x = 0; x < width; x++) {
length = Mask_calcRunLengthV(width, frame + x, runLength);
demerit += Mask_calcN1N3(length, runLength);
}
return demerit;
}
unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level)
{
int i;
unsigned char *mask, *bestMask;
int minDemerit = INT_MAX;
int blacks;
int bratio;
int demerit;
int w2 = width * width;
mask = (unsigned char *)malloc((size_t)w2);
if(mask == NULL) return NULL;
bestMask = (unsigned char *)malloc((size_t)w2);
if(bestMask == NULL) {
free(mask);
return NULL;
}
for(i = 0; i < maskNum; i++) {
// n1 = n2 = n3 = n4 = 0;
demerit = 0;
blacks = maskMakers[i](width, frame, mask);
blacks += Mask_writeFormatInformation(width, mask, i, level);
bratio = (200 * blacks + w2) / w2 / 2; /* (int)(100*blacks/w2+0.5) */
demerit = (abs(bratio - 50) / 5) * N4;
// n4 = demerit;
demerit += Mask_evaluateSymbol(width, mask);
// printf("(%d,%d,%d,%d)=%d\n", n1, n2, n3 ,n4, demerit);
if(demerit < minDemerit) {
minDemerit = demerit;
memcpy(bestMask, mask, (size_t)w2);
}
}
free(mask);
return bestMask;
}

38
datafile/qrencode/mask.h Normal file
View File

@ -0,0 +1,38 @@
/*
* qrencode - QR Code encoder
*
* Masking.
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MASK_H
#define MASK_H
extern unsigned char *Mask_makeMask(int width, unsigned char *frame, int mask, QRecLevel level);
extern unsigned char *Mask_mask(int width, unsigned char *frame, QRecLevel level);
#ifdef WITH_TESTS
extern int Mask_calcN2(int width, unsigned char *frame);
extern int Mask_calcN1N3(int length, int *runLength);
extern int Mask_calcRunLengthH(int width, unsigned char *frame, int *runLength);
extern int Mask_calcRunLengthV(int width, unsigned char *frame, int *runLength);
extern int Mask_evaluateSymbol(int width, unsigned char *frame);
extern int Mask_writeFormatInformation(int width, unsigned char *frame, int mask, QRecLevel level);
extern unsigned char *Mask_makeMaskedFrame(int width, unsigned char *frame, int mask);
#endif
#endif /* MASK_H */

177
datafile/qrencode/mmask.c Normal file
View File

@ -0,0 +1,177 @@
/*
* qrencode - QR Code encoder
*
* Masking for Micro QR Code.
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include "qrencode.h"
#include "mqrspec.h"
#include "mmask.h"
STATIC_IN_RELEASE void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level)
{
unsigned int format;
unsigned char v;
int i;
format = MQRspec_getFormatInfo(mask, version, level);
for(i = 0; i < 8; i++) {
v = 0x84 | (format & 1);
frame[width * (i + 1) + 8] = v;
format = format >> 1;
}
for(i = 0; i < 7; i++) {
v = 0x84 | (format & 1);
frame[width * 8 + 7 - i] = v;
format = format >> 1;
}
}
#define MASKMAKER(__exp__) \
int x, y;\
\
for(y = 0; y < width; y++) {\
for(x = 0; x < width; x++) {\
if(*s & 0x80) {\
*d = *s;\
} else {\
*d = *s ^ ((__exp__) == 0);\
}\
s++; d++;\
}\
}
static void Mask_mask0(int width, const unsigned char *s, unsigned char *d)
{
MASKMAKER(y&1)
}
static void Mask_mask1(int width, const unsigned char *s, unsigned char *d)
{
MASKMAKER(((y/2)+(x/3))&1)
}
static void Mask_mask2(int width, const unsigned char *s, unsigned char *d)
{
MASKMAKER((((x*y)&1)+(x*y)%3)&1)
}
static void Mask_mask3(int width, const unsigned char *s, unsigned char *d)
{
MASKMAKER((((x+y)&1)+((x*y)%3))&1)
}
#define maskNum (4)
typedef void MaskMaker(int, const unsigned char *, unsigned char *);
static MaskMaker *maskMakers[maskNum] = {
Mask_mask0, Mask_mask1, Mask_mask2, Mask_mask3
};
#ifdef WITH_TESTS
unsigned char *MMask_makeMaskedFrame(int width, unsigned char *frame, int mask)
{
unsigned char *masked;
masked = (unsigned char *)malloc((size_t)(width * width));
if(masked == NULL) return NULL;
maskMakers[mask](width, frame, masked);
return masked;
}
#endif
unsigned char *MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level)
{
unsigned char *masked;
int width;
if(mask < 0 || mask >= maskNum) {
errno = EINVAL;
return NULL;
}
width = MQRspec_getWidth(version);
masked = (unsigned char *)malloc((size_t)(width * width));
if(masked == NULL) return NULL;
maskMakers[mask](width, frame, masked);
MMask_writeFormatInformation(version, width, masked, mask, level);
return masked;
}
STATIC_IN_RELEASE int MMask_evaluateSymbol(int width, unsigned char *frame)
{
int x, y;
unsigned char *p;
int sum1 = 0, sum2 = 0;
p = frame + width * (width - 1);
for(x = 1; x < width; x++) {
sum1 += (p[x] & 1);
}
p = frame + width * 2 - 1;
for(y = 1; y < width; y++) {
sum2 += (*p & 1);
p += width;
}
return (sum1 <= sum2)?(sum1 * 16 + sum2):(sum2 * 16 + sum1);
}
unsigned char *MMask_mask(int version, unsigned char *frame, QRecLevel level)
{
int i;
unsigned char *mask, *bestMask;
int maxScore = 0;
int score;
int width;
width = MQRspec_getWidth(version);
mask = (unsigned char *)malloc((size_t)(width * width));
if(mask == NULL) return NULL;
bestMask = NULL;
for(i = 0; i < maskNum; i++) {
score = 0;
maskMakers[i](width, frame, mask);
MMask_writeFormatInformation(version, width, mask, i, level);
score = MMask_evaluateSymbol(width, mask);
if(score > maxScore) {
maxScore = score;
free(bestMask);
bestMask = mask;
mask = (unsigned char *)malloc((size_t)(width * width));
if(mask == NULL) break;
}
}
free(mask);
return bestMask;
}

34
datafile/qrencode/mmask.h Normal file
View File

@ -0,0 +1,34 @@
/*
* qrencode - QR Code encoder
*
* Masking for Micro QR Code.
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MMASK_H
#define MMASK_H
extern unsigned char *MMask_makeMask(int version, unsigned char *frame, int mask, QRecLevel level);
extern unsigned char *MMask_mask(int version, unsigned char *frame, QRecLevel level);
#ifdef WITH_TESTS
extern int MMask_evaluateSymbol(int width, unsigned char *frame);
extern void MMask_writeFormatInformation(int version, int width, unsigned char *frame, int mask, QRecLevel level);
extern unsigned char *MMask_makeMaskedFrame(int width, unsigned char *frame, int mask);
#endif
#endif /* MMASK_H */

232
datafile/qrencode/mqrspec.c Normal file
View File

@ -0,0 +1,232 @@
/*
* qrencode - QR Code encoder
*
* Micro QR Code specification in convenient format.
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* The following data / specifications are taken from
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
* or
* "Automatic identification and data capture techniques --
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "mqrspec.h"
/******************************************************************************
* Version and capacity
*****************************************************************************/
typedef struct {
int width; ///< Edge length of the symbol
int ec[4]; ///< Number of ECC code (bytes)
} MQRspec_Capacity;
/**
* Table of the capacity of symbols
* See Table 1 (pp.106) and Table 8 (pp.113) of Appendix 1, JIS X0510:2004.
*/
static const MQRspec_Capacity mqrspecCapacity[MQRSPEC_VERSION_MAX + 1] = {
{ 0, {0, 0, 0, 0}},
{ 11, {2, 0, 0, 0}},
{ 13, {5, 6, 0, 0}},
{ 15, {6, 8, 0, 0}},
{ 17, {8, 10, 14, 0}}
};
int MQRspec_getDataLengthBit(int version, QRecLevel level)
{
int w;
int ecc;
w = mqrspecCapacity[version].width - 1;
ecc = mqrspecCapacity[version].ec[level];
if(ecc == 0) return 0;
return w * w - 64 - ecc * 8;
}
int MQRspec_getDataLength(int version, QRecLevel level)
{
return (MQRspec_getDataLengthBit(version, level) + 4) / 8;
}
int MQRspec_getECCLength(int version, QRecLevel level)
{
return mqrspecCapacity[version].ec[level];
}
int MQRspec_getWidth(int version)
{
return mqrspecCapacity[version].width;
}
/******************************************************************************
* Length indicator
*****************************************************************************/
/**
* See Table 3 (pp.107) of Appendix 1, JIS X0510:2004.
*/
static const int lengthTableBits[4][4] = {
{ 3, 4, 5, 6},
{ 0, 3, 4, 5},
{ 0, 0, 4, 5},
{ 0, 0, 3, 4}
};
int MQRspec_lengthIndicator(QRencodeMode mode, int version)
{
return lengthTableBits[mode][version - 1];
}
int MQRspec_maximumWords(QRencodeMode mode, int version)
{
int bits;
int words;
bits = lengthTableBits[mode][version - 1];
words = (1 << bits) - 1;
if(mode == QR_MODE_KANJI) {
words *= 2; // the number of bytes is required
}
return words;
}
/******************************************************************************
* Format information
*****************************************************************************/
/* See calcFormatInfo in tests/test_mqrspec.c */
static const unsigned int formatInfo[4][8] = {
{0x4445, 0x55ae, 0x6793, 0x7678, 0x06de, 0x1735, 0x2508, 0x34e3},
{0x4172, 0x5099, 0x62a4, 0x734f, 0x03e9, 0x1202, 0x203f, 0x31d4},
{0x4e2b, 0x5fc0, 0x6dfd, 0x7c16, 0x0cb0, 0x1d5b, 0x2f66, 0x3e8d},
{0x4b1c, 0x5af7, 0x68ca, 0x7921, 0x0987, 0x186c, 0x2a51, 0x3bba}
};
/* See Table 10 of Appendix 1. (pp.115) */
static const int typeTable[MQRSPEC_VERSION_MAX + 1][3] = {
{-1, -1, -1},
{ 0, -1, -1},
{ 1, 2, -1},
{ 3, 4, -1},
{ 5, 6, 7}
};
unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level)
{
int type;
if(mask < 0 || mask > 3) return 0;
if(version <= 0 || version > MQRSPEC_VERSION_MAX) return 0;
if(level == QR_ECLEVEL_H) return 0;
type = typeTable[version][level];
if(type < 0) return 0;
return formatInfo[mask][type];
}
/******************************************************************************
* Frame
*****************************************************************************/
/**
* Put a finder pattern.
* @param frame
* @param width
* @param ox,oy upper-left coordinate of the pattern
*/
static void putFinderPattern(unsigned char *frame, int width, int ox, int oy)
{
static const unsigned char finder[] = {
0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
};
int x, y;
const unsigned char *s;
frame += oy * width + ox;
s = finder;
for(y = 0; y < 7; y++) {
for(x = 0; x < 7; x++) {
frame[x] = s[x];
}
frame += width;
s += 7;
}
}
static unsigned char *MQRspec_createFrame(int version)
{
unsigned char *frame, *p, *q;
int width;
int x, y;
width = mqrspecCapacity[version].width;
frame = (unsigned char *)malloc((size_t)(width * width));
if(frame == NULL) return NULL;
memset(frame, 0, (size_t)(width * width));
/* Finder pattern */
putFinderPattern(frame, width, 0, 0);
/* Separator */
p = frame;
for(y = 0; y < 7; y++) {
p[7] = 0xc0;
p += width;
}
memset(frame + width * 7, 0xc0, 8);
/* Mask format information area */
memset(frame + width * 8 + 1, 0x84, 8);
p = frame + width + 8;
for(y = 0; y < 7; y++) {
*p = 0x84;
p += width;
}
/* Timing pattern */
p = frame + 8;
q = frame + width * 8;
for(x = 1; x < width-7; x++) {
*p = 0x90 | (x & 1);
*q = 0x90 | (x & 1);
p++;
q += width;
}
return frame;
}
unsigned char *MQRspec_newFrame(int version)
{
if(version < 1 || version > MQRSPEC_VERSION_MAX) return NULL;
return MQRspec_createFrame(version);
}

150
datafile/qrencode/mqrspec.h Normal file
View File

@ -0,0 +1,150 @@
/*
* qrencode - QR Code encoder
*
* Micro QR Code specification in convenient format.
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MQRSPEC_H
#define MQRSPEC_H
#include "qrencode.h"
/******************************************************************************
* Version and capacity
*****************************************************************************/
/**
* Maximum width of a symbol
*/
#define MQRSPEC_WIDTH_MAX 17
/**
* Return maximum data code length (bits) for the version.
* @param version version of the symbol
* @param level error correction level
* @return maximum size (bits)
*/
extern int MQRspec_getDataLengthBit(int version, QRecLevel level);
/**
* Return maximum data code length (bytes) for the version.
* @param version version of the symbol
* @param level error correction level
* @return maximum size (bytes)
*/
extern int MQRspec_getDataLength(int version, QRecLevel level);
/**
* Return maximum error correction code length (bytes) for the version.
* @param version version of the symbol
* @param level error correction level
* @return ECC size (bytes)
*/
extern int MQRspec_getECCLength(int version, QRecLevel level);
/**
* Return a version number that satisfies the input code length.
* @param size input code length (byte)
* @param level error correction level
* @return version number
*/
extern int MQRspec_getMinimumVersion(int size, QRecLevel level);
/**
* Return the width of the symbol for the version.
* @param version version of the symbol
* @return width
*/
extern int MQRspec_getWidth(int version);
/**
* Return the numer of remainder bits.
* @param version version of the symbol
* @return number of remainder bits
*/
extern int MQRspec_getRemainder(int version);
/******************************************************************************
* Length indicator
*****************************************************************************/
/**
* Return the size of length indicator for the mode and version.
* @param mode encode mode
* @param version vesion of the symbol
* @return the size of the appropriate length indicator (bits).
*/
extern int MQRspec_lengthIndicator(QRencodeMode mode, int version);
/**
* Return the maximum length for the mode and version.
* @param mode encode mode
* @param version vesion of the symbol
* @return the maximum length (bytes)
*/
extern int MQRspec_maximumWords(QRencodeMode mode, int version);
/******************************************************************************
* Version information pattern
*****************************************************************************/
/**
* Return BCH encoded version information pattern that is used for the symbol
* of version 7 or greater. Use lower 18 bits.
* @param version vesion of the symbol
* @return BCH encoded version information pattern
*/
extern unsigned int MQRspec_getVersionPattern(int version);
/******************************************************************************
* Format information
*****************************************************************************/
/**
* Return BCH encoded format information pattern.
* @param mask mask number
* @param version version of the symbol
* @param level error correction level
* @return BCH encoded format information pattern
*/
extern unsigned int MQRspec_getFormatInfo(int mask, int version, QRecLevel level);
/******************************************************************************
* Frame
*****************************************************************************/
/**
* Return a copy of initialized frame.
* @param version version of the symbol
* @return Array of unsigned char. You can free it by free().
*/
extern unsigned char *MQRspec_newFrame(int version);
/******************************************************************************
* Mode indicator
*****************************************************************************/
/**
* Mode indicator. See Table 2 in Appendix 1 of JIS X0510:2004, pp.107.
*/
#define MQRSPEC_MODEID_NUM 0
#define MQRSPEC_MODEID_AN 1
#define MQRSPEC_MODEID_8 2
#define MQRSPEC_MODEID_KANJI 3
#endif /* MQRSPEC_H */

1453
datafile/qrencode/qrenc.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,938 @@
/*
* qrencode - QR Code encoder
*
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "qrencode.h"
#include "qrspec.h"
#include "mqrspec.h"
#include "bitstream.h"
#include "qrinput.h"
#include "rsecc.h"
#include "split.h"
#include "mask.h"
#include "mmask.h"
/******************************************************************************
* Raw code
*****************************************************************************/
typedef struct {
int dataLength;
int eccLength;
unsigned char *data;
unsigned char *ecc;
} RSblock;
typedef struct {
int version;
int dataLength;
int eccLength;
unsigned char *datacode;
unsigned char *ecccode;
int b1;
int blocks;
RSblock *rsblock;
int count;
} QRRawCode;
static void RSblock_initBlock(RSblock *block, int dl, unsigned char *data, int el, unsigned char *ecc)
{
block->dataLength = dl;
block->data = data;
block->eccLength = el;
block->ecc = ecc;
RSECC_encode((size_t)dl, (size_t)el, data, ecc);
}
static int RSblock_init(RSblock *blocks, int spec[5], unsigned char *data, unsigned char *ecc)
{
int i;
RSblock *block;
unsigned char *dp, *ep;
int el, dl;
dl = QRspec_rsDataCodes1(spec);
el = QRspec_rsEccCodes1(spec);
block = blocks;
dp = data;
ep = ecc;
for(i = 0; i < QRspec_rsBlockNum1(spec); i++) {
RSblock_initBlock(block, dl, dp, el, ep);
dp += dl;
ep += el;
block++;
}
if(QRspec_rsBlockNum2(spec) == 0) return 0;
dl = QRspec_rsDataCodes2(spec);
el = QRspec_rsEccCodes2(spec);
for(i = 0; i < QRspec_rsBlockNum2(spec); i++) {
RSblock_initBlock(block, dl, dp, el, ep);
dp += dl;
ep += el;
block++;
}
return 0;
}
STATIC_IN_RELEASE void QRraw_free(QRRawCode *raw);
STATIC_IN_RELEASE QRRawCode *QRraw_new(QRinput *input)
{
QRRawCode *raw;
int spec[5], ret;
raw = (QRRawCode *)malloc(sizeof(QRRawCode));
if(raw == NULL) return NULL;
raw->datacode = QRinput_getByteStream(input);
if(raw->datacode == NULL) {
free(raw);
return NULL;
}
QRspec_getEccSpec(input->version, input->level, spec);
raw->version = input->version;
raw->b1 = QRspec_rsBlockNum1(spec);
raw->dataLength = QRspec_rsDataLength(spec);
raw->eccLength = QRspec_rsEccLength(spec);
raw->ecccode = (unsigned char *)malloc((size_t)raw->eccLength);
if(raw->ecccode == NULL) {
free(raw->datacode);
free(raw);
return NULL;
}
raw->blocks = QRspec_rsBlockNum(spec);
raw->rsblock = (RSblock *)calloc((size_t)(raw->blocks), sizeof(RSblock));
if(raw->rsblock == NULL) {
QRraw_free(raw);
return NULL;
}
ret = RSblock_init(raw->rsblock, spec, raw->datacode, raw->ecccode);
if(ret < 0) {
QRraw_free(raw);
return NULL;
}
raw->count = 0;
return raw;
}
/**
* Return a code (byte).
* This function can be called iteratively.
* @param raw raw code.
* @return code
*/
STATIC_IN_RELEASE unsigned char QRraw_getCode(QRRawCode *raw)
{
int col, row;
unsigned char ret;
if(raw->count < raw->dataLength) {
row = raw->count % raw->blocks;
col = raw->count / raw->blocks;
if(col >= raw->rsblock[0].dataLength) {
row += raw->b1;
}
ret = raw->rsblock[row].data[col];
} else if(raw->count < raw->dataLength + raw->eccLength) {
row = (raw->count - raw->dataLength) % raw->blocks;
col = (raw->count - raw->dataLength) / raw->blocks;
ret = raw->rsblock[row].ecc[col];
} else {
return 0;
}
raw->count++;
return ret;
}
STATIC_IN_RELEASE void QRraw_free(QRRawCode *raw)
{
if(raw != NULL) {
free(raw->datacode);
free(raw->ecccode);
free(raw->rsblock);
free(raw);
}
}
/******************************************************************************
* Raw code for Micro QR Code
*****************************************************************************/
typedef struct {
int version;
int dataLength;
int eccLength;
unsigned char *datacode;
unsigned char *ecccode;
RSblock *rsblock;
int oddbits;
int count;
} MQRRawCode;
STATIC_IN_RELEASE void MQRraw_free(MQRRawCode *raw);
STATIC_IN_RELEASE MQRRawCode *MQRraw_new(QRinput *input)
{
MQRRawCode *raw;
raw = (MQRRawCode *)malloc(sizeof(MQRRawCode));
if(raw == NULL) return NULL;
raw->version = input->version;
raw->dataLength = MQRspec_getDataLength(input->version, input->level);
raw->eccLength = MQRspec_getECCLength(input->version, input->level);
raw->oddbits = raw->dataLength * 8 - MQRspec_getDataLengthBit(input->version, input->level);
raw->datacode = QRinput_getByteStream(input);
if(raw->datacode == NULL) {
free(raw);
return NULL;
}
raw->ecccode = (unsigned char *)malloc((size_t)raw->eccLength);
if(raw->ecccode == NULL) {
free(raw->datacode);
free(raw);
return NULL;
}
raw->rsblock = (RSblock *)calloc(1, sizeof(RSblock));
if(raw->rsblock == NULL) {
MQRraw_free(raw);
return NULL;
}
RSblock_initBlock(raw->rsblock, raw->dataLength, raw->datacode, raw->eccLength, raw->ecccode);
raw->count = 0;
return raw;
}
/**
* Return a code (byte).
* This function can be called iteratively.
* @param raw raw code.
* @return code
*/
STATIC_IN_RELEASE unsigned char MQRraw_getCode(MQRRawCode *raw)
{
unsigned char ret;
if(raw->count < raw->dataLength) {
ret = raw->datacode[raw->count];
} else if(raw->count < raw->dataLength + raw->eccLength) {
ret = raw->ecccode[raw->count - raw->dataLength];
} else {
return 0;
}
raw->count++;
return ret;
}
STATIC_IN_RELEASE void MQRraw_free(MQRRawCode *raw)
{
if(raw != NULL) {
free(raw->datacode);
free(raw->ecccode);
free(raw->rsblock);
free(raw);
}
}
/******************************************************************************
* Frame filling
*****************************************************************************/
typedef struct {
int width;
unsigned char *frame;
int x, y;
int dir;
int bit;
int mqr;
} FrameFiller;
static void FrameFiller_set(FrameFiller *filler, int width, unsigned char *frame, int mqr)
{
filler->width = width;
filler->frame = frame;
filler->x = width - 1;
filler->y = width - 1;
filler->dir = -1;
filler->bit = -1;
filler->mqr = mqr;
}
static unsigned char *FrameFiller_next(FrameFiller *filler)
{
unsigned char *p;
int x, y, w;
if(filler->bit == -1) {
filler->bit = 0;
return filler->frame + filler->y * filler->width + filler->x;
}
x = filler->x;
y = filler->y;
p = filler->frame;
w = filler->width;
if(filler->bit == 0) {
x--;
filler->bit++;
} else {
x++;
y += filler->dir;
filler->bit--;
}
if(filler->dir < 0) {
if(y < 0) {
y = 0;
x -= 2;
filler->dir = 1;
if(!filler->mqr && x == 6) {
x--;
y = 9;
}
}
} else if(y == w) {
y = w - 1;
x -= 2;
filler->dir = -1;
if(!filler->mqr && x == 6) {
x--;
y -= 8;
}
}
if(x < 0 || y < 0) return NULL;
filler->x = x;
filler->y = y;
if(p[y * w + x] & 0x80) {
// This tail recursion could be optimized.
return FrameFiller_next(filler);
}
return &p[y * w + x];
}
#ifdef WITH_TESTS
unsigned char *FrameFiller_test(int version)
{
int width;
unsigned char *frame, *p;
int i, length;
FrameFiller filler;
width = QRspec_getWidth(version);
frame = QRspec_newFrame(version);
if(frame == NULL) return NULL;
FrameFiller_set(&filler, width, frame, 0);
length = QRspec_getDataLength(version, QR_ECLEVEL_L) * 8
+ QRspec_getECCLength(version, QR_ECLEVEL_L) * 8
+ QRspec_getRemainder(version);
for(i = 0; i < length; i++) {
p = FrameFiller_next(&filler);
if(p == NULL) {
free(frame);
return NULL;
}
*p = (unsigned char)(i & 0x7f) | 0x80;
}
return frame;
}
unsigned char *FrameFiller_testMQR(int version)
{
int width;
unsigned char *frame, *p;
int i, length;
FrameFiller filler;
width = MQRspec_getWidth(version);
frame = MQRspec_newFrame(version);
if(frame == NULL) return NULL;
FrameFiller_set(&filler, width, frame, 1);
length = MQRspec_getDataLengthBit(version, QR_ECLEVEL_L)
+ MQRspec_getECCLength(version, QR_ECLEVEL_L) * 8;
for(i = 0; i < length; i++) {
p = FrameFiller_next(&filler);
if(p == NULL) {
fprintf(stderr, "Frame filler run over the frame!\n");
return frame;
}
*p = (unsigned char)(i & 0x7f) | 0x80;
}
return frame;
}
#endif
/******************************************************************************
* QR-code encoding
*****************************************************************************/
STATIC_IN_RELEASE QRcode *QRcode_new(int version, int width, unsigned char *data)
{
QRcode *qrcode;
qrcode = (QRcode *)malloc(sizeof(QRcode));
if(qrcode == NULL) return NULL;
qrcode->version = version;
qrcode->width = width;
qrcode->data = data;
return qrcode;
}
void QRcode_free(QRcode *qrcode)
{
if(qrcode != NULL) {
free(qrcode->data);
free(qrcode);
}
}
STATIC_IN_RELEASE QRcode *QRcode_encodeMask(QRinput *input, int mask)
{
int width, version;
QRRawCode *raw;
unsigned char *frame, *masked, *p, code, bit;
int i, j;
QRcode *qrcode = NULL;
FrameFiller filler;
if(input->mqr) {
errno = EINVAL;
return NULL;
}
if(input->version < 0 || input->version > QRSPEC_VERSION_MAX) {
errno = EINVAL;
return NULL;
}
if(!(input->level >= QR_ECLEVEL_L && input->level <= QR_ECLEVEL_H)) {
errno = EINVAL;
return NULL;
}
raw = QRraw_new(input);
if(raw == NULL) return NULL;
version = raw->version;
width = QRspec_getWidth(version);
frame = QRspec_newFrame(version);
if(frame == NULL) {
QRraw_free(raw);
return NULL;
}
FrameFiller_set(&filler, width, frame, 0);
/* interleaved data and ecc codes */
for(i = 0; i < raw->dataLength; i++) {
code = QRraw_getCode(raw);
bit = 0x80;
for(j = 0; j < 8; j++) {
p = FrameFiller_next(&filler);
if(p == NULL) goto EXIT;
*p = ((bit & code) != 0);
bit = bit >> 1;
}
}
for(i = 0; i < raw->eccLength; i++) {
code = QRraw_getCode(raw);
bit = 0x80;
for(j = 0; j < 8; j++) {
p = FrameFiller_next(&filler);
if(p == NULL) goto EXIT;
*p = 0x02 | ((bit & code) != 0);
bit = bit >> 1;
}
}
QRraw_free(raw);
raw = NULL;
/* remainder bits */
j = QRspec_getRemainder(version);
for(i = 0; i < j; i++) {
p = FrameFiller_next(&filler);
if(p == NULL) goto EXIT;
*p = 0x02;
}
/* masking */
if(mask == -2) { // just for debug purpose
masked = (unsigned char *)malloc((size_t)(width * width));
memcpy(masked, frame, (size_t)(width * width));
} else if(mask < 0) {
masked = Mask_mask(width, frame, input->level);
} else {
masked = Mask_makeMask(width, frame, mask, input->level);
}
if(masked == NULL) {
goto EXIT;
}
qrcode = QRcode_new(version, width, masked);
if(qrcode == NULL) {
free(masked);
}
EXIT:
QRraw_free(raw);
free(frame);
return qrcode;
}
STATIC_IN_RELEASE QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask)
{
int width, version;
MQRRawCode *raw;
unsigned char *frame, *masked, *p, code, bit;
int i, j, length;
QRcode *qrcode = NULL;
FrameFiller filler;
if(!input->mqr) {
errno = EINVAL;
return NULL;
}
if(input->version <= 0 || input->version > MQRSPEC_VERSION_MAX) {
errno = EINVAL;
return NULL;
}
if(!(input->level >= QR_ECLEVEL_L && input->level <= QR_ECLEVEL_Q)) {
errno = EINVAL;
return NULL;
}
raw = MQRraw_new(input);
if(raw == NULL) return NULL;
version = raw->version;
width = MQRspec_getWidth(version);
frame = MQRspec_newFrame(version);
if(frame == NULL) {
MQRraw_free(raw);
return NULL;
}
FrameFiller_set(&filler, width, frame, 1);
/* interleaved data and ecc codes */
for(i = 0; i < raw->dataLength; i++) {
code = MQRraw_getCode(raw);
bit = 0x80;
if(raw->oddbits && i == raw->dataLength - 1) {
length = raw->oddbits;
} else {
length = 8;
}
for(j = 0; j < length; j++) {
p = FrameFiller_next(&filler);
if(p == NULL) goto EXIT;
*p = ((bit & code) != 0);
bit = bit >> 1;
}
}
for(i = 0; i < raw->eccLength; i++) {
code = MQRraw_getCode(raw);
bit = 0x80;
length = 8;
for(j = 0; j < length; j++) {
p = FrameFiller_next(&filler);
if(p == NULL) goto EXIT;
*p = 0x02 | ((bit & code) != 0);
bit = bit >> 1;
}
}
MQRraw_free(raw);
raw = NULL;
/* masking */
if(mask == -2) { // just for debug purpose
masked = (unsigned char *)malloc((size_t)(width * width));
memcpy(masked, frame, (size_t)(width * width));
} else if(mask < 0) {
masked = MMask_mask(version, frame, input->level);
} else {
masked = MMask_makeMask(version, frame, mask, input->level);
}
if(masked == NULL) {
goto EXIT;
}
qrcode = QRcode_new(version, width, masked);
if(qrcode == NULL) {
free(masked);
}
EXIT:
MQRraw_free(raw);
free(frame);
return qrcode;
}
QRcode *QRcode_encodeInput(QRinput *input)
{
if(input->mqr) {
return QRcode_encodeMaskMQR(input, -1);
} else {
return QRcode_encodeMask(input, -1);
}
}
static QRcode *QRcode_encodeStringReal(const char *string, int version, QRecLevel level, int mqr, QRencodeMode hint, int casesensitive)
{
QRinput *input;
QRcode *code;
int ret;
if(string == NULL) {
errno = EINVAL;
return NULL;
}
if(hint != QR_MODE_8 && hint != QR_MODE_KANJI) {
errno = EINVAL;
return NULL;
}
if(mqr) {
input = QRinput_newMQR(version, level);
} else {
input = QRinput_new2(version, level);
}
if(input == NULL) return NULL;
ret = Split_splitStringToQRinput(string, input, hint, casesensitive);
if(ret < 0) {
QRinput_free(input);
return NULL;
}
code = QRcode_encodeInput(input);
QRinput_free(input);
return code;
}
QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
{
return QRcode_encodeStringReal(string, version, level, 0, hint, casesensitive);
}
QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
{
int i;
if(version == 0) {
version = 1;
}
for(i = version; i <= MQRSPEC_VERSION_MAX ; i++) {
QRcode *code = QRcode_encodeStringReal(string, i, level, 1, hint, casesensitive);
if(code != NULL) return code;
}
return NULL;
}
static QRcode *QRcode_encodeDataReal(const unsigned char *data, int length, int version, QRecLevel level, int mqr)
{
QRinput *input;
QRcode *code;
int ret;
if(data == NULL || length == 0) {
errno = EINVAL;
return NULL;
}
if(mqr) {
input = QRinput_newMQR(version, level);
} else {
input = QRinput_new2(version, level);
}
if(input == NULL) return NULL;
ret = QRinput_append(input, QR_MODE_8, length, data);
if(ret < 0) {
QRinput_free(input);
return NULL;
}
code = QRcode_encodeInput(input);
QRinput_free(input);
return code;
}
QRcode *QRcode_encodeData(int size, const unsigned char *data, int version, QRecLevel level)
{
return QRcode_encodeDataReal(data, size, version, level, 0);
}
QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level)
{
if(string == NULL) {
errno = EINVAL;
return NULL;
}
return QRcode_encodeDataReal((unsigned char *)string, (int)strlen(string), version, level, 0);
}
QRcode *QRcode_encodeDataMQR(int size, const unsigned char *data, int version, QRecLevel level)
{
int i;
if(version == 0) {
version = 1;
}
for(i = version; i <= MQRSPEC_VERSION_MAX; i++) {
QRcode *code = QRcode_encodeDataReal(data, size, i, level, 1);
if(code != NULL) return code;
}
return NULL;
}
QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level)
{
int i;
if(string == NULL) {
errno = EINVAL;
return NULL;
}
if(version == 0) {
version = 1;
}
for(i = version; i <= MQRSPEC_VERSION_MAX; i++) {
QRcode *code = QRcode_encodeDataReal((unsigned char *)string, (int)strlen(string), i, level, 1);
if(code != NULL) return code;
}
return NULL;
}
/******************************************************************************
* Structured QR-code encoding
*****************************************************************************/
static QRcode_List *QRcode_List_newEntry(void)
{
QRcode_List *entry;
entry = (QRcode_List *)malloc(sizeof(QRcode_List));
if(entry == NULL) return NULL;
entry->next = NULL;
entry->code = NULL;
return entry;
}
static void QRcode_List_freeEntry(QRcode_List *entry)
{
if(entry != NULL) {
QRcode_free(entry->code);
free(entry);
}
}
void QRcode_List_free(QRcode_List *qrlist)
{
QRcode_List *list = qrlist, *next;
while(list != NULL) {
next = list->next;
QRcode_List_freeEntry(list);
list = next;
}
}
int QRcode_List_size(QRcode_List *qrlist)
{
QRcode_List *list = qrlist;
int size = 0;
while(list != NULL) {
size++;
list = list->next;
}
return size;
}
#if 0
static unsigned char QRcode_parity(const char *str, int size)
{
unsigned char parity = 0;
int i;
for(i = 0; i < size; i++) {
parity ^= str[i];
}
return parity;
}
#endif
QRcode_List *QRcode_encodeInputStructured(QRinput_Struct *s)
{
QRcode_List *head = NULL;
QRcode_List *tail = NULL;
QRcode_List *entry;
QRinput_InputList *list = s->head;
while(list != NULL) {
if(head == NULL) {
entry = QRcode_List_newEntry();
if(entry == NULL) goto ABORT;
head = entry;
tail = head;
} else {
entry = QRcode_List_newEntry();
if(entry == NULL) goto ABORT;
tail->next = entry;
tail = tail->next;
}
tail->code = QRcode_encodeInput(list->input);
if(tail->code == NULL) {
goto ABORT;
}
list = list->next;
}
return head;
ABORT:
QRcode_List_free(head);
return NULL;
}
static QRcode_List *QRcode_encodeInputToStructured(QRinput *input)
{
QRinput_Struct *s;
QRcode_List *codes;
s = QRinput_splitQRinputToStruct(input);
if(s == NULL) return NULL;
codes = QRcode_encodeInputStructured(s);
QRinput_Struct_free(s);
return codes;
}
static QRcode_List *QRcode_encodeDataStructuredReal(
int size, const unsigned char *data,
int version, QRecLevel level,
int eightbit, QRencodeMode hint, int casesensitive)
{
QRinput *input;
QRcode_List *codes;
int ret;
if(version <= 0) {
errno = EINVAL;
return NULL;
}
if(!eightbit && (hint != QR_MODE_8 && hint != QR_MODE_KANJI)) {
errno = EINVAL;
return NULL;
}
input = QRinput_new2(version, level);
if(input == NULL) return NULL;
if(eightbit) {
ret = QRinput_append(input, QR_MODE_8, size, data);
} else {
ret = Split_splitStringToQRinput((char *)data, input, hint, casesensitive);
}
if(ret < 0) {
QRinput_free(input);
return NULL;
}
codes = QRcode_encodeInputToStructured(input);
QRinput_free(input);
return codes;
}
QRcode_List *QRcode_encodeDataStructured(int size, const unsigned char *data, int version, QRecLevel level) {
return QRcode_encodeDataStructuredReal(size, data, version, level, 1, QR_MODE_NUL, 0);
}
QRcode_List *QRcode_encodeString8bitStructured(const char *string, int version, QRecLevel level) {
if(string == NULL) {
errno = EINVAL;
return NULL;
}
return QRcode_encodeDataStructured((int)strlen(string), (unsigned char *)string, version, level);
}
QRcode_List *QRcode_encodeStringStructured(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive)
{
if(string == NULL) {
errno = EINVAL;
return NULL;
}
return QRcode_encodeDataStructuredReal((int)strlen(string), (unsigned char *)string, version, level, 0, hint, casesensitive);
}
/******************************************************************************
* System utilities
*****************************************************************************/
void QRcode_APIVersion(int *major_version, int *minor_version, int *micro_version)
{
if(major_version != NULL) {
*major_version = MAJOR_VERSION;
}
if(minor_version != NULL) {
*minor_version = MINOR_VERSION;
}
if(micro_version != NULL) {
*micro_version = MICRO_VERSION;
}
}
char *QRcode_APIVersionString(void)
{
return VERSION;
}
void QRcode_clearCache(void)
{
return;
}

View File

@ -0,0 +1,568 @@
/**
* qrencode - QR Code encoder
*
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/** \mainpage
* Libqrencode is a library for encoding data in a QR Code symbol, a kind of 2D
* symbology.
*
* \section encoding Encoding
*
* There are two methods to encode data: <b>encoding a string/data</b> or
* <b>encoding a structured data</b>.
*
* \subsection encoding-string Encoding a string/data
* You can encode a string by calling QRcode_encodeString().
* The given string is parsed automatically and encoded. If you want to encode
* data that can be represented as a C string style (NUL terminated), you can
* simply use this way.
*
* If the input data contains Kanji (Shift-JIS) characters and you want to
* encode them as Kanji in QR Code, you should give QR_MODE_KANJI as a hint.
* Otherwise, all of non-alphanumeric characters are encoded as 8-bit data.
* If you want to encode a whole string in 8-bit mode, you can use
* QRcode_encodeString8bit() instead.
*
* Please note that a C string can not contain NUL characters. If your data
* contains NUL, you must use QRcode_encodeData().
*
* \subsection encoding-input Encoding a structured data
* You can construct a structured input data manually. If the structure of the
* input data is known, you can use this method.
* At first, create a ::QRinput object by QRinput_new(). Then add input data
* to the QRinput object by QRinput_append(). Finally call QRcode_encodeInput()
* to encode the QRinput data.
* You can reuse the QRinput object again to encode it in other symbols with
* different parameters.
*
* \section result Result
* The encoded symbol is generated as a ::QRcode object. It will contain its
* version number, the width of the symbol, and an array represents the symbol.
* See ::QRcode for the details. You can free the object by QRcode_free().
*
* Please note that the version of the result may be larger than specified.
* In such cases, the input data would be too large to be encoded in a
* symbol of the specified version.
*
* \section structured Structured append
* Libqrencode can generate "Structured-appended" symbols that enables to split
* a large data set into mulitple QR codes. A QR code reader concatenates
* multiple QR code symbols into a string.
* Just like QRcode_encodeString(), you can use QRcode_encodeStringStructured()
* to generate structured-appended symbols. This functions returns an instance
* of ::QRcode_List. The returned list is a singly-linked list of QRcode: you
* can retrieve each QR code in this way:
*
* \code
* QRcode_List *qrcodes;
* QRcode_List *entry;
* QRcode *qrcode;
*
* qrcodes = QRcode_encodeStringStructured(...);
* entry = qrcodes;
* while(entry != NULL) {
* qrcode = entry->code;
* // do something
* entry = entry->next;
* }
* QRcode_List_free(entry);
* \endcode
*
* Instead of using auto-parsing functions, you can construct your own
* structured input. At first, instantiate an object of ::QRinput_Struct
* by calling QRinput_Struct_new(). This object can hold multiple ::QRinput,
* and one QR code is generated for a ::QRinput.
* QRinput_Struct_appendInput() appends a ::QRinput to a ::QRinput_Struct
* object. In order to generate structured-appended symbols, it is required to
* embed headers to each symbol. You can use
* QRinput_Struct_insertStructuredAppendHeaders() to insert appropriate
* headers to each symbol. You should call this function just once before
* encoding symbols.
*/
#ifndef QRENCODE_H
#define QRENCODE_H
#if defined(__cplusplus)
extern "C" {
#endif
/**
* Encoding mode.
*/
typedef enum {
QR_MODE_NUL = -1, ///< Terminator (NUL character). Internal use only
QR_MODE_NUM = 0, ///< Numeric mode
QR_MODE_AN, ///< Alphabet-numeric mode
QR_MODE_8, ///< 8-bit data mode
QR_MODE_KANJI, ///< Kanji (shift-jis) mode
QR_MODE_STRUCTURE, ///< Internal use only
QR_MODE_ECI, ///< ECI mode
QR_MODE_FNC1FIRST, ///< FNC1, first position
QR_MODE_FNC1SECOND, ///< FNC1, second position
} QRencodeMode;
/**
* Level of error correction.
*/
typedef enum {
QR_ECLEVEL_L = 0, ///< lowest
QR_ECLEVEL_M,
QR_ECLEVEL_Q,
QR_ECLEVEL_H ///< highest
} QRecLevel;
/**
* Maximum version (size) of QR-code symbol.
*/
#define QRSPEC_VERSION_MAX 40
/**
* Maximum version (size) of QR-code symbol.
*/
#define MQRSPEC_VERSION_MAX 4
/******************************************************************************
* Input data (qrinput.c)
*****************************************************************************/
/**
* Singly linked list to contain input strings. An instance of this class
* contains its version and error correction level too. It is required to
* set them by QRinput_setVersion() and QRinput_setErrorCorrectionLevel(),
* or use QRinput_new2() to instantiate an object.
*/
typedef struct _QRinput QRinput;
/**
* Instantiate an input data object. The version is set to 0 (auto-select)
* and the error correction level is set to QR_ECLEVEL_L.
* @return an input object (initialized). On error, NULL is returned and errno
* is set to indicate the error.
* @throw ENOMEM unable to allocate memory.
*/
extern QRinput *QRinput_new(void);
/**
* Instantiate an input data object.
* @param version version number.
* @param level Error correction level.
* @return an input object (initialized). On error, NULL is returned and errno
* is set to indicate the error.
* @throw ENOMEM unable to allocate memory for input objects.
* @throw EINVAL invalid arguments.
*/
extern QRinput *QRinput_new2(int version, QRecLevel level);
/**
* Instantiate an input data object. Object's Micro QR Code flag is set.
* Unlike with full-sized QR Code, version number must be specified (>0).
* @param version version number (1--4).
* @param level Error correction level.
* @return an input object (initialized). On error, NULL is returned and errno
* is set to indicate the error.
* @throw ENOMEM unable to allocate memory for input objects.
* @throw EINVAL invalid arguments.
*/
extern QRinput *QRinput_newMQR(int version, QRecLevel level);
/**
* Append data to an input object.
* The data is copied and appended to the input object.
* @param input input object.
* @param mode encoding mode.
* @param size size of data (byte).
* @param data a pointer to the memory area of the input data.
* @retval 0 success.
* @retval -1 an error occurred and errno is set to indeicate the error.
* See Execptions for the details.
* @throw ENOMEM unable to allocate memory.
* @throw EINVAL input data is invalid.
*
*/
extern int QRinput_append(QRinput *input, QRencodeMode mode, int size, const unsigned char *data);
/**
* Append ECI header.
* @param input input object.
* @param ecinum ECI indicator number (0 - 999999)
* @retval 0 success.
* @retval -1 an error occurred and errno is set to indeicate the error.
* See Execptions for the details.
* @throw ENOMEM unable to allocate memory.
* @throw EINVAL input data is invalid.
*
*/
extern int QRinput_appendECIheader(QRinput *input, unsigned int ecinum);
/**
* Get current version.
* @param input input object.
* @return current version.
*/
extern int QRinput_getVersion(QRinput *input);
/**
* Set version of the QR code that is to be encoded.
* This function cannot be applied to Micro QR Code.
* @param input input object.
* @param version version number (0 = auto)
* @retval 0 success.
* @retval -1 invalid argument.
*/
extern int QRinput_setVersion(QRinput *input, int version);
/**
* Get current error correction level.
* @param input input object.
* @return Current error correcntion level.
*/
extern QRecLevel QRinput_getErrorCorrectionLevel(QRinput *input);
/**
* Set error correction level of the QR code that is to be encoded.
* This function cannot be applied to Micro QR Code.
* @param input input object.
* @param level Error correction level.
* @retval 0 success.
* @retval -1 invalid argument.
*/
extern int QRinput_setErrorCorrectionLevel(QRinput *input, QRecLevel level);
/**
* Set version and error correction level of the QR code at once.
* This function is recommened for Micro QR Code.
* @param input input object.
* @param version version number (0 = auto)
* @param level Error correction level.
* @retval 0 success.
* @retval -1 invalid argument.
*/
extern int QRinput_setVersionAndErrorCorrectionLevel(QRinput *input, int version, QRecLevel level);
/**
* Free the input object.
* All of data chunks in the input object are freed too.
* @param input input object.
*/
extern void QRinput_free(QRinput *input);
/**
* Validate the input data.
* @param mode encoding mode.
* @param size size of data (byte).
* @param data a pointer to the memory area of the input data.
* @retval 0 success.
* @retval -1 invalid arguments.
*/
extern int QRinput_check(QRencodeMode mode, int size, const unsigned char *data);
/**
* Set of QRinput for structured symbols.
*/
typedef struct _QRinput_Struct QRinput_Struct;
/**
* Instantiate a set of input data object.
* @return an instance of QRinput_Struct. On error, NULL is returned and errno
* is set to indicate the error.
* @throw ENOMEM unable to allocate memory.
*/
extern QRinput_Struct *QRinput_Struct_new(void);
/**
* Set parity of structured symbols.
* @param s structured input object.
* @param parity parity of s.
*/
extern void QRinput_Struct_setParity(QRinput_Struct *s, unsigned char parity);
/**
* Append a QRinput object to the set. QRinput created by QRinput_newMQR()
* will be rejected.
* @warning never append the same QRinput object twice or more.
* @param s structured input object.
* @param input an input object.
* @retval >0 number of input objects in the structure.
* @retval -1 an error occurred. See Exceptions for the details.
* @throw ENOMEM unable to allocate memory.
* @throw EINVAL invalid arguments.
*/
extern int QRinput_Struct_appendInput(QRinput_Struct *s, QRinput *input);
/**
* Free all of QRinput in the set.
* @param s a structured input object.
*/
extern void QRinput_Struct_free(QRinput_Struct *s);
/**
* Split a QRinput to QRinput_Struct. It calculates a parity, set it, then
* insert structured-append headers. QRinput created by QRinput_newMQR() will
* be rejected.
* @param input input object. Version number and error correction level must be
* set.
* @return a set of input data. On error, NULL is returned, and errno is set
* to indicate the error. See Exceptions for the details.
* @throw ERANGE input data is too large.
* @throw EINVAL invalid input data.
* @throw ENOMEM unable to allocate memory.
*/
extern QRinput_Struct *QRinput_splitQRinputToStruct(QRinput *input);
/**
* Insert structured-append headers to the input structure. It calculates
* a parity and set it if the parity is not set yet.
* @param s input structure
* @retval 0 success.
* @retval -1 an error occurred and errno is set to indeicate the error.
* See Execptions for the details.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory.
*/
extern int QRinput_Struct_insertStructuredAppendHeaders(QRinput_Struct *s);
/**
* Set FNC1-1st position flag.
*/
extern int QRinput_setFNC1First(QRinput *input);
/**
* Set FNC1-2nd position flag and application identifier.
*/
extern int QRinput_setFNC1Second(QRinput *input, unsigned char appid);
/******************************************************************************
* QRcode output (qrencode.c)
*****************************************************************************/
/**
* QRcode class.
* Symbol data is represented as an array contains width*width uchars.
* Each uchar represents a module (dot). If the less significant bit of
* the uchar is 1, the corresponding module is black. The other bits are
* meaningless for usual applications, but here its specification is described.
*
* @verbatim
MSB 76543210 LSB
|||||||`- 1=black/0=white
||||||`-- 1=ecc/0=data code area
|||||`--- format information
||||`---- version information
|||`----- timing pattern
||`------ alignment pattern
|`------- finder pattern and separator
`-------- non-data modules (format, timing, etc.)
@endverbatim
*/
typedef struct {
int version; ///< version of the symbol
int width; ///< width of the symbol
unsigned char *data; ///< symbol data
} QRcode;
/**
* Singly-linked list of QRcode. Used to represent a structured symbols.
* A list is terminated with NULL.
*/
typedef struct _QRcode_List {
QRcode *code;
struct _QRcode_List *next;
} QRcode_List;
/**
* Create a symbol from the input data.
* @warning This function is THREAD UNSAFE when pthread is disabled.
* @param input input data.
* @return an instance of QRcode class. The version of the result QRcode may
* be larger than the designated version. On error, NULL is returned,
* and errno is set to indicate the error. See Exceptions for the
* details.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory for input objects.
*/
extern QRcode *QRcode_encodeInput(QRinput *input);
/**
* Create a symbol from the string. The library automatically parses the input
* string and encodes in a QR Code symbol.
* @warning This function is THREAD UNSAFE when pthread is disabled.
* @param string input string. It must be NUL terminated.
* @param version version of the symbol. If 0, the library chooses the minimum
* version for the given input data.
* @param level error correction level.
* @param hint tell the library how Japanese Kanji characters should be
* encoded. If QR_MODE_KANJI is given, the library assumes that the
* given string contains Shift-JIS characters and encodes them in
* Kanji-mode. If QR_MODE_8 is given, all of non-alphanumerical
* characters will be encoded as is. If you want to embed UTF-8
* string, choose this. Other mode will cause EINVAL error.
* @param casesensitive case-sensitive(1) or not(0).
* @return an instance of QRcode class. The version of the result QRcode may
* be larger than the designated version. On error, NULL is returned,
* and errno is set to indicate the error. See Exceptions for the
* details.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory for input objects.
* @throw ERANGE input data is too large.
*/
extern QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
/**
* Same to QRcode_encodeString(), but encode whole data in 8-bit mode.
* @warning This function is THREAD UNSAFE when pthread is disabled.
*/
extern QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level);
/**
* Micro QR Code version of QRcode_encodeString().
* @warning This function is THREAD UNSAFE when pthread is disabled.
*/
extern QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
/**
* Micro QR Code version of QRcode_encodeString8bit().
* @warning This function is THREAD UNSAFE when pthread is disabled.
*/
extern QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level);
/**
* Encode byte stream (may include '\0') in 8-bit mode.
* @warning This function is THREAD UNSAFE when pthread is disabled.
* @param size size of the input data.
* @param data input data.
* @param version version of the symbol. If 0, the library chooses the minimum
* version for the given input data.
* @param level error correction level.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory for input objects.
* @throw ERANGE input data is too large.
*/
extern QRcode *QRcode_encodeData(int size, const unsigned char *data, int version, QRecLevel level);
/**
* Micro QR Code version of QRcode_encodeData().
* @warning This function is THREAD UNSAFE when pthread is disabled.
*/
extern QRcode *QRcode_encodeDataMQR(int size, const unsigned char *data, int version, QRecLevel level);
/**
* Free the instance of QRcode class.
* @param qrcode an instance of QRcode class.
*/
extern void QRcode_free(QRcode *qrcode);
/**
* Create structured symbols from the input data.
* @warning This function is THREAD UNSAFE when pthread is disabled.
* @param s input data, structured.
* @return a singly-linked list of QRcode.
*/
extern QRcode_List *QRcode_encodeInputStructured(QRinput_Struct *s);
/**
* Create structured symbols from the string. The library automatically parses
* the input string and encodes in a QR Code symbol.
* @warning This function is THREAD UNSAFE when pthread is disabled.
* @param string input string. It must be NUL terminated.
* @param version version of the symbol.
* @param level error correction level.
* @param hint tell the library how Japanese Kanji characters should be
* encoded. If QR_MODE_KANJI is given, the library assumes that the
* given string contains Shift-JIS characters and encodes them in
* Kanji-mode. If QR_MODE_8 is given, all of non-alphanumerical
* characters will be encoded as is. If you want to embed UTF-8
* string, choose this. Other mode will cause EINVAL error.
* @param casesensitive case-sensitive(1) or not(0).
* @return a singly-linked list of QRcode. On error, NULL is returned, and
* errno is set to indicate the error. See Exceptions for the details.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory for input objects.
*/
extern QRcode_List *QRcode_encodeStringStructured(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
/**
* Same to QRcode_encodeStringStructured(), but encode whole data in 8-bit mode.
* @warning This function is THREAD UNSAFE when pthread is disabled.
*/
extern QRcode_List *QRcode_encodeString8bitStructured(const char *string, int version, QRecLevel level);
/**
* Create structured symbols from byte stream (may include '\0'). Wholde data
* are encoded in 8-bit mode.
* @warning This function is THREAD UNSAFE when pthread is disabled.
* @param size size of the input data.
* @param data input dat.
* @param version version of the symbol.
* @param level error correction level.
* @return a singly-linked list of QRcode. On error, NULL is returned, and
* errno is set to indicate the error. See Exceptions for the details.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory for input objects.
*/
extern QRcode_List *QRcode_encodeDataStructured(int size, const unsigned char *data, int version, QRecLevel level);
/**
* Return the number of symbols included in a QRcode_List.
* @param qrlist a head entry of a QRcode_List.
* @return number of symbols in the list.
*/
extern int QRcode_List_size(QRcode_List *qrlist);
/**
* Free the QRcode_List.
* @param qrlist a head entry of a QRcode_List.
*/
extern void QRcode_List_free(QRcode_List *qrlist);
/******************************************************************************
* System utilities
*****************************************************************************/
/**
* Return a string that identifies the library version.
* @param major_version major version number
* @param minor_version minor version number
* @param micro_version micro version number
*/
extern void QRcode_APIVersion(int *major_version, int *minor_version, int *micro_version);
/**
* Return a string that identifies the library version.
* @return a string identifies the library version. The string is held by the
* library. Do NOT free it.
*/
extern char *QRcode_APIVersionString(void);
/**
* @deprecated
*/
#ifndef _MSC_VER
extern void QRcode_clearCache(void) __attribute__ ((deprecated));
#else
extern void QRcode_clearCache(void);
#endif
#if defined(__cplusplus)
}
#endif
#endif /* QRENCODE_H */

View File

@ -0,0 +1,88 @@
/**
* qrencode - QR Code encoder
*
* Header for test use
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef QRENCODE_INNER_H
#define QRENCODE_INNER_H
/**
* This header file includes definitions for test use.
*/
/******************************************************************************
* Raw code
*****************************************************************************/
typedef struct {
int dataLength;
int eccLength;
unsigned char *data;
unsigned char *ecc;
} RSblock;
typedef struct {
int version;
int dataLength;
int eccLength;
unsigned char *datacode;
unsigned char *ecccode;
int b1;
int blocks;
RSblock *rsblock;
int count;
} QRRawCode;
extern QRRawCode *QRraw_new(QRinput *input);
extern unsigned char QRraw_getCode(QRRawCode *raw);
extern void QRraw_free(QRRawCode *raw);
/******************************************************************************
* Raw code for Micro QR Code
*****************************************************************************/
typedef struct {
int version;
int dataLength;
int eccLength;
unsigned char *datacode;
unsigned char *ecccode;
RSblock *rsblock;
int oddbits;
int count;
} MQRRawCode;
extern MQRRawCode *MQRraw_new(QRinput *input);
extern unsigned char MQRraw_getCode(MQRRawCode *raw);
extern void MQRraw_free(MQRRawCode *raw);
/******************************************************************************
* Frame filling
*****************************************************************************/
extern unsigned char *FrameFiller_test(int version);
extern unsigned char *FrameFiller_testMQR(int version);
/******************************************************************************
* QR-code encoding
*****************************************************************************/
extern QRcode *QRcode_encodeMask(QRinput *input, int mask);
extern QRcode *QRcode_encodeMaskMQR(QRinput *input, int mask);
extern QRcode *QRcode_new(int version, int width, unsigned char *data);
#endif /* QRENCODE_INNER_H */

1639
datafile/qrencode/qrinput.c Normal file

File diff suppressed because it is too large Load Diff

124
datafile/qrencode/qrinput.h Normal file
View File

@ -0,0 +1,124 @@
/*
* qrencode - QR Code encoder
*
* Input data chunk class
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef QRINPUT_H
#define QRINPUT_H
#include "qrencode.h"
#include "bitstream.h"
int QRinput_isSplittableMode(QRencodeMode mode);
/******************************************************************************
* Entry of input data
*****************************************************************************/
typedef struct _QRinput_List QRinput_List;
struct _QRinput_List {
QRencodeMode mode;
int size; ///< Size of data chunk (byte).
unsigned char *data; ///< Data chunk.
BitStream *bstream;
QRinput_List *next;
};
/******************************************************************************
* Input Data
*****************************************************************************/
struct _QRinput {
int version;
QRecLevel level;
QRinput_List *head;
QRinput_List *tail;
int mqr;
int fnc1;
unsigned char appid;
};
/******************************************************************************
* Structured append input data
*****************************************************************************/
typedef struct _QRinput_InputList QRinput_InputList;
struct _QRinput_InputList {
QRinput *input;
QRinput_InputList *next;
};
struct _QRinput_Struct {
int size; ///< number of structured symbols
int parity;
QRinput_InputList *head;
QRinput_InputList *tail;
};
/**
* Pack all bit streams padding bits into a byte array.
* @param input input data.
* @return padded merged byte stream
*/
extern unsigned char *QRinput_getByteStream(QRinput *input);
extern int QRinput_estimateBitsModeNum(int size);
extern int QRinput_estimateBitsModeAn(int size);
extern int QRinput_estimateBitsMode8(int size);
extern int QRinput_estimateBitsModeKanji(int size);
extern QRinput *QRinput_dup(QRinput *input);
extern const signed char QRinput_anTable[128];
/**
* Look up the alphabet-numeric convesion table (see JIS X0510:2004, pp.19).
* @param __c__ character
* @return value
*/
#define QRinput_lookAnTable(__c__) \
((__c__ & 0x80)?-1:QRinput_anTable[(int)__c__])
/**
* Length of a standard mode indicator in bits.
*/
#define MODE_INDICATOR_SIZE 4
/**
* Length of a segment of structured-append header.
*/
#define STRUCTURE_HEADER_SIZE 20
/**
* Maximum number of symbols in a set of structured-appended symbols.
*/
#define MAX_STRUCTURED_SYMBOLS 16
#ifdef WITH_TESTS
extern int QRinput_mergeBitStream(QRinput *input, BitStream *bstream);
extern int QRinput_getBitStream(QRinput *input, BitStream *bstream);
extern int QRinput_estimateBitStreamSize(QRinput *input, int version);
extern int QRinput_splitEntry(QRinput_List *entry, int bytes);
extern int QRinput_estimateVersion(QRinput *input);
extern int QRinput_lengthOfCode(QRencodeMode mode, int version, int bits);
extern int QRinput_insertStructuredAppendHeader(QRinput *input, int size, int index, unsigned char parity);
#endif
#endif /* QRINPUT_H */

514
datafile/qrencode/qrspec.c Normal file
View File

@ -0,0 +1,514 @@
/*
* qrencode - QR Code encoder
*
* QR Code specification in convenient format.
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* The following data / specifications are taken from
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
* or
* "Automatic identification and data capture techniques --
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "qrspec.h"
#include "qrinput.h"
/******************************************************************************
* Version and capacity
*****************************************************************************/
typedef struct {
int width; //< Edge length of the symbol
int words; //< Data capacity (bytes)
int remainder; //< Remainder bit (bits)
int ec[4]; //< Number of ECC code (bytes)
} QRspec_Capacity;
/**
* Table of the capacity of symbols
* See Table 1 (pp.13) and Table 12-16 (pp.30-36), JIS X0510:2004.
*/
static const QRspec_Capacity qrspecCapacity[QRSPEC_VERSION_MAX + 1] = {
{ 0, 0, 0, { 0, 0, 0, 0}},
{ 21, 26, 0, { 7, 10, 13, 17}}, // 1
{ 25, 44, 7, { 10, 16, 22, 28}},
{ 29, 70, 7, { 15, 26, 36, 44}},
{ 33, 100, 7, { 20, 36, 52, 64}},
{ 37, 134, 7, { 26, 48, 72, 88}}, // 5
{ 41, 172, 7, { 36, 64, 96, 112}},
{ 45, 196, 0, { 40, 72, 108, 130}},
{ 49, 242, 0, { 48, 88, 132, 156}},
{ 53, 292, 0, { 60, 110, 160, 192}},
{ 57, 346, 0, { 72, 130, 192, 224}}, //10
{ 61, 404, 0, { 80, 150, 224, 264}},
{ 65, 466, 0, { 96, 176, 260, 308}},
{ 69, 532, 0, { 104, 198, 288, 352}},
{ 73, 581, 3, { 120, 216, 320, 384}},
{ 77, 655, 3, { 132, 240, 360, 432}}, //15
{ 81, 733, 3, { 144, 280, 408, 480}},
{ 85, 815, 3, { 168, 308, 448, 532}},
{ 89, 901, 3, { 180, 338, 504, 588}},
{ 93, 991, 3, { 196, 364, 546, 650}},
{ 97, 1085, 3, { 224, 416, 600, 700}}, //20
{101, 1156, 4, { 224, 442, 644, 750}},
{105, 1258, 4, { 252, 476, 690, 816}},
{109, 1364, 4, { 270, 504, 750, 900}},
{113, 1474, 4, { 300, 560, 810, 960}},
{117, 1588, 4, { 312, 588, 870, 1050}}, //25
{121, 1706, 4, { 336, 644, 952, 1110}},
{125, 1828, 4, { 360, 700, 1020, 1200}},
{129, 1921, 3, { 390, 728, 1050, 1260}},
{133, 2051, 3, { 420, 784, 1140, 1350}},
{137, 2185, 3, { 450, 812, 1200, 1440}}, //30
{141, 2323, 3, { 480, 868, 1290, 1530}},
{145, 2465, 3, { 510, 924, 1350, 1620}},
{149, 2611, 3, { 540, 980, 1440, 1710}},
{153, 2761, 3, { 570, 1036, 1530, 1800}},
{157, 2876, 0, { 570, 1064, 1590, 1890}}, //35
{161, 3034, 0, { 600, 1120, 1680, 1980}},
{165, 3196, 0, { 630, 1204, 1770, 2100}},
{169, 3362, 0, { 660, 1260, 1860, 2220}},
{173, 3532, 0, { 720, 1316, 1950, 2310}},
{177, 3706, 0, { 750, 1372, 2040, 2430}} //40
};
int QRspec_getDataLength(int version, QRecLevel level)
{
return qrspecCapacity[version].words - qrspecCapacity[version].ec[level];
}
int QRspec_getECCLength(int version, QRecLevel level)
{
return qrspecCapacity[version].ec[level];
}
int QRspec_getMinimumVersion(int size, QRecLevel level)
{
int i;
int words;
for(i = 1; i <= QRSPEC_VERSION_MAX; i++) {
words = qrspecCapacity[i].words - qrspecCapacity[i].ec[level];
if(words >= size) return i;
}
return QRSPEC_VERSION_MAX;
}
int QRspec_getWidth(int version)
{
return qrspecCapacity[version].width;
}
int QRspec_getRemainder(int version)
{
return qrspecCapacity[version].remainder;
}
/******************************************************************************
* Length indicator
*****************************************************************************/
static const int lengthTableBits[4][3] = {
{10, 12, 14},
{ 9, 11, 13},
{ 8, 16, 16},
{ 8, 10, 12}
};
int QRspec_lengthIndicator(QRencodeMode mode, int version)
{
int l;
if(!QRinput_isSplittableMode(mode)) return 0;
if(version <= 9) {
l = 0;
} else if(version <= 26) {
l = 1;
} else {
l = 2;
}
return lengthTableBits[mode][l];
}
int QRspec_maximumWords(QRencodeMode mode, int version)
{
int l;
int bits;
int words;
if(!QRinput_isSplittableMode(mode)) return 0;
if(version <= 9) {
l = 0;
} else if(version <= 26) {
l = 1;
} else {
l = 2;
}
bits = lengthTableBits[mode][l];
words = (1 << bits) - 1;
if(mode == QR_MODE_KANJI) {
words *= 2; // the number of bytes is required
}
return words;
}
/******************************************************************************
* Error correction code
*****************************************************************************/
/**
* Table of the error correction code (Reed-Solomon block)
* See Table 12-16 (pp.30-36), JIS X0510:2004.
*/
static const int eccTable[QRSPEC_VERSION_MAX+1][4][2] = {
{{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}},
{{ 1, 0}, { 1, 0}, { 1, 0}, { 1, 0}}, // 1
{{ 1, 0}, { 1, 0}, { 1, 0}, { 1, 0}},
{{ 1, 0}, { 1, 0}, { 2, 0}, { 2, 0}},
{{ 1, 0}, { 2, 0}, { 2, 0}, { 4, 0}},
{{ 1, 0}, { 2, 0}, { 2, 2}, { 2, 2}}, // 5
{{ 2, 0}, { 4, 0}, { 4, 0}, { 4, 0}},
{{ 2, 0}, { 4, 0}, { 2, 4}, { 4, 1}},
{{ 2, 0}, { 2, 2}, { 4, 2}, { 4, 2}},
{{ 2, 0}, { 3, 2}, { 4, 4}, { 4, 4}},
{{ 2, 2}, { 4, 1}, { 6, 2}, { 6, 2}}, //10
{{ 4, 0}, { 1, 4}, { 4, 4}, { 3, 8}},
{{ 2, 2}, { 6, 2}, { 4, 6}, { 7, 4}},
{{ 4, 0}, { 8, 1}, { 8, 4}, {12, 4}},
{{ 3, 1}, { 4, 5}, {11, 5}, {11, 5}},
{{ 5, 1}, { 5, 5}, { 5, 7}, {11, 7}}, //15
{{ 5, 1}, { 7, 3}, {15, 2}, { 3, 13}},
{{ 1, 5}, {10, 1}, { 1, 15}, { 2, 17}},
{{ 5, 1}, { 9, 4}, {17, 1}, { 2, 19}},
{{ 3, 4}, { 3, 11}, {17, 4}, { 9, 16}},
{{ 3, 5}, { 3, 13}, {15, 5}, {15, 10}}, //20
{{ 4, 4}, {17, 0}, {17, 6}, {19, 6}},
{{ 2, 7}, {17, 0}, { 7, 16}, {34, 0}},
{{ 4, 5}, { 4, 14}, {11, 14}, {16, 14}},
{{ 6, 4}, { 6, 14}, {11, 16}, {30, 2}},
{{ 8, 4}, { 8, 13}, { 7, 22}, {22, 13}}, //25
{{10, 2}, {19, 4}, {28, 6}, {33, 4}},
{{ 8, 4}, {22, 3}, { 8, 26}, {12, 28}},
{{ 3, 10}, { 3, 23}, { 4, 31}, {11, 31}},
{{ 7, 7}, {21, 7}, { 1, 37}, {19, 26}},
{{ 5, 10}, {19, 10}, {15, 25}, {23, 25}}, //30
{{13, 3}, { 2, 29}, {42, 1}, {23, 28}},
{{17, 0}, {10, 23}, {10, 35}, {19, 35}},
{{17, 1}, {14, 21}, {29, 19}, {11, 46}},
{{13, 6}, {14, 23}, {44, 7}, {59, 1}},
{{12, 7}, {12, 26}, {39, 14}, {22, 41}}, //35
{{ 6, 14}, { 6, 34}, {46, 10}, { 2, 64}},
{{17, 4}, {29, 14}, {49, 10}, {24, 46}},
{{ 4, 18}, {13, 32}, {48, 14}, {42, 32}},
{{20, 4}, {40, 7}, {43, 22}, {10, 67}},
{{19, 6}, {18, 31}, {34, 34}, {20, 61}},//40
};
void QRspec_getEccSpec(int version, QRecLevel level, int spec[5])
{
int b1, b2;
int data, ecc;
b1 = eccTable[version][level][0];
b2 = eccTable[version][level][1];
data = QRspec_getDataLength(version, level);
ecc = QRspec_getECCLength(version, level);
if(b2 == 0) {
spec[0] = b1;
spec[1] = data / b1;
spec[2] = ecc / b1;
spec[3] = spec[4] = 0;
} else {
spec[0] = b1;
spec[1] = data / (b1 + b2);
spec[2] = ecc / (b1 + b2);
spec[3] = b2;
spec[4] = spec[1] + 1;
}
}
/******************************************************************************
* Alignment pattern
*****************************************************************************/
/**
* Positions of alignment patterns.
* This array includes only the second and the third position of the alignment
* patterns. Rest of them can be calculated from the distance between them.
*
* See Table 1 in Appendix E (pp.71) of JIS X0510:2004.
*/
static const int alignmentPattern[QRSPEC_VERSION_MAX+1][2] = {
{ 0, 0},
{ 0, 0}, {18, 0}, {22, 0}, {26, 0}, {30, 0}, // 1- 5
{34, 0}, {22, 38}, {24, 42}, {26, 46}, {28, 50}, // 6-10
{30, 54}, {32, 58}, {34, 62}, {26, 46}, {26, 48}, //11-15
{26, 50}, {30, 54}, {30, 56}, {30, 58}, {34, 62}, //16-20
{28, 50}, {26, 50}, {30, 54}, {28, 54}, {32, 58}, //21-25
{30, 58}, {34, 62}, {26, 50}, {30, 54}, {26, 52}, //26-30
{30, 56}, {34, 60}, {30, 58}, {34, 62}, {30, 54}, //31-35
{24, 50}, {28, 54}, {32, 58}, {26, 54}, {30, 58}, //35-40
};
/**
* Put an alignment marker.
* @param frame
* @param width
* @param ox,oy center coordinate of the pattern
*/
static void QRspec_putAlignmentMarker(unsigned char *frame, int width, int ox, int oy)
{
static const unsigned char finder[] = {
0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
0xa1, 0xa0, 0xa0, 0xa0, 0xa1,
0xa1, 0xa0, 0xa1, 0xa0, 0xa1,
0xa1, 0xa0, 0xa0, 0xa0, 0xa1,
0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
};
int x, y;
const unsigned char *s;
frame += (oy - 2) * width + ox - 2;
s = finder;
for(y = 0; y < 5; y++) {
for(x = 0; x < 5; x++) {
frame[x] = s[x];
}
frame += width;
s += 5;
}
}
static void QRspec_putAlignmentPattern(int version, unsigned char *frame, int width)
{
int d, w, x, y, cx, cy;
if(version < 2) return;
d = alignmentPattern[version][1] - alignmentPattern[version][0];
if(d < 0) {
w = 2;
} else {
w = (width - alignmentPattern[version][0]) / d + 2;
}
if(w * w - 3 == 1) {
x = alignmentPattern[version][0];
y = alignmentPattern[version][0];
QRspec_putAlignmentMarker(frame, width, x, y);
return;
}
cx = alignmentPattern[version][0];
for(x = 1; x < w - 1; x++) {
QRspec_putAlignmentMarker(frame, width, 6, cx);
QRspec_putAlignmentMarker(frame, width, cx, 6);
cx += d;
}
cy = alignmentPattern[version][0];
for(y = 0; y < w-1; y++) {
cx = alignmentPattern[version][0];
for(x = 0; x < w-1; x++) {
QRspec_putAlignmentMarker(frame, width, cx, cy);
cx += d;
}
cy += d;
}
}
/******************************************************************************
* Version information pattern
*****************************************************************************/
/**
* Version information pattern (BCH coded).
* See Table 1 in Appendix D (pp.68) of JIS X0510:2004.
*/
static const unsigned int versionPattern[QRSPEC_VERSION_MAX - 6] = {
0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
0x27541, 0x28c69
};
unsigned int QRspec_getVersionPattern(int version)
{
if(version < 7 || version > QRSPEC_VERSION_MAX) return 0;
return versionPattern[version - 7];
}
/******************************************************************************
* Format information
*****************************************************************************/
/* See calcFormatInfo in tests/test_qrspec.c */
static const unsigned int formatInfo[4][8] = {
{0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976},
{0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0},
{0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed},
{0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b}
};
unsigned int QRspec_getFormatInfo(int mask, QRecLevel level)
{
if(mask < 0 || mask > 7) return 0;
return formatInfo[level][mask];
}
/******************************************************************************
* Frame
*****************************************************************************/
/**
* Put a finder pattern.
* @param frame
* @param width
* @param ox,oy upper-left coordinate of the pattern
*/
static void putFinderPattern(unsigned char *frame, int width, int ox, int oy)
{
static const unsigned char finder[] = {
0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
0xc1, 0xc0, 0xc1, 0xc1, 0xc1, 0xc0, 0xc1,
0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1,
0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
};
int x, y;
const unsigned char *s;
frame += oy * width + ox;
s = finder;
for(y = 0; y < 7; y++) {
for(x = 0; x < 7; x++) {
frame[x] = s[x];
}
frame += width;
s += 7;
}
}
static unsigned char *QRspec_createFrame(int version)
{
unsigned char *frame, *p, *q;
int width;
int x, y;
unsigned int verinfo, v;
width = qrspecCapacity[version].width;
frame = (unsigned char *)malloc((size_t)(width * width));
if(frame == NULL) return NULL;
memset(frame, 0, (size_t)(width * width));
/* Finder pattern */
putFinderPattern(frame, width, 0, 0);
putFinderPattern(frame, width, width - 7, 0);
putFinderPattern(frame, width, 0, width - 7);
/* Separator */
p = frame;
q = frame + width * (width - 7);
for(y = 0; y < 7; y++) {
p[7] = 0xc0;
p[width - 8] = 0xc0;
q[7] = 0xc0;
p += width;
q += width;
}
memset(frame + width * 7, 0xc0, 8);
memset(frame + width * 8 - 8, 0xc0, 8);
memset(frame + width * (width - 8), 0xc0, 8);
/* Mask format information area */
memset(frame + width * 8, 0x84, 9);
memset(frame + width * 9 - 8, 0x84, 8);
p = frame + 8;
for(y = 0; y < 8; y++) {
*p = 0x84;
p += width;
}
p = frame + width * (width - 7) + 8;
for(y = 0; y < 7; y++) {
*p = 0x84;
p += width;
}
/* Timing pattern */
p = frame + width * 6 + 8;
q = frame + width * 8 + 6;
for(x = 1; x < width-15; x++) {
*p = 0x90 | (x & 1);
*q = 0x90 | (x & 1);
p++;
q += width;
}
/* Alignment pattern */
QRspec_putAlignmentPattern(version, frame, width);
/* Version information */
if(version >= 7) {
verinfo = QRspec_getVersionPattern(version);
p = frame + width * (width - 11);
v = verinfo;
for(x = 0; x < 6; x++) {
for(y = 0; y < 3; y++) {
p[width * y + x] = 0x88 | (v & 1);
v = v >> 1;
}
}
p = frame + width - 11;
v = verinfo;
for(y = 0; y < 6; y++) {
for(x = 0; x < 3; x++) {
p[x] = 0x88 | (v & 1);
v = v >> 1;
}
p += width;
}
}
/* and a little bit... */
frame[width * (width - 8) + 8] = 0x81;
return frame;
}
unsigned char *QRspec_newFrame(int version)
{
if(version < 1 || version > QRSPEC_VERSION_MAX) return NULL;
return QRspec_createFrame(version);
}

174
datafile/qrencode/qrspec.h Normal file
View File

@ -0,0 +1,174 @@
/*
* qrencode - QR Code encoder
*
* QR Code specification in convenient format.
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef QRSPEC_H
#define QRSPEC_H
#include "qrencode.h"
/******************************************************************************
* Version and capacity
*****************************************************************************/
/**
* Maximum width of a symbol
*/
#define QRSPEC_WIDTH_MAX 177
/**
* Return maximum data code length (bytes) for the version.
* @param version version of the symbol
* @param level error correction level
* @return maximum size (bytes)
*/
extern int QRspec_getDataLength(int version, QRecLevel level);
/**
* Return maximum error correction code length (bytes) for the version.
* @param version version of the symbol
* @param level error correction level
* @return ECC size (bytes)
*/
extern int QRspec_getECCLength(int version, QRecLevel level);
/**
* Return a version number that satisfies the input code length.
* @param size input code length (byte)
* @param level error correction level
* @return version number
*/
extern int QRspec_getMinimumVersion(int size, QRecLevel level);
/**
* Return the width of the symbol for the version.
* @param version vesion of the symbol
* @return width of the symbol
*/
extern int QRspec_getWidth(int version);
/**
* Return the numer of remainder bits.
* @param version vesion of the symbol
* @return number of remainder bits
*/
extern int QRspec_getRemainder(int version);
/******************************************************************************
* Length indicator
*****************************************************************************/
/**
* Return the size of length indicator for the mode and version.
* @param mode encode mode
* @param version vesion of the symbol
* @return the size of the appropriate length indicator (bits).
*/
extern int QRspec_lengthIndicator(QRencodeMode mode, int version);
/**
* Return the maximum length for the mode and version.
* @param mode encode mode
* @param version vesion of the symbol
* @return the maximum length (bytes)
*/
extern int QRspec_maximumWords(QRencodeMode mode, int version);
/******************************************************************************
* Error correction code
*****************************************************************************/
/**
* Return an array of ECC specification.
* @param version version of the symbol
* @param level error correction level
* @param spec an array of ECC specification contains as following:
* {# of type1 blocks, # of data code, # of ecc code,
* # of type2 blocks, # of data code}
*/
void QRspec_getEccSpec(int version, QRecLevel level, int spec[5]);
#define QRspec_rsBlockNum(__spec__) (__spec__[0] + __spec__[3])
#define QRspec_rsBlockNum1(__spec__) (__spec__[0])
#define QRspec_rsDataCodes1(__spec__) (__spec__[1])
#define QRspec_rsEccCodes1(__spec__) (__spec__[2])
#define QRspec_rsBlockNum2(__spec__) (__spec__[3])
#define QRspec_rsDataCodes2(__spec__) (__spec__[4])
#define QRspec_rsEccCodes2(__spec__) (__spec__[2])
#define QRspec_rsDataLength(__spec__) \
((QRspec_rsBlockNum1(__spec__) * QRspec_rsDataCodes1(__spec__)) + \
(QRspec_rsBlockNum2(__spec__) * QRspec_rsDataCodes2(__spec__)))
#define QRspec_rsEccLength(__spec__) \
(QRspec_rsBlockNum(__spec__) * QRspec_rsEccCodes1(__spec__))
/******************************************************************************
* Version information pattern
*****************************************************************************/
/**
* Return BCH encoded version information pattern that is used for the symbol
* of version 7 or greater. Use lower 18 bits.
* @param version version of the symbol
* @return BCH encoded version information pattern
*/
extern unsigned int QRspec_getVersionPattern(int version);
/******************************************************************************
* Format information
*****************************************************************************/
/**
* Return BCH encoded format information pattern.
* @param mask mask number
* @param level error correction level
* @return BCH encoded format information pattern
*/
extern unsigned int QRspec_getFormatInfo(int mask, QRecLevel level);
/******************************************************************************
* Frame
*****************************************************************************/
/**
* Return a copy of initialized frame.
* @param version version of the symbol
* @return Array of unsigned char. You can free it by free().
*/
extern unsigned char *QRspec_newFrame(int version);
/******************************************************************************
* Mode indicator
*****************************************************************************/
/**
* Mode indicator. See Table 2 of JIS X0510:2004, pp.16.
*/
#define QRSPEC_MODEID_ECI 7
#define QRSPEC_MODEID_NUM 1
#define QRSPEC_MODEID_AN 2
#define QRSPEC_MODEID_8 4
#define QRSPEC_MODEID_KANJI 8
#define QRSPEC_MODEID_FNC1FIRST 5
#define QRSPEC_MODEID_FNC1SECOND 9
#define QRSPEC_MODEID_STRUCTURE 3
#define QRSPEC_MODEID_TERMINATOR 0
#endif /* QRSPEC_H */

149
datafile/qrencode/rsecc.c Normal file
View File

@ -0,0 +1,149 @@
/*
* qrencode - QR Code encoder
*
* Reed solomon error correction code encoder specialized for QR code.
* This code is rewritten by Kentaro Fukuchi, referring to the FEC library
* developed by Phil Karn (KA9Q).
*
* Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
* Copyright (C) 2014-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#if HAVE_LIBPTHREAD
#include <pthread.h>
#endif
#include "rsecc.h"
#if HAVE_LIBPTHREAD
static pthread_mutex_t RSECC_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
static int initialized = 0;
#define SYMBOL_SIZE (8)
#define symbols ((1U << SYMBOL_SIZE) - 1)
static const unsigned int proot = 0x11d; /* stands for x^8+x^4+x^3+x^2+1 (see pp.37 of JIS X0510:2004) */
/* min/max codeword length of ECC, calculated from the specification. */
#define min_length (2)
#define max_length (30)
#define max_generatorSize (max_length)
static unsigned char alpha[symbols + 1];
static unsigned char aindex[symbols + 1];
static unsigned char generator[max_length - min_length + 1][max_generatorSize + 1];
static unsigned char generatorInitialized[max_length - min_length + 1];
static void RSECC_initLookupTable(void)
{
unsigned int i, b;
alpha[symbols] = 0;
aindex[0] = symbols;
b = 1;
for(i = 0; i < symbols; i++) {
alpha[i] = b;
aindex[b] = i;
b <<= 1;
if(b & (symbols + 1)) {
b ^= proot;
}
b &= symbols;
}
}
static void RSECC_init(void)
{
RSECC_initLookupTable();
memset(generatorInitialized, 0, (max_length - min_length + 1));
initialized = 1;
}
static void generator_init(size_t length)
{
size_t i, j;
int g[max_generatorSize + 1];
g[0] = 1;
for(i = 0; i < length; i++) {
g[i + 1] = 1;
/* Because g[0] never be zero, skipped some conditional checks. */
for(j = i; j > 0; j--) {
g[j] = g[j - 1] ^ alpha[(aindex[g[j]] + i) % symbols];
}
g[0] = alpha[(aindex[g[0]] + i) % symbols];
}
for(i = 0; i <= length; i++) {
generator[length - min_length][i] = aindex[g[i]];
}
generatorInitialized[length - min_length] = 1;
}
int RSECC_encode(size_t data_length, size_t ecc_length, const unsigned char *data, unsigned char *ecc)
{
size_t i, j;
unsigned char feedback;
unsigned char *gen;
#if HAVE_LIBPTHREAD
pthread_mutex_lock(&RSECC_mutex);
#endif
if(!initialized) {
RSECC_init();
}
#if HAVE_LIBPTHREAD
pthread_mutex_unlock(&RSECC_mutex);
#endif
if(ecc_length > max_length) return -1;
memset(ecc, 0, ecc_length);
#if HAVE_LIBPTHREAD
pthread_mutex_lock(&RSECC_mutex);
#endif
if(!generatorInitialized[ecc_length - min_length]) generator_init(ecc_length);
#if HAVE_LIBPTHREAD
pthread_mutex_unlock(&RSECC_mutex);
#endif
gen = generator[ecc_length - min_length];
for(i = 0; i < data_length; i++) {
feedback = aindex[data[i] ^ ecc[0]];
if(feedback != symbols) {
for(j = 1; j < ecc_length; j++) {
ecc[j] ^= alpha[(unsigned int)(feedback + gen[ecc_length - j]) % symbols];
}
}
memmove(&ecc[0], &ecc[1], ecc_length - 1);
if(feedback != symbols) {
ecc[ecc_length - 1] = alpha[(unsigned int)(feedback + gen[0]) % symbols];
} else {
ecc[ecc_length - 1] = 0;
}
}
return 0;
}

31
datafile/qrencode/rsecc.h Normal file
View File

@ -0,0 +1,31 @@
/*
* qrencode - QR Code encoder
*
* Reed solomon error correction code encoder specialized for QR code.
* This code is rewritten by Kentaro Fukuchi, referring to the FEC library
* developed by Phil Karn (KA9Q).
*
* Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
* Copyright (C) 2014-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef RSECC_H
#define RSECC_H
extern int RSECC_encode(size_t data_length, size_t ecc_length, const unsigned char *data, unsigned char *ecc);
#endif /* RSECC_H */

323
datafile/qrencode/split.c Normal file
View File

@ -0,0 +1,323 @@
/*
* qrencode - QR Code encoder
*
* Input data splitter.
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* The following data / specifications are taken from
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
* or
* "Automatic identification and data capture techniques --
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "qrencode.h"
#include "qrinput.h"
#include "qrspec.h"
#include "split.h"
#define isdigit(__c__) ((unsigned char)((signed char)(__c__) - '0') < 10)
#define isalnum(__c__) (QRinput_lookAnTable(__c__) >= 0)
#if !HAVE_STRDUP
#undef strdup
char *strdup(const char *s)
{
size_t len = strlen(s) + 1;
void *newstring = malloc(len);
if(newstring == NULL) return NULL;
return (char *)memcpy(newstring, s, len);
}
#endif
static QRencodeMode Split_identifyMode(const char *string, QRencodeMode hint)
{
unsigned char c, d;
unsigned int word;
c = (unsigned char)string[0];
if(c == '\0') return QR_MODE_NUL;
if(isdigit(c)) {
return QR_MODE_NUM;
} else if(isalnum(c)) {
return QR_MODE_AN;
} else if(hint == QR_MODE_KANJI) {
d = (unsigned char)string[1];
if(d != '\0') {
word = ((unsigned int)c << 8) | d;
if((word >= 0x8140 && word <= 0x9ffc) || (word >= 0xe040 && word <= 0xebbf)) {
return QR_MODE_KANJI;
}
}
}
return QR_MODE_8;
}
static int Split_eatAn(const char *string, QRinput *input, QRencodeMode hint);
static int Split_eat8(const char *string, QRinput *input, QRencodeMode hint);
static int Split_eatNum(const char *string, QRinput *input,QRencodeMode hint)
{
const char *p;
int ret;
int run;
int dif;
int ln;
QRencodeMode mode;
ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version);
p = string;
while(isdigit(*p)) {
p++;
}
run = (int)(p - string);
mode = Split_identifyMode(p, hint);
if(mode == QR_MODE_8) {
dif = QRinput_estimateBitsModeNum(run) + 4 + ln
+ QRinput_estimateBitsMode8(1) /* + 4 + l8 */
- QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */;
if(dif > 0) {
return Split_eat8(string, input, hint);
}
}
if(mode == QR_MODE_AN) {
dif = QRinput_estimateBitsModeNum(run) + 4 + ln
+ QRinput_estimateBitsModeAn(1) /* + 4 + la */
- QRinput_estimateBitsModeAn(run + 1) /* - 4 - la */;
if(dif > 0) {
return Split_eatAn(string, input, hint);
}
}
ret = QRinput_append(input, QR_MODE_NUM, run, (unsigned char *)string);
if(ret < 0) return -1;
return run;
}
static int Split_eatAn(const char *string, QRinput *input, QRencodeMode hint)
{
const char *p, *q;
int ret;
int run;
int dif;
int la, ln;
la = QRspec_lengthIndicator(QR_MODE_AN, input->version);
ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version);
p = string;
while(isalnum(*p)) {
if(isdigit(*p)) {
q = p;
while(isdigit(*q)) {
q++;
}
dif = QRinput_estimateBitsModeAn((int)(p - string)) /* + 4 + la */
+ QRinput_estimateBitsModeNum((int)(q - p)) + 4 + ln
+ (isalnum(*q)?(4 + ln):0)
- QRinput_estimateBitsModeAn((int)(q - string)) /* - 4 - la */;
if(dif < 0) {
break;
}
p = q;
} else {
p++;
}
}
run = (int)(p - string);
if(*p && !isalnum(*p)) {
dif = QRinput_estimateBitsModeAn(run) + 4 + la
+ QRinput_estimateBitsMode8(1) /* + 4 + l8 */
- QRinput_estimateBitsMode8(run + 1) /* - 4 - l8 */;
if(dif > 0) {
return Split_eat8(string, input, hint);
}
}
ret = QRinput_append(input, QR_MODE_AN, run, (unsigned char *)string);
if(ret < 0) return -1;
return run;
}
static int Split_eatKanji(const char *string, QRinput *input, QRencodeMode hint)
{
const char *p;
int ret;
int run;
p = string;
while(Split_identifyMode(p, hint) == QR_MODE_KANJI) {
p += 2;
}
run = (int)(p - string);
ret = QRinput_append(input, QR_MODE_KANJI, run, (unsigned char *)string);
if(ret < 0) return -1;
return run;
}
static int Split_eat8(const char *string, QRinput *input, QRencodeMode hint)
{
const char *p, *q;
QRencodeMode mode;
int ret;
int run;
int dif;
int la, ln, l8;
int swcost;
la = QRspec_lengthIndicator(QR_MODE_AN, input->version);
ln = QRspec_lengthIndicator(QR_MODE_NUM, input->version);
l8 = QRspec_lengthIndicator(QR_MODE_8, input->version);
p = string + 1;
while(*p != '\0') {
mode = Split_identifyMode(p, hint);
if(mode == QR_MODE_KANJI) {
break;
}
if(mode == QR_MODE_NUM) {
q = p;
while(isdigit(*q)) {
q++;
}
if(Split_identifyMode(q, hint) == QR_MODE_8) {
swcost = 4 + l8;
} else {
swcost = 0;
}
dif = QRinput_estimateBitsMode8((int)(p - string)) /* + 4 + l8 */
+ QRinput_estimateBitsModeNum((int)(q - p)) + 4 + ln
+ swcost
- QRinput_estimateBitsMode8((int)(q - string)) /* - 4 - l8 */;
if(dif < 0) {
break;
}
p = q;
} else if(mode == QR_MODE_AN) {
q = p;
while(isalnum(*q)) {
q++;
}
if(Split_identifyMode(q, hint) == QR_MODE_8) {
swcost = 4 + l8;
} else {
swcost = 0;
}
dif = QRinput_estimateBitsMode8((int)(p - string)) /* + 4 + l8 */
+ QRinput_estimateBitsModeAn((int)(q - p)) + 4 + la
+ swcost
- QRinput_estimateBitsMode8((int)(q - string)) /* - 4 - l8 */;
if(dif < 0) {
break;
}
p = q;
} else {
p++;
}
}
run = (int)(p - string);
ret = QRinput_append(input, QR_MODE_8, run, (unsigned char *)string);
if(ret < 0) return -1;
return run;
}
static int Split_splitString(const char *string, QRinput *input,
QRencodeMode hint)
{
int length;
QRencodeMode mode;
while(*string != '\0') {
mode = Split_identifyMode(string, hint);
if(mode == QR_MODE_NUM) {
length = Split_eatNum(string, input, hint);
} else if(mode == QR_MODE_AN) {
length = Split_eatAn(string, input, hint);
} else if(mode == QR_MODE_KANJI && hint == QR_MODE_KANJI) {
length = Split_eatKanji(string, input, hint);
} else {
length = Split_eat8(string, input, hint);
}
if(length == 0) break;
if(length < 0) return -1;
string += length;
}
return 0;
}
static char *dupAndToUpper(const char *str, QRencodeMode hint)
{
char *newstr, *p;
QRencodeMode mode;
newstr = strdup(str);
if(newstr == NULL) return NULL;
p = newstr;
while(*p != '\0') {
mode = Split_identifyMode(p, hint);
if(mode == QR_MODE_KANJI) {
p += 2;
} else {
if (*p >= 'a' && *p <= 'z') {
*p = (char)((int)*p - 32);
}
p++;
}
}
return newstr;
}
int Split_splitStringToQRinput(const char *string, QRinput *input,
QRencodeMode hint, int casesensitive)
{
char *newstr;
int ret;
if(string == NULL || *string == '\0') {
errno = EINVAL;
return -1;
}
if(!casesensitive) {
newstr = dupAndToUpper(string, hint);
if(newstr == NULL) return -1;
ret = Split_splitString(newstr, input, hint);
free(newstr);
} else {
ret = Split_splitString(string, input, hint);
}
return ret;
}

47
datafile/qrencode/split.h Normal file
View File

@ -0,0 +1,47 @@
/*
* qrencode - QR Code encoder
*
* Input data splitter.
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* The following data / specifications are taken from
* "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
* or
* "Automatic identification and data capture techniques --
* QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef SPLIT_H
#define SPLIT_H
#include "qrencode.h"
/**
* Split the input string (null terminated) into QRinput.
* @param string input string
* @param hint give QR_MODE_KANJI if the input string contains Kanji character encoded in Shift-JIS. If not, give QR_MODE_8.
* @param casesensitive 0 for case-insensitive encoding (all alphabet characters are replaced to UPPER-CASE CHARACTERS.
* @retval 0 success.
* @retval -1 an error occurred. errno is set to indicate the error. See
* Exceptions for the details.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory for input objects.
*/
extern int Split_splitStringToQRinput(const char *string, QRinput *input,
QRencodeMode hint, int casesensitive);
#endif /* SPLIT_H */

View File

@ -0,0 +1,261 @@
#include "mygraphicsitem.h"
MyGraphicsItem::MyGraphicsItem()
{
m_point.setX(0);
m_point.setY(0);
//使item可以被选择
//this->setFlag(QGraphicsItem::ItemIsSelectable);
//使item可以移动
//this->setFlag(QGraphicsItem::ItemIsMovable);
//item可以响应鼠标事件
//this->setAcceptHoverEvents(true);
}
MyGraphicsItem::~MyGraphicsItem()
{
}
void MyGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
return QGraphicsItem::mousePressEvent(event);
}
void MyGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
return QGraphicsItem::mouseMoveEvent(event);
}
void MyGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
return QGraphicsItem::mouseReleaseEvent(event);
}
QPicture MyGraphicsItem::getPicture(Marker marker,int penWidth)
{
if(penWidth != 1)
{
QPicture pic;
CBitmapInfo bitmapInfo;
QPainterPath painterPath;
QRect rect = marker.GetRect();
int minX = rect.left();
int minY = rect.top();
int maxY = rect.bottom();
int nLineCount = marker.m_listPolyline.size();
for(int i = 0; i < nLineCount; i++)
{
CRPPolyline polyLine = marker.m_listPolyline.at(i);
int type = polyLine.m_nDrawingType;
if(type == 0)//直线
{
int nPointCount = polyLine.m_listPoint.size();
for(int j = 0; j < nPointCount; j++)
{
double x = (polyLine.m_listPoint.at(j).x() - minX)/(double)M_IDPMM*MMPIXELY;
double y = ((0 - (polyLine.m_listPoint.at(j).y() - minY))+(maxY-minY))/(double)M_IDPMM*MMPIXELY;
QPointF point(x,y);
if(j == 0)
{
painterPath.moveTo(point);
}
else
{
painterPath.lineTo(point);
}
}
}
else if(type == 1)//位图
{
bitmapInfo = polyLine.m_bitmapInfo;
int x = bitmapInfo.m_ptAbPostLU.x();
int y = bitmapInfo.m_ptAbPostLU.y();
int nx = (x - minX)/M_IDPMM*MMPIXELY;
int ny = ((0 - (y - minY))+(maxY-minY))/M_IDPMM*MMPIXELY;
bitmapInfo.m_ptAbPostLU.setX(nx);
bitmapInfo.m_ptAbPostLU.setY(ny);
}
}
if(painterPath.isEmpty())
{
qDebug()<<"painterPath isEmpty";
}
//将路径画在picture上
QPen pen;
pen.setWidth(penWidth);//设置笔号
pen.setColor(QColor(Qt::black));
QPainter painter;
painter.begin(&pic);
painter.setPen(pen);
painter.drawPath(painterPath);
if(bitmapInfo.m_iBytes > 0)//有位图
{
painter.drawPixmap(bitmapInfo.m_ptAbPostLU.x(),bitmapInfo.m_ptAbPostLU.y(),bitmapInfo.m_pBitmap);
}
painter.end();
return pic;
}
return m_picture;
}
void MyGraphicsItem::setPicture(QPicture pic)
{
m_picture = pic;
// 外矩形
m_boundingRect = m_picture.boundingRect();
update();
}
void MyGraphicsItem::reflushBlockPos(QPoint p)
{
m_point = p;
m_blockPixmap = QPixmap(PIXMAPWIDTH,m_picture.height());
m_blockPixmap.fill(Qt::transparent);//透明色
if(m_point.x() >= 0 && m_point.y() >= 0)
{
QPainter painter(&m_blockPixmap);
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.fillRect(m_blockPixmap.rect(), QColor(0, 0, 0, 80));
painter.end();
}
update();
}
QRectF MyGraphicsItem::boundingRect() const
{
return m_boundingRect;
}
void MyGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
QPen pen;
QBrush brush;
brush.setStyle(Qt::SolidPattern);
pen.setWidth(1);
double scaleFactor = painter->matrix().m11();
double width = pen.width()/scaleFactor;
pen.setWidthF(width); // 线段保持原来的线宽
pen.setColor(QColor(Qt::black));
brush.setColor(QColor(255,255,255));
painter->setPen(pen);
painter->setBrush(brush);
//防锯齿,效果不好,所以注释掉
// painter->setRenderHint(QPainter::Antialiasing, true);
// painter->setRenderHint(QPainter::SmoothPixmapTransform, true);
painter->drawPicture(0,0,m_picture);
painter->drawPixmap(m_point.x(),m_point.y(),m_blockPixmap);
}
void MyGraphicsItem::creatPicture(Marker marker)
{
CBitmapInfo bitmapInfo;
QPainterPath painterPath;
QRect rect = marker.GetRect();
int minX = rect.left();
int minY = rect.top();
int maxY = rect.bottom();
int nLineCount = marker.m_listPolyline.size();
for(int i = 0; i < nLineCount; i++)
{
CRPPolyline polyLine = marker.m_listPolyline.at(i);
int type = polyLine.m_nDrawingType;
// if(polyLine.m_nDrawingType == 3)//文字
// {
// CRPText text = polyLine.m_text;
// }
if(type == 0)//直线
{
int nPointCount = polyLine.m_listPoint.size();
for(int j = 0; j < nPointCount; j++)
{
double x = (polyLine.m_listPoint.at(j).x() - minX)/(double)M_IDPMM*MMPIXELY;
double y = ((0 - (polyLine.m_listPoint.at(j).y() - minY))+(maxY-minY))/(double)M_IDPMM*MMPIXELY;
QPointF point(x,y);
if(j == 0)
{
painterPath.moveTo(point);
}
else
{
painterPath.lineTo(point);
}
}
}
else if(type == 1)//位图
{
bitmapInfo = polyLine.m_bitmapInfo;
int x = bitmapInfo.m_ptAbPostLU.x();
int y = bitmapInfo.m_ptAbPostLU.y();
int nx = (x - minX)/M_IDPMM*MMPIXELY;
int ny = ((0 - (y - minY))+(maxY-minY))/M_IDPMM*MMPIXELY;
bitmapInfo.m_ptAbPostLU.setX(nx);
bitmapInfo.m_ptAbPostLU.setY(ny);
}
}
if(painterPath.isEmpty())
{
qDebug()<<"painterPath.isEmpty";
}
//将路径画在picture上
QPicture pic;
QPen pen;
pen.setWidth(1);//设置笔号
pen.setColor(QColor(Qt::black));
QPainter painter;
painter.begin(&pic);
painter.setPen(pen);
painter.drawPath(painterPath);
if(bitmapInfo.m_iBytes > 0)//有位图
{
//bitmapInfo.m_pBitmap.save("D:\\1.bmp");
painter.drawPixmap(bitmapInfo.m_ptAbPostLU.x(),bitmapInfo.m_ptAbPostLU.y(),bitmapInfo.m_pBitmap);
}
painter.end();
m_picture = pic;
// 外矩形
m_boundingRect = m_picture.boundingRect();
}
void MyGraphicsItem::creatPicture(QPixmap pixmap)
{
//将图片画在picture上
QPicture pic;
QPen pen;
pen.setWidth(1);//设置笔号
pen.setColor(QColor(Qt::black));
QPainter painter;
painter.begin(&pic);
painter.setPen(pen);
painter.drawPixmap(0,0,pixmap);
painter.end();
m_picture = pic;
// 外矩形
m_boundingRect = m_picture.boundingRect();
}

View File

@ -0,0 +1,54 @@
#ifndef MYGRAPHICSITEM_H
#define MYGRAPHICSITEM_H
#include <QObject>
#include <QPainter>
#include <QGraphicsItem>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPixmap>
#include <QPicture>
#include <QList>
#include <QtGui>
#include "machine/bmp/creatprintbmp.h"
#include "datafile/hpgl/importhpgl.h"
class MyGraphicsItem : public QObject, public QGraphicsItem
{
Q_OBJECT
Q_INTERFACES(QGraphicsItem) //通知要实现的类构成何种界面的宏
public:
MyGraphicsItem();
~MyGraphicsItem();
//绘图区域
QRectF boundingRect() const;
//绘制按钮图像的函数
void paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget = 0);
void creatPicture(Marker marker);
void creatPicture(QPixmap pixmap);
protected: //事件
void mousePressEvent(QGraphicsSceneMouseEvent* event);
void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
private:
QPicture m_picture;
QPixmap m_blockPixmap;
QPoint m_point;
QRectF m_boundingRect;//返回形状
public:
QPicture getPicture(Marker marker,int penWidth = 1);
void setPicture(QPicture pic);
void reflushBlockPos(QPoint p);//更显打印块位置
public slots:
};
#endif // MYGRAPHICSITEM_H

View File

@ -0,0 +1,85 @@
#include "mygraphicsscene.h"
MyGraphicsScene::MyGraphicsScene()
{
m_myGraphicsItem= new MyGraphicsItem();
}
MyGraphicsScene::~MyGraphicsScene()
{
if(m_myGraphicsItem != NULL)
{
delete m_myGraphicsItem;
m_myGraphicsItem = NULL;
}
}
void MyGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
return QGraphicsScene::mousePressEvent(mouseEvent);
}
void MyGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
return QGraphicsScene::mouseMoveEvent(mouseEvent);
}
void MyGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
return QGraphicsScene::mouseReleaseEvent(mouseEvent);
}
void MyGraphicsScene::createScene(Marker marker)
{
m_myGraphicsItem->creatPicture(marker);
//绘制留边
this->setSceneRect(0,0,m_myGraphicsItem->boundingRect().width()+DRAWMARGINS,m_myGraphicsItem->boundingRect().height()+DRAWMARGINS);
//如果scene未超过graphicsView的范围图形就是居中显示的
this->addItem(m_myGraphicsItem);
m_myGraphicsItem->moveBy(DRAWMARGINS/2.0,DRAWMARGINS/2.0);//item居中显示
}
void MyGraphicsScene::createScene(QPixmap pixmap)
{
m_myGraphicsItem->creatPicture(pixmap);
//绘制留边
this->setSceneRect(0,0,m_myGraphicsItem->boundingRect().width()+DRAWMARGINS,m_myGraphicsItem->boundingRect().height()+DRAWMARGINS);
//如果scene未超过graphicsView的范围图形就是居中显示的
this->addItem(m_myGraphicsItem);
m_myGraphicsItem->moveBy(DRAWMARGINS/2.0,DRAWMARGINS/2.0);//item居中显示
}
void MyGraphicsScene::cleanScene()
{
if(m_myGraphicsItem != NULL)
{
this->removeItem(m_myGraphicsItem);
}
}
QPicture MyGraphicsScene::getPicture(Marker marker,int penWidth)
{
QPicture pic;
if(m_myGraphicsItem != NULL)
{
pic = m_myGraphicsItem->getPicture(marker,penWidth);
}
return pic;
}
void MyGraphicsScene::swithScene(QPicture pic)
{
if(m_myGraphicsItem != NULL)
{
m_myGraphicsItem->setPicture(pic);
this->addItem(m_myGraphicsItem);
}
}
void MyGraphicsScene::ReflushBlockScene(QPoint p)
{
if(m_myGraphicsItem != NULL)
{
m_myGraphicsItem->reflushBlockPos(p);
}
}

View File

@ -0,0 +1,38 @@
#ifndef MYGRAPHICSSCENE_H
#define MYGRAPHICSSCENE_H
#include <QObject>
#include <QGraphicsScene>
#include "datafile/view/mygraphicsitem.h"
#define DRAWMARGINS 200.0 //item在场景中绘制时的边距(留边)
class MyGraphicsScene: public QGraphicsScene
{
Q_OBJECT
public:
MyGraphicsScene();
~MyGraphicsScene();
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
private:
MyGraphicsItem *m_myGraphicsItem;
public:
void createScene(Marker marker);
void createScene(QPixmap pixmap);
void cleanScene();
QPicture getPicture(Marker marker,int penWidth = 1);
void swithScene(QPicture pic);
void ReflushBlockScene(QPoint p);
signals:
public slots:
};
#endif // MYGRAPHICSSCENE_H

View File

@ -0,0 +1,240 @@
#include "mygraphicsview.h"
MyGraphicsView::MyGraphicsView()
{
m_viewSize = this->size();
m_scene = new MyGraphicsScene();
this->setScene(m_scene);
setMouseTracking(true); // 跟踪鼠标位置
// this->setRenderHint(QPainter::Antialiasing, true);
// this->setRenderHint(QPainter::SmoothPixmapTransform, true);//防锯齿
}
MyGraphicsView::~MyGraphicsView()
{
if(m_scene != NULL)
{
delete m_scene;
m_scene = NULL;
}
}
void MyGraphicsView::resizeEvent(QResizeEvent *event)
{
if(event == NULL){}//为了去掉警告
if(m_scene != NULL && m_viewSize != this->size())
{
QRectF rectItem = m_scene->itemsBoundingRect();
this->setScene(m_scene);
this->fitInView(rectItem, Qt::KeepAspectRatio);
}
m_viewSize = this->size();
}
void MyGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
{
qreal scaleFactor = this->matrix().m11();
if(scaleFactor >= 20){return;}
if(event->button() == Qt::LeftButton &&
event->type() == QEvent::MouseButtonDblClick)
{
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
scale(2.0, 2.0);
}
if(event->button() == Qt::RightButton &&
event->type() == QEvent::MouseButtonDblClick)
{
QRectF rectItem = m_scene->itemsBoundingRect();
this->fitInView(rectItem, Qt::KeepAspectRatio);
}
}
void MyGraphicsView::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
{
setDragMode(QGraphicsView::RubberBandDrag);
m_leftBtnPressed = true;
m_startPoint = m_endPoint = event->pos();
}
else
{
setDragMode(QGraphicsView::NoDrag);
}
if(event->button() == Qt::RightButton)
{
m_startPoint = event->pos();
m_rightBtnPressed = true;
}
QGraphicsView::mousePressEvent(event);
}
//恢复原状
void MyGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
{
m_leftBtnPressed = false;
if(m_startPoint.x() == m_endPoint.x() || m_startPoint.y() == m_endPoint.y())
{
return;
}
double cx = (m_endPoint.x() + m_startPoint.x()) / 2.0;
double cy = (m_endPoint.y() + m_startPoint.y()) / 2.0;
// 获取当前鼠标相对于scene的位置;
QPointF scenePos = this->mapToScene(QPoint(cx,cy));
// 获取view的宽高;
qreal viewWidth = this->viewport()->width();
qreal viewHeight = this->viewport()->height();
// 获取当前鼠标位置相当于view大小的横纵比例;
qreal hScale = cx / viewWidth;
qreal vScale = cy / viewHeight;
this->scale(2.0, 2.0);
// 将scene坐标转换为放大缩小后的坐标;
QPointF viewPoint = this->matrix().map(scenePos);
// 通过滚动条控制view放大缩小后的展示scene的位置;
horizontalScrollBar()->setValue(int(viewPoint.x() - viewWidth * hScale));
verticalScrollBar()->setValue(int(viewPoint.y() - viewHeight * vScale));
}
if(event->button() == Qt::RightButton)
{
m_rightBtnPressed = false;
}
}
void MyGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
//QGraphicsView坐标
QPoint viewPoint = event->pos();
//QGraphicsScene坐标
QPointF scenePoint = mapToScene(viewPoint);
double x = scenePoint.x() / MMPIXELY;
double y = abs(abs(scenePoint.y()) - m_scene->itemsBoundingRect().height()) / MMPIXELY;
scenePoint.setX(x);
scenePoint.setY(y);
setMouseTracking(true);
siMouseMove(scenePoint);
if(m_leftBtnPressed)
{
m_endPoint = event->pos();
}
if(m_rightBtnPressed)
{
QPoint delta = m_startPoint - event->pos();
int hValue = horizontalScrollBar()->value();
int vValue = verticalScrollBar()->value();
horizontalScrollBar()->setValue(delta.x() + hValue);
verticalScrollBar()->setValue(delta.y() + vValue);
m_startPoint = event->pos();
}
QGraphicsView::mouseMoveEvent(event);
}
void MyGraphicsView::wheelEvent(QWheelEvent *event)
{
// 获取当前鼠标相对于view的位置;
QPointF cursorPoint = event->pos();
// 获取当前鼠标相对于scene的位置;
QPointF scenePos = this->mapToScene(QPoint(cursorPoint.x(), cursorPoint.y()));
// 获取view的宽高;
qreal viewWidth = this->viewport()->width();
qreal viewHeight = this->viewport()->height();
// 获取当前鼠标位置相当于view大小的横纵比例;
qreal hScale = cursorPoint.x() / viewWidth;
qreal vScale = cursorPoint.y() / viewHeight;
int wheelDeltaValue = event->delta();
// 向上滚动,放大;
if (wheelDeltaValue > 0)
{
this->scale(1.2, 1.2);
}
// 向下滚动,缩小;
else
{
this->scale(1.0 / 1.2, 1.0 / 1.2);
}
// 将scene坐标转换为放大缩小后的坐标;
QPointF viewPoint = this->matrix().map(scenePos);
// 通过滚动条控制view放大缩小后的展示scene的位置;
horizontalScrollBar()->setValue(int(viewPoint.x() - viewWidth * hScale));
verticalScrollBar()->setValue(int(viewPoint.y() - viewHeight * vScale));
}
QPicture MyGraphicsView::getPicture(Marker marker,int penWidth)
{
QPicture pic;
if(m_scene != NULL)
{
pic = m_scene->getPicture(marker,penWidth);
}
return pic;
}
void MyGraphicsView::creatView(Marker marker)
{
if(m_scene != NULL)
{
m_scene->createScene(marker);
QRectF rectItem = m_scene->itemsBoundingRect();
this->fitInView(rectItem, Qt::KeepAspectRatio);
}
}
void MyGraphicsView::creatView(QPixmap pixmap)
{
if(m_scene != NULL)
{
m_scene->createScene(pixmap);
QRectF rectItem = m_scene->itemsBoundingRect();
this->fitInView(rectItem, Qt::KeepAspectRatio);
}
}
void MyGraphicsView::cleanView()
{
if(m_scene != NULL)
{
//这里delete掉再重新new是因为view显示完大图再显示小图图形会不居中未找到其他解决方法
delete m_scene;
m_scene = NULL;
m_scene = new MyGraphicsScene();
this->setScene(m_scene);
}
}
void MyGraphicsView::swithView(QPicture pic)
{
if(m_scene != NULL)
{
m_scene->swithScene(pic);
QRectF rectItem = m_scene->itemsBoundingRect();
this->fitInView(rectItem, Qt::KeepAspectRatio);
}
}
void MyGraphicsView::reflushBlockView(QPoint p)
{
if(m_scene != NULL)
{
m_scene->ReflushBlockScene(p);
}
}

View File

@ -0,0 +1,50 @@
#ifndef MYGRAPHICSVIEW_H
#define MYGRAPHICSVIEW_H
#include <QObject>
#include <QGraphicsView>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QScrollBar>
#include "datafile/view/mygraphicsscene.h"
class MyGraphicsView : public QGraphicsView
{
Q_OBJECT
public:
MyGraphicsView();
~MyGraphicsView();
private:
MyGraphicsScene *m_scene;
QSize m_viewSize;
//鼠标起始点和结束点
QPoint m_startPoint;
QPoint m_endPoint;
bool m_leftBtnPressed = false;
bool m_rightBtnPressed = false;
protected:
void resizeEvent(QResizeEvent *event);//窗口大小发生变化的时候,该函数触发
void mouseDoubleClickEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
public:
QPicture getPicture(Marker marker,int penWidth = 1);
void creatView(Marker marker);
void creatView(QPixmap pixmap);
void cleanView();
void swithView(QPicture pic);
void reflushBlockView(QPoint p);
signals:
void siMouseMove(QPointF point);
public slots:
};
#endif // MYGRAPHICSVIEW_H

4334
datafile/zip/unzip.cpp Normal file

File diff suppressed because it is too large Load Diff

226
datafile/zip/unzip.h Normal file
View File

@ -0,0 +1,226 @@
#ifndef _unzip_H
#define _unzip_H
//
#ifdef ZIP_STD
#include <time.h>
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#ifndef MAX_PATH
#define MAX_PATH 1024
#endif
typedef unsigned long DWORD;
typedef char TCHAR;
typedef FILE* HANDLE;
typedef time_t FILETIME;
#endif
// UNZIPPING functions -- for unzipping.
// This file is a repackaged form of extracts from the zlib code available
// at www.gzip.org/zlib, by Jean-Loup Gailly and Mark Adler. The original
// copyright notice may be found in unzip.cpp. The repackaging was done
// by Lucian Wischik to simplify and extend its use in Windows/C++. Also
// encryption and unicode filenames have been added.
#ifndef _zip_H
DECLARE_HANDLE(HZIP);
#endif
// An HZIP identifies a zip file that has been opened
typedef DWORD ZRESULT;
// return codes from any of the zip functions. Listed later.
typedef struct
{ int index; // index of this file within the zip
TCHAR name[MAX_PATH]; // filename within the zip
DWORD attr; // attributes, as in GetFileAttributes.
FILETIME atime,ctime,mtime;// access, create, modify filetimes
long comp_size; // sizes of item, compressed and uncompressed. These
long unc_size; // may be -1 if not yet known (e.g. being streamed in)
} ZIPENTRY;
HZIP OpenZip(const TCHAR *fn, const char *password);
HZIP OpenZip(void *z,unsigned int len, const char *password);
HZIP OpenZipHandle(HANDLE h, const char *password);
// OpenZip - opens a zip file and returns a handle with which you can
// subsequently examine its contents. You can open a zip file from:
// from a pipe: OpenZipHandle(hpipe_read,0);
// from a file (by handle): OpenZipHandle(hfile,0);
// from a file (by name): OpenZip("c:\\test.zip","password");
// from a memory block: OpenZip(bufstart, buflen,0);
// If the file is opened through a pipe, then items may only be
// accessed in increasing order, and an item may only be unzipped once,
// although GetZipItem can be called immediately before and after unzipping
// it. If it's opened in any other way, then full random access is possible.
// Note: pipe input is not yet implemented.
// Note: zip passwords are ascii, not unicode.
// Note: for windows-ce, you cannot close the handle until after CloseZip.
// but for real windows, the zip makes its own copy of your handle, so you
// can close yours anytime.
ZRESULT GetZipItem(HZIP hz, int index, ZIPENTRY *ze);
// GetZipItem - call this to get information about an item in the zip.
// If index is -1 and the file wasn't opened through a pipe,
// then it returns information about the whole zipfile
// (and in particular ze.index returns the number of index items).
// Note: the item might be a directory (ze.attr & FILE_ATTRIBUTE_DIRECTORY)
// See below for notes on what happens when you unzip such an item.
// Note: if you are opening the zip through a pipe, then random access
// is not possible and GetZipItem(-1) fails and you can't discover the number
// of items except by calling GetZipItem on each one of them in turn,
// starting at 0, until eventually the call fails. Also, in the event that
// you are opening through a pipe and the zip was itself created into a pipe,
// then then comp_size and sometimes unc_size as well may not be known until
// after the item has been unzipped.
ZRESULT FindZipItem(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRY *ze);
// FindZipItem - finds an item by name. ic means 'insensitive to case'.
// It returns the index of the item, and returns information about it.
// If nothing was found, then index is set to -1 and the function returns
// an error code.
ZRESULT UnzipItem(HZIP hz, int index, const TCHAR *fn);
ZRESULT UnzipItem(HZIP hz, int index, void *z,unsigned int len);
ZRESULT UnzipItemHandle(HZIP hz, int index, HANDLE h);
// UnzipItem - given an index to an item, unzips it. You can unzip to:
// to a pipe: UnzipItemHandle(hz,i, hpipe_write);
// to a file (by handle): UnzipItemHandle(hz,i, hfile);
// to a file (by name): UnzipItem(hz,i, ze.name);
// to a memory block: UnzipItem(hz,i, buf,buflen);
// In the final case, if the buffer isn't large enough to hold it all,
// then the return code indicates that more is yet to come. If it was
// large enough, and you want to know precisely how big, GetZipItem.
// Note: zip files are normally stored with relative pathnames. If you
// unzip with ZIP_FILENAME a relative pathname then the item gets created
// relative to the current directory - it first ensures that all necessary
// subdirectories have been created. Also, the item may itself be a directory.
// If you unzip a directory with ZIP_FILENAME, then the directory gets created.
// If you unzip it to a handle or a memory block, then nothing gets created
// and it emits 0 bytes.
ZRESULT SetUnzipBaseDir(HZIP hz, const TCHAR *dir);
// if unzipping to a filename, and it's a relative filename, then it will be relative to here.
// (defaults to current-directory).
ZRESULT CloseZip(HZIP hz);
// CloseZip - the zip handle must be closed with this function.
unsigned int FormatZipMessage(ZRESULT code, TCHAR *buf,unsigned int len);
// FormatZipMessage - given an error code, formats it as a string.
// It returns the length of the error message. If buf/len points
// to a real buffer, then it also writes as much as possible into there.
// These are the result codes:
#define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned,
#define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage.
// The following come from general system stuff (e.g. files not openable)
#define ZR_GENMASK 0x0000FF00
#define ZR_NODUPH 0x00000100 // couldn't duplicate the handle
#define ZR_NOFILE 0x00000200 // couldn't create/open the file
#define ZR_NOALLOC 0x00000300 // failed to allocate some resource
#define ZR_WRITE 0x00000400 // a general error writing to the file
#define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip
#define ZR_MORE 0x00000600 // there's still more data to be unzipped
#define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile
#define ZR_READ 0x00000800 // a general error reading the file
#define ZR_PASSWORD 0x00001000 // we didn't get the right password to unzip the file
// The following come from mistakes on the part of the caller
#define ZR_CALLERMASK 0x00FF0000
#define ZR_ARGS 0x00010000 // general mistake with the arguments
#define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't
#define ZR_MEMSIZE 0x00030000 // the memory size is too small
#define ZR_FAILED 0x00040000 // the thing was already failed when you called this function
#define ZR_ENDED 0x00050000 // the zip creation has already been closed
#define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken
#define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped
#define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip
// The following come from bugs within the zip library itself
#define ZR_BUGMASK 0xFF000000
#define ZR_NOTINITED 0x01000000 // initialisation didn't work
#define ZR_SEEK 0x02000000 // trying to seek in an unseekable file
#define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed
#define ZR_FLATE 0x05000000 // an internal error in the de/inflation code
// e.g.
//
// SetCurrentDirectory("c:\\docs\\stuff");
// HZIP hz = OpenZip("c:\\stuff.zip",0);
// ZIPENTRY ze; GetZipItem(hz,-1,&ze); int numitems=ze.index;
// for (int i=0; i<numitems; i++)
// { GetZipItem(hz,i,&ze);
// UnzipItem(hz,i,ze.name);
// }
// CloseZip(hz);
//
//
// HRSRC hrsrc = FindResource(hInstance,MAKEINTRESOURCE(1),RT_RCDATA);
// HANDLE hglob = LoadResource(hInstance,hrsrc);
// void *zipbuf=LockResource(hglob);
// unsigned int ziplen=SizeofResource(hInstance,hrsrc);
// HZIP hz = OpenZip(zipbuf, ziplen, 0);
// - unzip to a membuffer -
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",true,&i,&ze);
// char *ibuf = new char[ze.unc_size];
// UnzipItem(hz,i, ibuf, ze.unc_size);
// delete[] ibuf;
// - unzip to a fixed membuff -
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",true,&i,&ze);
// char ibuf[1024]; ZRESULT zr=ZR_MORE; unsigned long totsize=0;
// while (zr==ZR_MORE)
// { zr = UnzipItem(hz,i, ibuf,1024);
// unsigned long bufsize=1024; if (zr==ZR_OK) bufsize=ze.unc_size-totsize;
// totsize+=bufsize;
// }
// - unzip to a pipe -
// HANDLE hwrite; HANDLE hthread=CreateWavReaderThread(&hwrite);
// int i; ZIPENTRY ze; FindZipItem(hz,"sound.wav",true,&i,&ze);
// UnzipItemHandle(hz,i, hwrite);
// CloseHandle(hwrite);
// WaitForSingleObject(hthread,INFINITE);
// CloseHandle(hwrite); CloseHandle(hthread);
// - finished -
// CloseZip(hz);
// // note: no need to free resources obtained through Find/Load/LockResource
//
//
// SetCurrentDirectory("c:\\docs\\pipedzipstuff");
// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite,0,0);
// CreateZipWriterThread(hwrite);
// HZIP hz = OpenZipHandle(hread,0);
// for (int i=0; ; i++)
// { ZIPENTRY ze;
// ZRESULT zr=GetZipItem(hz,i,&ze); if (zr!=ZR_OK) break; // no more
// UnzipItem(hz,i, ze.name);
// }
// CloseZip(hz);
//
//
// Now we indulge in a little skullduggery so that the code works whether
// the user has included just zip or both zip and unzip.
// Idea: if header files for both zip and unzip are present, then presumably
// the cpp files for zip and unzip are both present, so we will call
// one or the other of them based on a dynamic choice. If the header file
// for only one is present, then we will bind to that particular one.
ZRESULT CloseZipU(HZIP hz);
unsigned int FormatZipMessageU(ZRESULT code, TCHAR *buf,unsigned int len);
bool IsZipHandleU(HZIP hz);
#ifdef _zip_H
#undef CloseZip
#define CloseZip(hz) (IsZipHandleU(hz)?CloseZipU(hz):CloseZipZ(hz))
#else
#define CloseZip CloseZipU
#define FormatZipMessage FormatZipMessageU
#endif
#endif // _unzip_H

2990
datafile/zip/zip.cpp Normal file

File diff suppressed because it is too large Load Diff

214
datafile/zip/zip.h Normal file
View File

@ -0,0 +1,214 @@
#ifndef _zip_H
#define _zip_H
//
#ifdef ZIP_STD
#include <time.h>
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#ifndef MAX_PATH
#define MAX_PATH 1024
#endif
typedef unsigned long DWORD;
typedef char TCHAR;
typedef FILE* HANDLE;
typedef time_t FILETIME;
#endif
// ZIP functions -- for creating zip files
// This file is a repackaged form of the Info-Zip source code available
// at www.info-zip.org. The original copyright notice may be found in
// zip.cpp. The repackaging was done by Lucian Wischik to simplify and
// extend its use in Windows/C++. Also to add encryption and unicode.
#ifndef _unzip_H
DECLARE_HANDLE(HZIP);
#endif
// An HZIP identifies a zip file that is being created
typedef DWORD ZRESULT;
// return codes from any of the zip functions. Listed later.
HZIP CreateZip(const TCHAR *fn, const char *password);
HZIP CreateZip(void *buf,unsigned int len, const char *password);
HZIP CreateZipHandle(HANDLE h, const char *password);
// CreateZip - call this to start the creation of a zip file.
// As the zip is being created, it will be stored somewhere:
// to a pipe: CreateZipHandle(hpipe_write);
// in a file (by handle): CreateZipHandle(hfile);
// in a file (by name): CreateZip("c:\\test.zip");
// in memory: CreateZip(buf, len);
// or in pagefile memory: CreateZip(0, len);
// The final case stores it in memory backed by the system paging file,
// where the zip may not exceed len bytes. This is a bit friendlier than
// allocating memory with new[]: it won't lead to fragmentation, and the
// memory won't be touched unless needed. That means you can give very
// large estimates of the maximum-size without too much worry.
// As for the password, it lets you encrypt every file in the archive.
// (This api doesn't support per-file encryption.)
// Note: because pipes don't allow random access, the structure of a zipfile
// created into a pipe is slightly different from that created into a file
// or memory. In particular, the compressed-size of the item cannot be
// stored in the zipfile until after the item itself. (Also, for an item added
// itself via a pipe, the uncompressed-size might not either be known until
// after.) This is not normally a problem. But if you try to unzip via a pipe
// as well, then the unzipper will not know these things about the item until
// after it has been unzipped. Therefore: for unzippers which don't just write
// each item to disk or to a pipe, but instead pre-allocate memory space into
// which to unzip them, then either you have to create the zip not to a pipe,
// or you have to add items not from a pipe, or at least when adding items
// from a pipe you have to specify the length.
// Note: for windows-ce, you cannot close the handle until after CloseZip.
// but for real windows, the zip makes its own copy of your handle, so you
// can close yours anytime.
ZRESULT ZipAdd(HZIP hz,const TCHAR *dstzn, const TCHAR *fn);
ZRESULT ZipAdd(HZIP hz,const TCHAR *dstzn, void *src,unsigned int len);
ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, HANDLE h);
ZRESULT ZipAddHandle(HZIP hz,const TCHAR *dstzn, HANDLE h, unsigned int len);
ZRESULT ZipAddFolder(HZIP hz,const TCHAR *dstzn);
// ZipAdd - call this for each file to be added to the zip.
// dstzn is the name that the file will be stored as in the zip file.
// The file to be added to the zip can come
// from a pipe: ZipAddHandle(hz,"file.dat", hpipe_read);
// from a file: ZipAddHandle(hz,"file.dat", hfile);
// from a filen: ZipAdd(hz,"file.dat", "c:\\docs\\origfile.dat");
// from memory: ZipAdd(hz,"subdir\\file.dat", buf,len);
// (folder): ZipAddFolder(hz,"subdir");
// Note: if adding an item from a pipe, and if also creating the zip file itself
// to a pipe, then you might wish to pass a non-zero length to the ZipAddHandle
// function. This will let the zipfile store the item's size ahead of the
// compressed item itself, which in turn makes it easier when unzipping the
// zipfile from a pipe.
ZRESULT ZipGetMemory(HZIP hz, void **buf, unsigned long *len);
// ZipGetMemory - If the zip was created in memory, via ZipCreate(0,len),
// then this function will return information about that memory block.
// buf will receive a pointer to its start, and len its length.
// Note: you can't add any more after calling this.
ZRESULT CloseZip(HZIP hz);
// CloseZip - the zip handle must be closed with this function.
unsigned int FormatZipMessage(ZRESULT code, TCHAR *buf,unsigned int len);
// FormatZipMessage - given an error code, formats it as a string.
// It returns the length of the error message. If buf/len points
// to a real buffer, then it also writes as much as possible into there.
// These are the result codes:
#define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned,
#define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage.
// The following come from general system stuff (e.g. files not openable)
#define ZR_GENMASK 0x0000FF00
#define ZR_NODUPH 0x00000100 // couldn't duplicate the handle
#define ZR_NOFILE 0x00000200 // couldn't create/open the file
#define ZR_NOALLOC 0x00000300 // failed to allocate some resource
#define ZR_WRITE 0x00000400 // a general error writing to the file
#define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip
#define ZR_MORE 0x00000600 // there's still more data to be unzipped
#define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile
#define ZR_READ 0x00000800 // a general error reading the file
// The following come from mistakes on the part of the caller
#define ZR_CALLERMASK 0x00FF0000
#define ZR_ARGS 0x00010000 // general mistake with the arguments
#define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't
#define ZR_MEMSIZE 0x00030000 // the memory size is too small
#define ZR_FAILED 0x00040000 // the thing was already failed when you called this function
#define ZR_ENDED 0x00050000 // the zip creation has already been closed
#define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken
#define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped
#define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip
// The following come from bugs within the zip library itself
#define ZR_BUGMASK 0xFF000000
#define ZR_NOTINITED 0x01000000 // initialisation didn't work
#define ZR_SEEK 0x02000000 // trying to seek in an unseekable file
#define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed
#define ZR_FLATE 0x05000000 // an internal error in the de/inflation code
// e.g.
//
// (1) Traditional use, creating a zipfile from existing files
// HZIP hz = CreateZip("c:\\simple1.zip",0);
// ZipAdd(hz,"znsimple.bmp", "c:\\simple.bmp");
// ZipAdd(hz,"znsimple.txt", "c:\\simple.txt");
// CloseZip(hz);
//
// (2) Memory use, creating an auto-allocated mem-based zip file from various sources
// HZIP hz = CreateZip(0,100000, 0);
// // adding a conventional file...
// ZipAdd(hz,"src1.txt", "c:\\src1.txt");
// // adding something from memory...
// char buf[1000]; for (int i=0; i<1000; i++) buf[i]=(char)(i&0x7F);
// ZipAdd(hz,"file.dat", buf,1000);
// // adding something from a pipe...
// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite,NULL,0);
// HANDLE hthread = CreateThread(0,0,ThreadFunc,(void*)hwrite,0,0);
// ZipAdd(hz,"unz3.dat", hread,1000); // the '1000' is optional.
// WaitForSingleObject(hthread,INFINITE);
// CloseHandle(hthread); CloseHandle(hread);
// ... meanwhile DWORD WINAPI ThreadFunc(void *dat)
// { HANDLE hwrite = (HANDLE)dat;
// char buf[1000]={17};
// DWORD writ; WriteFile(hwrite,buf,1000,&writ,NULL);
// CloseHandle(hwrite);
// return 0;
// }
// // and now that the zip is created, let's do something with it:
// void *zbuf; unsigned long zlen; ZipGetMemory(hz,&zbuf,&zlen);
// HANDLE hfz = CreateFile("test2.zip",GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
// DWORD writ; WriteFile(hfz,zbuf,zlen,&writ,NULL);
// CloseHandle(hfz);
// CloseZip(hz);
//
// (3) Handle use, for file handles and pipes
// HANDLE hzread,hzwrite; CreatePipe(&hzread,&hzwrite,0,0);
// HANDLE hthread = CreateThread(0,0,ZipReceiverThread,(void*)hzread,0,0);
// HZIP hz = CreateZipHandle(hzwrite,0);
// // ... add to it
// CloseZip(hz);
// CloseHandle(hzwrite);
// WaitForSingleObject(hthread,INFINITE);
// CloseHandle(hthread);
// ... meanwhile DWORD WINAPI ZipReceiverThread(void *dat)
// { HANDLE hread = (HANDLE)dat;
// char buf[1000];
// while (true)
// { DWORD red; ReadFile(hread,buf,1000,&red,NULL);
// // ... and do something with this zip data we're receiving
// if (red==0) break;
// }
// CloseHandle(hread);
// return 0;
// }
// Now we indulge in a little skullduggery so that the code works whether
// the user has included just zip or both zip and unzip.
// Idea: if header files for both zip and unzip are present, then presumably
// the cpp files for zip and unzip are both present, so we will call
// one or the other of them based on a dynamic choice. If the header file
// for only one is present, then we will bind to that particular one.
ZRESULT CloseZipZ(HZIP hz);
unsigned int FormatZipMessageZ(ZRESULT code, char *buf,unsigned int len);
bool IsZipHandleZ(HZIP hz);
#ifdef _unzip_H
#undef CloseZip
#define CloseZip(hz) (IsZipHandleZ(hz)?CloseZipZ(hz):CloseZipU(hz))
#else
#define CloseZip CloseZipZ
#define FormatZipMessage FormatZipMessageZ
#endif
#endif

View File

@ -0,0 +1,89 @@
#include "zipreader.h"
#include <QFile>
ZipReader::ZipReader(const QString &filePath) :
#ifdef UNICODE
m_reader(OpenZip(reinterpret_cast<const wchar_t*>(filePath.utf16()),nullptr))
#else
m_reader(OpenZip(filePath.toUtf8().constData(),nullptr))
#endif
{
init();
}
ZipReader::ZipReader(QIODevice *device)
{
QFile *file = dynamic_cast<QFile*>(device);
if(nullptr != file)
{
QString strFile = file->fileName();
file->close();
#ifdef UNICODE
m_reader = OpenZip(reinterpret_cast<const wchar_t*>(strFile.utf16()),nullptr);
#else
m_reader = OpenZip(strFile.toUtf8().constData(),nullptr);
#endif
}
else
{
m_reader = OpenZip(device->readAll().data(),device->size(),nullptr);
}
init();
}
ZipReader::~ZipReader()
{
CloseZip(m_reader);
}
void ZipReader::init()
{
ZIPENTRY entry;
GetZipItem(m_reader,-1,&entry);
int nItems = entry.index;
for(int zi=0; zi<nItems; zi++)
{
GetZipItem(m_reader,zi,&entry);
#ifdef UNICODE
m_filePaths.append(QString::fromWCharArray(entry.name));
#else
m_filePaths.append(QString::fromUtf8(entry.name));
#endif
}
}
bool ZipReader::exists() const
{
return IsZipHandleU(m_reader);
}
QStringList ZipReader::filePaths() const
{
return m_filePaths;
}
QByteArray ZipReader::fileData(const QString &fileName) const
{
ZIPENTRY entry;
int i=-1;
#ifdef UNICODE
std::wstring strFile = fileName.toStdWString();
FindZipItem(m_reader,strFile.c_str(),true,&i,&entry);
#else
FindZipItem(m_reader,fileName.toUtf8().constData(),true,&i,&entry);
#endif
if(entry.unc_size < 0 || i<0)
{
return QByteArray("");
}
char*pBuf = new char[entry.unc_size +1];
QByteArray byteArray;
UnzipItem(m_reader,i,pBuf,entry.unc_size);
byteArray.append(pBuf,entry.unc_size);
delete []pBuf;
return byteArray;
}

30
datafile/zip/zipreader.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef ZIPREADER_H
#define ZIPREADER_H
#include <QStringList>
#include <QIODevice>
#if QT_VERSION >= 0x050600
#include <QVector>
#endif
#include "unzip.h"
class ZipReader
{
public:
explicit ZipReader(const QString &fileName);
explicit ZipReader(QIODevice *device);
~ZipReader();
bool exists() const;
QStringList filePaths() const;
QByteArray fileData(const QString &fileName) const;
private:
Q_DISABLE_COPY(ZipReader)
void init();
HZIP m_reader;
QStringList m_filePaths;
};
#endif // ZIPREADER_H

View File

@ -0,0 +1,70 @@
#include "zipwriter.h"
#include <QtGlobal>
#include <QDebug>
#include <QFile>
ZipWriter::ZipWriter(const QString &filePath)
{
#ifdef UNICODE
std::wstring strPath = filePath.toStdWString();
m_writer = CreateZip(strPath.c_str(),nullptr);
#else
m_writer = CreateZip(strFile.toUtf8().constData(),nullptr);
#endif
}
ZipWriter::ZipWriter(QIODevice *device)
{
QFile *file = dynamic_cast<QFile*>(device);
if(nullptr != file)
{
QString strFile = file->fileName();
file->close();
#ifdef UNICODE
m_writer = CreateZip(reinterpret_cast<const wchar_t*>(strFile.utf16()),nullptr);
#else
m_writer = CreateZip(strFile.toUtf8().constData(),nullptr);
#endif
}
else
{
m_writer =0;
}
}
ZipWriter::~ZipWriter()
{
CloseZip( m_writer);
}
bool ZipWriter::error() const
{
return !IsZipHandleZ(m_writer);
}
void ZipWriter::addFile(const QString &filePath, QIODevice *device)
{
#ifdef UNICODE
std::wstring strFilePath = filePath.toStdWString();
ZipAdd(m_writer,strFilePath.c_str(),(void*)device->readAll().data(),device->size());
#else
ZipAdd(m_writer,filePath.toUtf8().constData(),(void*)device->readAll().data(),device->size());
#endif
}
void ZipWriter::addFile(const QString &filePath, const QByteArray &data)
{
#ifdef UNICODE
std::wstring strFilePath = filePath.toStdWString();
ZipAdd(m_writer,strFilePath.c_str(),(void*)data.data(),data.size());
#else
ZipAdd(m_writer,filePath.toUtf8().constData(),(void*)data.data(),data.size());
#endif
}
void ZipWriter::close()
{
CloseZip( m_writer);
}

27
datafile/zip/zipwriter.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef ZIPWRITER_H
#define ZIPWRITER_H
#include <QtGlobal>
#include <QString>
#include <QIODevice>
#include "zip.h"
class ZipWriter
{
public:
explicit ZipWriter(const QString &filePath);
explicit ZipWriter(QIODevice *device);
~ZipWriter();
void addFile(const QString &filePath, QIODevice *device);
void addFile(const QString &filePath, const QByteArray &data);
bool error() const;
void close();
private:
HZIP m_writer;
ZRESULT m_result;
};
#endif // ZIPWRITER_H

16
drawingsetdialog.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "drawingsetdialog.h"
#include "ui_drawingsetdialog.h"
DrawingSetDialog::DrawingSetDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::DrawingSetDialog)
{
ui->setupUi(this);
setWindowModality(Qt::ApplicationModal);
setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
}
DrawingSetDialog::~DrawingSetDialog()
{
delete ui;
}

22
drawingsetdialog.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef DRAWINGSETDIALOG_H
#define DRAWINGSETDIALOG_H
#include <QDialog>
namespace Ui {
class DrawingSetDialog;
}
class DrawingSetDialog : public QDialog
{
Q_OBJECT
public:
explicit DrawingSetDialog(QWidget *parent = 0);
~DrawingSetDialog();
private:
Ui::DrawingSetDialog *ui;
};
#endif // DRAWINGSETDIALOG_H

356
drawingsetdialog.ui Normal file
View File

@ -0,0 +1,356 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DrawingSetDialog</class>
<widget class="QDialog" name="DrawingSetDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>346</width>
<height>370</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QCheckBox" name="checkBox_font">
<property name="geometry">
<rect>
<x>30</x>
<y>40</y>
<width>221</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>Use vector fonts</string>
</property>
</widget>
<widget class="QCheckBox" name="checkBox_angle">
<property name="geometry">
<rect>
<x>30</x>
<y>12</y>
<width>291</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>Graph positive rotation angle</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_ok">
<property name="geometry">
<rect>
<x>190</x>
<y>326</y>
<width>60</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Ok</string>
</property>
</widget>
<widget class="QGroupBox" name="groupBox_spaceSet">
<property name="geometry">
<rect>
<x>20</x>
<y>190</y>
<width>306</width>
<height>121</height>
</rect>
</property>
<property name="title">
<string>Boundary and alignment spacing</string>
</property>
<widget class="QLabel" name="label_rightUnit">
<property name="geometry">
<rect>
<x>270</x>
<y>30</y>
<width>30</width>
<height>12</height>
</rect>
</property>
<property name="text">
<string>mm</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_right">
<property name="geometry">
<rect>
<x>200</x>
<y>26</y>
<width>61</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
<widget class="QLabel" name="label_right">
<property name="geometry">
<rect>
<x>33</x>
<y>26</y>
<width>111</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>Right margin:</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_mark">
<property name="geometry">
<rect>
<x>200</x>
<y>56</y>
<width>61</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>0</string>
</property>
</widget>
<widget class="QLabel" name="label_markUnit">
<property name="geometry">
<rect>
<x>270</x>
<y>60</y>
<width>30</width>
<height>12</height>
</rect>
</property>
<property name="text">
<string>mm</string>
</property>
</widget>
<widget class="QLabel" name="label_mark">
<property name="geometry">
<rect>
<x>33</x>
<y>56</y>
<width>111</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>Mark margin:</string>
</property>
</widget>
<widget class="QLabel" name="label_butt">
<property name="geometry">
<rect>
<x>33</x>
<y>86</y>
<width>151</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>Butt joint margin:</string>
</property>
</widget>
<widget class="QLabel" name="label_buttUnit">
<property name="geometry">
<rect>
<x>270</x>
<y>90</y>
<width>30</width>
<height>12</height>
</rect>
</property>
<property name="text">
<string>mm</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_butt">
<property name="geometry">
<rect>
<x>200</x>
<y>86</y>
<width>61</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>1000</string>
</property>
</widget>
<widget class="QLabel" name="label_rightIcon">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>16</width>
<height>16</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-image: url(:/resources/right_ga.bmp);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_markIcon">
<property name="geometry">
<rect>
<x>10</x>
<y>60</y>
<width>16</width>
<height>16</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-image: url(:/resources/down_gap.bmp);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_buttIcon">
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<width>16</width>
<height>16</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-image: url(:/resources/mark_gap.bmp);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_paperWidth">
<property name="geometry">
<rect>
<x>20</x>
<y>130</y>
<width>306</width>
<height>51</height>
</rect>
</property>
<property name="title">
<string>Paper Width</string>
</property>
<widget class="QLabel" name="label_paperWidthUnit">
<property name="geometry">
<rect>
<x>170</x>
<y>24</y>
<width>54</width>
<height>12</height>
</rect>
</property>
<property name="text">
<string>mm</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_paperWidth">
<property name="geometry">
<rect>
<x>70</x>
<y>20</y>
<width>91</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>2400</string>
</property>
</widget>
<widget class="QLabel" name="label_paperWIcon">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>42</width>
<height>20</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-image: url(:/resources/page_cy.bmp);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</widget>
<widget class="QPushButton" name="pushButton_cancel">
<property name="geometry">
<rect>
<x>260</x>
<y>326</y>
<width>60</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
<widget class="QGroupBox" name="groupBox_lineWidth">
<property name="geometry">
<rect>
<x>20</x>
<y>70</y>
<width>306</width>
<height>51</height>
</rect>
</property>
<property name="title">
<string>Lineweight settings</string>
</property>
<widget class="QLabel" name="label_lineWidth">
<property name="geometry">
<rect>
<x>13</x>
<y>20</y>
<width>91</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>Lineweight:</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_lineWidth">
<property name="geometry">
<rect>
<x>110</x>
<y>20</y>
<width>91</width>
<height>20</height>
</rect>
</property>
<property name="text">
<string>2</string>
</property>
</widget>
<widget class="QLabel" name="label_lineUnit">
<property name="geometry">
<rect>
<x>210</x>
<y>19</y>
<width>61</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>pixel</string>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>

16
historydialog.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "historydialog.h"
#include "ui_historydialog.h"
HistoryDialog::HistoryDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::HistoryDialog)
{
ui->setupUi(this);
setWindowModality(Qt::ApplicationModal);
setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
}
HistoryDialog::~HistoryDialog()
{
delete ui;
}

22
historydialog.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef HISTORYDIALOG_H
#define HISTORYDIALOG_H
#include <QDialog>
namespace Ui {
class HistoryDialog;
}
class HistoryDialog : public QDialog
{
Q_OBJECT
public:
explicit HistoryDialog(QWidget *parent = 0);
~HistoryDialog();
private:
Ui::HistoryDialog *ui;
};
#endif // HISTORYDIALOG_H

68
historydialog.ui Normal file
View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>HistoryDialog</class>
<widget class="QDialog" name="HistoryDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>540</width>
<height>460</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QPushButton" name="pushButton_clear">
<property name="geometry">
<rect>
<x>400</x>
<y>430</y>
<width>60</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
<widget class="QTableWidget" name="tableWidget_log">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>521</width>
<height>411</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="pushButton_cancel">
<property name="geometry">
<rect>
<x>470</x>
<y>430</y>
<width>60</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_draw">
<property name="geometry">
<rect>
<x>330</x>
<y>430</y>
<width>60</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Draw</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

568
include/qrencode.h Normal file
View File

@ -0,0 +1,568 @@
/**
* qrencode - QR Code encoder
*
* Copyright (C) 2006-2017 Kentaro Fukuchi <kentaro@fukuchi.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/** \mainpage
* Libqrencode is a library for encoding data in a QR Code symbol, a kind of 2D
* symbology.
*
* \section encoding Encoding
*
* There are two methods to encode data: <b>encoding a string/data</b> or
* <b>encoding a structured data</b>.
*
* \subsection encoding-string Encoding a string/data
* You can encode a string by calling QRcode_encodeString().
* The given string is parsed automatically and encoded. If you want to encode
* data that can be represented as a C string style (NUL terminated), you can
* simply use this way.
*
* If the input data contains Kanji (Shift-JIS) characters and you want to
* encode them as Kanji in QR Code, you should give QR_MODE_KANJI as a hint.
* Otherwise, all of non-alphanumeric characters are encoded as 8 bit data.
* If you want to encode a whole string in 8 bit mode, you can use
* QRcode_encodeString8bit() instead.
*
* Please note that a C string can not contain NUL characters. If your data
* contains NUL, you must use QRcode_encodeData().
*
* \subsection encoding-input Encoding a structured data
* You can construct a structured input data manually. If the structure of the
* input data is known, you can use this way.
* At first, create a ::QRinput object by QRinput_new(). Then add input data
* to the QRinput object by QRinput_append(). Finally call QRcode_encodeInput()
* to encode the QRinput data.
* You can reuse the QRinput data again to encode it in other symbols with
* different parameters.
*
* \section result Result
* The encoded symbol is resulted as a ::QRcode object. It will contain
* its version number, width of the symbol and an array represents the symbol.
* See ::QRcode for the details. You can free the object by QRcode_free().
*
* Please note that the version of the result may be larger than specified.
* In such cases, the input data would be too large to be encoded in a
* symbol of the specified version.
*
* \section structured Structured append
* Libqrencode can generate "Structured-appended" symbols that enables to split
* a large data set into mulitple QR codes. A QR code reader concatenates
* multiple QR code symbols into a string.
* Just like QRcode_encodeString(), you can use QRcode_encodeStringStructured()
* to generate structured-appended symbols. This functions returns an instance
* of ::QRcode_List. The returned list is a singly-linked list of QRcode: you
* can retrieve each QR code in this way:
*
* \code
* QRcode_List *qrcodes;
* QRcode_List *entry;
* QRcode *qrcode;
*
* qrcodes = QRcode_encodeStringStructured(...);
* entry = qrcodes;
* while(entry != NULL) {
* qrcode = entry->code;
* // do something
* entry = entry->next;
* }
* QRcode_List_free(entry);
* \endcode
*
* Instead of using auto-parsing functions, you can construct your own
* structured input. At first, instantiate an object of ::QRinput_Struct
* by calling QRinput_Struct_new(). This object can hold multiple ::QRinput,
* and one QR code is generated for a ::QRinput.
* QRinput_Struct_appendInput() appends a ::QRinput to a ::QRinput_Struct
* object. In order to generate structured-appended symbols, it is required to
* embed headers to each symbol. You can use
* QRinput_Struct_insertStructuredAppendHeaders() to insert appropriate
* headers to each symbol. You should call this function just once before
* encoding symbols.
*/
#ifndef QRENCODE_H
#define QRENCODE_H
#if defined(__cplusplus)
extern "C" {
#endif
/**
* Encoding mode.
*/
typedef enum {
QR_MODE_NUL = -1, ///< Terminator (NUL character). Internal use only
QR_MODE_NUM = 0, ///< Numeric mode
QR_MODE_AN, ///< Alphabet-numeric mode
QR_MODE_8, ///< 8-bit data mode
QR_MODE_KANJI, ///< Kanji (shift-jis) mode
QR_MODE_STRUCTURE, ///< Internal use only
QR_MODE_ECI, ///< ECI mode
QR_MODE_FNC1FIRST, ///< FNC1, first position
QR_MODE_FNC1SECOND, ///< FNC1, second position
} QRencodeMode;
/**
* Level of error correction.
*/
typedef enum {
QR_ECLEVEL_L = 0, ///< lowest
QR_ECLEVEL_M,
QR_ECLEVEL_Q,
QR_ECLEVEL_H ///< highest
} QRecLevel;
/**
* Maximum version (size) of QR-code symbol.
*/
#define QRSPEC_VERSION_MAX 40
/**
* Maximum version (size) of QR-code symbol.
*/
#define MQRSPEC_VERSION_MAX 4
/******************************************************************************
* Input data (qrinput.c)
*****************************************************************************/
/**
* Singly linked list to contain input strings. An instance of this class
* contains its version and error correction level too. It is required to
* set them by QRinput_setVersion() and QRinput_setErrorCorrectionLevel(),
* or use QRinput_new2() to instantiate an object.
*/
typedef struct _QRinput QRinput;
/**
* Instantiate an input data object. The version is set to 0 (auto-select)
* and the error correction level is set to QR_ECLEVEL_L.
* @return an input object (initialized). On error, NULL is returned and errno
* is set to indicate the error.
* @throw ENOMEM unable to allocate memory.
*/
extern QRinput *QRinput_new(void);
/**
* Instantiate an input data object.
* @param version version number.
* @param level Error correction level.
* @return an input object (initialized). On error, NULL is returned and errno
* is set to indicate the error.
* @throw ENOMEM unable to allocate memory for input objects.
* @throw EINVAL invalid arguments.
*/
extern QRinput *QRinput_new2(int version, QRecLevel level);
/**
* Instantiate an input data object. Object's Micro QR Code flag is set.
* Unlike with full-sized QR Code, version number must be specified (>0).
* @param version version number (1--4).
* @param level Error correction level.
* @return an input object (initialized). On error, NULL is returned and errno
* is set to indicate the error.
* @throw ENOMEM unable to allocate memory for input objects.
* @throw EINVAL invalid arguments.
*/
extern QRinput *QRinput_newMQR(int version, QRecLevel level);
/**
* Append data to an input object.
* The data is copied and appended to the input object.
* @param input input object.
* @param mode encoding mode.
* @param size size of data (byte).
* @param data a pointer to the memory area of the input data.
* @retval 0 success.
* @retval -1 an error occurred and errno is set to indeicate the error.
* See Execptions for the details.
* @throw ENOMEM unable to allocate memory.
* @throw EINVAL input data is invalid.
*
*/
extern int QRinput_append(QRinput *input, QRencodeMode mode, int size, const unsigned char *data);
/**
* Append ECI header.
* @param input input object.
* @param ecinum ECI indicator number (0 - 999999)
* @retval 0 success.
* @retval -1 an error occurred and errno is set to indeicate the error.
* See Execptions for the details.
* @throw ENOMEM unable to allocate memory.
* @throw EINVAL input data is invalid.
*
*/
extern int QRinput_appendECIheader(QRinput *input, unsigned int ecinum);
/**
* Get current version.
* @param input input object.
* @return current version.
*/
extern int QRinput_getVersion(QRinput *input);
/**
* Set version of the QR code that is to be encoded.
* This function cannot be applied to Micro QR Code.
* @param input input object.
* @param version version number (0 = auto)
* @retval 0 success.
* @retval -1 invalid argument.
*/
extern int QRinput_setVersion(QRinput *input, int version);
/**
* Get current error correction level.
* @param input input object.
* @return Current error correcntion level.
*/
extern QRecLevel QRinput_getErrorCorrectionLevel(QRinput *input);
/**
* Set error correction level of the QR code that is to be encoded.
* This function cannot be applied to Micro QR Code.
* @param input input object.
* @param level Error correction level.
* @retval 0 success.
* @retval -1 invalid argument.
*/
extern int QRinput_setErrorCorrectionLevel(QRinput *input, QRecLevel level);
/**
* Set version and error correction level of the QR code at once.
* This function is recommened for Micro QR Code.
* @param input input object.
* @param version version number (0 = auto)
* @param level Error correction level.
* @retval 0 success.
* @retval -1 invalid argument.
*/
extern int QRinput_setVersionAndErrorCorrectionLevel(QRinput *input, int version, QRecLevel level);
/**
* Free the input object.
* All of data chunks in the input object are freed too.
* @param input input object.
*/
extern void QRinput_free(QRinput *input);
/**
* Validate the input data.
* @param mode encoding mode.
* @param size size of data (byte).
* @param data a pointer to the memory area of the input data.
* @retval 0 success.
* @retval -1 invalid arguments.
*/
extern int QRinput_check(QRencodeMode mode, int size, const unsigned char *data);
/**
* Set of QRinput for structured symbols.
*/
typedef struct _QRinput_Struct QRinput_Struct;
/**
* Instantiate a set of input data object.
* @return an instance of QRinput_Struct. On error, NULL is returned and errno
* is set to indicate the error.
* @throw ENOMEM unable to allocate memory.
*/
extern QRinput_Struct *QRinput_Struct_new(void);
/**
* Set parity of structured symbols.
* @param s structured input object.
* @param parity parity of s.
*/
extern void QRinput_Struct_setParity(QRinput_Struct *s, unsigned char parity);
/**
* Append a QRinput object to the set. QRinput created by QRinput_newMQR()
* will be rejected.
* @warning never append the same QRinput object twice or more.
* @param s structured input object.
* @param input an input object.
* @retval >0 number of input objects in the structure.
* @retval -1 an error occurred. See Exceptions for the details.
* @throw ENOMEM unable to allocate memory.
* @throw EINVAL invalid arguments.
*/
extern int QRinput_Struct_appendInput(QRinput_Struct *s, QRinput *input);
/**
* Free all of QRinput in the set.
* @param s a structured input object.
*/
extern void QRinput_Struct_free(QRinput_Struct *s);
/**
* Split a QRinput to QRinput_Struct. It calculates a parity, set it, then
* insert structured-append headers. QRinput created by QRinput_newMQR() will
* be rejected.
* @param input input object. Version number and error correction level must be
* set.
* @return a set of input data. On error, NULL is returned, and errno is set
* to indicate the error. See Exceptions for the details.
* @throw ERANGE input data is too large.
* @throw EINVAL invalid input data.
* @throw ENOMEM unable to allocate memory.
*/
extern QRinput_Struct *QRinput_splitQRinputToStruct(QRinput *input);
/**
* Insert structured-append headers to the input structure. It calculates
* a parity and set it if the parity is not set yet.
* @param s input structure
* @retval 0 success.
* @retval -1 an error occurred and errno is set to indeicate the error.
* See Execptions for the details.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory.
*/
extern int QRinput_Struct_insertStructuredAppendHeaders(QRinput_Struct *s);
/**
* Set FNC1-1st position flag.
*/
extern int QRinput_setFNC1First(QRinput *input);
/**
* Set FNC1-2nd position flag and application identifier.
*/
extern int QRinput_setFNC1Second(QRinput *input, unsigned char appid);
/******************************************************************************
* QRcode output (qrencode.c)
*****************************************************************************/
/**
* QRcode class.
* Symbol data is represented as an array contains width*width uchars.
* Each uchar represents a module (dot). If the less significant bit of
* the uchar is 1, the corresponding module is black. The other bits are
* meaningless for usual applications, but here its specification is described.
*
* @verbatim
MSB 76543210 LSB
|||||||`- 1=black/0=white
||||||`-- data and ecc code area
|||||`--- format information
||||`---- version information
|||`----- timing pattern
||`------ alignment pattern
|`------- finder pattern and separator
`-------- non-data modules (format, timing, etc.)
@endverbatim
*/
typedef struct {
int version; ///< version of the symbol
int width; ///< width of the symbol
unsigned char *data; ///< symbol data
} QRcode;
/**
* Singly-linked list of QRcode. Used to represent a structured symbols.
* A list is terminated with NULL.
*/
typedef struct _QRcode_List {
QRcode *code;
struct _QRcode_List *next;
} QRcode_List;
/**
* Create a symbol from the input data.
* @warning This function is THREAD UNSAFE when pthread is disabled.
* @param input input data.
* @return an instance of QRcode class. The version of the result QRcode may
* be larger than the designated version. On error, NULL is returned,
* and errno is set to indicate the error. See Exceptions for the
* details.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory for input objects.
*/
extern QRcode *QRcode_encodeInput(QRinput *input);
/**
* Create a symbol from the string. The library automatically parses the input
* string and encodes in a QR Code symbol.
* @warning This function is THREAD UNSAFE when pthread is disabled.
* @param string input string. It must be NUL terminated.
* @param version version of the symbol. If 0, the library chooses the minimum
* version for the given input data.
* @param level error correction level.
* @param hint tell the library how Japanese Kanji characters should be
* encoded. If QR_MODE_KANJI is given, the library assumes that the
* given string contains Shift-JIS characters and encodes them in
* Kanji-mode. If QR_MODE_8 is given, all of non-alphanumerical
* characters will be encoded as is. If you want to embed UTF-8
* string, choose this. Other mode will cause EINVAL error.
* @param casesensitive case-sensitive(1) or not(0).
* @return an instance of QRcode class. The version of the result QRcode may
* be larger than the designated version. On error, NULL is returned,
* and errno is set to indicate the error. See Exceptions for the
* details.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory for input objects.
* @throw ERANGE input data is too large.
*/
extern QRcode *QRcode_encodeString(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
/**
* Same to QRcode_encodeString(), but encode whole data in 8-bit mode.
* @warning This function is THREAD UNSAFE when pthread is disabled.
*/
extern QRcode *QRcode_encodeString8bit(const char *string, int version, QRecLevel level);
/**
* Micro QR Code version of QRcode_encodeString().
* @warning This function is THREAD UNSAFE when pthread is disabled.
*/
extern QRcode *QRcode_encodeStringMQR(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
/**
* Micro QR Code version of QRcode_encodeString8bit().
* @warning This function is THREAD UNSAFE when pthread is disabled.
*/
extern QRcode *QRcode_encodeString8bitMQR(const char *string, int version, QRecLevel level);
/**
* Encode byte stream (may include '\0') in 8-bit mode.
* @warning This function is THREAD UNSAFE when pthread is disabled.
* @param size size of the input data.
* @param data input data.
* @param version version of the symbol. If 0, the library chooses the minimum
* version for the given input data.
* @param level error correction level.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory for input objects.
* @throw ERANGE input data is too large.
*/
extern QRcode *QRcode_encodeData(int size, const unsigned char *data, int version, QRecLevel level);
/**
* Micro QR Code version of QRcode_encodeData().
* @warning This function is THREAD UNSAFE when pthread is disabled.
*/
extern QRcode *QRcode_encodeDataMQR(int size, const unsigned char *data, int version, QRecLevel level);
/**
* Free the instance of QRcode class.
* @param qrcode an instance of QRcode class.
*/
extern void QRcode_free(QRcode *qrcode);
/**
* Create structured symbols from the input data.
* @warning This function is THREAD UNSAFE when pthread is disabled.
* @param s input data, structured.
* @return a singly-linked list of QRcode.
*/
extern QRcode_List *QRcode_encodeInputStructured(QRinput_Struct *s);
/**
* Create structured symbols from the string. The library automatically parses
* the input string and encodes in a QR Code symbol.
* @warning This function is THREAD UNSAFE when pthread is disabled.
* @param string input string. It must be NUL terminated.
* @param version version of the symbol.
* @param level error correction level.
* @param hint tell the library how Japanese Kanji characters should be
* encoded. If QR_MODE_KANJI is given, the library assumes that the
* given string contains Shift-JIS characters and encodes them in
* Kanji-mode. If QR_MODE_8 is given, all of non-alphanumerical
* characters will be encoded as is. If you want to embed UTF-8
* string, choose this. Other mode will cause EINVAL error.
* @param casesensitive case-sensitive(1) or not(0).
* @return a singly-linked list of QRcode. On error, NULL is returned, and
* errno is set to indicate the error. See Exceptions for the details.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory for input objects.
*/
extern QRcode_List *QRcode_encodeStringStructured(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
/**
* Same to QRcode_encodeStringStructured(), but encode whole data in 8-bit mode.
* @warning This function is THREAD UNSAFE when pthread is disabled.
*/
extern QRcode_List *QRcode_encodeString8bitStructured(const char *string, int version, QRecLevel level);
/**
* Create structured symbols from byte stream (may include '\0'). Wholde data
* are encoded in 8-bit mode.
* @warning This function is THREAD UNSAFE when pthread is disabled.
* @param size size of the input data.
* @param data input dat.
* @param version version of the symbol.
* @param level error correction level.
* @return a singly-linked list of QRcode. On error, NULL is returned, and
* errno is set to indicate the error. See Exceptions for the details.
* @throw EINVAL invalid input object.
* @throw ENOMEM unable to allocate memory for input objects.
*/
extern QRcode_List *QRcode_encodeDataStructured(int size, const unsigned char *data, int version, QRecLevel level);
/**
* Return the number of symbols included in a QRcode_List.
* @param qrlist a head entry of a QRcode_List.
* @return number of symbols in the list.
*/
extern int QRcode_List_size(QRcode_List *qrlist);
/**
* Free the QRcode_List.
* @param qrlist a head entry of a QRcode_List.
*/
extern void QRcode_List_free(QRcode_List *qrlist);
/******************************************************************************
* System utilities
*****************************************************************************/
/**
* Return a string that identifies the library version.
* @param major_version major version number
* @param minor_version minor version number
* @param micro_version micro version number
*/
extern void QRcode_APIVersion(int *major_version, int *minor_version, int *micro_version);
/**
* Return a string that identifies the library version.
* @return a string identifies the library version. The string is held by the
* library. Do NOT free it.
*/
extern char *QRcode_APIVersionString(void);
/**
* @deprecated
*/
#ifndef _MSC_VER
extern void QRcode_clearCache(void) __attribute__ ((deprecated));
#else
extern void QRcode_clearCache(void);
#endif
#if defined(__cplusplus)
}
#endif
#endif /* QRENCODE_H */

BIN
lib/libqrencode.a Normal file

Binary file not shown.

604
machine/bmp/bwbmp.cpp Normal file
View File

@ -0,0 +1,604 @@
#include "bwbmp.h"
#include <QFile>
#include <QDebug>
BWBmp::BWBmp()
{
}
int BWBmp::LoadBiBmp(QString filename)
{
m_bwDdat.clear();
m_prDdat.clear();
QFile file(filename);
int rslt = file.open(QFile::ReadOnly);
if (rslt == 0)
{
qDebug() << "open file error" << filename;
return -1;
}
m_bwDdat = file.readAll();
if (m_bwDdat.size() <= (int)sizeof(BitmapHead))
{
m_bwDdat.clear();
file.close();
qDebug() << "file size error, size=" << m_bwDdat.size();
return -2;
}
BitmapHead * pHead = (BitmapHead *)(m_bwDdat.data());
if ( (pHead->identifier != 0x4d42) ||
(pHead->bitDatOffset != 0x3E) ||
(pHead->biSize != 0x28) ||
(pHead->biPlanes != 0x01) ||
(pHead->biBitPerPixel != 0x01) ||
(pHead->biCompression != 0x00) ||
0 )
{
m_bwDdat.clear();
file.close();
qDebug() << "not bi bmp";
return -3;
}
file.close();
return 0;
}
int BWBmp::SavePrBmp(QString filename)
{
QFile file(filename);
int rslt = file.open(QFile::ReadWrite | QFile::Truncate);
if (rslt == 0)
{
qDebug() << "open file error" << filename;
return -1;
}
file.write(m_prDdat);
file.close();
return 0;
}
int BWBmp::Compress(int dir)
{
/*
300
+
__________________________________________________
| bit7 bit6 | bit5 bit4 bit3 bit2 bit1 bit0 |
--------------------------------------------------
| | |
--------------------------------------------------
| 0 0 | |
--------------------------------------------------
| 0 1 | 1 |
--------------------------------------------------
| 1 0 | 100 |
--------------------------------------------------
| 1 1 | 0 |
--------------------------------------------------
*/
if (dir < 0)
{
dir = -1;
}
else
{
dir = 1;
}
m_prDdat.clear();
if (m_bwDdat.isEmpty() == 1)
{
qDebug() << "bit dat empty";
return -1;
}
BitmapHead * pHead = (BitmapHead *)(m_bwDdat.data());
int width = pHead->biWidth;
int height = pHead->biHeight;
int widthBytes = (int)((width + 31) / 32) * 4;
if (widthBytes <= 0 || height < 1 || width > 0x1000000)
{
qDebug() << "bit dat error";
return -2;
}
const unsigned char * pBitDat = (unsigned char *)(m_bwDdat.data() + pHead->bitDatOffset);
const unsigned char * pTmpDat;
if (dir == -1)
{
pBitDat += widthBytes * (height -1);
}
int * countBuff = new int [width];
if (countBuff == NULL)
{
qDebug() << "no enough memory";
return -3;
}
memset(countBuff, 0, sizeof(int)*width);
unsigned char tmpdat, mod;
int datsta = -1;
int count0 = 0;
int count1 = 0;
int i, j, k, l;
for (i = 0; i < height; i++) // 行计数
{
pTmpDat = pBitDat;
int countIdx = 0;
count0 = 0;
count1 = 0;
for (j = 0, k = 0; (j < widthBytes) && (k < width); j++) // 行内扫描检测出每段连续0和1的个数
{
tmpdat = *pTmpDat++;
// if(j+i*widthBytes > 12879)
// {
// qDebug()<<j+i*widthBytes<<" "<<tmpdat;
// }
//mod = 0x80;
mod = 0x01;
if((width - k) <= 8)
{
tmpdat = tmpdat >> (8 - (width - k ));
}
//for (mod = 0x80; (mod != 0) && (k < width); k++, mod /= 2)
for (mod = 0x01; (mod != 0) && (k < width); k++, mod *= 2)
{
if ((tmpdat & mod) == 0)
{
if (datsta == 1)
{
count1 |= 0x80000000;
countBuff[countIdx] = count1;
countIdx++;
count1 = 0;
}
datsta = 0;
count0++;
}
else
{
if (datsta == 0)
{
countBuff[countIdx] = count0;
countIdx++;
count0 = 0;
}
datsta = 1;
count1++;
}
}
}
if (count0 != 0)
{
countBuff[countIdx] = count0;
countIdx++;
count0 = 0;
}
if (count1 != 0)
{
count1 |= 0x80000000;
countBuff[countIdx] = count1;
countIdx++;
count1 = 0;
}
int psta = 0;
int pcount = 0;
unsigned char tgtdat = 0, pmod = 0x20, nums;
for (l = 0; l < countIdx; l++) // 分析数据,生成压缩数据
{
if ((countBuff[l] & 0x80000000) != 0)
{
count1 = countBuff[l] & 0xfffffff;
while (count1 != 0)
{
if (psta == 0) // 当前状态是原始数据
{
if (pcount != 0)
{
while (count1 != 0 && pcount != 0)
{
tgtdat |= pmod;
pcount--;
count1--;
//pmod /= 2;
pmod *= 2;
}
if (pcount == 0) // 够一个位图
{
tgtdat &= 0x3f;
m_prDdat.append(tgtdat); // 添加
//qDebug()<<m_prDdat.size()<<tgtdat;
tgtdat = 0x00;
}
}
}
if (pcount == 0 && count1 != 0) //
{
while (count1 != 0)
{
if (count1 <= 6)
{
psta = 0x00; // 位图模式
tgtdat = psta;
//pmod = 0x20;
pmod = 0x01;
pcount = 6;
break;
}
else
{
if (count1 > 64)
{
nums = 64;
}
else
{
nums = count1;
}
psta = 0x40;
tgtdat = psta;
tgtdat |= (nums & 0x3f);
m_prDdat.append(tgtdat); // 添加
//qDebug()<<m_prDdat.size()<<tgtdat;
count1 -= nums;
}
}
}
}
}
else
{
count0 = countBuff[l] & 0xfffffff;
while (count0 != 0)
{
if (psta == 0) // 当前状态是原始数据
{
if (pcount != 0)
{
while (count0 != 0 && pcount != 0)
{
tgtdat &= (~pmod);
pcount--;
count0--;
pmod *= 2;
}
if (pcount == 0) // 够一个位图
{
tgtdat &= 0x3f;
m_prDdat.append(tgtdat); // 添加
//qDebug()<<m_prDdat.size()<<tgtdat;
tgtdat = 0x00;
}
}
}
if (pcount == 0 && count0 != 0) //
{
while (count0 != 0)
{
if (count0 <= 6)
{
psta = 0x00; // 位图模式
tgtdat = psta;
pmod = 0x01;
pcount = 6;
break;
}
else
{
int muti = 1;
if (count0 >= 640)
{
nums = 64;
muti = 10;
psta = 0x80;
}
//else if (count0 > 64)
else if (count0 >= 64)
{
nums = (int)(count0/10);
muti = 10;
psta = 0x80;
}
else
{
nums = count0;
muti = 1;
psta = 0xC0;
}
tgtdat = psta;
tgtdat |= (nums & 0x3f);
m_prDdat.append(tgtdat); // 添加
//qDebug()<<m_prDdat.size()<<tgtdat;
count0 -= nums * muti;
}
}
}
}
}
}
if (psta == 0 && pcount != 0) // 不满一个位图的数据(小于6)
{
pcount = 0;
tgtdat &= 0x3f;
m_prDdat.append(tgtdat); // 添加
tgtdat = 0x00;
}
// 下一行
pBitDat += widthBytes * dir;
}
delete []countBuff;
// m_prDdat.append((char*)); // 添加文件头
// int size = m_prDdat.size();
// for(int p = 0; p < size; p++)
// {
// unsigned char ch = m_prDdat[p];
// qDebug()<<p<<" "<<ch;
// }
return 0;
}
int BWBmp::LoadPrBmp(QString filename)
{
m_fileName = filename;
m_rbwDdat.clear();
m_prDdat.clear();
QFile file(filename);
int rslt = file.open(QFile::ReadOnly);
if (rslt == 0)
{
qDebug() << "open file error" << filename;
return -1;
}
m_prDdat = file.readAll();
if (m_prDdat.size() <= 0)
{
file.close();
qDebug() << "file size error, size=" << m_prDdat.size();
m_prDdat.clear();
return -2;
}
file.close();
return 0;
}
int BWBmp::Unpress()
{
m_rbwDdat.clear();
QByteArray arrdat;
arrdat.clear();
QByteArray barr;
barr.clear();
QFileInfo file(m_fileName);
QString name = file.filePath().remove("."+file.suffix());
QFile bfile(name);
bfile.open(QFile::ReadOnly);
barr = bfile.readAll();
BitmapHead * pHead = (BitmapHead *)(barr.data());
int widthBytes = (int)((pHead->biWidth + 31) / 32) * 4;
m_rbwDdat.append((char*)pHead,sizeof(BitmapHead));
if (m_prDdat.isEmpty() == 1)
{
qDebug() << "pr dat empty";
return -1;
}
unsigned char sdat = 0;
int count0,count1,flag;
count0 = count1 = 0;
flag = -1;
int size = m_prDdat.size();
for(int i = 0; i < size; i++)
{
// if(i > 3250)
// {
// int a = 0;
// a = 1;
// }
count0 = count1 = 0;
flag = -1;
sdat = m_prDdat[i];
if((sdat & 0xC0) == 0xC0) // 连续0
{
count0 = sdat & 0x3f;
flag = 0;
}
else
{
if((sdat & 0x40) == 0x40) // 连续1
{
count1 = sdat & 0x3f;
flag = 1;
}
else if((sdat & 0x80) == 0x80) // 连续10个0
{
count0 = (sdat & 0x3f ) * 10;
flag = 0;
}
else // 原始数据
{
//每行扫描时最后一个像素为原始数据时原始数据个数
int pcount = 6;
int val = arrdat.size() % pHead->biWidth;
int cnt = pHead->biWidth - val;
int cnt1 = abs(pHead->biWidth - (widthBytes-1) * 8);
if(cnt >= cnt1)
{
pcount = 6;
}
else
{
if(cnt > 6)
{
pcount = 6;
}
else
{
pcount = cnt;
}
}
unsigned char sch = sdat & 0x3f; //够一个位图
unsigned char pmod = 0x01;
while (pcount != 0)
{
if((sch & pmod) != 0) // 为1
{
arrdat.append((char)0x01);
}
else // 为0
{
arrdat.append((char)0x00);
}
pcount--;
pmod *= 2;
}
continue;
}
}
int count = 0;
unsigned char ch = 0;
if(flag == 0)
{
count = count0;
ch = 0;
}
else if(flag == 1)
{
count = count1;
ch = 1;
}
for(int j = 0; j < count; j++)
{
arrdat.append(ch);
}
}
int num = 0;
unsigned char abyte = 0;
unsigned int cnt = 0;
for(unsigned int n = 0; n < pHead->biHeight; n++)
{
for(int j = 0; j < widthBytes; j++)
{
abyte = 0;
for(int i = 0; i < 8; i++)
{
int idx = n*pHead->biWidth+j*8+i;
//qDebug()<<"idx"<<idx;
unsigned char ch = arrdat[idx] << i;
//qDebug()<<"ch"<<ch;
cnt = j*8 + i;
if(cnt < pHead->biWidth)
{
abyte |= ch;
}
else if(cnt == pHead->biWidth)
{
abyte = abyte << (8 - i);
}
else if(cnt >= ((pHead->biWidth/8)*8+8))
{
abyte = 0;
}
else
{
continue;
}
}
//if(abyte != 0)
{
//qDebug()<<num<<" "<<abyte;
}
m_rbwDdat.append(abyte);
num++;
}
}
return 0;
}
int BWBmp::SaveBiBmp(QString filename)
{
QFile file(filename);
int rslt = file.open(QFile::ReadWrite | QFile::Truncate);
if (rslt == 0)
{
qDebug() << "open file error" << filename;
return -1;
}
file.write(m_rbwDdat);
file.close();
return 0;
}
QByteArray BWBmp::getPrBmpDat()
{
return m_prDdat;
}

73
machine/bmp/bwbmp.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef BWBMP_H
#define BWBMP_H
#include <QString>
#include <QFileInfo>
#pragma pack(1) //设定为1字节对齐
// 位图的调色板
typedef struct
{
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
}__attribute__ ((packed)) BmpRgbQuad;
// 位图文件头
typedef struct
{
unsigned short int identifier; // 类型 一般为 "BM"
unsigned long int fileSize; // 文件大小
unsigned long int reserved; // 保留
unsigned long int bitDatOffset; // 位图数据偏移,一般为 0x3E
unsigned long int biSize; // 位图信息头大小, 一般为 0x28
unsigned long int biWidth; // 位图宽度,以像素为单位
unsigned long int biHeight; // 位图高度,以像素为单位
unsigned short int biPlanes; // 位图的位面数必须为1
unsigned short int biBitPerPixel; // 每个像素的位数, =1, 单色位图; =4, 16色; = 8, 256色; = 24 真彩色
unsigned long int biCompression; // 位图压缩类型, =0, 不压缩BI_RGB; =1, BI_RLE8; = 2, BI_RLE4; = 3 BI_BITFIELDS; = 4, BI_JPEG; = 5, BI_PNG
unsigned long int biBitmapDatSize;// 位图数据区的大小(字节数), 必须是4的整数倍
unsigned long int biHResolution; // 水平分辨率, 像素/米
unsigned long int biVResolution; // 垂直分辨率, 像素/米
unsigned long int biColors; // 颜色数
unsigned long int biImpColors; // 重要颜色数
BmpRgbQuad palette[2]; // 调色板
}__attribute__ ((packed)) BitmapHead;
#pragma pack(4)
class BWBmp
{
public:
BWBmp();
public:
int LoadBiBmp(QString filename);
int SavePrBmp(QString filename);
int Compress(int dir = 1);
int LoadPrBmp(QString filename);
int Unpress();
int SaveBiBmp(QString filename);
QByteArray getPrBmpDat();
private:
QByteArray m_bwDdat;
QByteArray m_prDdat;
QByteArray m_rbwDdat;
QString m_fileName;
};
#endif // BWBMP_H

View File

@ -0,0 +1,741 @@
#include "creatprintbmp.h"
CreatPrintBmp::CreatPrintBmp(QObject *parent) : QObject(parent)
{
m_savePath.clear();
m_workState = PAUSE;
m_beginPrintFileIdx = -1;
m_fileBegIdx = -1;
m_fileEndIdx = -1;
m_deleteFileIdx = -1;
m_curFileIdx = -1;//当前生成数据的文件索引
m_curBmpBlockIdx = -1;//当前生成数据的位图块数索引
m_mcPrintInfo = NULL;
m_conpressDir = 1;
m_printFileDir.clear();
m_moveFileIdx = -1;//上下移动打印文件索引
m_moveDir = 0;//-1,上移 1下移
}
CreatPrintBmp::~CreatPrintBmp()
{
if(m_mcPrintInfo != NULL)
{
m_mcPrintInfo->clear();
delete m_mcPrintInfo;
}
}
int CreatPrintBmp::creatFileListMarker()
{
if(m_mcPrintInfo->m_loadFileFinishFlag < 0)
{
QString iniName = "MachineNo" + QString::number(m_mcPrintInfo->m_mcNum) + ".ini";
QDir apppath(qApp->applicationDirPath());
QString iniPath = apppath.path() + apppath.separator() + iniName;
QSettings setting(iniPath, QSettings::IniFormat); //QSettings能记录一些程序中的信息下次再打开时可以读取出来
QString dirPath = setting.value("AutoPrintDir/fileDir").toString();
QDir dir(dirPath);
if(dir.exists())
{
QStringList filter;
filter << QString("*.plt") << QString("*.PLT")
<< QString("*.png") << QString("*.PNG")
<< QString("*.bmp") << QString("*.BMP")
<< QString("*.jpg") << QString("*.JPG");
QFileInfoList fileList = dir.entryInfoList(filter, QDir::Files | QDir::NoSymLinks);
for(int i = 0; i < fileList.size(); i++)
{
if(m_workState == WORK_PAUSE)
{
return -1;
}
//QCoreApplication::processEvents(QEventLoop::AllEvents);
QFileInfo fileInfo(fileList[i]);
QString filePath = fileInfo.filePath();
if(m_mcPrintInfo->m_filesList.size() > i)
{
//已经生成数据的跳过
if(m_mcPrintInfo->m_filesList[i].m_creatDataFlag != 1)
{
McFilesInfo curFilesInfo;//当前文件信息
creatMarkerDat(curFilesInfo,filePath,i);
long long fileTotalLength = (curFilesInfo.m_fileRect.right() - curFilesInfo.m_fileRect.left())/M_IDPMM;
m_mcPrintInfo->m_fileNums = i+1;
m_mcPrintInfo->m_fileTotalLength += fileTotalLength;
m_mcPrintInfo->m_filesList.append(curFilesInfo);
}
}
else
{
McFilesInfo curFilesInfo;//当前文件信息
creatMarkerDat(curFilesInfo,filePath,i);
long long fileTotalLength = (curFilesInfo.m_fileRect.right() - curFilesInfo.m_fileRect.left())/M_IDPMM;
m_mcPrintInfo->m_fileNums = i+1;
m_mcPrintInfo->m_fileTotalLength += fileTotalLength;
m_mcPrintInfo->m_filesList.append(curFilesInfo);
}
}
m_mcPrintInfo->m_loadFileFinishFlag = 1;
}
}
QDir apppath(qApp->applicationDirPath());
QString printPath = apppath.path() + apppath.separator() + PRINTDIR;
QDir printDir(printPath);//总的打印目录
if(!printDir.exists())
{
printDir.mkdir(printPath);
}
QString mcFile = printPath + printDir.separator() + PRINTMCDIR + QString::number(m_mcPrintInfo->m_mcNum);
QDir mcDir(mcFile);//对应每台机器打印目录
if(!mcDir.exists())
{
mcDir.mkdir(mcFile);
}
return 0;
}
void CreatPrintBmp::creatMarkerDat(McFilesInfo &curFilesInfo, QString filePath, int fileIdx)
{
QFileInfo fileInfo(filePath);
curFilesInfo.m_marker.Initialize();
if(fileInfo.suffix().toUpper() == "PLT")
{
ImportHPGL importHPGL;
curFilesInfo.m_fileType = TYPE_FILE;
//判断是否为加密文件
if (importHPGL.IsSecretFile(filePath) == true)
{
// 文件路径
QString strSecretFile = m_printFileDir + QString::number(fileIdx+1) ;
QDir fileDir(strSecretFile);//对应每台机器的每个文件打印目录
if(!fileDir.exists())
{
fileDir.mkdir(strSecretFile);
}
strSecretFile = strSecretFile + fileDir.separator() + "Secret.plt";
//qDebug()<<"strSecretFile"<<strSecretFile;
importHPGL.BitMapDtat(filePath,strSecretFile);
importHPGL.IniPara();
importHPGL.ReadSecretFile(strSecretFile,&curFilesInfo.m_marker);
//qDebug()<<"importHPGL.IsSecretFile";
}
else
{
importHPGL.IniPara();
importHPGL.Read(filePath,&curFilesInfo.m_marker);
}
curFilesInfo.m_fileRect = curFilesInfo.m_marker.GetRect();
}
else
{
curFilesInfo.m_fileType = TYPE_IMAGE;
QBitmap pixmap;
pixmap.load(filePath);
QRect rect;
rect.setRect(0,0,pixmap.width()/MMPIXELY*M_IDPMM,pixmap.height()/MMPIXELY*M_IDPMM);
curFilesInfo.m_pixmap = pixmap;
curFilesInfo.m_fileRect = rect;
}
curFilesInfo.m_filePath = filePath;
curFilesInfo.m_fileName = fileInfo.fileName();
curFilesInfo.m_printNum = 1;
curFilesInfo.m_startPoint = 0;
curFilesInfo.m_printState = tr("Waitting");
curFilesInfo.m_curPrintBlock = 0;//当前打印块数
curFilesInfo.m_printedBlockNum = 0;//已打印块数
curFilesInfo.m_selectBlockNum = 0;//当前选择块数
curFilesInfo.m_creatDataFlag = 1;
}
QPicture CreatPrintBmp::getPicture(Marker marker, int penWidth)
{
QPicture pic;
CBitmapInfo bitmapInfo;
QPainterPath painterPath;
QRect rect = marker.GetRect();
int minX = rect.left();
int minY = rect.top();
int maxY = rect.bottom();
int nLineCount = marker.m_listPolyline.size();
for(int i = 0; i < nLineCount; i++)
{
CRPPolyline polyLine = marker.m_listPolyline.at(i);
int type = polyLine.m_nDrawingType;
if(type == 0)//直线
{
int nPointCount = polyLine.m_listPoint.size();
for(int j = 0; j < nPointCount; j++)
{
double x = (polyLine.m_listPoint.at(j).x() - minX)/(double)M_IDPMM*MMPIXELY;
double y = ((0 - (polyLine.m_listPoint.at(j).y() - minY))+(maxY-minY))/(double)M_IDPMM*MMPIXELY;
QPointF point(x,y);
if(j == 0)
{
painterPath.moveTo(point);
}
else
{
painterPath.lineTo(point);
}
}
}
else if(type == 1)//位图
{
bitmapInfo = polyLine.m_bitmapInfo;
int x = bitmapInfo.m_ptAbPostLU.x();
int y = bitmapInfo.m_ptAbPostLU.y();
int nx = (x - minX)/M_IDPMM*MMPIXELY;
int ny = ((0 - (y - minY))+(maxY-minY))/M_IDPMM*MMPIXELY;
bitmapInfo.m_ptAbPostLU.setX(nx);
bitmapInfo.m_ptAbPostLU.setY(ny);
}
}
if(painterPath.isEmpty())
{
qDebug()<<"painterPath isEmpty";
}
//将路径画在picture上
QPen pen;
pen.setWidth(penWidth);//设置笔号
pen.setColor(QColor(Qt::black));
QPainter painter;
painter.begin(&pic);
painter.setPen(pen);
painter.drawPath(painterPath);
if(bitmapInfo.m_iBytes > 0)//有位图
{
painter.drawPixmap(bitmapInfo.m_ptAbPostLU.x(),bitmapInfo.m_ptAbPostLU.y(),bitmapInfo.m_pBitmap);
}
painter.end();
return pic;
}
int CreatPrintBmp::creatFileListDatAndSend(int idx)
{
if(idx >= m_mcPrintInfo->m_filesList.size())
{
return 1;
}
McFilesInfo curFilesInfo;
if(m_workState == WORK_PAUSE)
{
return -1;
}
curFilesInfo = m_mcPrintInfo->m_filesList[idx];
QString filePath = m_printFileDir + QString::number(idx+1);
QDir fileDir(filePath);//对应每台机器的每个文件打印目录
if(!fileDir.exists())
{
fileDir.mkdir(filePath);
}
filePath = filePath + fileDir.separator();
if(curFilesInfo.m_creatDataFlag < 0)
{
creatMarkerDat(curFilesInfo,m_mcPrintInfo->m_filesList[idx].m_filePath,idx);
m_mcPrintInfo->m_filesList[idx] = curFilesInfo;
}
QPicture pic;
QPen pen;
pen.setWidth(1);
pen.setColor(QColor(Qt::black));
int oft = 0;//起始打印位置的偏移
if(curFilesInfo.m_fileType == TYPE_FILE)
{
//画笔宽度不为1时重画
if(PENWIDTH != 1)
{
pic = getPicture(curFilesInfo.m_marker,PENWIDTH);
}
else
{
pic = m_mcPrintInfo->m_filesList[idx].m_pic;
}
oft = (int)(m_mcPrintInfo->m_filesList[idx].m_startPoint*MMPIXELY);
//将picture保存为多个宽度为PIXMAPWIDTH像素的bmp
m_mcPrintInfo->m_totalNums = (pic.width() - oft) / PIXMAPWIDTH;
int lwidth = (pic.width() - oft) % (PIXMAPWIDTH);
if(lwidth != 0)
{
m_mcPrintInfo->m_totalNums += 1;
}
}
else if(curFilesInfo.m_fileType == TYPE_IMAGE)
{
//将图片画在picture上
QPainter painter;
painter.begin(&pic);
painter.setPen(pen);
painter.drawPixmap(0,0,m_mcPrintInfo->m_filesList[idx].m_pixmap);
painter.end();
//将pixmap保存为多个宽度为PIXMAPWIDTH像素的bmp
m_mcPrintInfo->m_totalNums = curFilesInfo.m_pixmap.width() / PIXMAPWIDTH;
int lwidth = curFilesInfo.m_pixmap.width() % PIXMAPWIDTH;
if(lwidth != 0)
{
m_mcPrintInfo->m_totalNums += 1;
}
}
m_mcPrintInfo->m_filesList[idx].m_pic = pic;
m_mcPrintInfo->m_filesList[idx].m_totalBlocks = (pic.width() - oft)/ PIXMAPWIDTH;
//发送文件列表数据
emit siSendFileListDatToMc(idx);
return 0;
}
int CreatPrintBmp::creatBmpBlockDatAndSend(int idx)
{
QPen pen;
pen.setWidth(1);
pen.setColor(QColor(Qt::black));
int nextNum = idx / m_mcPrintInfo->m_filesList[m_curFileIdx].m_totalBlocks;
if((idx % m_mcPrintInfo->m_filesList[m_curFileIdx].m_totalBlocks) == 0)
{
idx = 0;
}
QPicture pic = m_mcPrintInfo->m_filesList[m_curFileIdx].m_pic;
int oft = (int)(m_mcPrintInfo->m_filesList[m_curFileIdx].m_startPoint*MMPIXELY);
//将picture保存为多个宽度为PIXMAPWIDTH像素的bmp
int num = (pic.width() - oft) / PIXMAPWIDTH;
int lwidth = (pic.width() - oft) % PIXMAPWIDTH;
int height = pic.height();
int offset = 0 - idx * PIXMAPWIDTH + oft;//将picture画在bmp上每次的偏移量bmp的最大尺寸为u16
if(lwidth != 0)
{
num += 1;
}
QBitmap *pixmap = new QBitmap(PIXMAPWIDTH,height);
QPainter *pixPainter = new QPainter();
pixPainter->begin(pixmap);
pixPainter->setPen(pen);
QString filePath = m_printFileDir + QString::number(m_curFileIdx+1);
QDir fileDir(filePath);//对应每台机器的每个文件打印目录
if(!fileDir.exists())
{
fileDir.mkdir(filePath);
}
filePath = filePath + fileDir.separator();
pixmap->fill(Qt::white);//用白色填充
pixPainter->drawPicture(offset,0,pic);
QString path = filePath+QString::number(idx+nextNum*m_mcPrintInfo->m_filesList[m_curFileIdx].m_totalBlocks+1)+".bmp";
bool bls = pixmap->save(path);
while(bls == false)
{
bls = pixmap->save(path);
qDebug()<<"pixmap save failed";
}
//压缩位图
BWBmp bwBmp;
int rslt;
rslt = bwBmp.LoadBiBmp(path);
if (rslt != 0)
{
qDebug() << "open file error" << path;
return -1;
}
rslt = bwBmp.Compress(m_conpressDir);
if (rslt != 0)
{
qDebug() << "Compress error";
return -1;
}
rslt = bwBmp.SavePrBmp(path+".prbmp");
if (rslt != 0)
{
qDebug() << "save prbmp error";
return -1;
}
QByteArray dat = bwBmp.getPrBmpDat();
//发送文件
BmpDatInfo bmpInfo;
memset(&bmpInfo,0,sizeof(BmpDatInfo));
bmpInfo.blkIdx = idx;
bmpInfo.biWidth = pixmap->width();
bmpInfo.biHeight = pixmap->height();
bmpInfo.begPosY = idx * pixmap->width();
bmpInfo.endPosY = (idx+1) * pixmap->width();
if(m_conpressDir == -1)
{
bmpInfo.compDir = 0;
}
else
{
bmpInfo.compDir = 1;
}
//qDebug()<<"dat.size()"<<dat.size();
emit siSendDatToMc(dat, bmpInfo);
m_mcPrintInfo->m_sendedlNums++;
pixPainter->end();
bool bla = pixPainter->isActive();
while(bla == true)
{
bla = pixPainter->isActive();
qDebug()<<"pixPainter isActive";
}
delete pixmap;
delete pixPainter;
return 0;
}
void CreatPrintBmp::slotCreatBmp()
{
#if(1)
int val = creatFileListMarker();
if(val < 0)
{
return;
}
val = creatFileListDatAndSend(m_curFileIdx);
if(val < 0)
{
return;
}
#else
QPen pen;
pen.setWidth(1);
pen.setColor(QColor(Qt::black));
//将picture保存为多个宽度为PIXMAPWIDTH像素的bmp
int num = m_picture.width() / PIXMAPWIDTH;
int lwidth = m_picture.width() % PIXMAPWIDTH;
int height = m_picture.height();
int offset = 0;
if(lwidth != 0)
{
num += 1;
}
QBitmap *pixmap = new QBitmap(PIXMAPWIDTH,height);
QPainter *pixPainter = new QPainter();
pixPainter->begin(pixmap);
pixPainter->setPen(pen);
for(int i = 0 ; i < num; i++)
{
pixmap->fill(Qt::white);//用白色填充
pixPainter->drawPicture(offset,0,m_picture);
offset -= PIXMAPWIDTH;
QString path = m_savePath+QString::number(i+1)+".bmp";
bool bls = pixmap->save(path);
while(bls == false)
{
bls = pixmap->save(path);
qDebug()<<"pixmap save failed";
}
//压缩位图
BWBmp bwBmp;
int rslt;
rslt = bwBmp.LoadBiBmp(path);
if (rslt != 0)
{
qDebug() << "open file error" << path;
break;
}
rslt = bwBmp.Compress();
if (rslt != 0)
{
qDebug() << "Compress error";
break;
}
rslt = bwBmp.SavePrBmp(path+".prbmp");
if (rslt != 0)
{
qDebug() << "save prbmp error";
break;
}
QByteArray dat = bwBmp.getPrBmpDat();
siCreatOneBmpFinished((unsigned char*)dat.data(),dat.size());
}
pixPainter->end();
bool bla = pixPainter->isActive();
while(bla == true)
{
bla = pixPainter->isActive();
qDebug()<<"pixPainter isActive";
}
delete pixmap;
delete pixPainter;
#endif
}
void CreatPrintBmp::slotCreatNextBmpBlockDat()
{
//非正在打印的文件,正在发送文件时的删除操作
if(m_deleteFileIdx != m_curFileIdx && m_deleteFileIdx != -1)
{
int length = (m_mcPrintInfo->m_filesList[m_deleteFileIdx].m_fileRect.right() - m_mcPrintInfo->m_filesList[m_deleteFileIdx].m_fileRect.left())/M_IDPMM;
m_mcPrintInfo->m_fileTotalLength -= length;
m_mcPrintInfo->m_filesList[m_deleteFileIdx].clear();
m_mcPrintInfo->m_filesList.removeAt(m_deleteFileIdx);
QString mcFile = m_printFileDir + QString::number(m_deleteFileIdx+1);
QDir fileDir(mcFile);
if(fileDir.exists())//理论上无此条件
{
//删除位图文件夹
QFileInfoList fileList = fileDir.entryInfoList(QDir::Files);
for(int i = 0; i < fileList.size(); i++)
{
QString fileStr = fileList[i].filePath();
QFile::remove(fileStr);
}
fileDir.rmdir(mcFile);
}
if(m_deleteFileIdx < m_curFileIdx)//理论上无此条件
{
QString oldName = m_printFileDir + QString::number(m_curFileIdx+1);
QDir dir(oldName);
m_curFileIdx--;
QString newName = m_printFileDir + QString::number(m_curFileIdx+1);
dir.rename(oldName,newName);
}
m_mcPrintInfo->m_fileNums = m_mcPrintInfo->m_filesList.size();
m_deleteFileIdx = -1;
emit siDeleteFileFinish();
}
//非正在打印的文件,正在发送文件时的上下移操作
if(m_moveFileIdx != m_curFileIdx && m_moveFileIdx != -1 && m_moveDir != 0)
{
//交换列表
McFilesInfo info = m_mcPrintInfo->m_filesList[m_moveFileIdx];
McFilesInfo cInfo;
cInfo = m_mcPrintInfo->m_filesList[m_moveFileIdx+m_moveDir];
m_mcPrintInfo->m_filesList[m_moveFileIdx+m_moveDir] = info;
m_mcPrintInfo->m_filesList[m_moveFileIdx] = cInfo;
//更换位图文件夹的名称
//判断当前交换的文件夹是否存在
QString mcFile = m_printFileDir + QString::number(m_moveFileIdx+1);
QDir fileDir(mcFile);
if(fileDir.exists())//理论上无此条件
{
//对当前选中文件夹重命名
QString oldName = mcFile;
QString newName = mcFile.left(mcFile.size()-1);
fileDir.rename(oldName,newName);
int cRow = m_moveFileIdx + m_moveDir;
QString mcFile1 = m_printFileDir + QString::number(cRow+1);
QDir fileDir1(mcFile1);
//对要交换的文件夹重命名
oldName = mcFile1;
newName = mcFile;
fileDir1.rename(oldName,newName);
//再对选中的文件夹重命名
QString mcFile2 = mcFile.left(mcFile.size()-1);
QDir fileDir2(mcFile1);
oldName = mcFile2;
newName = mcFile1;
fileDir2.rename(oldName,newName);
}
m_moveFileIdx = -1;
m_moveDir = 0;
}
m_curBmpBlockIdx++;//一个文件可分为若干个位图块,位图块索引++
if(m_curBmpBlockIdx < 0)
{
m_curBmpBlockIdx = 0;
}
if(m_curBmpBlockIdx >= m_mcPrintInfo->m_filesList[m_curFileIdx].m_totalBlocks * m_mcPrintInfo->m_filesList[m_curFileIdx].m_printNum)
{
m_curFileIdx++;//文件索引++
creatFileListDatAndSend(m_curFileIdx);
m_curBmpBlockIdx = -1;
return;
}
creatBmpBlockDatAndSend(m_curBmpBlockIdx);
m_conpressDir *= -1;
}
void CreatPrintBmp::setPicture(QPicture pic)
{
m_picture = pic;
}
void CreatPrintBmp::setPicture(QBitmap bitmap)
{
//将图片画在picture上
QPicture pic;
QPen pen;
pen.setWidth(1);//设置笔号
pen.setColor(QColor(Qt::black));
QPainter painter;
painter.begin(&pic);
painter.setPen(pen);
painter.drawPixmap(0,0,bitmap);
painter.end();
m_picture = pic;
}
void CreatPrintBmp::setSavePath(QString path)
{
m_savePath.clear();
m_savePath = path;
}
QString CreatPrintBmp::getSavePath()
{
return m_savePath;
}
void CreatPrintBmp::setMcPrintInfo(int fileIdx, McPrintInfo *printInfo)
{
m_mcPrintInfo = printInfo;
if(fileIdx < 0)
{
m_fileBegIdx = 0;
}
else
{
m_fileBegIdx = fileIdx;
}
//自动打印
int autoPrint = 1;
if(autoPrint == 1)
{
m_fileEndIdx = m_mcPrintInfo->m_filesList.size();
}
else
{
m_fileEndIdx = m_fileBegIdx + 1;
}
m_curFileIdx = m_fileBegIdx;
QDir apppath(qApp->applicationDirPath());
QString printPath = apppath.path() + apppath.separator() + PRINTDIR;
QString mcFile = printPath + apppath.separator() + PRINTMCDIR + QString::number(m_mcPrintInfo->m_mcNum);
m_printFileDir = mcFile + apppath.separator() + PRINTFILEDIR;
}
void CreatPrintBmp::setDeleteFile(int fileIdx)
{
if(fileIdx == m_curFileIdx)
{
return;
}
m_deleteFileIdx = fileIdx;
//空闲时的删除文件操作
if(m_mcPrintInfo->m_mcWorkState == NotBusy)
{
int length = (m_mcPrintInfo->m_filesList[m_deleteFileIdx].m_fileRect.right() - m_mcPrintInfo->m_filesList[m_deleteFileIdx].m_fileRect.left())/M_IDPMM;
m_mcPrintInfo->m_fileTotalLength -= length;
m_mcPrintInfo->m_filesList[m_deleteFileIdx].clear();
m_mcPrintInfo->m_filesList.removeAt(m_deleteFileIdx);
QString mcFile = m_printFileDir + QString::number(m_deleteFileIdx+1);
QDir fileDir(mcFile);
if(fileDir.exists())
{
//删除位图文件夹
QFileInfoList fileList = fileDir.entryInfoList(QDir::Files);
for(int i = 0; i < fileList.size(); i++)
{
QString fileStr = fileList[i].filePath();
QFile::remove(fileStr);
}
fileDir.rmdir(mcFile);
}
m_mcPrintInfo->m_fileNums = m_mcPrintInfo->m_filesList.size();
m_deleteFileIdx = -1;
emit siDeleteFileFinish();
}
}
void CreatPrintBmp::setMoveFile(int fileIdx, int dir)
{
if(fileIdx == m_curFileIdx)
{
return;
}
m_moveFileIdx = fileIdx;//上下移动打印文件索引
m_moveDir = dir;//-1,上移 1下移
//空闲时的移动文件操作
if(m_mcPrintInfo->m_mcWorkState == NotBusy)
{
//交换列表
McFilesInfo info = m_mcPrintInfo->m_filesList[fileIdx];
McFilesInfo cInfo;
if(dir == -1)
{
cInfo = m_mcPrintInfo->m_filesList[fileIdx-1];
m_mcPrintInfo->m_filesList[fileIdx-1] = info;
}
else
{
cInfo = m_mcPrintInfo->m_filesList[fileIdx+1];
m_mcPrintInfo->m_filesList[fileIdx+1] = info;
}
m_mcPrintInfo->m_filesList[fileIdx] = cInfo;
m_moveFileIdx = -1;//上下移动打印文件索引
m_moveDir = 0;//-1,上移 1下移
}
}

View File

@ -0,0 +1,94 @@
#ifndef CREATPRINTBMP_H
#define CREATPRINTBMP_H
#include <QObject>
#include <QPicture>
#include <QPainter>
#include <QPicture>
#include <QDebug>
#include <QFile>
#include <QBitmap>
#include <QThread>
#include <QSettings>
#include <QDir>
#include "bwbmp.h"
#include "machine/printinfo/mcfiles.h"
#include "datafile/hpgl/importhpgl.h"
#define TYPE_FILE 0
#define TYPE_IMAGE 1
#define PIXMAPWIDTH 1200
#define PENWIDTH 5
#define START 1
#define PAUSE 0
#define PRINTDIR "print"
#define PRINTMCDIR "mc"
#define PRINTFILEDIR "file"
typedef struct
{
u32 blkIdx; // 当前位图块号(位图分块后的编号)
u32 biWidth; // 本块位图有效宽度,以像素为单位
u32 biHeight; // 本块位图有效高度,以像素为单位
u32 begPosY; // 本块起始位置(像素单位)
u32 endPosY; // 本块结束位置(像素单位)
u8 compType; // 本块位图压缩类型, =0, 不压缩; =1, 按字节压缩;
u8 compDir; // 本块位图压缩方向, =0, 从上到下; =1, 从下到上;(喷墨方向)
}__attribute__ ((packed)) BmpDatInfo;
class CreatPrintBmp : public QObject
{
Q_OBJECT
public:
explicit CreatPrintBmp(QObject *parent = NULL);
virtual ~CreatPrintBmp();
private:
QPicture m_picture;//绘图路径-线段
QString m_savePath;
int m_workState;
int m_beginPrintFileIdx;//开始打印文件索引
int m_deleteFileIdx;//删除打印文件索引
McPrintInfo *m_mcPrintInfo;//机器信息
int m_fileBegIdx;
int m_fileEndIdx;
int m_curFileIdx;//当前生成数据的文件索引
int m_curBmpBlockIdx;//当前生成数据的位图块数索引
int m_conpressDir;//压缩方向
QString m_printFileDir;//打印文件目录
int m_moveFileIdx;//上下移动打印文件索引
s16 m_moveDir;//-1,上移 1下移
private:
int creatFileListMarker();//加载文件列表marker数据
void creatMarkerDat(McFilesInfo &curFilesInfo, QString filePath, int fileIdx);//创建Marker数据
QPicture getPicture(Marker marker,int penWidth = 1);
int creatFileListDatAndSend(int idx);//创建文件列表数据并发送
int creatBmpBlockDatAndSend(int idx);//创建位图块数据并发送
public:
void setPicture(QPicture pic);
void setPicture(QBitmap bitmap);
void setSavePath(QString path);
QString getSavePath();
void setMcPrintInfo(int fileIdx,McPrintInfo *printInfo);//设置机器信息
void setDeleteFile(int fileIdx);//删除文件
void setMoveFile(int fileIdx, int dir = -1);//上下移动文件
signals:
void siCreatOneBmpFinished(int mcIdx,unsigned char *dat,int datSize);
void siSendFileListDatToMc(int idx);
void siSendDatToMc(QByteArray dat, BmpDatInfo bmpInfo);
void siDeleteFileFinish();//删除文件完成
public slots:
void slotCreatBmp();
void slotCreatNextBmpBlockDat();//创建下一个位图块数据
};
#endif // CREATPRINTBMP_H

438
machine/comm/comm.cpp Normal file
View File

@ -0,0 +1,438 @@
//-------------------------------------------------------------------------------
// File Name: comm.cpp
// Brief:
// Version: 1.0.0
// Create Date: 2017/05/08
// Create by: Marshal Lee
// Copyright:
// Copyright (c) 2017, Richpeace Co., LTD.
// All rights reserved.
//
// Modify by: Marshal Lee
// Modify Date: 2017/05/08
//-------------------------------------------------------------------------------
#define _IN_COMM_CPP
#include "comm.h"
#include "crc16.h"
//--------------------------------------------------------------------------------------------------
// 读空缓冲区
void readBuffEmpty(DataExFuns * funs)
{
int rslt, len;
u8 temp;
len = funs->getRsvLen();
while (len > 0)
{
rslt = funs->getCommData(&temp, 1);
if (rslt != 1)
{
rslt = 0;
break;
}
len--;
}
}
//--------------------------------------------------------------------------------------------------
// 功能: 从通讯口接收缓冲区中得到一个数据包, 如果有附加数据,包括附加数据
// 参数: pPacket, 数据包指针
// 返回: >=0, 成功取得一个数据包,包括定长数据包和可变长度数据包,返回值为数据包长度
// -1, 参数错误
// -2, CRC错误
// -3, 数据不足
// -4, 没有找到同步序列
// -5等待接收数据超时
// -6, 数据包参数错误
// -7, 附加数据CRC错误
// -8, 发生未知错误
// 结果: 如果正确取得数据包,或通讯口没有命令, 循环队列尾指针回向后移动
int getANormalPacket(DataExFuns * funs, DataPacket * pPacket)
{
int rslt, len;
int i;
int phase;
int status;
int exlen;
static int rdstatus = 0;
static u8 odBuf[LEN_NORMAL_PACKET];
u8 temp;
u8 rdBuf[LEN_NORMAL_PACKET];
DataPacket * pDat;
u8 getBuf[LEN_NORMAL_PACKET-DP_SYNC_LEN];
int getBuflen;
int getIdx;
u8 tmpBuf[LEN_NORMAL_PACKET-DP_SYNC_LEN];
int tmpBuflen;
if (funs == NULL || pPacket == NULL)
{
return -1;
}
rslt = 0;
i = 0; // 扫描字节计数器
getBuflen = 0;
getIdx = 0;
tmpBuflen = 0;
pDat = (DataPacket *)rdBuf;
if (rdstatus == 0)
{
do
{
len = funs->getRsvLen(); // 得到接收长度
len += getBuflen; // 加上已经获取的长度
if (len < LEN_NORMAL_PACKET)
{
rslt = -3;
break; // 没有足够数据
}
phase = 0;
status = 0;
rslt = 0;
// 从接收缓冲区中找数据包
while(((len + phase) >= LEN_NORMAL_PACKET) && (phase < LEN_NORMAL_PACKET))
{
if (getBuflen == 0)
{
if (phase == 0 && i > MAX_ONCE_SCAN)
{
rslt = -4;
break; // 查找同步序列超出最大单次扫描字节数
}
rslt = funs->getCommData(&temp, 1);
if (rslt != 1)
{
printf("error at GetCommData rslt\r\n");
rslt = -8;
break;
}
rslt = 0;
i++; // 扫描字数增加
}
else
{
temp = getBuf[getIdx];
getIdx++;
getBuflen--;
}
len--; // 剩余长度减小
pDat->buff.normal[phase] = temp;
if (phase < DP_SYNC_LEN) // 识别同步序列
{
tmpBuflen = 0;
if (phase == 0)
{
if (temp == FLDP_SYNC[0])
{
status = 1;
}
else if (temp == VLDP_SYNC[0])
{
status = 2;
}
else
{
status = 0;
phase = 0;
rslt = 0; // 非同步序列
break;
}
}
else
{
if (status == 1)
{
if (temp != FLDP_SYNC[phase])
{
status = 0;
phase = 0;
rslt = 0;
break;
}
}
else if (status == 2)
{
if (temp != VLDP_SYNC[phase])
{
status = 0;
phase = 0;
rslt = 0;
break;
}
}
else
{
printf("error status in GetANormalPacket\r\n");
rslt = -8;
break;
}
}
}
else
{
tmpBuf[tmpBuflen] = temp;
tmpBuflen++;
}
phase++;
}
if (rslt != 0)
{
break;
}
if (phase >= LEN_NORMAL_PACKET) // 得到数据包
{
u16 crc;
crc = calcCrc16(pDat->normal.content, DP_CONT_LEN);
if (crc == pDat->normal.crc)
{
// 得到正确数据包
memcpy(pPacket, pDat, LEN_NORMAL_PACKET);
// printf("GetANormalPacket ok\r\n");
rslt = LEN_NORMAL_PACKET;
break;
}
else
{
// CRC 不正确
printf("crc error in GetANormalPacket\r\n");
// 拷贝需要再判断的数据
if (tmpBuflen != 0)
{
memcpy(getBuf, tmpBuf, tmpBuflen);
}
getBuflen = tmpBuflen;
getIdx = 0;
// continue;
}
}
else
{
// 没有找到同步序列的情况
getBuflen = 0;
getIdx = 0;
// continue;
}
}while(1);
}
if (rdstatus == 1)
{
memcpy(pPacket, odBuf, LEN_NORMAL_PACKET);
rslt = LEN_NORMAL_PACKET;
}
// 附加数据
if (rslt == LEN_NORMAL_PACKET)
{
if (memcmp(pPacket->normal.sync, VLDP_SYNC, DP_SYNC_LEN) == 0) // 是可变长度数据包
{
exlen = pPacket->vldp.exlen;
if (exlen > MAX_EXDP_LEN)
{
printf("data exlen error, len=%d\r\n", exlen);
return -6; // 数据包参数错误
}
memset(pPacket->buff.exData, 0, MAX_EXDP_LEN);
i = 0;
status = 0; // 作为历史计数器
// 读取附加数据
do
{
rslt = funs->getCommData(pPacket->buff.exData, exlen);
if (rslt == exlen)
{
u16 crc;
// 校验CRC
crc = calcCrc16(pPacket->buff.exData, exlen);
if (crc == pPacket->vldp.excrc)
{
// printf("get exdata ok\r\n");
rslt = exlen+LEN_NORMAL_PACKET;
}
else
{
printf("crc error at get exdata\r\n");
rslt = -7; // CRC错误
}
rdstatus = 0;
break; // 得到数据
}
else if (rslt == 0)
{
memcpy(odBuf, pPacket, LEN_NORMAL_PACKET);
rdstatus = 1;
rslt = -3;
break;
/*
// 数据不足
if (funs->delay != NULL)
{
funs->delay(1); // 延时等待
}
len = funs->getRsvLen(); // 得到接收数据长度
qDebug()<<"getRsvLen"<<len;
if (len != status) // 和上次长度比较
{
status = len;
i = 0;
}
else // 如果没有变化,则计数器增加
{
i++;
if (i > GTEX_TIME_OUT) // 如果无变化计数器值大于超时值
{
qDebug()<<"call GetCommData timeout";
rslt = -5;
break;
}
}
*/
}
else
{
qDebug()<<"error after call GetCommData";
break;
}
}while(1);
}
}
return rslt;
}
//--------------------------------------------------------------------------------------------------
// 功能: 添加数据到发送队列中, 通过通讯口发送数据
// 参数: pPacket, 需要发送的数据,已经正确存放在了相应字段。
// 结果:
// 0, 可以发送, 添加到了发送数据队列中
// -1, 参数错误
// -2发送错误
// 1, 队列已满, 不能发送
int sendAPacket(DataExFuns * funs, DataPacket * pPacket)
{
int rslt;
int freelen, sendlen;
if (pPacket == NULL)
{
return -1;
}
if (memcmp(pPacket->normal.sync, FLDP_SYNC, DP_SYNC_LEN) == 0)
{
sendlen = LEN_NORMAL_PACKET;
}
else if (memcmp(pPacket->normal.sync, VLDP_SYNC, DP_SYNC_LEN) == 0)
{
sendlen = LEN_NORMAL_PACKET + pPacket->vldp.exlen;
}
else
{
printf("para err, not a corrected packet\r\n");
return -1;
}
freelen = funs->getTrsFreeLen();
if (freelen < sendlen)
{
// printf("buff is full in SendAPacket\r\n");
return 1;
}
rslt = funs->sendCommData(pPacket->datbuff, sendlen);
if (rslt != sendlen)
{
printf("error at call SendCommData, rslt=%d\r\n", rslt);
return -2;
}
return 0;
}
//--------------------------------------------------------------------------------------------------
// 功能: 打包一个固定长度数据包
// 参数:
// pPacket, 需要打包的数据包其中除了sync和crc的部分已经就绪
// 结果:
// 0, 打包好数据
// -1, 参数错误
int packetAFLDP(DataPacket * pPacket)
{
if (pPacket == NULL)
{
return -1;
}
memcpy(pPacket->normal.sync, FLDP_SYNC, DP_SYNC_LEN);
pPacket->normal.crc = calcCrc16(pPacket->normal.content, DP_CONT_LEN);
return 0;
}
//--------------------------------------------------------------------------------------------------
// 功能: 打包一个可变长度数据包
// 参数: pPacket, 需要打包的数据包,需要填充其中的 SYNC EXLEN EXCRC 和 EXDAT 等部分
// pExdat, 附加数据,可以为空
// exlen附加数据长度可以为0
// 结果:
// 0, 打包好数据
// -1, 参数错误
// -2
int packetAVLDP(DataPacket * pPacket, u8 * pExdat, u16 exlen)
{
if (pPacket == NULL)
{
return -1;
}
if (pExdat == NULL)
{
exlen = 0;
}
memcpy(pPacket->vldp.sync, VLDP_SYNC, DP_SYNC_LEN);
pPacket->vldp.exlen = exlen;
pPacket->vldp.excrc = calcCrc16(pExdat, exlen);
pPacket->vldp.crc = calcCrc16(pPacket->normal.content, DP_CONT_LEN);
if (exlen != 0)
{
memcpy(pPacket->vldp.exData, pExdat, exlen);
}
return 0;
}
//--------------------------------------------------------------------------------------------------

205
machine/comm/comm.h Normal file
View File

@ -0,0 +1,205 @@
//-------------------------------------------------------------------------------
// File Name: comm.h
// Brief:
// Version: 1.0.0
// Create Date: 2017/05/08
// Create by: Marshal Lee
// Copyright:
// Copyright (c) 2017, Richpeace Co., LTD.
// All rights reserved.
//
// Modify by: Marshal Lee
// Modify Date: 2017/05/08
//-------------------------------------------------------------------------------
#ifndef __COMM_H__
#define __COMM_H__
#include "typedef.h"
#include <string.h>
#include <QDebug>
#include <stdio.h>
//------------------------------------------------------------------------
// 通讯数据包定义
//------------------------------------
/*
1.
|-------------------------------------------------------------------|-----------|
| | | |
|-------------------------------------------------------------------|-----------|
| B0 B1 B2 B3 | B4 B5 | B6 B7 B8 B9 B10 B11 B12 B13 | B14 B15 |
|-------------------------------------------------------------------|-----------|
| | | | B4--B13的 |
| | ID | | |
| 'F','L','D','P' | | | 16CRC |
|-------------------------------------------------------------------|-----------|
2.
|---------------------------------------------------------------------------|-----------|----------------
| | | | |
|---------------------------------------------------------------------------|-----------|---------------|
| B0 B1 B2 B3 | B4 B5 | B6 B7 | B8 B9 | B10 B11 B12 B13 | B14 B15 | B16--Bn |
|---------------------------------------------------------------------------|-----------|---------------|
| | | | | | B4--B13的 | |
| | ID | | | | | |
| 'V','L','D','P' | | | | | 16CRC | |
|---------------------------------------------------------------------------|-----------|---------------|
0--1024
*/
//------------------------------------
#define DP_SYNC_LEN 4 // 数据识别序列长度
#define DP_CONT_LEN 10 // 数据内容长度
#define DP_CRC_LEN 2 // 校验字长度
#define MAX_EXDP_LEN 1024 // 最大附加数据长度
#define LEN_NORMAL_PACKET (DP_SYNC_LEN+DP_CONT_LEN+DP_CRC_LEN)
#define MAX_INDP_PARA 8
#ifdef _IN_COMM_CPP
const u8 FLDP_SYNC[DP_SYNC_LEN] =
{
'F','L','D','P',
};
const u8 VLDP_SYNC[DP_SYNC_LEN] =
{
'V','L','D','P',
};
#else
extern const u8 FLDP_SYNC[DP_SYNC_LEN];
extern const u8 VLDP_SYNC[DP_SYNC_LEN];
#endif
//-----------------------------------------------------------------------
typedef union
{
u8 datbuff[LEN_NORMAL_PACKET+MAX_EXDP_LEN]; // dat buff 方式
struct
{
u8 normal[LEN_NORMAL_PACKET];
u8 exData[MAX_EXDP_LEN];
} __attribute__ ((packed)) buff; // buff方式
struct
{
u8 sync[DP_SYNC_LEN];
u8 content[DP_CONT_LEN];
u16 crc;
} __attribute__ ((packed)) normal; // 通用方式
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmd;
u8 para[8];
u16 crc;
} __attribute__ ((packed)) fldp; // fldp方式
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmd;
u16 exlen;
u16 excrc;
u8 para[4];
u16 crc;
u8 exData[MAX_EXDP_LEN];
} __attribute__ ((packed)) vldp; // vldp方式
} DataPacket;
//-----------------------------------------------------------------------
typedef struct
{
int (*sendCommData)(u8 *, int);
int (*getCommData)(u8 *, int);
int (*getRsvLen)(void);
int (*getTrsFreeLen)(void);
void (*delay)(u32);
} DataExFuns;
//-----------------------------------------------------------------------
// 读空缓冲区
void readBuffEmpty(DataExFuns * funs);
//-----------------------------------------------------------------------
// 功能: 从通讯口接收缓冲区中得到一个数据包,
// 只能取得普通数据包结构. 如果数据包还有附加数据, 那么需要用 GetExCommData 函数取得
// 参数: pPacket, 数据包指针
// 返回: >=0, 成功取得一个数据包,包括定长数据包和可变长度数据包,返回值为数据包长度
// -1, 参数错误
// -2, CRC错误
// -3, 数据不足
// -4, 没有找到同步序列
// -5等待接收数据超时
// -6, 数据包参数错误
// -7, 附加数据CRC错误
// -8, 发生未知错误
// 结果: 如果正确取得数据包,或通讯口没有命令, 循环队列尾指针回向后移动
#define MAX_ONCE_SCAN (LEN_NORMAL_PACKET*10) // 一次扫描最大字节数
#define GTEX_TIME_OUT 100 // 得到数据包超时时间单位是ms
int getANormalPacket(DataExFuns * funs, DataPacket * pPacket);
//--------------------------------------------------------------------------------------------------
// 功能: 添加数据到发送队列中, 通过通讯口发送数据
// 参数: pPacket, 需要发送的数据,已经正确存放在了相应字段。
// 结果:
// 0, 可以发送, 添加到了发送数据队列中
// -1, 参数错误
// -2发送错误
// 1, 队列已满, 不能发送
int sendAPacket(DataExFuns * funs, DataPacket * pPacket);
//--------------------------------------------------------------------------------------------------
// 功能: 打包一个固定长度数据包
// 参数:
// pPacket, 需要打包的数据包其中除了sync和crc的部分已经就绪
// 结果:
// 0, 打包好数据
// -1, 参数错误
int packetAFLDP(DataPacket * pPacket);
//--------------------------------------------------------------------------------------------------
// 功能: 打包一个可变长度数据包
// 参数: pPacket, 需要打包的数据包,需要填充其中的 SYNC EXLEN EXCRC 和 EXDAT 等部分
// pExdat, 附加数据,可以为空
// exlen附加数据长度可以为0
// 结果:
// 0, 打包好数据
// -1, 参数错误
// -2
int packetAVLDP(DataPacket * pPacket, u8 * pExdat, u16 exlen);
//--------------------------------------------------------------------------------------------------
#endif

159
machine/comm/crc16.cpp Normal file
View File

@ -0,0 +1,159 @@

//-------------------------------------------------------------------------------
// File Name: crc16.cpp
// Brief:
// Version: 1.0.0
// Create Date: 2017/05/08
// Create by: Marshal Lee
// Copyright:
// Copyright (c) 2017, Richpeace Co., LTD.
// All rights reserved.
//
// Modify by: Marshal Lee
// Modify Date: 2017/05/08
//-------------------------------------------------------------------------------
#include "crc16.h"
//-------------------------------------------------------------------------------
#ifdef USE_CRC_TABLE
// 16 位 crc 列表
u16 CRC16_LIST[256] =
{
0x0000, 0x3096, 0x612C, 0x51BA, 0xC419, 0xF48F, 0xA535, 0x95A3,
0x8832, 0xB8A4, 0xE91E, 0xD988, 0x4C2B, 0x7CBD, 0x2D07, 0x1D91,
0x1064, 0x20F2, 0x7148, 0x41DE, 0xD47D, 0xE4EB, 0xB551, 0x85C7,
0x9856, 0xA8C0, 0xF97A, 0xC9EC, 0x5C4F, 0x6CD9, 0x3D63, 0x0DF5,
0x20C8, 0x105E, 0x41E4, 0x7172, 0xE4D1, 0xD447, 0x85FD, 0xB56B,
0xA8FA, 0x986C, 0xC9D6, 0xF940, 0x6CE3, 0x5C75, 0x0DCF, 0x3D59,
0x30AC, 0x003A, 0x5180, 0x6116, 0xF4B5, 0xC423, 0x9599, 0xA50F,
0xB89E, 0x8808, 0xD9B2, 0xE924, 0x7C87, 0x4C11, 0x1DAB, 0x2D3D,
0x4190, 0x7106, 0x20BC, 0x102A, 0x8589, 0xB51F, 0xE4A5, 0xD433,
0xC9A2, 0xF934, 0xA88E, 0x9818, 0x0DBB, 0x3D2D, 0x6C97, 0x5C01,
0x51F4, 0x6162, 0x30D8, 0x004E, 0x95ED, 0xA57B, 0xF4C1, 0xC457,
0xD9C6, 0xE950, 0xB8EA, 0x887C, 0x1DDF, 0x2D49, 0x7CF3, 0x4C65,
0x6158, 0x51CE, 0x0074, 0x30E2, 0xA541, 0x95D7, 0xC46D, 0xF4FB,
0xE96A, 0xD9FC, 0x8846, 0xB8D0, 0x2D73, 0x1DE5, 0x4C5F, 0x7CC9,
0x713C, 0x41AA, 0x1010, 0x2086, 0xB525, 0x85B3, 0xD409, 0xE49F,
0xF90E, 0xC998, 0x9822, 0xA8B4, 0x3D17, 0x0D81, 0x5C3B, 0x6CAD,
0x8320, 0xB3B6, 0xE20C, 0xD29A, 0x4739, 0x77AF, 0x2615, 0x1683,
0x0B12, 0x3B84, 0x6A3E, 0x5AA8, 0xCF0B, 0xFF9D, 0xAE27, 0x9EB1,
0x9344, 0xA3D2, 0xF268, 0xC2FE, 0x575D, 0x67CB, 0x3671, 0x06E7,
0x1B76, 0x2BE0, 0x7A5A, 0x4ACC, 0xDF6F, 0xEFF9, 0xBE43, 0x8ED5,
0xA3E8, 0x937E, 0xC2C4, 0xF252, 0x67F1, 0x5767, 0x06DD, 0x364B,
0x2BDA, 0x1B4C, 0x4AF6, 0x7A60, 0xEFC3, 0xDF55, 0x8EEF, 0xBE79,
0xB38C, 0x831A, 0xD2A0, 0xE236, 0x7795, 0x4703, 0x16B9, 0x262F,
0x3BBE, 0x0B28, 0x5A92, 0x6A04, 0xFFA7, 0xCF31, 0x9E8B, 0xAE1D,
0xC2B0, 0xF226, 0xA39C, 0x930A, 0x06A9, 0x363F, 0x6785, 0x5713,
0x4A82, 0x7A14, 0x2BAE, 0x1B38, 0x8E9B, 0xBE0D, 0xEFB7, 0xDF21,
0xD2D4, 0xE242, 0xB3F8, 0x836E, 0x16CD, 0x265B, 0x77E1, 0x4777,
0x5AE6, 0x6A70, 0x3BCA, 0x0B5C, 0x9EFF, 0xAE69, 0xFFD3, 0xCF45,
0xE278, 0xD2EE, 0x8354, 0xB3C2, 0x2661, 0x16F7, 0x474D, 0x77DB,
0x6A4A, 0x5ADC, 0x0B66, 0x3BF0, 0xAE53, 0x9EC5, 0xCF7F, 0xFFE9,
0xF21C, 0xC28A, 0x9330, 0xA3A6, 0x3605, 0x0693, 0x5729, 0x67BF,
0x7A2E, 0x4AB8, 0x1B02, 0x2B94, 0xBE37, 0x8EA1, 0xDF1B, 0xEF8D
};
#else
#ifdef SHIFT_RIGHT // 如果是右移
#define CRC_GEN 0xa001 // 使用多项式 0xa001
#else // 如果是左移
#define CRC_GEN 0x8005 // 使用多项式 0x8005
#endif // #ifdef SHIFT_RIGHT
#endif
//-------------------------------------------------------------------------------
u16 addCrc16(u16 crcword, u8 dat)
{
#ifdef USE_CRC_TABLE // 查表法crc
crcword = (crcword >> 8) ^ CRC16_LIST[(crcword ^ dat) & 0xFF];
#else
u8 i;
crcword ^= dat;
for (i = 0; i < 8; i++)
{
#ifdef SHIFT_RIGHT // 右移计算crc
if ((LOBYTE(crcword) & 0x01) != 0)
{
crcword >>= 1;
crcword ^= CRC_GEN;
}
else
{
crcword >>= 1;
}
#else // 左移计算crc
if ((HIBYTE(crcword) & 0x80) != 0)
{
crcword <<= 1;
crcword ^= CRC_GEN;
}
else
{
crcword <<= 1;
}
#endif
}
#endif
return crcword;
}
//-------------------------------------------------------------------------------
u16 calcCrc16(u8 * pBuf, int lenBuf)
{
int i;
u16 crcword = CRC_INIT;
for (i = 0; i < lenBuf; i++)
{
crcword = addCrc16(crcword, pBuf[i]);
}
return crcword;
}
//-------------------------------------------------------------------------------
u8 calcCheckSum8(u8 * pBuf, int lenBuf)
{
int i;
u8 checksum = 0;
for (i = 0; i < lenBuf; i++)
{
checksum += pBuf[i];
}
return checksum;
}
//-------------------------------------------------------------------------------
u32 calcCheckSum32(u8 * pBuf, int lenBuf)
{
int i;
u32 checksum = 0;
for (i = 0; i < lenBuf; i++)
{
checksum += pBuf[i];
}
return checksum;
}

60
machine/comm/crc16.h Normal file
View File

@ -0,0 +1,60 @@
//-------------------------------------------------------------------------------
// File Name: crc16.h
// Brief:
// Version: 1.0.0
// Create Date: 2017/05/08
// Create by: Marshal Lee
// Copyright:
// Copyright (c) 2017, Richpeace Co., LTD.
// All rights reserved.
//
// Modify by: Marshal Lee
// Modify Date: 2017/05/08
//-------------------------------------------------------------------------------
#ifndef __CRC16_H__
#define __CRC16_H__
/*
CRC16
CRC16
*/
#include "typedef.h"
#define USE_CRC_TABLE // 用查表法crc, 否则, 用移位法计算
#define SHIFT_RIGHT // 右移位
#ifdef USE_CRC_TABLE
#define CRC_INIT 0x0000 // 并且crc初值为0
#else
#ifdef SHIFT_RIGHT // 如果是右移
#define CRC_INIT 0xFFFF // crc初值为0xFFFF
#else // 如果是左移
#define CRC_INIT 0x0000 // 并且crc初值为0
#endif // #ifdef SHIFT_RIGHT
#endif
u16 calcCrc16(u8 * pBuf, int lenBuf);
u8 calcCheckSum8(u8 * pBuf, int lenBuf);
u32 calcCheckSum32(u8 * pBuf, int lenBuf);
#endif

74
machine/comm/crc32.cpp Normal file
View File

@ -0,0 +1,74 @@

//-------------------------------------------------------------------------------
// File Name: crc32.c
// Brief:
// Version: 1.0.0
// Create Date: 2018/08/13
// Create by: Marshal Lee
// Copyright:
// Copyright (c) 2019, Richpeace Co., LTD.
// All rights reserved.
//
// Modify by: Marshal Lee
// Modify Date: 2018/08/13
//-------------------------------------------------------------------------------
#include "crc32.h"
//-------------------------------------------------------------------------------
static const u32 CRC32_LIST[256] =
{
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL,
};
u32 addCrc32(u32 crcword, u8 dat)
{
return (crcword >> 8) ^ CRC32_LIST[((crcword ^ dat) & 0xFF)];
}
u32 calcCrc32(u8 * pBuf, int lenBuf)
{
int i;
u32 crcword = CRC32_INIT;
for (i = 0; i < lenBuf; i++)
{
crcword = addCrc32(crcword, pBuf[i]);
}
return crcword;
}

33
machine/comm/crc32.h Normal file
View File

@ -0,0 +1,33 @@
//-------------------------------------------------------------------------------
// File Name: crc32.h
// Brief:
// Version: 1.0.0
// Create Date: 2018/08/13
// Create by: Marshal Lee
// Copyright:
// Copyright (c) 2019, Richpeace Co., LTD.
// All rights reserved.
//
// Modify by: Marshal Lee
// Modify Date: 2018/08/13
//-------------------------------------------------------------------------------
#ifndef __CRC32_H__
#define __CRC32_H__
/*
CRC32
*/
#include "typedef.h"
#define CRC32_INIT 0xffffffff // crc初值
u32 addCrc32(u32 crcword, u8 dat);
u32 calcCrc32(u8 * pBuf, int lenBuf);
#endif

466
machine/comm/protocol.h Normal file
View File

@ -0,0 +1,466 @@
#ifndef PROTOCOL_H
#define PROTOCOL_H
#include "comm.h"
// 文件传输控制结构
#define LEN_RSV_BMP MAX_EXDP_LEN // 位图大小
#define MAX_FILE_SIZE (LEN_RSV_BMP*MAX_EXDP_LEN*8) // 最大文件字节数 按位图大小设定
#define PARA_NUM 256
// 传输文件类型
#define FILE_TYPE_DAT 0x00 // 数据文件
#define FILE_TYPE_PGM 0x02 // 升级文件
#define FILE_TYPE_PLOT 0x06 // 喷墨数据
#define MCPARA_MACH 0 // 机器参数
#define MCPARA_WORK 1 // 工作参数
// 传输有效标志定义
#define TRANS_NONE 0x00 // 无效
#define TRANS_ACTIVE 0x5A // 有效
// 传输结果代码定义
#define TRANS_NOT_BEG 0x00 // 没有收到启动命令
#define TRANS_READY 0x01 // 准备好接收
#define TRANS_DOING 0x02 // 正在接收
#define TRANS_DONE 0x03 // 接收完成
#define TRANS_REQUEST 0x04 // 请求传输模式
// 上位机发送命令
#define UCMD_GET_MC_INFO 0x0001 // 读取机器信息
#define UCMD_GET_MC_STATUS 0x0002 // 读取机器状态
#define UCMD_GET_MC_PARAS 0x0003 // 读取机器参数
#define UCMD_GET_TRANS_RESULT 0x0007 // 读取传输结果
#define UCMD_SET_MC_STATUS 0x0102 // 设置机器状态
#define UCMD_SET_MC_PARAS 0x0103 // 设置机器参数
#define UCMD_SET_MEM_DATA 0x0104 // 设置内存数据
#define UCMD_SET_FILE_PARAS 0x0105 // 设置文件参数
#define UCMD_SET_EXEC_PROGRESS 0x0106 // 设置执行进度
#define UCMD_SET_INSTALLMENT 0x0107 // 设置分期密码
#define UCMD_SET_ELAPSED_TIME 0x0108 // 设置经过的时间
#define UCMD_SET_DEF_PARA 0x0109 // 设置默认参数
#define UCMD_SET_FILE_EXDATA 0x010F // 设置文件扩展数据
#define UCMD_ACT_BYHAND 0x0201 // 手动控制命令
#define UCMD_MC_WORK 0x0202 // 机器工作命令
#define UCMD_MOVE_TO 0x0203 // 移动XY到坐标
#define UCMD_MOVE_OFST 0x0205 // XY移动偏移量
#define UCMD_START_TRANS 0x0301 // 启动文件传输
#define UCMD_TRANS_FILE_DATA 0x0302 // 文件传输命令
#define UCMD_SET_FILE_LIST 0x0304 // 设置文件列表
#define UCMD_MC_UPDATE 0x0401 // 下位机升级
// 下位机发送命令
#define DCMD_REQUEST_DAT 0x8000 // 请求文件数据
#define DCMD_SEND_MC_INFO 0x8001 // 发送机器信息
#define DCMD_SEND_MC_STATUS 0x8002 // 发送机器状态
#define DCMD_SEND_MC_PARAS 0x8003 // 发送机器参数
#define DCMD_SEND_FILE_INFO 0x8006 // 发送文件信息
#define DCMD_SEND_TRANS_RESULT 0x8007 // 发送传输结果
#define DCMD_SEND_DEBUG_INFO 0x8010 // 调试信息发送
// 状态码定义如下-设置
#define MC_STA_CLENA_ERR 0x0000 // 清除错误
#define MC_STA_EN_WORK 0x0001 // 允许工作(状态)
#define MC_STA_DIS_WORK 0x0002 // 禁止工作(状态)
#define MC_STA_EN_TIME 0x0003 // 允许工作(时间)
#define MC_STA_DIS_TIME 0x0004 // 禁止工作(时间)
#define MC_CLEAN_COUNT 0x0005 // 产量计数清零
#define MC_STA_MANUAL 0x0006 // 手动工作状态
#define MC_STA_AUTO 0x0007 // 自动工作状态
#define MC_FILE_SWITCH 0x0008 // 文件切换
#define MC_INVALID_FILE 0x0009 // 文件失效命令
// 工作控制功能
#define WORK_START 0x0001 // 启动工作
#define WORK_PAUSE 0x0002 // 暂停工作
// 喷墨图像按照黑白位图的格式存储
// 将整个喷墨图像位图分割为 (墨盒数量*300) 个像素宽度的块
// 每个块按照一个文件传输
// 数据列表, 描述整个位图
typedef struct
{
// 0
u32 fileId; // 文件标识
// 1
u32 totalWidth; // 位图宽度,以像素为单位
u32 totalHeight; // 位图高度,以像素为单位
// 3
u32 blkNums; // 分块个数
u32 blkWidth; // 分块位图宽度,以像素为单位
// 5
u32 rev[16-5];
}__attribute__ ((packed)) PlotFileList;
// 自定义压缩位图文件头
typedef struct
{
// 0
u32 fileId; // 整个位图文件标识
u32 blkIdx; // 当前位图块号(位图分块后的编号)
u32 datSize; // 本块位图数据区的大小(字节数)
u32 biWidth; // 本块位图有效宽度,以像素为单位
u32 biHeight; // 本块位图有效高度,以像素为单位
u32 dataChecksum; // 本块位图数据累加校验和
u32 begPosY; // 本块起始位置(像素单位)
u32 endPosY; // 本块结束位置(像素单位)
// 32
u8 compType; // 本块位图压缩类型, =0, 不压缩; =1, 按字节压缩;
u8 compDir; // 本块位图压缩方向, =0, 从上到下; =1, 从下到上;(喷墨方向)
// 34
u8 rev[64-2-34]; // 保留
// 62
u16 checkCrc; // 前面字段的CRC校验
}__attribute__ ((packed)) CompBmpHead;
// 机器信息结构定义
typedef struct
{
// 0
char softwareVerStr[32]; // 软件版本
// 32
char rev[1024-32];
} __attribute__ ((packed)) MCInfo;
typedef struct
{
u32 buf[PARA_NUM];
} __attribute__ ((packed)) ParaStruct;
// 升级文件头
typedef struct
{
// 0x00
char fileName[32]; // 文件名称
// 0x20
u32 dataSize; // 数据字节数
u32 dataChecksum; // 数据累加校验和
// 0x28
u8 reserved1[0x30-0x28]; // 保留区1
// 0x30
u8 reserved2[0x64-0x30]; // 保留区1
// 0x64
u8 reserved3[0x80-0x64]; // 保留区2
// 0x80
u8 reserved4[0x100-0x80];
}__attribute__ ((packed)) AppFileHead;
typedef struct
{
int transphase;
int filetransing;
int waitcount;
u8 transActive; // 传输结构有效
u8 transflag; // 接收进度标志 = 0, 接收未开始; = 1, 正在接收; = 2接收完成。
u8 fileType; // 文件类型
u8 fileIdx; // 为文件编号最多支持16个文件
u16 fileId; // 文件ID
u16 packetSize; // 包的大小
u32 packetNum; // 包的个数
AppFileHead * pAppHead;
CompBmpHead * pBmpHead;
u8 * pDatBuff;
u16 lenBmp; // 位图有效长度
u8 rsvBitmap[LEN_RSV_BMP]; // 文件接收进度标志位图
}FileTransCtrl;
// 机器状态数据结构定义
typedef struct
{
// 0
u32 workStatus; // 工作状态位图
// .0 允许时限。=0使用时限已到不允许下位机工作=1允许下位机工作
// .1 允许状态。=0界面钳制不允许下位机工作=1允许下位机工作
// .2 机器状态。=0手动工作状态; =1自动工作状态
// .3 钥匙状态。=0关闭状态; =1打开状态
// .4 文件接收标志。= 0初始状态。= 1收到了文件
// .5 参数接收标志。= 0初始状态。= 1收到了参数
// .6 正在忙标志。= 0空闲可以接收文件和参数。= 1工作中不会接收文件和参数
// .7 上料状态。=0手动上料状态; =1自动上料状态
// .8 参数更新标志。 =1下位机更新了参数
// .9 模拟工作标志。=1, 处于模拟工作状态
// .10 允许扫描条码状态。=1, 允许
// .11 允许拍照状态。=1, 允许
// .12 正在工作标志
// .13 传感信号扫描中标志
// .14 相机校准模式中标志
// .15
// .16
// .17
// .18
// .19 取模板框状态
// .20 放模板框状态
// .21 匹绣, 0:退出匹绣,主轴归零 1:进入匹绣,扎针,允许移框
// .22 断线检测, 0退出断线检测状态 1进入断线检测状态
// 1
u32 errorCode; // 错误代码
u32 fileIdx; // 文件序号
u32 dataIdx; // 数据索引
u32 runSpeed; // 运动速度 主轴转速
u32 runAction; // 执行动作代码 *
u32 runSteps; // 当前执行步骤 *
u32 outCounter; // 产量计数
} __attribute__ ((packed)) MCStatus;
//OperPacket
typedef union
{
DataPacket packet;
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 toggle;
u8 rev[6];
u16 crc;
} __attribute__ ((packed)) getMcInfo; // 读取机器信息
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 paraType;
u16 paraId;
u8 rev[4];
u16 crc;
} __attribute__ ((packed)) getMcParas; // UCMD_GET_MC_PARAS 读取机器参数
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u8 fileType;
u8 fileIdx;
u8 rev[6];
u16 crc;
} __attribute__ ((packed)) getFileInfo; // UCMD_GET_FILE_INFO 读取文件信息
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 fileId;
u8 rev[6];
u16 crc;
} __attribute__ ((packed)) getTransResult; // UCMD_GET_TRANS_RESULT 读取传输结果
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 upObj;
u16 upFileID;
u32 checksum;
u16 crc;
} __attribute__ ((packed)) mcUpdate; // UCMD_MC_UPDATE 系统升级
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 staCode;
u16 para;
u8 rev[4];
u16 crc;
} __attribute__ ((packed)) setMcStatus; // UCMD_SET_MC_STATUS 设置机器状态
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 exLen;
u16 exCrc;
u16 paraType;
u16 paraId;
u16 crc;
u8 exData[MAX_EXDP_LEN];
} __attribute__ ((packed)) setParas; // UCMD_SET_MC_PARAS 设置下位机参数
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 exLen;
u16 exCrc;
u8 fileType;
u8 fileIdx;
u16 fileId;
u16 crc;
u8 exData[MAX_EXDP_LEN];
} __attribute__ ((packed)) startTrans; // UCMD_START_TRANS 启动文件传输
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 exLen;
u16 exCrc;
u16 pktIdx;
u16 fileId;
u16 crc;
u8 exData[MAX_EXDP_LEN];
} __attribute__ ((packed)) transFileData; // UCMD_TRANS_FILE_DATA 文件数据传输
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 exLen;
u16 exCrc;
u32 fileIdxMap;
u16 crc;
u8 exData[MAX_EXDP_LEN];
} __attribute__ ((packed)) setFilesList; // 设置文件列表 UCMD_SET_FILE_LIST
//----------------------------------
// 下位机发送命令
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u8 fileType;
u8 fileIdx;
u16 fileId;
u32 datBlockIdx; // 数据包索引每个包1024字节)
u16 crc;
u8 exData[MAX_EXDP_LEN];
} __attribute__ ((packed)) dRequestDatBlock; // DCMD_REQUEST_DAT 请求文件数据
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 exLen;
u16 exCrc;
u16 toggle;
u8 rev[2];
u16 crc;
u8 exData[MAX_EXDP_LEN];
} __attribute__ ((packed)) dSendMcInfo; // DCMD_SEND_MC_INFO 发送机器信息
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 exLen;
u16 exCrc;
u16 toggle;
u8 rev[2];
u16 crc;
u8 exData[MAX_EXDP_LEN];
} __attribute__ ((packed)) dSendMcStatus; // DCMD_SEND_MC_STATUS 发送机器状态
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 exLen;
u16 exCrc;
u16 paraType;
u16 paraId;
u16 crc;
u8 exData[MAX_EXDP_LEN];
} __attribute__ ((packed)) dSendMcParas; // DCMD_SEND_MC_PARAS 发送机器参数
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 exLen;
u16 exCrc;
u8 fileType;
u8 fileIdx;
u8 rev[2];
u16 crc;
u8 exData[MAX_EXDP_LEN];
} __attribute__ ((packed)) dSendFileInfo; // DCMD_SEND_FILE_INFO 发送文件信息
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 exLen;
u16 exCrc;
u16 fileId;
u8 active;
u8 result;
u16 crc;
u8 exData[MAX_EXDP_LEN];
} __attribute__ ((packed)) dSendTransResult; // DCMD_SEND_TRANS_RESULT 发送传输结果
struct
{
u8 sync[DP_SYNC_LEN];
u16 cmdCode;
u16 workCode;
u32 para1;
u16 para2;
u16 crc;
} __attribute__ ((packed)) mcWork; // UCMD_MC_WORK 机器工作命令
}OperPacket;
#endif // PROTOCOL_H

16
machine/comm/typedef.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef TYPEDEF_H
#define TYPEDEF_H
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short int WORD;
typedef unsigned long int DWORD;
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned int u32;
typedef char s8;
typedef short int s16;
typedef int s32;
#endif // TYPEDEF_H

1061
machine/machine.cpp Normal file

File diff suppressed because it is too large Load Diff

140
machine/machine.h Normal file
View File

@ -0,0 +1,140 @@
#ifndef MACHINE_H
#define MACHINE_H
#include "tcp/tcpclient.h"
#include "bmp/creatprintbmp.h"
#include "printinfo/mcfiles.h"
#include "machine/comm/crc16.h"
#define SEND_STEP0 0
#define SEND_STEP1 1
#define SEND_STEP2 2
#define SEND_STEP3 3
#define SEND_STEP4 4
#define SEND_STEP5 5
#define SEND_STEP_MAX 10
#define SEND_ANSWER 100
class Machine : public QObject
{
Q_OBJECT
public:
explicit Machine(QObject *parent = NULL);
virtual ~Machine();
protected:
QString m_mcName;
QString m_mcIp;
private:
// 通讯线程和网络连接
TcpClient * m_pTcpClient;
QThread * m_pTcpBmpThread;
//生成打印数据
CreatPrintBmp * m_pCreatPrintDat;
MCInfo m_mcInfo; // 机器信息
ParaStruct m_mcPara; // 机器参数信息 配置信息
ParaStruct m_wkPara; // 工作参数信息
int m_totalSendNum;//传输文件时总共发送的包数
int m_totalPacketNum;//传输文件时总的包数
QTimer *m_pSendTimer;
FileTransCtrl m_transCtrl;
int m_fileTransEn;
int m_transBreak;
PlotFileList *m_pPlotFileList;//文件数据列表
CompBmpHead *m_pCompBmpHead;//压缩位图文件头
private:
int m_connected; // 机器连接状态. 0, 未连接; 1, 连接中; 2,
MCStatus m_mcStatus; // 机器状态
int m_mcParaEn;
int m_wkParaEn;
public:
McPrintInfo m_mcPrintInfo;//机器打印信息(包括机器的连接状态和工作状态)
private:
void startFileTrans(FileTransCtrl & transCtrl);
void startFileDyTrans(FileTransCtrl & transCtrl);//开始动态传输文件
void transFileData(FileTransCtrl & transCtrl, int pktidx);
void setAParasToMachine(int type, int idx, u32 value);
void setMcStatusAsMc(u8 * buff, u16 len, int toggle);
void updateFirmware(); // 下位机升级
// 连接
public:
inline int isConnected() const { return m_connected; }
public:
void setIpAndPort(QString mcName, QString serverIp, quint16 serverPort, QString localIp, quint16 localPort);
void startCommunication();
//机器信息
inline const MCInfo &getMcInfo() { return m_mcInfo; }
inline int getTotalSendNum() { return m_totalSendNum; }
inline int getTotalPacketNum() { return m_totalPacketNum; }
inline const MCStatus & getMcStatus() {return m_mcStatus; }
inline const ParaStruct & getMcPara() {/*m_mcParaEn = 0; */ return m_mcPara; }
inline const ParaStruct & getWkPara() {/*m_wkParaEn = 0; */ return m_wkPara; }
void getInfoFromMachine();
void getParasFromMachine(int type, int id); // 读取机器参数
void getTransResultFromMachine(int fileid);
void sleep(int sec);
public:
void setMcStatus(int stacode, int para = 0); // 设置机器状态
// 设置机器参数
void setParasToMachine(ParaStruct & para);
void setAMcPara(int id, u32 value);
void setAWkPara(int id, u32 value);
void startWork(); // 启动工作
void pauseWork(); // 暂停工作
// 文件传输命令
int sendFileProc(int idx, u8 *dat, int datSize);
int dySendFileProc(int type, int idx, int id, u8 * pDatBuff); //动态传输文件
int sendAPPFileProc(int type, int idx, int id, AppFileHead &fileHead, u8 *pDatBuff); //发送升级文件
// 机器工作命令
void mcWorkCmd(int workcode, int para1 = 0 , int para2 = 0);
void creatPrintDat(int fileIdx); //生成打印数据
void deleteFilePrintDat(int fileIdx);//删除文件打印数据
void moveFilePrintDat(int fileIdx,int dir = -1);//移动(上下移)文件打印数据
void invalidateWorkFile(int idx = 0); // 文件失效
signals:
// 发送数据到机器的信号
void siSendData(QByteArray dat);
void siSendDataDone();
void siStatusChange(int); // 状态改变信号
void siMcInfoChange(); // 机器信息改变信号
void siParaChange(int type, int id); // 参数更新信号
void siTransResultChange(); // 文件传输结果信号
void siTransProgress(u8 fileType, int send, int total); // 文件传输结果信号
void siCreatData(); //生成要发送的数据
void siCreatBmpBlockDatAndSend();//生成位图数据块数据并发送
void siDeleteFileFinish();
void siMoveFileFinish();
private slots:
void slotConnectSta(int sta); // 连接状态改变的槽函数
void slotConnectErr(QString errinfo); // 接收到通讯错误槽函数
void slotReceiveData(QByteArray dat); // 接收到数据的槽函数
void onSendTimer(void);
void slotSendDatToMc(QByteArray dat, BmpDatInfo bmpInfo);//发送打印数据
void slotSendPlotFileListToMc(int idx);//发送设置文件列表
public slots:
void breakFileTrans(); // 打断文件传输
};
#endif // MACHINE_H

232
machine/printinfo/mcfiles.h Normal file
View File

@ -0,0 +1,232 @@
#ifndef MCFILES_H
#define MCFILES_H
#include <QString>
#include <QPicture>
#include <QBitmap>
#include "machine/comm/protocol.h"
#include "datafile/hpgl/marker.h"
//连接状态
enum ConnectState
{
InitConnect = 0,//初始值
NoConnect = 1, //未连接
Connectting = 2, //连接中
Connected = 3 //已连接
};
//工作状态
enum WorkState
{
NotBusy = 0,//空闲中
Busying = 1 //工作中
};
class McFilesInfo
{
public:
s16 m_creatDataFlag;//是否已经生成数据的标志
s16 m_creatBmpFlag;//是否已经生成bmp的标志
QString m_fileName;//文件名称
QString m_filePath;//文件路径
s16 m_fileType;//文件类型
QRect m_fileRect;//图形被包络的矩形区域
s16 m_printNum;//打印份数
s16 m_startPoint;//打印起始点
QString m_printState;//打印状态
QPicture m_pic;//文件-图片
QBitmap m_pixmap;//图片-图片
s16 m_totalBlocks;//总块数
s16 m_curPrintBlock;//当前打印块数
s16 m_printedBlockNum;//已打印块数
s16 m_leaveBlockNum;//剩余打印块数
s16 m_selectBlockNum;//当前选择块数
Marker m_marker;//数据
void clear()
{
QPicture pic;
m_creatDataFlag = -1;
m_creatBmpFlag = -1;//是否已经生成bmp的标志
m_fileName.clear();//文件名称
m_filePath.clear();//文件路径
m_fileType = 0;//文件类型
m_printNum = 0;//打印份数
m_startPoint = 0;//打印起始点
m_printState.clear();//打印状态
m_pic = pic;
m_pixmap.clear();
m_totalBlocks = 0;//总块数
m_curPrintBlock = 0;//当前打印块数
m_printedBlockNum = 0;//已打印块数
m_leaveBlockNum = 0;//剩余打印块数
m_selectBlockNum = 0;//当前选择块数
m_marker.Initialize();
}
McFilesInfo()
{
m_creatDataFlag = -1;
m_creatBmpFlag = -1;//是否已经生成bmp的标志
m_fileName.clear();//文件名称
m_filePath.clear();//文件路径
m_fileType = 0;//文件类型
m_printNum = 0;//打印份数
m_startPoint = 0;//打印起始点
m_printState.clear();//打印状态
m_totalBlocks = 0;//总块数
m_curPrintBlock = 0;//当前打印块数
m_printedBlockNum = 0;//已打印块数
m_leaveBlockNum = 0;//剩余打印块数
m_selectBlockNum = 0;//当前选择块数
m_marker.Initialize();
}
McFilesInfo(const McFilesInfo &item)
{
m_creatDataFlag = item.m_creatDataFlag;//是否已经生成数据的标志
m_creatBmpFlag = item.m_creatBmpFlag;//是否已经生成bmp的标志
m_fileName = item.m_fileName;//文件名称
m_filePath = item.m_filePath;//文件路径
m_fileType = item.m_fileType;//文件类型
m_fileRect = item.m_fileRect;//图形被包络的矩形区域
m_printNum = item.m_printNum;//打印份数
m_startPoint = item.m_startPoint;//打印起始点
m_printState = item.m_printState;//打印状态
m_pic = item.m_pic;
m_pixmap = item.m_pixmap;
m_totalBlocks = item.m_totalBlocks;//总块数
m_curPrintBlock = item.m_curPrintBlock;//当前打印块数
m_printedBlockNum = item.m_printedBlockNum;//已打印块数
m_leaveBlockNum = item.m_leaveBlockNum;//剩余打印块数
m_selectBlockNum = item.m_selectBlockNum;//当前选择块数
m_marker = item.m_marker;
}
~McFilesInfo() {}
McFilesInfo & operator=(const McFilesInfo &item)
{
m_creatDataFlag = item.m_creatDataFlag;//是否已经生成数据的标志
m_creatBmpFlag = item.m_creatBmpFlag;//是否已经生成bmp的标志
m_fileName = item.m_fileName;//文件名称
m_filePath = item.m_filePath;//文件路径
m_fileType = item.m_fileType;//文件类型
m_fileRect = item.m_fileRect;//图形被包络的矩形区域
m_printNum = item.m_printNum;//打印份数
m_startPoint = item.m_startPoint;//打印起始点
m_printState = item.m_printState;//打印状态
m_pic = item.m_pic;
m_pixmap = item.m_pixmap;
m_totalBlocks = item.m_totalBlocks;//总块数
m_curPrintBlock = item.m_curPrintBlock;//当前打印块数
m_printedBlockNum = item.m_printedBlockNum;//已打印块数
m_leaveBlockNum = item.m_leaveBlockNum;//剩余打印块数
m_selectBlockNum = item.m_selectBlockNum;//当前选择块数
m_marker = item.m_marker;
return *this;
}
};
Q_DECLARE_METATYPE(McFilesInfo)
class McPrintInfo
{
public:
s16 m_mcNum;//机器号
s16 m_loadFileFinishFlag;//自动加载文件完成标志(包括自动绘图目录和上次未打印完的)
QString m_mcName;//机器名称
int m_mcConnState;//机器连接状态
int m_mcWorkState;//机器工作状态
int m_mcSendProgress;//机器文件发送进度
int m_totalNums;//要发送的总块数
int m_sendedlNums;//已发送的总块数
QString m_ip;//机器ip
s16 m_port;//机器端口
s16 m_fileNums;//文件数量
s16 m_curCreatPrintDatFileIdx;//当前正在生成打印数据的文件索引
long long m_fileTotalLength;//文件总长度
QList<McFilesInfo> m_filesList;//图片列表
void clear()
{
m_mcNum = 0;
m_loadFileFinishFlag = -1;
m_mcName.clear();
m_mcConnState = InitConnect;
m_mcWorkState = NotBusy;
m_mcSendProgress = 0;
m_totalNums = 0;
m_sendedlNums = 0;
m_ip.clear();
m_port = 0;
m_fileNums = 0;
m_fileTotalLength = 0;
m_curCreatPrintDatFileIdx = -1;
for(int i = 0; i < m_filesList.size(); i++)
{
m_filesList[i].clear();
}
m_filesList.clear();
}
McPrintInfo()
{
m_mcNum = 0;
m_loadFileFinishFlag = -1;
m_mcName.clear();
m_mcConnState = InitConnect;
m_mcWorkState = NotBusy;
m_mcSendProgress = 0;
m_mcSendProgress = 0;
m_totalNums = 0;
m_sendedlNums = 0;
m_ip.clear();
m_port = 0;
m_fileNums = 0;
m_fileTotalLength = 0;
m_curCreatPrintDatFileIdx = -1;
m_filesList.clear();
}
McPrintInfo(const McPrintInfo &item)
{
m_mcNum = item.m_mcNum;
m_loadFileFinishFlag = item.m_loadFileFinishFlag;
m_mcName = item.m_mcName;
m_mcConnState = item.m_mcConnState;
m_mcWorkState = item.m_mcWorkState;
m_mcSendProgress = item.m_mcSendProgress;
m_totalNums = item.m_totalNums;
m_sendedlNums = item.m_sendedlNums;
m_ip = item.m_ip;
m_port = item.m_port;
m_fileNums = item.m_fileNums;
m_fileTotalLength = item.m_fileTotalLength;
m_curCreatPrintDatFileIdx = -1;
m_filesList = item.m_filesList;
}
~McPrintInfo() {}
McPrintInfo & operator=(const McPrintInfo &item)
{
m_mcNum = item.m_mcNum;
m_loadFileFinishFlag = item.m_loadFileFinishFlag;
m_mcName = item.m_mcName;
m_mcConnState = item.m_mcConnState;
m_mcWorkState = item.m_mcWorkState;
m_mcSendProgress = item.m_mcSendProgress;
m_totalNums = item.m_totalNums;
m_sendedlNums = item.m_sendedlNums;
m_ip = item.m_ip;
m_port = item.m_port;
m_fileNums = item.m_fileNums;
m_fileTotalLength = item.m_fileTotalLength;
m_curCreatPrintDatFileIdx = -1;
m_filesList = item.m_filesList;
return *this;
}
};
Q_DECLARE_METATYPE(McPrintInfo)
#endif // MCFILES_H

View File

@ -0,0 +1,186 @@
#include "qbindtcpsocket.h"
#include <QHostAddress>
QBindTcpSocket::QBindTcpSocket(QObject *parent):
QTcpSocket(parent)
{
}
QBindTcpSocket::~QBindTcpSocket()
{
}
int QBindTcpSocket::bindAddrAndPort(QString localAddr, quint16 localPort)
{
QString str = localAddr;
QHostAddress addr(str);
setLocalAddress(addr);
setLocalPort(localPort);
return 0;
}
//-------------------------------
TcpConnectDetect::TcpConnectDetect(QObject *parent) :
QObject(parent),
m_pDetectSocket(NULL),
m_localip(DEF_LOCAL_IP),
m_localport(DEF_LOCAL_PORT),
m_serverip(DEF_SERVER_IP),
m_serverport(DEF_SERVER_PORT)
{
}
TcpConnectDetect::~TcpConnectDetect()
{
if (m_pDetectSocket == NULL)
{
m_pDetectSocket->disconnectFromHost();
m_pDetectSocket->waitForDisconnected();
m_pDetectSocket->close();
delete m_pDetectSocket;
}
}
void TcpConnectDetect::detectStart()
{
qDebug("TcpConnectDetect start");
if (m_pDetectSocket == NULL)
{
m_pDetectSocket = new QBindTcpSocket;
}
}
int TcpConnectDetect::connectDetect()
{
int connectsta = 0;
int rslt;
// qDebug() << "TcpConnectDetect " << QThread::currentThread();
if (m_pDetectSocket == NULL)
{
return 0;
}
if (m_localip.isEmpty() == false)
{
m_pDetectSocket->bindAddrAndPort(m_localip, m_localport);
}
m_pDetectSocket->abort();
m_pDetectSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
m_pDetectSocket->connectToHost(m_serverip, m_serverport);
do
{
rslt = m_pDetectSocket->waitForConnected(4000); // 等待连接
qDebug("bind Detect connect rslt=%d", rslt);
qDebug() << "localip=" << m_localip << "localport=" << m_localport;
qDebug() << "serverip=" << m_serverip << "serverport=" << m_serverport;
switch(m_pDetectSocket->state())
{
case QAbstractSocket::ConnectedState:
{
// 如果连接上,说明 m_pClientSocket 连接已经无效, 需要断开重新连接
// 先断开测试连接
m_pDetectSocket->disconnectFromHost();
m_pDetectSocket->waitForDisconnected();
connectsta = 1;
// 发送断开主连接的信号
qDebug() << "detect is Connected, disconnect all";
break;
}
case QAbstractSocket::UnconnectedState:
{
// qDebug() << "detect is Unconnected err=" << m_pDetectSocket->error() << ", info:" << m_pDetectSocket->errorString();
switch (m_pDetectSocket->error())
{
case QAbstractSocket::SocketTimeoutError: // 连接超时,说明已经断开
case QAbstractSocket::NetworkError: // 网络错误, 主机不可连接, 可能已经断开
{
qDebug() << "detect is timout, disconnect all";
connectsta = 1;
// 发送断开主连接的信号
break;
}
case QAbstractSocket::ConnectionRefusedError: // 拒绝连接, 说明连接还在
{
connectsta = 2;
// qDebug() << "Connection Refused, old connect is alive";
break;
}
/*
case QAbstractSocket::RemoteHostClosedError:
case QAbstractSocket::HostNotFoundError:
case QAbstractSocket::SocketAccessError:
case QAbstractSocket::SocketResourceError:
case QAbstractSocket::SocketTimeoutError:
case QAbstractSocket::DatagramTooLargeError:
case QAbstractSocket::AddressInUseError:
case QAbstractSocket::SocketAddressNotAvailableError:
case QAbstractSocket::UnsupportedSocketOperationError:
case QAbstractSocket::UnfinishedSocketOperationError:
case QAbstractSocket::ProxyAuthenticationRequiredError:
case QAbstractSocket::SslHandshakeFailedError:
case QAbstractSocket::ProxyConnectionRefusedError:
case QAbstractSocket::ProxyConnectionClosedError:
case QAbstractSocket::ProxyConnectionTimeoutError:
case QAbstractSocket::ProxyNotFoundError:
case QAbstractSocket::ProxyProtocolError:
case QAbstractSocket::UnknownSocketError:
*/
default:
{
// 继续检测
connectsta = 2;
qDebug() << " retry";
break;
}
} // 错误处理结束
}
case QAbstractSocket::ConnectingState:
{
// qDebug() << "detect is Connecting";
// qDebug() << "localip=" << m_localip << "localport=" << m_localport;
// 继续等待
break;
}
case QAbstractSocket::HostLookupState:
case QAbstractSocket::BoundState:
case QAbstractSocket::ListeningState:
case QAbstractSocket::ClosingState:
default:
{
// 继续等待
qDebug("detect sta is %d\r\n", m_pDetectSocket->state());
break;
}
}
if (connectsta != 0)
{
break;
}
}while(1);
m_pDetectSocket->close();
// 发送本次测试连接的状态信号
emit(siConnectSta(connectsta));
return connectsta;
}
void TcpConnectDetect::setIpAndPort(QString localip, quint16 localport, QString serverip, quint16 serverport)
{
m_localip = localip;
m_localport = localport;
m_serverip = serverip;
m_serverport = serverport;
}

View File

@ -0,0 +1,53 @@
#ifndef QBINDTCPSOCKET_H
#define QBINDTCPSOCKET_H
#define DEF_SERVER_IP "192.168.16.253"
#define DEF_SERVER_PORT 5000
#define DEF_LOCAL_IP ""
#define DEF_LOCAL_PORT 5001
#include <QTcpSocket>
class QBindTcpSocket : public QTcpSocket
{
public:
QBindTcpSocket(QObject *parent = 0);
virtual ~QBindTcpSocket();
public:
int bindAddrAndPort(QString localAddr, quint16 localPort);
};
#if(1)
class TcpConnectDetect : public QObject
{
Q_OBJECT
public:
explicit TcpConnectDetect(QObject *parent = NULL);
virtual ~TcpConnectDetect();
signals:
void siConnectSta(int sta); // 网络连接信号
public:
public slots:
void detectStart();
int connectDetect();
private:
QBindTcpSocket * m_pDetectSocket;
public:
void setIpAndPort(QString localip, quint16 localport, QString serverip, quint16 serverport);
private:
QString m_localip;
quint16 m_localport;
QString m_serverip;
quint16 m_serverport;
};
#endif
#endif // QBINDTCPSOCKET_H

Some files were not shown because too many files have changed in this diff Show More