~fgaz/blobfox

4dbb3df432d0119de037e296cf4fc8eabcb5bbf4 — Adrien Burgun 1 year, 6 months ago 395e167
:sparkles: Flag hearts
A species/blobfox/assets/flag_ace.svg => species/blobfox/assets/flag_ace.svg +9 -0
@@ 0,0 1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="480" width="800" viewBox="0 0 128 76.8">
  <g>
    <rect height="76.8" width="128" fill="#000000" />
    <rect height="57.6" y="19.2" width="128" fill="#a3a3a3" />
    <rect height="38.4" y="38.4" width="128" fill="#ffffff" />
    <rect height="19.2" y="57.6" width="128" fill="#800080" />
  </g>
</svg>

A species/blobfox/assets/flag_demisexual.svg => species/blobfox/assets/flag_demisexual.svg +7 -0
@@ 0,0 1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 76.8">
  <path d="M 0 0 h 128 v 76.8 H 0 " fill="#D2D2D2"/>
  <path fill="#6E0070" d="M 0 0 h 128 v 44.8 H 0 "/>
  <path fill="#FFF" d="M 0 0 h 128 v 32 H 0 "/>
  <path d="M 0 0 l 48.96 38.4 L 0 76.8 "/>
</svg>

A species/blobfox/assets/flag_enby.svg => species/blobfox/assets/flag_enby.svg +9 -0
@@ 0,0 1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="480" width="800" viewBox="0 0 128 76.8">
  <g>
    <rect height="76.8" width="128" fill="#fef433" />
    <rect height="57.6" y="19.2" width="128" fill="#ffffff" />
    <rect height="38.4" y="38.4" width="128" fill="#9a59cf" />
    <rect height="19.2" y="57.6" width="128" fill="#000000" />
  </g>
</svg>

A species/blobfox/assets/flag_pan.svg => species/blobfox/assets/flag_pan.svg +6 -0
@@ 0,0 1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 76.8">
  <path fill="#21b1ff" d="M 0 0 h 128 v 76.8 H 0 z "/>
  <path fill="#ffd800" d="M 0 0 h 128 v 51.2 H 0 z "/>
  <path fill="#ff218c" d="M 0 0 h 128 v 25.6 H 0 z "/>
</svg>

A species/blobfox/assets/flag_progress.svg => species/blobfox/assets/flag_progress.svg +14 -0
@@ 0,0 1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 81.28">
  <rect fill="#750787" width="128" height="81.28"/>
  <rect fill="#004dff" height="67.73333333" width="128"/>
  <rect width="128" height="54.18666666" fill="#008026"/>
  <rect height="40.64" fill="#ffed00" width="128"/>
  <rect width="128" fill="#ff8c00" height="27.09333333"/>
  <rect width="128" fill="#e40303" height="13.54666666"/>
  <polygon fill="#ffffff" points="-0.02133333,20.48 20.26666666,40.64 -0.02133333,60.8"/>
  <polygon fill="#ffafc8" points="-0.02133333,20.48 -0.02133333,10.24 30.29333,40.64 -0.02133333,71.03999999 -0.02133333,60.8 20.26666666,40.64"/>
  <polygon fill="#74d7ee" points="-0.02133333,10.24 -0.02133333,0 40.78933333,40.64 -0.02133333,81.28 -0.02133333,71.03999999 30.29333,40.64 -0.02133333,10.24"/>
  <polygon points="-0.02133333,0 40.78933333,40.64 -0.02133333,81.28 10.24,81.28 50.85866666,40.64 10.24,0" fill="#613915"/>
  <polygon points="10.24,0 20.48,0 61.09866666,40.64 20.48,81.28 10.24,81.28 50.85866666,40.64 10.24,0" fill="#000000"/>
</svg>

M species/blobfox/species.toml => species/blobfox/species.toml +7 -0
@@ 36,3 36,10 @@ blush = ["body-basic", "ear-blush", "eyes-closed", "blush", "mouth-hmpf"]

heart = ["body-basic", "eyes-basic", "left-hand", "right-hand", "holding", "big-object"]
egg = ["body-basic", "eyes-basic", "left-hand", "right-hand", "holding"]

