/*
* This file provided by Facebook is for non-commercial testing and evaluation
* purposes only. Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.facebook.fresco.samples.showcase.imageformat.svg;
import javax.annotation.Nullable;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PictureDrawable;
import com.facebook.drawee.backends.pipeline.DrawableFactory;
import com.facebook.imageformat.ImageFormat;
import com.facebook.imageformat.ImageFormatCheckerUtils;
import com.facebook.imagepipeline.common.ImageDecodeOptions;
import com.facebook.imagepipeline.decoder.ImageDecoder;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.image.EncodedImage;
import com.facebook.imagepipeline.image.QualityInfo;
import com.caverock.androidsvg.SVG;
import com.caverock.androidsvg.SVGParseException;
/**
* SVG example that defines all classes required to decode and render SVG images.
*/
public class SvgDecoderExample {
public static final ImageFormat SVG_FORMAT = new ImageFormat("SVG_FORMAT", "svg");
// We do not include the closing ">" since there can be additional information
private static final String HEADER_TAG = "<svg";
public static class SvgFormatChecker implements ImageFormat.FormatChecker {
public static final byte[] HEADER = ImageFormatCheckerUtils.asciiBytes(HEADER_TAG);
@Override
public int getHeaderSize() {
return HEADER.length;
}
@Nullable
@Override
public ImageFormat determineFormat(byte[] headerBytes, int headerSize) {
if (headerSize < getHeaderSize()) {
return null;
}
if (ImageFormatCheckerUtils.startsWithPattern(headerBytes, HEADER)) {
return SVG_FORMAT;
}
return null;
}
}
public static class CloseableSvgImage extends CloseableImage {
private final SVG mSvg;
private boolean mClosed = false;
public CloseableSvgImage(SVG svg) {
mSvg = svg;
}
public SVG getSvg() {
return mSvg;
}
@Override
public int getSizeInBytes() {
return 0;
}
@Override
public void close() {
mClosed = true;
}
@Override
public boolean isClosed() {
return mClosed;
}
@Override
public int getWidth() {
return 0;
}
@Override
public int getHeight() {
return 0;
}
}
/**
* Decodes a SVG_FORMAT image
*/
public static class SvgDecoder implements ImageDecoder {
@Override
public CloseableImage decode(
EncodedImage encodedImage,
int length,
QualityInfo qualityInfo,
ImageDecodeOptions options) {
try {
SVG svg = SVG.getFromInputStream(encodedImage.getInputStream());
return new CloseableSvgImage(svg);
} catch (SVGParseException e) {
e.printStackTrace();
}
return null;
}
}
/**
* SVG drawable factory that creates {@link PictureDrawable}s for SVG images.
*/
public static class SvgDrawableFactory implements DrawableFactory {
@Override
public boolean supportsImageType(CloseableImage image) {
return image instanceof CloseableSvgImage;
}
@Nullable
@Override
public Drawable createDrawable(CloseableImage image) {
return new SvgPictureDrawable(((CloseableSvgImage) image).getSvg());
}
}
public static class SvgPictureDrawable extends PictureDrawable {
private final SVG mSvg;
public SvgPictureDrawable(SVG svg) {
super(null);
mSvg = svg;
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
setPicture(mSvg.renderToPicture(bounds.width(), bounds.height()));
}
}
}