Yet Another [à compléter]

XamSvg, Managed SVG Support for Android

As part of the new release of Moyeu, I’m also finally publishing a library that I have been using for some time.

This library is called XamSvg and in a nutshell it’s a managed (partial) implementation of an SVG parser/renderer for, currently only, Xamarin.Android.

The idea stems from the fact that Android has by default no serious way to do scalable graphics in a world with an exploding amount of device densities.

SVG appeared as a good fit because it’s easy to parse (XML), text-based (compress well) and fit well with the Android graphics API. It’s also incidentally the format used by the lovely Inkscape which makes my work even easier.

Before anyone gets their hopes high and starts throwing fancy SVG tigers at the library, know that this is by no mean meant to be a complete implementation of the standard.

As described in the README, the goal is to provide a minimum viable product™ to support traditional shape-based icons.

Still, I haven’t had any problem parsing all the SVG that I have created as almost all the icons in Moyeu are entirely SVG based. In general, if you follow the exporting guide in the README you should be fine.

The other good thing about the library is that it’s very simple to use. You will generally use only one class, SvgFactory and its two methods GetBitmap / GetDrawable:

var bmp = SvgFactory.GetBitmap (Activity.Resources, Resource.Raw.ic_svg, 48, 48);
var drawable = SvgFactory.GetDrawable (Activity.Resources, Resource.Raw.ic_svg);

I recommend the second form as the returned drawable will automatically scale depending on the bounds requested. This means that if you have an ImageView set up using dp units like this:

<ImageView
    android:layout_width="14dp"
    android:layout_height="9dp"
    android:scaleType="fitXY" />

The displayed image will look the same crispy crispness on every devices no matter how many pixel per inches they have.

Another cool thing about the library is that it lets you dynamically adapt colors at runtime. To do so, you need to provide an implementation of the ISvgColorMapper interface which sports the single method Color MapColor (Color c) (instance that can also be retrieved from a Func<Color, Color>).

I use this tricks for the pins that are displayed by Moyeu on the map. Concretely, the pins are all the same base SVG:

On which I can apply tinting with my color mapper:

Color ColorReplacer (Color inColor, float ratio)
{
	Color tone = InterpolateColor (baseLightRedColor, baseLightGreenColor, ratio);
	Color result = inColor;

	if (inColor == fillColor)
		result = tone;
	else if (inColor == borderColor)
		result = Lighten (tone, 0x20);
	else if (inColor == bottomFillColor)
		result = InterpolateColor (baseDarkRedColor, baseDarkGreenColor, ratio);

	return result;
}

In order to have a multi-colored view of the world:

You can find more usage sample of the library in Moyeu source code.