mirror of
https://github.com/rdkit/rdkit.git
synced 2026-06-06 22:39:55 +08:00
175 lines
5.5 KiB
C++
175 lines
5.5 KiB
C++
//
|
|
// @@ All Rights Reserved @@
|
|
// This file is part of the RDKit.
|
|
// The contents are covered by the terms of the BSD license
|
|
// which is included in the file license.txt, found at the root
|
|
// of the RDKit source tree.
|
|
//
|
|
// Original author: David Cosgrove (AstraZeneca)
|
|
// 19th June 2014
|
|
//
|
|
|
|
#include "MolDraw2DQt.h"
|
|
|
|
#include <QPainter>
|
|
#include <QString>
|
|
|
|
using namespace boost;
|
|
using namespace std;
|
|
|
|
namespace RDKit {
|
|
|
|
// ****************************************************************************
|
|
MolDraw2DQt::MolDraw2DQt(int width, int height, QPainter &qp)
|
|
: MolDraw2D(width, height), qp_(qp) {}
|
|
|
|
// ****************************************************************************
|
|
void MolDraw2DQt::setColour(const DrawColour &col) {
|
|
MolDraw2D::setColour(col);
|
|
QColor this_col(int(255.0 * col.get<0>()), int(255.0 * col.get<1>()),
|
|
int(255.0 * col.get<2>()));
|
|
|
|
QPen pen(this_col);
|
|
pen.setJoinStyle(Qt::RoundJoin);
|
|
pen.setColor(this_col);
|
|
qp_.setPen(pen);
|
|
|
|
QBrush brush(this_col);
|
|
brush.setStyle(Qt::SolidPattern);
|
|
qp_.setBrush(brush);
|
|
}
|
|
|
|
// ****************************************************************************
|
|
void MolDraw2DQt::drawLine(const Point2D &cds1, const Point2D &cds2) {
|
|
Point2D c1 = getDrawCoords(cds1);
|
|
Point2D c2 = getDrawCoords(cds2);
|
|
|
|
const DashPattern &dashes = dash();
|
|
QPen pen = qp_.pen();
|
|
if (dashes.size()) {
|
|
QVector<qreal> dd;
|
|
for (unsigned int di = 0; di < dashes.size(); ++di) dd << dashes[di];
|
|
pen.setDashPattern(dd);
|
|
} else {
|
|
pen.setStyle(Qt::SolidLine);
|
|
}
|
|
pen.setWidth(lineWidth());
|
|
qp_.setPen(pen);
|
|
qp_.drawLine(QPointF(c1.x, c1.y), QPointF(c2.x, c2.y));
|
|
}
|
|
|
|
// ****************************************************************************
|
|
// draw the char, with the bottom left hand corner at cds
|
|
void MolDraw2DQt::drawChar(char c, const Point2D &cds) {
|
|
QRectF br = qp_.boundingRect(0, 0, 100, 100, Qt::AlignLeft | Qt::AlignBottom,
|
|
QString(c));
|
|
qp_.drawText(QRectF(cds.x, cds.y - br.height(), br.width(), br.height()),
|
|
Qt::AlignLeft | Qt::AlignBottom, QString(c), &br);
|
|
}
|
|
|
|
// ****************************************************************************
|
|
void MolDraw2DQt::drawPolygon(const vector<Point2D> &cds) {
|
|
PRECONDITION(cds.size() >= 3, "must have at least three points");
|
|
#ifdef NOTYET
|
|
QBrush brush("Black");
|
|
brush.setStyle(Qt::SolidPattern);
|
|
DrawColour cc = colour();
|
|
brush.setColor(
|
|
QColor(255.0 * cc.get<0>(), 255.0 * cc.get<1>(), 255.0 * cc.get<2>()));
|
|
#endif
|
|
|
|
qp_.save();
|
|
QBrush brush = qp_.brush();
|
|
if (fillPolys())
|
|
brush.setStyle(Qt::SolidPattern);
|
|
else
|
|
brush.setStyle(Qt::NoBrush);
|
|
qp_.setBrush(brush);
|
|
|
|
QPointF points[cds.size()];
|
|
for (unsigned int i = 0; i < cds.size(); ++i) {
|
|
Point2D lc = getDrawCoords(cds[i]);
|
|
points[i] = QPointF(lc.x, lc.y);
|
|
}
|
|
qp_.drawConvexPolygon(points, cds.size());
|
|
qp_.restore();
|
|
}
|
|
|
|
// ****************************************************************************
|
|
void MolDraw2DQt::clearDrawing() {
|
|
QColor this_col(int(255.0 * drawOptions().backgroundColour.get<0>()),
|
|
int(255.0 * drawOptions().backgroundColour.get<1>()),
|
|
int(255.0 * drawOptions().backgroundColour.get<2>()));
|
|
|
|
qp_.setBackground(QBrush(this_col));
|
|
qp_.fillRect(0, 0, width(), height(), this_col);
|
|
}
|
|
|
|
// ****************************************************************************
|
|
void MolDraw2DQt::setFontSize(double new_size) {
|
|
MolDraw2D::setFontSize(new_size);
|
|
double font_size_in_points = fontSize() * scale();
|
|
#ifdef NOTYET
|
|
cout << "initial font size in points : " << qp_.font().pointSizeF() << endl;
|
|
cout << "font_size_in_points : " << font_size_in_points << endl;
|
|
#endif
|
|
QFont font(qp_.font());
|
|
font.setPointSizeF(font_size_in_points);
|
|
qp_.setFont(font);
|
|
|
|
while (1) {
|
|
double old_font_size_in_points = font_size_in_points;
|
|
double font_size_in_points = fontSize() * scale();
|
|
if (fabs(font_size_in_points - old_font_size_in_points) < 0.1) {
|
|
break;
|
|
}
|
|
QFont font(qp_.font());
|
|
font.setPointSizeF(font_size_in_points);
|
|
qp_.setFont(font);
|
|
calculateScale();
|
|
}
|
|
}
|
|
|
|
// ****************************************************************************
|
|
// using the current scale, work out the size of the label in molecule
|
|
// coordinates
|
|
void MolDraw2DQt::getStringSize(const string &label, double &label_width,
|
|
double &label_height) const {
|
|
label_width = 0.0;
|
|
label_height = 0.0;
|
|
|
|
TextDrawType draw_mode =
|
|
TextDrawNormal; // 0 for normal, 1 for superscript, 2 for subscript
|
|
QString next_char(" ");
|
|
bool had_a_super = false;
|
|
|
|
for (int i = 0, is = label.length(); i < is; ++i) {
|
|
// setStringDrawMode moves i along to the end of any <sub> or <sup>
|
|
// markup
|
|
if ('<' == label[i] && setStringDrawMode(label, draw_mode, i)) {
|
|
continue;
|
|
}
|
|
|
|
next_char[0] = label[i];
|
|
QRectF br = qp_.boundingRect(0, 0, 100, 100,
|
|
Qt::AlignBottom | Qt::AlignLeft, next_char);
|
|
label_height = br.height() / scale();
|
|
double char_width = br.width() / scale();
|
|
if (TextDrawSubscript == draw_mode) {
|
|
char_width *= 0.5;
|
|
} else if (TextDrawSuperscript == draw_mode) {
|
|
char_width *= 0.5;
|
|
had_a_super = true;
|
|
}
|
|
label_width += char_width;
|
|
}
|
|
|
|
// subscript keeps its bottom in line with the bottom of the bit chars,
|
|
// superscript goes above the original char top by a quarter
|
|
if (had_a_super) {
|
|
label_height *= 1.25;
|
|
}
|
|
}
|
|
|
|
} // EO namespace RDKit
|