summaryrefslogtreecommitdiff
path: root/capi
diff options
context:
space:
mode:
authorEvgeniy Reizner <razrfalcon@gmail.com>2019-06-13 16:51:09 +0300
committerEvgeniy Reizner <razrfalcon@gmail.com>2019-06-13 16:51:45 +0300
commitb63a0898ecdca97414c13ffe98162b1e5083fc33 (patch)
tree59f1737c21821ca6833ce98766fd7a39b3f8f170 /capi
parentbfa7137b57c8d95ae0bb99ab2ffacef8953a182b (diff)
(c-api) Added resvg_get_image_bbox method.
Closes #140
Diffstat (limited to 'capi')
-rw-r--r--capi/include/ResvgQt.h17
-rw-r--r--capi/include/resvg.h14
-rw-r--r--capi/qtests/tst_resvgqt.cpp24
-rw-r--r--capi/qtests/vb.svg3
-rw-r--r--capi/src/lib.rs33
5 files changed, 87 insertions, 4 deletions
diff --git a/capi/include/ResvgQt.h b/capi/include/ResvgQt.h
index d4516fc..53b44d7 100644
--- a/capi/include/ResvgQt.h
+++ b/capi/include/ResvgQt.h
@@ -216,6 +216,11 @@ public:
QRectF boundsOnElement(const QString &id) const;
/**
+ * @brief Returns bounding rectangle of a whole image.
+ */
+ QRectF boundingBox() const;
+
+ /**
* @brief Returns \b true if element with such an ID exists.
*/
bool elementExists(const QString &id) const;
@@ -380,6 +385,18 @@ inline QRectF ResvgRenderer::boundsOnElement(const QString &id) const
return QRectF();
}
+inline QRectF ResvgRenderer::boundingBox() const
+{
+ if (!d->tree)
+ return QRectF();
+
+ resvg_rect bbox;
+ if (resvg_get_image_bbox(d->tree, &bbox))
+ return QRectF(bbox.x, bbox.y, bbox.height, bbox.width);
+
+ return QRectF();
+}
+
inline bool ResvgRenderer::elementExists(const QString &id) const
{
if (!d->tree)
diff --git a/capi/include/resvg.h b/capi/include/resvg.h
index 1a5bf4d..8702978 100644
--- a/capi/include/resvg.h
+++ b/capi/include/resvg.h
@@ -301,6 +301,8 @@ bool resvg_is_image_empty(const resvg_render_tree *tree);
/**
* @brief Returns an image size.
*
+ * The size of a canvas that required to render this SVG.
+ *
* @param tree Render tree.
* @return Image size.
*/
@@ -315,6 +317,18 @@ resvg_size resvg_get_image_size(const resvg_render_tree *tree);
resvg_rect resvg_get_image_viewbox(const resvg_render_tree *tree);
/**
+ * @brief Returns an image bounding box.
+ *
+ * Can be smaller or bigger than a \b viewbox.
+ *
+ * @param tree Render tree.
+ * @param bbox Image's bounding box.
+ * @return \b false if an image has no elements.
+ */
+bool resvg_get_image_bbox(const resvg_render_tree *tree,
+ resvg_rect *bbox);
+
+/**
* @brief Returns \b true if a renderable node with such an ID exists.
*
* @param tree Render tree.
diff --git a/capi/qtests/tst_resvgqt.cpp b/capi/qtests/tst_resvgqt.cpp
index 72e8dec..c5bec64 100644
--- a/capi/qtests/tst_resvgqt.cpp
+++ b/capi/qtests/tst_resvgqt.cpp
@@ -15,6 +15,9 @@ private Q_SLOTS:
void test_renderFile();
+ void test_imageSize();
+ void test_imageViewBox();
+ void test_imageBoundingBox();
void test_elementExists();
void test_transformForElement();
};
@@ -66,6 +69,27 @@ void ResvgQtTests::test_renderFile()
#endif
}
+void ResvgQtTests::test_imageSize()
+{
+ ResvgRenderer render(localPath("vb.svg"));
+ QVERIFY(!render.isEmpty());
+ QCOMPARE(render.defaultSize(), QSize(200, 400));
+}
+
+void ResvgQtTests::test_imageViewBox()
+{
+ ResvgRenderer render(localPath("vb.svg"));
+ QVERIFY(!render.isEmpty());
+ QCOMPARE(render.viewBox(), QRect(50, 100, 200, 400));
+}
+
+void ResvgQtTests::test_imageBoundingBox()
+{
+ ResvgRenderer render(localPath("test.svg"));
+ QVERIFY(!render.isEmpty());
+ QCOMPARE(render.boundingBox(), QRect(20, 20, 160, 160));
+}
+
void ResvgQtTests::test_elementExists()
{
ResvgRenderer render(localPath("test.svg"));
diff --git a/capi/qtests/vb.svg b/capi/qtests/vb.svg
new file mode 100644
index 0000000..7049b09
--- /dev/null
+++ b/capi/qtests/vb.svg
@@ -0,0 +1,3 @@
+<svg id="svg1" viewBox="50 100 200 400" xmlns="http://www.w3.org/2000/svg">
+ <circle id="circle1" cx="80" cy="100" r="40" fill="green" transform="scale(2)"/>
+</svg>
diff --git a/capi/src/lib.rs b/capi/src/lib.rs
index 3d31a7f..08d5dac 100644
--- a/capi/src/lib.rs
+++ b/capi/src/lib.rs
@@ -438,6 +438,20 @@ pub extern "C" fn resvg_cairo_render_to_canvas_by_id(
}
#[no_mangle]
+pub extern "C" fn resvg_is_image_empty(
+ tree: *const resvg_render_tree,
+) -> bool {
+ let tree = unsafe {
+ assert!(!tree.is_null());
+ &*tree
+ };
+
+ // The root/svg node should have at least two children.
+ // The first child is `defs` and it always present.
+ tree.0.root().children().count() > 1
+}
+
+#[no_mangle]
pub extern "C" fn resvg_get_image_size(
tree: *const resvg_render_tree,
) -> resvg_size {
@@ -473,18 +487,29 @@ pub extern "C" fn resvg_get_image_viewbox(
}
}
+
#[no_mangle]
-pub extern "C" fn resvg_is_image_empty(
+pub extern "C" fn resvg_get_image_bbox(
tree: *const resvg_render_tree,
+ bbox: *mut resvg_rect,
) -> bool {
let tree = unsafe {
assert!(!tree.is_null());
&*tree
};
- // The root/svg node should have at least two children.
- // The first child is `defs` and it always present.
- tree.0.root().children().count() > 1
+ if let Some(r) = tree.0.root().calculate_bbox() {
+ unsafe {
+ (*bbox).x = r.x();
+ (*bbox).y = r.y();
+ (*bbox).width = r.width();
+ (*bbox).height = r.height();
+ }
+
+ true
+ } else {
+ false
+ }
}
#[no_mangle]