jkqtcommon/jkqtpdrawingtools.h: added template-function to draw a decorated line

JKQTPlotter: add auto-generated line-decorator images
This commit is contained in:
jkriege2 2022-09-06 11:07:52 +02:00
parent 59f500a0a9
commit 2831dcbfb5
54 changed files with 108 additions and 44 deletions

View File

@ -96,8 +96,16 @@ if(JKQtPlotter_BUILD_TOOLS)
WORKING_DIRECTORY ${JKQtPlotter_QT_BINDIR}
DEPENDS jkqtplotter_doc_imagegenerator
)
add_dependencies(JKQTPlotter_GenerateDocImages JKQTPlotter_GenerateDocImages_listplotsymbols)
add_custom_target(JKQTPlotter_GenerateDocImages_listlinedecorators
COMMENT "Building JKQTPlotter Documentation Images: LISTLINEDECORATORS"
COMMAND ${JKQTPlotter_GenerateDocImages_COMMAND} --listlinedecorators --iconsize=32 --outputdir="${JKQTPlotter_GenerateDocImages_OutputDir}/linedecorators/"
WORKING_DIRECTORY ${JKQtPlotter_QT_BINDIR}
DEPENDS jkqtplotter_doc_imagegenerator
)
add_dependencies(JKQTPlotter_GenerateDocImages JKQTPlotter_GenerateDocImages_listlinedecorators)
endif(JKQtPlotter_BUILD_TOOLS)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 645 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 512 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 938 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 997 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1018 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -203,31 +203,31 @@ JKQTCOMMON_LIB_EXPORT JKQTPGraphSymbols String2JKQTPGraphSymbols(const QString&
* \see \ref JKQTPlotterGeometricArrows and \ref JKQTPlotterGeometricGraphs
*/
enum JKQTPLineDecoratorStyle {
JKQTPNoDecorator=0, /*!< \brief no decorator, i.e. a simple line-end */
JKQTPArrow, /*!< \brief a simple arrow tip, unfilled \image html JKQTPArrow.png*/
JKQTPFilledArrow, /*!< \brief a nice filled arrow tip \image html JKQTPFilledArrow.png */
JKQTPTriangleDecorator, /*!< \brief a triangular arrow tip \image html JKQTPTriangleDecorator.png */
JKQTPFilledTriangleDecorator, /*!< \brief a triangular filled arrow tip \image html JKQTPFilledTriangleDecorator.png */
JKQTPTriangleDecoratorAndBar, /*!< \brief a triangular arrow tip, with vertical bar \image html JKQTPTriangleDecoratorAndBar.png */
JKQTPFilledTriangleDecoratorAndBar, /*!< \brief a triangular filled arrow tip, with vertical bar \image html JKQTPFilledTriangleDecoratorAndBar.png */
JKQTPDoubleArrow, /*!< \brief a nice double-arrow tip \image html JKQTPDoubleArrow.png*/
JKQTPFilledDoubleArrow, /*!< \brief a nice filled double-arrow tip \image html JKQTPFilledDoubleArrow.png */
JKQTPCircleDecorator, /*!< \brief an open circle tip \image html JKQTPCircleDecorator.png */
JKQTPFilledCircleDecorator, /*!< \brief a filled circle tip \image html JKQTPFilledCircleDecorator.png */
JKQTPRectangleDecorator, /*!< \brief an open rectangle tip \image html JKQTPRectangleDecorator.png */
JKQTPFilledRectangleDecorator, /*!< \brief a filled rectangle tip \image html JKQTPFilledRectangleDecorator.png */
JKQTPArrowAndBar, /*!< \brief a simple arrow tip, unfilled, with vertical bar \image html JKQTPArrowAndBar.png */
JKQTPDoubleArrowAndBar, /*!< \brief a simple double-arrow tip, unfilled, with vertical bar \image html JKQTPDoubleArrowAndBar.png */
JKQTPBarDecorator, /*!< \brief a full vertical bar \image html JKQTPBarDecorator.png */
JKQTPBracketDecorator, /*!< \brief a vertical bracket decorator \image html JKQTPBracketDecorator.png */
JKQTPDiamondDecorator, /*!< \brief an open diamond tip \image html JKQTPDiamondDecorator.png */
JKQTPDiamondDecoratorAndBar, /*!< \brief an open diamond tip \image html JKQTPDiamondDecoratorAndBar.png */
JKQTPFilledDiamondDecorator, /*!< \brief a filled diamond tip \image html JKQTPFilledDiamondDecorator.png */
JKQTPFilledDiamondDecoratorAndBar, /*!< \brief a filled diamond tip \image html JKQTPFilledDiamondDecoratorAndBar.png */
JKQTPHalfBarDecorator, /*!< \brief a half vertical bar \image html JKQTPHalfBarDecorator.png */
JKQTPHarpoonDecorator, /*!< \brief an harpoon arrow \image html JKQTPHarpoonDecorator.png */
JKQTPHarpoonDecoratorAndBar, /*!< \brief an harpoon arrow, with vertical bar \image html JKQTPHarpoonDecoratorAndBar.png */
JKQTPSkewedBarDecorator, /*!< \brief a skewed vertical bar \image html JKQTPSkewedBarDecorator.png */
JKQTPNoDecorator=0, /*!< \brief no decorator, i.e. a simple line-end \image html linedecorators/none.png */
JKQTPArrow, /*!< \brief a simple arrow tip, unfilled \image html linedecorators/arrow.png */
JKQTPFilledArrow, /*!< \brief a nice filled arrow tip \image html linedecorators/filled_arrow.png */
JKQTPTriangleDecorator, /*!< \brief a triangular arrow tip \image html linedecorators/triangle.png */
JKQTPFilledTriangleDecorator, /*!< \brief a triangular filled arrow tip \image html linedecorators/filled_triangle.png */
JKQTPTriangleDecoratorAndBar, /*!< \brief a triangular arrow tip, with vertical bar \image html linedecorators/triangle_bar.png */
JKQTPFilledTriangleDecoratorAndBar, /*!< \brief a triangular filled arrow tip, with vertical bar \image html linedecorators/filled_triangle_bar.png */
JKQTPDoubleArrow, /*!< \brief a nice double-arrow tip \image html linedecorators/double_arrow.png*/
JKQTPFilledDoubleArrow, /*!< \brief a nice filled double-arrow tip \image html linedecorators/filled_double_arrow.png */
JKQTPCircleDecorator, /*!< \brief an open circle tip \image html linedecorators/circle.png */
JKQTPFilledCircleDecorator, /*!< \brief a filled circle tip \image html linedecorators/filled_circle.png */
JKQTPRectangleDecorator, /*!< \brief an open rectangle tip \image html linedecorators/rectangle.png */
JKQTPFilledRectangleDecorator, /*!< \brief a filled rectangle tip \image html linedecorators/filled_rectangle.png */
JKQTPArrowAndBar, /*!< \brief a simple arrow tip, unfilled, with vertical bar \image html linedecorators/arrow_bar.png */
JKQTPDoubleArrowAndBar, /*!< \brief a simple double-arrow tip, unfilled, with vertical bar \image html linedecorators/double_arrow_bar.png */
JKQTPBarDecorator, /*!< \brief a full vertical bar \image html linedecorators/bar.png */
JKQTPBracketDecorator, /*!< \brief a vertical bracket decorator \image html linedecorators/bracket.png */
JKQTPDiamondDecorator, /*!< \brief an open diamond tip \image html linedecorators/diamond.png */
JKQTPDiamondDecoratorAndBar, /*!< \brief an open diamond tip \image html linedecorators/diamond_bar.png */
JKQTPFilledDiamondDecorator, /*!< \brief a filled diamond tip \image html linedecorators/filled_diamond.png */
JKQTPFilledDiamondDecoratorAndBar, /*!< \brief a filled diamond tip \image html linedecorators/filled_dimanond_bar.png */
JKQTPHalfBarDecorator, /*!< \brief a half vertical bar \image html linedecorators/half_bar.png */
JKQTPHarpoonDecorator, /*!< \brief an harpoon arrow \image html linedecorators/harpoon.png */
JKQTPHarpoonDecoratorAndBar, /*!< \brief an harpoon arrow, with vertical bar \image html linedecorators/harpoon_bar.png */
JKQTPSkewedBarDecorator, /*!< \brief a skewed vertical bar \image html linedecorators/skewed_bar.png */
JKQTPLineDecoratorCount, /*!< \brief can be used to iterate over all symbols using: <code>for (int i=0; i<static_cast<int>(JKQTPLineDecoratorCount); i++) { JKQTPLineDecoratorStyle s=static_cast<JKQTPLineDecoratorStyle>(i); ... }</code> */
JKQTPMaxLineDecoratorID=JKQTPLineDecoratorCount-1, /*!< \brief points to the last available symbol, can be used to iterate over all symbols: <code>for (int i=0; i<=static_cast<int>(JKQTPMaxLineDecoratorID); i++) { JKQTPLineDecoratorStyle s=static_cast<JKQTPLineDecoratorStyle>(i); ... }</code> */
@ -263,6 +263,20 @@ JKQTCOMMON_LIB_EXPORT JKQTPLineDecoratorStyle String2JKQTPLineDecoratorStyle(con
template <class TPainter>
inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double angle_rad, JKQTPLineDecoratorStyle style, double size, QPointF* line_start=nullptr);
/*! \brief plot a line with the given decorators \a style1 and a style2 at the start- and end-point repsectively, using the painter's current pen
\ingroup jkqtptools_drawing
\tparam TPainter Type of \a painter: A class like JKQTPEnhancedPainter or <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a>
\param painter the <a href="http://doc.qt.io/qt-5/qpainter.html">QPainter</a> to draw to
\param l line to draw
\param style1 type of the first decorator to plot, see JKQTPLineDecoratorStyle
\param size1 size of the first decorator
\param style2 type of the second decorator to plot, see JKQTPLineDecoratorStyle
\param size2 size of the second decorator
*/
template <class TPainter>
inline void JKQTPPlotDecoratedLine(TPainter& painter, const QLineF& l, JKQTPLineDecoratorStyle style1, double size1, JKQTPLineDecoratorStyle style2, double size2);
/** \brief calculates the tail decorator size from the line width \a line_width, using decoratorSizeFactor and a non-linear scaling function that levels off towards small \a line_width and increases sub-linearly for large ones, so the arrow heads to not grow too much */
JKQTCOMMON_LIB_EXPORT double JKQTPLineDecoratorStyleCalcDecoratorSize(double line_width, double decoratorSizeFactor);
@ -898,6 +912,19 @@ inline void JKQTPDrawTooltip(TPainter& painter, double x, double y, const QRectF
}
}
template <class TPainter>
inline void JKQTPPlotDecoratedLine(TPainter& painter, const QLineF& l, JKQTPLineDecoratorStyle style1, double size1, JKQTPLineDecoratorStyle style2, double size2) {
const double angle1=atan2(l.p2().y()-l.p1().y(), l.p2().x()-l.p1().x());
const double angle2=atan2(l.p1().y()-l.p2().y(), l.p1().x()-l.p2().x());
QPointF lx1=l.p1(), lx2=l.p2();
JKQTPPlotLineDecorator(painter, l.p1().x(), l.p1().y(), angle1, style1, size1, &lx1);
JKQTPPlotLineDecorator(painter, l.p2().x(), l.p2().y(), angle2, style2, size2, &lx2);
// draw corrected line
painter.drawLine(QLineF(lx1, lx2));
}
template <class TPainter>
inline void JKQTPPlotLineDecorator(TPainter& painter, double x, double y, double angle_rad, JKQTPLineDecoratorStyle style, double size, QPointF* line_start) {
if (line_start) *line_start=QPointF(x,y);

View File

@ -25,6 +25,24 @@
#include "jkqtcommon/jkqtpenhancedpainter.h"
#include <iostream>
void startPainting(QImage& img, JKQTPEnhancedPainter& p, int iconsizex, int iconsizey, QColor backgroundColor) {
img=QImage(QSize(iconsizex,iconsizey),QImage::Format_ARGB32_Premultiplied);
img.fill(backgroundColor);
p.begin(&img);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::TextAntialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
}
void startPainting(QImage& img, JKQTPEnhancedPainter& p, int iconsize, QColor backgroundColor) {
startPainting(img, p, iconsize,iconsize,backgroundColor);
}
void stopPaintingAndSave(QImage& img, JKQTPEnhancedPainter& p, const QString& filename) {
p.end();
img.save(filename);
}
int main(int argc, char* argv[])
{
@ -38,6 +56,8 @@ int main(int argc, char* argv[])
parser.addOption(outputDirectoryOption);
QCommandLineOption listsymbolsOption("listsymbols", "list all symbols in the given output file and generate images.");
parser.addOption(listsymbolsOption);
QCommandLineOption listlinedecoratorsOption("listlinedecorators", "list all line-endings in the given output file and generate images.");
parser.addOption(listlinedecoratorsOption);
QCommandLineOption iconsizeOption("iconsize", "typical size of the generatued images.", "iconsize", "24");
parser.addOption(iconsizeOption);
QCommandLineOption backgroundOption("background", "background color.", "background", "white");
@ -46,36 +66,45 @@ int main(int argc, char* argv[])
const QDir outputDir(parser.value(outputDirectoryOption));
const bool listsymbols=parser.isSet(listsymbolsOption);
const bool listlinedecorators=parser.isSet(listlinedecoratorsOption);
const int iconsize=parser.value(iconsizeOption).toInt();
const QColor backgroundColor = jkqtp_String2QColor(parser.value(backgroundOption));
if (listsymbols) {
for (uint64_t i=0; i<JKQTPSymbolCount; i++) {
const JKQTPGraphSymbols s=static_cast<JKQTPGraphSymbols>(i);
QImage img(QSize(iconsize,iconsize),QImage::Format_ARGB32_Premultiplied);
img.fill(backgroundColor);
QImage img;
JKQTPEnhancedPainter p;
p.begin(&img);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::TextAntialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
startPainting(img, p, iconsize, backgroundColor);
JKQTPPlotSymbol(p, iconsize/2,iconsize/2,s,iconsize-4,2,QColor("blue"), QColor("salmon").lighter(120),QGuiApplication::font().family());
p.end();
const bool ok=img.save(outputDir.absoluteFilePath(JKQTPGraphSymbols2String(s)+".png"));
std::cout<<"saving to "<<outputDir.absoluteFilePath(JKQTPGraphSymbols2String(s)+".png").toStdString()<<" ==> "<<std::boolalpha<<ok<<"\n";
stopPaintingAndSave(img, p, outputDir.absoluteFilePath(JKQTPGraphSymbols2String(s)+".png"));
}
QImage img(QSize(iconsize,iconsize),QImage::Format_ARGB32_Premultiplied);
img.fill(backgroundColor);
QImage img;
JKQTPEnhancedPainter p;
p.begin(&img);
p.setRenderHint(QPainter::Antialiasing);
p.setRenderHint(QPainter::TextAntialiasing);
p.setRenderHint(QPainter::SmoothPixmapTransform);
startPainting(img, p, iconsize, backgroundColor);
JKQTPPlotSymbol(p, iconsize/2,iconsize/2,JKQTPCharacterSymbol+QChar('@').unicode(),iconsize-4,2,QColor("blue"), QColor("blue").lighter(),QGuiApplication::font().family());
p.end();
img.save(outputDir.absoluteFilePath("symbol_char_at.png"));
stopPaintingAndSave(img, p, outputDir.absoluteFilePath("symbol_char_at.png"));
}
if (listlinedecorators) {
for (uint64_t i=0; i<JKQTPLineDecoratorCount; i++) {
const JKQTPLineDecoratorStyle s=static_cast<JKQTPLineDecoratorStyle>(i);
QImage img;
JKQTPEnhancedPainter p;
startPainting(img, p, iconsize*2,iconsize, backgroundColor);
p.setPen(QPen(QColor("red"), 1));
p.setBrush(p.pen().color().lighter());
JKQTPPlotDecoratedLine(p, QLineF(5, iconsize-14, iconsize, 7), JKQTPNoDecorator, 0, s, JKQTPLineDecoratorStyleCalcDecoratorSize(p.pen().widthF(), 9));
p.setPen(QPen(QColor("blue"), 2));
p.setBrush(p.pen().color().lighter());
JKQTPPlotDecoratedLine(p, QLineF(5, iconsize-5, iconsize*2-5, 17), JKQTPNoDecorator, 0, s, JKQTPLineDecoratorStyleCalcDecoratorSize(p.pen().widthF(), 9));
stopPaintingAndSave(img, p, outputDir.absoluteFilePath(JKQTPLineDecoratorStyle2String(s)+".png"));
}
}
return EXIT_SUCCESS;
}