206 lines
7.0 KiB
C++
206 lines
7.0 KiB
C++
#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 |