Files
rdkit/Code/GraphMol/MolDraw2D/MolDraw2DQt.cpp
2016-03-03 13:49:33 +01:00

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