Skip to content

Commit af551a2

Browse files
Add SVG rendering support to ICairoShim interface
- Added renderSVG(void* svgHandle, double width, double height) to ICairoShim - Added SVGRenderer::handle() method to expose RsvgHandle* for ICairoShim - Implemented renderSVG in CairoShimCairo using librsvg - Updated GodleyIcon, Group, Ravel, and Lock to use cairoShim.renderSVG() - Removed 3 more _internalGetCairoContext calls (down from 14 to 11) - SVG rendering now fully abstracted through ICairoShim interface Co-authored-by: highperformancecoder <3075825+highperformancecoder@users.noreply.github.com>
1 parent 84344b2 commit af551a2

8 files changed

Lines changed: 50 additions & 11 deletions

File tree

engine/cairoShimCairo.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
#include <cairo.h>
55
#undef CAIRO_WIN32_STATIC_BUILD
66
#include <pango.h>
7+
#include <librsvg/rsvg.h>
8+
9+
// if not #ifdef protected, you get a deprecated warning, which is
10+
// made fatal by -Werror
11+
#ifndef RSVG_CAIRO_H
12+
#include <librsvg/rsvg-cairo.h>
13+
#endif
714

815
using namespace std;
916

@@ -137,4 +144,27 @@ namespace minsky
137144
m_pango.reset(new ecolab::Pango(cairo));
138145
return *m_pango;
139146
}
147+
148+
// SVG rendering support
149+
void CairoShimCairo::renderSVG(void* svgHandle, double width, double height) const
150+
{
151+
if (!svgHandle) return;
152+
153+
RsvgHandle* svg = static_cast<RsvgHandle*>(svgHandle);
154+
#ifdef MXE // MXE doesn't currently have a Rust compiler, so librsvg can be no later than 2.40.21
155+
RsvgDimensionData dims;
156+
rsvg_handle_get_dimensions(svg, &dims);
157+
cairo_scale(cairo, width/dims.width, height/dims.height);
158+
rsvg_handle_render_cairo(svg, cairo);
159+
#else
160+
GError* err=nullptr;
161+
const RsvgRectangle rect{0,0,width,height};
162+
rsvg_handle_render_document(svg, cairo, &rect, &err);
163+
if (err)
164+
{
165+
g_error_free(err);
166+
// Silently ignore errors for now to avoid breaking rendering
167+
}
168+
#endif
169+
}
140170
}

engine/cairoShimCairo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ namespace minsky
7777
// Pango support
7878
ecolab::Pango& pango() const override;
7979

80+
// SVG rendering support
81+
void renderSVG(void* svgHandle, double width, double height) const override;
82+
8083
// TEMPORARY: Internal accessor for migration - to be removed once all implementations are updated
8184
cairo_t* _internalGetCairoContext() const { return cairo; }
8285
};

model/ICairoShim.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ namespace minsky
9090

9191
// Pango support for text rendering
9292
virtual ecolab::Pango& pango() const = 0;
93+
94+
// SVG rendering support
95+
/// Render a pre-loaded SVG resource into a region of size width x height
96+
/// @param svgHandle - RsvgHandle* from SVGRenderer::handle(), passed as void* for abstraction
97+
/// @param width - target width for rendering
98+
/// @param height - target height for rendering
99+
virtual void renderSVG(void* svgHandle, double width, double height) const = 0;
93100
};
94101
}
95102

model/SVGItem.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ namespace minsky
4444
void setResource(const std::string& resource);
4545
/// render SVG into region of size \a width \a height
4646
void render(cairo_t*, double width, double height) const;
47+
/// get the internal RsvgHandle* for use with ICairoShim
48+
void* handle() const {return svg;}
4749
};
4850

4951

model/godleyIcon.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -566,9 +566,8 @@ namespace minsky
566566
{
567567
cairoShim.save();
568568
cairoShim.translate(left+leftMargin(),top);
569-
// SVGRenderer requires cairo_t* (librsvg dependency)
570-
auto& shimImpl = dynamic_cast<const CairoShimCairo&>(cairoShim);
571-
svgRenderer.render(shimImpl._internalGetCairoContext(), w-leftMargin(), h-bottomMargin());
569+
// Render SVG using ICairoShim abstraction
570+
cairoShim.renderSVG(svgRenderer.handle(), w-leftMargin(), h-bottomMargin());
572571
titley=top+0.1*(h-bottomMargin());
573572
cairoShim.restore();
574573
}

model/group.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,8 +1114,8 @@ namespace minsky
11141114
{
11151115
cairoShim.rectangle(0, 0,width, height);
11161116
cairoShim.clip();
1117-
// SVGRenderer requires cairo_t* (librsvg dependency)
1118-
svgRenderer.render(cairo,width, height);
1117+
// Render SVG using ICairoShim abstraction
1118+
cairoShim.renderSVG(svgRenderer.handle(), width, height);
11191119
}
11201120
}
11211121
cairoShim.restore();

model/lock.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,8 @@ namespace minsky
113113
cairoShim.save();
114114
cairoShim.translate(-0.5*w,-0.5*h);
115115
SVGRenderer* icon=locked()? &lockedIcon: &unlockedIcon;
116-
// TODO: Add SVGRenderer support to ICairoShim
117-
auto& shimImpl = dynamic_cast<const CairoShimCairo&>(cairoShim);
118-
icon->render(shimImpl._internalGetCairoContext(),w,h);
116+
// Render SVG using ICairoShim abstraction
117+
cairoShim.renderSVG(icon->handle(), w, h);
119118
cairoShim.restore();
120119
}
121120

model/ravelWrap.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,8 @@ namespace minsky
198198
else
199199
{
200200
cairoShim.translate(-r,-r);
201-
// TODO: SVGRenderer needs ICairoShim support
202-
auto& shimImpl = dynamic_cast<const CairoShimCairo&>(cairoShim);
203-
svgRenderer.render(shimImpl._internalGetCairoContext(),2*r,2*r);
201+
// Render SVG using ICairoShim abstraction
202+
cairoShim.renderSVG(svgRenderer.handle(), 2*r, 2*r);
204203
}
205204
cairoShim.restore();
206205
}

0 commit comments

Comments
 (0)