TechDraw - SVG changes via DOM manipulation instead of Regex replace
This commit is contained in:
committed by
WandererFan
parent
0717b4fc23
commit
cf721089a9
@@ -50,6 +50,7 @@
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "DrawUtil.h"
|
||||
#include "DrawPage.h"
|
||||
#include "DrawSVGTemplate.h"
|
||||
|
||||
@@ -290,7 +291,6 @@ std::map<std::string, std::string> DrawSVGTemplate::getEditableTextsFromTemplate
|
||||
return editables;
|
||||
}
|
||||
|
||||
|
||||
QDomDocument templateDocument;
|
||||
if (!templateDocument.setContent(&templateFile)) {
|
||||
Base::Console().Message("DrawSVGTemplate::getEditableTextsFromTemplate() - failed to parse file: %s\n",
|
||||
|
||||
@@ -29,9 +29,6 @@
|
||||
#include <QRectF>
|
||||
#include "DrawTemplate.h"
|
||||
|
||||
#define SVG_NS_URI "http://www.w3.org/2000/svg"
|
||||
#define FREECAD_SVG_NS_URI "http://www.freecadweb.org/wiki/index.php?title=Svg_Namespace"
|
||||
|
||||
namespace TechDraw
|
||||
{
|
||||
|
||||
|
||||
@@ -56,6 +56,9 @@
|
||||
|
||||
#define VERTEXTOLERANCE (2.0 * Precision::Confusion())
|
||||
|
||||
#define SVG_NS_URI "http://www.w3.org/2000/svg"
|
||||
#define FREECAD_SVG_NS_URI "http://www.freecadweb.org/wiki/index.php?title=Svg_Namespace"
|
||||
|
||||
namespace TechDraw
|
||||
{
|
||||
|
||||
|
||||
@@ -25,16 +25,23 @@
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
#include <QDomDocument>
|
||||
#endif
|
||||
|
||||
#include <iomanip>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#include <QXmlQuery>
|
||||
#include <QXmlResultItems>
|
||||
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/FileInfo.h>
|
||||
#include <Base/Console.h>
|
||||
|
||||
#include "QDomNodeModel.h"
|
||||
#include "DrawUtil.h"
|
||||
#include "DrawPage.h"
|
||||
#include "DrawViewSymbol.h"
|
||||
|
||||
@@ -68,26 +75,45 @@ void DrawViewSymbol::onChanged(const App::Property* prop)
|
||||
{
|
||||
// Base::Console().Message("DVS::onChanged(%s) \n",prop->getName());
|
||||
if (prop == &Symbol) {
|
||||
if (!isRestoring()) {
|
||||
if (!isRestoring() && Symbol.getValue()[0]) {
|
||||
//this pulls the initial values from svg into editabletexts
|
||||
// should only happen first time?? extra loop onChanged->execute->onChanged
|
||||
std::vector<string> eds;
|
||||
std::string svg = Symbol.getValue();
|
||||
if (!svg.empty()) {
|
||||
boost::regex e ("<text.*?freecad:editable=\"(.*?)\".*?<tspan.*?>(.*?)</tspan>");
|
||||
std::string::const_iterator tbegin, tend;
|
||||
tbegin = svg.begin();
|
||||
tend = svg.end();
|
||||
boost::match_results<std::string::const_iterator> twhat;
|
||||
while (boost::regex_search(tbegin, tend, twhat, e)) {
|
||||
eds.push_back(twhat[2]);
|
||||
tbegin = twhat[0].second;
|
||||
|
||||
std::vector<string> editables;
|
||||
QDomDocument symbolDocument;
|
||||
|
||||
if (symbolDocument.setContent(QString::fromUtf8(Symbol.getValue()))) {
|
||||
QDomElement symbolDocElem = symbolDocument.documentElement();
|
||||
|
||||
QXmlQuery query(QXmlQuery::XQuery10);
|
||||
QDomNodeModel model(query.namePool(), symbolDocument);
|
||||
query.setFocus(QXmlItem(model.fromDomNode(symbolDocElem)));
|
||||
|
||||
// XPath query to select all <tspan> nodes whose <text> parent
|
||||
// has "freecad:editable" attribute
|
||||
query.setQuery(QString::fromUtf8(
|
||||
"declare default element namespace \"" SVG_NS_URI "\"; "
|
||||
"declare namespace freecad=\"" FREECAD_SVG_NS_URI "\"; "
|
||||
"//text[@freecad:editable]/tspan"));
|
||||
|
||||
QXmlResultItems queryResult;
|
||||
query.evaluateTo(&queryResult);
|
||||
|
||||
while (!queryResult.next().isNull())
|
||||
{
|
||||
QDomElement tspanElement = model.toDomNode(queryResult.current().toNodeModelIndex()).toElement();
|
||||
editables.push_back(tspanElement.text().toStdString());
|
||||
}
|
||||
EditableTexts.setValues(eds);
|
||||
// requestPaint();
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning("DrawViewSymbol:onChanged - SVG for Symbol is not a valid document\n");
|
||||
}
|
||||
|
||||
EditableTexts.setValues(editables);
|
||||
// requestPaint();
|
||||
}
|
||||
}
|
||||
|
||||
TechDraw::DrawView::onChanged(prop);
|
||||
}
|
||||
|
||||
@@ -102,27 +128,51 @@ App::DocumentObjectExecReturn *DrawViewSymbol::execute(void)
|
||||
std::string svg = Symbol.getValue();
|
||||
const std::vector<std::string>& editText = EditableTexts.getValues();
|
||||
|
||||
//this pushes the editabletexts into the svg
|
||||
std::string newsvg = svg;
|
||||
if (!editText.empty()) {
|
||||
boost::regex e1 ("<text.*?freecad:editable=\"(.*?)\".*?<tspan.*?>(.*?)</tspan>");
|
||||
string::const_iterator begin, end;
|
||||
begin = svg.begin();
|
||||
end = svg.end();
|
||||
boost::match_results<std::string::const_iterator> what;
|
||||
std::size_t count = 0;
|
||||
QDomDocument symbolDocument;
|
||||
|
||||
while (boost::regex_search(begin, end, what, e1)) {
|
||||
if (count < editText.size()) {
|
||||
boost::regex e2 ("(<text.*?freecad:editable=\"" + what[1].str() + "\".*?<tspan.*?)>(.*?)(</tspan>)");
|
||||
newsvg = boost::regex_replace(newsvg, e2, "$1>" + editText[count] + "$3");
|
||||
if (symbolDocument.setContent(QString::fromUtf8(Symbol.getValue()))) {
|
||||
QDomElement symbolDocElem = symbolDocument.documentElement();
|
||||
|
||||
QXmlQuery query(QXmlQuery::XQuery10);
|
||||
QDomNodeModel model(query.namePool(), symbolDocument);
|
||||
query.setFocus(QXmlItem(model.fromDomNode(symbolDocElem)));
|
||||
|
||||
// XPath query to select all <tspan> nodes whose <text> parent
|
||||
// has "freecad:editable" attribute
|
||||
query.setQuery(QString::fromUtf8(
|
||||
"declare default element namespace \"" SVG_NS_URI "\"; "
|
||||
"declare namespace freecad=\"" FREECAD_SVG_NS_URI "\"; "
|
||||
"//text[@freecad:editable]/tspan"));
|
||||
|
||||
QXmlResultItems queryResult;
|
||||
query.evaluateTo(&queryResult);
|
||||
|
||||
unsigned int count = 0;
|
||||
while (!queryResult.next().isNull())
|
||||
{
|
||||
QDomElement tspanElement = model.toDomNode(queryResult.current().toNodeModelIndex()).toElement();
|
||||
|
||||
// Keep all spaces in the text node
|
||||
tspanElement.setAttribute(QString::fromUtf8("xml:space"), QString::fromUtf8("preserve"));
|
||||
|
||||
// Remove all child nodes (if any)
|
||||
while (!tspanElement.lastChild().isNull()) {
|
||||
tspanElement.removeChild(tspanElement.lastChild());
|
||||
}
|
||||
|
||||
// Finally append text node with editable replacement as the only <tspan> descendant
|
||||
tspanElement.appendChild(symbolDocument.createTextNode(QString::fromUtf8(editText[count].c_str())));
|
||||
++count;
|
||||
}
|
||||
count++;
|
||||
begin = what[0].second;
|
||||
}
|
||||
|
||||
Symbol.setValue(symbolDocument.toString(1).toStdString());
|
||||
}
|
||||
else {
|
||||
Base::Console().Warning("DrawViewSymbol:execute - SVG for Symbol is not a valid document\n");
|
||||
}
|
||||
}
|
||||
Symbol.setValue(newsvg);
|
||||
|
||||
// requestPaint();
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
@@ -28,10 +28,12 @@
|
||||
#include <QPen>
|
||||
#include <QSvgRenderer>
|
||||
#include <QGraphicsSvgItem>
|
||||
#include <boost/regex.hpp>
|
||||
#include <QDomDocument>
|
||||
#endif // #ifndef _PreComp_
|
||||
|
||||
#include <QFile>
|
||||
#include <QXmlQuery>
|
||||
#include <QXmlResultItems>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Base/Console.h>
|
||||
@@ -39,6 +41,8 @@
|
||||
#include <Base/Parameter.h>
|
||||
#include <Gui/Command.h>
|
||||
|
||||
#include <Mod/TechDraw/App/QDomNodeModel.h>
|
||||
#include <Mod/TechDraw/App/DrawUtil.h>
|
||||
#include <Mod/TechDraw/App/Geometry.h>
|
||||
#include <Mod/TechDraw/App/DrawSVGTemplate.h>
|
||||
|
||||
@@ -142,90 +146,87 @@ void QGISVGTemplate::updateView(bool update)
|
||||
|
||||
void QGISVGTemplate::createClickHandles(void)
|
||||
{
|
||||
TechDraw::DrawSVGTemplate *tmplte = getSVGTemplate();
|
||||
std::string temp = tmplte->PageResult.getValue();
|
||||
TechDraw::DrawSVGTemplate *svgTemplate = getSVGTemplate();
|
||||
QString templateFilename(QString::fromUtf8(svgTemplate->PageResult.getValue()));
|
||||
|
||||
if (temp.empty())
|
||||
if (templateFilename.isEmpty()) {
|
||||
return;
|
||||
|
||||
Base::FileInfo fi(temp);
|
||||
|
||||
std::ostringstream oStream;
|
||||
std::string tempendl = "--endOfLine--";
|
||||
std::string line;
|
||||
|
||||
//read all of PageResult into oStream (except the DrawingContent marker comment - why??)
|
||||
std::ifstream ifile (fi.filePath().c_str());
|
||||
while (std::getline(ifile,line))
|
||||
{
|
||||
// check if the marker in the template is found
|
||||
if(line.find("<!-- DrawingContent -->") == std::string::npos) {
|
||||
// if not - write line to oStream
|
||||
oStream << line << tempendl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string outfragment(oStream.str());
|
||||
QFile file(templateFilename);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
Base::Console().Error("QGISVGTemplate::createClickHandles - error opening template file %s\n",
|
||||
svgTemplate->PageResult.getValue());
|
||||
return;
|
||||
}
|
||||
|
||||
// Find text tags with freecad:editable attribute and their matching tspans
|
||||
// keep tagRegex in sync with App/DrawSVGTemplate.cpp
|
||||
boost::regex tagRegex("<text([^>]*freecad:editable=[^>]*)>[^<]*<tspan[^>]*>([^<]*)</tspan>");
|
||||
QDomDocument templateDocument;
|
||||
if (!templateDocument.setContent(&file)) {
|
||||
Base::Console().Message("QGISVGTemplate::createClickHandles - xml loading error\n");
|
||||
return;
|
||||
}
|
||||
file.close();
|
||||
|
||||
// Smaller regexes for parsing matches to tagRegex
|
||||
boost::regex editableNameRegex("freecad:editable=\"(.*?)\"");
|
||||
boost::regex xRegex("x=\"([\\d.-]+)\"");
|
||||
boost::regex yRegex("y=\"([\\d.-]+)\"");
|
||||
//Note: some templates have fancy Transform clauses and don't use absolute x,y to position editableFields.
|
||||
// editableFields will be in the wrong place in this case.
|
||||
QDomElement templateDocElem = templateDocument.documentElement();
|
||||
|
||||
std::string::const_iterator begin, end;
|
||||
begin = outfragment.begin();
|
||||
end = outfragment.end();
|
||||
boost::match_results<std::string::const_iterator> tagMatch, nameMatch, xMatch, yMatch;
|
||||
QXmlQuery query(QXmlQuery::XQuery10);
|
||||
QDomNodeModel model(query.namePool(), templateDocument);
|
||||
query.setFocus(QXmlItem(model.fromDomNode(templateDocElem)));
|
||||
|
||||
// XPath query to select all <text> nodes with "freecad:editable" attribute
|
||||
query.setQuery(QString::fromUtf8(
|
||||
"declare default element namespace \"" SVG_NS_URI "\"; "
|
||||
"declare namespace freecad=\"" FREECAD_SVG_NS_URI "\"; "
|
||||
"//text[@freecad:editable]"));
|
||||
|
||||
QXmlResultItems queryResult;
|
||||
query.evaluateTo(&queryResult);
|
||||
|
||||
//TODO: Find location of special fields (first/third angle) and make graphics items for them
|
||||
|
||||
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/General");
|
||||
double dotSize = hGrp->GetFloat("TemplateDotSize", 3.0);
|
||||
double editClickBoxSize = Rez::guiX(hGrp->GetFloat("TemplateDotSize", 3.0));
|
||||
|
||||
while (boost::regex_search(begin, end, tagMatch, tagRegex)) {
|
||||
if ( boost::regex_search(tagMatch[1].first, tagMatch[1].second, nameMatch, editableNameRegex) &&
|
||||
boost::regex_search(tagMatch[1].first, tagMatch[1].second, xMatch, xRegex) &&
|
||||
boost::regex_search(tagMatch[1].first, tagMatch[1].second, yMatch, yRegex) ) {
|
||||
QColor editClickBoxColor = Qt::green;
|
||||
editClickBoxColor.setAlpha(128); //semi-transparent
|
||||
|
||||
QString xStr = QString::fromStdString(xMatch[1].str());
|
||||
QString yStr = QString::fromStdString(yMatch[1].str());
|
||||
double width = editClickBoxSize;
|
||||
double height = editClickBoxSize;
|
||||
|
||||
double x = Rez::guiX(xStr.toDouble());
|
||||
double y = Rez::guiX(yStr.toDouble());
|
||||
while (!queryResult.next().isNull())
|
||||
{
|
||||
QDomElement textElement = model.toDomNode(queryResult.current().toNodeModelIndex()).toElement();
|
||||
|
||||
double editClickBoxSize = Rez::guiX(dotSize);
|
||||
QColor editClickBoxColor = Qt::green;
|
||||
editClickBoxColor.setAlpha(128); //semi-transparent
|
||||
QString name = textElement.attribute(QString::fromUtf8("freecad:editable"));
|
||||
double x = Rez::guiX(textElement.attribute(QString::fromUtf8("x"), QString::fromUtf8("0.0")).toDouble());
|
||||
double y = Rez::guiX(textElement.attribute(QString::fromUtf8("y"), QString::fromUtf8("0.0")).toDouble());
|
||||
|
||||
double width = editClickBoxSize;
|
||||
double height = editClickBoxSize;
|
||||
|
||||
auto item( new TemplateTextField(this, tmplte, nameMatch[1].str()) );
|
||||
float pad = 1;
|
||||
|
||||
item->setRect(x - pad, Rez::guiX(-tmplte->getHeight()) + y - height - pad,
|
||||
width + 2 * pad, height + 2 * pad);
|
||||
QPen myPen;
|
||||
QBrush myBrush(editClickBoxColor,Qt::SolidPattern);
|
||||
myPen.setStyle(Qt::SolidLine);
|
||||
myPen.setColor(editClickBoxColor);
|
||||
myPen.setWidth(0); // 0 means "cosmetic pen" - always 1px
|
||||
item->setPen(myPen);
|
||||
item->setBrush(myBrush);
|
||||
|
||||
item->setZValue(ZVALUE::SVGTEMPLATE + 1);
|
||||
addToGroup(item);
|
||||
textFields.push_back(item);
|
||||
if (name.isEmpty()) {
|
||||
Base::Console().Warning("QGISVGTemplate::createClickHandles - no name for editable text at %f, %f\n",
|
||||
x, y);
|
||||
continue;
|
||||
}
|
||||
|
||||
begin = tagMatch[0].second;
|
||||
auto item(new TemplateTextField(this, svgTemplate, name.toStdString()));
|
||||
|
||||
double pad = 1.0;
|
||||
item->setRect(x - pad, Rez::guiX(-svgTemplate->getHeight()) + y - height - pad,
|
||||
width + 2.0*pad, height + 2.0*pad);
|
||||
|
||||
QPen myPen;
|
||||
myPen.setStyle(Qt::SolidLine);
|
||||
myPen.setColor(editClickBoxColor);
|
||||
myPen.setWidth(0); // 0 means "cosmetic pen" - always 1px
|
||||
item->setPen(myPen);
|
||||
|
||||
QBrush myBrush(editClickBoxColor,Qt::SolidPattern);
|
||||
item->setBrush(myBrush);
|
||||
|
||||
item->setZValue(ZVALUE::SVGTEMPLATE + 1);
|
||||
addToGroup(item);
|
||||
|
||||
textFields.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#include <Mod/TechDraw/App/DrawTile.h>
|
||||
#include <Mod/TechDraw/App/DrawTileWeld.h>
|
||||
#include <Mod/TechDraw/App/QDomNodeModel.h>
|
||||
#include <Mod/TechDraw/App/DrawUtil.h>
|
||||
|
||||
#include "Rez.h"
|
||||
#include "QGIDrawingTemplate.h"
|
||||
@@ -867,29 +868,13 @@ void QGVPage::postProcessXml(QTemporaryFile& temporaryFile, QString fileName, QS
|
||||
|
||||
QDomElement exportDocElem = exportDoc.documentElement(); //root <svg>
|
||||
|
||||
QXmlQuery query(QXmlQuery::XQuery10);
|
||||
QDomNodeModel model(query.namePool(), exportDoc);
|
||||
query.setFocus(QXmlItem(model.fromDomNode(exportDocElem)));
|
||||
|
||||
// XPath query to select first <g> node as direct <svg> element descendant
|
||||
query.setQuery(QString::fromUtf8(
|
||||
"declare default element namespace \"" SVG_NS_URI "\"; "
|
||||
"declare namespace freecad=\"" FREECAD_SVG_NS_URI "\"; "
|
||||
"/svg/g[1]"));
|
||||
|
||||
QXmlResultItems queryResult;
|
||||
query.evaluateTo(&queryResult);
|
||||
|
||||
// Insert Freecad SVG namespace into namespace declarations
|
||||
exportDocElem.setAttribute(QString::fromUtf8("xmlns:freecad"),
|
||||
QString::fromUtf8(FREECAD_SVG_NS_URI));
|
||||
|
||||
// Set the first group's id to page name
|
||||
QDomElement g;
|
||||
if (!queryResult.next().isNull()) {
|
||||
g = model.toDomNode(queryResult.current().toNodeModelIndex()).toElement();
|
||||
g.setAttribute(QString::fromUtf8("id"), pageName);
|
||||
}
|
||||
// Create the root group which will host the drawing group and the template group
|
||||
QDomElement rootGroup = exportDoc.createElement(QString::fromUtf8("g"));
|
||||
rootGroup.setAttribute(QString::fromUtf8("id"), pageName);
|
||||
|
||||
// Now insert our template
|
||||
QGISVGTemplate *svgTemplate = dynamic_cast<QGISVGTemplate *>(pageTemplate);
|
||||
@@ -903,33 +888,51 @@ void QGVPage::postProcessXml(QTemporaryFile& temporaryFile, QString fileName, QS
|
||||
QDomElement templateDocElem = templateResultDoc.documentElement();
|
||||
|
||||
// Insert the template into a new group with id set to template name
|
||||
QDomElement groupWrapper = exportDoc.createElement(QString::fromUtf8("g"));
|
||||
QDomElement templateGroup = exportDoc.createElement(QString::fromUtf8("g"));
|
||||
Base::FileInfo fi(drawTemplate->Template.getValue());
|
||||
groupWrapper.setAttribute(QString::fromUtf8("id"),
|
||||
QString::fromUtf8(fi.fileName().c_str()));
|
||||
groupWrapper.setAttribute(QString::fromUtf8("style"),
|
||||
QString::fromUtf8("stroke: none;"));
|
||||
templateGroup.setAttribute(QString::fromUtf8("id"),
|
||||
QString::fromUtf8(fi.fileName().c_str()));
|
||||
templateGroup.setAttribute(QString::fromUtf8("style"),
|
||||
QString::fromUtf8("stroke: none;"));
|
||||
|
||||
// Scale the template group correctly
|
||||
groupWrapper.setAttribute(QString::fromUtf8("transform"),
|
||||
templateGroup.setAttribute(QString::fromUtf8("transform"),
|
||||
QString().sprintf("scale(%f, %f)", Rez::guiX(1.0), Rez::guiX(1.0)));
|
||||
|
||||
// Finally, transfer all template document child nodes under the wrapper group
|
||||
// Finally, transfer all template document child nodes under the template group
|
||||
while (!templateDocElem.firstChild().isNull()) {
|
||||
groupWrapper.appendChild(templateDocElem.firstChild());
|
||||
templateGroup.appendChild(templateDocElem.firstChild());
|
||||
}
|
||||
|
||||
if (!g.isNull()) {
|
||||
g.insertBefore(groupWrapper, QDomNode());
|
||||
}
|
||||
else {
|
||||
exportDocElem.insertBefore(groupWrapper, QDomNode());
|
||||
}
|
||||
rootGroup.appendChild(templateGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QXmlQuery query(QXmlQuery::XQuery10);
|
||||
QDomNodeModel model(query.namePool(), exportDoc);
|
||||
query.setFocus(QXmlItem(model.fromDomNode(exportDocElem)));
|
||||
|
||||
// XPath query to select first <g> node as direct <svg> element descendant
|
||||
query.setQuery(QString::fromUtf8(
|
||||
"declare default element namespace \"" SVG_NS_URI "\"; "
|
||||
"declare namespace freecad=\"" FREECAD_SVG_NS_URI "\"; "
|
||||
"/svg/g[1]"));
|
||||
|
||||
QXmlResultItems queryResult;
|
||||
query.evaluateTo(&queryResult);
|
||||
|
||||
// Obtain the drawing group element, move it under root node and set its id to "DrawingContent"
|
||||
QDomElement drawingGroup;
|
||||
if (!queryResult.next().isNull()) {
|
||||
drawingGroup = model.toDomNode(queryResult.current().toNodeModelIndex()).toElement();
|
||||
drawingGroup.setAttribute(QString::fromUtf8("id"), QString::fromUtf8("DrawingContent"));
|
||||
rootGroup.appendChild(drawingGroup);
|
||||
}
|
||||
|
||||
exportDocElem.appendChild(rootGroup);
|
||||
|
||||
// As icing on the cake, get rid of the empty <g>'s Qt SVG generator painting inserts.
|
||||
// XPath query to select any <g> element anywhere with no child nodes whatsoever
|
||||
query.setQuery(QString::fromUtf8(
|
||||
@@ -939,7 +942,7 @@ void QGVPage::postProcessXml(QTemporaryFile& temporaryFile, QString fileName, QS
|
||||
|
||||
query.evaluateTo(&queryResult);
|
||||
while (!queryResult.next().isNull()) {
|
||||
g = model.toDomNode(queryResult.current().toNodeModelIndex()).toElement();
|
||||
QDomElement g(model.toDomNode(queryResult.current().toNodeModelIndex()).toElement());
|
||||
g.parentNode().removeChild(g);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.6 KiB |
@@ -2,6 +2,7 @@
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:freecad="http://www.freecadweb.org/wiki/index.php?title=Svg_Namespace"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
@@ -84,11 +85,11 @@ All symbols in this repository are licensed under CC-BY 3.0</dc:description>
|
||||
x="33.975941"
|
||||
y="1041.7771"
|
||||
id="text5288"
|
||||
xml:space="preserve"
|
||||
style="font-size:5.07499981px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial Narrow;-inkscape-font-specification:'Arial Narrow, Condensed'"><tspan
|
||||
x="33.975941"
|
||||
y="1041.7771"
|
||||
id="tspan5290"
|
||||
xml:space="preserve"
|
||||
style="font-size:5.07499981px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;text-align:center;line-height:100%;writing-mode:lr-tb;text-anchor:middle;font-family:Arial Narrow;-inkscape-font-specification:'Arial Narrow, Condensed'">A</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.8 KiB |
@@ -2,6 +2,7 @@
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:freecad="http://www.freecadweb.org/wiki/index.php?title=Svg_Namespace"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
@@ -94,12 +95,13 @@
|
||||
id="text5269"
|
||||
y="1041.7535"
|
||||
x="23.514435"
|
||||
style="font-size:5.07499981px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial Narrow;-inkscape-font-specification:'Arial Narrow, Condensed'"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:5.07499981px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;text-align:center;line-height:100%;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial Narrow;-inkscape-font-specification:'Arial Narrow, Condensed'">
|
||||
<tspan
|
||||
style="font-size:5.07499981px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;text-align:center;line-height:100%;writing-mode:lr-tb;text-anchor:middle;font-family:Arial Narrow;-inkscape-font-specification:'Arial Narrow, Condensed'"
|
||||
y="1041.7535"
|
||||
x="23.514435"
|
||||
id="tspan5271"
|
||||
xml:space="preserve"
|
||||
sodipodi:role="line">0.01</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.0 KiB |
Reference in New Issue
Block a user