86
bool FSvgRenderer::loadSvg(const QString & filename) {
86
QByteArray FSvgRenderer::loadSvg(const QString & filename) {
87
87
QStringList strings;
89
return loadSvg(filename, strings, strings, string, string, false);
89
return loadSvg(filename, strings, strings, strings, string, string, false);
92
bool FSvgRenderer::loadSvg(const QString & filename, const QStringList & connectorIDs, const QStringList & terminalIDs, const QString & setColor, const QString & colorElementID, bool findNonConnectors) {
92
QByteArray FSvgRenderer::loadSvg(const QString & filename, const QStringList & connectorIDs, const QStringList & terminalIDs, const QStringList & legIDs, const QString & setColor, const QString & colorElementID, bool findNonConnectors) {
93
93
if (!QFileInfo(filename).exists() || !QFileInfo(filename).isFile()) {
97
97
QFile file(filename);
98
98
if (!file.open(QFile::ReadOnly | QFile::Text)) {
102
102
QByteArray contents = file.readAll();
105
if (contents.length() <= 0) return false;
105
if (contents.length() <= 0) return QByteArray();
107
return loadAux(contents, filename, connectorIDs, terminalIDs, setColor, colorElementID, findNonConnectors);
107
return loadAux(contents, filename, connectorIDs, terminalIDs, legIDs, setColor, colorElementID, findNonConnectors);
129
bool FSvgRenderer::loadSvg(const QByteArray & contents, const QString & filename) {
129
QByteArray FSvgRenderer::loadSvg(const QByteArray & contents, const QString & filename) {
130
130
QStringList strings;
132
return loadSvg(contents, filename, strings, strings, string, string, false);
135
bool FSvgRenderer::loadSvg(const QByteArray & contents, const QString & filename, const QStringList & connectorIDs, const QStringList & terminalIDs, const QString & setColor, const QString & colorElementID, bool findNonConnectors) {
136
return loadAux(contents, filename, connectorIDs, terminalIDs, setColor, colorElementID, findNonConnectors);
139
bool FSvgRenderer::loadAux(const QByteArray & contents, const QString & filename, const QStringList & connectorIDs, const QStringList & terminalIDs, const QString & setColor, const QString & colorElementID, bool findNonConnectors) {
132
return loadSvg(contents, filename, strings, strings, strings, string, string, false);
135
QByteArray FSvgRenderer::loadSvg(const QByteArray & contents, const QString & filename, const QStringList & connectorIDs, const QStringList & terminalIDs, const QStringList & legIDs, const QString & setColor, const QString & colorElementID, bool findNonConnectors) {
136
return loadAux(contents, filename, connectorIDs, terminalIDs, legIDs, setColor, colorElementID, findNonConnectors);
139
QByteArray FSvgRenderer::loadAux(const QByteArray & contents, const QString & filename, const QStringList & connectorIDs, const QStringList & terminalIDs, const QStringList & legIDs, const QString & setColor, const QString & colorElementID, bool findNonConnectors) {
141
141
QByteArray cleanContents;
142
142
bool cleaned = false;
190
192
QStringList exceptions;
191
193
exceptions << "black" << "#000000";
192
194
SvgFileSplitter::fixColorRecurse(element, setColor, exceptions);
193
cleanContents = TextUtils::removeXMLEntities(doc.toString()).toUtf8();
195
resetContents = true;
196
198
if (connectorIDs.count() > 0) {
197
initConnectorInfo(doc, connectorIDs, terminalIDs);
199
resetContents = resetContents || initConnectorInfo(doc, connectorIDs, terminalIDs, legIDs);
199
201
if (findNonConnectors) {
200
202
initNonConnectorInfo(doc);
206
cleanContents = TextUtils::removeXMLEntities(doc.toString()).toUtf8();
323
331
QString ws = xml.attributes().value("width").toString();
324
332
QString hs = xml.attributes().value("height").toString();
326
qreal w = TextUtils::convertToInches(ws, &ok, isIllustrator);
334
double w = TextUtils::convertToInches(ws, &ok, isIllustrator);
327
335
if (!ok) return size;
329
qreal h = TextUtils::convertToInches(hs, &ok, isIllustrator);
337
double h = TextUtils::convertToInches(hs, &ok, isIllustrator);
330
338
if (!ok) return size;
332
340
size.setWidth(w);
406
void FSvgRenderer::initConnectorInfo(QDomDocument & domDocument, const QStringList & connectorIDs, const QStringList & terminalIDs)
414
bool FSvgRenderer::initConnectorInfo(QDomDocument & domDocument, const QStringList & connectorIDs, const QStringList & terminalIDs, const QStringList & legIDs)
408
417
clearConnectorInfoHash(m_connectorInfoHash);
409
418
QDomElement root = domDocument.documentElement();
410
419
initConnectorInfoAux(root, connectorIDs);
411
420
if (terminalIDs.count() > 0) {
412
421
initTerminalInfoAux(root, connectorIDs, terminalIDs);
423
if (legIDs.count() > 0) {
424
initLegInfoAux(root, connectorIDs, legIDs, result);
430
void FSvgRenderer::initLegInfoAux(QDomElement & element, const QStringList & connectorIDs, const QStringList & legIDs, bool & gotOne)
432
QString id = element.attribute("id");
434
int ix = legIDs.indexOf(id);
436
element.setTagName("g"); // don't want this element to actually be drawn
438
ConnectorInfo * connectorInfo = m_connectorInfoHash.value(connectorIDs.at(ix), NULL);
440
connectorInfo->legMatrix = TextUtils::elementToMatrix(element);
441
connectorInfo->legColor = element.attribute("stroke");
442
connectorInfo->legLine = QLineF();
443
connectorInfo->legStrokeWidth = 0;
444
initLegInfoAux(element, connectorInfo);
446
// don't return here, might miss other legs
450
QDomElement child = element.firstChildElement();
451
while (!child.isNull()) {
452
initLegInfoAux(child, connectorIDs, legIDs, gotOne);
453
child = child.nextSiblingElement();
457
bool FSvgRenderer::initLegInfoAux(QDomElement & element, ConnectorInfo * connectorInfo)
460
double sw = element.attribute("stroke-width").toDouble(&ok);
461
if (!ok) return false;
463
double x1 = element.attribute("x1").toDouble(&ok);
464
if (!ok) return false;
466
double y1 = element.attribute("y1").toDouble(&ok);
467
if (!ok) return false;
469
double x2 = element.attribute("x2").toDouble(&ok);
470
if (!ok) return false;
472
double y2 = element.attribute("y2").toDouble(&ok);
473
if (!ok) return false;
475
connectorInfo->legStrokeWidth = sw;
476
connectorInfo->legLine = QLineF(x1, y1, x2, y2);
416
480
void FSvgRenderer::initTerminalInfoAux(QDomElement & element, const QStringList & connectorIDs, const QStringList & terminalIDs)
418
482
QString id = element.attribute("id");
419
int ix = terminalIDs.indexOf(id);
421
ConnectorInfo * connectorInfo = m_connectorInfoHash.value(connectorIDs.at(ix), NULL);
423
connectorInfo->terminalMatrix = TextUtils::elementToMatrix(element);
484
int ix = terminalIDs.indexOf(id);
486
ConnectorInfo * connectorInfo = m_connectorInfoHash.value(connectorIDs.at(ix), NULL);
488
connectorInfo->terminalMatrix = TextUtils::elementToMatrix(element);
490
// don't return here, might miss other terminal ids
426
494
QDomElement child = element.firstChildElement();
427
495
while (!child.isNull()) {
428
496
initTerminalInfoAux(child, connectorIDs, terminalIDs);
433
501
void FSvgRenderer::initConnectorInfoAux(QDomElement & element, const QStringList & connectorIDs)
435
503
QString id = element.attribute("id");
436
if (connectorIDs.contains(id)) {
437
ConnectorInfo * connectorInfo = initConnectorInfo(element);
438
m_connectorInfoHash.insert(id, connectorInfo);
505
if (connectorIDs.contains(id)) {
506
ConnectorInfo * connectorInfo = initConnectorInfo(element);
507
m_connectorInfoHash.insert(id, connectorInfo);
509
// don't return here, might miss other connectors
440
512
QDomElement child = element.firstChildElement();
441
513
while (!child.isNull()) {
442
514
initConnectorInfoAux(child, connectorIDs);
477
qreal cx = connectorElement.attribute("cx").toDouble(&ok);
478
if (!ok) return false;
480
qreal cy = connectorElement.attribute("cy").toDouble(&ok);
481
if (!ok) return false;
483
qreal r = connectorElement.attribute("r").toDouble(&ok);
484
if (!ok) return false;
486
qreal sw = connectorElement.attribute("stroke-width").toDouble(&ok);
549
double cx = connectorElement.attribute("cx").toDouble(&ok);
550
if (!ok) return false;
552
double cy = connectorElement.attribute("cy").toDouble(&ok);
553
if (!ok) return false;
555
double r = connectorElement.attribute("r").toDouble(&ok);
556
if (!ok) return false;
558
double sw = connectorElement.attribute("stroke-width").toDouble(&ok);
488
560
//QString strokewidth("stroke-width");
489
561
//QString s = element.attribute("style");
490
562
//SvgFileSplitter::fixStyleAttribute(connectorElement, s, strokewidth);
491
sw = connectorElement.attribute("stroke-width").toDouble(&ok);
563
//sw = connectorElement.attribute("stroke-width").toDouble(&ok);
497
569
connectorInfo->gotCircle = true;
534
606
QRectF bounds = this->boundsOnElement(connectorID);
535
607
if (bounds.isNull() && !svgIdLayer->m_hybrid) { // hybrids can have zero size
536
svgIdLayer->m_visible = false;
608
svgIdLayer->m_svgVisible = false;
537
609
DebugDialog::debug("renderer::setupconnector: null bounds");
541
613
QSizeF defaultSizeF = this->defaultSizeF();
542
QSize defaultSize = this->defaultSize();
543
614
QRectF viewBox = this->viewBoxF();
545
616
ConnectorInfo * connectorInfo = getConnectorInfo(connectorID);
574
645
r1.width() * defaultSizeF.width() / viewBox.width(),
575
646
r1.height() * defaultSizeF.height() / viewBox.height());
577
svgIdLayer->m_visible = !bounds.isNull();
578
svgIdLayer->m_point = calcTerminalPoint(svgIdLayer->m_terminalId, svgIdLayer->m_rect, ignoreTerminalPoint, viewBox, connectorInfo->terminalMatrix, true);
648
svgIdLayer->m_svgVisible = !bounds.isNull();
649
//if (!svgIdLayer->m_svgVisible) {
650
//DebugDialog::debug("not vis");
652
svgIdLayer->m_point = calcTerminalPoint(svgIdLayer->m_terminalId, svgIdLayer->m_rect, ignoreTerminalPoint, viewBox, connectorInfo->terminalMatrix);
653
calcLeg(svgIdLayer, viewBox, connectorInfo);
582
svgIdLayer->m_point = calcTerminalPoint(svgIdLayer->m_terminalId, svgIdLayer->m_rect, ignoreTerminalPoint, viewBox, connectorInfo->terminalMatrix, false);
583
if (calcWeirdOffset) {
584
QRectF trueRect(r1.x() * defaultSizeF.width() / viewBox.width(),
585
r1.y() * defaultSizeF.height() / viewBox.height(),
586
r1.width() * defaultSizeF.width() / viewBox.width(),
587
r1.height() * defaultSizeF.height() / viewBox.height());
589
QPointF truePoint = calcTerminalPoint(svgIdLayer->m_terminalId, trueRect, ignoreTerminalPoint, viewBox, m, true);
590
svgIdLayer->m_weirdOffset = truePoint - svgIdLayer->m_point;
591
if (truePoint != svgIdLayer->m_point) {
592
DebugDialog::debug("difference ");
600
QPointF FSvgRenderer::calcTerminalPoint(const QString & terminalId, const QRectF & connectorRect, bool ignoreTerminalPoint, const QRectF & viewBox, QMatrix & terminalMatrix, bool useF)
658
void FSvgRenderer::calcLeg(SvgIdLayer * svgIdLayer, const QRectF & viewBox, ConnectorInfo * connectorInfo)
660
if (svgIdLayer->m_legId.isEmpty()) return;
662
svgIdLayer->m_legColor = connectorInfo->legColor;
664
QSizeF defaultSizeF = this->defaultSizeF();
665
svgIdLayer->m_legStrokeWidth = connectorInfo->legStrokeWidth * defaultSizeF.width() / viewBox.width();
667
QMatrix matrix = this->matrixForElement(svgIdLayer->m_legId) * connectorInfo->legMatrix;
668
QPointF p1 = matrix.map(connectorInfo->legLine.p1());
669
QPointF p2 = matrix.map(connectorInfo->legLine.p2());
671
double x1 = p1.x() * defaultSizeF.width() / viewBox.width();
672
double y1 = p1.y() * defaultSizeF.height() / viewBox.height();
673
double x2 = p2.x() * defaultSizeF.width() / viewBox.width();
674
double y2 = p2.y() * defaultSizeF.height() / viewBox.height();
675
QPointF center = viewBox.center();
676
double d1 = ((x1 - center.x()) * (x1 - center.x())) + ((y1 - center.y()) * (y1 - center.y()));
677
double d2 = ((x2 - center.x()) * (x2 - center.x())) + ((y2 - center.y()) * (y1 - center.y()));
679
// find the end which is closer to the center of the viewBox (which shouldn't include the leg)
681
svgIdLayer->m_legLine = QLineF(x1, y1, x2, y2);
684
svgIdLayer->m_legLine = QLineF(x2, y2, x1, y1);
688
QPointF FSvgRenderer::calcTerminalPoint(const QString & terminalId, const QRectF & connectorRect, bool ignoreTerminalPoint, const QRectF & viewBox, QMatrix & terminalMatrix)
602
690
QPointF terminalPoint = connectorRect.center() - connectorRect.topLeft(); // default spot is centered
603
691
if (ignoreTerminalPoint) {
629
716
QMatrix tMatrix = this->matrixForElement(terminalId) * terminalMatrix;
630
717
QRectF terminalRect = tMatrix.mapRect(tBounds);
631
718
QPointF c = terminalRect.center();
633
? QPointF(c.x() * defaultSizeF.width() / viewBox.width(), c.y() * defaultSizeF.height() / viewBox.height())
634
: QPointF(c.x() * defaultSize.width() / viewBox.width(), c.y() * defaultSize.height() / viewBox.height());
719
QPointF q(c.x() * defaultSizeF.width() / viewBox.width(), c.y() * defaultSizeF.height() / viewBox.height());
635
720
terminalPoint = q - connectorRect.topLeft();
636
721
//DebugDialog::debug( QString("terminalagain %3 rect %1,%2 ").arg(terminalPoint.x()).
637
722
//arg(terminalPoint.y()).