Doxygen
diagram.cpp
浏览该文件的文档.
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2020 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby
7  * granted. No representations are made about the suitability of this software
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <fstream>
19 #include <algorithm>
20 
21 #include "diagram.h"
22 #include "image.h"
23 #include "classdef.h"
24 #include "config.h"
25 #include "message.h"
26 #include "util.h"
27 #include "doxygen.h"
28 #include "portable.h"
29 #include "index.h"
30 #include "classlist.h"
31 #include "textstream.h"
32 
33 //-----------------------------------------------------------------------------
34 
35 class TreeDiagram;
36 class DiagramItem;
37 using DiagramItemList = std::vector<DiagramItem*>;
38 
39 /** Class representing a single node in the built-in class diagram */
41 {
42  public:
44  Protection prot,Specifier virt,const QCString &ts);
45  QCString label() const;
46  QCString fileName() const;
49  void move(int dx,int dy) { m_x+=(uint)dx; m_y+=(uint)dy; }
50  uint xPos() const { return m_x; }
51  uint yPos() const { return m_y; }
52  uint avgChildPos() const;
53  uint numChildren() const;
54  void addChild(DiagramItem *di);
55  uint number() const { return m_num; }
56  Protection protection() const { return m_prot; }
57  Specifier virtualness() const { return m_virt; }
58  void putInList() { m_inList=TRUE; }
59  bool isInList() const { return m_inList; }
60  const ClassDef *getClassDef() const { return m_classDef; }
61  private:
64  uint m_x = 0;
65  uint m_y = 0;
70  bool m_inList = false;
72 };
73 
74 /** Class representing a row in the built-in class diagram */
76 {
77  public:
78  using Ptr = std::unique_ptr<DiagramItem>;
79  using Vec = std::vector<Ptr>;
80  using iterator = typename Vec::iterator;
81  using reverse_iterator = typename Vec::reverse_iterator;
83  void insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases,
84  Protection prot,Specifier virt,const QCString &ts);
85  uint number() { return m_level; }
86 
87  DiagramItem *item(int index) { return m_items.at(index).get(); }
88  uint numItems() const { return static_cast<uint>(m_items.size()); }
89  iterator begin() { return m_items.begin(); }
90  iterator end() { return m_items.end(); }
91  reverse_iterator rbegin() { return m_items.rbegin(); }
92  reverse_iterator rend() { return m_items.rend(); }
93  private:
97 };
98 
99 /** Class representing the tree layout for the built-in class diagram. */
101 {
102  public:
103  using Ptr = std::unique_ptr<DiagramRow>;
104  using Vec = std::vector<Ptr>;
105  using iterator = typename Vec::iterator;
106  TreeDiagram(const ClassDef *root,bool doBases);
107  void computeLayout();
108  uint computeRows();
109  void moveChildren(DiagramItem *root,int dx);
110  void computeExtremes(uint *labelWidth,uint *xpos);
111  void drawBoxes(TextStream &t,Image *image,
112  bool doBase,bool bitmap,
113  uint baseRows,uint superRows,
114  uint cellWidth,uint cellHeight,
115  QCString relPath="",
116  bool generateMap=TRUE);
117  void drawConnectors(TextStream &t,Image *image,
118  bool doBase,bool bitmap,
119  uint baseRows,uint superRows,
120  uint cellWidth,uint cellheight);
121  DiagramRow *row(int index) { return m_rows.at(index).get(); }
122  uint numRows() const { return static_cast<uint>(m_rows.size()); }
124  { m_rows.push_back(std::make_unique<DiagramRow>(this,l)); return m_rows.back().get(); }
125  iterator begin() { return m_rows.begin(); }
126  iterator end() { return m_rows.end(); }
127  private:
128  bool layoutTree(DiagramItem *root,uint row);
130  TreeDiagram(const TreeDiagram &);
132 };
133 
134 
135 
136 //-----------------------------------------------------------------------------
137 
138 const uint maxTreeWidth = 8;
139 const uint gridWidth = 100;
140 const uint gridHeight = 100;
141 
142 const uint labelHorSpacing = 10; // horizontal distance between labels
143 const uint labelVertSpacing = 32; // vertical distance between labels
144 const uint labelHorMargin = 6; // horiz. spacing between label and box
145 const uint fontHeight = 12; // height of a character
146 
148 {
149  switch(p)
150  {
151  case Public: return 0xffffffff;
152  case Package: // package is not possible!
153  case Protected: return 0xcccccccc;
154  case Private: return 0xaaaaaaaa;
155  }
156  return 0;
157 }
158 
160 {
161  switch(p)
162  {
163  case Public: return 6;
164  case Package: // package is not possible!
165  case Protected: return 5;
166  case Private: return 4;
167  }
168  return 0;
169 }
170 
172 {
173  switch(p)
174  {
175  case Public: return "solid";
176  case Package: // package is not possible!
177  case Protected: return "dashed";
178  case Private: return "dotted";
179  }
180  return QCString();
181 }
182 
184 {
185  switch(p)
186  {
187  case Normal: return 0xffffffff;
188  case Virtual: return 0xf0f0f0f0;
189  default: return 0;
190  }
191  return 0;
192 }
193 
194 // pre: dil is not empty
196 {
197  auto it = dil.begin();
198  Protection result = Private;
199  if (it!=dil.end())
200  {
201  result=(*it)->protection();
202  for (++it;it!=dil.end();++it)
203  {
204  Protection p=(*it)->protection();
205  if (p!=result)
206  {
207  if (result==Protected && p==Public) result=p;
208  else if (result==Private) result=p;
209  }
210  }
211  }
212  return result;
213 }
214 
215 static void writeBitmapBox(DiagramItem *di,Image *image,
216  uint x,uint y,uint w,uint h,bool firstRow,
217  bool hasDocs,bool children=FALSE)
218 {
219  uchar colFill = hasDocs ? (firstRow ? 0 : 2) : 7;
220  uchar colBorder = (firstRow || !hasDocs) ? 1 : 3;
221  uint l = Image::stringLength(di->label());
222  uint mask=virtToMask(di->virtualness());
223  image->fillRect(x+1,y+1,w-2,h-2,colFill,mask);
224  image->drawRect(x,y,w,h,colBorder,mask);
225  image->writeString(x+(w-l)/2, y+(h-fontHeight)/2, di->label(),1);
226  if (children)
227  {
228  uint i;
229  for (i=0;i<5;i++)
230  {
231  image->drawHorzLine(y+h+i-6,x+w-2-i,x+w-2,firstRow?1:3,0xffffffff);
232  }
233  }
234 }
235 
237  float x,float y,bool children=FALSE)
238 {
239  if (di->virtualness()==Virtual) t << "dashed\n";
240  t << " (" << convertToPSString(di->label()) << ") " << x << " " << y << " box\n";
241  if (children) t << x << " " << y << " mark\n";
242  if (di->virtualness()==Virtual) t << "solid\n";
243 }
244 
245 static void writeMapArea(TextStream &t,const ClassDef *cd,QCString relPath,
246  uint x,uint y,uint w,uint h)
247 {
248  if (cd->isLinkable())
249  {
250  QCString ref=cd->getReference();
251  t << "<area ";
252  if (!ref.isEmpty())
253  {
254  t << externalLinkTarget(true);
255  }
256  t << "href=\"";
257  t << externalRef(relPath,ref,TRUE);
259  if (!cd->anchor().isEmpty())
260  {
261  t << "#" << cd->anchor();
262  }
263  t << "\" ";
264  QCString tooltip = cd->briefDescriptionAsTooltip();
265  if (!tooltip.isEmpty())
266  {
267  t << "title=\"" << convertToHtml(tooltip) << "\" ";
268  }
269  t << "alt=\"" << convertToXML(cd->displayName());
270  t << "\" shape=\"rect\" coords=\"" << x << "," << y << ",";
271  t << (x+w) << "," << (y+h) << "\"/>\n";
272  }
273 }
274 //-----------------------------------------------------------------------------
275 
277  Protection pr,Specifier vi,const QCString &ts)
278  : m_parent(p), m_num(number), m_prot(pr), m_virt(vi), m_templSpec(ts), m_classDef(cd)
279 {
280 }
281 
283 {
284  QCString result;
285  if (!m_templSpec.isEmpty())
286  {
287  // we use classDef->name() here and not displayName() in order
288  // to get the name used in the inheritance relation.
289  QCString n = m_classDef->name();
290  if (/*n.right(2)=="-g" ||*/ n.right(2)=="-p")
291  {
292  n = n.left(n.length()-2);
293  }
295  }
296  else
297  {
298  result=m_classDef->displayName();
299  }
300  if (Config_getBool(HIDE_SCOPE_NAMES)) result=stripScope(result);
301  return result;
302 }
303 
305 {
306  return m_classDef->getOutputFileBase();
307 }
308 
310 {
311  DiagramItem *di;
312  size_t c=m_children.size();
313  if (c==0) // no children -> don't move
314  return xPos();
315  if ((di=m_children.front())->isInList()) // children should be in a list
316  return di->xPos();
317  if (c&1) // odd number of children -> get pos of middle child
318  return m_children.at(c/2)->xPos();
319  else // even number of children -> get middle of most middle children
320  return (m_children.at(c/2-1)->xPos()+m_children.at(c/2)->xPos())/2;
321 }
322 
324 {
325  return static_cast<uint>(m_children.size());
326 }
327 
329 {
330  m_children.push_back(di);
331 }
332 
333 //---------------------------------------------------------------------------
334 
335 void DiagramRow::insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases,
336  Protection prot,Specifier virt,const QCString &ts)
337 {
338  auto di = std::make_unique<DiagramItem>(parent, m_diagram->row(m_level)->numItems(),
339  cd,prot,virt,ts);
340  DiagramItem *di_ptr = di.get();
341  if (parent) parent->addChild(di_ptr);
342  di->move((int)(m_items.size()*gridWidth),(int)(m_level*gridHeight));
343  m_items.push_back(std::move(di));
344  int count=0;
345  for (const auto &bcd : doBases ? cd->baseClasses() : cd->subClasses())
346  {
347  /* there are base/sub classes */
348  ClassDef *ccd=bcd.classDef;
349  if (ccd && ccd->isVisibleInHierarchy()) count++;
350  }
351  if (count>0 && (prot!=Private || !doBases))
352  {
353  DiagramRow *row=0;
354  if (m_diagram->numRows()<=m_level+1) /* add new row */
355  {
356  row=m_diagram->addRow(m_level+1);
357  }
358  else /* get next row */
359  {
360  row=m_diagram->row(m_level+1);
361  }
362  for (const auto &bcd : doBases ? cd->baseClasses() : cd->subClasses())
363  {
364  ClassDef *ccd=bcd.classDef;
365  if (ccd && ccd->isVisibleInHierarchy())
366  {
367  row->insertClass(di_ptr,ccd,doBases,bcd.prot,
368  doBases?bcd.virt:Normal,
369  doBases?bcd.templSpecifiers:QCString());
370  }
371  }
372  }
373 }
374 
375 //---------------------------------------------------------------------------
376 
377 TreeDiagram::TreeDiagram(const ClassDef *root,bool doBases)
378 {
379  auto row = std::make_unique<DiagramRow>(this,0);
380  DiagramRow *row_ptr = row.get();
381  m_rows.push_back(std::move(row));
382  row_ptr->insertClass(0,root,doBases,Public,Normal,QCString());
383 }
384 
386 {
387  for (const auto &di : root->getChildren())
388  {
389  di->move(dx,0);
390  moveChildren(di,dx);
391  }
392 }
393 
395 {
396  bool moved=FALSE;
397  //printf("layoutTree(%s,%d)\n",qPrint(root->label()),r);
398 
399  if (root->numChildren()>0)
400  {
401  auto children = root->getChildren();
402  uint k;
403  uint pPos=root->xPos();
404  uint cPos=root->avgChildPos();
405  if (pPos>cPos) // move children
406  {
407  const auto &row=m_rows.at(r+1);
408  //printf("Moving children %d-%d in row %d\n",
409  // dil->getFirst()->number(),row->count()-1,r+1);
410  for (k=children.front()->number();k<row->numItems();k++)
411  row->item(k)->move((int)(pPos-cPos),0);
412  moved=TRUE;
413  }
414  else if (pPos<cPos) // move parent
415  {
416  const auto &row=m_rows.at(r);
417  //printf("Moving parents %d-%d in row %d\n",
418  // root->number(),row->count()-1,r);
419  for (k=root->number();k<row->numItems();k++)
420  row->item(k)->move((int)(cPos-pPos),0);
421  moved=TRUE;
422  }
423 
424  // recurse to children
425  auto it = children.begin();
426  for (;it!=children.end() && !moved && !(*it)->isInList();++it)
427  {
428  moved = layoutTree(*it,r+1);
429  }
430  }
431  return moved;
432 }
433 
435 {
436  auto it = m_rows.begin();
437  while (it!=m_rows.end() && (*it)->numItems()<maxTreeWidth) ++it;
438  if (it!=m_rows.end())
439  {
440  const auto &row = *it;
441  //printf("computeLayout() list row at %d\n",row->number());
442  DiagramItem *opi=0;
443  int delta=0;
444  bool first=TRUE;
445  for (const auto &di : *row)
446  {
447  DiagramItem *pi=di->parentItem();
448  if (pi==opi && !first) { delta-=gridWidth; }
449  first = pi!=opi;
450  opi=pi;
451  di->move(delta,0); // collapse all items in the same
452  // list (except the first)
453  di->putInList();
454  }
455  }
456 
457  // re-organize the diagram items
458  DiagramItem *root=m_rows.front()->item(0);
459  while (layoutTree(root,0)) { }
460 
461  // move first items of the lists
462  if (it!=m_rows.end())
463  {
464  const auto &row = *it;
465  auto rit = row->begin();
466  while (rit!=row->end())
467  {
468  DiagramItem *pi=(*rit)->parentItem();
469  if (pi->numChildren()>1)
470  {
471  (*rit)->move(gridWidth,0);
472  while (rit!=row->end() && (*rit)->parentItem()==pi)
473  {
474  ++rit;
475  }
476  }
477  else
478  {
479  ++rit;
480  }
481  }
482  }
483 }
484 
486 {
487  //printf("TreeDiagram::computeRows()=%d\n",count());
488  uint count=0;
489  auto it = m_rows.begin();
490  while (it!=m_rows.end() && !(*it)->item(0)->isInList())
491  {
492  ++it;
493  ++count;
494  }
495 
496  //printf("count=%d row=%p\n",count,row);
497  if (it!=m_rows.end())
498  {
499  const auto &row = *it;
500  uint maxListLen=0;
501  uint curListLen=0;
502  DiagramItem *opi=0;
503  for (const auto &di : *row) // for each item in a row
504  {
505  if (di->parentItem()!=opi) curListLen=1; else curListLen++;
506  if (curListLen>maxListLen) maxListLen=curListLen;
507  opi=di->parentItem();
508  }
509  //printf("maxListLen=%d\n",maxListLen);
510  count+=maxListLen;
511  }
512  return count;
513 }
514 
515 void TreeDiagram::computeExtremes(uint *maxLabelLen,uint *maxXPos)
516 {
517  uint ml=0,mx=0;
518  for (const auto &dr : m_rows) // for each row
519  {
520  bool done=FALSE;
521  for (const auto &di : *dr) // for each item in a row
522  {
523  if (di->isInList()) done=TRUE;
524  if (maxXPos) mx=std::max(mx,(uint)di->xPos());
525  if (maxLabelLen) ml=std::max(ml,Image::stringLength(di->label()));
526  }
527  if (done) break;
528  }
529  if (maxLabelLen) *maxLabelLen=ml;
530  if (maxXPos) *maxXPos=mx;
531 }
532 
533 //! helper class representing an iterator that can iterate forwards or backwards
534 template<class C,class I>
536 {
537  public:
538  DualDirIterator(C &container,bool fwd)
539  : m_container(container), m_forward(fwd)
540  {
541  if (fwd) m_it = container.begin();
542  else m_rit = container.rbegin();
543  }
544  void operator++()
545  {
546  if (m_forward) ++m_it++; else ++m_rit;
547  }
549  {
550  return m_forward ? *m_it : *m_rit;
551  }
552 
553  bool atEnd()
554  {
555  if (m_forward)
556  return m_it==m_container.end();
557  else
558  return m_rit==m_container.rend();
559  }
560 
561  private:
563  bool m_forward;
564  typename C::iterator m_it;
565  typename C::reverse_iterator m_rit;
566 };
567 
569  bool doBase,bool bitmap,
570  uint baseRows,uint superRows,
571  uint cellWidth,uint cellHeight,
572  QCString relPath,
573  bool generateMap)
574 {
575  auto it = m_rows.begin();
576  if (it!=m_rows.end() && !doBase) ++it;
577  bool firstRow = doBase;
578  bool done=FALSE;
579  for (;it!=m_rows.end() && !done;++it) // for each row
580  {
581  const auto &dr = *it;
582  uint x=0,y=0;
583  float xf=0.0f,yf=0.0f;
584  DiagramItem *firstDi = dr->item(0);
585  if (firstDi->isInList()) // put boxes in a list
586  {
587  DiagramItem *opi=0;
589  while (!dit.atEnd())
590  {
591  DiagramItem *di = (*dit).get();
592  if (di->parentItem()==opi)
593  {
594  if (bitmap)
595  {
596  if (doBase) y -= cellHeight+labelVertSpacing;
597  else y += cellHeight+labelVertSpacing;
598  }
599  else
600  {
601  if (doBase) yf += 1.0f;
602  else yf -= 1.0f;
603  }
604  }
605  else
606  {
607  if (bitmap)
608  {
609  x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth;
610  if (doBase)
611  {
612  y = image->height()-
613  superRows*cellHeight-
614  (superRows-1)*labelVertSpacing-
615  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
616  }
617  else
618  {
619  y = (baseRows-1)*(cellHeight+labelVertSpacing)+
620  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
621  }
622  }
623  else
624  {
625  xf = di->xPos()/(float)gridWidth;
626  if (doBase)
627  {
628  yf = di->yPos()/(float)gridHeight+superRows-1;
629  }
630  else
631  {
632  yf = superRows-1-di->yPos()/(float)gridHeight;
633  }
634  }
635  }
636  opi=di->parentItem();
637 
638  if (bitmap)
639  {
640  bool hasDocs=di->getClassDef()->isLinkable();
641  writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,
642  hasDocs,di->numChildren()>0);
643  if (!firstRow && generateMap)
644  writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight);
645  }
646  else
647  {
648  writeVectorBox(t,di,xf,yf,di->numChildren()>0);
649  }
650 
651  ++dit;
652  }
653  done=TRUE;
654  }
655  else // draw a tree of boxes
656  {
657  for (const auto &di : *dr)
658  {
659  if (bitmap)
660  {
661  x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth;
662  if (doBase)
663  {
664  y = image->height()-
665  superRows*cellHeight-
666  (superRows-1)*labelVertSpacing-
667  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
668  }
669  else
670  {
671  y = (baseRows-1)*(cellHeight+labelVertSpacing)+
672  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
673  }
674  bool hasDocs=di->getClassDef()->isLinkable();
675  writeBitmapBox(di.get(),image,x,y,cellWidth,cellHeight,firstRow,hasDocs);
676  if (!firstRow && generateMap)
677  writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight);
678  }
679  else
680  {
681  xf=di->xPos()/(float)gridWidth;
682  if (doBase)
683  {
684  yf = di->yPos()/(float)gridHeight+superRows-1;
685  }
686  else
687  {
688  yf = superRows-1-di->yPos()/(float)gridHeight;
689  }
690  writeVectorBox(t,di.get(),xf,yf);
691  }
692  }
693  }
694  firstRow=FALSE;
695  }
696 }
697 
699  bool doBase,bool bitmap,
700  uint baseRows,uint superRows,
701  uint cellWidth,uint cellHeight)
702 {
703  bool done=FALSE;
704  auto it = m_rows.begin();
705  for (;it!=m_rows.end() && !done;++it) // for each row
706  {
707  const auto &dr = *it;
708  DiagramItem *rootDi = dr->item(0);
709  if (rootDi->isInList()) // row consists of list connectors
710  {
711  uint x=0,y=0,ys=0;
712  float xf=0.0f,yf=0.0f,ysf=0.0f;
713  auto rit = dr->begin();
714  while (rit!=dr->end())
715  {
716  DiagramItem *di=(*rit).get();
717  DiagramItem *pi=di->parentItem();
718  DiagramItemList dil=pi->getChildren();
719  DiagramItem *last=dil.back();
720  if (di==last) // single child
721  {
722  if (bitmap) // draw pixels
723  {
724  x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
725  if (doBase) // base classes
726  {
727  y = image->height()-
728  (superRows-1)*(cellHeight+labelVertSpacing)-
729  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
730  image->drawVertArrow(x,y,y+labelVertSpacing/2,
731  protToColor(di->protection()),
732  protToMask(di->protection()));
733  }
734  else // super classes
735  {
736  y = (baseRows-1)*(cellHeight+labelVertSpacing)-
738  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
739  image->drawVertLine(x,y,y+labelVertSpacing/2,
740  protToColor(di->protection()),
741  protToMask(di->protection()));
742  }
743  }
744  else // draw vectors
745  {
746  t << protToString(di->protection()) << "\n";
747  if (doBase)
748  {
749  t << "1 " << (di->xPos()/(float)gridWidth) << " "
750  << (di->yPos()/(float)gridHeight+superRows-1) << " in\n";
751  }
752  else
753  {
754  t << "0 " << (di->xPos()/(float)gridWidth) << " "
755  << ((float)superRows-0.25f-di->yPos()/(float)gridHeight)
756  << " in\n";
757  }
758  }
759  }
760  else // multiple children, put them in a vertical list
761  {
762  if (bitmap)
763  {
764  x = di->parentItem()->xPos()*
765  (cellWidth+labelHorSpacing)/gridWidth+cellWidth/2;
766  if (doBase) // base classes
767  {
768  ys = image->height()-
769  (superRows-1)*(cellHeight+labelVertSpacing)-
770  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
771  y = ys - cellHeight/2;
772  }
773  else // super classes
774  {
775  ys = (baseRows-1)*(cellHeight+labelVertSpacing)+
776  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
777  y = ys + cellHeight/2;
778  }
779  }
780  else
781  {
782  xf = di->parentItem()->xPos()/(float)gridWidth;
783  if (doBase)
784  {
785  ysf = di->yPos()/(float)gridHeight+superRows-1;
786  yf = ysf + 0.5f;
787  }
788  else
789  {
790  ysf = (float)superRows-0.25f-di->yPos()/(float)gridHeight;
791  yf = ysf - 0.25f;
792  }
793  }
794  while (di!=last) // more children to add
795  {
796  if (bitmap)
797  {
798  if (doBase) // base classes
799  {
800  image->drawHorzArrow(y,x,x+cellWidth/2+labelHorSpacing,
801  protToColor(di->protection()),
802  protToMask(di->protection()));
803  y -= cellHeight+labelVertSpacing;
804  }
805  else // super classes
806  {
807  image->drawHorzLine(y,x,x+cellWidth/2+labelHorSpacing,
808  protToColor(di->protection()),
809  protToMask(di->protection()));
810  y += cellHeight+labelVertSpacing;
811  }
812  }
813  else
814  {
815  t << protToString(di->protection()) << "\n";
816  if (doBase)
817  {
818  t << "1 " << xf << " " << yf << " hedge\n";
819  yf += 1.0f;
820  }
821  else
822  {
823  t << "0 " << xf << " " << yf << " hedge\n";
824  yf -= 1.0f;
825  }
826  }
827  ++rit;
828  if (rit!=dr->end()) di = (*rit).get(); else di=0;
829  }
830  // add last horizontal line and a vertical connection line
831  if (bitmap)
832  {
833  if (doBase) // base classes
834  {
835  image->drawHorzArrow(y,x,x+cellWidth/2+labelHorSpacing,
836  protToColor(di->protection()),
837  protToMask(di->protection()));
838  image->drawVertLine(x,y,ys+labelVertSpacing/2,
841  }
842  else // super classes
843  {
844  image->drawHorzLine(y,x,x+cellWidth/2+labelHorSpacing,
845  protToColor(di->protection()),
846  protToMask(di->protection()));
847  image->drawVertLine(x,ys-labelVertSpacing/2,y,
850  }
851  }
852  else
853  {
854  t << protToString(di->protection()) << "\n";
855  if (doBase)
856  {
857  t << "1 " << xf << " " << yf << " hedge\n";
858  }
859  else
860  {
861  t << "0 " << xf << " " << yf << " hedge\n";
862  }
863  t << protToString(getMinProtectionLevel(dil)) << "\n";
864  if (doBase)
865  {
866  t << xf << " " << ysf << " " << yf << " vedge\n";
867  }
868  else
869  {
870  t << xf << " " << (ysf + 0.25f) << " " << yf << " vedge\n";
871  }
872  }
873  }
874  if (rit!=dr->end()) ++rit;
875  }
876  done=TRUE; // the tree is drawn now
877  }
878  else // normal tree connector
879  {
880  for (const auto &di : *dr)
881  {
882  uint x=0,y=0;
883  DiagramItemList dil = di->getChildren();
884  DiagramItem *parent = di->parentItem();
885  if (parent) // item has a parent -> connect to it
886  {
887  if (bitmap) // draw pixels
888  {
889  x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
890  if (doBase) // base classes
891  {
892  y = image->height()-
893  (superRows-1)*(cellHeight+labelVertSpacing)-
894  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
895  /* write input line */
896  image->drawVertArrow(x,y,y+labelVertSpacing/2,
897  protToColor(di->protection()),
898  protToMask(di->protection()));
899  }
900  else // super classes
901  {
902  y = (baseRows-1)*(cellHeight+labelVertSpacing)-
904  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
905  /* write output line */
906  image->drawVertLine(x,y,y+labelVertSpacing/2,
907  protToColor(di->protection()),
908  protToMask(di->protection()));
909  }
910  }
911  else // draw pixels
912  {
913  t << protToString(di->protection()) << "\n";
914  if (doBase)
915  {
916  t << "1 " << di->xPos()/(float)gridWidth << " "
917  << (di->yPos()/(float)gridHeight+superRows-1) << " in\n";
918  }
919  else
920  {
921  t << "0 " << di->xPos()/(float)gridWidth << " "
922  << ((float)superRows-0.25f-di->yPos()/(float)gridHeight)
923  << " in\n";
924  }
925  }
926  }
927  if (!dil.empty())
928  {
930  uint mask=protToMask(p);
931  uchar col=protToColor(p);
932  if (bitmap)
933  {
934  x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
935  if (doBase) // base classes
936  {
937  y = image->height()-
938  (superRows-1)*(cellHeight+labelVertSpacing)-
939  cellHeight-labelVertSpacing/2-
940  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
941  image->drawVertLine(x,y,y+labelVertSpacing/2-1,col,mask);
942  }
943  else // super classes
944  {
945  y = (baseRows-1)*(cellHeight+labelVertSpacing)+
946  cellHeight+
947  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
948  image->drawVertArrow(x,y,y+labelVertSpacing/2-1,col,mask);
949  }
950  }
951  else
952  {
953  t << protToString(p) << "\n";
954  if (doBase)
955  {
956  t << "0 " << di->xPos()/(float)gridWidth << " "
957  << (di->yPos()/(float)gridHeight+superRows-1) << " out\n";
958  }
959  else
960  {
961  t << "1 " << di->xPos()/(float)gridWidth << " "
962  << ((float)superRows-1.75f-di->yPos()/(float)gridHeight)
963  << " out\n";
964  }
965  }
966  /* write input line */
967  DiagramItem *first = dil.front();
968  DiagramItem *last = dil.back();
969  if (first!=last && !first->isInList()) /* connect with all base classes */
970  {
971  if (bitmap)
972  {
973  uint xs = first->xPos()*(cellWidth+labelHorSpacing)/gridWidth
974  + cellWidth/2;
975  uint xe = last->xPos()*(cellWidth+labelHorSpacing)/gridWidth
976  + cellWidth/2;
977  if (doBase) // base classes
978  {
979  image->drawHorzLine(y,xs,xe,col,mask);
980  }
981  else // super classes
982  {
983  image->drawHorzLine(y+labelVertSpacing/2,xs,xe,col,mask);
984  }
985  }
986  else
987  {
988  t << protToString(p) << "\n";
989  if (doBase)
990  {
991  t << first->xPos()/(float)gridWidth << " "
992  << last->xPos()/(float)gridWidth << " "
993  << (first->yPos()/(float)gridHeight+superRows-1)
994  << " conn\n";
995  }
996  else
997  {
998  t << first->xPos()/(float)gridWidth << " "
999  << last->xPos()/(float)gridWidth << " "
1000  << ((float)superRows-first->yPos()/(float)gridHeight)
1001  << " conn\n";
1002  }
1003  }
1004  }
1005  }
1006  }
1007  }
1008  }
1009 }
1010 
1011 //-----------------------------------------------------------------
1012 
1014 {
1015  Private(const ClassDef *root) : base(root,true), super(root,false) {}
1018 };
1019 
1020 //-----------------------------------------------------------------
1021 
1022 
1023 ClassDiagram::ClassDiagram(const ClassDef *root) : p(std::make_unique<Private>(root))
1024 {
1025  p->base.computeLayout();
1026  p->super.computeLayout();
1027  DiagramItem *baseItem = p->base.row(0)->item(0);
1028  DiagramItem *superItem = p->super.row(0)->item(0);
1029  uint xbase = baseItem->xPos();
1030  uint xsuper = superItem->xPos();
1031  if (xbase>xsuper)
1032  {
1033  superItem->move((int)(xbase-xsuper),0);
1034  p->super.moveChildren(superItem,(int)(xbase-xsuper));
1035  }
1036  else if (xbase<xsuper)
1037  {
1038  baseItem->move((int)(xsuper-xbase),0);
1039  p->base.moveChildren(baseItem,(int)(xsuper-xbase));
1040  }
1041 }
1042 
1044 {
1045 }
1046 
1048  const QCString &fileName) const
1049 {
1050  uint baseRows=p->base.computeRows();
1051  uint superRows=p->super.computeRows();
1052  uint baseMaxX, baseMaxLabelWidth, superMaxX, superMaxLabelWidth;
1053  p->base.computeExtremes(&baseMaxLabelWidth,&baseMaxX);
1054  p->super.computeExtremes(&superMaxLabelWidth,&superMaxX);
1055 
1056  uint rows=std::max(1u,baseRows+superRows-1);
1057  uint cols=(std::max(baseMaxX,superMaxX)+gridWidth*2-1)/gridWidth;
1058 
1059  // Estimate the image aspect width and height in pixels.
1060  uint estHeight = rows*40;
1061  uint estWidth = cols*(20+std::max(baseMaxLabelWidth,superMaxLabelWidth));
1062  //printf("Estimated size %d x %d\n",estWidth,estHeight);
1063 
1064  const float pageWidth = 14.0f; // estimated page width in cm.
1065  // Somewhat lower to deal with estimation
1066  // errors.
1067 
1068  // compute the image height in centimeters based on the estimates
1069  float realHeight = static_cast<float>(std::min(rows,12u)); // real height in cm
1070  float realWidth = realHeight * estWidth/static_cast<float>(estHeight);
1071  if (realWidth>pageWidth) // assume that the page width is about 15 cm
1072  {
1073  realHeight*=pageWidth/realWidth;
1074  }
1075 
1076  //output << "}\n";
1077  output << "\\begin{figure}[H]\n"
1078  "\\begin{center}\n"
1079  "\\leavevmode\n";
1080  output << "\\includegraphics[height=" << realHeight << "cm]{"
1081  << fileName << "}\n";
1082  output << "\\end{center}\n"
1083  "\\end{figure}\n";
1084 
1085  //printf("writeFigure rows=%d cols=%d\n",rows,cols);
1086 
1087  QCString epsBaseName=(QCString)path+"/"+fileName;
1088  QCString epsName=epsBaseName+".eps";
1089  std::ofstream f(epsName.str(),std::ofstream::out | std::ofstream::binary);
1090  if (!f.is_open())
1091  {
1092  term("Could not open file %s for writing\n",qPrint(epsName));
1093  }
1094  else
1095  {
1096  TextStream t(&f);
1097 
1098  //printf("writeEPS() rows=%d cols=%d\n",rows,cols);
1099 
1100  // generate EPS header and postscript variables and procedures
1101 
1102  t << "%!PS-Adobe-2.0 EPSF-2.0\n";
1103  t << "%%Title: ClassName\n";
1104  t << "%%Creator: Doxygen\n";
1105  t << "%%CreationDate: Time\n";
1106  t << "%%For: \n";
1107  t << "%Magnification: 1.00\n";
1108  t << "%%Orientation: Portrait\n";
1109  t << "%%BoundingBox: 0 0 500 " << estHeight*500.0f/(float)estWidth << "\n";
1110  t << "%%Pages: 0\n";
1111  t << "%%BeginSetup\n";
1112  t << "%%EndSetup\n";
1113  t << "%%EndComments\n";
1114  t << "\n";
1115  t << "% ----- variables -----\n";
1116  t << "\n";
1117  t << "/boxwidth 0 def\n";
1118  t << "/boxheight 40 def\n";
1119  t << "/fontheight 24 def\n";
1120  t << "/marginwidth 10 def\n";
1121  t << "/distx 20 def\n";
1122  t << "/disty 40 def\n";
1123  t << "/boundaspect " << estWidth/(float)estHeight << " def % aspect ratio of the BoundingBox (width/height)\n";
1124  t << "/boundx 500 def\n";
1125  t << "/boundy boundx boundaspect div def\n";
1126  t << "/xspacing 0 def\n";
1127  t << "/yspacing 0 def\n";
1128  t << "/rows " << rows << " def\n";
1129  t << "/cols " << cols << " def\n";
1130  t << "/scalefactor 0 def\n";
1131  t << "/boxfont /Times-Roman findfont fontheight scalefont def\n";
1132  t << "\n";
1133  t << "% ----- procedures -----\n";
1134  t << "\n";
1135  t << "/dotted { [1 4] 0 setdash } def\n";
1136  t << "/dashed { [5] 0 setdash } def\n";
1137  t << "/solid { [] 0 setdash } def\n";
1138  t << "\n";
1139  t << "/max % result = MAX(arg1,arg2)\n";
1140  t << "{\n";
1141  t << " /a exch def\n";
1142  t << " /b exch def\n";
1143  t << " a b gt {a} {b} ifelse\n";
1144  t << "} def\n";
1145  t << "\n";
1146  t << "/xoffset % result = MAX(0,(scalefactor-(boxwidth*cols+distx*(cols-1)))/2)\n";
1147  t << "{\n";
1148  t << " 0 scalefactor boxwidth cols mul distx cols 1 sub mul add sub 2 div max\n";
1149  t << "} def\n";
1150  t << "\n";
1151  t << "/cw % boxwidth = MAX(boxwidth, stringwidth(arg1))\n";
1152  t << "{\n";
1153  t << " /str exch def\n";
1154  t << " /boxwidth boxwidth str stringwidth pop max def\n";
1155  t << "} def\n";
1156  t << "\n";
1157  t << "/box % draws a box with text 'arg1' at grid pos (arg2,arg3)\n";
1158  t << "{ gsave\n";
1159  t << " 2 setlinewidth\n";
1160  t << " newpath\n";
1161  t << " exch xspacing mul xoffset add\n";
1162  t << " exch yspacing mul\n";
1163  t << " moveto\n";
1164  t << " boxwidth 0 rlineto \n";
1165  t << " 0 boxheight rlineto \n";
1166  t << " boxwidth neg 0 rlineto \n";
1167  t << " 0 boxheight neg rlineto \n";
1168  t << " closepath\n";
1169  t << " dup stringwidth pop neg boxwidth add 2 div\n";
1170  t << " boxheight fontheight 2 div sub 2 div\n";
1171  t << " rmoveto show stroke\n";
1172  t << " grestore\n";
1173  t << "} def \n";
1174  t << "\n";
1175  t << "/mark\n";
1176  t << "{ newpath\n";
1177  t << " exch xspacing mul xoffset add boxwidth add\n";
1178  t << " exch yspacing mul\n";
1179  t << " moveto\n";
1180  t << " 0 boxheight 4 div rlineto\n";
1181  t << " boxheight neg 4 div boxheight neg 4 div rlineto\n";
1182  t << " closepath\n";
1183  t << " eofill\n";
1184  t << " stroke\n";
1185  t << "} def\n";
1186  t << "\n";
1187  t << "/arrow\n";
1188  t << "{ newpath\n";
1189  t << " moveto\n";
1190  t << " 3 -8 rlineto\n";
1191  t << " -6 0 rlineto\n";
1192  t << " 3 8 rlineto\n";
1193  t << " closepath\n";
1194  t << " eofill\n";
1195  t << " stroke\n";
1196  t << "} def\n";
1197  t << "\n";
1198  t << "/out % draws an output connector for the block at (arg1,arg2)\n";
1199  t << "{\n";
1200  t << " newpath\n";
1201  t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
1202  t << " exch yspacing mul boxheight add\n";
1203  t << " /y exch def\n";
1204  t << " /x exch def\n";
1205  t << " x y moveto\n";
1206  t << " 0 disty 2 div rlineto \n";
1207  t << " stroke\n";
1208  t << " 1 eq { x y disty 2 div add arrow } if\n";
1209  t << "} def\n";
1210  t << "\n";
1211  t << "/in % draws an input connector for the block at (arg1,arg2)\n";
1212  t << "{\n";
1213  t << " newpath\n";
1214  t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
1215  t << " exch yspacing mul disty 2 div sub\n";
1216  t << " /y exch def\n";
1217  t << " /x exch def\n";
1218  t << " x y moveto\n";
1219  t << " 0 disty 2 div rlineto\n";
1220  t << " stroke\n";
1221  t << " 1 eq { x y disty 2 div add arrow } if\n";
1222  t << "} def\n";
1223  t << "\n";
1224  t << "/hedge\n";
1225  t << "{\n";
1226  t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
1227  t << " exch yspacing mul boxheight 2 div sub\n";
1228  t << " /y exch def\n";
1229  t << " /x exch def\n";
1230  t << " newpath\n";
1231  t << " x y moveto\n";
1232  t << " boxwidth 2 div distx add 0 rlineto\n";
1233  t << " stroke\n";
1234  t << " 1 eq\n";
1235  t << " { newpath x boxwidth 2 div distx add add y moveto\n";
1236  t << " -8 3 rlineto\n";
1237  t << " 0 -6 rlineto\n";
1238  t << " 8 3 rlineto\n";
1239  t << " closepath\n";
1240  t << " eofill\n";
1241  t << " stroke\n";
1242  t << " } if\n";
1243  t << "} def\n";
1244  t << "\n";
1245  t << "/vedge\n";
1246  t << "{\n";
1247  t << " /ye exch def\n";
1248  t << " /ys exch def\n";
1249  t << " /xs exch def\n";
1250  t << " newpath\n";
1251  t << " xs xspacing mul xoffset add boxwidth 2 div add dup\n";
1252  t << " ys yspacing mul boxheight 2 div sub\n";
1253  t << " moveto\n";
1254  t << " ye yspacing mul boxheight 2 div sub\n";
1255  t << " lineto\n";
1256  t << " stroke\n";
1257  t << "} def\n";
1258  t << "\n";
1259  t << "/conn % connections the blocks from col 'arg1' to 'arg2' of row 'arg3'\n";
1260  t << "{\n";
1261  t << " /ys exch def\n";
1262  t << " /xe exch def\n";
1263  t << " /xs exch def\n";
1264  t << " newpath\n";
1265  t << " xs xspacing mul xoffset add boxwidth 2 div add\n";
1266  t << " ys yspacing mul disty 2 div sub\n";
1267  t << " moveto\n";
1268  t << " xspacing xe xs sub mul 0\n";
1269  t << " rlineto\n";
1270  t << " stroke\n";
1271  t << "} def\n";
1272  t << "\n";
1273  t << "% ----- main ------\n";
1274  t << "\n";
1275  t << "boxfont setfont\n";
1276  t << "1 boundaspect scale\n";
1277 
1278 
1279  for (const auto &dr : p->base)
1280  {
1281  bool done=FALSE;
1282  for (const auto &di : *dr)
1283  {
1284  done=di->isInList();
1285  t << "(" << convertToPSString(di->label()) << ") cw\n";
1286  }
1287  if (done) break;
1288  }
1289 
1290  auto it = p->super.begin();
1291  if (it!=p->super.end()) ++it;
1292  for (;it!=p->super.end();++it)
1293  {
1294  const auto &dr = *it;
1295  bool done=FALSE;
1296  for (const auto &di : *dr)
1297  {
1298  done=di->isInList();
1299  t << "(" << convertToPSString(di->label()) << ") cw\n";
1300  }
1301  if (done) break;
1302  }
1303 
1304  t << "/boxwidth boxwidth marginwidth 2 mul add def\n"
1305  << "/xspacing boxwidth distx add def\n"
1306  << "/yspacing boxheight disty add def\n"
1307  << "/scalefactor \n"
1308  << " boxwidth cols mul distx cols 1 sub mul add\n"
1309  << " boxheight rows mul disty rows 1 sub mul add boundaspect mul \n"
1310  << " max def\n"
1311  << "boundx scalefactor div boundy scalefactor div scale\n";
1312 
1313  t << "\n% ----- classes -----\n\n";
1314  p->base.drawBoxes(t,0,TRUE,FALSE,baseRows,superRows,0,0);
1315  p->super.drawBoxes(t,0,FALSE,FALSE,baseRows,superRows,0,0);
1316 
1317  t << "\n% ----- relations -----\n\n";
1318  p->base.drawConnectors(t,0,TRUE,FALSE,baseRows,superRows,0,0);
1319  p->super.drawConnectors(t,0,FALSE,FALSE,baseRows,superRows,0,0);
1320 
1321  }
1322  f.close();
1323 
1324  if (Config_getBool(USE_PDFLATEX))
1325  {
1326  QCString epstopdfArgs(4096);
1327  epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",
1328  qPrint(epsBaseName),qPrint(epsBaseName));
1329  //printf("Converting eps using '%s'\n",qPrint(epstopdfArgs));
1331  if (Portable::system("epstopdf",epstopdfArgs)!=0)
1332  {
1333  err("Problems running epstopdf. Check your TeX installation!\n");
1335  return;
1336  }
1338  }
1339 }
1340 
1341 
1343  const QCString &relPath,const QCString &fileName,
1344  bool generateMap) const
1345 {
1346  uint baseRows=p->base.computeRows();
1347  uint superRows=p->super.computeRows();
1348  uint rows=baseRows+superRows-1;
1349 
1350  uint lb,ls,xb,xs;
1351  p->base.computeExtremes(&lb,&xb);
1352  p->super.computeExtremes(&ls,&xs);
1353 
1354  uint cellWidth = std::max(lb,ls)+labelHorMargin*2;
1355  uint maxXPos = std::max(xb,xs);
1356  uint labelVertMargin = 6; //std::max(6,(cellWidth-fontHeight)/6); // aspect at least 1:3
1357  uint cellHeight = labelVertMargin*2+fontHeight;
1358  uint imageWidth = (maxXPos+gridWidth)*cellWidth/gridWidth+
1359  (maxXPos*labelHorSpacing)/gridWidth;
1360  uint imageHeight = rows*cellHeight+(rows-1)*labelVertSpacing;
1361 
1362  Image image(imageWidth,imageHeight);
1363 
1364  p->base.drawBoxes(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight,relPath,generateMap);
1365  p->super.drawBoxes(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight,relPath,generateMap);
1366  p->base.drawConnectors(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight);
1367  p->super.drawConnectors(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight);
1368 
1369 #define IMAGE_EXT ".png"
1370  image.save((QCString)path+"/"+fileName+IMAGE_EXT);
1372 }
1373 
DiagramRow::item
DiagramItem * item(int index)
Definition: diagram.cpp:87
DiagramRow::m_level
uint m_level
Definition: diagram.cpp:95
ClassDiagram::Private::Private
Private(const ClassDef *root)
Definition: diagram.cpp:1015
Image::writeString
void writeString(uint x, uint y, const QCString &s, uchar fg)
Definition: image.cpp:300
DiagramRow::Ptr
std::unique_ptr< DiagramItem > Ptr
Definition: diagram.cpp:78
DiagramRow::end
iterator end()
Definition: diagram.cpp:90
TreeDiagram::addRow
DiagramRow * addRow(uint l)
Definition: diagram.cpp:123
Normal
@ Normal
Definition: types.h:29
DualDirIterator::m_it
C::iterator m_it
Definition: diagram.cpp:564
Protection
Protection
Protection level of members
Definition: types.h:26
DiagramItem::move
void move(int dx, int dy)
Definition: diagram.cpp:49
getMinProtectionLevel
static Protection getMinProtectionLevel(const DiagramItemList &dil)
Definition: diagram.cpp:195
stripScope
QCString stripScope(const QCString &name)
Definition: util.cpp:3815
Private
@ Private
Definition: types.h:26
DiagramItem::label
QCString label() const
Definition: diagram.cpp:282
DiagramItem::getChildren
DiagramItemList getChildren()
Definition: diagram.cpp:48
QCString::length
uint length() const
Returns the length of the string, not counting the 0-terminator.
Definition: qcstring.h:147
DiagramRow
Class representing a row in the built-in class diagram
Definition: diagram.cpp:75
DiagramItem::m_num
uint m_num
Definition: diagram.cpp:66
ClassDiagram::writeImage
void writeImage(TextStream &t, const QCString &path, const QCString &relPath, const QCString &file, bool generateMap=true) const
Definition: diagram.cpp:1342
DiagramItem::parentItem
DiagramItem * parentItem()
Definition: diagram.cpp:47
DualDirIterator::DualDirIterator
DualDirIterator(C &container, bool fwd)
Definition: diagram.cpp:538
writeMapArea
static void writeMapArea(TextStream &t, const ClassDef *cd, QCString relPath, uint x, uint y, uint w, uint h)
Definition: diagram.cpp:245
QCString::isEmpty
bool isEmpty() const
Returns TRUE iff the string is empty
Definition: qcstring.h:144
index.h
maxTreeWidth
const uint maxTreeWidth
Definition: diagram.cpp:138
Doxygen::indexList
static IndexList * indexList
Definition: doxygen.h:114
DiagramItem::m_y
uint m_y
Definition: diagram.cpp:65
TreeDiagram::iterator
typename Vec::iterator iterator
Definition: diagram.cpp:105
DiagramRow::begin
iterator begin()
Definition: diagram.cpp:89
DiagramRow::DiagramRow
DiagramRow(TreeDiagram *d, uint l)
Definition: diagram.cpp:82
TreeDiagram::begin
iterator begin()
Definition: diagram.cpp:125
TreeDiagram::numRows
uint numRows() const
Definition: diagram.cpp:122
DiagramItem::m_prot
Protection m_prot
Definition: diagram.cpp:67
Image::drawRect
void drawRect(uint x, uint y, uint width, uint height, uchar colIndex, uint mask)
Definition: image.cpp:367
Image::stringLength
friend uint stringLength(const QCString &s)
Definition: image.cpp:314
Virtual
@ Virtual
Definition: types.h:29
QCString::str
std::string str() const
Definition: qcstring.h:442
Specifier
Specifier
Virtualness of a member.
Definition: types.h:29
DualDirIterator::operator*
I & operator*()
Definition: diagram.cpp:548
DiagramRow::numItems
uint numItems() const
Definition: diagram.cpp:88
Image::drawVertLine
void drawVertLine(uint x, uint ys, uint ye, uchar colIndex, uint mask)
Definition: image.cpp:347
DualDirIterator::m_container
C & m_container
Definition: diagram.cpp:562
Public
@ Public
Definition: types.h:26
Image::fillRect
void fillRect(uint x, uint y, uint width, uint height, uchar colIndex, uint mask)
Definition: image.cpp:375
Package
@ Package
Definition: types.h:26
DiagramItem::addChild
void addChild(DiagramItem *di)
Definition: diagram.cpp:328
textstream.h
err
void err(const char *fmt,...)
Definition: message.cpp:203
DiagramRow::m_items
Vec m_items
Definition: diagram.cpp:96
ClassDef::isVisibleInHierarchy
virtual bool isVisibleInHierarchy() const =0
the class is visible in a class diagram, or class hierarchy
TextStream
Text streaming class that buffers data.
Definition: textstream.h:33
DiagramItem::isInList
bool isInList() const
Definition: diagram.cpp:59
TreeDiagram::computeRows
uint computeRows()
Definition: diagram.cpp:485
TreeDiagram::m_rows
Vec m_rows
Definition: diagram.cpp:131
DiagramRow::m_diagram
TreeDiagram * m_diagram
Definition: diagram.cpp:94
DiagramItem::xPos
uint xPos() const
Definition: diagram.cpp:50
uint
unsigned uint
Definition: qcstring.h:40
Image
Class representing a bitmap image generated by doxygen.
Definition: image.h:26
Image::height
uint height() const
Definition: image.h:61
addHtmlExtensionIfMissing
QCString addHtmlExtensionIfMissing(const QCString &fName)
Definition: util.cpp:5275
labelHorMargin
const uint labelHorMargin
Definition: diagram.cpp:144
ClassDiagram::Private
Definition: diagram.cpp:1013
ClassDef
A abstract class representing of a compound symbol.
Definition: classdef.h:103
classlist.h
DiagramItem::number
uint number() const
Definition: diagram.cpp:55
uchar
unsigned char uchar
Definition: qcstring.h:38
QCString::left
QCString left(size_t len) const
Definition: qcstring.h:212
TreeDiagram::moveChildren
void moveChildren(DiagramItem *root, int dx)
Definition: diagram.cpp:385
message.h
fontHeight
const uint fontHeight
Definition: diagram.cpp:145
Portable::sysTimerStart
void sysTimerStart()
Definition: portable.cpp:470
DiagramItem::m_templSpec
QCString m_templSpec
Definition: diagram.cpp:69
IndexList::addImageFile
void addImageFile(const QCString &name)
Definition: index.h:105
ClassDef::getOutputFileBase
virtual QCString getOutputFileBase() const =0
Returns the unique base name (without extension) of the class's file on disk
DiagramItem::protection
Protection protection() const
Definition: diagram.cpp:56
DiagramItem::numChildren
uint numChildren() const
Definition: diagram.cpp:323
ClassDiagram::Private::base
TreeDiagram base
Definition: diagram.cpp:1016
ClassDef::baseClasses
virtual const BaseClassList & baseClasses() const =0
Returns the list of base classes from which this class directly inherits.
DiagramItem::DiagramItem
DiagramItem(DiagramItem *p, uint number, const ClassDef *cd, Protection prot, Specifier virt, const QCString &ts)
Definition: diagram.cpp:276
TreeDiagram::operator=
TreeDiagram & operator=(const TreeDiagram &)
Definition::name
virtual QCString name() const =0
TreeDiagram::computeExtremes
void computeExtremes(uint *labelWidth, uint *xpos)
Definition: diagram.cpp:515
protToMask
static uint protToMask(Protection p)
Definition: diagram.cpp:147
Image::drawHorzLine
void drawHorzLine(uint y, uint xs, uint xe, uchar colIndex, uint mask)
Definition: image.cpp:326
doxygen.h
labelHorSpacing
const uint labelHorSpacing
Definition: diagram.cpp:142
DualDirIterator
helper class representing an iterator that can iterate forwards or backwards
Definition: diagram.cpp:535
ClassDiagram::ClassDiagram
ClassDiagram(const ClassDef *root)
Definition: diagram.cpp:1023
image.h
TRUE
#define TRUE
Definition: qcstring.h:36
protToColor
static uchar protToColor(Protection p)
Definition: diagram.cpp:159
Portable::system
int system(const QCString &command, const QCString &args, bool commandHasConsole=true)
Definition: portable.cpp:42
TreeDiagram
Class representing the tree layout for the built-in class diagram.
Definition: diagram.cpp:100
TreeDiagram::TreeDiagram
TreeDiagram(const ClassDef *root, bool doBases)
Definition: diagram.cpp:377
Image::drawVertArrow
void drawVertArrow(uint x, uint ys, uint ye, uchar colIndex, uint mask)
Definition: image.cpp:356
gridHeight
const uint gridHeight
Definition: diagram.cpp:140
insertTemplateSpecifierInScope
QCString insertTemplateSpecifierInScope(const QCString &scope, const QCString &templ)
Definition: util.cpp:3782
DiagramItem::fileName
QCString fileName() const
Definition: diagram.cpp:304
ClassDef::subClasses
virtual const BaseClassList & subClasses() const =0
Returns the list of sub classes that directly derive from this class
externalLinkTarget
QCString externalLinkTarget(const bool parent)
Definition: util.cpp:6323
TreeDiagram::drawConnectors
void drawConnectors(TextStream &t, Image *image, bool doBase, bool bitmap, uint baseRows, uint superRows, uint cellWidth, uint cellheight)
Definition: diagram.cpp:698
DiagramItem::yPos
uint yPos() const
Definition: diagram.cpp:51
TreeDiagram::Vec
std::vector< Ptr > Vec
Definition: diagram.cpp:104
DiagramRow::rend
reverse_iterator rend()
Definition: diagram.cpp:92
DiagramRow::rbegin
reverse_iterator rbegin()
Definition: diagram.cpp:91
Protected
@ Protected
Definition: types.h:26
classdef.h
ClassDiagram::p
std::unique_ptr< Private > p
Definition: diagram.h:39
writeBitmapBox
static void writeBitmapBox(DiagramItem *di, Image *image, uint x, uint y, uint w, uint h, bool firstRow, bool hasDocs, bool children=FALSE)
Definition: diagram.cpp:215
IMAGE_EXT
#define IMAGE_EXT
DiagramItem::m_virt
Specifier m_virt
Definition: diagram.cpp:68
ClassDiagram::Private::super
TreeDiagram super
Definition: diagram.cpp:1017
TreeDiagram::drawBoxes
void drawBoxes(TextStream &t, Image *image, bool doBase, bool bitmap, uint baseRows, uint superRows, uint cellWidth, uint cellHeight, QCString relPath="", bool generateMap=TRUE)
Definition: diagram.cpp:568
DiagramRow::Vec
std::vector< Ptr > Vec
Definition: diagram.cpp:79
Config_getBool
#define Config_getBool(name)
Definition: config.h:33
protToString
static QCString protToString(Protection p)
Definition: diagram.cpp:171
labelVertSpacing
const uint labelVertSpacing
Definition: diagram.cpp:143
DiagramRow::iterator
typename Vec::iterator iterator
Definition: diagram.cpp:80
ClassDef::getReference
virtual QCString getReference() const =0
If this class originated from a tagfile, this will return the tag file reference
DiagramItem::m_parent
DiagramItem * m_parent
Definition: diagram.cpp:63
term
void term(const char *fmt,...)
Definition: message.cpp:220
qPrint
const char * qPrint(const char *s)
Definition: qcstring.h:589
ClassDiagram::~ClassDiagram
~ClassDiagram()
Definition: diagram.cpp:1043
DualDirIterator::m_rit
C::reverse_iterator m_rit
Definition: diagram.cpp:565
TreeDiagram::layoutTree
bool layoutTree(DiagramItem *root, uint row)
Definition: diagram.cpp:394
config.h
Portable::sysTimerStop
void sysTimerStop()
Definition: portable.cpp:475
DiagramRow::number
uint number()
Definition: diagram.cpp:85
ClassDef::displayName
virtual QCString displayName(bool includeScope=TRUE) const =0
Returns the name as it is appears in the documentation
gridWidth
const uint gridWidth
Definition: diagram.cpp:139
convertToXML
QCString convertToXML(const QCString &s, bool keepEntities)
Definition: util.cpp:3948
DualDirIterator::operator++
void operator++()
Definition: diagram.cpp:544
TreeDiagram::end
iterator end()
Definition: diagram.cpp:126
DiagramItem::putInList
void putInList()
Definition: diagram.cpp:58
DiagramItem::getClassDef
const ClassDef * getClassDef() const
Definition: diagram.cpp:60
DiagramItemList
std::vector< DiagramItem * > DiagramItemList
Definition: diagram.cpp:37
DiagramItem::virtualness
Specifier virtualness() const
Definition: diagram.cpp:57
DiagramRow::reverse_iterator
typename Vec::reverse_iterator reverse_iterator
Definition: diagram.cpp:81
DiagramItem::avgChildPos
uint avgChildPos() const
Definition: diagram.cpp:309
portable.h
Portable versions of functions that are platform dependent.
TreeDiagram::Ptr
std::unique_ptr< DiagramRow > Ptr
Definition: diagram.cpp:103
Definition::briefDescriptionAsTooltip
virtual QCString briefDescriptionAsTooltip() const =0
virtToMask
static uint virtToMask(Specifier p)
Definition: diagram.cpp:183
externalRef
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition: util.cpp:6334
DiagramItem::m_x
uint m_x
Definition: diagram.cpp:64
DiagramItem::m_inList
bool m_inList
Definition: diagram.cpp:70
util.h
A bunch of utility functions.
DiagramRow::insertClass
void insertClass(DiagramItem *parent, const ClassDef *cd, bool doBases, Protection prot, Specifier virt, const QCString &ts)
Definition: diagram.cpp:335
DiagramItem::m_children
DiagramItemList m_children
Definition: diagram.cpp:62
Image::drawHorzArrow
void drawHorzArrow(uint y, uint xs, uint xe, uchar colIndex, uint mask)
Definition: image.cpp:336
ClassDef::isLinkable
virtual bool isLinkable() const =0
return TRUE iff a link to this class is possible (either within this project, or as a cross-reference...
writeVectorBox
static void writeVectorBox(TextStream &t, DiagramItem *di, float x, float y, bool children=FALSE)
Definition: diagram.cpp:236
TreeDiagram::row
DiagramRow * row(int index)
Definition: diagram.cpp:121
convertToPSString
QCString convertToPSString(const QCString &s)
Definition: util.cpp:4142
QCString::right
QCString right(size_t len) const
Definition: qcstring.h:217
diagram.h
QCString::sprintf
QCString & sprintf(const char *format,...)
Definition: qcstring.cpp:24
convertToHtml
QCString convertToHtml(const QCString &s, bool keepEntities)
Definition: util.cpp:4063
DiagramItem::m_classDef
const ClassDef * m_classDef
Definition: diagram.cpp:71
DiagramItem
Class representing a single node in the built-in class diagram
Definition: diagram.cpp:40
TreeDiagram::computeLayout
void computeLayout()
Definition: diagram.cpp:434
ClassDiagram::writeFigure
void writeFigure(TextStream &t, const QCString &path, const QCString &file) const
Definition: diagram.cpp:1047
FALSE
#define FALSE
Definition: qcstring.h:33
DualDirIterator::atEnd
bool atEnd()
Definition: diagram.cpp:553
ClassDef::anchor
virtual QCString anchor() const =0
DualDirIterator::m_forward
bool m_forward
Definition: diagram.cpp:563
QCString
This is an alternative implementation of QCString.
Definition: qcstring.h:108