[librsvg: 1/95] Generate a PHF of SVG attribute names
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 1/95] Generate a PHF of SVG attribute names
- Date: Thu, 22 Feb 2018 03:13:13 +0000 (UTC)
commit fe3297f336b712d44e70f4a6af5f8e08f9e0c59a
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Feb 7 12:31:54 2018 -0600
Generate a PHF of SVG attribute names
We will map SVG attribute names to enum values using a Perfect Hash
Function, instead of doing string comparisons and hash table lookups
everywhere.
At build time, we generate the PHF mapping. We do this with
phf_codegen (in the build.rs script) instead of phf_macros, as the
latter cannot be used on Rust stable yet.
Makefile.am | 2 +
rust/Cargo.lock | 42 ++++++++++++-
rust/Cargo.toml | 5 ++
rust/build.rs | 156 +++++++++++++++++++++++++++++++++++++++++++++++++
rust/src/attributes.rs | 28 +++++++++
rust/src/lib.rs | 1 +
6 files changed, 231 insertions(+), 3 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index e7a7ae77..5cdf82d5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -64,7 +64,9 @@ librsvg_@RSVG_API_MAJOR_VERSION@_la_SOURCES = \
RUST_SOURCES = \
rust/Cargo.toml \
+ rust/build.rs \
rust/src/aspect_ratio.rs \
+ rust/src/attributes.rs \
rust/src/bbox.rs \
rust/src/chars.rs \
rust/src/clip_path.rs \
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
index 779a0046..f9179c55 100644
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -220,7 +220,7 @@ version = "0.7.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -248,11 +248,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand"
-version = "0.3.20"
+version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -287,6 +298,8 @@ dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"pango 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pango-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
+ "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -355,6 +368,25 @@ name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "winapi"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[metadata]
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" =
"d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" =
"b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
@@ -387,7 +419,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" =
"3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
"checksum procedural-masquerade 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" =
"dc1bcafee1590f81acb329ae45ec627b318123f085153913620316ae9a144b2a"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" =
"7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
-"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" =
"512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1"
+"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" =
"15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
+"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" =
"eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" =
"744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa"
"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" =
"8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e"
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" =
"0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
@@ -400,3 +433,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" =
"6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" =
"167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
+"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" =
"04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
+"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index 487e91d8..ad20a0d9 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -2,6 +2,10 @@
name = "rsvg_internals"
version = "0.0.1"
authors = ["Federico Mena Quintero <federico gnome org>"]
+build = "build.rs"
+
+[build-dependencies]
+phf_codegen = "0.7.21"
[dependencies]
libc = "0.2"
@@ -12,6 +16,7 @@ pango = "0.3.0"
pango-sys = "0.5.0"
cssparser = "0.23"
lazy_static = "1.0.0"
+phf = "0.7.21"
[dependencies.cairo-sys-rs]
version = "0.5.0"
diff --git a/rust/build.rs b/rust/build.rs
new file mode 100644
index 00000000..de73fc26
--- /dev/null
+++ b/rust/build.rs
@@ -0,0 +1,156 @@
+extern crate phf_codegen;
+
+use std::env;
+use std::fs::File;
+use std::io::{BufWriter, Write};
+use std::path::Path;
+
+fn main() {
+ generate_phf_of_svg_attributes();
+}
+
+/// Creates a perfect hash function (PHF) to map SVG attribute names to enum values.
+fn generate_phf_of_svg_attributes() {
+ // (attribute name, Rust enum value, C enum value suffix
+ let attribute_defs = [
+ ( "alternate", "Alternate", "ALTERNATE" ),
+ ( "amplitude", "Amplitude", "AMPLITUDE" ),
+ ( "azimuth", "Azimuth", "AZIMUTH" ),
+ ( "baseFrequency", "BaseFrequency", "BASE_FREQUENCY" ),
+ ( "baseline-shift", "BaselineShift", "BASELINE_SHIFT" ),
+ ( "bias", "Bias", "BIAS" ),
+ ( "class", "Class", "CLASS" ),
+ ( "clip-path", "ClipPath", "CLIP_PATH" ),
+ ( "clip-rule", "ClipRule", "CLIP_RULE" ),
+ ( "color", "Color", "COLOR" ),
+ ( "comp-op", "CompOp", "COMP_OP" ),
+ ( "diffuseConstant", "DiffuseConstant", "DIFFUSE_CONSTANT" ),
+ ( "direction", "Direction", "DIRECTION" ),
+ ( "display", "Display", "DISPLAY" ),
+ ( "divisor", "Divisor", "DIVISOR" ),
+ ( "dx", "Dx", "DX" ),
+ ( "dy", "Dy", "DY" ),
+ ( "edgeMode", "EdgeMode", "EDGE_MODE" ),
+ ( "elevation", "Elevation", "ELEVATION" ),
+ ( "enable-background", "EnableBackground", "ENABLE_BACKGROUND" ),
+ ( "encoding", "Encoding", "ENCODING" ),
+ ( "exponent", "Exponent", "EXPONENT" ),
+ ( "fill", "Fill", "FILL" ),
+ ( "fill-opacity", "FillOpacity", "FILL_OPACITY" ),
+ ( "fill-rule", "FillRule", "FILL_RULE" ),
+ ( "filter", "Filter", "FILTER" ),
+ ( "filterUnits", "FilterUnits", "FILTERUNITS" ),
+ ( "flood-color", "FloodColor", "FLOOD_COLOR" ),
+ ( "flood-opacity", "FloodOpacity", "FLOOD_OPACITY" ),
+ ( "font-family", "FontFamily", "FONT_FAMILY" ),
+ ( "font-size", "FontSize", "FONT_SIZE" ),
+ ( "font-stretch", "FontStretch", "FONT_STRETCH" ),
+ ( "font-style", "FontStyle", "FONT_STYLE" ),
+ ( "font-variant", "FontVariant", "FONT_VARIANT" ),
+ ( "font-weight", "FontWeight", "FONT_WEIGHT" ),
+ ( "height", "Height", "HEIGHT" ),
+ ( "href", "Href", "HREF" ),
+ ( "id", "Id", "ID" ),
+ ( "in", "In", "IN" ),
+ ( "in2", "In2", "IN2" ),
+ ( "intercept", "Intercept", "INTERCEPT" ),
+ ( "k1", "K1", "K1" ),
+ ( "k2", "K2", "K2" ),
+ ( "k3", "K3", "K3" ),
+ ( "k4", "K4", "K4" ),
+ ( "kernelMatrix", "KernelMatrix", "KERNEL_MATRIX" ),
+ ( "kernelUnitLength", "KernelUnitLength", "KERNEL_UNIT_LENGTH" ),
+ ( "letter-spacing", "LetterSpacing", "LETTER_SPACING" ),
+ ( "lighting-color", "LightingColor", "LIGHTING_COLOR" ),
+ ( "limitingConeAngle", "LimitingConeAngle", "LIMITING_CONE_ANGLE" ),
+ ( "marker", "Marker", "MARKER" ),
+ ( "marker-end", "MarkerEnd", "MARKER_END" ),
+ ( "marker-mid", "MarkerMid", "MARKER_MID" ),
+ ( "marker-start", "MarkerStart", "MARKER_START" ),
+ ( "mask", "Mask", "MASK" ),
+ ( "mode", "Mode", "MODE" ),
+ ( "numOctaves", "NumOctaves", "NUM_OCTAVES" ),
+ ( "offset", "Offset", "OFFSET" ),
+ ( "opacity", "Opacity", "OPACITY" ),
+ ( "operator", "Operator", "OPERATOR" ),
+ ( "order", "Order", "ORDER" ),
+ ( "overflow", "Overflow", "OVERFLOW" ),
+ ( "parse", "Parse", "PARSE" ),
+ ( "pointsAtX", "PointsAtX", "POINTS_AT_X" ),
+ ( "pointsAtY", "PointsAtY", "POINTS_AT_Y" ),
+ ( "pointsAtZ", "PointsAtZ", "POINTS_AT_Z" ),
+ ( "preserveAlpha", "PreserveAlpha", "PRESERVE_ALPHA" ),
+ ( "primitiveUnits", "PrimitiveUnits", "PRIMITIVE_UNITS" ),
+ ( "radius", "Radius", "RADIUS" ),
+ ( "requiredExtensions", "RequiredExtensions", "REQUIRED_EXTENSIONS" ),
+ ( "requiredFeatures", "RequiredFeatures", "REQUIRED_FEATURES" ),
+ ( "result", "Result", "RESULT" ),
+ ( "scale", "Scale", "SCALE" ),
+ ( "seed", "Seed", "SEED" ),
+ ( "shape-rendering", "ShapeRendering", "SHAPE_RENDERING" ),
+ ( "slope", "Slope", "SLOPE" ),
+ ( "specularConstant", "SpecularConstant", "SPECULAR_CONSTANT" ),
+ ( "specularExponent", "SpecularExponent", "SPECULAR_EXPONENT" ),
+ ( "stdDeviation", "StdDeviation", "STD_DEVIATION" ),
+ ( "stitchTiles", "StitchTiles", "STITCH_TILES" ),
+ ( "stop-color", "StopColor", "STOP_COLOR" ),
+ ( "stop-opacity", "StopOpacity", "STOP_OPACITY" ),
+ ( "stroke", "Stroke", "STROKE" ),
+ ( "stroke-dasharray", "StrokeDasharray", "STROKE_DASHARRAY" ),
+ ( "stroke-dashoffset", "StrokeDashoffset", "STROKE_DASHOFFSET" ),
+ ( "stroke-linecap", "StrokeLinecap", "STROKE_LINECAP" ),
+ ( "stroke-linejoin", "StrokeLinejoin", "STROKE_LINEJOIN" ),
+ ( "stroke-miterlimit", "StrokeMiterlimit", "STROKE_MITERLIMIT" ),
+ ( "stroke-opacity", "StrokeOpacity", "STROKE_OPACITY" ),
+ ( "stroke-width", "StrokeWidth", "STROKE_WIDTH" ),
+ ( "style", "Style", "STYLE" ),
+ ( "surfaceScale", "SurfaceScale", "SURFACE_SCALE" ),
+ ( "systemLanguage", "SystemLanguage", "SYSTEM_LANGUAGE" ),
+ ( "tableValues", "TableValues", "TABLE_VALUES" ),
+ ( "targetX", "TargetX", "TARGET_X" ),
+ ( "targetY", "TargetY", "TARGET_Y" ),
+ ( "text-anchor", "TextAnchor", "TEXT_ANCHOR" ),
+ ( "text-decoration", "TextDecoration", "TEXT_DECORATION" ),
+ ( "text-rendering", "TextRendering", "TEXT_RENDERING" ),
+ ( "transform", "Transform", "TRANSFORM" ),
+ ( "type", "Type", "TYPE" ),
+ ( "unicode-bidi", "UnicodeBidi", "UNICODE_BIDI" ),
+ ( "values", "Values", "VALUES" ),
+ ( "visibility", "Visibility", "VISIBILITY" ),
+ ( "width", "Width", "WIDTH" ),
+ ( "writing-mode", "WritingMode", "WRITING_MODE" ),
+ ( "x", "X", "X" ),
+ ( "xChannelSelector", "XChannelSelector", "X_CHANNEL_SELECTOR" ),
+ ( "xlink:href", "XlinkHref", "XLINK_HREF" ),
+ ( "xml:lang", "XmlLang", "XML_LANG" ),
+ ( "xml:space", "XmlSpace", "XML_SPACE" ),
+ ( "y", "Y", "Y" ),
+ ( "yChannelSelector", "YChannelSelector", "Y_CHANNEL_SELECTOR" ),
+ ( "z", "Z", "Z" ),
+ ];
+
+ let path = Path::new(&env::var("OUT_DIR").unwrap()).join("attributes-codegen.rs");
+ let mut file = BufWriter::new(File::create(&path).unwrap());
+
+ writeln!(&mut file, "#[repr(C)]").unwrap();
+ writeln!(&mut file, "#[derive(Debug, Clone, Copy, PartialEq)]").unwrap();
+ writeln!(&mut file, "pub enum Attribute {{").unwrap();
+
+ for &(_, rust, _) in attribute_defs.iter() {
+ writeln!(&mut file, " {},", rust).unwrap();
+ }
+
+ writeln!(&mut file, "}}").unwrap();
+
+ writeln!(&mut file, "static ATTRIBUTES: phf::Map<&'static str, Attribute> = ").unwrap();
+
+ let mut map = phf_codegen::Map::new();
+ map.phf_path("phf");
+ for &(name, rust, _) in attribute_defs.iter() {
+ let rust = ["Attribute::", rust].concat();
+ map.entry(name, &rust);
+ }
+
+ map.build(&mut file).unwrap();
+ writeln!(&mut file, ";").unwrap();
+}
diff --git a/rust/src/attributes.rs b/rust/src/attributes.rs
new file mode 100644
index 00000000..5c7d4c28
--- /dev/null
+++ b/rust/src/attributes.rs
@@ -0,0 +1,28 @@
+extern crate phf;
+
+use std::str::FromStr;
+
+include!(concat!(env!("OUT_DIR"), "/attributes-codegen.rs"));
+
+impl FromStr for Attribute {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Attribute, ()> {
+ ATTRIBUTES.get(s).cloned().ok_or(())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn parses_attributes() {
+ assert_eq!(Attribute::from_str("width"), Ok(Attribute::Width));
+ }
+
+ #[test]
+ fn unknown_attribute_yields_error() {
+ assert_eq!(Attribute::from_str("foobar"), Err(()));
+ }
+}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 95605b0a..1fbf438d 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -173,6 +173,7 @@ pub use viewbox::{
mod coord_units;
mod aspect_ratio;
+mod attributes;
mod bbox;
mod chars;
mod clip_path;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]