Doxygen
Loading...
Searching...
No Matches
ClassDiagram Class Reference

Class representing a built-in class diagram. More...

#include <src/diagram.h>

Classes

struct  Private
 

Public Member Functions

 ClassDiagram (const ClassDef *root)
 
 ~ClassDiagram ()
 
void writeFigure (TextStream &t, const QCString &path, const QCString &file) const
 
void writeImage (TextStream &t, const QCString &path, const QCString &relPath, const QCString &file, bool generateMap=true) const
 

Private Attributes

std::unique_ptr< Privatep
 

Detailed Description

Class representing a built-in class diagram.

Definition at line 30 of file diagram.h.

Constructor & Destructor Documentation

◆ ClassDiagram()

ClassDiagram::ClassDiagram ( const ClassDef * root)

Definition at line 1049 of file diagram.cpp.

1049 : p(std::make_unique<Private>(root))
1050{
1051 p->base.computeLayout();
1052 p->super.computeLayout();
1053 DiagramItem *baseItem = p->base.row(0)->item(0);
1054 DiagramItem *superItem = p->super.row(0)->item(0);
1055 uint32_t xbase = baseItem->xPos();
1056 uint32_t xsuper = superItem->xPos();
1057 if (xbase>xsuper)
1058 {
1059 int dist=static_cast<int>(xbase-xsuper);
1060 superItem->move(dist,0);
1061 p->super.moveChildren(superItem,dist);
1062 }
1063 else if (xbase<xsuper)
1064 {
1065 int dist=static_cast<int>(xsuper-xbase);
1066 baseItem->move(dist,0);
1067 p->base.moveChildren(baseItem,dist);
1068 }
1069}
std::unique_ptr< Private > p
Definition diagram.h:42
void move(int dx, int dy)
Definition diagram.cpp:50
uint32_t xPos() const
Definition diagram.cpp:51

References DiagramItem::move(), p, and DiagramItem::xPos().

Referenced by ~ClassDiagram().

◆ ~ClassDiagram()

ClassDiagram::~ClassDiagram ( )
default

References ClassDiagram().

Member Function Documentation

◆ writeFigure()

void ClassDiagram::writeFigure ( TextStream & t,
const QCString & path,
const QCString & file ) const

Definition at line 1073 of file diagram.cpp.

