Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cartocrow/core/arrangement_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ PolygonWithHoles<K> face_to_polygon_with_holes(FaceH fh) {
/// Constructs a general polygon with holes from a face of an arrangement.
/// The Traits class should be a model of ArrangementDirectionalXMonotoneTraits_2.
template <class Traits, class FaceH>
CGAL::General_polygon_with_holes_2<Traits> face_to_general_polygon_with_holes(FaceH fh) {
CGAL::General_polygon_with_holes_2<CGAL::General_polygon_2<Traits>> face_to_general_polygon_with_holes(FaceH fh) {
CGAL::General_polygon_2<Traits> outer;
if (fh->has_outer_ccb()) {
outer = ccb_to_general_polygon<Traits>(fh->outer_ccb());
Expand Down
8 changes: 8 additions & 0 deletions cartocrow/renderer/geometry_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,14 @@ class GeometryRenderer {
virtual void setHorizontalTextAlignment(HorizontalTextAlignment alignment) = 0;
/// Set vertical text alignment.
virtual void setVerticalTextAlignment(VerticalTextAlignment alignment) = 0;
/// Set font family (assumes it is the name of a system font that is installed)
virtual void setFontFamily(std::string fontFamily) = 0;
/// Set font size
virtual void setFontSize(double fontSize) = 0;
/// Set font weight
virtual void setFontWeight(bool bold) = 0;
/// Remove font specification (if possible in the renderer) and use the default instead
virtual void useDefaultFont() = 0;
/// @}
};

Expand Down
77 changes: 74 additions & 3 deletions cartocrow/renderer/geometry_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <QPolygon>
#include <QSlider>
#include <QToolButton>
#include <QScreen>

#include <cmath>
#include <limits>
Expand Down Expand Up @@ -694,6 +695,10 @@ QPainterPath GeometryWidget::renderPathToQt(const RenderPath& p) {
return path;
}

QPainter& GeometryWidget::painter() {
return *m_painter;
}

void GeometryWidget::draw(const RenderPath& p) {
setupPainter();
QPainterPath path = renderPathToQt(p);
Expand All @@ -710,8 +715,46 @@ void GeometryWidget::draw(const RenderPath& p) {
void GeometryWidget::drawText(const Point<Inexact>& p, const std::string& text, bool escape) {
setupPainter();
QPointF p2 = convertPoint(p);
m_painter->drawText(QRectF(p2 - QPointF{500, 250}, p2 + QPointF{500, 250}), m_textAlignment,

auto font = m_font;

if (m_textScalesWithZoom) {
double pixelSize = font.pixelSize() * zoomFactor();
double pointSize = pixelSize * 72.0 / screen()->logicalDotsPerInch();
if (pointSize < 0.375) return;
font.setPointSizeF(pointSize);
}

QFontMetricsF m(font);

double w = m.horizontalAdvance(QString::fromStdString(text));
double h = m.height();

QRectF rect;
double x = p2.x();
double y = p2.y();

if (m_textAlignment & Qt::AlignHCenter)
rect.setLeft(x - w / 2);
else if (m_textAlignment & Qt::AlignRight)
rect.setLeft(x - w);
else
rect.setLeft(x);

if (m_textAlignment & Qt::AlignVCenter)
rect.setTop(y - h / 2);
else if (m_textAlignment & Qt::AlignBottom)
rect.setTop(y - h);
else
rect.setTop(y);

rect.setSize(QSizeF(w, h));

m_painter->save();
m_painter->setFont(font);
m_painter->drawText(rect, m_textAlignment,
QString::fromStdString(text));
m_painter->restore();
}

void GeometryWidget::drawImage(const Box& target, const QImage& image, const Box& source, Qt::ImageConversionFlag flags) {
Expand Down Expand Up @@ -869,6 +912,30 @@ void GeometryWidget::setVerticalTextAlignment(VerticalTextAlignment alignment) {
}
}

void GeometryWidget::setFontFamily(std::string fontFamily) {
m_font.setFamily(QString::fromStdString(fontFamily));
}

void GeometryWidget::setFontSize(double fontSize) {
m_font.setPixelSize(fontSize);
}

void GeometryWidget::setFontWeight(bool bold) {
m_font.setBold(bold);
}

void GeometryWidget::useDefaultFont() {
m_font = {};
}

void GeometryWidget::setTextFont(QFont font) {
m_font = font;
}

void GeometryWidget::setTextScaling(bool textScalesWithZoom) {
m_textScalesWithZoom = textScalesWithZoom;
}

void GeometryWidget::addPainting(std::shared_ptr<GeometryPainting> painting, const std::string& name) {
bool visible = !m_invisibleLayerNames.contains(name);
m_paintings.push_back(DrawnPainting{painting, name, visible});
Expand Down Expand Up @@ -972,7 +1039,9 @@ void GeometryWidget::saveToIpe() {

IpeRenderer renderer;
for (const DrawnPainting& painting : m_paintings) {
renderer.addPainting(painting.m_painting, painting.name);
if (painting.visible) {
renderer.addPainting(painting.m_painting, painting.name);
}
}
std::filesystem::path filePath = fileName.toStdString();
if (!filePath.has_extension()) {
Expand All @@ -989,7 +1058,9 @@ void GeometryWidget::saveToSvg() {

SvgRenderer renderer;
for (const DrawnPainting& painting : m_paintings) {
renderer.addPainting(painting.m_painting, painting.name);
if (painting.visible) {
renderer.addPainting(painting.m_painting, painting.name);
}
}
auto windowSize = size();
auto bottomLeft = inverseConvertPoint(QPoint(0, windowSize.height()));
Expand Down
12 changes: 10 additions & 2 deletions cartocrow/renderer/geometry_widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,16 @@ class GeometryWidget : public QWidget, public GeometryRenderer {
void setLineCap(LineCap lineCap) override;
void setHorizontalTextAlignment(HorizontalTextAlignment alignment) override;
void setVerticalTextAlignment(VerticalTextAlignment alignment) override;

void setFontFamily(std::string fontFamily) override;
void setFontSize(double fontSize) override;
void setFontWeight(bool bold) override;
void useDefaultFont() override;
void setTextScaling(bool textScalesWithZoom);
void setTextFont(QFont font);
private:
QFlags<Qt::AlignmentFlag> m_textAlignment = Qt::AlignCenter;
bool m_textScalesWithZoom = false;
QFont m_font;

public:

Expand Down Expand Up @@ -305,9 +312,10 @@ class GeometryWidget : public QWidget, public GeometryRenderer {
/// Converts a rectangle in Qt coordinates back to drawing coordinates.
Box inverseConvertBox(QRectF r) const;
/// Convert a render path to a Qt path.
private:
QPainterPath renderPathToQt(const RenderPath& p);

QPainter& painter();

private:
/// Converts the polygon to Qt coordinates and adds it to the QPainterPath.
void addPolygonToPath(QPainterPath& path, const Polygon<Inexact>& p);
Expand Down
54 changes: 47 additions & 7 deletions cartocrow/renderer/ipe_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,6 @@ void IpeRenderer::save(const std::filesystem::path& file) {
setFillOpacity(255); // add default alpha to style sheet
setStrokeOpacity(255); // add default alpha to style sheet

auto latexPreambleSheet = new ipe::StyleSheet();
latexPreambleSheet->setPreamble(m_preamble.c_str());
latexPreambleSheet->setName("latex-preamble");
document.cascade()->insert(3, latexPreambleSheet);

m_page = new ipe::Page();
document.push_back(m_page);

Expand All @@ -103,6 +98,18 @@ void IpeRenderer::save(const std::filesystem::path& file) {
popStyle();
}

auto latexPreambleSheet = new ipe::StyleSheet();
latexPreambleSheet->setPreamble(m_preamble.c_str());
latexPreambleSheet->setName("latex-preamble");
document.cascade()->insert(3, latexPreambleSheet);

if (m_usedLocalFont) {
auto fontSpecSheet = new ipe::StyleSheet();
fontSpecSheet->setPreamble("\\usepackage{fontspec}");
fontSpecSheet->setName("font-spec");
document.cascade()->insert(4, fontSpecSheet);
}

auto pdf = file.extension() == ".pdf";
if (pdf) {
bool success = document.runLatex(file.c_str());
Expand Down Expand Up @@ -290,8 +297,24 @@ void IpeRenderer::draw(const RenderPath& p) {
}

void IpeRenderer::drawText(const Point<Inexact>& p, const std::string& text, bool escape) {
ipe::String labelText = escape ? escapeForLaTeX(text).data() : text.data();
ipe::Text* label = new ipe::Text(getAttributesForStyle(), labelText,
std::string labelText = escape ? escapeForLaTeX(text) : text;
std::stringstream fullLabelText;
if (m_style.m_fontFamily.has_value() || m_style.m_fontSize.has_value()) {
m_usedLocalFont = true;
if (m_style.m_fontFamily.has_value()) {
fullLabelText << "\\fontspec{" << (m_style.m_bold ? *m_style.m_fontFamily + " Bold" : *m_style.m_fontFamily) << "}";
}
if (m_style.m_fontSize.has_value()) {
fullLabelText << "\\fontsize{" << *m_style.m_fontSize << "}{" << (*m_style.m_fontSize + 2) << "}";
}
fullLabelText << "\\selectfont ";
fullLabelText << labelText;
} else if (m_style.m_bold) {
fullLabelText << "\\textbf{" << labelText << "}";
} else {
fullLabelText << labelText;
}
ipe::Text* label = new ipe::Text(getAttributesForStyle(), fullLabelText.str().data(),
ipe::Vector(p.x(), p.y()), ipe::Text::TextType::ELabel);
label->setHorizontalAlignment(m_style.m_horizontalTextAlignment);
label->setVerticalAlignment(m_style.m_verticalTextAlignment);
Expand Down Expand Up @@ -425,6 +448,23 @@ void IpeRenderer::setVerticalTextAlignment(VerticalTextAlignment alignment) {
}
}

void IpeRenderer::setFontFamily(std::string fontFamily) {
m_style.m_fontFamily = fontFamily;
}

void IpeRenderer::setFontSize(double fontSize) {
m_style.m_fontSize = fontSize;
}

void IpeRenderer::useDefaultFont() {
m_style.m_fontSize = std::nullopt;
m_style.m_fontFamily = std::nullopt;
}

void IpeRenderer::setFontWeight(bool bold) {
m_style.m_bold = bold;
}

void IpeRenderer::drawPathOnPage(ipe::Path* path) {
path->setLineCap(m_style.m_lineCap);
path->setLineJoin(m_style.m_lineJoin);
Expand Down
12 changes: 12 additions & 0 deletions cartocrow/renderer/ipe_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ struct IpeRendererStyle {
ipe::THorizontalAlignment m_horizontalTextAlignment = ipe::EAlignHCenter;
/// Vertical text alignment
ipe::TVerticalAlignment m_verticalTextAlignment = ipe::EAlignVCenter;
/// Bold text?
bool m_bold = false;
/// Local (per text element) font size
std::optional<double> m_fontSize = std::nullopt;
/// Local (per text element) font family
std::optional<std::string> m_fontFamily = std::nullopt;
};

/// Ipe specialization of the GeometryRenderer.
Expand Down Expand Up @@ -114,6 +120,10 @@ class IpeRenderer : public GeometryRenderer {
void setLineCap(LineCap lineCap) override;
void setHorizontalTextAlignment(HorizontalTextAlignment alignment) override;
void setVerticalTextAlignment(VerticalTextAlignment alignment) override;
void setFontFamily(std::string fontFamily) override;
void setFontSize(double fontSize) override;
void useDefaultFont() override;
void setFontWeight(bool bold) override;

void setPreamble(const std::string& preamble);

Expand Down Expand Up @@ -172,6 +182,8 @@ class IpeRenderer : public GeometryRenderer {
int m_pageIndex = 0;
/// Latex preamble
std::string m_preamble;
/// Whether a font size or family was set; the fontspec package then needs to be added to the preamble.
bool m_usedLocalFont = false;
};

} // namespace cartocrow::renderer
17 changes: 17 additions & 0 deletions cartocrow/renderer/painting_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,4 +168,21 @@ void PaintingRenderer::setVerticalTextAlignment(VerticalTextAlignment alignment)
m_style.m_verticalTextAlignment = alignment;
m_objects.push_back(m_style);
}

void PaintingRenderer::setFontFamily(std::string fontFamily) {
m_style.m_fontFamily = fontFamily;
}

void PaintingRenderer::setFontSize(double fontSize) {
m_style.m_fontSize = fontSize;
}

void PaintingRenderer::setFontWeight(bool bold) {
m_style.m_bold = bold;
}

void PaintingRenderer::useDefaultFont() {
m_style.m_fontSize = std::nullopt;
m_style.m_fontFamily = std::nullopt;
}
} // namespace cartocrow::renderer
10 changes: 10 additions & 0 deletions cartocrow/renderer/painting_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class PaintingRenderer : public GeometryPainting, public GeometryRenderer {
void setLineCap(LineCap lineCap) override;
void setHorizontalTextAlignment(HorizontalTextAlignment alignment) override;
void setVerticalTextAlignment(VerticalTextAlignment alignment) override;
void setFontFamily(std::string fontFamily) override;
void setFontSize(double fontSize) override;
void setFontWeight(bool bold) override;
void useDefaultFont() override;

private:
struct Style {
Expand Down Expand Up @@ -88,6 +92,12 @@ class PaintingRenderer : public GeometryPainting, public GeometryRenderer {
HorizontalTextAlignment m_horizontalTextAlignment = AlignHCenter;
/// Vertical text alignment
VerticalTextAlignment m_verticalTextAlignment = AlignVCenter;
/// Bold text?
bool m_bold = false;
/// Local (per text element) font size
std::optional<double> m_fontSize = std::nullopt;
/// Local (per text element) font family
std::optional<std::string> m_fontFamily = std::nullopt;
};
using Label = std::tuple<Point<Inexact>, std::string, bool>;
using DrawableObject =
Expand Down
20 changes: 20 additions & 0 deletions cartocrow/renderer/svg_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ void SvgRenderer::draw(const RenderPath& p) {
void SvgRenderer::drawText(const Point<Inexact>& p, const std::string& text, bool escape) {
m_out << "<text text-anchor=\"" << m_style.m_horizontalTextAlignment
<< "\" dominant-baseline=\"" << m_style.m_verticalTextAlignment
<< (m_style.m_fontFamily.has_value() ? ("\" font-family=\"" + *m_style.m_fontFamily) : "")
<< (m_style.m_fontSize.has_value() ? ("\" font-size=\"" + std::to_string(*m_style.m_fontSize)) : "")
<< (m_style.m_bold ? ("\" font-weight=\"bold") : "")
<< "\" fill=\"" << m_style.m_strokeColor // ipe and qt use stroke color for text color so we do the same here
<< "\" x=\"" << p.x() << "\" y=\""
<< -p.y() << "\">" << (escape ? escapeForSvg(text) : text) << "</text>\n";
}
Expand Down Expand Up @@ -405,4 +409,20 @@ void SvgRenderer::setVerticalTextAlignment(VerticalTextAlignment alignment) {
}
}

void SvgRenderer::setFontFamily(std::string fontFamily) {
m_style.m_fontFamily = fontFamily;
}

void SvgRenderer::setFontSize(double fontSize) {
m_style.m_fontSize = fontSize;
}

void SvgRenderer::setFontWeight(bool bold) {
m_style.m_bold = bold;
}

void SvgRenderer::useDefaultFont() {
m_style.m_fontSize = std::nullopt;
m_style.m_fontFamily = std::nullopt;
}
} // namespace cartocrow::renderer
10 changes: 10 additions & 0 deletions cartocrow/renderer/svg_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ struct SvgRendererStyle {
std::string m_horizontalTextAlignment = "middle";
/// Vertical text alignment.
std::string m_verticalTextAlignment = "middle";
/// Bold text?
bool m_bold = false;
/// Local (per text element) font size
std::optional<double> m_fontSize = std::nullopt;
/// Local (per text element) font family
std::optional<std::string> m_fontFamily = std::nullopt;
};

/// SVG specialization of the GeometryRenderer.
Expand Down Expand Up @@ -96,6 +102,10 @@ class SvgRenderer : public GeometryRenderer {
void setLineCap(LineCap lineCap) override;
void setHorizontalTextAlignment(HorizontalTextAlignment alignment) override;
void setVerticalTextAlignment(VerticalTextAlignment alignment) override;
void setFontFamily(std::string fontFamily) override;
void setFontSize(double fontSize) override;
void setFontWeight(bool bold) override;
void useDefaultFont() override;

void addPainting(const std::shared_ptr<GeometryPainting>& painting);
void addPainting(const std::shared_ptr<GeometryPainting>& painting, const std::string& name);
Expand Down