mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-06 08:22:23 +00:00
Allow int32ARGBColor and use it to represent colors instead of rgbaArray
int32ARGBColor is 0xaarrggbb format to allow no processing Optimize default fill handling Improve gradient input validation Simplify gradient extraction Use a single array to represent gradient, with two numbers per stop Reuse transform props in extractProps, short circuit identity transform. [android] Refactor ImageView, fix mLoading
This commit is contained in:
@@ -65,15 +65,13 @@ class Brush {
|
||||
}
|
||||
|
||||
private static void parseGradientStops(ReadableArray value, int stopsCount, float[] stops, int[] stopsColors, float opacity) {
|
||||
int startStops = value.size() - stopsCount;
|
||||
for (int i = 0; i < stopsCount; i++) {
|
||||
stops[i] = (float) value.getDouble(startStops + i);
|
||||
stopsColors[i] = Color.argb(
|
||||
(int) (value.getDouble(i * 4 + 3) * 255 * opacity),
|
||||
(int) (value.getDouble(i * 4) * 255),
|
||||
(int) (value.getDouble(i * 4 + 1) * 255),
|
||||
(int) (value.getDouble(i * 4 + 2) * 255));
|
||||
|
||||
int stopIndex = i * 2;
|
||||
stops[i] = (float) value.getDouble(stopIndex);
|
||||
int color = value.getInt(stopIndex + 1);
|
||||
int alpha = color >>> 24;
|
||||
int combined = Math.round((float)alpha * opacity);
|
||||
stopsColors[i] = combined << 24 | (color & 0x00ffffff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +155,7 @@ class Brush {
|
||||
return;
|
||||
}
|
||||
|
||||
int stopsCount = mColors.size() / 5;
|
||||
int stopsCount = mColors.size() / 2;
|
||||
int[] stopsColors = new int[stopsCount];
|
||||
float[] stops = new float[stopsCount];
|
||||
parseGradientStops(mColors, stopsCount, stops, stopsColors, opacity);
|
||||
|
||||
@@ -23,11 +23,11 @@ import com.facebook.common.logging.FLog;
|
||||
import com.facebook.common.references.CloseableReference;
|
||||
import com.facebook.datasource.DataSource;
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.facebook.imagepipeline.core.ImagePipeline;
|
||||
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
|
||||
import com.facebook.imagepipeline.image.CloseableBitmap;
|
||||
import com.facebook.imagepipeline.image.CloseableImage;
|
||||
import com.facebook.imagepipeline.request.ImageRequest;
|
||||
import com.facebook.imagepipeline.request.ImageRequestBuilder;
|
||||
import com.facebook.react.bridge.Dynamic;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
@@ -121,13 +121,15 @@ class ImageView extends RenderableView {
|
||||
@Override
|
||||
void draw(final Canvas canvas, final Paint paint, final float opacity) {
|
||||
if (!mLoading.get()) {
|
||||
final ImageSource imageSource = new ImageSource(mContext, uriString);
|
||||
ImagePipeline imagePipeline = Fresco.getImagePipeline();
|
||||
ImageSource imageSource = new ImageSource(mContext, uriString);
|
||||
ImageRequest request = ImageRequest.fromUri(imageSource.getUri());
|
||||
boolean inMemoryCache = imagePipeline.isInBitmapMemoryCache(request);
|
||||
|
||||
final ImageRequest request = ImageRequestBuilder.newBuilderWithSource(imageSource.getUri()).build();
|
||||
if (Fresco.getImagePipeline().isInBitmapMemoryCache(request)) {
|
||||
tryRender(request, canvas, paint, opacity * mOpacity);
|
||||
if (inMemoryCache) {
|
||||
tryRenderFromBitmapCache(imagePipeline, request, canvas, paint, opacity * mOpacity);
|
||||
} else {
|
||||
loadBitmap(request);
|
||||
loadBitmap(imagePipeline, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,29 +141,29 @@ class ImageView extends RenderableView {
|
||||
return path;
|
||||
}
|
||||
|
||||
private void loadBitmap(ImageRequest request) {
|
||||
private void loadBitmap(final ImagePipeline imagePipeline, final ImageRequest request) {
|
||||
mLoading.set(true);
|
||||
final DataSource<CloseableReference<CloseableImage>> dataSource
|
||||
= Fresco.getImagePipeline().fetchDecodedImage(request, mContext);
|
||||
dataSource.subscribe(new BaseBitmapDataSubscriber() {
|
||||
@Override
|
||||
public void onNewResultImpl(Bitmap bitmap) {
|
||||
mLoading.set(false);
|
||||
SvgView view = getSvgView();
|
||||
if (view != null) {
|
||||
view.invalidate();
|
||||
}
|
||||
}
|
||||
= imagePipeline.fetchDecodedImage(request, mContext);
|
||||
BaseBitmapDataSubscriber subscriber = new BaseBitmapDataSubscriber() {
|
||||
@Override
|
||||
public void onNewResultImpl(Bitmap bitmap) {
|
||||
mLoading.set(false);
|
||||
SvgView view = getSvgView();
|
||||
if (view != null) {
|
||||
view.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailureImpl(DataSource dataSource) {
|
||||
// No cleanup required here.
|
||||
// TODO: more details about this failure
|
||||
mLoading.set(false);
|
||||
FLog.w(ReactConstants.TAG, dataSource.getFailureCause(), "RNSVG: fetchDecodedImage failed!");
|
||||
}
|
||||
},
|
||||
UiThreadImmediateExecutorService.getInstance()
|
||||
);
|
||||
@Override
|
||||
public void onFailureImpl(DataSource dataSource) {
|
||||
// No cleanup required here.
|
||||
// TODO: more details about this failure
|
||||
mLoading.set(false);
|
||||
FLog.w(ReactConstants.TAG, dataSource.getFailureCause(), "RNSVG: fetchDecodedImage failed!");
|
||||
}
|
||||
};
|
||||
dataSource.subscribe(subscriber, UiThreadImmediateExecutorService.getInstance());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@@ -177,7 +179,7 @@ class ImageView extends RenderableView {
|
||||
h = mImageHeight * mScale;
|
||||
}
|
||||
|
||||
return new RectF((float)x, (float)y, (float)(x + w), (float)(y + h));
|
||||
return new RectF((float) x, (float) y, (float) (x + w), (float) (y + h));
|
||||
}
|
||||
|
||||
private void doRender(Canvas canvas, Paint paint, Bitmap bitmap, float opacity) {
|
||||
@@ -212,27 +214,37 @@ class ImageView extends RenderableView {
|
||||
this.setClientRect(vbRect);
|
||||
}
|
||||
|
||||
private void tryRender(ImageRequest request, Canvas canvas, Paint paint, float opacity) {
|
||||
private void tryRenderFromBitmapCache(ImagePipeline imagePipeline, ImageRequest request, Canvas canvas, Paint paint, float opacity) {
|
||||
final DataSource<CloseableReference<CloseableImage>> dataSource
|
||||
= Fresco.getImagePipeline().fetchImageFromBitmapCache(request, mContext);
|
||||
= imagePipeline.fetchImageFromBitmapCache(request, mContext);
|
||||
|
||||
try {
|
||||
final CloseableReference<CloseableImage> imageReference = dataSource.getResult();
|
||||
if (imageReference != null) {
|
||||
try {
|
||||
if (imageReference.get() instanceof CloseableBitmap) {
|
||||
final Bitmap bitmap = ((CloseableBitmap) imageReference.get()).getUnderlyingBitmap();
|
||||
|
||||
if (bitmap != null) {
|
||||
doRender(canvas, paint, bitmap, opacity);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
} finally {
|
||||
CloseableReference.closeSafely(imageReference);
|
||||
}
|
||||
if (imageReference == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
CloseableImage closeableImage = imageReference.get();
|
||||
if (!(closeableImage instanceof CloseableBitmap)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CloseableBitmap closeableBitmap = (CloseableBitmap) closeableImage;
|
||||
final Bitmap bitmap = closeableBitmap.getUnderlyingBitmap();
|
||||
|
||||
if (bitmap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
doRender(canvas, paint, bitmap, opacity);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
} finally {
|
||||
CloseableReference.closeSafely(imageReference);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
} finally {
|
||||
|
||||
@@ -403,12 +403,19 @@ abstract public class RenderableView extends VirtualView {
|
||||
int colorType = colors.getInt(0);
|
||||
switch (colorType) {
|
||||
case 0:
|
||||
// solid color
|
||||
paint.setARGB(
|
||||
(int) (colors.size() > 4 ? colors.getDouble(4) * opacity * 255 : opacity * 255),
|
||||
(int) (colors.getDouble(1) * 255),
|
||||
(int) (colors.getDouble(2) * 255),
|
||||
(int) (colors.getDouble(3) * 255));
|
||||
if (colors.size() == 2) {
|
||||
int color = colors.getInt(1);
|
||||
int alpha = color >>> 24;
|
||||
int combined = Math.round((float)alpha * opacity);
|
||||
paint.setColor(combined << 24 | (color & 0x00ffffff));
|
||||
} else {
|
||||
// solid color
|
||||
paint.setARGB(
|
||||
(int) (colors.size() > 4 ? colors.getDouble(4) * opacity * 255 : opacity * 255),
|
||||
(int) (colors.getDouble(1) * 255),
|
||||
(int) (colors.getDouble(2) * 255),
|
||||
(int) (colors.getDouble(3) * 255));
|
||||
}
|
||||
break;
|
||||
case 1: {
|
||||
Brush brush = getSvgView().getDefinedBrush(colors.getString(1));
|
||||
|
||||
Reference in New Issue
Block a user