# Flags
heart_progress = ["body-basic", "eyes-basic", "left-hand", "right-hand", "holding", "big-object"]
heart_enby = ["body-basic", "eyes-basic", "left-hand", "right-hand", "holding", "big-object"]
heart_ace = ["body-basic", "eyes-basic", "left-hand", "right-hand", "holding", "big-object"]
heart_demisexual = ["body-basic", "eyes-basic", "left-hand", "right-hand", "holding", "big-object"]
heart_pan = ["body-basic", "eyes-basic", "left-hand", "right-hand", "holding", "big-object"]

A species/blobfox/variants/heart_ace.mustache => species/blobfox/variants/heart_ace.mustache +21 -0
@@ 0,0 1,21 @@
{{>header}}
    {{>body}}

    {{>eyes}}

    <defs>
        <clipPath id="clip-heart">
            {{#heart}}#heart{{/heart}}
        </clipPath>
    </defs>

    <g clip-path="url(#clip-heart)">
        <g transform="rotate(9) scale(1.05 1.05) translate(10 45)">
            {{#flag_ace}}{{/flag_ace}}
        </g>
    </g>

    {{#set-fill}} rgba(255,255,255,0.5) | {{#heart}}#heart-reflection{{/heart}} {{/set-fill}}

    {{>hands}}
{{>footer}}

A species/blobfox/variants/heart_demisexual.mustache => species/blobfox/variants/heart_demisexual.mustache +21 -0
@@ 0,0 1,21 @@
{{>header}}
    {{>body}}

    {{>eyes}}

    <defs>
        <clipPath id="clip-heart">
            {{#heart}}#heart{{/heart}}
        </clipPath>
    </defs>

    <g clip-path="url(#clip-heart)">
        <g transform="rotate(9) scale(1.05 1.05) translate(10 45)">
            {{#flag_demisexual}}{{/flag_demisexual}}
        </g>
    </g>

    {{#set-fill}} rgba(255,255,255,0.5) | {{#heart}}#heart-reflection{{/heart}} {{/set-fill}}

    {{>hands}}
{{>footer}}

A species/blobfox/variants/heart_enby.mustache => species/blobfox/variants/heart_enby.mustache +21 -0
@@ 0,0 1,21 @@
{{>header}}
    {{>body}}

    {{>eyes}}

    <defs>
        <clipPath id="clip-heart">
            {{#heart}}#heart{{/heart}}
        </clipPath>
    </defs>

    <g clip-path="url(#clip-heart)">
        <g transform="rotate(9) scale(1.05 1.05) translate(10 45)">
            {{#flag_enby}}{{/flag_enby}}
        </g>
    </g>

    {{#set-fill}} rgba(255,255,255,0.5) | {{#heart}}#heart-reflection{{/heart}} {{/set-fill}}

    {{>hands}}
{{>footer}}

A species/blobfox/variants/heart_pan.mustache => species/blobfox/variants/heart_pan.mustache +21 -0
@@ 0,0 1,21 @@
{{>header}}
    {{>body}}

    {{>eyes}}

    <defs>
        <clipPath id="clip-heart">
            {{#heart}}#heart{{/heart}}
        </clipPath>
    </defs>

    <g clip-path="url(#clip-heart)">
        <g transform="rotate(9) scale(1.05 1.05) translate(10 45)">
            {{#flag_pan}}{{/flag_pan}}
        </g>
    </g>

    {{#set-fill}} rgba(255,255,255,0.5) | {{#heart}}#heart-reflection{{/heart}} {{/set-fill}}

    {{>hands}}
{{>footer}}

A species/blobfox/variants/heart_progress.mustache => species/blobfox/variants/heart_progress.mustache +21 -0
@@ 0,0 1,21 @@
{{>header}}
    {{>body}}

    {{>eyes}}

    <defs>
        <clipPath id="clip-heart">
            {{#heart}}#heart{{/heart}}
        </clipPath>
    </defs>

    <g clip-path="url(#clip-heart)">
        <g transform="rotate(9) scale(0.95 0.95) translate(20 50)">
            {{#flag_progress}}{{/flag_progress}}
        </g>
    </g>

    {{#set-fill}} rgba(255,255,255,0.5) | {{#heart}}#heart-reflection{{/heart}} {{/set-fill}}

    {{>hands}}
{{>footer}}

A species/blobstella/assets/flag_pan.svg => species/blobstella/assets/flag_pan.svg +6 -0
@@ 0,0 1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 76.8">
  <path fill="#61d1ff" d="M 0 0 h 128 v 76.8 H 0 z "/> <!-- made the blue a bit lighter -->
  <path fill="#ffd800" d="M 0 0 h 128 v 51.2 H 0 z "/>
  <path fill="#ff218c" d="M 0 0 h 128 v 25.6 H 0 z "/>
</svg>

M species/blobstella/templates/body-basic.mustache => species/blobstella/templates/body-basic.mustache +8 -2
@@ 16,8 16,14 @@

{{! Marks }}
<g clip-path="url(#body-clip)">
    {{#base}}#left-marks{{/base}}
    {{#base}}#right-marks{{/base}}
    {{#set-fill}}
        {{vars.marks_color}}
        | {{#base}}#left-marks{{/base}}
    {{/set-fill}}
    {{#set-fill}}
        {{vars.marks_color}}
        | {{#base}}#right-marks{{/base}}
    {{/set-fill}}
</g>

{{! Whiskers }}

M src/bin/rescale.rs => src/bin/rescale.rs +27 -3
@@ 98,8 98,13 @@ fn rescale(element: &mut Element, scale: f64) {
        if let Some(units) = element.attributes.get_mut("document-units") {
            *units = "px".to_string();
        }
    } else if element.name == "ellipse" || element.name == "radialGradient" || element.name == "linearGradient" {
        const PROPS: [&'static str; 11] = [
    } else if
        element.name == "ellipse"
        || element.name == "radialGradient"
        || element.name == "linearGradient"
        || element.name == "rect"
    {
        const PROPS: [&'static str; 15] = [
            "cx",
            "cy",
            "rx",


@@ 110,7 115,11 @@ fn rescale(element: &mut Element, scale: f64) {
            "x1",
            "x2",
            "y1",
            "y2"
            "y2",
            "x",
            "y",
            "width",
            "height",
        ];

        for prop in PROPS {


@@ 120,6 129,21 @@ fn rescale(element: &mut Element, scale: f64) {
                }
            }
        }
    } else if element.name == "polygon" {
        if let Some(points) = element.attributes.get_mut("points") {
            let new_points = points.split_whitespace().map(|pair| {
                let parsed = pair.split(',').map(|x| x.parse::<f64>()).collect::<Vec<_>>();
                if let [Ok(x), Ok(y)] = parsed[..] {
                    format!("{},{}", x * scale, y * scale)
                } else if let [Ok(z)] = parsed[..] {
                    format!("{}", z * scale)
                } else {
                    pair.to_string()
                }
            }).collect::<Vec<_>>().join(" ");

            *points = new_points;
        }
    }

    if let Some(style) = element.attributes.get_mut("style") {

M src/template.rs => src/template.rs +19 -7
@@ 237,12 237,21 @@ impl PartialLoader for RenderingContext {
}

fn set_fill(color: &str, xml: &mut Element) {
    // Substitute the fill color
    if let Some(style) = xml.attributes.get("style") {
        xml.attributes.insert(
            "style".to_string(),
            format!("{};fill: {};", style, color),
        );
    // Substitute the fill color; TODO: handle transparency for SVG 1.1
    if let Some(style) = xml.attributes.get_mut("style") {
        let mut new_style = Vec::new();

        for rule in style.split(';') {
            if let [name, value] = rule.splitn(2, ':').collect::<Vec<_>>()[..] {
                if name.trim() != "fill" && name.trim() != "fill-opacity" {
                    new_style.push(format!("{}:{}", name, value));
                }
            }
        }

        new_style.push(format!("fill: {};", color));

        *style = new_style.join(";");
    }
    if let Some(_fill) = xml.attributes.get("fill") {
        xml.attributes.insert("fill".to_string(), color.to_string());


@@ 257,7 266,10 @@ fn set_fill(color: &str, xml: &mut Element) {

pub fn query_selector(svg: Element, pattern: &str) -> Option<Element> {
    if pattern == "" {
        return Some(svg);
        // NOTE: it looks like having a nested svg makes resvg unhappy
        let mut group = Element::new("g");
        group.children = svg.children;
        return Some(group);
    }

    for child in svg.children {