1075{
1076 uint32_t baseRows=p->base.computeRows();
1077 uint32_t superRows=p->super.computeRows();
1078 uint32_t baseMaxX = 0, baseMaxLabelWidth = 0, superMaxX = 0, superMaxLabelWidth = 0;
1079 p->base.computeExtremes(&baseMaxLabelWidth,&baseMaxX);
1080 p->super.computeExtremes(&superMaxLabelWidth,&superMaxX);
1081
1082 uint32_t rows=std::max(1u,baseRows+superRows-1);
1083 uint32_t cols=(std::max(baseMaxX,superMaxX)+gridWidth*2-1)/gridWidth;
1084
1085 // Estimate the image aspect width and height in pixels.
1086 float estHeight = static_cast<float>(rows)*40.0f;
1087 float estWidth = static_cast<float>(cols)*(20+static_cast<float>(std::max(baseMaxLabelWidth,superMaxLabelWidth)));
1088 //printf("Estimated size %d x %d\n",estWidth,estHeight);
1089
1090 const float pageWidth = 14.0f; // estimated page width in cm.
1091 // Somewhat lower to deal with estimation
1092 // errors.
1093
1094 // compute the image height in centimeters based on the estimates
1095 float realHeight = static_cast<float>(std::min(rows,12u)); // real height in cm
1096 float realWidth = realHeight * estWidth/estHeight;
1097 if (realWidth>pageWidth) // assume that the page width is about 15 cm
1098 {
1099 realHeight*=pageWidth/realWidth;
1100 }
1101
1102 //output << "}\n";
1103 output << "\\begin{figure}[H]\n"
1104 "\\begin{center}\n"
1105 "\\leavevmode\n";
1106 output << "\\includegraphics[height=" << realHeight << "cm]{"
1107 << fileName << "}\n";
1108 output << "\\end{center}\n"
1109 "\\end{figure}\n";
1110
1111 //printf("writeFigure rows=%d cols=%d\n",rows,cols);
1112
1113 QCString epsBaseName=QCString(path)+"/"+fileName;
1114 QCString epsName=epsBaseName+".eps";
1115 std::ofstream f = Portable::openOutputStream(epsName);
1116 if (!f.is_open())
1117 {
1118 term("Could not open file %s for writing\n",qPrint(epsName));
1119 }
1120 else
1121 {
1122 TextStream t(&f);
1123
1124 //printf("writeEPS() rows=%d cols=%d\n",rows,cols);
1125
1126 // generate EPS header and postscript variables and procedures
1127
1128 t << "%!PS-Adobe-2.0 EPSF-2.0\n";
1129 t << "%%Title: ClassName\n";
1130 t << "%%Creator: Doxygen\n";
1131 t << "%%CreationDate: Time\n";
1132 t << "%%For: \n";
1133 t << "%Magnification: 1.00\n";
1134 t << "%%Orientation: Portrait\n";
1135 t << "%%BoundingBox: 0 0 500 " << estHeight*500.0f/estWidth << "\n";
1136 t << "%%Pages: 0\n";
1137 t << "%%BeginSetup\n";
1138 t << "%%EndSetup\n";
1139 t << "%%EndComments\n";
1140 t << "\n";
1141 t << "% ----- variables -----\n";
1142 t << "\n";
1143 t << "/boxwidth 0 def\n";
1144 t << "/boxheight 40 def\n";
1145 t << "/fontheight 24 def\n";
1146 t << "/marginwidth 10 def\n";
1147 t << "/distx 20 def\n";
1148 t << "/disty 40 def\n";
1149 t << "/boundaspect " << estWidth/estHeight << " def % aspect ratio of the BoundingBox (width/height)\n";
1150 t << "/boundx 500 def\n";
1151 t << "/boundy boundx boundaspect div def\n";
1152 t << "/xspacing 0 def\n";
1153 t << "/yspacing 0 def\n";
1154 t << "/rows " << rows << " def\n";
1155 t << "/cols " << cols << " def\n";
1156 t << "/scalefactor 0 def\n";
1157 t << "/boxfont /Times-Roman findfont fontheight scalefont def\n";
1158 t << "\n";
1159 t << "% ----- procedures -----\n";
1160 t << "\n";
1161 t << "/dotted { [1 4] 0 setdash } def\n";
1162 t << "/dashed { [5] 0 setdash } def\n";
1163 t << "/solid { [] 0 setdash } def\n";
1164 t << "\n";
1165 t << "/max % result = MAX(arg1,arg2)\n";
1166 t << "{\n";
1167 t << " /a exch def\n";
1168 t << " /b exch def\n";
1169 t << " a b gt {a} {b} ifelse\n";
1170 t << "} def\n";
1171 t << "\n";
1172 t << "/xoffset % result = MAX(0,(scalefactor-(boxwidth*cols+distx*(cols-1)))/2)\n";
1173 t << "{\n";
1174 t << " 0 scalefactor boxwidth cols mul distx cols 1 sub mul add sub 2 div max\n";
1175 t << "} def\n";
1176 t << "\n";
1177 t << "/cw % boxwidth = MAX(boxwidth, stringwidth(arg1))\n";
1178 t << "{\n";
1179 t << " /str exch def\n";
1180 t << " /boxwidth boxwidth str stringwidth pop max def\n";
1181 t << "} def\n";
1182 t << "\n";
1183 t << "/box % draws a box with text 'arg1' at grid pos (arg2,arg3)\n";
1184 t << "{ gsave\n";
1185 t << " 2 setlinewidth\n";
1186 t << " newpath\n";
1187 t << " exch xspacing mul xoffset add\n";
1188 t << " exch yspacing mul\n";
1189 t << " moveto\n";
1190 t << " boxwidth 0 rlineto \n";
1191 t << " 0 boxheight rlineto \n";
1192 t << " boxwidth neg 0 rlineto \n";
1193 t << " 0 boxheight neg rlineto \n";
1194 t << " closepath\n";
1195 t << " dup stringwidth pop neg boxwidth add 2 div\n";
1196 t << " boxheight fontheight 2 div sub 2 div\n";
1197 t << " rmoveto show stroke\n";
1198 t << " grestore\n";
1199 t << "} def \n";
1200 t << "\n";
1201 t << "/mark\n";
1202 t << "{ newpath\n";
1203 t << " exch xspacing mul xoffset add boxwidth add\n";
1204 t << " exch yspacing mul\n";
1205 t << " moveto\n";
1206 t << " 0 boxheight 4 div rlineto\n";
1207 t << " boxheight neg 4 div boxheight neg 4 div rlineto\n";
1208 t << " closepath\n";
1209 t << " eofill\n";
1210 t << " stroke\n";
1211 t << "} def\n";
1212 t << "\n";
1213 t << "/arrow\n";
1214 t << "{ newpath\n";
1215 t << " moveto\n";
1216 t << " 3 -8 rlineto\n";
1217 t << " -6 0 rlineto\n";
1218 t << " 3 8 rlineto\n";
1219 t << " closepath\n";
1220 t << " eofill\n";
1221 t << " stroke\n";
1222 t << "} def\n";
1223 t << "\n";
1224 t << "/out % draws an output connector for the block at (arg1,arg2)\n";
1225 t << "{\n";
1226 t << " newpath\n";
1227 t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
1228 t << " exch yspacing mul boxheight add\n";
1229 t << " /y exch def\n";
1230 t << " /x exch def\n";
1231 t << " x y moveto\n";
1232 t << " 0 disty 2 div rlineto \n";
1233 t << " stroke\n";
1234 t << " 1 eq { x y disty 2 div add arrow } if\n";
1235 t << "} def\n";
1236 t << "\n";
1237 t << "/in % draws an input connector for the block at (arg1,arg2)\n";
1238 t << "{\n";
1239 t << " newpath\n";
1240 t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
1241 t << " exch yspacing mul disty 2 div sub\n";
1242 t << " /y exch def\n";
1243 t << " /x exch def\n";
1244 t << " x y moveto\n";
1245 t << " 0 disty 2 div rlineto\n";
1246 t << " stroke\n";
1247 t << " 1 eq { x y disty 2 div add arrow } if\n";
1248 t << "} def\n";
1249 t << "\n";
1250 t << "/hedge\n";
1251 t << "{\n";
1252 t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
1253 t << " exch yspacing mul boxheight 2 div sub\n";
1254 t << " /y exch def\n";
1255 t << " /x exch def\n";
1256 t << " newpath\n";
1257 t << " x y moveto\n";
1258 t << " boxwidth 2 div distx add 0 rlineto\n";
1259 t << " stroke\n";
1260 t << " 1 eq\n";
1261 t << " { newpath x boxwidth 2 div distx add add y moveto\n";
1262 t << " -8 3 rlineto\n";
1263 t << " 0 -6 rlineto\n";
1264 t << " 8 3 rlineto\n";
1265 t << " closepath\n";
1266 t << " eofill\n";
1267 t << " stroke\n";
1268 t << " } if\n";
1269 t << "} def\n";
1270 t << "\n";
1271 t << "/vedge\n";
1272 t << "{\n";
1273 t << " /ye exch def\n";
1274 t << " /ys exch def\n";
1275 t << " /xs exch def\n";
1276 t << " newpath\n";
1277 t << " xs xspacing mul xoffset add boxwidth 2 div add dup\n";
1278 t << " ys yspacing mul boxheight 2 div sub\n";
1279 t << " moveto\n";
1280 t << " ye yspacing mul boxheight 2 div sub\n";
1281 t << " lineto\n";
1282 t << " stroke\n";
1283 t << "} def\n";
1284 t << "\n";
1285 t << "/conn % connections the blocks from col 'arg1' to 'arg2' of row 'arg3'\n";
1286 t << "{\n";
1287 t << " /ys exch def\n";
1288 t << " /xe exch def\n";
1289 t << " /xs exch def\n";
1290 t << " newpath\n";
1291 t << " xs xspacing mul xoffset add boxwidth 2 div add\n";
1292 t << " ys yspacing mul disty 2 div sub\n";
1293 t << " moveto\n";
1294 t << " xspacing xe xs sub mul 0\n";
1295 t << " rlineto\n";
1296 t << " stroke\n";
1297 t << "} def\n";
1298 t << "\n";
1299 t << "% ----- main ------\n";
1300 t << "\n";
1301 t << "boxfont setfont\n";
1302 t << "1 boundaspect scale\n";
1303
1304
1305 for (const auto &dr : p->base)
1306 {
1307 bool done=FALSE;
1308 for (const auto &di : *dr)
1309 {
1310 done=di->isInList();
1311 t << "(" << convertToPSString(di->label()) << ") cw\n";
1312 }
1313 if (done) break;
1314 }
1315
1316 auto it = p->super.begin();
1317 if (it!=p->super.end()) ++it;
1318 for (;it!=p->super.end();++it)
1319 {
1320 const auto &dr = *it;
1321 bool done=FALSE;
1322 for (const auto &di : *dr)
1323 {
1324 done=di->isInList();
1325 t << "(" << convertToPSString(di->label()) << ") cw\n";
1326 }
1327 if (done) break;
1328 }
1329
1330 t << "/boxwidth boxwidth marginwidth 2 mul add def\n"
1331 << "/xspacing boxwidth distx add def\n"
1332 << "/yspacing boxheight disty add def\n"
1333 << "/scalefactor \n"
1334 << " boxwidth cols mul distx cols 1 sub mul add\n"
1335 << " boxheight rows mul disty rows 1 sub mul add boundaspect mul \n"
1336 << " max def\n"
1337 << "boundx scalefactor div boundy scalefactor div scale\n";
1338
1339 t << "\n% ----- classes -----\n\n";
1340 p->base.drawBoxes(t,nullptr,TRUE,FALSE,baseRows,superRows,0,0);
1341 p->super.drawBoxes(t,nullptr,FALSE,FALSE,baseRows,superRows,0,0);
1342
1343 t << "\n% ----- relations -----\n\n";
1344 p->base.drawConnectors(t,nullptr,TRUE,FALSE,baseRows,superRows,0,0);
1345 p->super.drawConnectors(t,nullptr,FALSE,FALSE,baseRows,superRows,0,0);
1346
1347 }
1348 f.close();
1349
1350 if (Config_getBool(USE_PDFLATEX))
1351 {
1352 QCString epstopdfArgs(4096, QCString::ExplicitSize);
1353 epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",
1354 qPrint(epsBaseName),qPrint(epsBaseName));
1355 //printf("Converting eps using '%s'\n",qPrint(epstopdfArgs));
1356 if (Portable::system("epstopdf",epstopdfArgs)!=0)
1357 {
1358 err("Problems running epstopdf. Check your TeX installation!\n");
1359 return;
1360 }
1361 else
1362 {
1363 Dir().remove(epsBaseName.str()+".eps");
1364 }
1365 }
1366}
const std::string & str() const
Definition qcstring.h:526
@ ExplicitSize
Definition qcstring.h:133
#define Config_getBool(name)
Definition config.h:33
const uint32_t gridWidth
Definition diagram.cpp:140
static QCString convertToPSString(const QCString &s)
Definition diagram.cpp:195
#define err(fmt,...)
Definition message.h:84
#define term(fmt,...)
Definition message.h:94
std::ofstream openOutputStream(const QCString &name, bool append=false)
Definition portable.cpp:665
int system(const QCString &command, const QCString &args, bool commandHasConsole=true)
Definition portable.cpp:106
const char * qPrint(const char *s)
Definition qcstring.h:661
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34

