31<svg id="main" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
35<svg id="main" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">
39<style type="text/css"><![CDATA[
40.node, .edge {opacity: 0.7;}
41.node.selected, .edge.selected {opacity: 1;}
42.edge:hover path { stroke: red; }
43.edge:hover polygon { stroke: red; fill: red; }
50 <circle id="rim" cx="0" cy="0" r="7"/>
51 <circle id="rim2" cx="0" cy="0" r="3.5"/>
53 <use xlink:href="#rim" fill="#404040"><set attributeName="fill" to="#808080" begin="zoomplus.mouseover" end="zoomplus.mouseout"/></use>
54 <path d="M-4,0h8M0,-4v8" fill="none" stroke="white" stroke-width="1.5" pointer-events="none"/>
57 <use xlink:href="#rim" fill="#404040"><set attributeName="fill" to="#808080" begin="zoomminus.mouseover" end="zoomminus.mouseout"/></use>
58 <path d="M-4,0h8" fill="none" stroke="white" stroke-width="1.5" pointer-events="none"/>
60 <g id="arrowUp" transform="translate(30 24)">
61 <use xlink:href="#rim"/>
62 <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"/>
64 <g id="arrowRight" transform="rotate(90) translate(36 -43)">
65 <use xlink:href="#rim"/>
66 <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"/>
68 <g id="arrowDown" transform="rotate(180) translate(-30 -48)">
69 <use xlink:href="#rim"/>
70 <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"/>
72 <g id="arrowLeft" transform="rotate(270) translate(-36 17)">
73 <use xlink:href="#rim"/>
74 <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"/>
77 <use xlink:href="#rim2" fill="#404040"><set attributeName="fill" to="#808080" begin="reset.mouseover" end="reset.mouseout"/></use>
84<g id="navigator" transform="translate(0 0)" fill="#404254">
85 <rect fill="#f2f5e9" fill-opacity="0.5" stroke="#606060" stroke-width=".5" x="0" y="0" width="60" height="60"/>
86 <use id="zoomplus" xlink:href="#zoomPlus" x="17" y="9" data-zoom="in"/>
87 <use id="zoomminus" xlink:href="#zoomMin" x="42" y="9" data-zoom="out"/>
88 <use id="reset" xlink:href="#resetDef" x="30" y="36" data-reset="true"/>
89 <use id="arrowup" xlink:href="#arrowUp" x="0" y="0" data-pan-x="0" data-pan-y="-1"/>
90 <use id="arrowright" xlink:href="#arrowRight" x="0" y="0" data-pan-x="1" data-pan-y="0"/>
91 <use id="arrowdown" xlink:href="#arrowDown" x="0" y="0" data-pan-x="0" data-pan-y="1"/>
92 <use id="arrowleft" xlink:href="#arrowLeft" x="0" y="0" data-pan-x="-1" data-pan-y="0"/>
94<svg viewBox="0 0 15 15" width="100%" height="30px" preserveAspectRatio="xMaxYMin meet">
95 <g id="arrow_out" transform="scale(0.3 0.3)">
96 <a xlink:href="$orgname" target="_base">
97 <rect id="button" ry="5" rx="5" y="6" x="6" height="38" width="38"
98 fill="#f2f5e9" fill-opacity="0.5" stroke="#606060" stroke-width="1.0"/>
100 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"
101 style="fill:#404040;"/>
109<style type='text/css'>
111[data-mouse-over-selected='false'] { opacity: 0.7; }
112[data-mouse-over-selected='true'] { opacity: 1.0; }
125 int indexS = buf.
find(
"href=\""), indexE = 0;
126 bool targetAlreadySet = buf.
find(
"target=")!=-1;
127 if (indexS>5 && buf.
find(
"xlink:href=\"")!=-1)
134 if (indexS>=0 && (indexE=buf.
find(
'"',indexS+len))!=-1)
136 QCString link = buf.
mid(indexS+len,indexE-indexS-len);
145 auto dfAst {
createRef( *parser.get(), link.
mid(5), context ) };
146 auto dfAstImpl =
dynamic_cast<const DocNodeAST*
>(dfAst.get());
147 const DocRef *df = std::get_if<DocRef>(&dfAstImpl->root);
157 result +=
"#" + df->
anchor();
163 result = href+
"=\"" + link +
"\"";
168 int marker = link.
find(
'$');
176 if (!result.
isEmpty())targetAlreadySet=
true;
184 result = href+
"=\"" + link +
"\"";
187 if (!target.isEmpty() && !targetAlreadySet)
189 result+=
" target=\""+target+
"\"";
195 return leftPart + result + rightPart;
215 const QCString &relPath,
bool urlOnly,
221 err(
"problems opening map file {} for inclusion in the docs!\n"
222 "If you installed Graphviz/dot after a previous failing run, \n"
223 "try deleting the output directory and rerun doxygen.\n",mapName);
227 while (getline(f,line))
235 int indexA = replBuf.
find(
"alt=");
238 replBuf = replBuf.
left(5) +
" alt=\"\"" + replBuf.
right(replBuf.
length() - 5);
242 int indexS = replBuf.
find(
"id=\""), indexE = 0;
243 if (indexS>0 && (indexE=replBuf.
find(
'"',indexS+4))!=-1)
245 t << replBuf.
left(indexS-1) << replBuf.
right(replBuf.
length() - indexE - 1);
269 size_t id =
m_maps.size();
270 m_maps.emplace_back(mapFile,relPath,urlOnly,context,label);
271 return static_cast<int>(id);
275 const QCString &figureName,
bool heightCheck)
277 size_t id =
m_maps.size();
278 m_maps.emplace_back(figureName,
"",heightCheck,
"",baseName);
279 return static_cast<int>(id);
283 const QCString &context,
bool zoomable,
286 size_t id =
m_maps.size();
287 m_maps.emplace_back(
"",relPath,urlOnly,context,
"",zoomable,graphId);
288 return static_cast<int>(id);
295 size_t id =
m_maps.size();
296 m_maps.emplace_back(absImgName,relPath,
false,
"",baseName);
297 return static_cast<int>(id);
310 interactiveSVG = interactiveSVG && map.
zoomable;
327 err(
"problem opening file {} for patching!\n",tmpName);
338 int width=0,height=0;
339 bool insideHeader=
FALSE;
340 bool replacedHeader=
FALSE;
341 bool useNagivation=
FALSE;
343 static const reg::Ex reSVG(R
"([\[<]!-- SVG [0-9]+)");
344 static const reg::Ex reMAP(R
"(<!-- MAP [0-9]+)");
345 static const reg::Ex reFIG(R
"(% FIG [0-9]+)");
347 while (getline(fi,lineStr))
351 auto pos = lineStr.find(
"id=\"page0,1_graph0\"");
352 if (pos != std::string::npos)
353 lineStr.replace(pos, 19,
"id=\"graph0\"");
362 if (line.
find(
"<svg")!=-1 && !replacedHeader)
364 int count = sscanf(line.
data(),
"<svg width=\"%dpt\" height=\"%dpt\"",&width,&height);
365 if (count != 2) count = sscanf(line.
data(),
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"%d\" height=\"%d\"",&width,&height);
367 useNagivation = count==2 && (width>500 || height>450);
368 insideHeader = count==2;
370 else if (insideHeader && !replacedHeader && line.
find(
"<g id=\"graph")!=-1)
375 t <<
"<!--zoomable " << height <<
" -->\n";
387 t <<
"<script type=\"application/ecmascript\" xlink:href=\"" << relPath <<
"svg.min.js\"/>\n";
388 t <<
"<svg id=\"graph\" class=\"graph\"";
391 t <<
" data-view-width=\"" << width <<
"\" data-view-height=\"" << height <<
"\"";
394 t <<
" data-section-id=\"dynsection-" << graphId <<
"\"";
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(
"-->"));
434 err(
"Problem extracting size from SVG file {}\n",map.
mapFile);
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 {} figure!\n",mapId);
487 err(
"Found invalid bounding FIG {} in file {}!\n",mapId,
m_patchFile);
496 if (
isSVGFile && interactiveSVG && !useNagivation) t <<
"</svg>\n";
499 if (
isSVGFile && interactiveSVG && replacedHeader)
515 err(
"problem opening file {} for reading!\n",tmpName);
520 err(
"problem opening file {} for writing!\n",orgName);
524 while (getline(fi,lineStr))
552 while (getline(f,line) && !found)
558 sscanf(line.c_str(),
"<!--zoomable %d",height);
561 else if (sscanf(line.c_str(),
"<svg width=\"%dpt\" height=\"%dpt\"",width,height)==2)
565 else if (sscanf(line.c_str(),
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"%d\" height=\"%d\"",width,height)==2)
575 out <<
"<p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p>";
583 int width=600,height=600;
590 if (height<=60) height=300;
else height+=300;
591 if (height>600) height=600;
592 out <<
"<div class=\"zoom\">";
595 out <<
"<iframe scrolling=\"no\" loading=\"lazy\" frameborder=\"0\" src=\""
596 << relPath << baseName <<
".svg\" width=\"100%\" height=\"" << height <<
"\">";
602 out <<
"<iframe scrolling=\"no\" loading=\"lazy\" frameborder=\"0\" src=\""
603 << relPath << baseName <<
".svg\" width=\""
604 << ((width*96+48)/72) <<
"\" height=\""
605 << ((height*96+48)/72) <<
"\">";
622 int width=400,height=550;
642 out <<
"\\nopagebreak\n"
643 "\\begin{figure}[H]\n"
646 if (width>maxWidth || height>maxHeight)
649 if (width*maxHeight>height*maxWidth)
651 out <<
"\\includegraphics[width=" << maxWidth <<
"pt]";
655 out <<
"\\includegraphics[height=" << maxHeight <<
"pt]";
660 out <<
"\\includegraphics[width=" << width <<
"pt]";
663 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
Some helper functions for std::string.
bool literal_at(const char *data, const char(&str)[N])
returns TRUE iff data points to a substring that matches string literal str
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.