[librsvg: 3/5] Move rsvg_css_parse_color() and its machinery to librsvg_c_api
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 3/5] Move rsvg_css_parse_color() and its machinery to librsvg_c_api
- Date: Tue, 14 Jan 2020 17:57:53 +0000 (UTC)
commit 3b235a3bd8b71636787fe4fe920b1105586096fd
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Jan 14 10:47:46 2020 -0600
Move rsvg_css_parse_color() and its machinery to librsvg_c_api
This is only used by rsvg-convert now; no need to have it in the main
internals library.
Makefile.am | 1 +
librsvg/color_utils.rs | 186 ++++++++++++++++++++++++++++++++++++++++++++
librsvg/lib.rs | 3 +
rsvg_internals/src/color.rs | 186 --------------------------------------------
rsvg_internals/src/lib.rs | 6 +-
5 files changed, 194 insertions(+), 188 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index d2ab8a3e..c51b2e1d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -117,6 +117,7 @@ LIBRSVG_CRATE_SRC = \
LIBRSVG_C_API_SRC = \
librsvg/Cargo.toml \
librsvg/c_api.rs \
+ librsvg/color_utils.rs \
librsvg/lib.rs \
librsvg/pixbuf_utils.rs \
$(NULL)
diff --git a/librsvg/color_utils.rs b/librsvg/color_utils.rs
new file mode 100644
index 00000000..be8d12c9
--- /dev/null
+++ b/librsvg/color_utils.rs
@@ -0,0 +1,186 @@
+use libc;
+
+use std::ffi::CStr;
+
+use rsvg_internals::{Color, Parse, ParseError};
+
+// There are two quirks here:
+//
+// First, we need to expose the Color algebraic type *and* a parse
+// error to C, but we can't repr(C) them plainly. So, we define a
+// ColorKind enum and a ColorSpec struct that can both be represented
+// in C.
+//
+// Second, the C code in librsvg expects ARGB colors passed around as
+// guint32. However, in Rust we'd prefer to use cssparser's RGBA
+// structure, which has explicit fields for red/green/blue/alpha.
+// We'll do those conversions here, for the benefit of the C code, and
+// then just wait until the C code gradually disappears.
+
+// Keep this in sync with rsvg-css.h:RsvgCssColorKind
+#[repr(C)]
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub enum ColorKind {
+ ARGB,
+ ParseError,
+}
+
+// Keep this in sync with rsvg-css.h:RsvgCssColorSpec
+#[repr(C)]
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub struct ColorSpec {
+ kind: ColorKind,
+ argb: u32,
+}
+
+fn rgba_to_argb(r: u8, g: u8, b: u8, a: u8) -> u32 {
+ u32::from(a) << 24 | u32::from(r) << 16 | u32::from(g) << 8 | u32::from(b)
+}
+
+impl<'i> From<Result<Color, ParseError<'i>>> for ColorSpec {
+ fn from(result: Result<Color, ParseError<'i>>) -> ColorSpec {
+ match result {
+ Ok(Color::RGBA(rgba)) => ColorSpec {
+ kind: ColorKind::ARGB,
+ argb: rgba_to_argb(rgba.red, rgba.green, rgba.blue, rgba.alpha),
+ },
+
+ _ => ColorSpec {
+ kind: ColorKind::ParseError,
+ argb: 0,
+ },
+ }
+ }
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn rsvg_css_parse_color(string: *const libc::c_char) -> ColorSpec {
+ let s = CStr::from_ptr(string).to_string_lossy();
+
+ ColorSpec::from(<Color as Parse>::parse_str(&s))
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use glib::translate::*;
+
+ fn parse(s: &str) -> ColorSpec {
+ unsafe { rsvg_css_parse_color(s.to_glib_none().0) }
+ }
+
+ #[test]
+ fn parses_hash_hex_colors() {
+ assert_eq!(
+ parse("#AB10fa20"),
+ ColorSpec {
+ kind: ColorKind::ARGB,
+ argb: 0x20ab10fa,
+ }
+ );
+ assert_eq!(
+ parse("#10fa20"),
+ ColorSpec {
+ kind: ColorKind::ARGB,
+ argb: 0xff10fa20,
+ }
+ );
+ assert_eq!(
+ parse("#abcd"),
+ ColorSpec {
+ kind: ColorKind::ARGB,
+ argb: 0xddaabbcc,
+ }
+ );
+ assert_eq!(
+ parse("#123"),
+ ColorSpec {
+ kind: ColorKind::ARGB,
+ argb: 0xff112233,
+ }
+ );
+ }
+
+ #[test]
+ fn parses_color_keywords() {
+ assert_eq!(
+ parse("red"),
+ ColorSpec {
+ kind: ColorKind::ARGB,
+ argb: 0xffff0000,
+ }
+ );
+ assert_eq!(
+ parse("lime"),
+ ColorSpec {
+ kind: ColorKind::ARGB,
+ argb: 0xff00ff00,
+ }
+ );
+ assert_eq!(
+ parse("blue"),
+ ColorSpec {
+ kind: ColorKind::ARGB,
+ argb: 0xff0000ff,
+ }
+ );
+ }
+
+ #[test]
+ fn parses_color_functions() {
+ assert_eq!(
+ parse("rgb(255, 0, 0)"),
+ ColorSpec {
+ kind: ColorKind::ARGB,
+ argb: 0xffff0000,
+ }
+ );
+ assert_eq!(
+ parse("rgb(0, 255, 0)"),
+ ColorSpec {
+ kind: ColorKind::ARGB,
+ argb: 0xff00ff00,
+ }
+ );
+ assert_eq!(
+ parse("rgb(0, 0, 255)"),
+ ColorSpec {
+ kind: ColorKind::ARGB,
+ argb: 0xff0000ff,
+ }
+ );
+ }
+
+ #[test]
+ fn current_color_is_error() {
+ assert_eq!(
+ parse("currentColor"),
+ ColorSpec {
+ kind: ColorKind::ParseError,
+ argb: 0,
+ }
+ );
+ }
+
+ fn make_error() -> ColorSpec {
+ ColorSpec {
+ kind: ColorKind::ParseError,
+ argb: 0,
+ }
+ }
+
+ #[test]
+ fn invalid_hash_hex_colors_yield_error() {
+ assert_eq!(parse("#"), make_error());
+ assert_eq!(parse("#xyz"), make_error());
+ assert_eq!(parse("#112233gg"), make_error());
+ }
+
+ #[test]
+ fn invalid_colors_yield_error() {
+ assert_eq!(parse(""), make_error());
+ assert_eq!(parse("foo"), make_error());
+ assert_eq!(parse("rgb(chilaquil)"), make_error());
+ assert_eq!(parse("rgb(1, 2, 3, 4, 5)"), make_error());
+ }
+}
diff --git a/librsvg/lib.rs b/librsvg/lib.rs
index 770ea939..60efd427 100644
--- a/librsvg/lib.rs
+++ b/librsvg/lib.rs
@@ -38,6 +38,8 @@ pub use crate::c_api::{
rsvg_rust_handle_write,
};
+pub use crate::color_utils::rsvg_css_parse_color;
+
pub use crate::pixbuf_utils::{
rsvg_rust_pixbuf_from_file_at_max_size,
rsvg_rust_pixbuf_from_file_at_size,
@@ -46,4 +48,5 @@ pub use crate::pixbuf_utils::{
};
mod c_api;
+mod color_utils;
mod pixbuf_utils;
diff --git a/rsvg_internals/src/color.rs b/rsvg_internals/src/color.rs
index 3807075c..b83b76f4 100644
--- a/rsvg_internals/src/color.rs
+++ b/rsvg_internals/src/color.rs
@@ -1,11 +1,9 @@
//! CSS color values.
use cssparser::Parser;
-use libc;
use crate::error::*;
use crate::parsers::Parse;
-use crate::util::utf8_cstr;
pub use cssparser::Color;
@@ -27,187 +25,3 @@ impl Parse for cssparser::RGBA {
}
}
}
-
-// There are two quirks here:
-//
-// First, we need to expose the Color algebraic type *and* a parse
-// error to C, but we can't repr(C) them plainly. So, we define a
-// ColorKind enum and a ColorSpec struct that can both be represented
-// in C.
-//
-// Second, the C code in librsvg expects ARGB colors passed around as
-// guint32. However, in Rust we'd prefer to use cssparser's RGBA
-// structure, which has explicit fields for red/green/blue/alpha.
-// We'll do those conversions here, for the benefit of the C code, and
-// then just wait until the C code gradually disappears.
-
-// Keep this in sync with rsvg-css.h:RsvgCssColorKind
-#[repr(C)]
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub enum ColorKind {
- ARGB,
- ParseError,
-}
-
-// Keep this in sync with rsvg-css.h:RsvgCssColorSpec
-#[repr(C)]
-#[derive(Clone, Copy, PartialEq, Debug)]
-pub struct ColorSpec {
- kind: ColorKind,
- argb: u32,
-}
-
-fn rgba_to_argb(rgba: cssparser::RGBA) -> u32 {
- u32::from(rgba.alpha) << 24
- | u32::from(rgba.red) << 16
- | u32::from(rgba.green) << 8
- | u32::from(rgba.blue)
-}
-
-impl<'i> From<Result<cssparser::Color, ParseError<'i>>> for ColorSpec {
- fn from(result: Result<cssparser::Color, ParseError<'i>>) -> ColorSpec {
- match result {
- Ok(cssparser::Color::RGBA(rgba)) => ColorSpec {
- kind: ColorKind::ARGB,
- argb: rgba_to_argb(rgba),
- },
-
- _ => ColorSpec {
- kind: ColorKind::ParseError,
- argb: 0,
- },
- }
- }
-}
-
-#[no_mangle]
-pub extern "C" fn rsvg_css_parse_color(string: *const libc::c_char) -> ColorSpec {
- let s = unsafe { utf8_cstr(string) };
-
- ColorSpec::from(<Color as Parse>::parse_str(s))
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use glib::translate::*;
-
- fn parse(s: &str) -> ColorSpec {
- rsvg_css_parse_color(s.to_glib_none().0)
- }
-
- #[test]
- fn parses_hash_hex_colors() {
- assert_eq!(
- parse("#AB10fa20"),
- ColorSpec {
- kind: ColorKind::ARGB,
- argb: 0x20ab10fa,
- }
- );
- assert_eq!(
- parse("#10fa20"),
- ColorSpec {
- kind: ColorKind::ARGB,
- argb: 0xff10fa20,
- }
- );
- assert_eq!(
- parse("#abcd"),
- ColorSpec {
- kind: ColorKind::ARGB,
- argb: 0xddaabbcc,
- }
- );
- assert_eq!(
- parse("#123"),
- ColorSpec {
- kind: ColorKind::ARGB,
- argb: 0xff112233,
- }
- );
- }
-
- #[test]
- fn parses_color_keywords() {
- assert_eq!(
- parse("red"),
- ColorSpec {
- kind: ColorKind::ARGB,
- argb: 0xffff0000,
- }
- );
- assert_eq!(
- parse("lime"),
- ColorSpec {
- kind: ColorKind::ARGB,
- argb: 0xff00ff00,
- }
- );
- assert_eq!(
- parse("blue"),
- ColorSpec {
- kind: ColorKind::ARGB,
- argb: 0xff0000ff,
- }
- );
- }
-
- #[test]
- fn parses_color_functions() {
- assert_eq!(
- parse("rgb(255, 0, 0)"),
- ColorSpec {
- kind: ColorKind::ARGB,
- argb: 0xffff0000,
- }
- );
- assert_eq!(
- parse("rgb(0, 255, 0)"),
- ColorSpec {
- kind: ColorKind::ARGB,
- argb: 0xff00ff00,
- }
- );
- assert_eq!(
- parse("rgb(0, 0, 255)"),
- ColorSpec {
- kind: ColorKind::ARGB,
- argb: 0xff0000ff,
- }
- );
- }
-
- #[test]
- fn current_color_is_error() {
- assert_eq!(
- parse("currentColor"),
- ColorSpec {
- kind: ColorKind::ParseError,
- argb: 0,
- }
- );
- }
-
- fn make_error() -> ColorSpec {
- ColorSpec {
- kind: ColorKind::ParseError,
- argb: 0,
- }
- }
-
- #[test]
- fn invalid_hash_hex_colors_yield_error() {
- assert_eq!(parse("#"), make_error());
- assert_eq!(parse("#xyz"), make_error());
- assert_eq!(parse("#112233gg"), make_error());
- }
-
- #[test]
- fn invalid_colors_yield_error() {
- assert_eq!(parse(""), make_error());
- assert_eq!(parse("foo"), make_error());
- assert_eq!(parse("rgb(chilaquil)"), make_error());
- assert_eq!(parse("rgb(1, 2, 3, 4, 5)"), make_error());
- }
-}
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 4fc29d48..d8075c3f 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -40,11 +40,11 @@
#![warn(unused)]
use ::xml as xml_rs;
-pub use crate::color::{rsvg_css_parse_color, ColorKind, ColorSpec};
+pub use crate::color::Color;
pub use crate::dpi::{rsvg_rust_set_default_dpi_x_y, Dpi};
-pub use crate::error::{DefsLookupErrorKind, HrefError, LoadingError, RenderingError};
+pub use crate::error::{DefsLookupErrorKind, HrefError, LoadingError, ParseError, RenderingError};
pub use crate::handle::{
Handle, LoadOptions, RsvgDimensionData, RsvgPositionData, RsvgSizeFunc, SizeCallback,
@@ -52,6 +52,8 @@ pub use crate::handle::{
pub use crate::length::{Length, LengthUnit, RsvgLength};
+pub use crate::parsers::Parse;
+
pub use crate::rect::IRect;
pub use crate::structure::IntrinsicDimensions;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]