12 changed files with 568 additions and 258 deletions
-
94CMakeLists.txt
-
1README.md
-
17appsrc/appbase/appevent/app_disinfection_finished_event.hpp
-
2appsrc/appbase/appevent/app_disinfection_snapshot_event.hpp
-
224appsrc/appbase/utils/zsimplepdf.cpp
-
79appsrc/appbase/utils/zsimplepdf.hpp
-
14appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.cpp
-
2appsrc/service/app/disinfection_ctrl/disinfection_ctrl_service.hpp
-
145appsrc/service/disinfection_logs_service.cpp
-
3appsrc/service/disinfection_logs_service.hpp
-
10buildpc.sh
-
235test/testpdf.cpp
@ -0,0 +1,224 @@ |
|||
#include "zsimplepdf.hpp"
|
|||
using namespace iflytop; |
|||
|
|||
void ZSimplePDF::ZSimplePDF::spitText(const string& content, list<string>& textlist) { |
|||
textlist.clear(); |
|||
// 按行分割字符串
|
|||
std::istringstream stream(content); |
|||
std::string line; |
|||
|
|||
while (std::getline(stream, line)) { |
|||
textlist.push_back(line); |
|||
} |
|||
} |
|||
|
|||
void ZSimplePDF::forceMkdir(string filename) { |
|||
string::size_type sepPos = filename.find_last_of("/"); |
|||
if (sepPos != string::npos) { |
|||
string dirPath = filename.substr(0, sepPos); |
|||
system(("mkdir -p " + dirPath).c_str()); |
|||
} |
|||
} |
|||
|
|||
void ZSimplePDF::buildPDFAndFont(HPDF_Doc& pdf, HPDF_Font& font) { |
|||
pdf = HPDF_New(error_handler, this); |
|||
ZASSERT(pdf); |
|||
// install chinese fonts
|
|||
HPDF_UseCNSFonts(pdf); |
|||
HPDF_UseCNTFonts(pdf); |
|||
HPDF_UseCNTEncodings(pdf); |
|||
HPDF_UseCNSEncodings(pdf); |
|||
|
|||
// getFont
|
|||
font = HPDF_GetFont(pdf, "SimSun", "GBK-EUC-H"); |
|||
ZASSERT(font); |
|||
} |
|||
|
|||
ZSimplePDF::ZSimplePDF(string filename, int defaultFrontSize) : m_fileName(filename), m_defaultFrontSize(defaultFrontSize) {} |
|||
|
|||
void ZSimplePDF::newPage() { |
|||
if (curPage != nullptr) { |
|||
pushPage(); |
|||
} |
|||
shared_ptr<Page> pPage = make_shared<Page>(); |
|||
curPage = pPage; |
|||
} |
|||
void ZSimplePDF::pushPage() { |
|||
ZASSERT(curPage); |
|||
if (curContent) { |
|||
curPage->contents.push_back(curContent); |
|||
curContent = nullptr; |
|||
} |
|||
m_pages.push_back(curPage); |
|||
curPage = nullptr; |
|||
} |
|||
|
|||
void ZSimplePDF::newConent(int frontSize) { |
|||
if (curPage == nullptr) { |
|||
newPage(); |
|||
} |
|||
if (curContent != nullptr) { |
|||
pushContent(); |
|||
} |
|||
|
|||
shared_ptr<Content> pContent = make_shared<Content>(); |
|||
pContent->fontSize = frontSize; |
|||
curContent = pContent; |
|||
} |
|||
|
|||
void ZSimplePDF::pushContent() { |
|||
ZASSERT(curPage); |
|||
ZASSERT(curContent); |
|||
curPage->contents.push_back(curContent); |
|||
curContent = nullptr; |
|||
} |
|||
|
|||
void ZSimplePDF::addText(const string& text) { |
|||
if (curPage == nullptr) { |
|||
newPage(); |
|||
} |
|||
if (curContent == nullptr) { |
|||
newConent(m_defaultFrontSize); |
|||
} |
|||
list<string> textlist; |
|||
spitText(text, textlist); |
|||
curContent->textlist.insert(curContent->textlist.end(), textlist.begin(), textlist.end()); |
|||
} |
|||
|
|||
void ZSimplePDF::utf8ToGb2312(const string& incontent, string& output) { |
|||
// 打开转换描述符
|
|||
iconv_t cd = iconv_open("GB2312", "UTF-8"); |
|||
if (cd == (iconv_t)-1) { |
|||
perror("iconv_open failed"); |
|||
exit(EXIT_FAILURE); |
|||
} |
|||
|
|||
// 输入字符串
|
|||
const char* in_str = incontent.c_str(); |
|||
size_t in_size = incontent.size(); |
|||
|
|||
// 输出缓冲区
|
|||
size_t out_size = in_size * 2; // 假设输出的字节数不会超过输入的两倍
|
|||
char* out_buf = new char[out_size]; |
|||
char* out_str = out_buf; |
|||
|
|||
// 进行转换
|
|||
if (iconv(cd, const_cast<char**>(&in_str), &in_size, &out_str, &out_size) == (size_t)-1) { |
|||
perror("iconv failed"); |
|||
iconv_close(cd); |
|||
delete[] out_buf; |
|||
exit(EXIT_FAILURE); |
|||
} |
|||
|
|||
// 关闭转换描述符
|
|||
iconv_close(cd); |
|||
|
|||
// 获取转换后的字符串
|
|||
std::string gb2312_str(out_buf, out_str - out_buf); |
|||
// 释放内存
|
|||
delete[] out_buf; |
|||
output = gb2312_str; |
|||
} |
|||
|
|||
void ZSimplePDF::utf8ToGb2312() { |
|||
for (auto& page : m_pages) { |
|||
for (auto& content : page->contents) { |
|||
for (auto& line : content->textlist) { |
|||
string gb2312; |
|||
utf8ToGb2312(line, gb2312); |
|||
line = gb2312; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
float ZSimplePDF::findTextMaxWidth(shared_ptr<Content> content) { |
|||
HPDF_Doc pdf; |
|||
HPDF_Font font; |
|||
buildPDFAndFont(pdf, font); |
|||
HPDF_Page szPage = HPDF_AddPage(pdf); |
|||
HPDF_Page_SetFontAndSize(szPage, font, content->fontSize); |
|||
|
|||
float maxWidth = 0; |
|||
for (auto& line : content->textlist) { |
|||
float size = HPDF_Page_TextWidth(szPage, line.c_str()); |
|||
if (size > maxWidth) { |
|||
maxWidth = size; |
|||
} |
|||
} |
|||
HPDF_Free(pdf); |
|||
return maxWidth; |
|||
} |
|||
|
|||
float ZSimplePDF::findTextMaxWidth() { |
|||
float maxWidth = 0; |
|||
for (auto& page : m_pages) { |
|||
for (auto& content : page->contents) { |
|||
float size = findTextMaxWidth(content); |
|||
if (size > maxWidth) { |
|||
maxWidth = size; |
|||
} |
|||
} |
|||
} |
|||
return maxWidth; |
|||
} |
|||
|
|||
int ZSimplePDF::findTextMaxHight() { |
|||
int maxHight = 0; |
|||
for (auto& page : m_pages) { |
|||
int hight = 0; |
|||
for (auto& content : page->contents) { |
|||
hight += (content->fontSize + linePadding) * content->textlist.size(); |
|||
} |
|||
if (hight > maxHight) { |
|||
maxHight = hight; |
|||
} |
|||
} |
|||
return maxHight; |
|||
} |
|||
|
|||
void ZSimplePDF::dump() { |
|||
if (curContent) pushContent(); |
|||
if (curPage) pushPage(); |
|||
|
|||
forceMkdir(m_fileName); |
|||
utf8ToGb2312(); |
|||
|
|||
float maxWidth = findTextMaxWidth(); |
|||
HPDF_Doc pdf; |
|||
HPDF_Font font; |
|||
buildPDFAndFont(pdf, font); |
|||
int pageHight = findTextMaxHight(); |
|||
|
|||
for (auto& page : m_pages) { |
|||
HPDF_Page szPage = HPDF_AddPage(pdf); |
|||
|
|||
HPDF_Page_SetSize(szPage, HPDF_PAGE_SIZE_COMM10, HPDF_PAGE_PORTRAIT); |
|||
// 设置页面高度
|
|||
HPDF_Page_SetHeight(szPage, pageHight + pagePadding * 2); |
|||
// 设置页面宽度
|
|||
HPDF_Page_SetWidth(szPage, maxWidth + pagePadding * 2); |
|||
|
|||
float writehpos = HPDF_Page_GetHeight(szPage); |
|||
writehpos -= pagePadding; |
|||
for (auto& content : page->contents) { |
|||
HPDF_Page_SetFontAndSize(szPage, font, content->fontSize); |
|||
for (auto& line : content->textlist) { |
|||
HPDF_Page_BeginText(szPage); |
|||
writehpos -= content->fontSize; |
|||
// printf("writehpos=%f\n", writehpos);
|
|||
HPDF_Page_MoveTextPos(szPage, pagePadding, writehpos); |
|||
HPDF_Page_ShowText(szPage, line.c_str()); |
|||
HPDF_Page_EndText(szPage); |
|||
writehpos -= linePadding; |
|||
} |
|||
} |
|||
} |
|||
|
|||
HPDF_SaveToFile(pdf, m_fileName.c_str()); |
|||
}; |
|||
|
|||
void ZSimplePDF::error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void* user_data) { //
|
|||
ZSimplePDF* thisclass = (ZSimplePDF*)user_data; |
|||
thisclass->logger->error("ERROR: error_no={:x}, detail_no={:x}", (HPDF_UINT)error_no, (HPDF_UINT)detail_no); |
|||
} |
@ -0,0 +1,79 @@ |
|||
#pragma once
|
|||
#include <assert.h>
|
|||
#include <iconv.h>
|
|||
#include <stdio.h>
|
|||
#include <stdlib.h>
|
|||
#include <string.h>
|
|||
|
|||
#include <fstream>
|
|||
#include <functional>
|
|||
#include <iostream>
|
|||
#include <list>
|
|||
#include <map>
|
|||
#include <memory>
|
|||
#include <set>
|
|||
#include <sstream>
|
|||
#include <string>
|
|||
#include <vector>
|
|||
|
|||
#include "hpdf.h"
|
|||
#include "iflytop/core/core.hpp"
|
|||
|
|||
namespace iflytop { |
|||
|
|||
class ZSimplePDF { |
|||
THISCLASS(ZSimplePDF); |
|||
class Content { |
|||
public: |
|||
int fontSize = 20; |
|||
list<string> textlist; |
|||
int maxWidth; |
|||
}; |
|||
|
|||
class Page { |
|||
public: |
|||
list<shared_ptr<Content>> contents; |
|||
}; |
|||
|
|||
public: |
|||
string m_fileName; |
|||
int m_defaultFrontSize = 20; |
|||
int pagePadding = 5; |
|||
int linePadding = 10; |
|||
|
|||
HPDF_Doc m_pdf; |
|||
HPDF_Font m_font; |
|||
|
|||
// shared_ptr<Content> curContent;
|
|||
list<shared_ptr<Page>> m_pages; |
|||
|
|||
shared_ptr<Page> curPage; |
|||
shared_ptr<Content> curContent; |
|||
|
|||
public: |
|||
ZSimplePDF(string filename, int defaultFrontSize = 20); |
|||
|
|||
void newPage(); |
|||
void newConent(int frontSize = 20); |
|||
void addText(const string& text); |
|||
|
|||
void dump(); |
|||
|
|||
private: |
|||
void spitText(const string& content, list<string>& textlist); |
|||
void forceMkdir(string filename); |
|||
|
|||
void buildPDFAndFont(HPDF_Doc& pdf, HPDF_Font& font); |
|||
|
|||
void utf8ToGb2312(const string& incontent, string& output); |
|||
void utf8ToGb2312(); |
|||
float findTextMaxWidth(shared_ptr<Content> content); |
|||
float findTextMaxWidth(); |
|||
int findTextMaxHight(); |
|||
|
|||
void pushContent(); |
|||
void pushPage(); |
|||
|
|||
static void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void* user_data); |
|||
}; |
|||
} // namespace iflytop
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue