30<svg id="main" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" onload="init(evt)">
34<svg id="main" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
38<style type="text/css"><![CDATA[
39.node, .edge {opacity: 0.7;}
40.node.selected, .edge.selected {opacity: 1;}
41.edge:hover path { stroke: red; }
42.edge:hover polygon { stroke: red; fill: red; }
49 <circle id="rim" cx="0" cy="0" r="7"/>
50 <circle id="rim2" cx="0" cy="0" r="3.5"/>
52 <use xlink:href="#rim" fill="#404040"><set attributeName="fill" to="#808080" begin="zoomplus.mouseover" end="zoomplus.mouseout"/></use>
53 <path d="M-4,0h8M0,-4v8" fill="none" stroke="white" stroke-width="1.5" pointer-events="none"/>
56 <use xlink:href="#rim" fill="#404040"><set attributeName="fill" to="#808080" begin="zoomminus.mouseover" end="zoomminus.mouseout"/></use>
57 <path d="M-4,0h8" fill="none" stroke="white" stroke-width="1.5" pointer-events="none"/>
59 <g id="arrowUp" transform="translate(30 24)">
60 <use xlink:href="#rim"/>
61 <path pointer-events="none" fill="none" stroke="white" stroke-width="1.5" d="M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5"/>
63 <g id="arrowRight" transform="rotate(90) translate(36 -43)">
64 <use xlink:href="#rim"/>
65 <path pointer-events="none" fill="none" stroke="white" stroke-width="1.5" d="M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5"/>
67 <g id="arrowDown" transform="rotate(180) translate(-30 -48)">
68 <use xlink:href="#rim"/>
69 <path pointer-events="none" fill="none" stroke="white" stroke-width="1.5" d="M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5"/>
71 <g id="arrowLeft" transform="rotate(270) translate(-36 17)">
72 <use xlink:href="#rim"/>
73 <path pointer-events="none" fill="none" stroke="white" stroke-width="1.5" d="M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5"/>
76 <use xlink:href="#rim2" fill="#404040"><set attributeName="fill" to="#808080" begin="reset.mouseover" end="reset.mouseout"/></use>
83<g id="navigator" transform="translate(0 0)" fill="#404254">
84 <rect fill="#f2f5e9" fill-opacity="0.5" stroke="#606060" stroke-width=".5" x="0" y="0" width="60" height="60"/>
85 <use id="zoomplus" xlink:href="#zoomPlus" x="17" y="9" onmousedown="handleZoom(evt,'in')"/>
86 <use id="zoomminus" xlink:href="#zoomMin" x="42" y="9" onmousedown="handleZoom(evt,'out')"/>
87 <use id="reset" xlink:href="#resetDef" x="30" y="36" onmousedown="handleReset()"/>
88 <use id="arrowup" xlink:href="#arrowUp" x="0" y="0" onmousedown="handlePan(0,-1)"/>
89 <use id="arrowright" xlink:href="#arrowRight" x="0" y="0" onmousedown="handlePan(1,0)"/>
90 <use id="arrowdown" xlink:href="#arrowDown" x="0" y="0" onmousedown="handlePan(0,1)"/>
91 <use id="arrowleft" xlink:href="#arrowLeft" x="0" y="0" onmousedown="handlePan(-1,0)"/>
93<svg viewBox="0 0 15 15" width="100%" height="30px" preserveAspectRatio="xMaxYMin meet">
94 <g id="arrow_out" transform="scale(0.3 0.3)">
95 <a xlink:href="$orgname" target="_base">
96 <rect id="button" ry="5" rx="5" y="6" x="6" height="38" width="38"
97 fill="#f2f5e9" fill-opacity="0.5" stroke="#606060" stroke-width="1.0"/>
99 d="M 11.500037,31.436501 C 11.940474,20.09759 22.043105,11.32322 32.158766,21.979434 L 37.068811,17.246167 C 37.068811,17.246167 37.088388,32 37.088388,32 L 22.160133,31.978069 C 22.160133,31.978069 26.997745,27.140456 26.997745,27.140456 C 18.528582,18.264221 13.291696,25.230495 11.500037,31.436501 z"
100 style="fill:#404040;"/>
108<style type='text/css'>
110[data-mouse-over-selected='false'] { opacity: 0.7; }
111[data-mouse-over-selected='true'] { opacity: 1.0; }
114<script type="application/ecmascript"><![CDATA[
115document.addEventListener('DOMContentLoaded', (event) => {
117 highlightAdjacentNodes();
130 int indexS = buf.
find(
"href=\""), indexE = 0;
131 bool targetAlreadySet = buf.
find(
"target=")!=-1;
132 if (indexS>5 && buf.
find(
"xlink:href=\"")!=-1)
139 if (indexS>=0 && (indexE=buf.
find(
'"',indexS+len))!=-1)
141 QCString link = buf.
mid(indexS+len,indexE-indexS-len);
150 auto dfAst {
createRef( *parser.get(), link.
mid(5), context ) };
151 auto dfAstImpl =
dynamic_cast<const DocNodeAST*
>(dfAst.get());
152 const DocRef *df = std::get_if<DocRef>(&dfAstImpl->root);
162 result +=
"#" + df->
anchor();
168 result = href+
"=\"" + link +
"\"";
173 int marker = link.
find(
'$');
181 if (!result.
isEmpty())targetAlreadySet=
true;
189 result = href+
"=\"" + link +
"\"";
192 if (!target.isEmpty() && !targetAlreadySet)
194 result+=
" target=\""+target+
"\"";
200 return leftPart + result + rightPart;
220 const QCString &relPath,
bool urlOnly,
226 err(
"problems opening map file %s for inclusion in the docs!\n"
227 "If you installed Graphviz/dot after a previous failing run, \n"
228 "try deleting the output directory and rerun doxygen.\n",
qPrint(mapName));
232 while (getline(f,line))
240 int indexA = replBuf.
find(
"alt=");
243 replBuf = replBuf.
left(5) +
" alt=\"\"" + replBuf.
right(replBuf.
length() - 5);
247 int indexS = replBuf.
find(
"id=\""), indexE = 0;
248 if (indexS>0 && (indexE=replBuf.
find(
'"',indexS+4))!=-1)
250 t << replBuf.
left(indexS-1) << replBuf.
right(replBuf.
length() - indexE - 1);
274 size_t id =
m_maps.size();
275 m_maps.emplace_back(mapFile,relPath,urlOnly,context,label);
276 return static_cast<int>(id);
280 const QCString &figureName,
bool heightCheck)
282 size_t id =
m_maps.size();
283 m_maps.emplace_back(figureName,
"",heightCheck,
"",baseName);
284 return static_cast<int>(id);
288 const QCString &context,
bool zoomable,
291 size_t id =
m_maps.size();
292 m_maps.emplace_back(
"",relPath,urlOnly,context,
"",zoomable,graphId);
293 return static_cast<int>(id);
300 size_t id =
m_maps.size();
301 m_maps.emplace_back(absImgName,relPath,
false,
"",baseName);
302 return static_cast<int>(id);
315 interactiveSVG = interactiveSVG && map.
zoomable;
332 err(
"problem opening file %s for patching!\n",
qPrint(tmpName));
343 int width=0,height=0;
344 bool insideHeader=
FALSE;
345 bool replacedHeader=
FALSE;
346 bool useNagivation=
FALSE;
348 static const reg::Ex reSVG(R
"([\[<]!-- SVG [0-9]+)");
349 static const reg::Ex reMAP(R
"(<!-- MAP [0-9]+)");
350 static const reg::Ex reFIG(R
"(% FIG [0-9]+)");
352 while (getline(fi,lineStr))
361 if (line.
find(
"<svg")!=-1 && !replacedHeader)
363 int count = sscanf(line.
data(),
"<svg width=\"%dpt\" height=\"%dpt\"",&width,&height);
365 useNagivation = count==2 && (width>500 || height>450);
366 insideHeader = count==2;
368 else if (insideHeader && !replacedHeader && line.
find(
"<g id=\"graph")!=-1)
373 t <<
"<!--zoomable " << height <<
" -->\n";
387 t <<
"<script type=\"application/ecmascript\">\n";
388 t <<
"var viewWidth = " << width <<
";\n";
389 t <<
"var viewHeight = " << height <<
";\n";
392 t <<
"var sectionId = 'dynsection-" << graphId <<
"';\n";
396 t <<
"<script type=\"application/ecmascript\" xlink:href=\"" << relPath <<
"svg.min.js\"/>\n";
397 t <<
"<svg id=\"graph\" class=\"graph\">\n";
401 t <<
"<g id=\"viewport\">\n";
412 if (!insideHeader || !useNagivation)
425 int n = sscanf(line.
data()+i+1,
"!-- SVG %d",&mapId);
426 if (n==1 && mapId>=0 && mapId<
static_cast<int>(
m_maps.size()))
428 int e = std::max(line.
find(
"--]"),line.
find(
"-->"));
436 if (e!=-1) t << line.
mid(e+3);
448 int n = sscanf(line.
data()+i,
"<!-- MAP %d",&mapId);
449 if (n==1 && mapId>=0 && mapId<
static_cast<int>(
m_maps.size()))
472 int n = sscanf(line.
data()+i+2,
"FIG %d",&mapId);
474 if (n==1 && mapId>=0 && mapId<
static_cast<int>(
m_maps.size()))
481 err(
"problem writing FIG %d figure!\n",mapId);
496 if (
isSVGFile && interactiveSVG && !useNagivation) t <<
"</svg>\n";
499 if (
isSVGFile && interactiveSVG && replacedHeader)
515 err(
"problem opening file %s for reading!\n",
qPrint(tmpName));
520 err(
"problem opening file %s for writing!\n",
qPrint(orgName));
524 while (getline(fi,lineStr))
526 std::string line = lineStr+
'\n';
552 while (getline(f,line) && !
found)
554 if (
qstrncmp(line.c_str(),
"<!--zoomable ",13)==0)
558 sscanf(line.c_str(),
"<!--zoomable %d",height);
561 else if (sscanf(line.c_str(),
"<svg width=\"%dpt\" height=\"%dpt\"",width,height)==2)
571 out <<
"<p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p>";
579 int width=600,height=600;
586 if (height<=60) height=300;
else height+=300;
587 if (height>600) height=600;
588 out <<
"<div class=\"zoom\">";
591 out <<
"<iframe scrolling=\"no\" frameborder=\"0\" src=\""
592 << relPath << baseName <<
".svg\" width=\"100%\" height=\"" << height <<
"\">";
598 out <<
"<iframe scrolling=\"no\" frameborder=\"0\" src=\""
599 << relPath << baseName <<
".svg\" width=\""
600 << ((width*96+48)/72) <<
"\" height=\""
601 << ((height*96+48)/72) <<
"\">";
618 int width=400,height=550;
638 out <<
"\\nopagebreak\n"
639 "\\begin{figure}[H]\n"
642 if (width>maxWidth || height>maxHeight)
645 if (width*maxHeight>height*maxWidth)
647 out <<
"\\includegraphics[width=" << maxWidth <<
"pt]";
651 out <<
"\\includegraphics[height=" << maxHeight <<
"pt]";
656 out <<
"\\includegraphics[width=" << width <<
"pt]";
659 out <<
"{" << baseName <<
"}\n"
Class representing a directory in the file system.
bool remove(const std::string &path, bool acceptsAbsPath=true) const
bool rename(const std::string &orgName, const std::string &newName, bool acceptsAbsPath=true) const
Class representing the abstract syntax tree of a documentation block.
Node representing a reference to some item.
static bool writeVecGfxFigure(TextStream &out, const QCString &baseName, const QCString &figureName)
static bool convertMapFile(TextStream &t, const QCString &mapName, const QCString &relPath, bool urlOnly=FALSE, const QCString &context=QCString())
DotFilePatcher(const QCString &patchFile)
std::vector< Map > m_maps
int addSVGObject(const QCString &baseName, const QCString &figureName, const QCString &relPath)
int addMap(const QCString &mapFile, const QCString &relPath, bool urlOnly, const QCString &context, const QCString &label)
int addSVGConversion(const QCString &relPath, bool urlOnly, const QCString &context, bool zoomable, int graphId)
static bool writeSVGFigureLink(TextStream &out, const QCString &relPath, const QCString &baseName, const QCString &absImgName)
Check if a reference to a SVG figure can be written and do so if possible.
int addFigure(const QCString &baseName, const QCString &figureName, bool heightCheck)
static bool readBoundingBox(const QCString &fileName, int *width, int *height, bool isEps)
This is an alternative implementation of QCString.
int find(char c, int index=0, bool cs=TRUE) const
QCString & prepend(const char *s)
size_t length() const
Returns the length of the string, not counting the 0-terminator.
bool startsWith(const char *s) const
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
bool isEmpty() const
Returns TRUE iff the string is empty.
const std::string & str() const
QCString right(size_t len) const
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
QCString left(size_t len) const
Text streaming class that buffers data.
bool empty() const
Returns true iff the buffer is empty.
void setStream(std::ostream *s)
Sets or changes the std::ostream to write to.
void flush()
Flushes the buffer.
std::string str() const
Return the contents of the buffer as a std::string object.
Class representing a regular expression.
#define Config_getBool(name)
IDocParserPtr createDocParser()
factory function to create a parser
IDocNodeASTPtr createRef(IDocParser &parserIntf, const QCString &target, const QCString &context, const QCString &srcFile, int srcLine)
static bool readSVGSize(const QCString &fileName, int *width, int *height)
static void writeSVGNotSupported(TextStream &out)
static const char svgZoomHeader1[]
static const char svgZoomHeader2[]
static QCString replaceRef(const QCString &buf, const QCString &relPath, bool urlOnly, const QCString &context, const QCString &target=QCString())
static const char svgZoomHeader0_noinit[]
static const char svgZoomFooter2[]
static const char svgZoomHeader0[]
static const char svgZoomFooter1[]
std::ifstream openInputStream(const QCString &name, bool binary=false, bool openAtEnd=false)
std::ofstream openOutputStream(const QCString &name, bool append=false)
Portable versions of functions that are platform dependent.
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
int qstrncmp(const char *str1, const char *str2, size_t len)
const char * qPrint(const char *s)
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
QCString stripPath(const QCString &s)
int findIndex(const StringVector &sv, const std::string &s)
find the index of a string in a vector of strings, returns -1 if the string could not be found
QCString correctId(const QCString &s)
QCString externalLinkTarget(const bool parent)
void addHtmlExtensionIfMissing(QCString &fName)
A bunch of utility functions.