feat: add FeOffset filter (#2361)

# Summary

Continuation of #2316
Introducing new filter `FeOffset`.

## Test Plan

Example app -> Filters -> FeOffset

## Compatibility

| OS      | Implemented |
| ------- | :---------: |
| iOS     |         |
| Android |         |

## Checklist

- [x] I have tested this on a device and a simulator
- [x] I added documentation in `README.md`
- [x] I updated the typed files (typescript)
This commit is contained in:
Jakub Grzywacz
2024-07-25 12:32:15 +02:00
committed by GitHub
parent 44254df9fb
commit 5807f2c1a6
23 changed files with 507 additions and 5 deletions

View File

@@ -0,0 +1,50 @@
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import java.util.HashMap;
@SuppressLint("ViewConstructor")
class FeOffsetView extends FilterPrimitiveView {
String mIn1;
SVGLength mDx;
SVGLength mDy;
public FeOffsetView(ReactContext reactContext) {
super(reactContext);
}
public void setIn1(String in1) {
this.mIn1 = in1;
invalidate();
}
public void setDx(Dynamic dx) {
mDx = SVGLength.from(dx);
invalidate();
}
public void setDy(Dynamic dy) {
mDy = SVGLength.from(dy);
invalidate();
}
@Override
public Bitmap applyFilter(HashMap<String, Bitmap> resultsMap, Bitmap prevResult) {
Bitmap source = getSource(resultsMap, prevResult, this.mIn1);
Bitmap result =
Bitmap.createBitmap(prevResult.getWidth(), prevResult.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
float dx = this.mDx != null ? (float) this.relativeOnWidth(this.mDx) : 0;
float dy = this.mDy != null ? (float) this.relativeOnHeight(this.mDy) : 0;
canvas.drawBitmap(source, dx, dy, new Paint());
return result;
}
}

View File

@@ -107,6 +107,8 @@ import com.facebook.react.viewmanagers.RNSVGFeColorMatrixManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGFeColorMatrixManagerInterface;
import com.facebook.react.viewmanagers.RNSVGFeGaussianBlurManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGFeGaussianBlurManagerInterface;
import com.facebook.react.viewmanagers.RNSVGFeOffsetManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGFeOffsetManagerInterface;
import com.facebook.react.viewmanagers.RNSVGFilterManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGFilterManagerInterface;
import com.facebook.react.viewmanagers.RNSVGForeignObjectManagerDelegate;
@@ -587,6 +589,7 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
RNSVGFilter,
RNSVGFeColorMatrix,
RNSVGFeGaussianBlur,
RNSVGFeOffset,
RNSVGMarker,
RNSVGForeignObject,
}
@@ -637,6 +640,8 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
return new FeColorMatrixView(reactContext);
case RNSVGFeGaussianBlur:
return new FeGaussianBlurView(reactContext);
case RNSVGFeOffset:
return new FeOffsetView(reactContext);
case RNSVGMarker:
return new MarkerView(reactContext);
case RNSVGForeignObject:
@@ -1447,6 +1452,56 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class FeOffsetManager extends VirtualViewManager<FeOffsetView>
implements RNSVGFeOffsetManagerInterface<FeOffsetView> {
FeOffsetManager() {
super(SVGClass.RNSVGFeOffset);
mDelegate = new RNSVGFeOffsetManagerDelegate(this);
}
public static final String REACT_CLASS = "RNSVGFeOffset";
@ReactProp(name = "x")
public void setX(FeOffsetView node, Dynamic x) {
node.setX(x);
}
@ReactProp(name = "y")
public void setY(FeOffsetView node, Dynamic y) {
node.setY(y);
}
@ReactProp(name = "width")
public void setWidth(FeOffsetView node, Dynamic width) {
node.setWidth(width);
}
@ReactProp(name = "height")
public void setHeight(FeOffsetView node, Dynamic height) {
node.setHeight(height);
}
@ReactProp(name = "result")
public void setResult(FeOffsetView node, String result) {
node.setResult(result);
}
@ReactProp(name = "in1")
public void setIn1(FeOffsetView node, String in1) {
node.setIn1(in1);
}
@ReactProp(name = "dx")
public void setDx(FeOffsetView node, Dynamic dx) {
node.setDx(dx);
}
@ReactProp(name = "dy")
public void setDy(FeOffsetView node, Dynamic dy) {
node.setDy(dy);
}
}
static class ForeignObjectManager extends GroupViewManagerAbstract<ForeignObjectView>
implements RNSVGForeignObjectManagerInterface<ForeignObjectView> {
ForeignObjectManager() {

View File

@@ -232,6 +232,15 @@ public class SvgPackage extends TurboReactPackage implements ViewManagerOnDemand
return new FeGaussianBlurManager();
}
}));
specs.put(
FeOffsetManager.REACT_CLASS,
ModuleSpec.viewManagerSpec(
new Provider<NativeModule>() {
@Override
public NativeModule get() {
return new FeOffsetManager();
}
}));
specs.put(
ForeignObjectManager.REACT_CLASS,
ModuleSpec.viewManagerSpec(

View File

@@ -0,0 +1,53 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaDelegate.js
*/
package com.facebook.react.viewmanagers;
import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.DynamicFromObject;
import com.facebook.react.uimanager.BaseViewManagerDelegate;
import com.facebook.react.uimanager.BaseViewManagerInterface;
public class RNSVGFeOffsetManagerDelegate<T extends View, U extends BaseViewManagerInterface<T> & RNSVGFeOffsetManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
public RNSVGFeOffsetManagerDelegate(U viewManager) {
super(viewManager);
}
@Override
public void setProperty(T view, String propName, @Nullable Object value) {
switch (propName) {
case "x":
mViewManager.setX(view, new DynamicFromObject(value));
break;
case "y":
mViewManager.setY(view, new DynamicFromObject(value));
break;
case "width":
mViewManager.setWidth(view, new DynamicFromObject(value));
break;
case "height":
mViewManager.setHeight(view, new DynamicFromObject(value));
break;
case "result":
mViewManager.setResult(view, value == null ? null : (String) value);
break;
case "in1":
mViewManager.setIn1(view, value == null ? null : (String) value);
break;
case "dx":
mViewManager.setDx(view, new DynamicFromObject(value));
break;
case "dy":
mViewManager.setDy(view, new DynamicFromObject(value));
break;
default:
super.setProperty(view, propName, value);
}
}
}

View File

@@ -0,0 +1,25 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsJavaInterface.js
*/
package com.facebook.react.viewmanagers;
import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.Dynamic;
public interface RNSVGFeOffsetManagerInterface<T extends View> {
void setX(T view, Dynamic value);
void setY(T view, Dynamic value);
void setWidth(T view, Dynamic value);
void setHeight(T view, Dynamic value);
void setResult(T view, @Nullable String value);
void setIn1(T view, @Nullable String value);
void setDx(T view, Dynamic value);
void setDy(T view, Dynamic value);
}