COMPASSi/trunk/code/3rd/CCSReport_2/include/utils/svgtopdf.h

206 lines
7.0 KiB
C
Raw Permalink Normal View History

2025-06-25 15:06:42 +08:00
#pragma execution_character_set( "utf-8" )
#ifndef CCSSVGTOPDF_H
#define CCSSVGTOPDF_H
#include <QtSvg/QSvgRenderer>
#include <QFile>
#include <QPdfWriter>
#include <QPainter>
#include <QFont>
#include <QPageLayout>
#include <QPrinter>
//#include <QMatrix>
//#include <QStringRef>
#if QT_VERSION == QT_VERSION_CHECK(5, 15, 2)
#include <QtSvg/5.15.2/QtSvg/private/qsvgtinydocument_p.h>
#include <QtSvg/5.15.2/QtSvg/private/qsvggraphics_p.h>
#endif //
#if QT_VERSION == QT_VERSION_CHECK(5, 15, 4)
#include <QtSvg/5.15.4/QtSvg/private/qsvgtinydocument_p.h>
#include <QtSvg/5.15.4/QtSvg/private/qsvggraphics_p.h>
#endif //
#if QT_VERSION == QT_VERSION_CHECK(5, 12, 0)
#include <QtSvg/5.12.0/QtSvg/private/qsvgtinydocument_p.h>
#include <QtSvg/5.12.0/QtSvg/private/qsvggraphics_p.h>
#endif //
#if QT_VERSION == QT_VERSION_CHECK(5, 15, 0)
#include <QtSvg/5.15.0/QtSvg/private/qsvgtinydocument_p.h>
#include <QtSvg/5.15.0/QtSvg/private/qsvggraphics_p.h>
#endif
#if QT_VERSION == QT_VERSION_CHECK(6, 3, 2)
#include <QtSvg/6.3.2/QtSvg/private/qtsvgexports_p.h>
#include <QtSvg/6.3.2/QtSvg/private/qsvgtinydocument_p.h>
#include <QtSvg/6.3.2/QtSvg/private/qsvggraphics_p.h>
#endif
class ReportSVGRender
{
public:
void Render(QString strPath, QPainter* pPainter,QRectF bounds,int iOption = 0)
{
//std::string str = (strPath).toLocal8Bit();
std::string str = (strPath).toStdString();
const char* ch = str.c_str();
FILE* pf = fopen(ch, "rb+");
if (pf == nullptr) return;
QFile file;
file.open(pf, QIODevice::ReadOnly, QFileDevice::AutoCloseHandle);
QByteArray data = file.readAll();
if (iOption == 1)
{
QSvgRenderer* pRenderer = new QSvgRenderer(data);
pRenderer->render(pPainter, bounds);
file.close();
fclose(pf);
delete pRenderer;
}
else
{
QXmlStreamReader xml(data);
QSvgTinyDocument* doc = QSvgTinyDocument::load(data);
QSvgExtraStates states;
WriteText(pPainter, doc, states, bounds, &xml);
file.close();
fclose(pf);
delete doc;
}
}
bool xmlToNode(QXmlStreamReader* xml, QSvgNode::Type type)
{
while (!xml->atEnd())
{
switch (xml->readNext()) {
case QXmlStreamReader::StartElement:
{
QString localName = xml->name().toString();
if ((type == QSvgNode::G && localName == "g")
|| (type == QSvgNode::TEXT && localName == "text"))
{
return true;
}
}
default:
break;
}
}
return false;
}
void WriteNodeText(QPainter* pPainter, QSvgStructureNode* parentNode, QSvgExtraStates& states, QXmlStreamReader* xml)
{
QList<QSvgNode*> nodeList = parentNode->renderers();
QList<QSvgNode*>::iterator itr = nodeList.begin();
//QList
parentNode->applyStyle(pPainter, states);
while (itr != nodeList.end()) {
QSvgNode* node = *itr;
if ((node->isVisible()) && (node->displayMode() != QSvgNode::NoneMode))
{
if (node->type() == QSvgNode::TEXT)
{
QSvgText* textNode = static_cast<QSvgText*>(node);
textNode->applyStyle(pPainter, states);
qreal oldOpacity = pPainter->opacity();
pPainter->setOpacity(oldOpacity * states.fillOpacity);
// Force the font to have a size of 100 pixels to avoid truncation problems
// when the font is very small.
qreal scale = 100.0 / pPainter->font().pointSizeF();
Qt::Alignment alignment = states.textAnchor;
QTransform oldTransform = pPainter->worldTransform();
pPainter->scale(1 / scale, 1 / scale);
QFont font = pPainter->font();
font.setPixelSize(font.pointSizeF() * scale);
pPainter->setFont(font);
xmlToNode(xml, QSvgNode::TEXT);
QXmlStreamAttributes attributes = xml->attributes();
//const QStringRef x = attributes.value(QLatin1String("x"));
//const QStringRef y = attributes.value(QLatin1String("y"));
const QStringView x = attributes.value(QLatin1String("x"));
const QStringView y = attributes.value(QLatin1String("y"));
#if QT_VERSION == QT_VERSION_CHECK(5, 12, 0)
qreal nx = x.toString().toDouble() * scale;
qreal ny = y.toString().toDouble() * scale;
#else
qreal nx = x.toDouble() * scale;
qreal ny = y.toDouble() * scale;
#endif //
QString text = xmlText(xml);
pPainter->drawText(QPointF(nx, ny), text);
pPainter->setWorldTransform(oldTransform, false);
pPainter->setOpacity(oldOpacity);
textNode->revertStyle(pPainter, states);
}
else if (node->type() == QSvgNode::G)
{
QSvgStructureNode* nodeG = static_cast<QSvgStructureNode*>(node);
xmlToNode(xml, QSvgNode::G);
WriteNodeText(pPainter, nodeG, states, xml);
}
else
{
node->draw(pPainter, states);
}
}
++itr;
}
parentNode->revertStyle(pPainter, states);
}
void WriteText(QPainter* pPainter, QSvgTinyDocument* doc, QSvgExtraStates& states, QRectF& bounds, QXmlStreamReader* xml)
{
QRectF source = doc->viewBox();
//QMatrix matrixSrc = pPainter->matrix();
QTransform curTransform = pPainter->transform();
if (source != bounds && !source.isNull()) {
QTransform transform;
transform.scale(bounds.width() / source.width(),
bounds.height() / source.height());
QRectF c2 = transform.mapRect(source);
pPainter->translate(bounds.x() - c2.x(),
bounds.y() - c2.y());
pPainter->scale(bounds.width() / source.width(),
bounds.height() / source.height());
}
WriteNodeText(pPainter, doc, states, xml);
pPainter->setTransform(curTransform);
//pPainter->setMatrix(matrixSrc);
}
void WriteText(QPainter* pPainter, QSvgTinyDocument* doc, QSvgExtraStates& states, QXmlStreamReader* xml)
{
WriteNodeText(pPainter, doc, states, xml);
}
QString xmlText(QXmlStreamReader* xml)
{
while (!xml->atEnd())
{
switch (xml->readNext()) {
case QXmlStreamReader::Characters:
return xml->text().toString();
break;
default:
break;
}
}
return "";
}
};
#endif