From 749d5bc12734a01317cb1a4ff954443e8f0e0a58 Mon Sep 17 00:00:00 2001 From: Yvee1 Date: Wed, 17 Jun 2026 22:10:31 +0200 Subject: [PATCH 1/9] Text rendering --- cartocrow/renderer/geometry_widget.cpp | 49 +++++++++++++++++++++++++- cartocrow/renderer/geometry_widget.h | 8 +++-- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/cartocrow/renderer/geometry_widget.cpp b/cartocrow/renderer/geometry_widget.cpp index 0679579d..7068c74b 100644 --- a/cartocrow/renderer/geometry_widget.cpp +++ b/cartocrow/renderer/geometry_widget.cpp @@ -694,6 +694,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); @@ -710,8 +714,43 @@ void GeometryWidget::draw(const RenderPath& p) { void GeometryWidget::drawText(const Point& 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) { + font.setPixelSize(font.pixelSize() * zoomFactor()); + } + + 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) { @@ -869,6 +908,14 @@ void GeometryWidget::setVerticalTextAlignment(VerticalTextAlignment alignment) { } } +void GeometryWidget::setTextFont(QFont font) { + m_font = font; +} + +void GeometryWidget::setTextScaling(bool textScalesWithZoom) { + m_textScalesWithZoom = textScalesWithZoom; +} + void GeometryWidget::addPainting(std::shared_ptr painting, const std::string& name) { bool visible = !m_invisibleLayerNames.contains(name); m_paintings.push_back(DrawnPainting{painting, name, visible}); diff --git a/cartocrow/renderer/geometry_widget.h b/cartocrow/renderer/geometry_widget.h index 5f5b39cb..5683b7fb 100644 --- a/cartocrow/renderer/geometry_widget.h +++ b/cartocrow/renderer/geometry_widget.h @@ -218,9 +218,12 @@ class GeometryWidget : public QWidget, public GeometryRenderer { void setLineCap(LineCap lineCap) override; void setHorizontalTextAlignment(HorizontalTextAlignment alignment) override; void setVerticalTextAlignment(VerticalTextAlignment alignment) override; - + void setTextScaling(bool textScalesWithZoom); + void setTextFont(QFont font); private: QFlags m_textAlignment = Qt::AlignCenter; + bool m_textScalesWithZoom = false; + QFont m_font; public: @@ -305,9 +308,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& p); From d24f6b0828e1835fb1f39fe4bf96338b89368079 Mon Sep 17 00:00:00 2001 From: Yvee1 Date: Wed, 29 Jul 2026 13:21:21 +0200 Subject: [PATCH 2/9] Do not draw text when it becomes too small --- cartocrow/renderer/geometry_widget.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cartocrow/renderer/geometry_widget.cpp b/cartocrow/renderer/geometry_widget.cpp index 7068c74b..fbeeba67 100644 --- a/cartocrow/renderer/geometry_widget.cpp +++ b/cartocrow/renderer/geometry_widget.cpp @@ -31,6 +31,7 @@ along with this program. If not, see . #include #include #include +#include #include #include @@ -718,7 +719,10 @@ void GeometryWidget::drawText(const Point& p, const std::string& text, auto font = m_font; if (m_textScalesWithZoom) { - font.setPixelSize(font.pixelSize() * zoomFactor()); + double pixelSize = font.pixelSize() * zoomFactor(); + double pointSize = pixelSize * 72.0 / screen()->logicalDotsPerInch(); + if (pointSize < 0.375) return; + font.setPointSizeF(pointSize); } QFontMetricsF m(font); From 35bab742a43a5387f639b706478221846e6c6e13 Mon Sep 17 00:00:00 2001 From: Yvee1 Date: Mon, 3 Aug 2026 12:09:07 +0200 Subject: [PATCH 3/9] Fix face_to_general_polygon_with_holes --- cartocrow/core/arrangement_helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cartocrow/core/arrangement_helpers.h b/cartocrow/core/arrangement_helpers.h index 46a8e4a3..18d77232 100644 --- a/cartocrow/core/arrangement_helpers.h +++ b/cartocrow/core/arrangement_helpers.h @@ -130,7 +130,7 @@ PolygonWithHoles 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 -CGAL::General_polygon_with_holes_2 face_to_general_polygon_with_holes(FaceH fh) { +CGAL::General_polygon_with_holes_2> face_to_general_polygon_with_holes(FaceH fh) { CGAL::General_polygon_2 outer; if (fh->has_outer_ccb()) { outer = ccb_to_general_polygon(fh->outer_ccb()); From 71fb3c29f69613213a55e3ea1c70d004c03ed086 Mon Sep 17 00:00:00 2001 From: Yvee1 Date: Mon, 3 Aug 2026 17:58:31 +0200 Subject: [PATCH 4/9] Add basic font settings --- cartocrow/renderer/geometry_renderer.h | 8 +++ cartocrow/renderer/geometry_widget.cpp | 16 ++++++ cartocrow/renderer/geometry_widget.h | 4 ++ cartocrow/renderer/ipe_renderer.cpp | 67 +++++++++++++++++++++--- cartocrow/renderer/ipe_renderer.h | 12 +++++ cartocrow/renderer/painting_renderer.cpp | 17 ++++++ cartocrow/renderer/painting_renderer.h | 10 ++++ cartocrow/renderer/svg_renderer.cpp | 19 +++++++ cartocrow/renderer/svg_renderer.h | 10 ++++ 9 files changed, 156 insertions(+), 7 deletions(-) diff --git a/cartocrow/renderer/geometry_renderer.h b/cartocrow/renderer/geometry_renderer.h index a35ea135..b7ae83ff 100644 --- a/cartocrow/renderer/geometry_renderer.h +++ b/cartocrow/renderer/geometry_renderer.h @@ -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; /// @} }; diff --git a/cartocrow/renderer/geometry_widget.cpp b/cartocrow/renderer/geometry_widget.cpp index fbeeba67..9b3fb904 100644 --- a/cartocrow/renderer/geometry_widget.cpp +++ b/cartocrow/renderer/geometry_widget.cpp @@ -912,6 +912,22 @@ 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; } diff --git a/cartocrow/renderer/geometry_widget.h b/cartocrow/renderer/geometry_widget.h index 5683b7fb..5a417fde 100644 --- a/cartocrow/renderer/geometry_widget.h +++ b/cartocrow/renderer/geometry_widget.h @@ -218,6 +218,10 @@ 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: diff --git a/cartocrow/renderer/ipe_renderer.cpp b/cartocrow/renderer/ipe_renderer.cpp index 908539df..618f9367 100644 --- a/cartocrow/renderer/ipe_renderer.cpp +++ b/cartocrow/renderer/ipe_renderer.cpp @@ -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); @@ -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()); @@ -290,8 +297,24 @@ void IpeRenderer::draw(const RenderPath& p) { } void IpeRenderer::drawText(const Point& 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_fontFamily << "}"; + } + if (m_style.m_fontSize.has_value()) { + fullLabelText << "\\fontsize{" << *m_style.m_fontSize << "}{" << (*m_style.m_fontSize + 2) << "}"; + } + fullLabelText << "\\selectfont "; + } + if (m_style.m_bold) { + fullLabelText << "\\textbf{" << text << "}"; + } else { + fullLabelText << text; + } + 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); @@ -330,6 +353,19 @@ ipe::Attribute IpeRenderer::opacity_attribute(int alpha) { return name; } +//ipe::Attribute IpeRenderer::opacity_attribute(int alpha) { +// // Ipe does not allow arbitrary opacity values; it only allows symbolic +// // references to alpha values from the stylesheet. +// // Therefore, we check if the requested opacity value already exists. If +// // not, we add it to the stylesheet. +// ipe::Attribute name = ipe::Attribute(true, std::to_string(alpha).data()); +// if (!m_alphaSheet->has(ipe::Kind::EOpacity, name)) { +// m_alphaSheet->add(ipe::Kind::EOpacity, name, +// ipe::Attribute(ipe::Fixed::fromDouble(alpha / 255.0))); +// } +// return name; +//} + void IpeRenderer::setStrokeOpacity(int alpha) { auto name = opacity_attribute(alpha); m_style.m_strokeOpacity = name; @@ -425,6 +461,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); diff --git a/cartocrow/renderer/ipe_renderer.h b/cartocrow/renderer/ipe_renderer.h index 177e553f..4c7169b4 100644 --- a/cartocrow/renderer/ipe_renderer.h +++ b/cartocrow/renderer/ipe_renderer.h @@ -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 m_fontSize = std::nullopt; + /// Local (per text element) font family + std::optional m_fontFamily = std::nullopt; }; /// Ipe specialization of the GeometryRenderer. @@ -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); @@ -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 diff --git a/cartocrow/renderer/painting_renderer.cpp b/cartocrow/renderer/painting_renderer.cpp index 31f62c5d..cce7e27a 100644 --- a/cartocrow/renderer/painting_renderer.cpp +++ b/cartocrow/renderer/painting_renderer.cpp @@ -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 diff --git a/cartocrow/renderer/painting_renderer.h b/cartocrow/renderer/painting_renderer.h index 2f392da4..5557583c 100644 --- a/cartocrow/renderer/painting_renderer.h +++ b/cartocrow/renderer/painting_renderer.h @@ -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 { @@ -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 m_fontSize = std::nullopt; + /// Local (per text element) font family + std::optional m_fontFamily = std::nullopt; }; using Label = std::tuple, std::string, bool>; using DrawableObject = diff --git a/cartocrow/renderer/svg_renderer.cpp b/cartocrow/renderer/svg_renderer.cpp index 5114b8f8..13e9994c 100644 --- a/cartocrow/renderer/svg_renderer.cpp +++ b/cartocrow/renderer/svg_renderer.cpp @@ -201,6 +201,9 @@ void SvgRenderer::draw(const RenderPath& p) { void SvgRenderer::drawText(const Point& p, const std::string& text, bool escape) { m_out << "" << (escape ? escapeForSvg(text) : text) << "\n"; } @@ -405,4 +408,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 diff --git a/cartocrow/renderer/svg_renderer.h b/cartocrow/renderer/svg_renderer.h index 5ae53a94..375b72bb 100644 --- a/cartocrow/renderer/svg_renderer.h +++ b/cartocrow/renderer/svg_renderer.h @@ -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 m_fontSize = std::nullopt; + /// Local (per text element) font family + std::optional m_fontFamily = std::nullopt; }; /// SVG specialization of the GeometryRenderer. @@ -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& painting); void addPainting(const std::shared_ptr& painting, const std::string& name); From a1577b94badf9188274990e1a8c3a29a8ba2dc63 Mon Sep 17 00:00:00 2001 From: Yvee1 Date: Tue, 4 Aug 2026 14:46:43 +0200 Subject: [PATCH 5/9] Fix bold text in ipe renderer --- cartocrow/renderer/ipe_renderer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cartocrow/renderer/ipe_renderer.cpp b/cartocrow/renderer/ipe_renderer.cpp index 618f9367..126785d3 100644 --- a/cartocrow/renderer/ipe_renderer.cpp +++ b/cartocrow/renderer/ipe_renderer.cpp @@ -302,14 +302,14 @@ void IpeRenderer::drawText(const Point& p, const std::string& text, boo 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_fontFamily << "}"; + 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 "; - } - if (m_style.m_bold) { + fullLabelText << text; + } else if (m_style.m_bold) { fullLabelText << "\\textbf{" << text << "}"; } else { fullLabelText << text; From fc18d0f40567143f2204f68de168e31d36869dcd Mon Sep 17 00:00:00 2001 From: Yvee1 Date: Tue, 4 Aug 2026 14:47:08 +0200 Subject: [PATCH 6/9] Export to svg/ipe only the paintings that are currently visible --- cartocrow/renderer/geometry_widget.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cartocrow/renderer/geometry_widget.cpp b/cartocrow/renderer/geometry_widget.cpp index 9b3fb904..c3151bf8 100644 --- a/cartocrow/renderer/geometry_widget.cpp +++ b/cartocrow/renderer/geometry_widget.cpp @@ -1039,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()) { @@ -1056,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())); From 1c21dda0081588b1eb6995711f45209b4965d077 Mon Sep 17 00:00:00 2001 From: Yvee1 Date: Tue, 4 Aug 2026 16:45:59 +0200 Subject: [PATCH 7/9] SvgRenderer: set text color to stroke color --- cartocrow/renderer/svg_renderer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cartocrow/renderer/svg_renderer.cpp b/cartocrow/renderer/svg_renderer.cpp index 13e9994c..e8e9b440 100644 --- a/cartocrow/renderer/svg_renderer.cpp +++ b/cartocrow/renderer/svg_renderer.cpp @@ -204,6 +204,7 @@ void SvgRenderer::drawText(const Point& p, const std::string& text, boo << (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) << "\n"; } From 030a0cb3f35e152f548e0f2e720ab72c95c7ad6a Mon Sep 17 00:00:00 2001 From: Yvee1 Date: Tue, 18 Aug 2026 12:11:43 +0200 Subject: [PATCH 8/9] Fix text escaping --- cartocrow/renderer/ipe_renderer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cartocrow/renderer/ipe_renderer.cpp b/cartocrow/renderer/ipe_renderer.cpp index 126785d3..8ee0500e 100644 --- a/cartocrow/renderer/ipe_renderer.cpp +++ b/cartocrow/renderer/ipe_renderer.cpp @@ -308,11 +308,11 @@ void IpeRenderer::drawText(const Point& p, const std::string& text, boo fullLabelText << "\\fontsize{" << *m_style.m_fontSize << "}{" << (*m_style.m_fontSize + 2) << "}"; } fullLabelText << "\\selectfont "; - fullLabelText << text; + fullLabelText << labelText; } else if (m_style.m_bold) { - fullLabelText << "\\textbf{" << text << "}"; + fullLabelText << "\\textbf{" << labelText << "}"; } else { - fullLabelText << text; + fullLabelText << labelText; } ipe::Text* label = new ipe::Text(getAttributesForStyle(), fullLabelText.str().data(), ipe::Vector(p.x(), p.y()), ipe::Text::TextType::ELabel); From e0d967376eaa70ade3958b7d55d9754502490eda Mon Sep 17 00:00:00 2001 From: Yvee1 Date: Tue, 18 Aug 2026 12:14:31 +0200 Subject: [PATCH 9/9] Remove leftover commented code --- cartocrow/renderer/ipe_renderer.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/cartocrow/renderer/ipe_renderer.cpp b/cartocrow/renderer/ipe_renderer.cpp index 8ee0500e..cc320160 100644 --- a/cartocrow/renderer/ipe_renderer.cpp +++ b/cartocrow/renderer/ipe_renderer.cpp @@ -353,19 +353,6 @@ ipe::Attribute IpeRenderer::opacity_attribute(int alpha) { return name; } -//ipe::Attribute IpeRenderer::opacity_attribute(int alpha) { -// // Ipe does not allow arbitrary opacity values; it only allows symbolic -// // references to alpha values from the stylesheet. -// // Therefore, we check if the requested opacity value already exists. If -// // not, we add it to the stylesheet. -// ipe::Attribute name = ipe::Attribute(true, std::to_string(alpha).data()); -// if (!m_alphaSheet->has(ipe::Kind::EOpacity, name)) { -// m_alphaSheet->add(ipe::Kind::EOpacity, name, -// ipe::Attribute(ipe::Fixed::fromDouble(alpha / 255.0))); -// } -// return name; -//} - void IpeRenderer::setStrokeOpacity(int alpha) { auto name = opacity_attribute(alpha); m_style.m_strokeOpacity = name;