/
SvgDecoderExample.java
173 lines (142 loc) · 4.57 KB
/
SvgDecoderExample.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.fresco.samples.showcase.imageformat.svg;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PictureDrawable;
import com.caverock.androidsvg.SVG;
import com.caverock.androidsvg.SVGParseException;
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.drawable.DrawableFactory;
import com.facebook.imagepipeline.image.BaseCloseableImage;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.image.EncodedImage;
import com.facebook.imagepipeline.image.ImageInfo;
import com.facebook.imagepipeline.image.ImmutableQualityInfo;
import com.facebook.imagepipeline.image.QualityInfo;
import javax.annotation.Nullable;
/** 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";
private static final byte[][] POSSIBLE_HEADER_TAGS = {
ImageFormatCheckerUtils.asciiBytes("<?xml")
};
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;
}
for (byte[] possibleHeaderTag : POSSIBLE_HEADER_TAGS) {
if (ImageFormatCheckerUtils.startsWithPattern(headerBytes, possibleHeaderTag)
&& ImageFormatCheckerUtils.indexOfPattern(
headerBytes, headerBytes.length, HEADER, HEADER.length)
> -1) {
return SVG_FORMAT;
}
}
return null;
}
}
public static class CloseableSvgImage extends BaseCloseableImage {
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 boolean isStateful() {
return false;
}
@Override
public int getWidth() {
return 0;
}
@Override
public int getHeight() {
return 0;
}
@Override
public QualityInfo getQualityInfo() {
return ImmutableQualityInfo.FULL_QUALITY;
}
@Override
public ImageInfo getImageInfo() {
return this;
}
}
/** 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()));
}
}
}