References Config_getBool, convertToPSString(), err, QCString::ExplicitSize, FALSE, gridWidth, Portable::openOutputStream(), p, qPrint(), QCString::sprintf(), QCString::str(), Portable::system(), term, and TRUE.

Referenced by LatexGenerator::endClassDiagram().

◆ writeImage()

void ClassDiagram::writeImage ( TextStream & t,
const QCString & path,
const QCString & relPath,
const QCString & file,
bool generateMap = true ) const

Definition at line 1369 of file diagram.cpp.

1372{
1373 uint32_t baseRows=p->base.computeRows();
1374 uint32_t superRows=p->super.computeRows();
1375 uint32_t rows=baseRows+superRows-1;
1376
1377 uint32_t lb=0,ls=0,xb=0,xs=0;
1378 p->base.computeExtremes(&lb,&xb);
1379 p->super.computeExtremes(&ls,&xs);
1380
1381 uint32_t cellWidth = std::max(lb,ls)+labelHorMargin*2;
1382 uint32_t maxXPos = std::max(xb,xs);
1383 uint32_t labelVertMargin = 6; //std::max(6,(cellWidth-fontHeight)/6); // aspect at least 1:3
1384 uint32_t cellHeight = labelVertMargin*2+fontHeight;
1385 uint32_t imageWidth = (maxXPos+gridWidth)*cellWidth/gridWidth+
1386 (maxXPos*labelHorSpacing)/gridWidth;
1387 uint32_t imageHeight = rows*cellHeight+(rows-1)*labelVertSpacing;
1388
1389 Image image(imageWidth,imageHeight);
1390
1391 p->base.drawBoxes(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight,relPath,generateMap);
1392 p->super.drawBoxes(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight,relPath,generateMap);
1393 p->base.drawConnectors(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight);
1394 p->super.drawConnectors(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight);
1395
1396#define IMAGE_EXT ".png"
1397 image.save(QCString(path)+"/"+fileName+IMAGE_EXT);
1398 Doxygen::indexList->addImageFile(QCString(fileName)+IMAGE_EXT);
1399}
static IndexList * indexList
Definition doxygen.h:134
void addImageFile(const QCString &name)
Definition indexlist.h:126
const uint32_t labelHorMargin
Definition diagram.cpp:145
const uint32_t labelHorSpacing
Definition diagram.cpp:143
const uint32_t fontHeight
Definition diagram.cpp:146
#define IMAGE_EXT
const uint32_t labelVertSpacing
Definition diagram.cpp:144

References IndexList::addImageFile(), FALSE, fontHeight, gridWidth, IMAGE_EXT, Doxygen::indexList, labelHorMargin, labelHorSpacing, labelVertSpacing, p, and TRUE.

Referenced by DocbookGenerator::endClassDiagram(), HtmlGenerator::endClassDiagram(), and RTFGenerator::endClassDiagram().

Member Data Documentation

◆ p

std::unique_ptr<Private> ClassDiagram::p
private

Definition at line 42 of file diagram.h.

Referenced by ClassDiagram(), writeFigure(), and writeImage().


The documentation for this class was generated from the following files: