chore: add CI for JS, iOS and Android formatting (#1782)

Added CI workflow and local pre-commit hook for formatting and linting the newly added JS, iOS and Android code.
This commit is contained in:
Wojciech Lewicki
2022-08-16 12:00:32 +02:00
committed by GitHub
parent 77267be5fc
commit 98c14b4f45
177 changed files with 16855 additions and 16018 deletions

91
.clang-format Normal file
View File

@@ -0,0 +1,91 @@
---
AccessModifierOffset: -1
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: true
AlignOperands: false
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ForEachMacros: [ FOR_EACH_RANGE, FOR_EACH, ]
IncludeCategories:
- Regex: '^<.*\.h(pp)?>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IndentCaseLabels: true
IndentWidth: 2
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
---
Language: ObjC
ColumnLimit: 120
BreakBeforeBraces: WebKit
...

View File

@@ -25,10 +25,8 @@ jobs:
run: yarn
- name: Build
run: yarn bob
- name: Lint
run: yarn lint
- name: Tests
run: yarn jest
- name: Test and lint
run: yarn test
- name: Build Example App
working-directory: Example/
run: yarn && yarn tsc

4
.husky/pre-commit Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
yarn lint-staged

View File

@@ -501,7 +501,7 @@ SPEC CHECKSUMS:
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
FBLazyVector: bcdeff523be9f87a135b7c6fde8736db94904716
FBReactNativeSpec: 226f8b0f1a2e736a49301883ee34bca88cdc24f6
FBReactNativeSpec: 0c3f104f594b34d7b3a923cd12e03b0d4e12eaf5
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
Flipper-DoubleConversion: 57ffbe81ef95306cc9e69c4aa3aeeeeb58a6a28c

View File

@@ -112,7 +112,7 @@ export default function TestComponent() {
onError={onError}
onLoad={onLoad}
/>
{loading && <ActivityIndicator size="large" color="#0000ff"/>}
{loading && <ActivityIndicator size="large" color="#0000ff" />}
</>
);
}
@@ -129,16 +129,20 @@ import * as React from 'react';
import { SvgUri } from 'react-native-svg';
export default () => {
const [uri, setUri] = React.useState('https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/not_existing.svg')
const [uri, setUri] = React.useState(
'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/not_existing.svg',
);
return (
<SvgUri
onError={() => setUri('https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/ruby.svg')}
onError={() =>
setUri('https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/ruby.svg')
}
width="100%"
height="100%"
uri={uri}
/>
);
}
};
```
# Use with svg files

View File

@@ -10,6 +10,7 @@ buildscript {
dependencies {
classpath("com.android.tools.build:gradle:3.6.1")
classpath "com.diffplug.spotless:spotless-plugin-gradle:5.15.0"
}
}
}
@@ -26,6 +27,10 @@ if (isNewArchitectureEnabled()) {
apply plugin: "com.facebook.react"
}
if (project == rootProject) {
apply from: 'spotless.gradle'
}
apply plugin: 'com.android.library'
def safeExtGet(prop, fallback) {

Binary file not shown.

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

240
android/gradlew vendored Executable file
View File

@@ -0,0 +1,240 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

91
android/gradlew.bat vendored Normal file
View File

@@ -0,0 +1,91 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

9
android/spotless.gradle Normal file
View File

@@ -0,0 +1,9 @@
// formatter & linter configuration for java
apply plugin: 'com.diffplug.spotless'
spotless {
java {
target 'src/fabric/**/*.java', 'src/main/java/**/*.java', 'src/paper/java/com/horcrux/svg/**/*.java'
googleJavaFormat()
}
}

View File

@@ -1,22 +1,21 @@
package com.horcrux.svg;
import android.content.Context;
import android.view.ViewGroup;
import androidx.annotation.UiThread;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.uimanager.FabricViewStateManager;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.FabricViewStateManager.HasFabricViewStateManager;
import com.facebook.react.uimanager.FabricViewStateManager.StateUpdateCallback;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.views.view.ReactViewGroup;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class FabricEnabledViewGroup extends ReactViewGroup implements HasFabricViewStateManager {
public abstract class FabricEnabledViewGroup extends ReactViewGroup
implements HasFabricViewStateManager {
private final FabricViewStateManager mFabricViewStateManager = new FabricViewStateManager();
@NotNull
@@ -30,30 +29,34 @@ public abstract class FabricEnabledViewGroup extends ReactViewGroup implements H
@UiThread
public final void updateState(int width, int height) {
final float realWidth = PixelUtil.toDIPFromPixel((float)width);
final float realHeight = PixelUtil.toDIPFromPixel((float)height);
final float realWidth = PixelUtil.toDIPFromPixel((float) width);
final float realHeight = PixelUtil.toDIPFromPixel((float) height);
ReadableMap currentState = this.mFabricViewStateManager.getStateData();
if (currentState != null) {
float delta = 0.9F;
float stateFrameHeight = currentState.hasKey("frameHeight") ? (float)currentState.getDouble("frameHeight") : 0.0F;
float stateFrameWidth = currentState.hasKey("frameWidth") ? (float)currentState.getDouble("frameWidth") : 0.0F;
if (Math.abs(stateFrameWidth - realWidth) < delta &&
Math.abs(stateFrameHeight - realHeight) < delta) {
float stateFrameHeight =
currentState.hasKey("frameHeight") ? (float) currentState.getDouble("frameHeight") : 0.0F;
float stateFrameWidth =
currentState.hasKey("frameWidth") ? (float) currentState.getDouble("frameWidth") : 0.0F;
if (Math.abs(stateFrameWidth - realWidth) < delta
&& Math.abs(stateFrameHeight - realHeight) < delta) {
return;
}
}
this.mFabricViewStateManager.setState((StateUpdateCallback)(new StateUpdateCallback() {
this.mFabricViewStateManager.setState(
(StateUpdateCallback)
(new StateUpdateCallback() {
public final WritableMap getStateUpdate() {
WritableMap map = (WritableMap)(new WritableNativeMap());
map.putDouble("frameWidth", (double)realWidth);
map.putDouble("frameHeight", (double)realHeight);
WritableMap map = (WritableMap) (new WritableNativeMap());
map.putDouble("frameWidth", (double) realWidth);
map.putDouble("frameHeight", (double) realHeight);
return map;
}
}));
}
public FabricEnabledViewGroup(@Nullable ReactContext context) {
super((Context)context);
super((Context) context);
}
}

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.graphics.Bitmap;
@@ -19,7 +18,6 @@ import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
@@ -63,13 +61,14 @@ class Brush {
USER_SPACE_ON_USE
}
private static void parseGradientStops(ReadableArray value, int stopsCount, float[] stops, int[] stopsColors, float opacity) {
private static void parseGradientStops(
ReadableArray value, int stopsCount, float[] stops, int[] stopsColors, float opacity) {
for (int i = 0; i < stopsCount; i++) {
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);
int combined = Math.round((float) alpha * opacity);
stopsColors[i] = combined << 24 | (color & 0x00ffffff);
}
}
@@ -102,8 +101,12 @@ class Brush {
}
private double getVal(SVGLength length, double relative, float scale, float textSize) {
return PropHelper.fromRelative(length, relative, 0, mUseObjectBoundingBox &&
length.unit == SVGLength.UnitType.NUMBER ? relative : scale, textSize);
return PropHelper.fromRelative(
length,
relative,
0,
mUseObjectBoundingBox && length.unit == SVGLength.UnitType.NUMBER ? relative : scale,
textSize);
}
void setupPaint(Paint paint, RectF pathBoundingBox, float scale, float opacity) {
@@ -124,16 +127,14 @@ class Brush {
return;
}
Bitmap bitmap = Bitmap.createBitmap(
(int) w,
(int) h,
Bitmap.Config.ARGB_8888);
Bitmap bitmap = Bitmap.createBitmap((int) w, (int) h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
RectF vbRect = mPattern.getViewBox();
if (vbRect != null && vbRect.width() > 0 && vbRect.height() > 0) {
RectF eRect = new RectF((float) x, (float) y, (float) w, (float) h);
Matrix mViewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mPattern.mAlign, mPattern.mMeetOrSlice);
Matrix mViewBoxMatrix =
ViewBox.getTransform(vbRect, eRect, mPattern.mAlign, mPattern.mMeetOrSlice);
canvas.concat(mViewBoxMatrix);
}
@@ -148,7 +149,8 @@ class Brush {
patternMatrix.preConcat(mMatrix);
}
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
BitmapShader bitmapShader =
new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
bitmapShader.setLocalMatrix(patternMatrix);
paint.setShader(bitmapShader);
return;
@@ -170,8 +172,8 @@ class Brush {
// two stops at the same spot (see lib/extract/extractGradient.js).
// Although it's mistake SVGs like this can be produced by vector
// editors or other tools, so let's handle that gracefully.
stopsColors = new int[] { stopsColors[0], stopsColors[0] };
stops = new float[] { stops[0], stops[0] };
stopsColors = new int[] {stopsColors[0], stopsColors[0]};
stops = new float[] {stops[0], stops[0]};
FLog.w(ReactConstants.TAG, "Gradient contains only one stop");
}
@@ -181,7 +183,8 @@ class Brush {
double x2 = getVal(mPoints[2], width, scale, textSize) + offsetX;
double y2 = getVal(mPoints[3], height, scale, textSize) + offsetY;
Shader linearGradient = new LinearGradient(
Shader linearGradient =
new LinearGradient(
(float) x1,
(float) y1,
(float) x2,
@@ -207,17 +210,12 @@ class Brush {
double cy = getVal(mPoints[5], height / ratio, scale, textSize) + offsetY / ratio;
// TODO: support focus point.
//double fx = PropHelper.fromRelative(mPoints[0], width, offsetX, scale);
//double fy = PropHelper.fromRelative(mPoints[1], height, offsetY, scale) / (ry / rx);
// double fx = PropHelper.fromRelative(mPoints[0], width, offsetX, scale);
// double fy = PropHelper.fromRelative(mPoints[1], height, offsetY, scale) / (ry / rx);
Shader radialGradient = new RadialGradient(
(float) cx,
(float) cy,
(float) rx,
stopsColors,
stops,
Shader.TileMode.CLAMP
);
Shader radialGradient =
new RadialGradient(
(float) cx, (float) cy, (float) rx, stopsColors, stops, Shader.TileMode.CLAMP);
Matrix radialMatrix = new Matrix();
radialMatrix.preScale(1f, (float) ratio);

View File

@@ -6,15 +6,12 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;

View File

@@ -6,13 +6,11 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Paint;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.common.ReactConstants;
@@ -26,7 +24,9 @@ class ClipPathView extends GroupView {
@Override
void draw(Canvas canvas, Paint paint, float opacity) {
FLog.w(ReactConstants.TAG, "RNSVG: ClipPath can't be drawn, it should be defined as a child component for `Defs` ");
FLog.w(
ReactConstants.TAG,
"RNSVG: ClipPath can't be drawn, it should be defined as a child component for `Defs` ");
}
@Override

View File

@@ -6,14 +6,12 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import com.facebook.react.bridge.ReactContext;
@SuppressLint("ViewConstructor")

View File

@@ -6,14 +6,12 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;
import com.facebook.react.bridge.ReactContext;
@SuppressLint("ViewConstructor")
@@ -30,7 +28,7 @@ class DefsView extends DefinitionView {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof VirtualView) {
((VirtualView)child).saveDefinition();
((VirtualView) child).saveDefinition();
}
}
}

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -14,7 +13,6 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
@@ -81,7 +79,8 @@ class EllipseView extends RenderableView {
double cy = relativeOnHeight(mCy);
double rx = relativeOnWidth(mRx);
double ry = relativeOnHeight(mRy);
RectF oval = new RectF((float) (cx - rx), (float) (cy - ry), (float) (cx + rx), (float) (cy + ry));
RectF oval =
new RectF((float) (cx - rx), (float) (cy - ry), (float) (cx + rx), (float) (cy + ry));
path.addOval(oval, Path.Direction.CW);
return path;

View File

@@ -1,21 +1,22 @@
package com.horcrux.svg;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import static com.facebook.react.uimanager.ViewProps.FONT_FAMILY;
import static com.facebook.react.uimanager.ViewProps.FONT_SIZE;
import static com.facebook.react.uimanager.ViewProps.FONT_STYLE;
import static com.facebook.react.uimanager.ViewProps.FONT_WEIGHT;
import static com.horcrux.svg.TextProperties.*;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
class FontData {
static class AbsoluteFontWeight {
static final int normal = 400;
private static final FontWeight[] WEIGHTS = new FontWeight[]{
private static final FontWeight[] WEIGHTS =
new FontWeight[] {
FontWeight.w100,
FontWeight.w100,
FontWeight.w200,
@@ -33,9 +34,8 @@ class FontData {
return WEIGHTS[Math.round(absoluteFontWeight / 100f)];
}
private static final int[] absoluteFontWeights = new int[]{
400, 700, 100, 200, 300, 400, 500, 600, 700, 800, 900
};
private static final int[] absoluteFontWeights =
new int[] {400, 700, 100, 200, 300, 400, 500, 600, 700, 800, 900};
// https://drafts.csswg.org/css-fonts-4/#relative-weights
static int from(FontWeight fontWeight, FontData parent) {
@@ -132,18 +132,14 @@ class FontData {
letterSpacing = DEFAULT_LETTER_SPACING;
}
private double toAbsolute(ReadableMap font, String prop, double scale, double fontSize, double relative) {
private double toAbsolute(
ReadableMap font, String prop, double scale, double fontSize, double relative) {
ReadableType propType = font.getType(prop);
if (propType == ReadableType.Number) {
return font.getDouble(prop);
} else {
String string = font.getString(prop);
return PropHelper.fromRelative(
string,
relative,
scale,
fontSize
);
return PropHelper.fromRelative(string, relative, scale, fontSize);
}
}
@@ -155,7 +151,7 @@ class FontData {
private void handleNumericWeight(FontData parent, double number) {
long weight = Math.round(number);
if (weight >= 1 && weight <= 1000) {
absoluteFontWeight = (int)weight;
absoluteFontWeight = (int) weight;
fontWeight = AbsoluteFontWeight.nearestFontWeight(absoluteFontWeight);
} else {
setInheritedWeight(parent);
@@ -193,13 +189,29 @@ class FontData {
fontData = font.hasKey(FONT_DATA) ? font.getMap(FONT_DATA) : parent.fontData;
fontFamily = font.hasKey(FONT_FAMILY) ? font.getString(FONT_FAMILY) : parent.fontFamily;
fontStyle = font.hasKey(FONT_STYLE) ? FontStyle.valueOf(font.getString(FONT_STYLE)) : parent.fontStyle;
fontFeatureSettings = font.hasKey(FONT_FEATURE_SETTINGS) ? font.getString(FONT_FEATURE_SETTINGS) : parent.fontFeatureSettings;
fontVariationSettings = font.hasKey(FONT_VARIATION_SETTINGS) ? font.getString(FONT_VARIATION_SETTINGS) : parent.fontVariationSettings;
fontVariantLigatures = font.hasKey(FONT_VARIANT_LIGATURES) ? FontVariantLigatures.valueOf(font.getString(FONT_VARIANT_LIGATURES)) : parent.fontVariantLigatures;
fontStyle =
font.hasKey(FONT_STYLE) ? FontStyle.valueOf(font.getString(FONT_STYLE)) : parent.fontStyle;
fontFeatureSettings =
font.hasKey(FONT_FEATURE_SETTINGS)
? font.getString(FONT_FEATURE_SETTINGS)
: parent.fontFeatureSettings;
fontVariationSettings =
font.hasKey(FONT_VARIATION_SETTINGS)
? font.getString(FONT_VARIATION_SETTINGS)
: parent.fontVariationSettings;
fontVariantLigatures =
font.hasKey(FONT_VARIANT_LIGATURES)
? FontVariantLigatures.valueOf(font.getString(FONT_VARIANT_LIGATURES))
: parent.fontVariantLigatures;
textAnchor = font.hasKey(TEXT_ANCHOR) ? TextAnchor.valueOf(font.getString(TEXT_ANCHOR)) : parent.textAnchor;
textDecoration = font.hasKey(TEXT_DECORATION) ? TextDecoration.getEnum(font.getString(TEXT_DECORATION)) : parent.textDecoration;
textAnchor =
font.hasKey(TEXT_ANCHOR)
? TextAnchor.valueOf(font.getString(TEXT_ANCHOR))
: parent.textAnchor;
textDecoration =
font.hasKey(TEXT_DECORATION)
? TextDecoration.getEnum(font.getString(TEXT_DECORATION))
: parent.textDecoration;
final boolean hasKerning = font.hasKey(KERNING);
manualKerning = hasKerning || parent.manualKerning;
@@ -208,7 +220,13 @@ class FontData {
// https://drafts.csswg.org/css-text-3/#spacing
// calculated values for units in: kerning, word-spacing, and, letter-spacing.
kerning = hasKerning ? toAbsolute(font, KERNING, scale, fontSize, 0) : parent.kerning;
wordSpacing = font.hasKey(WORD_SPACING) ? toAbsolute(font, WORD_SPACING, scale, fontSize, 0) : parent.wordSpacing;
letterSpacing = font.hasKey(LETTER_SPACING) ? toAbsolute(font, LETTER_SPACING, scale, fontSize, 0) : parent.letterSpacing;
wordSpacing =
font.hasKey(WORD_SPACING)
? toAbsolute(font, WORD_SPACING, scale, fontSize, 0)
: parent.wordSpacing;
letterSpacing =
font.hasKey(LETTER_SPACING)
? toAbsolute(font, LETTER_SPACING, scale, fontSize, 0)
: parent.letterSpacing;
}
}

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -15,9 +14,7 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;
import androidx.annotation.NonNull;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
@@ -36,10 +33,10 @@ class ForeignObjectView extends GroupView {
@Override
void draw(Canvas canvas, Paint paint, float opacity) {
float x = (float)relativeOnWidth(mX);
float y = (float)relativeOnHeight(mY);
float w = (float)relativeOnWidth(mW);
float h = (float)relativeOnHeight(mH);
float x = (float) relativeOnWidth(mX);
float y = (float) relativeOnHeight(mY);
float w = (float) relativeOnWidth(mW);
float h = (float) relativeOnHeight(mH);
canvas.translate(x, y);
canvas.clipRect(0, 0, w, h);
super.draw(canvas, paint, opacity);
@@ -106,12 +103,12 @@ class ForeignObjectView extends GroupView {
continue;
}
if (child instanceof VirtualView) {
VirtualView node = ((VirtualView)child);
VirtualView node = ((VirtualView) child);
if ("none".equals(node.mDisplay)) {
continue;
}
if (node instanceof RenderableView) {
((RenderableView)node).mergeProperties(self);
((RenderableView) node).mergeProperties(self);
}
int count = node.saveAndSetupCanvas(canvas, mCTM);
@@ -124,14 +121,14 @@ class ForeignObjectView extends GroupView {
node.restoreCanvas(canvas, count);
if (node instanceof RenderableView) {
((RenderableView)node).resetProperties();
((RenderableView) node).resetProperties();
}
if (node.isResponsible()) {
svg.enableTouchEvents();
}
} else if (child instanceof SvgView) {
SvgView svgView = (SvgView)child;
SvgView svgView = (SvgView) child;
svgView.drawChildren(canvas);
if (svgView.isResponsible()) {
svg.enableTouchEvents();

View File

@@ -6,13 +6,10 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import com.facebook.react.bridge.ReadableMap;
import java.util.ArrayList;
import javax.annotation.Nullable;
// https://www.w3.org/TR/SVG/text.html#TSpanElement
@@ -61,25 +58,25 @@ class GlyphContext {
// https://www.w3.org/TR/SVG/types.html#DataTypeCoordinates
// https://www.w3.org/TR/SVG/text.html#TSpanElementXAttribute
private SVGLength[] mXs = new SVGLength[]{};
private SVGLength[] mXs = new SVGLength[] {};
// https://www.w3.org/TR/SVG/text.html#TSpanElementYAttribute
private SVGLength[] mYs = new SVGLength[]{};
private SVGLength[] mYs = new SVGLength[] {};
// Current <list-of-lengths> SVGLengthList
// https://www.w3.org/TR/SVG/types.html#DataTypeLengths
// https://www.w3.org/TR/SVG/text.html#TSpanElementDXAttribute
private SVGLength[] mDXs = new SVGLength[]{};
private SVGLength[] mDXs = new SVGLength[] {};
// https://www.w3.org/TR/SVG/text.html#TSpanElementDYAttribute
private SVGLength[] mDYs = new SVGLength[]{};
private SVGLength[] mDYs = new SVGLength[] {};
// Current <list-of-numbers> SVGLengthList
// https://www.w3.org/TR/SVG/types.html#DataTypeNumbers
// https://www.w3.org/TR/SVG/text.html#TSpanElementRotateAttribute
private double[] mRs = new double[]{0};
private double[] mRs = new double[] {0};
// Current attribute list index
private int mXsIndex;
@@ -174,7 +171,6 @@ class GlyphContext {
mFontSize = data.fontSize;
mFontContext.add(data);
topFont = data;
}
void pushContext(GroupView node, @Nullable ReadableMap font) {
@@ -209,8 +205,7 @@ class GlyphContext {
@Nullable ArrayList<SVGLength> y,
@Nullable ArrayList<SVGLength> deltaX,
@Nullable ArrayList<SVGLength> deltaY,
@Nullable ArrayList<SVGLength> rotate
) {
@Nullable ArrayList<SVGLength> rotate) {
if (reset) {
this.reset();
}
@@ -321,32 +316,24 @@ class GlyphContext {
/**
* Get font size from context.
* <p>
* font-size
* Value: < absolute-size > | < relative-size > | < length > | < percentage > | inherit
* Initial: medium
* Applies to: text content elements
* Inherited: yes, the computed value is inherited
* Percentages: refer to parent element's font size
* Media: visual
* Animatable: yes
* <p>
* This property refers to the size of the font from baseline to
* baseline when multiple lines of text are set solid in a multiline
* layout environment.
* <p>
* For SVG, if a < length > is provided without a unit identifier
* (e.g., an unqualified number such as 128), the SVG user agent
* processes the < length > as a height value in the current user
*
* <p>font-size Value: < absolute-size > | < relative-size > | < length > | < percentage > |
* inherit Initial: medium Applies to: text content elements Inherited: yes, the computed value is
* inherited Percentages: refer to parent element's font size Media: visual Animatable: yes
*
* <p>This property refers to the size of the font from baseline to baseline when multiple lines
* of text are set solid in a multiline layout environment.
*
* <p>For SVG, if a < length > is provided without a unit identifier (e.g., an unqualified number
* such as 128), the SVG user agent processes the < length > as a height value in the current user
* coordinate system.
* <p>
* If a < length > is provided with one of the unit identifiers
* (e.g., 12pt or 10%), then the SVG user agent converts the
* < length > into a corresponding value in the current user
*
* <p>If a < length > is provided with one of the unit identifiers (e.g., 12pt or 10%), then the
* SVG user agent converts the < length > into a corresponding value in the current user
* coordinate system by applying the rules described in Units.
* <p>
* Except for any additional information provided in this specification,
* the normative definition of the property is in CSS2 ([CSS2], section 15.2.4).
*
* <p>Except for any additional information provided in this specification, the normative
* definition of the property is in CSS2 ([CSS2], section 15.2.4).
*/
double getFontSize() {
return mFontSize;

View File

@@ -2,7 +2,6 @@ package com.horcrux.svg;
import android.graphics.Paint;
import android.graphics.Path;
import java.util.ArrayList;
class GlyphPathBag {

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -19,12 +18,9 @@ import android.graphics.RectF;
import android.graphics.Region;
import android.os.Build;
import android.view.View;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.view.ReactViewGroup;
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
@@ -58,8 +54,7 @@ class GroupView extends RenderableView {
}
private static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
if (obj == null) throw new NullPointerException();
return obj;
}
@@ -92,12 +87,12 @@ class GroupView extends RenderableView {
continue;
}
if (child instanceof VirtualView) {
VirtualView node = ((VirtualView)child);
VirtualView node = ((VirtualView) child);
if ("none".equals(node.mDisplay)) {
continue;
}
if (node instanceof RenderableView) {
((RenderableView)node).mergeProperties(self);
((RenderableView) node).mergeProperties(self);
}
int count = node.saveAndSetupCanvas(canvas, mCTM);
@@ -110,14 +105,14 @@ class GroupView extends RenderableView {
node.restoreCanvas(canvas, count);
if (node instanceof RenderableView) {
((RenderableView)node).resetProperties();
((RenderableView) node).resetProperties();
}
if (node.isResponsible()) {
svg.enableTouchEvents();
}
} else if (child instanceof SvgView) {
SvgView svgView = (SvgView)child;
SvgView svgView = (SvgView) child;
svgView.drawChildren(canvas);
if (svgView.isResponsible()) {
svg.enableTouchEvents();
@@ -145,7 +140,7 @@ class GroupView extends RenderableView {
continue;
}
if (node instanceof VirtualView) {
VirtualView n = (VirtualView)node;
VirtualView n = (VirtualView) node;
Matrix transform = n.mMatrix;
mPath.addPath(n.getPath(canvas, paint), transform);
}
@@ -165,11 +160,11 @@ class GroupView extends RenderableView {
continue;
}
if (node instanceof VirtualView) {
VirtualView n = (VirtualView)node;
VirtualView n = (VirtualView) node;
Matrix transform = n.mMatrix;
Path p2;
if (n instanceof GroupView) {
p2 = ((GroupView)n).getPath(canvas, paint, op);
p2 = ((GroupView) n).getPath(canvas, paint, op);
} else {
p2 = n.getPath(canvas, paint);
}
@@ -187,11 +182,11 @@ class GroupView extends RenderableView {
continue;
}
if (node instanceof VirtualView) {
VirtualView n = (VirtualView)node;
VirtualView n = (VirtualView) node;
Matrix transform = n.mMatrix;
Path p2;
if (n instanceof GroupView) {
p2 = ((GroupView)n).getPath(canvas, paint, op);
p2 = ((GroupView) n).getPath(canvas, paint, op);
} else {
p2 = n.getPath(canvas, paint);
}
@@ -269,7 +264,7 @@ class GroupView extends RenderableView {
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof VirtualView) {
((VirtualView)node).saveDefinition();
((VirtualView) node).saveDefinition();
}
}
}
@@ -279,7 +274,7 @@ class GroupView extends RenderableView {
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof RenderableView) {
((RenderableView)node).resetProperties();
((RenderableView) node).resetProperties();
}
}
}

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -17,7 +16,6 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.net.Uri;
import com.facebook.common.executors.UiThreadImmediateExecutorService;
import com.facebook.common.logging.FLog;
import com.facebook.common.references.CloseableReference;
@@ -35,9 +33,7 @@ import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.imagehelper.ImageSource;
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -102,14 +98,13 @@ class ImageView extends RenderableView {
invalidate();
}
@ReactProp(name = "src")
public void setSrc(@Nullable ReadableMap src) {
if (src != null) {
uriString = src.getString("uri");
if (uriString == null || uriString.isEmpty()) {
//TODO: give warning about this
// TODO: give warning about this
return;
}
@@ -164,9 +159,10 @@ class ImageView extends RenderableView {
private void loadBitmap(final ImagePipeline imagePipeline, final ImageRequest request) {
mLoading.set(true);
final DataSource<CloseableReference<CloseableImage>> dataSource
= imagePipeline.fetchDecodedImage(request, mContext);
BaseBitmapDataSubscriber subscriber = new BaseBitmapDataSubscriber() {
final DataSource<CloseableReference<CloseableImage>> dataSource =
imagePipeline.fetchDecodedImage(request, mContext);
BaseBitmapDataSubscriber subscriber =
new BaseBitmapDataSubscriber() {
@Override
public void onNewResultImpl(Bitmap bitmap) {
mLoading.set(false);
@@ -181,7 +177,10 @@ class ImageView extends RenderableView {
// No cleanup required here.
// TODO: more details about this failure
mLoading.set(false);
FLog.w(ReactConstants.TAG, dataSource.getFailureCause(), "RNSVG: fetchDecodedImage failed!");
FLog.w(
ReactConstants.TAG,
dataSource.getFailureCause(),
"RNSVG: fetchDecodedImage failed!");
}
};
dataSource.subscribe(subscriber, UiThreadImmediateExecutorService.getInstance());
@@ -228,9 +227,14 @@ class ImageView extends RenderableView {
this.setClientRect(vbRect);
}
private void tryRenderFromBitmapCache(ImagePipeline imagePipeline, ImageRequest request, Canvas canvas, Paint paint, float opacity) {
final DataSource<CloseableReference<CloseableImage>> dataSource
= imagePipeline.fetchImageFromBitmapCache(request, mContext);
private void tryRenderFromBitmapCache(
ImagePipeline imagePipeline,
ImageRequest request,
Canvas canvas,
Paint paint,
float opacity) {
final DataSource<CloseableReference<CloseableImage>> dataSource =
imagePipeline.fetchImageFromBitmapCache(request, mContext);
try {
final CloseableReference<CloseableImage> imageReference = dataSource.getResult();
@@ -265,5 +269,4 @@ class ImageView extends RenderableView {
dataSource.close();
}
}
}

View File

@@ -6,14 +6,12 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;

View File

@@ -6,19 +6,16 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Matrix;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.annotations.ReactProp;
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
@@ -31,7 +28,8 @@ class LinearGradientView extends DefinitionView {
private ReadableArray mGradient;
private Brush.BrushUnits mGradientUnits;
private static final float[] sRawMatrix = new float[]{
private static final float[] sRawMatrix =
new float[] {
1, 0, 0,
0, 1, 0,
0, 0, 1
@@ -127,7 +125,7 @@ class LinearGradientView extends DefinitionView {
@Override
void saveDefinition() {
if (mName != null) {
SVGLength[] points = new SVGLength[]{mX1, mY1, mX2, mY2};
SVGLength[] points = new SVGLength[] {mX1, mY1, mX2, mY2};
Brush brush = new Brush(Brush.BrushType.LINEAR_GRADIENT, points, mGradientUnits);
brush.setGradientColors(mGradient);
if (mMatrix != null) {

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -15,7 +14,6 @@ import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
@@ -143,18 +141,19 @@ class MarkerView extends GroupView {
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof VirtualView) {
((VirtualView)node).saveDefinition();
((VirtualView) node).saveDefinition();
}
}
}
}
void renderMarker(Canvas canvas, Paint paint, float opacity, RNSVGMarkerPosition position, float strokeWidth) {
void renderMarker(
Canvas canvas, Paint paint, float opacity, RNSVGMarkerPosition position, float strokeWidth) {
int count = saveAndSetupCanvas(canvas, mCTM);
markerTransform.reset();
Point origin = position.origin;
markerTransform.setTranslate((float)origin.x * mScale, (float)origin.y * mScale);
markerTransform.setTranslate((float) origin.x * mScale, (float) origin.y * mScale);
double markerAngle = "auto".equals(mOrient) ? -1 : Double.parseDouble(mOrient);
float degrees = 180 + (float) (markerAngle == -1 ? position.angle : markerAngle);
@@ -167,9 +166,14 @@ class MarkerView extends GroupView {
double width = relativeOnWidth(mMarkerWidth) / mScale;
double height = relativeOnHeight(mMarkerHeight) / mScale;
RectF eRect = new RectF(0, 0, (float)width, (float)height);
RectF eRect = new RectF(0, 0, (float) width, (float) height);
if (mAlign != null) {
RectF vbRect = new RectF(mMinX * mScale, mMinY * mScale, (mMinX + mVbWidth) * mScale, (mMinY + mVbHeight) * mScale);
RectF vbRect =
new RectF(
mMinX * mScale,
mMinY * mScale,
(mMinX + mVbWidth) * mScale,
(mMinY + mVbHeight) * mScale);
Matrix viewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mAlign, mMeetOrSlice);
float[] values = new float[9];
viewBoxMatrix.getValues(values);
@@ -178,7 +182,7 @@ class MarkerView extends GroupView {
double x = relativeOnWidth(mRefX);
double y = relativeOnHeight(mRefY);
markerTransform.preTranslate((float)-x, (float)-y);
markerTransform.preTranslate((float) -x, (float) -y);
canvas.concat(markerTransform);

View File

@@ -6,19 +6,16 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Matrix;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.annotations.ReactProp;
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
@@ -32,10 +29,12 @@ class MaskView extends GroupView {
// TODO implement proper support for units
@SuppressWarnings({"FieldCanBeLocal", "unused"})
private Brush.BrushUnits mMaskUnits;
@SuppressWarnings({"FieldCanBeLocal", "unused"})
private Brush.BrushUnits mMaskContentUnits;
private static final float[] sRawMatrix = new float[]{
private static final float[] sRawMatrix =
new float[] {
1, 0, 0,
0, 1, 0,
0, 0, 1

View File

@@ -2,12 +2,12 @@ package com.horcrux.svg;
import android.graphics.Path;
import android.graphics.RectF;
import java.util.ArrayList;
class PathElement {
ElementType type;
Point[] points;
PathElement(ElementType type, Point[] points) {
this.type = type;
this.points = points;
@@ -34,7 +34,7 @@ class PathParser {
static Path parse(String d) {
elements = new ArrayList<>();
mPath = new Path();
if(d == null){
if (d == null) {
return mPath;
}
char prev_cmd = ' ';
@@ -98,89 +98,138 @@ class PathParser {
boolean absolute = is_absolute(cmd);
switch (cmd) {
case 'm': {
case 'm':
{
move(parse_list_number(), parse_list_number());
break;
}
case 'M': {
case 'M':
{
moveTo(parse_list_number(), parse_list_number());
break;
}
case 'l': {
case 'l':
{
line(parse_list_number(), parse_list_number());
break;
}
case 'L': {
case 'L':
{
lineTo(parse_list_number(), parse_list_number());
break;
}
case 'h': {
case 'h':
{
line(parse_list_number(), 0);
break;
}
case 'H': {
case 'H':
{
lineTo(parse_list_number(), mPenY);
break;
}
case 'v': {
case 'v':
{
line(0, parse_list_number());
break;
}
case 'V': {
case 'V':
{
lineTo(mPenX, parse_list_number());
break;
}
case 'c': {
curve(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
case 'c':
{
curve(
parse_list_number(),
parse_list_number(),
parse_list_number(),
parse_list_number(),
parse_list_number(),
parse_list_number());
break;
}
case 'C': {
curveTo(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
case 'C':
{
curveTo(
parse_list_number(),
parse_list_number(),
parse_list_number(),
parse_list_number(),
parse_list_number(),
parse_list_number());
break;
}
case 's': {
smoothCurve(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
case 's':
{
smoothCurve(
parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
break;
}
case 'S': {
smoothCurveTo(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
case 'S':
{
smoothCurveTo(
parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
break;
}
case 'q': {
quadraticBezierCurve(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
case 'q':
{
quadraticBezierCurve(
parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
break;
}
case 'Q': {
quadraticBezierCurveTo(parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
case 'Q':
{
quadraticBezierCurveTo(
parse_list_number(), parse_list_number(), parse_list_number(), parse_list_number());
break;
}
case 't': {
case 't':
{
smoothQuadraticBezierCurve(parse_list_number(), parse_list_number());
break;
}
case 'T': {
case 'T':
{
smoothQuadraticBezierCurveTo(parse_list_number(), parse_list_number());
break;
}
case 'a': {
arc(parse_list_number(), parse_list_number(), parse_list_number(), parse_flag(), parse_flag(), parse_list_number(), parse_list_number());
case 'a':
{
arc(
parse_list_number(),
parse_list_number(),
parse_list_number(),
parse_flag(),
parse_flag(),
parse_list_number(),
parse_list_number());
break;
}
case 'A': {
arcTo(parse_list_number(), parse_list_number(), parse_list_number(), parse_flag(), parse_flag(), parse_list_number(), parse_list_number());
case 'A':
{
arcTo(
parse_list_number(),
parse_list_number(),
parse_list_number(),
parse_flag(),
parse_flag(),
parse_list_number(),
parse_list_number());
break;
}
case 'z':
case 'Z': {
case 'Z':
{
close();
break;
}
default: {
default:
{
throw new Error(String.format("Unexpected comand '%c' (s=%s)", cmd, s));
}
}
if (is_implicit_move_to) {
if (absolute) {
prev_cmd = 'M';
@@ -190,7 +239,6 @@ class PathParser {
} else {
prev_cmd = cmd;
}
}
return mPath;
@@ -201,11 +249,12 @@ class PathParser {
}
private static void moveTo(float x, float y) {
//FLog.w(ReactConstants.TAG, "move x: " + x + " y: " + y);
// FLog.w(ReactConstants.TAG, "move x: " + x + " y: " + y);
mPenDownX = mPivotX = mPenX = x;
mPenDownY = mPivotY = mPenY = y;
mPath.moveTo(x * mScale, y * mScale);
elements.add(new PathElement(ElementType.kCGPathElementMoveToPoint, new Point[]{new Point(x,y)}));
elements.add(
new PathElement(ElementType.kCGPathElementMoveToPoint, new Point[] {new Point(x, y)}));
}
private static void line(float x, float y) {
@@ -213,12 +262,13 @@ class PathParser {
}
private static void lineTo(float x, float y) {
//FLog.w(ReactConstants.TAG, "line x: " + x + " y: " + y);
// FLog.w(ReactConstants.TAG, "line x: " + x + " y: " + y);
setPenDown();
mPivotX = mPenX = x;
mPivotY = mPenY = y;
mPath.lineTo(x * mScale, y * mScale);
elements.add(new PathElement(ElementType.kCGPathElementAddLineToPoint, new Point[]{new Point(x,y)}));
elements.add(
new PathElement(ElementType.kCGPathElementAddLineToPoint, new Point[] {new Point(x, y)}));
}
private static void curve(float c1x, float c1y, float c2x, float c2y, float ex, float ey) {
@@ -226,7 +276,8 @@ class PathParser {
}
private static void curveTo(float c1x, float c1y, float c2x, float c2y, float ex, float ey) {
//FLog.w(ReactConstants.TAG, "curve c1x: " + c1x + " c1y: " + c1y + "ex: " + ex + " ey: " + ey);
// FLog.w(ReactConstants.TAG, "curve c1x: " + c1x + " c1y: " + c1y + "ex: " + ex + " ey: " +
// ey);
mPivotX = c2x;
mPivotY = c2y;
cubicTo(c1x, c1y, c2x, c2y, ex, ey);
@@ -237,7 +288,10 @@ class PathParser {
mPenX = ex;
mPenY = ey;
mPath.cubicTo(c1x * mScale, c1y * mScale, c2x * mScale, c2y * mScale, ex * mScale, ey * mScale);
elements.add(new PathElement(ElementType.kCGPathElementAddCurveToPoint, new Point[]{new Point(c1x, c1y), new Point(c2x, c2y), new Point(ex, ey)}));
elements.add(
new PathElement(
ElementType.kCGPathElementAddCurveToPoint,
new Point[] {new Point(c1x, c1y), new Point(c2x, c2y), new Point(ex, ey)}));
}
private static void smoothCurve(float c1x, float c1y, float ex, float ey) {
@@ -245,7 +299,8 @@ class PathParser {
}
private static void smoothCurveTo(float c1x, float c1y, float ex, float ey) {
//FLog.w(ReactConstants.TAG, "smoothcurve c1x: " + c1x + " c1y: " + c1y + "ex: " + ex + " ey: " + ey);
// FLog.w(ReactConstants.TAG, "smoothcurve c1x: " + c1x + " c1y: " + c1y + "ex: " + ex + " ey: "
// + ey);
float c2x = c1x;
float c2y = c1y;
c1x = (mPenX * 2) - mPivotX;
@@ -260,7 +315,8 @@ class PathParser {
}
private static void quadraticBezierCurveTo(float c1x, float c1y, float c2x, float c2y) {
//FLog.w(ReactConstants.TAG, "quad c1x: " + c1x + " c1y: " + c1y + "c2x: " + c2x + " c2y: " + c2y);
// FLog.w(ReactConstants.TAG, "quad c1x: " + c1x + " c1y: " + c1y + "c2x: " + c2x + " c2y: " +
// c2y);
mPivotX = c1x;
mPivotY = c1y;
float ex = c2x;
@@ -277,7 +333,7 @@ class PathParser {
}
private static void smoothQuadraticBezierCurveTo(float c1x, float c1y) {
//FLog.w(ReactConstants.TAG, "smoothquad c1x: " + c1x + " c1y: " + c1y);
// FLog.w(ReactConstants.TAG, "smoothquad c1x: " + c1x + " c1y: " + c1y);
float c2x = c1x;
float c2y = c1y;
c1x = (mPenX * 2) - mPivotX;
@@ -285,12 +341,15 @@ class PathParser {
quadraticBezierCurveTo(c1x, c1y, c2x, c2y);
}
private static void arc(float rx, float ry, float rotation, boolean outer, boolean clockwise, float x, float y) {
private static void arc(
float rx, float ry, float rotation, boolean outer, boolean clockwise, float x, float y) {
arcTo(rx, ry, rotation, outer, clockwise, x + mPenX, y + mPenY);
}
private static void arcTo(float rx, float ry, float rotation, boolean outer, boolean clockwise, float x, float y) {
//FLog.w(ReactConstants.TAG, "arc rx: " + rx + " ry: " + ry + " rotation: " + rotation + " outer: " + outer + " clockwise: " + clockwise + " x: " + x + " y: " + y);
private static void arcTo(
float rx, float ry, float rotation, boolean outer, boolean clockwise, float x, float y) {
// FLog.w(ReactConstants.TAG, "arc rx: " + rx + " ry: " + ry + " rotation: " + rotation + "
// outer: " + outer + " clockwise: " + clockwise + " x: " + x + " y: " + y);
float tX = mPenX;
float tY = mPenY;
@@ -376,14 +435,13 @@ class PathParser {
sweep = -sweep;
}
RectF oval = new RectF(
(cx - rx) * mScale,
(cy - rx) * mScale,
(cx + rx) * mScale,
(cy + rx) * mScale);
RectF oval =
new RectF((cx - rx) * mScale, (cy - rx) * mScale, (cx + rx) * mScale, (cy + rx) * mScale);
mPath.arcTo(oval, start, sweep);
elements.add(new PathElement(ElementType.kCGPathElementAddCurveToPoint, new Point[]{new Point(x, y)}));
elements.add(
new PathElement(
ElementType.kCGPathElementAddCurveToPoint, new Point[] {new Point(x, y)}));
}
}
@@ -393,11 +451,14 @@ class PathParser {
mPenY = mPenDownY;
mPenDown = false;
mPath.close();
elements.add(new PathElement(ElementType.kCGPathElementCloseSubpath, new Point[]{new Point(mPenX, mPenY)}));
elements.add(
new PathElement(
ElementType.kCGPathElementCloseSubpath, new Point[] {new Point(mPenX, mPenY)}));
}
}
private static void arcToBezier(float cx, float cy, float rx, float ry, float sa, float ea, boolean clockwise, float rad) {
private static void arcToBezier(
float cx, float cy, float rx, float ry, float sa, float ea, boolean clockwise, float rad) {
// Inverse Rotation + Scale Transform
float cos = (float) Math.cos(rad);
float sin = (float) Math.sin(rad);
@@ -440,8 +501,12 @@ class PathParser {
float ex = (cx + xx * x + yx * y);
float ey = (cy + xy * x + yy * y);
mPath.cubicTo(c1x * mScale, c1y * mScale, c2x * mScale, c2y * mScale, ex * mScale, ey * mScale);
elements.add(new PathElement(ElementType.kCGPathElementAddCurveToPoint, new Point[]{new Point(c1x, c1y), new Point(c2x, c2y), new Point(ex, ey)}));
mPath.cubicTo(
c1x * mScale, c1y * mScale, c2x * mScale, c2y * mScale, ex * mScale, ey * mScale);
elements.add(
new PathElement(
ElementType.kCGPathElementAddCurveToPoint,
new Point[] {new Point(c1x, c1y), new Point(c2x, c2y), new Point(ex, ey)}));
}
}
@@ -505,7 +570,8 @@ class PathParser {
char c = s.charAt(i);
switch (c) {
case '0':
case '1': {
case '1':
{
i += 1;
if (i < l && s.charAt(i) == ',') {
i += 1;
@@ -557,7 +623,8 @@ class PathParser {
c = s.charAt(i);
}
} else if (c != '.') {
throw new Error(String.format("Invalid number formating character '%c' (i=%d, s=%s)", c ,i, s));
throw new Error(
String.format("Invalid number formating character '%c' (i=%d, s=%s)", c, i, s));
}
// Consume fraction.
@@ -582,7 +649,8 @@ class PathParser {
} else if (c >= '0' && c <= '9') {
skip_digits();
} else {
throw new Error(String.format("Invalid number formating character '%c' (i=%d, s=%s)", c, i, s));
throw new Error(
String.format("Invalid number formating character '%c' (i=%d, s=%s)", c, i, s));
}
}
}
@@ -592,7 +660,8 @@ class PathParser {
// inf, nan, etc. are an error.
if (Float.isInfinite(n) || Float.isNaN(n)) {
throw new Error(String.format("Invalid number '%s' (start=%d, i=%d, s=%s)", num, start, i, s));
throw new Error(
String.format("Invalid number '%s' (start=%d, i=%d, s=%s)", num, start, i, s));
}
return n;

View File

@@ -6,14 +6,12 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
@@ -38,5 +36,4 @@ class PathView extends RenderableView {
Path getPath(Canvas canvas, Paint paint) {
return mPath;
}
}

View File

@@ -6,20 +6,17 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Matrix;
import android.graphics.RectF;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.annotations.ReactProp;
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
@@ -39,7 +36,8 @@ class PatternView extends GroupView {
String mAlign;
int mMeetOrSlice;
private static final float[] sRawMatrix = new float[]{
private static final float[] sRawMatrix =
new float[] {
1, 0, 0,
0, 1, 0,
0, 0, 1
@@ -82,6 +80,7 @@ class PatternView extends GroupView {
mW = SVGLength.from(width);
invalidate();
}
@ReactProp(name = "height")
public void setHeight(Dynamic height) {
mH = SVGLength.from(height);
@@ -174,15 +173,15 @@ class PatternView extends GroupView {
invalidate();
}
RectF getViewBox() {
return new RectF(mMinX * mScale, mMinY * mScale, (mMinX + mVbWidth) * mScale, (mMinY + mVbHeight) * mScale);
return new RectF(
mMinX * mScale, mMinY * mScale, (mMinX + mVbWidth) * mScale, (mMinY + mVbHeight) * mScale);
}
@Override
void saveDefinition() {
if (mName != null) {
SVGLength[] points = new SVGLength[]{mX,mY,mW,mH};
SVGLength[] points = new SVGLength[] {mX, mY, mW, mH};
Brush brush = new Brush(Brush.BrushType.PATTERN, points, mPatternUnits);
brush.setContentUnits(mPatternContentUnits);
brush.setPattern(this);
@@ -192,7 +191,8 @@ class PatternView extends GroupView {
}
SvgView svg = getSvgView();
if (mPatternUnits == Brush.BrushUnits.USER_SPACE_ON_USE || mPatternContentUnits == Brush.BrushUnits.USER_SPACE_ON_USE) {
if (mPatternUnits == Brush.BrushUnits.USER_SPACE_ON_USE
|| mPatternContentUnits == Brush.BrushUnits.USER_SPACE_ON_USE) {
brush.setUserSpaceBoundingBox(svg.getCanvasBounds());
}

View File

@@ -6,25 +6,22 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import com.facebook.react.bridge.ReadableArray;
/**
* Contains static helper methods for accessing props.
*/
/** Contains static helper methods for accessing props. */
class PropHelper {
private static final int inputMatrixDataSize = 6;
/**
* Converts given {@link ReadableArray} to a matrix data array, {@code float[6]}.
* Writes result to the array passed in {@param into}.
* This method will write exactly six items to the output array from the input array.
* Converts given {@link ReadableArray} to a matrix data array, {@code float[6]}. Writes result to
* the array passed in {@param into}. This method will write exactly six items to the output array
* from the input array.
*
* If the input array has a different size, then only the size is returned;
* Does not check output array size. Ensure space for at least six elements.
* <p>If the input array has a different size, then only the size is returned; Does not check
* output array size. Ensure space for at least six elements.
*
* @param value input array
* @param sRawMatrix output matrix
@@ -48,8 +45,7 @@ class PropHelper {
}
/**
* Converts length string into px / user units
* in the current user coordinate system
* Converts length string into px / user units in the current user coordinate system
*
* @param length length string
* @param relative relative size for percentages
@@ -141,8 +137,7 @@ class PropHelper {
}
}
/**
* Converts SVGLength into px / user units
* in the current user coordinate system
* Converts SVGLength into px / user units in the current user coordinate system
*
* @param length length string
* @param relative relative size for percentages
@@ -151,7 +146,8 @@ class PropHelper {
* @param fontSize current font size
* @return value in the current user coordinate system
*/
static double fromRelative(SVGLength length, double relative, double offset, double scale, double fontSize) {
static double fromRelative(
SVGLength length, double relative, double offset, double scale, double fontSize) {
/*
TODO list

View File

@@ -19,7 +19,8 @@ enum ElementType {
class Point {
double x;
double y;
Point(double x, double y){
Point(double x, double y) {
this.x = x;
this.y = y;
}
@@ -33,14 +34,15 @@ class SegmentData {
class RNSVGMarkerPosition {
static private ArrayList<RNSVGMarkerPosition> positions_;
static private int element_index_;
static private Point origin_;
static private Point subpath_start_;
static private Point in_slope_;
static private Point out_slope_;
private static ArrayList<RNSVGMarkerPosition> positions_;
private static int element_index_;
private static Point origin_;
private static Point subpath_start_;
private static Point in_slope_;
private static Point out_slope_;
@SuppressWarnings("unused")
static private boolean auto_start_reverse_; // TODO
private static boolean auto_start_reverse_; // TODO
RNSVGMarkerType type;
Point origin;
@@ -71,8 +73,7 @@ class RNSVGMarkerPosition {
private static double BisectingAngle(double in_angle, double out_angle) {
// WK193015: Prevent bugs due to angles being non-continuous.
if (Math.abs(in_angle - out_angle) > 180)
in_angle += 360;
if (Math.abs(in_angle - out_angle) > 180) in_angle += 360;
return (in_angle + out_angle) / 2;
}
@@ -92,8 +93,7 @@ class RNSVGMarkerPosition {
double out_angle = rad2deg(SlopeAngleRadians(out_slope_));
switch (type) {
case kStartMarker:
if (auto_start_reverse_)
out_angle += 180;
if (auto_start_reverse_) out_angle += 180;
return out_angle;
case kMidMarker:
return BisectingAngle(in_angle, out_angle);
@@ -111,16 +111,11 @@ class RNSVGMarkerPosition {
return p.x == 0 && p.y == 0;
}
private static void ComputeQuadTangents(SegmentData data,
Point start,
Point control,
Point end) {
private static void ComputeQuadTangents(SegmentData data, Point start, Point control, Point end) {
data.start_tangent = subtract(control, start);
data.end_tangent = subtract(end, control);
if (isZero(data.start_tangent))
data.start_tangent = data.end_tangent;
else if (isZero(data.end_tangent))
data.end_tangent = data.start_tangent;
if (isZero(data.start_tangent)) data.start_tangent = data.end_tangent;
else if (isZero(data.end_tangent)) data.end_tangent = data.start_tangent;
}
private static SegmentData ExtractPathElementFeatures(PathElement element) {
@@ -131,10 +126,8 @@ class RNSVGMarkerPosition {
data.position = points[2];
data.start_tangent = subtract(points[0], origin_);
data.end_tangent = subtract(points[2], points[1]);
if (isZero(data.start_tangent))
ComputeQuadTangents(data, points[0], points[1], points[2]);
else if (isZero(data.end_tangent))
ComputeQuadTangents(data, origin_, points[0], points[1]);
if (isZero(data.start_tangent)) ComputeQuadTangents(data, points[0], points[1], points[2]);
else if (isZero(data.end_tangent)) ComputeQuadTangents(data, origin_, points[0], points[1]);
break;
case kCGPathElementAddQuadCurveToPoint:
data.position = points[1];
@@ -171,8 +164,7 @@ class RNSVGMarkerPosition {
// Update marker position.
origin_ = segment_data.position;
// If this is a 'move to' segment, save the point for use with 'close'.
if (element.type == ElementType.kCGPathElementMoveToPoint)
subpath_start_ = element.points[0];
if (element.type == ElementType.kCGPathElementMoveToPoint) subpath_start_ = element.points[0];
else if (element.type == ElementType.kCGPathElementCloseSubpath)
subpath_start_ = new Point(0, 0);
++element_index_;

View File

@@ -6,16 +6,16 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import static com.facebook.react.common.StandardCharsets.UTF_8;
import android.content.res.Resources;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.graphics.Region;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
@@ -23,15 +23,11 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.annotation.Nonnull;
import static com.facebook.react.common.StandardCharsets.UTF_8;
class RNSVGRenderableManager extends ReactContextBaseJavaModule {
RNSVGRenderableManager(ReactApplicationContext reactContext) {
super(reactContext);
@@ -55,7 +51,7 @@ class RNSVGRenderableManager extends ReactContextBaseJavaModule {
float x = (float) options.getDouble("x") * scale;
float y = (float) options.getDouble("y") * scale;
int i = svg.hitTest(new float[]{x, y});
int i = svg.hitTest(new float[] {x, y});
return i != -1;
}

View File

@@ -6,19 +6,16 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Matrix;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.annotations.ReactProp;
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
@@ -32,7 +29,8 @@ class RadialGradientView extends DefinitionView {
private ReadableArray mGradient;
private Brush.BrushUnits mGradientUnits;
private static final float[] sRawMatrix = new float[]{
private static final float[] sRawMatrix =
new float[] {
1, 0, 0,
0, 1, 0,
0, 0, 1
@@ -150,7 +148,7 @@ class RadialGradientView extends DefinitionView {
@Override
void saveDefinition() {
if (mName != null) {
SVGLength[] points = new SVGLength[]{mFx,mFy,mRx,mRy,mCx,mCy};
SVGLength[] points = new SVGLength[] {mFx, mFy, mRx, mRy, mCx, mCy};
Brush brush = new Brush(Brush.BrushType.RADIAL_GRADIENT, points, mGradientUnits);
brush.setGradientColors(mGradient);
if (mMatrix != null) {

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -15,7 +14,6 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Build;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
@@ -129,13 +127,25 @@ class RectView extends RenderableView {
ry = h / 2;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
path.addRoundRect((float) x, (float) y, (float) (x + w), (float) (y + h), (float) rx, (float) ry, Path.Direction.CW);
path.addRoundRect(
(float) x,
(float) y,
(float) (x + w),
(float) (y + h),
(float) rx,
(float) ry,
Path.Direction.CW);
} else {
path.addRoundRect(new RectF((float) x, (float) y, (float) (x + w), (float) (y + h)), (float) rx, (float) ry, Path.Direction.CW);
path.addRoundRect(
new RectF((float) x, (float) y, (float) (x + w), (float) (y + h)),
(float) rx,
(float) ry,
Path.Direction.CW);
}
} else {
path.addRect((float) x, (float) y, (float) (x + w), (float) (y + h), Path.Direction.CW);
path.close(); // Ensure isSimplePath = false such that rect doesn't become represented using integers
path.close(); // Ensure isSimplePath = false such that rect doesn't become represented using
// integers
}
return path;
}

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.graphics.Bitmap;
@@ -20,7 +19,7 @@ import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import com.facebook.react.bridge.ColorPropConverter;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.JavaOnlyArray;
@@ -28,19 +27,16 @@ import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.ColorPropConverter;
import com.facebook.react.uimanager.PointerEvents;
import com.facebook.react.uimanager.annotations.ReactProp;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
@SuppressWarnings({"WeakerAccess", "RedundantSuppression"})
abstract public class RenderableView extends VirtualView {
public abstract class RenderableView extends VirtualView {
RenderableView(ReactContext reactContext) {
super(reactContext);
@@ -66,8 +62,8 @@ abstract public class RenderableView extends VirtualView {
// vectorEffect
private static final int VECTOR_EFFECT_DEFAULT = 0;
private static final int VECTOR_EFFECT_NON_SCALING_STROKE = 1;
//static final int VECTOR_EFFECT_INHERIT = 2;
//static final int VECTOR_EFFECT_URI = 3;
// static final int VECTOR_EFFECT_INHERIT = 2;
// static final int VECTOR_EFFECT_URI = 3;
/*
Used in mergeProperties, keep public
@@ -125,7 +121,6 @@ abstract public class RenderableView extends VirtualView {
setFill(fillMap);
}
// This code will probably never be reached with current changes
if (fillType.equals(ReadableType.Number)) {
this.fill = JavaOnlyArray.of(0, fill.asInt());
@@ -182,8 +177,7 @@ abstract public class RenderableView extends VirtualView {
case FILL_RULE_NONZERO:
break;
default:
throw new JSApplicationIllegalArgumentException(
"fillRule " + fillRule + " unrecognized");
throw new JSApplicationIllegalArgumentException("fillRule " + fillRule + " unrecognized");
}
invalidate();
@@ -363,7 +357,8 @@ abstract public class RenderableView extends VirtualView {
Paint maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mask.draw(maskCanvas, maskPaint, 1);
// Apply luminanceToAlpha filter primitive https://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement
// Apply luminanceToAlpha filter primitive
// https://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement
int nPixels = width * height;
int[] pixels = new int[nPixels];
maskBitmap.getPixels(pixels, 0, width, 0, 0, width, height);
@@ -447,13 +442,13 @@ abstract public class RenderableView extends VirtualView {
}
void renderMarkers(Canvas canvas, Paint paint, float opacity) {
MarkerView markerStart = (MarkerView)getSvgView().getDefinedMarker(mMarkerStart);
MarkerView markerMid = (MarkerView)getSvgView().getDefinedMarker(mMarkerMid);
MarkerView markerEnd = (MarkerView)getSvgView().getDefinedMarker(mMarkerEnd);
MarkerView markerStart = (MarkerView) getSvgView().getDefinedMarker(mMarkerStart);
MarkerView markerMid = (MarkerView) getSvgView().getDefinedMarker(mMarkerMid);
MarkerView markerEnd = (MarkerView) getSvgView().getDefinedMarker(mMarkerEnd);
if (elements != null && (markerStart != null || markerMid != null || markerEnd != null)) {
contextElement = this;
ArrayList<RNSVGMarkerPosition> positions = RNSVGMarkerPosition.fromPath(elements);
float width = (float)(this.strokeWidth != null ? relativeOnOther(this.strokeWidth) : 1);
float width = (float) (this.strokeWidth != null ? relativeOnOther(this.strokeWidth) : 1);
mMarkerPath = new Path();
for (RNSVGMarkerPosition position : positions) {
RNSVGMarkerType type = position.type;
@@ -483,8 +478,8 @@ abstract public class RenderableView extends VirtualView {
}
/**
* Sets up paint according to the props set on a view. Returns {@code true}
* if the fill should be drawn, {@code false} if not.
* Sets up paint according to the props set on a view. Returns {@code true} if the fill should be
* drawn, {@code false} if not.
*/
boolean setupFillPaint(Paint paint, float opacity) {
if (fill != null && fill.size() > 0) {
@@ -498,8 +493,8 @@ abstract public class RenderableView extends VirtualView {
}
/**
* Sets up paint according to the props set on a view. Returns {@code true}
* if the stroke should be drawn, {@code false} if not.
* Sets up paint according to the props set on a view. Returns {@code true} if the stroke should
* be drawn, {@code false} if not.
*/
boolean setupStrokePaint(Paint paint, float opacity) {
paint.reset();
@@ -520,7 +515,7 @@ abstract public class RenderableView extends VirtualView {
int length = strokeDasharray.length;
float[] intervals = new float[length];
for (int i = 0; i < length; i++) {
intervals[i] = (float)relativeOnOther(strokeDasharray[i]);
intervals[i] = (float) relativeOnOther(strokeDasharray[i]);
}
paint.setPathEffect(new DashPathEffect(intervals, strokeDashoffset));
}
@@ -540,7 +535,7 @@ abstract public class RenderableView extends VirtualView {
color = colors.getInt(1);
}
int alpha = color >>> 24;
int combined = Math.round((float)alpha * opacity);
int combined = Math.round((float) alpha * opacity);
paint.setColor(combined << 24 | (color & 0x00ffffff));
} else {
// solid color
@@ -551,32 +546,35 @@ abstract public class RenderableView extends VirtualView {
(int) (colors.getDouble(3) * 255));
}
break;
case 1: {
case 1:
{
Brush brush = getSvgView().getDefinedBrush(colors.getString(1));
if (brush != null) {
brush.setupPaint(paint, mBox, mScale, opacity);
}
break;
}
case 2: {
case 2:
{
int brush = getSvgView().mTintColor;
paint.setColor(brush);
break;
}
case 3: {
case 3:
{
if (contextElement != null && contextElement.fill != null) {
setupPaint(paint, opacity, contextElement.fill);
}
break;
}
case 4: {
case 4:
{
if (contextElement != null && contextElement.stroke != null) {
setupPaint(paint, opacity, contextElement.stroke);
}
break;
}
}
}
abstract Path getPath(Canvas canvas, Paint paint);
@@ -599,11 +597,10 @@ abstract public class RenderableView extends VirtualView {
initBounds();
if (
(mRegion == null || !mRegion.contains(x, y)) &&
(mStrokeRegion == null || !mStrokeRegion.contains(x, y) &&
(mMarkerRegion == null || !mMarkerRegion.contains(x, y)))
) {
if ((mRegion == null || !mRegion.contains(x, y))
&& (mStrokeRegion == null
|| !mStrokeRegion.contains(x, y)
&& (mMarkerRegion == null || !mMarkerRegion.contains(x, y)))) {
return -1;
}
@@ -651,14 +648,13 @@ abstract public class RenderableView extends VirtualView {
Region getRegion(Path path, RectF rectF) {
Region region = new Region();
region.setPath(path,
region.setPath(
path,
new Region(
(int) Math.floor(rectF.left),
(int) Math.floor(rectF.top),
(int) Math.ceil(rectF.right),
(int) Math.ceil(rectF.bottom)
)
);
(int) Math.ceil(rectF.bottom)));
return region;
}
@@ -670,8 +666,7 @@ abstract public class RenderableView extends VirtualView {
void mergeProperties(RenderableView target) {
ArrayList<String> targetAttributeList = target.getAttributeList();
if (targetAttributeList == null ||
targetAttributeList.size() == 0) {
if (targetAttributeList == null || targetAttributeList.size() == 0) {
return;
}

View File

@@ -6,77 +6,8 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.graphics.Matrix;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.JavaOnlyMap;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.MatrixMathHelper;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.PointerEvents;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.TransformHelper;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.ViewManagerDelegate;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.annotations.ReactPropGroup;
import com.facebook.react.viewmanagers.RNSVGCircleManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGCircleManagerInterface;
import com.facebook.react.viewmanagers.RNSVGClipPathManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGClipPathManagerInterface;
import com.facebook.react.viewmanagers.RNSVGDefsManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGDefsManagerInterface;
import com.facebook.react.viewmanagers.RNSVGEllipseManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGEllipseManagerInterface;
import com.facebook.react.viewmanagers.RNSVGForeignObjectManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGForeignObjectManagerInterface;
import com.facebook.react.viewmanagers.RNSVGGroupManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGGroupManagerInterface;
import com.facebook.react.viewmanagers.RNSVGImageManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGImageManagerInterface;
import com.facebook.react.viewmanagers.RNSVGLineManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGLineManagerInterface;
import com.facebook.react.viewmanagers.RNSVGLinearGradientManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGLinearGradientManagerInterface;
import com.facebook.react.viewmanagers.RNSVGMarkerManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGMarkerManagerInterface;
import com.facebook.react.viewmanagers.RNSVGMaskManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGMaskManagerInterface;
import com.facebook.react.viewmanagers.RNSVGPathManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGPathManagerInterface;
import com.facebook.react.viewmanagers.RNSVGPatternManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGPatternManagerInterface;
import com.facebook.react.viewmanagers.RNSVGRadialGradientManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGRadialGradientManagerInterface;
import com.facebook.react.viewmanagers.RNSVGRectManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGRectManagerInterface;
import com.facebook.react.viewmanagers.RNSVGSymbolManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGSymbolManagerInterface;
import com.facebook.react.viewmanagers.RNSVGTSpanManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGTSpanManagerInterface;
import com.facebook.react.viewmanagers.RNSVGTextManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGTextManagerInterface;
import com.facebook.react.viewmanagers.RNSVGTextPathManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGTextPathManagerInterface;
import com.facebook.react.viewmanagers.RNSVGUseManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGUseManagerInterface;
import java.util.Locale;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static com.facebook.react.uimanager.MatrixMathHelper.determinant;
import static com.facebook.react.uimanager.MatrixMathHelper.inverse;
import static com.facebook.react.uimanager.MatrixMathHelper.multiplyVectorByMatrix;
@@ -142,9 +73,72 @@ import static com.horcrux.svg.RenderableView.CAP_ROUND;
import static com.horcrux.svg.RenderableView.FILL_RULE_NONZERO;
import static com.horcrux.svg.RenderableView.JOIN_ROUND;
/**
* ViewManager for DefinitionView RNSVG views
*/
import android.graphics.Matrix;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.JavaOnlyMap;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.MatrixMathHelper;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.PointerEvents;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.TransformHelper;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.ViewManagerDelegate;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.annotations.ReactPropGroup;
import com.facebook.react.viewmanagers.RNSVGCircleManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGCircleManagerInterface;
import com.facebook.react.viewmanagers.RNSVGClipPathManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGClipPathManagerInterface;
import com.facebook.react.viewmanagers.RNSVGDefsManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGDefsManagerInterface;
import com.facebook.react.viewmanagers.RNSVGEllipseManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGEllipseManagerInterface;
import com.facebook.react.viewmanagers.RNSVGForeignObjectManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGForeignObjectManagerInterface;
import com.facebook.react.viewmanagers.RNSVGGroupManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGGroupManagerInterface;
import com.facebook.react.viewmanagers.RNSVGImageManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGImageManagerInterface;
import com.facebook.react.viewmanagers.RNSVGLineManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGLineManagerInterface;
import com.facebook.react.viewmanagers.RNSVGLinearGradientManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGLinearGradientManagerInterface;
import com.facebook.react.viewmanagers.RNSVGMarkerManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGMarkerManagerInterface;
import com.facebook.react.viewmanagers.RNSVGMaskManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGMaskManagerInterface;
import com.facebook.react.viewmanagers.RNSVGPathManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGPathManagerInterface;
import com.facebook.react.viewmanagers.RNSVGPatternManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGPatternManagerInterface;
import com.facebook.react.viewmanagers.RNSVGRadialGradientManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGRadialGradientManagerInterface;
import com.facebook.react.viewmanagers.RNSVGRectManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGRectManagerInterface;
import com.facebook.react.viewmanagers.RNSVGSymbolManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGSymbolManagerInterface;
import com.facebook.react.viewmanagers.RNSVGTSpanManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGTSpanManagerInterface;
import com.facebook.react.viewmanagers.RNSVGTextManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGTextManagerInterface;
import com.facebook.react.viewmanagers.RNSVGTextPathManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGTextPathManagerInterface;
import com.facebook.react.viewmanagers.RNSVGUseManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGUseManagerInterface;
import java.util.Locale;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** ViewManager for DefinitionView RNSVG views */
class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<VirtualView> {
protected final SVGClass svgClass;
@@ -212,7 +206,6 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
PADDING_BOTTOM,
PADDING_START,
PADDING_END,
BORDER_WIDTH,
BORDER_START_WIDTH,
BORDER_END_WIDTH,
@@ -220,8 +213,7 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
BORDER_BOTTOM_WIDTH,
BORDER_LEFT_WIDTH,
BORDER_RIGHT_WIDTH,
}
)
})
public void ignoreLayoutProps(int index, Dynamic value) {}
}
@@ -290,16 +282,12 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
if (!isZero(matrix[0][3]) || !isZero(matrix[1][3]) || !isZero(matrix[2][3])) {
// rightHandSide is the right hand side of the equation.
// rightHandSide is a vector, or point in 3d space relative to the origin.
double[] rightHandSide = { matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3] };
double[] rightHandSide = {matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]};
// Solve the equation by inverting perspectiveMatrix and multiplying
// rightHandSide by the inverse.
double[] inversePerspectiveMatrix = inverse(
perspectiveMatrix
);
double[] transposedInversePerspectiveMatrix = transpose(
inversePerspectiveMatrix
);
double[] inversePerspectiveMatrix = inverse(perspectiveMatrix);
double[] transposedInversePerspectiveMatrix = transpose(inversePerspectiveMatrix);
multiplyVectorByMatrix(rightHandSide, transposedInversePerspectiveMatrix, perspective);
} else {
// no perspective
@@ -365,7 +353,10 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
// Based on: http://nghiaho.com/?page_id=846
double conv = 180 / Math.PI;
rotationDegrees[0] = roundTo3Places(-Math.atan2(row[2][1], row[2][2]) * conv);
rotationDegrees[1] = roundTo3Places(-Math.atan2(-row[2][0], Math.sqrt(row[2][1] * row[2][1] + row[2][2] * row[2][2])) * conv);
rotationDegrees[1] =
roundTo3Places(
-Math.atan2(-row[2][0], Math.sqrt(row[2][1] * row[2][1] + row[2][2] * row[2][2]))
* conv);
rotationDegrees[2] = roundTo3Places(-Math.atan2(row[1][0], row[0][0]) * conv);
}
@@ -385,7 +376,8 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
double[] perspectiveArray = sMatrixDecompositionContext.perspective;
if (perspectiveArray.length > PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX) {
float invertedCameraDistance = (float) perspectiveArray[PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX];
float invertedCameraDistance =
(float) perspectiveArray[PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX];
if (invertedCameraDistance == 0) {
// Default camera distance, before scale multiplier (1280)
invertedCameraDistance = 0.00078125f;
@@ -399,9 +391,9 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
// calculation, so squaring and a normalization value of
// sqrt(5) produces an exact replica with iOS.
// For more information, see https://github.com/facebook/react-native/pull/18302
float normalizedCameraDistance = scale * scale * cameraDistance * CAMERA_DISTANCE_NORMALIZATION_MULTIPLIER;
float normalizedCameraDistance =
scale * scale * cameraDistance * CAMERA_DISTANCE_NORMALIZATION_MULTIPLIER;
view.setCameraDistance(normalizedCameraDistance);
}
}
@@ -487,7 +479,6 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
node.setDisplay(display);
}
@ReactProp(name = "matrix")
public void setMatrix(V node, Dynamic matrixArray) {
node.setMatrix(matrixArray);
@@ -515,18 +506,20 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
private void invalidateSvgView(V node) {
SvgView view = node.getSvgView();
if (view!= null) {
if (view != null) {
view.invalidate();
}
if (node instanceof TextView) {
((TextView)node).getTextContainer().clearChildCache();
((TextView) node).getTextContainer().clearChildCache();
}
}
@Override
protected void addEventEmitters(@Nonnull ThemedReactContext reactContext, @Nonnull VirtualView view) {
protected void addEventEmitters(
@Nonnull ThemedReactContext reactContext, @Nonnull VirtualView view) {
super.addEventEmitters(reactContext, view);
view.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
view.setOnHierarchyChangeListener(
new ViewGroup.OnHierarchyChangeListener() {
@Override
public void onChildViewAdded(View view, View view1) {
if (view instanceof VirtualView) {
@@ -546,8 +539,8 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
/**
* Callback that will be triggered after all properties are updated in current update transaction
* (all @ReactProp handlers for properties updated in current transaction have been called). If
* you want to override this method you should call super.onAfterUpdateTransaction from it as
* the parent class of the ViewManager may rely on callback being executed.
* you want to override this method you should call super.onAfterUpdateTransaction from it as the
* parent class of the ViewManager may rely on callback being executed.
*/
protected void onAfterUpdateTransaction(@Nonnull V node) {
super.onAfterUpdateTransaction(node);
@@ -626,7 +619,6 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
}
}
private static final SparseArray<RenderableView> mTagToRenderableView = new SparseArray<>();
private static final SparseArray<Runnable> mTagToRunnable = new SparseArray<>();
@@ -652,16 +644,14 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
super.onDropViewInstance(view);
mTagToRenderableView.remove(view.getId());
}
}
/**
* ViewManager for Renderable RNSVG views
*/
/** ViewManager for Renderable RNSVG views */
class RenderableViewManager<T extends RenderableView> extends VirtualViewManager<T> {
RenderableViewManager(SVGClass svgclass) {
super(svgclass);
}
static class GroupViewManagerAbstract<U extends GroupView> extends RenderableViewManager<U> {
GroupViewManagerAbstract(SVGClass svgClass) {
super(svgClass);
@@ -717,7 +707,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class GroupViewManager extends GroupViewManagerAbstract<GroupView> implements RNSVGGroupManagerInterface<GroupView> {
static class GroupViewManager extends GroupViewManagerAbstract<GroupView>
implements RNSVGGroupManagerInterface<GroupView> {
GroupViewManager() {
super(SVGClass.RNSVGGroup);
mDelegate = new RNSVGGroupManagerDelegate(this);
@@ -725,13 +716,13 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<GroupView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
}
static class PathViewManager extends RenderableViewManager<PathView> implements RNSVGPathManagerInterface<PathView> {
static class PathViewManager extends RenderableViewManager<PathView>
implements RNSVGPathManagerInterface<PathView> {
PathViewManager() {
super(SVGClass.RNSVGPath);
mDelegate = new RNSVGPathManagerDelegate(this);
@@ -739,7 +730,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<PathView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -863,7 +854,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class TextViewManager extends TextViewManagerAbstract<TextView> implements RNSVGTextManagerInterface<TextView> {
static class TextViewManager extends TextViewManagerAbstract<TextView>
implements RNSVGTextManagerInterface<TextView> {
TextViewManager() {
super(SVGClass.RNSVGText);
mDelegate = new RNSVGTextManagerDelegate(this);
@@ -871,7 +863,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<TextView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -879,10 +871,10 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
super(svgClass);
mDelegate = new RNSVGTextManagerDelegate(this);
}
}
static class TSpanViewManager extends TextViewManagerAbstract<TSpanView> implements RNSVGTSpanManagerInterface<TSpanView> {
static class TSpanViewManager extends TextViewManagerAbstract<TSpanView>
implements RNSVGTSpanManagerInterface<TSpanView> {
TSpanViewManager() {
super(SVGClass.RNSVGTSpan);
mDelegate = new RNSVGTSpanManagerDelegate(this);
@@ -895,7 +887,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<TSpanView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -903,10 +895,10 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
public void setContent(TSpanView node, @Nullable String content) {
node.setContent(content);
}
}
static class TextPathViewManager extends TextViewManagerAbstract<TextPathView> implements RNSVGTextPathManagerInterface<TextPathView> {
static class TextPathViewManager extends TextViewManagerAbstract<TextPathView>
implements RNSVGTextPathManagerInterface<TextPathView> {
TextPathViewManager() {
super(SVGClass.RNSVGTextPath);
mDelegate = new RNSVGTextPathManagerDelegate(this);
@@ -914,12 +906,12 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
TextPathViewManager(SVGClass svgClass) {
super(svgClass);
mDelegate = new RNSVGTextPathManagerDelegate (this);
mDelegate = new RNSVGTextPathManagerDelegate(this);
}
private final ViewManagerDelegate<TextPathView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -964,7 +956,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class ImageViewManager extends RenderableViewManager<ImageView> implements RNSVGImageManagerInterface<ImageView> {
static class ImageViewManager extends RenderableViewManager<ImageView>
implements RNSVGImageManagerInterface<ImageView> {
ImageViewManager() {
super(SVGClass.RNSVGImage);
mDelegate = new RNSVGImageManagerDelegate(this);
@@ -972,7 +965,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<ImageView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -1031,7 +1024,6 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
node.setSrc(src);
}
@ReactProp(name = "align")
public void setAlign(ImageView node, String align) {
node.setAlign(align);
@@ -1043,7 +1035,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class CircleViewManager extends RenderableViewManager<CircleView> implements RNSVGCircleManagerInterface<CircleView> {
static class CircleViewManager extends RenderableViewManager<CircleView>
implements RNSVGCircleManagerInterface<CircleView> {
CircleViewManager() {
super(SVGClass.RNSVGCircle);
mDelegate = new RNSVGCircleManagerDelegate(this);
@@ -1051,7 +1044,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<CircleView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -1086,7 +1079,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class EllipseViewManager extends RenderableViewManager<EllipseView> implements RNSVGEllipseManagerInterface<EllipseView> {
static class EllipseViewManager extends RenderableViewManager<EllipseView>
implements RNSVGEllipseManagerInterface<EllipseView> {
EllipseViewManager() {
super(SVGClass.RNSVGEllipse);
mDelegate = new RNSVGEllipseManagerDelegate(this);
@@ -1094,7 +1088,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<EllipseView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -1139,7 +1133,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class LineViewManager extends RenderableViewManager<LineView> implements RNSVGLineManagerInterface<LineView> {
static class LineViewManager extends RenderableViewManager<LineView>
implements RNSVGLineManagerInterface<LineView> {
LineViewManager() {
super(SVGClass.RNSVGLine);
@@ -1148,7 +1143,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<LineView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -1193,7 +1188,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class RectViewManager extends RenderableViewManager<RectView> implements RNSVGRectManagerInterface<RectView> {
static class RectViewManager extends RenderableViewManager<RectView>
implements RNSVGRectManagerInterface<RectView> {
RectViewManager() {
super(SVGClass.RNSVGRect);
@@ -1202,7 +1198,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<RectView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -1244,47 +1240,41 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
@Override
public void setY(RectView view, @Nullable String value) {
view.setY(value);
}
@Override
public void setRectheight(RectView view, @Nullable String value) {
view.setHeight(value);
}
@Override
public void setRectwidth(RectView view, @Nullable String value) {
view.setWidth(value);
}
@Override
public void setHeight(RectView view, @Nullable String value) {
view.setHeight(value);
}
@Override
public void setWidth(RectView view, @Nullable String value) {
view.setWidth(value);
}
@Override
public void setRx(RectView view, @Nullable String value) {
view.setRx(value);
}
@Override
public void setRy(RectView view, @Nullable String value) {
view.setRy(value);
}
}
static class ClipPathViewManager extends GroupViewManagerAbstract<ClipPathView> implements RNSVGClipPathManagerInterface<ClipPathView>{
static class ClipPathViewManager extends GroupViewManagerAbstract<ClipPathView>
implements RNSVGClipPathManagerInterface<ClipPathView> {
ClipPathViewManager() {
super(SVGClass.RNSVGClipPath);
mDelegate = new RNSVGClipPathManagerDelegate(this);
@@ -1292,12 +1282,13 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<ClipPathView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
}
static class DefsViewManager extends VirtualViewManager<DefsView> implements RNSVGDefsManagerInterface<DefsView> {
static class DefsViewManager extends VirtualViewManager<DefsView>
implements RNSVGDefsManagerInterface<DefsView> {
DefsViewManager() {
super(SVGClass.RNSVGDefs);
@@ -1306,12 +1297,13 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<DefsView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
}
static class UseViewManager extends RenderableViewManager<UseView> implements RNSVGUseManagerInterface<UseView> {
static class UseViewManager extends RenderableViewManager<UseView>
implements RNSVGUseManagerInterface<UseView> {
UseViewManager() {
super(SVGClass.RNSVGUse);
@@ -1320,7 +1312,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<UseView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -1380,7 +1372,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class SymbolManager extends GroupViewManagerAbstract<SymbolView> implements RNSVGSymbolManagerInterface<SymbolView> {
static class SymbolManager extends GroupViewManagerAbstract<SymbolView>
implements RNSVGSymbolManagerInterface<SymbolView> {
SymbolManager() {
super(SVGClass.RNSVGSymbol);
mDelegate = new RNSVGSymbolManagerDelegate(this);
@@ -1388,7 +1381,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<SymbolView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -1423,7 +1416,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class PatternManager extends GroupViewManagerAbstract<PatternView> implements RNSVGPatternManagerInterface<PatternView> {
static class PatternManager extends GroupViewManagerAbstract<PatternView>
implements RNSVGPatternManagerInterface<PatternView> {
PatternManager() {
super(SVGClass.RNSVGPattern);
mDelegate = new RNSVGPatternManagerDelegate(this);
@@ -1431,7 +1425,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<PatternView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -1531,7 +1525,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class MaskManager extends GroupViewManagerAbstract<MaskView> implements RNSVGMaskManagerInterface<MaskView> {
static class MaskManager extends GroupViewManagerAbstract<MaskView>
implements RNSVGMaskManagerInterface<MaskView> {
MaskManager() {
super(SVGClass.RNSVGMask);
mDelegate = new RNSVGMaskManagerDelegate(this);
@@ -1539,7 +1534,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<MaskView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -1609,7 +1604,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class ForeignObjectManager extends GroupViewManagerAbstract<ForeignObjectView> implements RNSVGForeignObjectManagerInterface<ForeignObjectView> {
static class ForeignObjectManager extends GroupViewManagerAbstract<ForeignObjectView>
implements RNSVGForeignObjectManagerInterface<ForeignObjectView> {
ForeignObjectManager() {
super(SVGClass.RNSVGForeignObject);
mDelegate = new RNSVGForeignObjectManagerDelegate(this);
@@ -1617,9 +1613,10 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<ForeignObjectView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@ReactProp(name = "x")
public void setX(ForeignObjectView node, Dynamic x) {
node.setX(x);
@@ -1671,7 +1668,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class MarkerManager extends GroupViewManagerAbstract<MarkerView> implements RNSVGMarkerManagerInterface<MarkerView> {
static class MarkerManager extends GroupViewManagerAbstract<MarkerView>
implements RNSVGMarkerManagerInterface<MarkerView> {
MarkerManager() {
super(SVGClass.RNSVGMarker);
mDelegate = new RNSVGMarkerManagerDelegate(this);
@@ -1679,7 +1677,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<MarkerView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -1764,7 +1762,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class LinearGradientManager extends VirtualViewManager<LinearGradientView> implements RNSVGLinearGradientManagerInterface<LinearGradientView> {
static class LinearGradientManager extends VirtualViewManager<LinearGradientView>
implements RNSVGLinearGradientManagerInterface<LinearGradientView> {
LinearGradientManager() {
super(SVGClass.RNSVGLinearGradient);
@@ -1773,11 +1772,10 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<RectView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@ReactProp(name = "x1")
public void setX1(LinearGradientView node, Dynamic x1) {
node.setX1(x1);
@@ -1834,7 +1832,8 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
}
}
static class RadialGradientManager extends VirtualViewManager<RadialGradientView> implements RNSVGRadialGradientManagerInterface<RadialGradientView> {
static class RadialGradientManager extends VirtualViewManager<RadialGradientView>
implements RNSVGRadialGradientManagerInterface<RadialGradientView> {
RadialGradientManager() {
super(SVGClass.RNSVGRadialGradient);
@@ -1843,7 +1842,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<RectView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -1942,7 +1941,6 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
node.setFillRule(fillRule);
}
@ReactProp(name = "stroke")
public void setStroke(T node, @Nullable Dynamic strokeColors) {
node.setStroke(strokeColors);
@@ -2000,5 +1998,4 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
public void setPropList(T node, @Nullable ReadableArray propList) {
node.setPropList(propList);
}
}

View File

@@ -2,7 +2,6 @@ package com.horcrux.svg;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReadableArray;
import java.util.ArrayList;
class SVGLength {
@@ -121,12 +120,14 @@ class SVGLength {
static ArrayList<SVGLength> arrayFrom(Dynamic dynamic) {
switch (dynamic.getType()) {
case Number: {
case Number:
{
ArrayList<SVGLength> list = new ArrayList<>(1);
list.add(new SVGLength(dynamic.asDouble()));
return list;
}
case Array: {
case Array:
{
ReadableArray arr = dynamic.asArray();
int size = arr.size();
ArrayList<SVGLength> list = new ArrayList<>(size);
@@ -136,7 +137,8 @@ class SVGLength {
}
return list;
}
case String: {
case String:
{
ArrayList<SVGLength> list = new ArrayList<>(1);
list.add(new SVGLength(dynamic.asString()));
return list;

View File

@@ -6,24 +6,21 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import static com.horcrux.svg.RenderableViewManager.*;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.soloader.SoLoader;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
import static com.horcrux.svg.RenderableViewManager.*;
public class SvgPackage implements ReactPackage {
@Nonnull
@@ -64,9 +61,7 @@ public class SvgPackage implements ReactPackage {
SoLoader.loadLibrary("rnsvg_modules");
}
return Arrays.<NativeModule>asList(
new SvgViewModule(reactContext),
new RNSVGRenderableManager(reactContext)
);
new SvgViewModule(reactContext), new RNSVGRenderableManager(reactContext));
}
@SuppressWarnings("unused")

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -20,9 +19,6 @@ import android.graphics.Typeface;
import android.util.Base64;
import android.view.View;
import android.view.ViewParent;
import androidx.annotation.NonNull;
import com.facebook.react.bridge.ColorPropConverter;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
@@ -30,20 +26,16 @@ import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.ReactCompoundView;
import com.facebook.react.uimanager.ReactCompoundViewGroup;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.view.ReactViewGroup;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Custom {@link View} implementation that draws an RNSVGSvg React view and its children.
*/
/** Custom {@link View} implementation that draws an RNSVGSvg React view and its children. */
@SuppressLint("ViewConstructor")
public class SvgView extends FabricEnabledViewGroup implements ReactCompoundView, ReactCompoundViewGroup {
public class SvgView extends FabricEnabledViewGroup
implements ReactCompoundView, ReactCompoundViewGroup {
@Override
public boolean interceptsTouchEvent(float touchX, float touchY) {
@@ -169,7 +161,7 @@ public class SvgView extends FabricEnabledViewGroup implements ReactCompoundView
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof VirtualView) {
VirtualView n = ((VirtualView)node);
VirtualView n = ((VirtualView) node);
n.clearChildCache();
}
}
@@ -269,14 +261,16 @@ public class SvgView extends FabricEnabledViewGroup implements ReactCompoundView
mRendered = true;
float width = getWidth();
float height = getHeight();
boolean invalid = Float.isNaN(width) || Float.isNaN(height) || width < 1 || height < 1 || (Math.log10(width) + Math.log10(height) > 42);
boolean invalid =
Float.isNaN(width)
|| Float.isNaN(height)
|| width < 1
|| height < 1
|| (Math.log10(width) + Math.log10(height) > 42);
if (invalid) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(
(int) width,
(int) height,
Bitmap.Config.ARGB_8888);
Bitmap bitmap = Bitmap.createBitmap((int) width, (int) height, Bitmap.Config.ARGB_8888);
drawChildren(new Canvas(bitmap));
return bitmap;
@@ -299,7 +293,7 @@ public class SvgView extends FabricEnabledViewGroup implements ReactCompoundView
width = (float) PropHelper.fromRelative(mbbWidth, width, 0f, mScale, 12);
height = (float) PropHelper.fromRelative(mbbHeight, height, 0f, mScale, 12);
}
RectF eRect = new RectF(0,0, width, height);
RectF eRect = new RectF(0, 0, width, height);
if (nested) {
canvas.clipRect(eRect);
}
@@ -314,18 +308,17 @@ public class SvgView extends FabricEnabledViewGroup implements ReactCompoundView
paint.setTypeface(Typeface.DEFAULT);
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof VirtualView) {
((VirtualView)node).saveDefinition();
((VirtualView) node).saveDefinition();
}
}
for (int i = 0; i < getChildCount(); i++) {
View lNode = getChildAt(i);
if (lNode instanceof VirtualView) {
VirtualView node = (VirtualView)lNode;
VirtualView node = (VirtualView) lNode;
int count = node.saveAndSetupCanvas(canvas, mViewBoxMatrix);
node.render(canvas, paint, 1f);
node.restoreCanvas(canvas, count);
@@ -338,14 +331,12 @@ public class SvgView extends FabricEnabledViewGroup implements ReactCompoundView
}
private RectF getViewBox() {
return new RectF(mMinX * mScale, mMinY * mScale, (mMinX + mVbWidth) * mScale, (mMinY + mVbHeight) * mScale);
return new RectF(
mMinX * mScale, mMinY * mScale, (mMinX + mVbWidth) * mScale, (mMinY + mVbHeight) * mScale);
}
String toDataURL() {
Bitmap bitmap = Bitmap.createBitmap(
getWidth(),
getHeight(),
Bitmap.Config.ARGB_8888);
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
clearChildCache();
drawChildren(new Canvas(bitmap));
@@ -359,10 +350,7 @@ public class SvgView extends FabricEnabledViewGroup implements ReactCompoundView
}
String toDataURL(int width, int height) {
Bitmap bitmap = Bitmap.createBitmap(
width,
height,
Bitmap.Config.ARGB_8888);
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
clearChildCache();
drawChildren(new Canvas(bitmap));
@@ -390,7 +378,7 @@ public class SvgView extends FabricEnabledViewGroup implements ReactCompoundView
return getId();
}
float[] transformed = { touchX, touchY };
float[] transformed = {touchX, touchY};
mInvViewBoxMatrix.mapPoints(transformed);
int count = getChildCount();

View File

@@ -6,26 +6,23 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.util.SparseArray;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewManagerDelegate;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.view.ReactViewGroup;
import com.facebook.react.views.view.ReactViewManager;
import com.facebook.react.viewmanagers.RNSVGSvgViewManagerDelegate;
import com.facebook.react.viewmanagers.RNSVGSvgViewManagerInterface;
import com.facebook.react.views.view.ReactViewGroup;
import com.facebook.react.views.view.ReactViewManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* ViewManager for RNSVGSvgView React views. Renders as a {@link SvgView} and handles
* invalidating the native view on view updates happening in the underlying tree.
* ViewManager for RNSVGSvgView React views. Renders as a {@link SvgView} and handles invalidating
* the native view on view updates happening in the underlying tree.
*/
class SvgViewManager extends ReactViewManager implements RNSVGSvgViewManagerInterface<SvgView> {
@@ -36,7 +33,7 @@ class SvgViewManager extends ReactViewManager implements RNSVGSvgViewManagerInte
private final ViewManagerDelegate<SvgView> mDelegate;
protected ViewManagerDelegate getDelegate(){
protected ViewManagerDelegate getDelegate() {
return mDelegate;
}
@@ -165,5 +162,4 @@ class SvgViewManager extends ReactViewManager implements RNSVGSvgViewManagerInte
public void setBbHeight(SvgView view, @Nullable String value) {
view.setBbHeight(value);
}
}

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import com.facebook.react.bridge.Callback;
@@ -15,7 +14,6 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.UiThreadUtil;
import javax.annotation.Nonnull;
class SvgViewModule extends ReactContextBaseJavaModule {
@@ -29,7 +27,8 @@ class SvgViewModule extends ReactContextBaseJavaModule {
return "RNSVGSvgViewManager";
}
private static void toDataURL(final int tag, final ReadableMap options, final Callback successCallback, final int attempt) {
private static void toDataURL(
final int tag, final ReadableMap options, final Callback successCallback, final int attempt) {
UiThreadUtil.runOnUiThread(
new Runnable() {
@Override
@@ -37,14 +36,17 @@ class SvgViewModule extends ReactContextBaseJavaModule {
SvgView svg = SvgViewManager.getSvgViewByTag(tag);
if (svg == null) {
SvgViewManager.runWhenViewIsAvailable(tag, new Runnable() {
SvgViewManager.runWhenViewIsAvailable(
tag,
new Runnable() {
@Override
public void run() {
SvgView svg = SvgViewManager.getSvgViewByTag(tag);
if (svg == null) { // Should never happen
return;
}
svg.setToDataUrlTask(new Runnable() {
svg.setToDataUrlTask(
new Runnable() {
@Override
public void run() {
toDataURL(tag, options, successCallback, attempt + 1);
@@ -53,7 +55,8 @@ class SvgViewModule extends ReactContextBaseJavaModule {
}
});
} else if (svg.notRendered()) {
svg.setToDataUrlTask(new Runnable() {
svg.setToDataUrlTask(
new Runnable() {
@Override
public void run() {
toDataURL(tag, options, successCallback, attempt + 1);
@@ -62,18 +65,13 @@ class SvgViewModule extends ReactContextBaseJavaModule {
} else {
if (options != null) {
successCallback.invoke(
svg.toDataURL(
options.getInt("width"),
options.getInt("height")
)
);
svg.toDataURL(options.getInt("width"), options.getInt("height")));
} else {
successCallback.invoke(svg.toDataURL());
}
}
}
}
);
});
}
@SuppressWarnings("unused")

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -14,7 +13,6 @@ import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
@@ -75,7 +73,12 @@ class SymbolView extends GroupView {
void drawSymbol(Canvas canvas, Paint paint, float opacity, float width, float height) {
if (mAlign != null) {
RectF vbRect = new RectF(mMinX * mScale, mMinY * mScale, (mMinX + mVbWidth) * mScale, (mMinY + mVbHeight) * mScale);
RectF vbRect =
new RectF(
mMinX * mScale,
mMinY * mScale,
(mMinX + mVbWidth) * mScale,
(mMinY + mVbHeight) * mScale);
RectF eRect = new RectF(0, 0, width, height);
Matrix viewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mAlign, mMeetOrSlice);
canvas.concat(viewBoxMatrix);

View File

@@ -6,9 +6,19 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import static android.graphics.Matrix.MTRANS_X;
import static android.graphics.Matrix.MTRANS_Y;
import static android.graphics.PathMeasure.POSITION_MATRIX_FLAG;
import static android.graphics.PathMeasure.TANGENT_MATRIX_FLAG;
import static com.horcrux.svg.TextProperties.AlignmentBaseline;
import static com.horcrux.svg.TextProperties.FontStyle;
import static com.horcrux.svg.TextProperties.FontVariantLigatures;
import static com.horcrux.svg.TextProperties.FontWeight;
import static com.horcrux.svg.TextProperties.TextAnchor;
import static com.horcrux.svg.TextProperties.TextPathMidLine;
import static com.horcrux.svg.TextProperties.TextPathSide;
import android.annotation.SuppressLint;
import android.content.res.AssetManager;
@@ -27,30 +37,14 @@ import android.text.StaticLayout;
import android.text.TextPaint;
import android.view.View;
import android.view.ViewParent;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.text.ReactFontManager;
import java.util.ArrayList;
import java.text.Bidi;
import java.util.ArrayList;
import javax.annotation.Nullable;
import static android.graphics.Matrix.MTRANS_X;
import static android.graphics.Matrix.MTRANS_Y;
import static android.graphics.PathMeasure.POSITION_MATRIX_FLAG;
import static android.graphics.PathMeasure.TANGENT_MATRIX_FLAG;
import static com.horcrux.svg.TextProperties.AlignmentBaseline;
import static com.horcrux.svg.TextProperties.FontStyle;
import static com.horcrux.svg.TextProperties.FontVariantLigatures;
import static com.horcrux.svg.TextProperties.FontWeight;
import static com.horcrux.svg.TextProperties.TextAnchor;
import static com.horcrux.svg.TextProperties.TextPathMidLine;
import static com.horcrux.svg.TextProperties.TextPathSide;
@SuppressLint("ViewConstructor")
class TSpanView extends TextView {
private static final double tau = 2 * Math.PI;
@@ -149,7 +143,8 @@ class TSpanView extends TextView {
boolean includeFontPadding = true;
SpannableString text = new SpannableString(mContent);
final double width = PropHelper.fromRelative(mInlineSize, canvas.getWidth(), 0, mScale, fontSize);
final double width =
PropHelper.fromRelative(mInlineSize, canvas.getWidth(), 0, mScale, fontSize);
StaticLayout layout = getStaticLayout(tp, align, includeFontPadding, text, (int) width);
int lineAscent = layout.getLineAscent(0);
@@ -165,16 +160,14 @@ class TSpanView extends TextView {
}
@SuppressWarnings("deprecation")
private StaticLayout getStaticLayout(TextPaint tp, Layout.Alignment align, boolean includeFontPadding, SpannableString text, int width) {
private StaticLayout getStaticLayout(
TextPaint tp,
Layout.Alignment align,
boolean includeFontPadding,
SpannableString text,
int width) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return new StaticLayout(
text,
tp,
width,
align,
1.f,
0.f,
includeFontPadding);
return new StaticLayout(text, tp, width, align, 1.f, 0.f, includeFontPadding);
} else {
return StaticLayout.Builder.obtain(text, 0, text.length(), tp, width)
.setAlignment(align)
@@ -186,26 +179,21 @@ class TSpanView extends TextView {
}
}
/**
* Implements visual to logical order converter.
*
* @author <a href="http://www.nesterovsky-bros.com">Nesterovsky bros</a>
*
* @param text an input text in visual order to convert.
* @return a String value in logical order.
*/
public static String visualToLogical(String text)
{
if ((text == null) || (text.length() == 0))
{
public static String visualToLogical(String text) {
if ((text == null) || (text.length() == 0)) {
return text;
}
Bidi bidi = new Bidi(text, Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
if (bidi.isLeftToRight())
{
if (bidi.isLeftToRight()) {
return text;
}
@@ -213,9 +201,8 @@ class TSpanView extends TextView {
byte[] levels = new byte[count];
Integer[] runs = new Integer[count];
for (int i = 0; i < count; i++)
{
levels[i] = (byte)bidi.getRunLevel(i);
for (int i = 0; i < count; i++) {
levels[i] = (byte) bidi.getRunLevel(i);
runs[i] = i;
}
@@ -223,22 +210,17 @@ class TSpanView extends TextView {
StringBuilder result = new StringBuilder();
for (int i = 0; i < count; i++)
{
for (int i = 0; i < count; i++) {
int index = runs[i];
int start = bidi.getRunStart(index);
int end = bidi.getRunLimit(index);
int level = levels[index];
if ((level & 1) != 0)
{
for (; --end >= start;)
{
if ((level & 1) != 0) {
for (; --end >= start; ) {
result.append(text.charAt(end));
}
}
else
{
} else {
result.append(text, start, end);
}
}
@@ -276,7 +258,7 @@ class TSpanView extends TextView {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof TextView) {
TextView text = (TextView)child;
TextView text = (TextView) child;
advance += text.getSubtreeTextChunksTotalAdvance(paint);
}
}
@@ -302,28 +284,33 @@ class TSpanView extends TextView {
return cachedAdvance;
}
final static String requiredFontFeatures = "'rlig', 'liga', 'clig', 'calt', 'locl', 'ccmp', 'mark', 'mkmk',";
final static String disableDiscretionaryLigatures = "'liga' 0, 'clig' 0, 'dlig' 0, 'hlig' 0, 'cala' 0, ";
final static String defaultFeatures = requiredFontFeatures + "'kern', ";
final static String additionalLigatures = "'hlig', 'cala', ";
final static String fontWeightTag = "'wght' ";
static final String requiredFontFeatures =
"'rlig', 'liga', 'clig', 'calt', 'locl', 'ccmp', 'mark', 'mkmk',";
static final String disableDiscretionaryLigatures =
"'liga' 0, 'clig' 0, 'dlig' 0, 'hlig' 0, 'cala' 0, ";
static final String defaultFeatures = requiredFontFeatures + "'kern', ";
static final String additionalLigatures = "'hlig', 'cala', ";
static final String fontWeightTag = "'wght' ";
private void applySpacingAndFeatures(Paint paint, FontData font) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
double letterSpacing = font.letterSpacing;
paint.setLetterSpacing((float) (letterSpacing / (font.fontSize * mScale)));
final boolean allowOptionalLigatures = letterSpacing == 0 &&
font.fontVariantLigatures == FontVariantLigatures.normal;
final boolean allowOptionalLigatures =
letterSpacing == 0 && font.fontVariantLigatures == FontVariantLigatures.normal;
if (allowOptionalLigatures) {
paint.setFontFeatureSettings(defaultFeatures + additionalLigatures + font.fontFeatureSettings);
paint.setFontFeatureSettings(
defaultFeatures + additionalLigatures + font.fontFeatureSettings);
} else {
paint.setFontFeatureSettings(defaultFeatures + disableDiscretionaryLigatures + font.fontFeatureSettings);
paint.setFontFeatureSettings(
defaultFeatures + disableDiscretionaryLigatures + font.fontFeatureSettings);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
paint.setFontVariationSettings(fontWeightTag + font.absoluteFontWeight + font.fontVariationSettings);
paint.setFontVariationSettings(
fontWeightTag + font.absoluteFontWeight + font.fontVariationSettings);
}
}
}
@@ -432,8 +419,8 @@ class TSpanView extends TextView {
user agents should not apply optional ligatures.
https://www.w3.org/TR/css-text-3/#letter-spacing-property
*/
final boolean allowOptionalLigatures = letterSpacing == 0 &&
font.fontVariantLigatures == FontVariantLigatures.normal;
final boolean allowOptionalLigatures =
letterSpacing == 0 && font.fontVariantLigatures == FontVariantLigatures.normal;
/*
For OpenType fonts, discretionary ligatures include those enabled by
@@ -494,13 +481,16 @@ class TSpanView extends TextView {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// String arabic = "'isol', 'fina', 'medi', 'init', 'rclt', 'mset', 'curs', ";
if (allowOptionalLigatures) {
paint.setFontFeatureSettings(defaultFeatures + additionalLigatures + font.fontFeatureSettings);
paint.setFontFeatureSettings(
defaultFeatures + additionalLigatures + font.fontFeatureSettings);
} else {
paint.setFontFeatureSettings(defaultFeatures + disableDiscretionaryLigatures + font.fontFeatureSettings);
paint.setFontFeatureSettings(
defaultFeatures + disableDiscretionaryLigatures + font.fontFeatureSettings);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
paint.setFontVariationSettings(fontWeightTag + font.absoluteFontWeight + font.fontVariationSettings);
paint.setFontVariationSettings(
fontWeightTag + font.absoluteFontWeight + font.fontVariationSettings);
}
}
// OpenType.js font data
@@ -607,11 +597,13 @@ class TSpanView extends TextView {
a point on the path equal distance in both directions from the initial position on
the path is reached.
*/
final double absoluteStartOffset = getAbsoluteStartOffset(textPath.getStartOffset(), pathLength, fontSize);
final double absoluteStartOffset =
getAbsoluteStartOffset(textPath.getStartOffset(), pathLength, fontSize);
offset += absoluteStartOffset;
if (isClosed) {
final double halfPathDistance = pathLength / 2;
startOfRendering = absoluteStartOffset + (textAnchor == TextAnchor.middle ? -halfPathDistance : 0);
startOfRendering =
absoluteStartOffset + (textAnchor == TextAnchor.middle ? -halfPathDistance : 0);
endOfRendering = startOfRendering + pathLength;
}
/*
@@ -700,7 +692,8 @@ class TSpanView extends TextView {
*/
double scaleSpacingAndGlyphs = 1;
if (mTextLength != null) {
final double author = PropHelper.fromRelative(mTextLength, canvas.getWidth(), 0, mScale, fontSize);
final double author =
PropHelper.fromRelative(mTextLength, canvas.getWidth(), 0, mScale, fontSize);
if (author < 0) {
throw new IllegalArgumentException("Negative textLength value");
}
@@ -784,7 +777,8 @@ class TSpanView extends TextView {
break;
case middle:
// Align the vertical midpoint of the box with the baseline of the parent box plus half the x-height of the parent.
// Align the vertical midpoint of the box with the baseline of the parent box plus half
// the x-height of the parent.
// middle = x height / 2
Rect bounds = new Rect();
// this will just retrieve the bounding rect for 'x'
@@ -907,7 +901,8 @@ class TSpanView extends TextView {
break;
default:
baselineShift -= PropHelper.fromRelative(baselineShiftString, mScale * fontSize, mScale, fontSize);
baselineShift -=
PropHelper.fromRelative(baselineShiftString, mScale * fontSize, mScale, fontSize);
}
break;
}
@@ -1087,7 +1082,6 @@ class TSpanView extends TextView {
mid.preRotate((float) r);
Path glyph;
if (hasLigature) {
glyph = new Path();
@@ -1232,10 +1226,8 @@ class TSpanView extends TextView {
initBounds();
if (
(mRegion == null || !mRegion.contains(x, y)) &&
(mStrokeRegion == null || !mStrokeRegion.contains(x, y))
) {
if ((mRegion == null || !mRegion.contains(x, y))
&& (mStrokeRegion == null || !mStrokeRegion.contains(x, y))) {
return -1;
}

View File

@@ -6,22 +6,19 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import static com.horcrux.svg.TextProperties.*;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import javax.annotation.Nullable;
import static com.horcrux.svg.TextProperties.*;
@SuppressLint("ViewConstructor")
class TextPathView extends TextView {
@@ -113,7 +110,7 @@ class TextPathView extends TextView {
return null;
}
RenderableView view = (RenderableView)template;
RenderableView view = (RenderableView) template;
return view.getPath(canvas, paint);
}

View File

@@ -2,7 +2,6 @@ package com.horcrux.svg;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nonnull;
class TextProperties {
@@ -85,33 +84,36 @@ class TextProperties {
enum FontVariantLigatures {
normal,
@SuppressWarnings("unused")none
@SuppressWarnings("unused")
none
}
enum FontStyle {
normal,
italic,
@SuppressWarnings("unused")oblique
@SuppressWarnings("unused")
oblique
}
enum FontWeight {
// Absolute
Normal ("normal"),
Bold ("bold"),
w100 ("100"),
w200 ("200"),
w300 ("300"),
w400 ("400"),
w500 ("500"),
w600 ("600"),
w700 ("700"),
w800 ("800"),
w900 ("900"),
Normal("normal"),
Bold("bold"),
w100("100"),
w200("200"),
w300("300"),
w400("400"),
w500("500"),
w600("600"),
w700("700"),
w800("800"),
w900("900"),
// Relative
Bolder ("bolder"),
Lighter ("lighter");
Bolder("bolder"),
Lighter("lighter");
private final String weight;
FontWeight(String weight) {
this.weight = weight;
}
@@ -125,6 +127,7 @@ class TextProperties {
}
private static final Map<String, FontWeight> weightToEnum = new HashMap<>();
static {
for (final FontWeight en : FontWeight.values()) {
weightToEnum.put(en.weight, en);
@@ -138,15 +141,13 @@ class TextProperties {
}
}
enum TextAnchor
{
enum TextAnchor {
start,
middle,
end
}
enum TextDecoration
{
enum TextDecoration {
None("none"),
Underline("underline"),
Overline("overline"),
@@ -154,18 +155,20 @@ class TextProperties {
Blink("blink");
private final String decoration;
TextDecoration(String decoration) {
this.decoration = decoration;
}
static TextDecoration getEnum(String strVal) {
if(!decorationToEnum.containsKey(strVal)) {
if (!decorationToEnum.containsKey(strVal)) {
throw new IllegalArgumentException("Unknown String Value: " + strVal);
}
return decorationToEnum.get(strVal);
}
private static final Map<String, TextDecoration> decorationToEnum = new HashMap<>();
static {
for (final TextDecoration en : TextDecoration.values()) {
decorationToEnum.put(en.decoration, en);
@@ -179,15 +182,15 @@ class TextProperties {
}
}
enum TextLengthAdjust
{
enum TextLengthAdjust {
spacing,
spacingAndGlyphs
}
enum TextPathMethod {
align,
@SuppressWarnings("unused")stretch
@SuppressWarnings("unused")
stretch
}
/*
@@ -198,16 +201,19 @@ class TextProperties {
*/
enum TextPathMidLine {
sharp,
@SuppressWarnings("unused")smooth
@SuppressWarnings("unused")
smooth
}
enum TextPathSide {
@SuppressWarnings("unused")left,
@SuppressWarnings("unused")
left,
right
}
enum TextPathSpacing {
@SuppressWarnings("unused")auto,
@SuppressWarnings("unused")
auto,
exact
}
}

View File

@@ -6,9 +6,11 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import static com.horcrux.svg.TextProperties.AlignmentBaseline;
import static com.horcrux.svg.TextProperties.TextLengthAdjust;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Paint;
@@ -16,19 +18,13 @@ import android.graphics.Path;
import android.graphics.Region;
import android.view.View;
import android.view.ViewParent;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.uimanager.annotations.ReactProp;
import java.util.ArrayList;
import javax.annotation.Nullable;
import static com.horcrux.svg.TextProperties.AlignmentBaseline;
import static com.horcrux.svg.TextProperties.TextLengthAdjust;
@SuppressLint("ViewConstructor")
class TextView extends GroupView {
SVGLength mInlineSize = null;
@@ -172,7 +168,6 @@ class TextView extends GroupView {
invalidate();
}
@ReactProp(name = "y")
public void setPositionY(Dynamic positionY) {
mPositionY = SVGLength.arrayFrom(positionY);
@@ -213,7 +208,7 @@ class TextView extends GroupView {
ViewParent parent = this.getParent();
while (parent != null) {
if (parent instanceof TextView) {
TextView node = (TextView)parent;
TextView node = (TextView) parent;
final AlignmentBaseline baseline = node.mAlignmentBaseline;
if (baseline != null) {
mAlignmentBaseline = baseline;
@@ -234,7 +229,7 @@ class TextView extends GroupView {
ViewParent parent = this.getParent();
while (parent != null) {
if (parent instanceof TextView) {
TextView node = (TextView)parent;
TextView node = (TextView) parent;
final String baselineShift = node.mBaselineShift;
if (baselineShift != null) {
mBaselineShift = baselineShift;
@@ -261,7 +256,8 @@ class TextView extends GroupView {
@Override
void pushGlyphContext() {
boolean isTextNode = !(this instanceof TextPathView) && !(this instanceof TSpanView);
getTextRootGlyphContext().pushContext(isTextNode, this, mFont, mPositionX, mPositionY, mDeltaX, mDeltaY, mRotate);
getTextRootGlyphContext()
.pushContext(isTextNode, this, mFont, mPositionX, mPositionY, mDeltaX, mDeltaY, mRotate);
}
TextView getTextAnchorRoot() {
@@ -270,7 +266,9 @@ class TextView extends GroupView {
TextView node = this;
ViewParent parent = this.getParent();
for (int i = font.size() - 1; i >= 0; i--) {
if (!(parent instanceof TextView) || font.get(i).textAnchor == TextProperties.TextAnchor.start || node.mPositionX != null) {
if (!(parent instanceof TextView)
|| font.get(i).textAnchor == TextProperties.TextAnchor.start
|| node.mPositionX != null) {
return node;
}
node = (TextView) parent;

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -14,7 +13,6 @@ import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
@@ -88,23 +86,28 @@ class UseView extends RenderableView {
VirtualView template = getSvgView().getDefinedTemplate(mHref);
if (template == null) {
FLog.w(ReactConstants.TAG, "`Use` element expected a pre-defined svg template as `href` prop, " +
"template named: " + mHref + " is not defined.");
FLog.w(
ReactConstants.TAG,
"`Use` element expected a pre-defined svg template as `href` prop, "
+ "template named: "
+ mHref
+ " is not defined.");
return;
}
template.clearCache();
canvas.translate((float) relativeOnWidth(mX), (float) relativeOnHeight(mY));
if (template instanceof RenderableView) {
((RenderableView)template).mergeProperties(this);
((RenderableView) template).mergeProperties(this);
}
int count = template.saveAndSetupCanvas(canvas, mCTM);
clip(canvas, paint);
if (template instanceof SymbolView) {
SymbolView symbol = (SymbolView)template;
symbol.drawSymbol(canvas, paint, opacity, (float) relativeOnWidth(mW), (float) relativeOnHeight(mH));
SymbolView symbol = (SymbolView) template;
symbol.drawSymbol(
canvas, paint, opacity, (float) relativeOnWidth(mW), (float) relativeOnHeight(mH));
} else {
template.draw(canvas, paint, opacity * mOpacity);
}
@@ -113,7 +116,7 @@ class UseView extends RenderableView {
template.restoreCanvas(canvas, count);
if (template instanceof RenderableView) {
((RenderableView)template).resetProperties();
((RenderableView) template).resetProperties();
}
}
@@ -129,8 +132,12 @@ class UseView extends RenderableView {
VirtualView template = getSvgView().getDefinedTemplate(mHref);
if (template == null) {
FLog.w(ReactConstants.TAG, "`Use` element expected a pre-defined svg template as `href` prop, " +
"template named: " + mHref + " is not defined.");
FLog.w(
ReactConstants.TAG,
"`Use` element expected a pre-defined svg template as `href` prop, "
+ "template named: "
+ mHref
+ " is not defined.");
return -1;
}
@@ -146,8 +153,12 @@ class UseView extends RenderableView {
Path getPath(Canvas canvas, Paint paint) {
VirtualView template = getSvgView().getDefinedTemplate(mHref);
if (template == null) {
FLog.w(ReactConstants.TAG, "`Use` element expected a pre-defined svg template as `href` prop, " +
"template named: " + mHref + " is not defined.");
FLog.w(
ReactConstants.TAG,
"`Use` element expected a pre-defined svg template as `href` prop, "
+ "template named: "
+ mHref
+ " is not defined.");
return null;
}
Path path = template.getPath(canvas, paint);

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.graphics.Matrix;
@@ -21,7 +20,8 @@ class ViewBox {
static Matrix getTransform(RectF vbRect, RectF eRect, String align, int meetOrSlice) {
// based on https://svgwg.org/svg2-draft/coords.html#ComputingAViewportsTransform
// Let vb-x, vb-y, vb-width, vb-height be the min-x, min-y, width and height values of the viewBox attribute respectively.
// Let vb-x, vb-y, vb-width, vb-height be the min-x, min-y, width and height values of the
// viewBox attribute respectively.
double vbX = vbRect.left;
double vbY = vbRect.top;
double vbWidth = vbRect.width();
@@ -33,7 +33,6 @@ class ViewBox {
double eWidth = eRect.width();
double eHeight = eRect.height();
// Initialize scale-x to e-width/vb-width.
double scaleX = eWidth / vbWidth;
@@ -62,8 +61,10 @@ class ViewBox {
translateY -= (eHeight - vbHeight * scale) / 2;
}
} else {
// If align is not 'none' and meetOrSlice is 'meet', set the larger of scale-x and scale-y to the smaller.
// Otherwise, if align is not 'none' and meetOrSlice is 'slice', set the smaller of scale-x and scale-y to the larger.
// If align is not 'none' and meetOrSlice is 'meet', set the larger of scale-x and scale-y to
// the smaller.
// Otherwise, if align is not 'none' and meetOrSlice is 'slice', set the smaller of scale-x
// and scale-y to the larger.
if (!align.equals("none") && meetOrSlice == MOS_MEET) {
scaleX = scaleY = Math.min(scaleX, scaleY);
@@ -90,7 +91,6 @@ class ViewBox {
if (align.contains("YMax")) {
translateY += (eHeight - vbHeight * scaleY);
}
}
// The transform applied to content contained by the element is given by

View File

@@ -1,5 +1,7 @@
package com.horcrux.svg;
import static com.horcrux.svg.FontData.DEFAULT_FONT_SIZE;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.Matrix;
@@ -9,7 +11,6 @@ import android.graphics.RectF;
import android.graphics.Region;
import android.view.View;
import android.view.ViewParent;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
@@ -23,15 +24,11 @@ import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.view.ReactViewGroup;
import java.util.ArrayList;
import javax.annotation.Nullable;
import static com.horcrux.svg.FontData.DEFAULT_FONT_SIZE;
@SuppressLint("ViewConstructor")
abstract public class VirtualView extends ReactViewGroup {
public abstract class VirtualView extends ReactViewGroup {
final ReactContext mContext;
VirtualView(ReactContext reactContext) {
@@ -47,7 +44,8 @@ abstract public class VirtualView extends ReactViewGroup {
*/
private static final double M_SQRT1_2l = 0.707106781186547524400844362104849039;
private static final float[] sRawMatrix = new float[]{
private static final float[] sRawMatrix =
new float[] {
1, 0, 0,
0, 1, 0,
0, 0, 1
@@ -136,7 +134,7 @@ abstract public class VirtualView extends ReactViewGroup {
for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i);
if (node instanceof VirtualView) {
((VirtualView)node).clearChildCache();
((VirtualView) node).clearChildCache();
}
}
}
@@ -148,7 +146,7 @@ abstract public class VirtualView extends ReactViewGroup {
if (!(parent instanceof VirtualView)) {
return;
}
node = (VirtualView)parent;
node = (VirtualView) parent;
if (node.mPath == null) {
return;
}
@@ -162,7 +160,7 @@ abstract public class VirtualView extends ReactViewGroup {
if (mTextRoot == null) {
while (node != null) {
if (node instanceof GroupView && ((GroupView) node).getGlyphContext() != null) {
mTextRoot = (GroupView)node;
mTextRoot = (GroupView) node;
break;
}
@@ -171,7 +169,7 @@ abstract public class VirtualView extends ReactViewGroup {
if (!(parent instanceof VirtualView)) {
node = null;
} else {
node = (VirtualView)parent;
node = (VirtualView) parent;
}
}
}
@@ -189,7 +187,6 @@ abstract public class VirtualView extends ReactViewGroup {
}
}
private double getFontSizeFromContext() {
if (fontSize != -1) {
return fontSize;
@@ -209,6 +206,7 @@ abstract public class VirtualView extends ReactViewGroup {
}
abstract void draw(Canvas canvas, Paint paint, float opacity);
void render(Canvas canvas, Paint paint, float opacity) {
draw(canvas, paint, opacity);
}
@@ -216,7 +214,7 @@ abstract public class VirtualView extends ReactViewGroup {
/**
* Sets up the transform matrix on the canvas before an element is drawn.
*
* NB: for perf reasons this does not apply opacity, as that would mean creating a new canvas
* <p>NB: for perf reasons this does not apply opacity, as that would mean creating a new canvas
* layer (which allocates an offscreen bitmap) and having it composited afterwards. Instead, the
* drawing code should apply opacity recursively.
*
@@ -233,8 +231,8 @@ abstract public class VirtualView extends ReactViewGroup {
}
/**
* Restore the canvas after an element was drawn. This is always called in mirror with
* {@link #saveAndSetupCanvas}.
* Restore the canvas after an element was drawn. This is always called in mirror with {@link
* #saveAndSetupCanvas}.
*
* @param canvas the canvas to restore
*/
@@ -339,17 +337,21 @@ abstract public class VirtualView extends ReactViewGroup {
invalidate();
}
@Nullable Path getClipPath() {
@Nullable
Path getClipPath() {
return mCachedClipPath;
}
@Nullable Path getClipPath(Canvas canvas, Paint paint) {
@Nullable
Path getClipPath(Canvas canvas, Paint paint) {
if (mClipPath != null) {
ClipPathView mClipNode = (ClipPathView) getSvgView().getDefinedClipPath(mClipPath);
if (mClipNode != null) {
Path clipPath = mClipRule == CLIP_RULE_EVENODD ? mClipNode.getPath(canvas, paint) :
mClipNode.getPath(canvas, paint, Region.Op.UNION);
Path clipPath =
mClipRule == CLIP_RULE_EVENODD
? mClipNode.getPath(canvas, paint)
: mClipNode.getPath(canvas, paint, Region.Op.UNION);
clipPath.transform(mClipNode.mMatrix);
clipPath.transform(mClipNode.mTransform);
switch (mClipRule) {
@@ -396,11 +398,13 @@ abstract public class VirtualView extends ReactViewGroup {
if (parent == null) {
return null;
} else if (parent instanceof SvgView) {
svgView = (SvgView)parent;
svgView = (SvgView) parent;
} else if (parent instanceof VirtualView) {
svgView = ((VirtualView) parent).getSvgView();
} else {
FLog.e(ReactConstants.TAG, "RNSVG: " + getClass().getName() + " should be descendant of a SvgView.");
FLog.e(
ReactConstants.TAG,
"RNSVG: " + getClass().getName() + " should be descendant of a SvgView.");
}
return svgView;
@@ -408,9 +412,9 @@ abstract public class VirtualView extends ReactViewGroup {
double relativeOnWidth(SVGLength length) {
SVGLength.UnitType unit = length.unit;
if (unit == SVGLength.UnitType.NUMBER){
if (unit == SVGLength.UnitType.NUMBER) {
return length.value * mScale;
} else if (unit == SVGLength.UnitType.PERCENTAGE){
} else if (unit == SVGLength.UnitType.PERCENTAGE) {
return length.value / 100 * getCanvasWidth();
}
return fromRelativeFast(length);
@@ -418,9 +422,9 @@ abstract public class VirtualView extends ReactViewGroup {
double relativeOnHeight(SVGLength length) {
SVGLength.UnitType unit = length.unit;
if (unit == SVGLength.UnitType.NUMBER){
if (unit == SVGLength.UnitType.NUMBER) {
return length.value * mScale;
} else if (unit == SVGLength.UnitType.PERCENTAGE){
} else if (unit == SVGLength.UnitType.PERCENTAGE) {
return length.value / 100 * getCanvasHeight();
}
return fromRelativeFast(length);
@@ -428,17 +432,16 @@ abstract public class VirtualView extends ReactViewGroup {
double relativeOnOther(SVGLength length) {
SVGLength.UnitType unit = length.unit;
if (unit == SVGLength.UnitType.NUMBER){
if (unit == SVGLength.UnitType.NUMBER) {
return length.value * mScale;
} else if (unit == SVGLength.UnitType.PERCENTAGE){
} else if (unit == SVGLength.UnitType.PERCENTAGE) {
return length.value / 100 * getCanvasDiagonal();
}
return fromRelativeFast(length);
}
/**
* Converts SVGLength into px / user units
* in the current user coordinate system
* Converts SVGLength into px / user units in the current user coordinate system
*
* @param length length string
* @return value in the current user coordinate system
@@ -520,24 +523,25 @@ abstract public class VirtualView extends ReactViewGroup {
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = mClientRect != null ?
(int) Math.ceil(mClientRect.width())
int width =
mClientRect != null
? (int) Math.ceil(mClientRect.width())
: getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
int height = mClientRect != null ?
(int) Math.ceil(mClientRect.height())
int height =
mClientRect != null
? (int) Math.ceil(mClientRect.height())
: getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
}
/**
* Called from layout when this view should
* assign a size and position to each of its children.
* Called from layout when this view should assign a size and position to each of its children.
*
* <p>Derived classes with children should override this method and call layout on each of their
* children.
*
* Derived classes with children should override
* this method and call layout on each of
* their children.
* @param changed This is a new size or position for this view
* @param pleft Left position, relative to parent
* @param ptop Top position, relative to parent
@@ -588,20 +592,12 @@ abstract public class VirtualView extends ReactViewGroup {
if (!mOnLayout) {
return;
}
EventDispatcher eventDispatcher = mContext
.getNativeModule(UIManagerModule.class)
.getEventDispatcher();
eventDispatcher.dispatchEvent(OnLayoutEvent.obtain(
this.getId(),
left,
top,
width,
height
));
EventDispatcher eventDispatcher =
mContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
eventDispatcher.dispatchEvent(OnLayoutEvent.obtain(this.getId(), left, top, width, height));
}
RectF getClientRect() {
return mClientRect;
}
}

View File

@@ -1,9 +1,7 @@
package com.horcrux.svg;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.views.view.ReactViewGroup;
import org.jetbrains.annotations.Nullable;
public abstract class FabricEnabledViewGroup extends ReactViewGroup {

View File

@@ -12,7 +12,7 @@
@interface RNSVGBrush : NSObject
@property (nonatomic, strong) NSString* brushRef;
@property (nonatomic, strong) NSString *brushRef;
/* @abstract */
- (instancetype)initWithArray:(NSArray *)data;

View File

@@ -18,7 +18,6 @@
- (void)paint:(CGContextRef)context opacity:(CGFloat)opacity painter:(RNSVGPainter *)painter bounds:(CGRect)bounds
{
}
- (BOOL)applyFillColor:(CGContextRef)context opacity:(CGFloat)opacity

View File

@@ -7,14 +7,13 @@
*/
#import "RNSVGContextBrush.h"
#import "RNSVGRenderable.h"
#import "RNSVGNode.h"
#import "RNSVGRenderable.h"
#import "RCTConvert+RNSVG.h"
#import <React/RCTLog.h>
#import "RCTConvert+RNSVG.h"
@implementation RNSVGContextBrush
{
@implementation RNSVGContextBrush {
BOOL _isStroke;
}
@@ -59,8 +58,6 @@
return fillColor;
}
- (BOOL)applyStrokeColor:(CGContextRef)context opacity:(CGFloat)opacity
{
RNSVGRenderable *element = RNSVGRenderable.contextElement;

View File

@@ -8,14 +8,14 @@
#import "RCTConvert+RNSVG.h"
#import "RNSVGBrushType.h"
#import "RNSVGUnits.h"
#import "RNSVGLength.h"
#import "RNSVGUnits.h"
@class RNSVGPattern;
@interface RNSVGPainter : NSObject
@property (nonatomic, assign) RNSVGPattern* pattern;
@property (nonatomic, assign) RNSVGPattern *pattern;
@property (nonatomic, assign) CGRect paintBounds;
@property (nonatomic, assign) bool useObjectBoundingBoxForContentUnits;
@property (nonatomic, assign) CGRect bounds;

View File

@@ -10,8 +10,7 @@
#import "RNSVGPattern.h"
#import "RNSVGViewBox.h"
@implementation RNSVGPainter
{
@implementation RNSVGPainter {
NSArray<RNSVGLength *> *_points;
NSArray<NSNumber *> *_colors;
RNSVGBrushType _type;
@@ -29,7 +28,7 @@
return self;
}
RCT_NOT_IMPLEMENTED(- (instancetype)init)
RCT_NOT_IMPLEMENTED(-(instancetype)init)
- (void)setUnits:(RNSVGUnits)unit
{
@@ -111,7 +110,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
return CGRectMake(x, y, width, height);
}
void PatternFunction(void* info, CGContextRef context)
void PatternFunction(void *info, CGContextRef context)
{
RNSVGPainter *_painter = (__bridge RNSVGPainter *)info;
RNSVGPattern *_pattern = [_painter pattern];
@@ -122,8 +121,7 @@ void PatternFunction(void* info, CGContextRef context)
CGFloat vbHeight = _pattern.vbHeight;
if (vbWidth > 0 && vbHeight > 0) {
CGRect vbRect = CGRectMake(minX, minY, vbWidth, vbHeight);
CGAffineTransform _viewBoxTransform = [RNSVGViewBox
getTransform:vbRect
CGAffineTransform _viewBoxTransform = [RNSVGViewBox getTransform:vbRect
eRect:rect
align:_pattern.align
meetOrSlice:_pattern.meetOrSlice];
@@ -138,13 +136,11 @@ void PatternFunction(void* info, CGContextRef context)
[_pattern renderTo:context rect:rect];
}
- (CGFloat)getVal:(RNSVGLength*)length relative:(CGFloat)relative
- (CGFloat)getVal:(RNSVGLength *)length relative:(CGFloat)relative
{
RNSVGLengthUnitType unit = [length unit];
CGFloat val = [RNSVGPropHelper fromRelative:length
relative:relative];
return _useObjectBoundingBox &&
unit == SVG_LENGTHTYPE_NUMBER ? val * relative : val;
CGFloat val = [RNSVGPropHelper fromRelative:length relative:relative];
return _useObjectBoundingBox && unit == SVG_LENGTHTYPE_NUMBER ? val * relative : val;
}
- (void)paintPattern:(CGContextRef)context bounds:(CGRect)bounds
@@ -170,12 +166,13 @@ void PatternFunction(void* info, CGContextRef context)
self.paintBounds = newBounds;
self.bounds = rect;
const CGPatternCallbacks callbacks = { 0, &PatternFunction, NULL };
const CGPatternCallbacks callbacks = {0, &PatternFunction, NULL};
CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
CGContextSetFillColorSpace(context, patternSpace);
CGColorSpaceRelease(patternSpace);
CGPatternRef pattern = CGPatternCreate((__bridge void * _Nullable)(self),
CGPatternRef pattern = CGPatternCreate(
(__bridge void *_Nullable)(self),
newBounds,
viewbox,
size.width,
@@ -252,4 +249,3 @@ void PatternFunction(void* info, CGContextRef context)
}
@end

View File

@@ -7,9 +7,9 @@
*/
#import "RNSVGPainterBrush.h"
#import "RNSVGPainter.h"
#import "RCTConvert+RNSVG.h"
#import <React/RCTLog.h>
#import "RCTConvert+RNSVG.h"
#import "RNSVGPainter.h"
@implementation RNSVGPainterBrush
@@ -17,8 +17,7 @@
{
if ((self = [super initWithArray:array])) {
if (array.count != 2) {
RCTLogError(@"-[%@ %@] expects 2 elements, received %@",
self.class, NSStringFromSelector(_cmd), array);
RCTLogError(@"-[%@ %@] expects 2 elements, received %@", self.class, NSStringFromSelector(_cmd), array);
return nil;
}

View File

@@ -9,11 +9,10 @@
#import "RNSVGSolidColorBrush.h"
#import "RNSVGUIKit.h"
#import "RCTConvert+RNSVG.h"
#import <React/RCTLog.h>
#import "RCTConvert+RNSVG.h"
@implementation RNSVGSolidColorBrush
{
@implementation RNSVGSolidColorBrush {
RNSVGColor *_color;
}
@@ -41,7 +40,6 @@
return self;
}
- (void)dealloc
{
_color = nil;

View File

@@ -10,9 +10,9 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -55,12 +55,11 @@ using namespace facebook::react;
[self.svgView defineClipPath:self clipPathName:self.name];
}
- (BOOL)isSimpleClipPath
{
NSArray<RNSVGView*> *children = self.subviews;
NSArray<RNSVGView *> *children = self.subviews;
if (children.count == 1) {
RNSVGView* child = children[0];
RNSVGView *child = children[0];
if ([child class] != [RNSVGGroup class]) {
return true;
}

View File

@@ -9,9 +9,9 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED

View File

@@ -12,9 +12,9 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -43,8 +43,12 @@ using namespace facebook::react;
{
const auto &newProps = *std::static_pointer_cast<const RNSVGForeignObjectProps>(props);
self.x = RCTNSStringFromStringNilIfEmpty(newProps.x) ? [RNSVGLength lengthWithString:RCTNSStringFromString(newProps.x)] : nil;
self.y = RCTNSStringFromStringNilIfEmpty(newProps.y) ? [RNSVGLength lengthWithString:RCTNSStringFromString(newProps.y)] : nil;
self.x = RCTNSStringFromStringNilIfEmpty(newProps.x)
? [RNSVGLength lengthWithString:RCTNSStringFromString(newProps.x)]
: nil;
self.y = RCTNSStringFromStringNilIfEmpty(newProps.y)
? [RNSVGLength lengthWithString:RCTNSStringFromString(newProps.y)]
: nil;
if (RCTNSStringFromStringNilIfEmpty(newProps.foreignObjectheight)) {
self.foreignObjectheight = [RNSVGLength lengthWithString:RCTNSStringFromString(newProps.foreignObjectheight)];
}
@@ -85,11 +89,7 @@ using namespace facebook::react;
[self clip:context];
CGContextTranslateCTM(context, [self relativeOnWidth:self.x], [self relativeOnHeight:self.y]);
CGRect clip = CGRectMake(
0,
0,
[self relativeOnWidth:self.foreignObjectwidth],
[self relativeOnHeight:self.foreignObjectheight]
);
0, 0, [self relativeOnWidth:self.foreignObjectwidth], [self relativeOnHeight:self.foreignObjectheight]);
CGContextClipToRect(context, clip);
[super renderLayerTo:context rect:rect];
}
@@ -104,7 +104,7 @@ using namespace facebook::react;
if ([node isKindOfClass:[RNSVGMask class]] || [node isKindOfClass:[RNSVGClipPath class]]) {
// no-op
} else if ([node isKindOfClass:[RNSVGNode class]]) {
RNSVGNode* svgNode = (RNSVGNode*)node;
RNSVGNode *svgNode = (RNSVGNode *)node;
if (svgNode.display && [@"none" isEqualToString:svgNode.display]) {
return YES;
}
@@ -113,7 +113,7 @@ using namespace facebook::react;
}
if ([node isKindOfClass:[RNSVGRenderable class]]) {
[(RNSVGRenderable*)node mergeProperties:self];
[(RNSVGRenderable *)node mergeProperties:self];
}
[svgNode renderTo:context rect:rect];
@@ -124,10 +124,10 @@ using namespace facebook::react;
}
if ([node isKindOfClass:[RNSVGRenderable class]]) {
[(RNSVGRenderable*)node resetProperties];
[(RNSVGRenderable *)node resetProperties];
}
} else if ([node isKindOfClass:[RNSVGSvgView class]]) {
RNSVGSvgView* svgView = (RNSVGSvgView*)node;
RNSVGSvgView *svgView = (RNSVGSvgView *)node;
CGFloat width = [self relativeOnWidth:svgView.bbWidth];
CGFloat height = [self relativeOnHeight:svgView.bbHeight];
CGRect rect = CGRectMake(0, 0, width, height);

View File

@@ -10,11 +10,11 @@
#import "RNSVGUIKit.h"
#import "RNSVGContainer.h"
#import "RNSVGCGFCRule.h"
#import "RNSVGSvgView.h"
#import "RNSVGPath.h"
#import "RNSVGContainer.h"
#import "RNSVGGlyphContext.h"
#import "RNSVGPath.h"
#import "RNSVGSvgView.h"
@interface RNSVGGroup : RNSVGPath <RNSVGContainer>

View File

@@ -10,17 +10,15 @@
#import "RNSVGClipPath.h"
#import "RNSVGMask.h"
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@implementation RNSVGGroup
{
@implementation RNSVGGroup {
RNSVGGlyphContext *_glyphContext;
}
@@ -58,7 +56,7 @@ using namespace facebook::react;
}
#endif // RN_FABRIC_ENABLED
- (void)setFont:(NSDictionary*)font
- (void)setFont:(NSDictionary *)font
{
if (font == _font) {
return;
@@ -85,7 +83,7 @@ using namespace facebook::react;
if ([node isKindOfClass:[RNSVGMask class]] || [node isKindOfClass:[RNSVGClipPath class]]) {
// no-op
} else if ([node isKindOfClass:[RNSVGNode class]]) {
RNSVGNode* svgNode = (RNSVGNode*)node;
RNSVGNode *svgNode = (RNSVGNode *)node;
if (svgNode.display && [@"none" isEqualToString:svgNode.display]) {
return YES;
}
@@ -94,7 +92,7 @@ using namespace facebook::react;
}
if ([node isKindOfClass:[RNSVGRenderable class]]) {
[(RNSVGRenderable*)node mergeProperties:self];
[(RNSVGRenderable *)node mergeProperties:self];
}
[svgNode renderTo:context rect:rect];
@@ -105,10 +103,10 @@ using namespace facebook::react;
}
if ([node isKindOfClass:[RNSVGRenderable class]]) {
[(RNSVGRenderable*)node resetProperties];
[(RNSVGRenderable *)node resetProperties];
}
} else if ([node isKindOfClass:[RNSVGSvgView class]]) {
RNSVGSvgView* svgView = (RNSVGSvgView*)node;
RNSVGSvgView *svgView = (RNSVGSvgView *)node;
CGFloat width = [self relativeOnWidth:svgView.bbWidth];
CGFloat height = [self relativeOnHeight:svgView.bbHeight];
CGRect rect = CGRectMake(0, 0, width, height);
@@ -156,8 +154,7 @@ using namespace facebook::react;
CGFloat width = CGRectGetWidth(clipBounds);
CGFloat height = CGRectGetHeight(clipBounds);
_glyphContext = [[RNSVGGlyphContext alloc] initWithWidth:width
height:height];
_glyphContext = [[RNSVGGlyphContext alloc] initWithWidth:width height:height];
}
- (RNSVGGlyphContext *)getGlyphContext
@@ -213,14 +210,14 @@ using namespace facebook::react;
}
if (self.clipPath) {
RNSVGClipPath *clipNode = (RNSVGClipPath*)[self.svgView getDefinedClipPath:self.clipPath];
RNSVGClipPath *clipNode = (RNSVGClipPath *)[self.svgView getDefinedClipPath:self.clipPath];
if ([clipNode isSimpleClipPath]) {
CGPathRef clipPath = [self getClipPath];
if (clipPath && !CGPathContainsPoint(clipPath, nil, transformed, clipNode.clipRule == kRNSVGCGFCRuleEvenodd)) {
return nil;
}
} else {
RNSVGRenderable *clipGroup = (RNSVGRenderable*)clipNode;
RNSVGRenderable *clipGroup = (RNSVGRenderable *)clipNode;
if (![clipGroup hitTest:transformed withEvent:event]) {
return nil;
}
@@ -228,7 +225,8 @@ using namespace facebook::react;
}
if (!event) {
NSPredicate *const anyActive = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@ AND active == TRUE", [RNSVGNode class]];
NSPredicate *const anyActive =
[NSPredicate predicateWithFormat:@"self isKindOfClass: %@ AND active == TRUE", [RNSVGNode class]];
NSArray *const filtered = [self.subviews filteredArrayUsingPredicate:anyActive];
if ([filtered count] != 0) {
return [filtered.lastObject hitTest:transformed withEvent:event];
@@ -240,7 +238,7 @@ using namespace facebook::react;
if ([node isKindOfClass:[RNSVGMask class]]) {
continue;
}
RNSVGNode* svgNode = (RNSVGNode*)node;
RNSVGNode *svgNode = (RNSVGNode *)node;
if (event) {
svgNode.active = NO;
}
@@ -250,7 +248,7 @@ using namespace facebook::react;
return (svgNode.responsible || (svgNode != hitChild)) ? hitChild : self;
}
} else if ([node isKindOfClass:[RNSVGSvgView class]]) {
RNSVGSvgView* svgView = (RNSVGSvgView*)node;
RNSVGSvgView *svgView = (RNSVGSvgView *)node;
RNSVGPlatformView *hitChild = [svgView hitTest:transformed withEvent:event];
if (hitChild) {
return hitChild;
@@ -286,7 +284,7 @@ using namespace facebook::react;
{
[self traverseSubviews:^(__kindof RNSVGNode *node) {
if ([node isKindOfClass:[RNSVGRenderable class]]) {
[(RNSVGRenderable*)node resetProperties];
[(RNSVGRenderable *)node resetProperties];
}
return YES;
}];

View File

@@ -9,9 +9,9 @@
#import <Foundation/Foundation.h>
#import <React/RCTBridge.h>
#import "RNSVGLength.h"
#import "RNSVGRenderable.h"
#import "RNSVGVBMOS.h"
#import "RNSVGLength.h"
#import <React/RCTImageSource.h>
@@ -19,10 +19,10 @@
@property (nonatomic, weak) RCTBridge *bridge;
@property (nonatomic, assign) id src;
@property (nonatomic, strong) RNSVGLength* x;
@property (nonatomic, strong) RNSVGLength* y;
@property (nonatomic, strong) RNSVGLength* imagewidth;
@property (nonatomic, strong) RNSVGLength* imageheight;
@property (nonatomic, strong) RNSVGLength *x;
@property (nonatomic, strong) RNSVGLength *y;
@property (nonatomic, strong) RNSVGLength *imagewidth;
@property (nonatomic, strong) RNSVGLength *imageheight;
@property (nonatomic, strong) NSString *align;
@property (nonatomic, assign) RNSVGVBMOS meetOrSlice;

View File

@@ -15,25 +15,25 @@
#else
#import <React/RCTImageURLLoader.h>
#import <React/RCTImageShadowView.h>
#import <React/RCTImageView.h>
#import <React/RCTImageLoaderProtocol.h>
#import <React/RCTImageShadowView.h>
#import <React/RCTImageURLLoader.h>
#import <React/RCTImageView.h>
#endif // RN_FABRIC_ENABLED
#import <React/RCTLog.h>
#import "RNSVGViewBox.h"
#import "RCTBridge.h"
#import "RNSVGViewBox.h"
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RNSVGFabricConversions.h"
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RCTImagePrimitivesConversions.h"
#import "RCTImageSource.h"
#import "RNSVGFabricConversions.h"
// Some RN private method hacking below similar to how it is done in RNScreens:
// https://github.com/software-mansion/react-native-screens/blob/90e548739f35b5ded2524a9d6410033fc233f586/ios/RNSScreenStackHeaderConfig.mm#L30
@@ -43,8 +43,7 @@
#endif // RN_FABRIC_ENABLED
@implementation RNSVGImage
{
@implementation RNSVGImage {
CGImageRef _image;
CGSize _imageSize;
RCTImageLoaderCancellationBlock _reloadImageCancellationBlock;
@@ -143,7 +142,9 @@ using namespace facebook::react;
_reloadImageCancellationBlock = nil;
}
_reloadImageCancellationBlock = [[self.bridge moduleForName:@"ImageLoader"] loadImageWithURLRequest:[RCTConvert NSURLRequest:src] callback:^(NSError *error, UIImage *image) {
_reloadImageCancellationBlock = [[self.bridge moduleForName:@"ImageLoader"]
loadImageWithURLRequest:[RCTConvert NSURLRequest:src]
callback:^(NSError *error, UIImage *image) {
dispatch_async(dispatch_get_main_queue(), ^{
self->_image = CGImageRetain(image.CGImage);
self->_imageSize = CGSizeMake(CGImageGetWidth(self->_image), CGImageGetHeight(self->_image));
@@ -260,7 +261,10 @@ using namespace facebook::react;
// apply viewBox transform on Image render.
CGRect imageBounds = CGRectMake(0, 0, _imageSize.width, _imageSize.height);
CGAffineTransform viewbox = [RNSVGViewBox getTransform:imageBounds eRect:hitArea align:self.align meetOrSlice:self.meetOrSlice];
CGAffineTransform viewbox = [RNSVGViewBox getTransform:imageBounds
eRect:hitArea
align:self.align
meetOrSlice:self.meetOrSlice];
[self clip:context];
CGContextClipToRect(context, hitArea);

View File

@@ -6,8 +6,8 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGNode.h"
#import "RNSVGLength.h"
#import "RNSVGNode.h"
@interface RNSVGLinearGradient : RNSVGNode

View File

@@ -6,14 +6,14 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGLinearGradient.h"
#import "RNSVGPainter.h"
#import "RNSVGBrushType.h"
#import "RNSVGPainter.h"
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -55,7 +55,13 @@ using namespace facebook::react;
}
self.gradientUnits = newProps.gradientUnits == 0 ? kRNSVGUnitsObjectBoundingBox : kRNSVGUnitsUserSpaceOnUse;
if (newProps.gradientTransform.size() == 6) {
self.gradientTransform = CGAffineTransformMake(newProps.gradientTransform.at(0), newProps.gradientTransform.at(1), newProps.gradientTransform.at(2), newProps.gradientTransform.at(3), newProps.gradientTransform.at(4), newProps.gradientTransform.at(5));
self.gradientTransform = CGAffineTransformMake(
newProps.gradientTransform.at(0),
newProps.gradientTransform.at(1),
newProps.gradientTransform.at(2),
newProps.gradientTransform.at(3),
newProps.gradientTransform.at(4),
newProps.gradientTransform.at(5));
}
setCommonNodeProps(newProps, self);
@@ -156,7 +162,7 @@ using namespace facebook::react;
- (void)parseReference
{
self.dirty = false;
NSArray<RNSVGLength *> *points = @[self.x1, self.y1, self.x2, self.y2];
NSArray<RNSVGLength *> *points = @[ self.x1, self.y1, self.x2, self.y2 ];
RNSVGPainter *painter = [[RNSVGPainter alloc] initWithPointsArray:points];
[painter setUnits:self.gradientUnits];
[painter setTransform:self.gradientTransform];

View File

@@ -19,6 +19,9 @@
@property (nonatomic, strong) NSString *align;
@property (nonatomic, assign) RNSVGVBMOS meetOrSlice;
- (void)renderMarker:(CGContextRef)context rect:(CGRect)rect position:(RNSVGMarkerPosition*)position strokeWidth:(CGFloat)strokeWidth;
- (void)renderMarker:(CGContextRef)context
rect:(CGRect)rect
position:(RNSVGMarkerPosition *)position
strokeWidth:(CGFloat)strokeWidth;
@end

View File

@@ -6,16 +6,16 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGMarker.h"
#import "RNSVGPainter.h"
#import "RNSVGBrushType.h"
#import "RNSVGNode.h"
#import "RNSVGPainter.h"
#import "RNSVGViewBox.h"
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -219,11 +219,15 @@ using namespace facebook::react;
static CGFloat RNSVG_degToRad = (CGFloat)M_PI / 180;
double deg2rad(CGFloat deg) {
double deg2rad(CGFloat deg)
{
return deg * RNSVG_degToRad;
}
- (void)renderMarker:(CGContextRef)context rect:(CGRect)rect position:(RNSVGMarkerPosition*)position strokeWidth:(CGFloat)strokeWidth
- (void)renderMarker:(CGContextRef)context
rect:(CGRect)rect
position:(RNSVGMarkerPosition *)position
strokeWidth:(CGFloat)strokeWidth
{
CGContextSaveGState(context);
@@ -244,7 +248,8 @@ double deg2rad(CGFloat deg) {
CGFloat height = [self relativeOnHeight:self.markerHeight];
CGRect eRect = CGRectMake(0, 0, width, height);
if (self.align) {
CGAffineTransform viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
CGAffineTransform viewBoxTransform =
[RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
eRect:eRect
align:self.align
meetOrSlice:self.meetOrSlice];
@@ -265,7 +270,6 @@ double deg2rad(CGFloat deg) {
@end
#ifdef RN_FABRIC_ENABLED
Class<RCTComponentViewProtocol> RNSVGMarkerCls(void)
{

View File

@@ -6,16 +6,15 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGMask.h"
#import "RNSVGPainter.h"
#import "RNSVGBrushType.h"
#import "RNSVGNode.h"
#import "RNSVGPainter.h"
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -61,7 +60,13 @@ using namespace facebook::react;
self.maskUnits = newProps.maskUnits == 0 ? kRNSVGUnitsObjectBoundingBox : kRNSVGUnitsUserSpaceOnUse;
self.maskContentUnits = newProps.maskUnits == 0 ? kRNSVGUnitsObjectBoundingBox : kRNSVGUnitsUserSpaceOnUse;
if (newProps.maskTransform.size() == 6) {
self.maskTransform = CGAffineTransformMake(newProps.maskTransform.at(0), newProps.maskTransform.at(1), newProps.maskTransform.at(2), newProps.maskTransform.at(3), newProps.maskTransform.at(4), newProps.maskTransform.at(5));
self.maskTransform = CGAffineTransformMake(
newProps.maskTransform.at(0),
newProps.maskTransform.at(1),
newProps.maskTransform.at(2),
newProps.maskTransform.at(3),
newProps.maskTransform.at(4),
newProps.maskTransform.at(5));
}
setCommonGroupProps(newProps, self);

View File

@@ -10,14 +10,13 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@implementation RNSVGPath
{
@implementation RNSVGPath {
CGPathRef _path;
}
@@ -43,7 +42,7 @@ using namespace facebook::react;
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
{
const auto &newProps = *std::static_pointer_cast<const RNSVGPathProps>(props);
self.d = [[RNSVGPathParser alloc] initWithPathString: RCTNSStringFromString(newProps.d)];
self.d = [[RNSVGPathParser alloc] initWithPathString:RCTNSStringFromString(newProps.d)];
setCommonRenderableProps(newProps, self);
}

View File

@@ -6,15 +6,15 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGPattern.h"
#import "RNSVGPainter.h"
#import "RNSVGBrushType.h"
#import "RNSVGNode.h"
#import "RNSVGPainter.h"
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -60,7 +60,13 @@ using namespace facebook::react;
self.patternUnits = newProps.patternUnits == 0 ? kRNSVGUnitsObjectBoundingBox : kRNSVGUnitsUserSpaceOnUse;
self.patternContentUnits = newProps.patternUnits == 0 ? kRNSVGUnitsObjectBoundingBox : kRNSVGUnitsUserSpaceOnUse;
if (newProps.patternTransform.size() == 6) {
self.patternTransform = CGAffineTransformMake(newProps.patternTransform.at(0), newProps.patternTransform.at(1), newProps.patternTransform.at(2), newProps.patternTransform.at(3), newProps.patternTransform.at(4), newProps.patternTransform.at(5));
self.patternTransform = CGAffineTransformMake(
newProps.patternTransform.at(0),
newProps.patternTransform.at(1),
newProps.patternTransform.at(2),
newProps.patternTransform.at(3),
newProps.patternTransform.at(4),
newProps.patternTransform.at(5));
}
self.minX = newProps.minX;
self.minY = newProps.minY;
@@ -108,7 +114,7 @@ using namespace facebook::react;
- (void)parseReference
{
self.dirty = false;
NSArray<RNSVGLength *> *points = @[self.x, self.y, self.patternwidth, self.patternheight];
NSArray<RNSVGLength *> *points = @[ self.x, self.y, self.patternwidth, self.patternheight ];
RNSVGPainter *painter = [[RNSVGPainter alloc] initWithPointsArray:points];
[painter setUnits:self.patternUnits];
[painter setContentUnits:self.patternContentUnits];

View File

@@ -6,8 +6,8 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGNode.h"
#import "RNSVGLength.h"
#import "RNSVGNode.h"
@interface RNSVGRadialGradient : RNSVGNode

View File

@@ -9,9 +9,9 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -55,7 +55,13 @@ using namespace facebook::react;
}
self.gradientUnits = newProps.gradientUnits == 0 ? kRNSVGUnitsObjectBoundingBox : kRNSVGUnitsUserSpaceOnUse;
if (newProps.gradientTransform.size() == 6) {
self.gradientTransform = CGAffineTransformMake(newProps.gradientTransform.at(0), newProps.gradientTransform.at(1), newProps.gradientTransform.at(2), newProps.gradientTransform.at(3), newProps.gradientTransform.at(4), newProps.gradientTransform.at(5));
self.gradientTransform = CGAffineTransformMake(
newProps.gradientTransform.at(0),
newProps.gradientTransform.at(1),
newProps.gradientTransform.at(2),
newProps.gradientTransform.at(3),
newProps.gradientTransform.at(4),
newProps.gradientTransform.at(5));
}
setCommonNodeProps(newProps, self);
@@ -177,7 +183,7 @@ using namespace facebook::react;
- (void)parseReference
{
self.dirty = false;
NSArray<RNSVGLength *> *points = @[self.fx, self.fy, self.rx, self.ry, self.cx, self.cy];
NSArray<RNSVGLength *> *points = @[ self.fx, self.fy, self.rx, self.ry, self.cx, self.cy ];
RNSVGPainter *painter = [[RNSVGPainter alloc] initWithPointsArray:points];
[painter setUnits:self.gradientUnits];
[painter setTransform:self.gradientTransform];

View File

@@ -8,8 +8,8 @@
#import "RNSVGUIKit.h"
#import "RNSVGPainter.h"
#import "RNSVGContainer.h"
#import "RNSVGPainter.h"
#import "RNSVGVBMOS.h"
#ifdef RN_FABRIC_ENABLED
@@ -20,9 +20,9 @@
@interface RNSVGSvgView :
#ifdef RN_FABRIC_ENABLED
RCTViewComponentView <RNSVGContainer>
RCTViewComponentView <RNSVGContainer>
#else
RNSVGView <RNSVGContainer>
RNSVGView <RNSVGContainer>
#endif // RN_FABRIC_ENABLED
@property (nonatomic, strong) RNSVGLength *bbWidth;

View File

@@ -7,20 +7,19 @@
*/
#import "RNSVGSvgView.h"
#import "RNSVGViewBox.h"
#import "RNSVGNode.h"
#import <React/RCTLog.h>
#import "RNSVGNode.h"
#import "RNSVGViewBox.h"
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@implementation RNSVGSvgView
{
@implementation RNSVGSvgView {
NSMutableDictionary<NSString *, RNSVGNode *> *_clipPaths;
NSMutableDictionary<NSString *, RNSVGNode *> *_templates;
NSMutableDictionary<NSString *, RNSVGPainter *> *_painters;
@@ -81,7 +80,6 @@ using namespace facebook::react;
}
}
- (void)prepareForRecycle
{
[super prepareForRecycle];
@@ -144,12 +142,12 @@ using namespace facebook::react;
- (void)invalidate
{
RNSVGPlatformView* parent = self.superview;
RNSVGPlatformView *parent = self.superview;
if ([parent isKindOfClass:[RNSVGNode class]]) {
if (!rendered) {
return;
}
RNSVGNode* svgNode = (RNSVGNode*)parent;
RNSVGNode *svgNode = (RNSVGNode *)parent;
[svgNode invalidate];
rendered = false;
return;
@@ -251,16 +249,14 @@ using namespace facebook::react;
_meetOrSlice = meetOrSlice;
}
- (void)drawToContext:(CGContextRef)context withRect:(CGRect)rect {
- (void)drawToContext:(CGContextRef)context withRect:(CGRect)rect
{
rendered = true;
self.initialCTM = CGContextGetCTM(context);
self.invInitialCTM = CGAffineTransformInvert(self.initialCTM);
if (self.align) {
CGRect tRect = CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight);
_viewBoxTransform = [RNSVGViewBox getTransform:tRect
eRect:rect
align:self.align
meetOrSlice:self.meetOrSlice];
_viewBoxTransform = [RNSVGViewBox getTransform:tRect eRect:rect align:self.align meetOrSlice:self.meetOrSlice];
_invviewBoxTransform = CGAffineTransformInvert(_viewBoxTransform);
CGContextConcatCTM(context, _viewBoxTransform);
} else {
@@ -271,8 +267,7 @@ using namespace facebook::react;
for (RNSVGView *node in self.subviews) {
if ([node isKindOfClass:[RNSVGNode class]]) {
RNSVGNode *svg = (RNSVGNode *)node;
[svg renderTo:context
rect:rect];
[svg renderTo:context rect:rect];
} else {
[node drawRect:rect];
}
@@ -281,7 +276,7 @@ using namespace facebook::react;
- (void)drawRect:(CGRect)rect
{
RNSVGPlatformView* parent = self.superview;
RNSVGPlatformView *parent = self.superview;
if ([parent isKindOfClass:[RNSVGNode class]]) {
return;
}
@@ -388,7 +383,6 @@ using namespace facebook::react;
return _templates ? [_templates objectForKey:templateName] : nil;
}
- (void)definePainter:(RNSVGPainter *)painter painterName:(NSString *)painterName
{
if (!_painters) {

View File

@@ -10,9 +10,9 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -134,8 +134,8 @@ using namespace facebook::react;
{
CGRect eRect = CGRectMake(0, 0, width, height);
if (self.align) {
CGAffineTransform viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
CGAffineTransform viewBoxTransform =
[RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
eRect:eRect
align:self.align
meetOrSlice:self.meetOrSlice];

View File

@@ -6,8 +6,8 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGRenderable.h"
#import "RNSVGLength.h"
#import "RNSVGRenderable.h"
/**
* RNSVG defination are implemented as abstract UIViews for all elements inside Defs.

View File

@@ -6,14 +6,14 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGUse.h"
#import "RNSVGSymbol.h"
#import <React/RCTLog.h>
#import "RNSVGSymbol.h"
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -102,7 +102,6 @@ using namespace facebook::react;
_y = y;
}
- (void)setUsewidth:(RNSVGLength *)usewidth
{
if ([usewidth isEqualTo:_usewidth]) {
@@ -126,30 +125,34 @@ using namespace facebook::react;
- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect
{
CGContextTranslateCTM(context, [self relativeOnWidth:self.x], [self relativeOnHeight:self.y]);
RNSVGNode* definedTemplate = [self.svgView getDefinedTemplate:self.href];
RNSVGNode *definedTemplate = [self.svgView getDefinedTemplate:self.href];
if (definedTemplate) {
[self beginTransparencyLayer:context];
[self clip:context];
if ([definedTemplate isKindOfClass:[RNSVGRenderable class]]) {
[(RNSVGRenderable*)definedTemplate mergeProperties:self];
[(RNSVGRenderable *)definedTemplate mergeProperties:self];
}
if ([definedTemplate class] == [RNSVGSymbol class]) {
RNSVGSymbol *symbol = (RNSVGSymbol*)definedTemplate;
[symbol renderSymbolTo:context width:[self relativeOnWidth:self.usewidth] height:[self relativeOnHeight:self.useheight]];
RNSVGSymbol *symbol = (RNSVGSymbol *)definedTemplate;
[symbol renderSymbolTo:context
width:[self relativeOnWidth:self.usewidth]
height:[self relativeOnHeight:self.useheight]];
} else {
[definedTemplate renderTo:context rect:rect];
}
if ([definedTemplate isKindOfClass:[RNSVGRenderable class]]) {
[(RNSVGRenderable*)definedTemplate resetProperties];
[(RNSVGRenderable *)definedTemplate resetProperties];
}
[self endTransparencyLayer:context];
} else if (self.href) {
// TODO: calling yellow box here
RCTLogWarn(@"`Use` element expected a pre-defined svg template as `href` prop, template named: %@ is not defined.", self.href);
RCTLogWarn(
@"`Use` element expected a pre-defined svg template as `href` prop, template named: %@ is not defined.",
self.href);
return;
} else {
return;
@@ -174,16 +177,17 @@ using namespace facebook::react;
self.frame = bounds;
}
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
transformed = CGPointApplyAffineTransform(transformed, self.invTransform);
RNSVGNode const* definedTemplate = [self.svgView getDefinedTemplate:self.href];
RNSVGNode const *definedTemplate = [self.svgView getDefinedTemplate:self.href];
if (event) {
self.active = NO;
} else if (self.active) {
return self;
}
RNSVGPlatformView const* hitChild = [definedTemplate hitTest:transformed withEvent:event];
RNSVGPlatformView const *hitChild = [definedTemplate hitTest:transformed withEvent:event];
if (hitChild) {
self.active = YES;
return self;
@@ -191,10 +195,11 @@ using namespace facebook::react;
return nil;
}
- (CGPathRef)getPath: (CGContextRef)context
- (CGPathRef)getPath:(CGContextRef)context
{
CGAffineTransform transform = CGAffineTransformMakeTranslation([self relativeOnWidth:self.x], [self relativeOnHeight:self.y]);
RNSVGNode const* definedTemplate = [self.svgView getDefinedTemplate:self.href];
CGAffineTransform transform =
CGAffineTransformMakeTranslation([self relativeOnWidth:self.x], [self relativeOnHeight:self.y]);
RNSVGNode const *definedTemplate = [self.svgView getDefinedTemplate:self.href];
if (!definedTemplate) {
return nil;
}

View File

@@ -6,10 +6,11 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGSvgView.h"
#import <React/UIView+React.h>
#import <React/RCTPointerEvents.h>
#import "RNSVGCGFCRule.h"
#import "RNSVGSvgView.h"
#import <React/RCTPointerEvents.h>
#import <React/UIView+React.h>
#ifdef RN_FABRIC_ENABLED
#import <React/RCTViewComponentView.h>
@@ -24,9 +25,9 @@
@interface RNSVGNode :
#ifdef RN_FABRIC_ENABLED
RCTViewComponentView
RCTViewComponentView
#else
RNSVGView
RNSVGView
#endif // RN_FABRIC_ENABLED
/*
N[1/Sqrt[2], 36]
@@ -73,7 +74,6 @@ extern CGFloat const RNSVG_DEFAULT_FONT_SIZE;
@property (nonatomic, assign) CGRect markerBounds;
@property (nonatomic, copy) RCTDirectEventBlock onLayout;
/**
* RNSVGSvgView which ownes current RNSVGNode
*/
@@ -111,7 +111,7 @@ extern CGFloat const RNSVG_DEFAULT_FONT_SIZE;
/**
* getPath will return the path inside node as a ClipPath.
*/
- (CGPathRef)getPath:(CGContextRef) context;
- (CGPathRef)getPath:(CGContextRef)context;
- (CGFloat)relativeOnWidthString:(NSString *)length;

View File

@@ -7,18 +7,17 @@
*/
#import "RNSVGNode.h"
#import "RNSVGContainer.h"
#import "RNSVGClipPath.h"
#import "RNSVGGroup.h"
#import "RNSVGContainer.h"
#import "RNSVGGlyphContext.h"
#import "RNSVGGroup.h"
@interface RNSVGNode()
@interface RNSVGNode ()
@property (nonatomic, readwrite, weak) RNSVGSvgView *svgView;
@property (nonatomic, readwrite, weak) RNSVGGroup *textRoot;
@end
@implementation RNSVGNode
{
@implementation RNSVGNode {
RNSVGGlyphContext *glyphContext;
BOOL _transparent;
RNSVGClipPath *_clipNode;
@@ -72,7 +71,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
RNSVGView *container = self.superview;
// on Fabric, when the child components are added to hierarchy and their props are set,
// their superview is not set yet.
if ([container conformsToProtocol:@protocol(RNSVGContainer)]){
if ([container conformsToProtocol:@protocol(RNSVGContainer)]) {
[(id<RNSVGContainer>)container invalidate];
}
[self clearPath];
@@ -99,14 +98,14 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
- (void)clearParentCache
{
RNSVGNode* node = self;
RNSVGNode *node = self;
while (node != nil) {
RNSVGPlatformView* parent = [node superview];
RNSVGPlatformView *parent = [node superview];
if (![parent isKindOfClass:[RNSVGNode class]]) {
return;
}
node = (RNSVGNode*)parent;
node = (RNSVGNode *)parent;
if (!node.path) {
return;
}
@@ -120,19 +119,19 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return _textRoot;
}
RNSVGNode* node = self;
RNSVGNode *node = self;
while (node != nil) {
if ([node isKindOfClass:[RNSVGGroup class]] && [((RNSVGGroup*) node) getGlyphContext] != nil) {
_textRoot = (RNSVGGroup*)node;
if ([node isKindOfClass:[RNSVGGroup class]] && [((RNSVGGroup *)node) getGlyphContext] != nil) {
_textRoot = (RNSVGGroup *)node;
break;
}
RNSVGPlatformView* parent = [node superview];
RNSVGPlatformView *parent = [node superview];
if (![node isKindOfClass:[RNSVGNode class]]) {
node = nil;
} else {
node = (RNSVGNode*)parent;
node = (RNSVGNode *)parent;
}
}
@@ -141,7 +140,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
- (RNSVGGroup *)getParentTextRoot
{
RNSVGNode* parent = (RNSVGGroup*)[self superview];
RNSVGNode *parent = (RNSVGGroup *)[self superview];
if (![parent isKindOfClass:[RNSVGGroup class]]) {
return nil;
} else {
@@ -151,7 +150,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
- (CGFloat)getFontSizeFromContext
{
RNSVGGroup* root = self.textRoot;
RNSVGGroup *root = self.textRoot;
if (root == nil) {
return RNSVG_DEFAULT_FONT_SIZE;
}
@@ -228,26 +227,26 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
RNSVGView *container = self.superview;
// on Fabric, when the child components are added to hierarchy and their props are set,
// their superview is still their componentView, we change it in `mountChildComponentView` method.
if ([container conformsToProtocol:@protocol(RNSVGContainer)]){
if ([container conformsToProtocol:@protocol(RNSVGContainer)]) {
[(id<RNSVGContainer>)container invalidate];
}
}
- (void)setClientRect:(CGRect)clientRect {
- (void)setClientRect:(CGRect)clientRect
{
if (CGRectEqualToRect(_clientRect, clientRect)) {
return;
}
_clientRect = clientRect;
if (self.onLayout) {
self.onLayout(@{
@"layout": @{
@"x": @(_clientRect.origin.x),
@"y": @(_clientRect.origin.y),
@"width": @(_clientRect.size.width),
@"height": @(_clientRect.size.height),
@"layout" : @{
@"x" : @(_clientRect.origin.x),
@"y" : @(_clientRect.origin.y),
@"width" : @(_clientRect.size.width),
@"height" : @(_clientRect.size.height),
}
});
}
}
@@ -337,7 +336,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
- (CGPathRef)getClipPath:(CGContextRef)context
{
if (self.clipPath) {
_clipNode = (RNSVGClipPath*)[self.svgView getDefinedClipPath:self.clipPath];
_clipNode = (RNSVGClipPath *)[self.svgView getDefinedClipPath:self.clipPath];
if (_cachedClipPath) {
CGPathRelease(_cachedClipPath);
}
@@ -362,7 +361,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
}
}
- (CGPathRef)getPath: (CGContextRef)context
- (CGPathRef)getPath:(CGContextRef)context
{
// abstract
return nil;
@@ -376,7 +375,6 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
// hitTest delagate
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
// abstract
return nil;
}
@@ -424,9 +422,9 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
- (CGFloat)relativeOn:(RNSVGLength *)length relative:(CGFloat)relative
{
RNSVGLengthUnitType unit = length.unit;
if (unit == SVG_LENGTHTYPE_NUMBER){
if (unit == SVG_LENGTHTYPE_NUMBER) {
return length.value;
} else if (unit == SVG_LENGTHTYPE_PERCENTAGE){
} else if (unit == SVG_LENGTHTYPE_PERCENTAGE) {
return length.value / 100 * relative;
}
return [self fromRelative:length];
@@ -435,9 +433,9 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
- (CGFloat)relativeOnWidth:(RNSVGLength *)length
{
RNSVGLengthUnitType unit = length.unit;
if (unit == SVG_LENGTHTYPE_NUMBER){
if (unit == SVG_LENGTHTYPE_NUMBER) {
return length.value;
} else if (unit == SVG_LENGTHTYPE_PERCENTAGE){
} else if (unit == SVG_LENGTHTYPE_PERCENTAGE) {
return length.value / 100 * [self getCanvasWidth];
}
return [self fromRelative:length];
@@ -446,9 +444,9 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
- (CGFloat)relativeOnHeight:(RNSVGLength *)length
{
RNSVGLengthUnitType unit = length.unit;
if (unit == SVG_LENGTHTYPE_NUMBER){
if (unit == SVG_LENGTHTYPE_NUMBER) {
return length.value;
} else if (unit == SVG_LENGTHTYPE_PERCENTAGE){
} else if (unit == SVG_LENGTHTYPE_PERCENTAGE) {
return length.value / 100 * [self getCanvasHeight];
}
return [self fromRelative:length];
@@ -457,15 +455,16 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
- (CGFloat)relativeOnOther:(RNSVGLength *)length
{
RNSVGLengthUnitType unit = length.unit;
if (unit == SVG_LENGTHTYPE_NUMBER){
if (unit == SVG_LENGTHTYPE_NUMBER) {
return length.value;
} else if (unit == SVG_LENGTHTYPE_PERCENTAGE){
} else if (unit == SVG_LENGTHTYPE_PERCENTAGE) {
return length.value / 100 * [self getCanvasDiagonal];
}
return [self fromRelative:length];
}
- (CGFloat)fromRelative:(RNSVGLength*)length {
- (CGFloat)fromRelative:(RNSVGLength *)length
{
CGFloat unit;
switch (length.unit) {
case SVG_LENGTHTYPE_EMS:
@@ -512,7 +511,8 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return CGRectGetHeight([self getContextBounds]);
}
- (CGFloat)getContextDiagonal {
- (CGFloat)getContextDiagonal
{
CGRect bounds = [self getContextBounds];
CGFloat width = CGRectGetWidth(bounds);
CGFloat height = CGRectGetHeight(bounds);
@@ -522,11 +522,12 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return r;
}
- (CGFloat) getCanvasWidth {
- (CGFloat)getCanvasWidth
{
if (canvasWidth != -1) {
return canvasWidth;
}
RNSVGGroup* root = [self textRoot];
RNSVGGroup *root = [self textRoot];
if (root == nil) {
canvasWidth = [self getContextWidth];
} else {
@@ -536,11 +537,12 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return canvasWidth;
}
- (CGFloat) getCanvasHeight {
- (CGFloat)getCanvasHeight
{
if (canvasHeight != -1) {
return canvasHeight;
}
RNSVGGroup* root = [self textRoot];
RNSVGGroup *root = [self textRoot];
if (root == nil) {
canvasHeight = [self getContextHeight];
} else {
@@ -550,7 +552,8 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return canvasHeight;
}
- (CGFloat) getCanvasDiagonal {
- (CGFloat)getCanvasDiagonal
{
if (canvasDiagonal != -1) {
return canvasDiagonal;
}
@@ -636,7 +639,6 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
_svgView = nil;
_textRoot = nil;
glyphContext = nil;
_transparent = NO;
_clipNode = nil;

View File

@@ -12,8 +12,8 @@
#import "RNSVGBrush.h"
#import "RNSVGCGFCRule.h"
#import "RNSVGNode.h"
#import "RNSVGLength.h"
#import "RNSVGNode.h"
#import "RNSVGVectorEffect.h"
@interface RNSVGRenderable : RNSVGNode

View File

@@ -6,18 +6,17 @@
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTPointerEvents.h>
#import "RNSVGRenderable.h"
#import "RNSVGClipPath.h"
#import "RNSVGMask.h"
#import "RNSVGViewBox.h"
#import "RNSVGVectorEffect.h"
#import <React/RCTPointerEvents.h>
#import "RNSVGBezierElement.h"
#import "RNSVGClipPath.h"
#import "RNSVGMarker.h"
#import "RNSVGMarkerPosition.h"
#import "RNSVGMask.h"
#import "RNSVGVectorEffect.h"
#import "RNSVGViewBox.h"
@implementation RNSVGRenderable
{
@implementation RNSVGRenderable {
NSMutableDictionary *_originProperties;
NSArray<NSString *> *_lastMergedList;
NSArray<NSString *> *_attributeList;
@@ -26,9 +25,15 @@
CGPathRef _srcHitPath;
}
static RNSVGRenderable * _contextElement;
+ (RNSVGRenderable *)contextElement { return _contextElement; }
+ (void)setContextElement:(RNSVGRenderable *)contextElement { _contextElement = contextElement; }
static RNSVGRenderable *_contextElement;
+ (RNSVGRenderable *)contextElement
{
return _contextElement;
}
+ (void)setContextElement:(RNSVGRenderable *)contextElement
{
_contextElement = contextElement;
}
- (id)init
{
@@ -97,7 +102,7 @@ static RNSVGRenderable * _contextElement;
_strokeOpacity = strokeOpacity;
}
- (void)setStrokeWidth:(RNSVGLength*)strokeWidth
- (void)setStrokeWidth:(RNSVGLength *)strokeWidth
{
if ([strokeWidth isEqualTo:_strokeWidth]) {
return;
@@ -217,7 +222,8 @@ static RNSVGRenderable * _contextElement;
}
#endif // RN_FABRIC_ENABLED
UInt32 saturate(CGFloat value) {
UInt32 saturate(CGFloat value)
{
return value <= 0 ? 0 : value >= 255 ? 255 : (UInt32)value;
}
@@ -234,7 +240,7 @@ UInt32 saturate(CGFloat value) {
if (self.mask) {
// https://www.w3.org/TR/SVG11/masking.html#MaskElement
RNSVGMask *_maskNode = (RNSVGMask*)[self.svgView getDefinedMask:self.mask];
RNSVGMask *_maskNode = (RNSVGMask *)[self.svgView getDefinedMask:self.mask];
CGRect bounds = CGContextGetClipBoundingBox(context);
CGSize boundsSize = bounds.size;
CGFloat height = boundsSize.height;
@@ -257,26 +263,29 @@ UInt32 saturate(CGFloat value) {
NSUInteger bitsPerComponent = 8;
NSUInteger bytesPerRow = bytesPerPixel * scaledWidth;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UInt32 * pixels = (UInt32 *) calloc(npixels, sizeof(UInt32));
CGContextRef bcontext = CGBitmapContextCreate(pixels, scaledWidth, scaledHeight, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
UInt32 *pixels = (UInt32 *)calloc(npixels, sizeof(UInt32));
CGContextRef bcontext = CGBitmapContextCreate(
pixels,
scaledWidth,
scaledHeight,
bitsPerComponent,
bytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextScaleCTM(bcontext, iscale, iscale);
// Clip to mask bounds and render the mask
CGFloat x = [self relativeOn:[_maskNode x]
relative:width];
CGFloat y = [self relativeOn:[_maskNode y]
relative:height];
CGFloat w = [self relativeOn:[_maskNode maskwidth]
relative:width];
CGFloat h = [self relativeOn:[_maskNode maskheight]
relative:height];
CGFloat x = [self relativeOn:[_maskNode x] relative:width];
CGFloat y = [self relativeOn:[_maskNode y] relative:height];
CGFloat w = [self relativeOn:[_maskNode maskwidth] relative:width];
CGFloat h = [self relativeOn:[_maskNode maskheight] relative:height];
CGRect maskBounds = CGRectMake(x, y, w, h);
CGContextClipToRect(bcontext, maskBounds);
[_maskNode renderLayerTo:bcontext rect:rect];
// Apply luminanceToAlpha filter primitive
// https://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement
UInt32 * currentPixel = pixels;
UInt32 *currentPixel = pixels;
for (NSUInteger i = 0; i < npixels; i++) {
UInt32 color = *currentPixel;
@@ -334,7 +343,8 @@ UInt32 saturate(CGFloat value) {
[self renderMarkers:context path:self.path rect:&rect];
}
- (void)prepareStrokeDash:(NSUInteger)count strokeDasharray:(NSArray<RNSVGLength *> *)strokeDasharray {
- (void)prepareStrokeDash:(NSUInteger)count strokeDasharray:(NSArray<RNSVGLength *> *)strokeDasharray
{
if (strokeDasharray != _sourceStrokeDashArray) {
CGFloat *dash = _strokeDashArrayData;
_strokeDashArrayData = (CGFloat *)realloc(dash, sizeof(CGFloat) * count);
@@ -349,17 +359,18 @@ UInt32 saturate(CGFloat value) {
}
}
- (void)renderMarkers:(CGContextRef)context path:(CGPathRef)path rect:(const CGRect *)rect {
RNSVGMarker *markerStart = (RNSVGMarker*)[self.svgView getDefinedMarker:self.markerStart];
RNSVGMarker *markerMid = (RNSVGMarker*)[self.svgView getDefinedMarker:self.markerMid];
RNSVGMarker *markerEnd = (RNSVGMarker*)[self.svgView getDefinedMarker:self.markerEnd];
- (void)renderMarkers:(CGContextRef)context path:(CGPathRef)path rect:(const CGRect *)rect
{
RNSVGMarker *markerStart = (RNSVGMarker *)[self.svgView getDefinedMarker:self.markerStart];
RNSVGMarker *markerMid = (RNSVGMarker *)[self.svgView getDefinedMarker:self.markerMid];
RNSVGMarker *markerEnd = (RNSVGMarker *)[self.svgView getDefinedMarker:self.markerEnd];
if (markerStart || markerMid || markerEnd) {
_contextElement = self;
NSArray<RNSVGMarkerPosition*>* positions = [RNSVGMarkerPosition fromCGPath:path];
NSArray<RNSVGMarkerPosition *> *positions = [RNSVGMarkerPosition fromCGPath:path];
CGFloat width = self.strokeWidth ? [self relativeOnOther:self.strokeWidth] : 1;
__block CGRect bounds = CGRectNull;
CGMutablePathRef markerPath = CGPathCreateMutable();
for (RNSVGMarkerPosition* position in positions) {
for (RNSVGMarkerPosition *position in positions) {
RNSVGMarkerType type = [position type];
RNSVGMarker *marker;
switch (type) {
@@ -467,8 +478,7 @@ UInt32 saturate(CGFloat value) {
[self.fill paint:context
opacity:self.fillOpacity
painter:[self.svgView getDefinedPainter:self.fill.brushRef]
bounds:pathBounds
];
bounds:pathBounds];
CGContextRestoreGState(context);
if (!self.stroke) {
@@ -482,7 +492,7 @@ UInt32 saturate(CGFloat value) {
CGContextSetLineWidth(context, width);
CGContextSetLineCap(context, self.strokeLinecap);
CGContextSetLineJoin(context, self.strokeLinejoin);
NSArray<RNSVGLength *>* strokeDasharray = self.strokeDasharray;
NSArray<RNSVGLength *> *strokeDasharray = self.strokeDasharray;
NSUInteger count = strokeDasharray.count;
if (count) {
@@ -501,7 +511,7 @@ UInt32 saturate(CGFloat value) {
BOOL strokeColor;
if (self.stroke.class == RNSVGBrush.class) {
CGContextSetStrokeColorWithColor(context,[self.tintColor CGColor]);
CGContextSetStrokeColorWithColor(context, [self.tintColor CGColor]);
strokeColor = YES;
} else {
strokeColor = [self.stroke applyStrokeColor:context opacity:self.strokeOpacity];
@@ -524,8 +534,7 @@ UInt32 saturate(CGFloat value) {
[self.stroke paint:context
opacity:self.strokeOpacity
painter:[self.svgView getDefinedPainter:self.stroke.brushRef]
bounds:pathBounds
];
bounds:pathBounds];
return;
}
}
@@ -547,9 +556,11 @@ UInt32 saturate(CGFloat value) {
if (self.stroke && self.strokeWidth) {
// Add stroke to hitArea
CGFloat width = [self relativeOnOther:self.strokeWidth];
self.strokePath = CGPathRetain((CGPathRef)CFAutorelease(CGPathCreateCopyByStrokingPath(path, nil, width, self.strokeLinecap, self.strokeLinejoin, self.strokeMiterlimit)));
self.strokePath = CGPathRetain((CGPathRef)CFAutorelease(CGPathCreateCopyByStrokingPath(
path, nil, width, self.strokeLinecap, self.strokeLinejoin, self.strokeMiterlimit)));
// TODO add dashing
// CGPathCreateCopyByDashingPath(CGPathRef _Nullable path, const CGAffineTransform * _Nullable transform, CGFloat phase, const CGFloat * _Nullable lengths, size_t count)
// CGPathCreateCopyByDashingPath(CGPathRef _Nullable path, const CGAffineTransform * _Nullable transform, CGFloat
// phase, const CGFloat * _Nullable lengths, size_t count)
}
}
@@ -566,7 +577,7 @@ UInt32 saturate(CGFloat value) {
}
BOOL canReceiveTouchEvents = (self.pointerEvents != RCTPointerEventsNone && ![self isHidden]);
if(!canReceiveTouchEvents) {
if (!canReceiveTouchEvents) {
return nil;
}
@@ -580,8 +591,7 @@ UInt32 saturate(CGFloat value) {
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
transformed = CGPointApplyAffineTransform(transformed, self.invTransform);
if (!CGRectContainsPoint(self.pathBounds, transformed) &&
!CGRectContainsPoint(self.markerBounds, transformed)) {
if (!CGRectContainsPoint(self.pathBounds, transformed) && !CGRectContainsPoint(self.markerBounds, transformed)) {
return nil;
}
@@ -593,14 +603,14 @@ UInt32 saturate(CGFloat value) {
}
if (self.clipPath) {
RNSVGClipPath *clipNode = (RNSVGClipPath*)[self.svgView getDefinedClipPath:self.clipPath];
RNSVGClipPath *clipNode = (RNSVGClipPath *)[self.svgView getDefinedClipPath:self.clipPath];
if ([clipNode isSimpleClipPath]) {
CGPathRef clipPath = [self getClipPath];
if (clipPath && !CGPathContainsPoint(clipPath, nil, transformed, clipNode.clipRule == kRNSVGCGFCRuleEvenodd)) {
return nil;
}
} else {
RNSVGRenderable *clipGroup = (RNSVGRenderable*)clipNode;
RNSVGRenderable *clipGroup = (RNSVGRenderable *)clipNode;
if (![clipGroup hitTest:transformed withEvent:event]) {
return nil;
}
@@ -624,7 +634,7 @@ UInt32 saturate(CGFloat value) {
}
self.merging = true;
NSMutableArray* attributeList = self.propList ? [self.propList mutableCopy] : [[NSMutableArray alloc] init];
NSMutableArray *attributeList = self.propList ? [self.propList mutableCopy] : [[NSMutableArray alloc] init];
_originProperties = [[NSMutableDictionary alloc] init];
for (NSString *key in targetAttributeList) {

View File

@@ -1,5 +1,5 @@
// Most (if not all) of this file could probably go away once react-native-macos's version of RCTUIKit.h makes its way upstream.
// https://github.com/microsoft/react-native-macos/issues/242
// Most (if not all) of this file could probably go away once react-native-macos's version of RCTUIKit.h makes its way
// upstream. https://github.com/microsoft/react-native-macos/issues/242
#if !TARGET_OS_OSX
@@ -12,9 +12,9 @@
#else // TARGET_OS_OSX [
// Due to name mangling, calling c-style functions from .mm files will fail, therefore we need to wrap them with extern "C"
// so they are handled correctly. We also need to have imports positioned in a correct way,
// so that this extern "C" wrapper is used before the functions from RCTUIKit are used.
// Due to name mangling, calling c-style functions from .mm files will fail, therefore we need to wrap them with extern
// "C" so they are handled correctly. We also need to have imports positioned in a correct way, so that this extern "C"
// wrapper is used before the functions from RCTUIKit are used.
#ifdef __cplusplus
extern "C" {
#endif
@@ -37,7 +37,8 @@ extern "C" {
@end
// TODO: These could probably be a part of react-native-macos
// See https://github.com/microsoft/react-native-macos/issues/658 and https://github.com/microsoft/react-native-macos/issues/659
// See https://github.com/microsoft/react-native-macos/issues/658 and
// https://github.com/microsoft/react-native-macos/issues/659
@interface NSImage (RNSVGMacOSExtensions)
@property (readonly) CGImageRef CGImage;
@end

View File

@@ -1,7 +1,6 @@
#import "RNSVGUIKit.h"
@implementation RNSVGView
{
@implementation RNSVGView {
NSColor *_tintColor;
}
@@ -46,17 +45,15 @@
@end
@implementation NSImage (RNSVGMacOSExtensions)
- (CGImageRef) CGImage
- (CGImageRef)CGImage
{
return [self CGImageForProposedRect:NULL context:NULL hints:NULL];
}
@end
@implementation NSValue (RNSVGMacOSExtensions)
+ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform

View File

@@ -12,9 +12,8 @@
@interface RNSVGCircle : RNSVGRenderable
@property (nonatomic, strong) RNSVGLength* cx;
@property (nonatomic, strong) RNSVGLength* cy;
@property (nonatomic, strong) RNSVGLength* r;
@property (nonatomic, strong) RNSVGLength *cx;
@property (nonatomic, strong) RNSVGLength *cy;
@property (nonatomic, strong) RNSVGLength *r;
@end

View File

@@ -11,9 +11,9 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED

View File

@@ -11,8 +11,8 @@
#import "RNSVGPath.h"
@interface RNSVGEllipse : RNSVGRenderable
@property (nonatomic, strong) RNSVGLength* cx;
@property (nonatomic, strong) RNSVGLength* cy;
@property (nonatomic, strong) RNSVGLength* rx;
@property (nonatomic, strong) RNSVGLength* ry;
@property (nonatomic, strong) RNSVGLength *cx;
@property (nonatomic, strong) RNSVGLength *cy;
@property (nonatomic, strong) RNSVGLength *rx;
@property (nonatomic, strong) RNSVGLength *ry;
@end

View File

@@ -11,9 +11,9 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED

View File

@@ -11,8 +11,8 @@
#import "RNSVGPath.h"
@interface RNSVGLine : RNSVGRenderable
@property (nonatomic, strong) RNSVGLength* x1;
@property (nonatomic, strong) RNSVGLength* y1;
@property (nonatomic, strong) RNSVGLength* x2;
@property (nonatomic, strong) RNSVGLength* y2;
@property (nonatomic, strong) RNSVGLength *x1;
@property (nonatomic, strong) RNSVGLength *y1;
@property (nonatomic, strong) RNSVGLength *x2;
@property (nonatomic, strong) RNSVGLength *y2;
@end

View File

@@ -11,9 +11,9 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED

View File

@@ -12,11 +12,11 @@
@interface RNSVGRect : RNSVGRenderable
@property (nonatomic, strong) RNSVGLength* x;
@property (nonatomic, strong) RNSVGLength* y;
@property (nonatomic, strong) RNSVGLength* rectwidth;
@property (nonatomic, strong) RNSVGLength* rectheight;
@property (nonatomic, strong) RNSVGLength* rx;
@property (nonatomic, strong) RNSVGLength* ry;
@property (nonatomic, strong) RNSVGLength *x;
@property (nonatomic, strong) RNSVGLength *y;
@property (nonatomic, strong) RNSVGLength *rectwidth;
@property (nonatomic, strong) RNSVGLength *rectheight;
@property (nonatomic, strong) RNSVGLength *rx;
@property (nonatomic, strong) RNSVGLength *ry;
@end

View File

@@ -11,9 +11,9 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED

View File

@@ -2,16 +2,16 @@
#import "RNSVGUIKit.h"
#import "RNSVGTextProperties.h"
#import "RNSVGPropHelper.h"
#import "RNSVGTextProperties.h"
@interface RNSVGFontData : NSObject {
@public
@public
CGFloat fontSize;
NSString * fontSize_;
NSString *fontSize_;
NSString *fontFamily;
enum RNSVGFontStyle fontStyle;
NSDictionary * fontData;
NSDictionary *fontData;
enum RNSVGFontWeight fontWeight;
int absoluteFontWeight;
NSString *fontFeatureSettings;
@@ -26,11 +26,9 @@
+ (instancetype)Defaults;
+ (CGFloat)toAbsoluteWithNSString:(NSString *)string
fontSize:(CGFloat)fontSize;
+ (CGFloat)toAbsoluteWithNSString:(NSString *)string fontSize:(CGFloat)fontSize;
+ (instancetype)initWithNSDictionary:(NSDictionary *)font
parent:(RNSVGFontData *)parent;
+ (instancetype)initWithNSDictionary:(NSDictionary *)font parent:(RNSVGFontData *)parent;
@end

View File

@@ -1,7 +1,7 @@
#import "RNSVGFontData.h"
#import "RNSVGNode.h"
#import "RNSVGPropHelper.h"
#import "RNSVGTextProperties.h"
#import "RNSVGNode.h"
#define RNSVG_DEFAULT_KERNING 0.0
#define RNSVG_DEFAULT_WORD_SPACING 0.0
@@ -23,7 +23,8 @@ RNSVGFontData *RNSVGFontData_Defaults;
@implementation RNSVGFontData
+ (instancetype)Defaults {
+ (instancetype)Defaults
{
if (!RNSVGFontData_Defaults) {
RNSVGFontData *self = [RNSVGFontData alloc];
self->fontData = nil;
@@ -45,23 +46,24 @@ RNSVGFontData *RNSVGFontData_Defaults;
return RNSVGFontData_Defaults;
}
+ (CGFloat)toAbsoluteWithNSString:(NSString *)string
fontSize:(CGFloat)fontSize {
return [RNSVGPropHelper fromRelativeWithNSString:string
relative:0
fontSize:fontSize];
+ (CGFloat)toAbsoluteWithNSString:(NSString *)string fontSize:(CGFloat)fontSize
{
return [RNSVGPropHelper fromRelativeWithNSString:string relative:0 fontSize:fontSize];
}
- (void)setInheritedWeight:(RNSVGFontData*) parent {
- (void)setInheritedWeight:(RNSVGFontData *)parent
{
absoluteFontWeight = parent->absoluteFontWeight;
fontWeight = parent->fontWeight;
}
RNSVGFontWeight nearestFontWeight(int absoluteFontWeight) {
RNSVGFontWeight nearestFontWeight(int absoluteFontWeight)
{
return RNSVGFontWeights[(int)round(absoluteFontWeight / 100.0)];
}
- (void)handleNumericWeight:(RNSVGFontData*)parent weight:(double)weight {
- (void)handleNumericWeight:(RNSVGFontData *)parent weight:(double)weight
{
long roundWeight = round(weight);
if (roundWeight >= 1 && roundWeight <= 1000) {
absoluteFontWeight = (int)roundWeight;
@@ -72,7 +74,8 @@ RNSVGFontWeight nearestFontWeight(int absoluteFontWeight) {
}
// https://drafts.csswg.org/css-fonts-4/#relative-weights
int AbsoluteFontWeight(RNSVGFontWeight fontWeight, RNSVGFontData* parent) {
int AbsoluteFontWeight(RNSVGFontWeight fontWeight, RNSVGFontData *parent)
{
if (fontWeight == RNSVGFontWeightBolder) {
return bolder(parent->absoluteFontWeight);
} else if (fontWeight == RNSVGFontWeightLighter) {
@@ -82,7 +85,8 @@ int AbsoluteFontWeight(RNSVGFontWeight fontWeight, RNSVGFontData* parent) {
}
}
int bolder(int inherited) {
int bolder(int inherited)
{
if (inherited < 350) {
return 400;
} else if (inherited < 550) {
@@ -94,7 +98,8 @@ int bolder(int inherited) {
}
}
int lighter(int inherited) {
int lighter(int inherited)
{
if (inherited < 100) {
return inherited;
} else if (inherited < 550) {
@@ -106,22 +111,21 @@ int lighter(int inherited) {
}
}
+ (instancetype)initWithNSDictionary:(NSDictionary *)font
parent:(RNSVGFontData *)parent {
+ (instancetype)initWithNSDictionary:(NSDictionary *)font parent:(RNSVGFontData *)parent
{
RNSVGFontData *data = [RNSVGFontData alloc];
CGFloat parentFontSize = parent->fontSize;
if ([font objectForKey:FONT_SIZE]) {
id fontSize = [font objectForKey:FONT_SIZE];
if ([fontSize isKindOfClass:NSNumber.class]) {
NSNumber* fs = fontSize;
NSNumber *fs = fontSize;
data->fontSize = (CGFloat)[fs doubleValue];
} else {
data->fontSize = [RNSVGPropHelper fromRelativeWithNSString:fontSize
relative:parentFontSize
fontSize:parentFontSize];
}
}
else {
} else {
data->fontSize = parentFontSize;
}
@@ -130,7 +134,7 @@ int lighter(int inherited) {
if ([fontWeight isKindOfClass:NSNumber.class]) {
[data handleNumericWeight:parent weight:[fontWeight doubleValue]];
} else {
NSString* weight = fontWeight;
NSString *weight = fontWeight;
NSInteger fw = RNSVGFontWeightFromString(weight);
if (fw != -1) {
data->absoluteFontWeight = AbsoluteFontWeight((RNSVGFontWeight)fw, parent);
@@ -147,54 +151,46 @@ int lighter(int inherited) {
data->fontData = [font objectForKey:FONT_DATA] ? [font objectForKey:FONT_DATA] : parent->fontData;
data->fontFamily = [font objectForKey:FONT_FAMILY] ? [font objectForKey:FONT_FAMILY] : parent->fontFamily;
NSString* style = [font objectForKey:FONT_STYLE];
NSString *style = [font objectForKey:FONT_STYLE];
data->fontStyle = style ? RNSVGFontStyleFromString(style) : parent->fontStyle;
NSString* feature = [font objectForKey:FONT_FEATURE_SETTINGS];
NSString *feature = [font objectForKey:FONT_FEATURE_SETTINGS];
data->fontFeatureSettings = feature ? [font objectForKey:FONT_FEATURE_SETTINGS] : parent->fontFeatureSettings;
NSString* variant = [font objectForKey:FONT_VARIANT_LIGATURES];
NSString *variant = [font objectForKey:FONT_VARIANT_LIGATURES];
data->fontVariantLigatures = variant ? RNSVGFontVariantLigaturesFromString(variant) : parent->fontVariantLigatures;
NSString* anchor = [font objectForKey:TEXT_ANCHOR];
NSString *anchor = [font objectForKey:TEXT_ANCHOR];
data->textAnchor = anchor ? RNSVGTextAnchorFromString(anchor) : parent->textAnchor;
NSString* decoration = [font objectForKey:TEXT_DECORATION];
NSString *decoration = [font objectForKey:TEXT_DECORATION];
data->textDecoration = decoration ? RNSVGTextDecorationFromString(decoration) : parent->textDecoration;
CGFloat fontSize = data->fontSize;
id kerning = [font objectForKey:KERNING];
data->manualKerning = (kerning || parent->manualKerning );
data->manualKerning = (kerning || parent->manualKerning);
if ([kerning isKindOfClass:NSNumber.class]) {
NSNumber* kern = kerning;
NSNumber *kern = kerning;
data->kerning = (CGFloat)[kern doubleValue];
} else {
data->kerning = kerning ?
[RNSVGFontData toAbsoluteWithNSString:kerning
fontSize:fontSize]
: parent->kerning;
data->kerning = kerning ? [RNSVGFontData toAbsoluteWithNSString:kerning fontSize:fontSize] : parent->kerning;
}
id wordSpacing = [font objectForKey:WORD_SPACING];
if ([wordSpacing isKindOfClass:NSNumber.class]) {
NSNumber* ws = wordSpacing;
NSNumber *ws = wordSpacing;
data->wordSpacing = (CGFloat)[ws doubleValue];
} else {
data->wordSpacing = wordSpacing ?
[RNSVGFontData toAbsoluteWithNSString:wordSpacing
fontSize:fontSize]
: parent->wordSpacing;
data->wordSpacing =
wordSpacing ? [RNSVGFontData toAbsoluteWithNSString:wordSpacing fontSize:fontSize] : parent->wordSpacing;
}
id letterSpacing = [font objectForKey:LETTER_SPACING];
if ([letterSpacing isKindOfClass:NSNumber.class]) {
NSNumber* ls = letterSpacing;
NSNumber *ls = letterSpacing;
data->wordSpacing = (CGFloat)[ls doubleValue];
} else {
data->letterSpacing = letterSpacing ?
[RNSVGFontData toAbsoluteWithNSString:letterSpacing
fontSize:fontSize]
: parent->letterSpacing;
data->letterSpacing =
letterSpacing ? [RNSVGFontData toAbsoluteWithNSString:letterSpacing fontSize:fontSize] : parent->letterSpacing;
}
return data;
}
@end

View File

@@ -1,5 +1,5 @@
#import <React/UIView+React.h>
#import <CoreText/CoreText.h>
#import <React/UIView+React.h>
#import "RNSVGFontData.h"
@class RNSVGText;
@@ -10,8 +10,7 @@
- (CTFontRef)getGlyphFont;
- (instancetype)initWithWidth:(CGFloat)width
height:(CGFloat)height;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;
- (RNSVGFontData *)getFont;
@@ -33,17 +32,16 @@
- (void)popContext;
- (void)pushContext:(RNSVGText*)node
font:(NSDictionary*)font
x:(NSArray<RNSVGLength*>*)x
y:(NSArray<RNSVGLength*>*)y
deltaX:(NSArray<RNSVGLength*>*)deltaX
deltaY:(NSArray<RNSVGLength*>*)deltaY
rotate:(NSArray<RNSVGLength*>*)rotate;
- (void)pushContext:(RNSVGText *)node
font:(NSDictionary *)font
x:(NSArray<RNSVGLength *> *)x
y:(NSArray<RNSVGLength *> *)y
deltaX:(NSArray<RNSVGLength *> *)deltaX
deltaY:(NSArray<RNSVGLength *> *)deltaY
rotate:(NSArray<RNSVGLength *> *)rotate;
- (void)pushContext:(RNSVGGroup*)node
font:(NSDictionary *)font;
- (void)pushContext:(RNSVGGroup *)node font:(NSDictionary *)font;
- (NSArray*)getFontContext;
- (NSArray *)getFontContext;
@end

View File

@@ -1,36 +1,36 @@
#import "RNSVGGlyphContext.h"
#import <React/RCTFont.h>
#import "RNSVGFontData.h"
#import "RNSVGNode.h"
#import "RNSVGPropHelper.h"
#import "RNSVGFontData.h"
#import "RNSVGText.h"
// https://www.w3.org/TR/SVG/text.html#TSpanElement
@interface RNSVGGlyphContext () {
@public
@public
// Current stack (one per node push/pop)
NSMutableArray *mFontContext_;
// Unique input attribute lists (only added if node sets a value)
NSMutableArray<NSArray<RNSVGLength*>*> *mXsContext_;
NSMutableArray<NSArray<RNSVGLength*>*> *mYsContext_;
NSMutableArray<NSArray<RNSVGLength*>*> *mDXsContext_;
NSMutableArray<NSArray<RNSVGLength*>*> *mDYsContext_;
NSMutableArray<NSArray<RNSVGLength*>*> *mRsContext_;
NSMutableArray<NSArray<RNSVGLength *> *> *mXsContext_;
NSMutableArray<NSArray<RNSVGLength *> *> *mYsContext_;
NSMutableArray<NSArray<RNSVGLength *> *> *mDXsContext_;
NSMutableArray<NSArray<RNSVGLength *> *> *mDYsContext_;
NSMutableArray<NSArray<RNSVGLength *> *> *mRsContext_;
// Unique index into attribute list (one per unique list)
NSMutableArray<NSNumber*> *mXIndices_;
NSMutableArray<NSNumber*> *mYIndices_;
NSMutableArray<NSNumber*> *mDXIndices_;
NSMutableArray<NSNumber*> *mDYIndices_;
NSMutableArray<NSNumber*> *mRIndices_;
NSMutableArray<NSNumber *> *mXIndices_;
NSMutableArray<NSNumber *> *mYIndices_;
NSMutableArray<NSNumber *> *mDXIndices_;
NSMutableArray<NSNumber *> *mDYIndices_;
NSMutableArray<NSNumber *> *mRIndices_;
// Index of unique context used (one per node push/pop)
NSMutableArray<NSNumber*> *mXsIndices_;
NSMutableArray<NSNumber*> *mYsIndices_;
NSMutableArray<NSNumber*> *mDXsIndices_;
NSMutableArray<NSNumber*> *mDYsIndices_;
NSMutableArray<NSNumber*> *mRsIndices_;
NSMutableArray<NSNumber *> *mXsIndices_;
NSMutableArray<NSNumber *> *mYsIndices_;
NSMutableArray<NSNumber *> *mDXsIndices_;
NSMutableArray<NSNumber *> *mDYsIndices_;
NSMutableArray<NSNumber *> *mRsIndices_;
// Calculated on push context, percentage and em length depends on parent font size
CGFloat mFontSize_;
@@ -51,25 +51,25 @@
// https://www.w3.org/TR/SVG/types.html#DataTypeCoordinates
// https://www.w3.org/TR/SVG/text.html#TSpanElementXAttribute
NSArray<RNSVGLength*> *mXs_;
NSArray<RNSVGLength *> *mXs_;
// https://www.w3.org/TR/SVG/text.html#TSpanElementYAttribute
NSArray<RNSVGLength*> *mYs_;
NSArray<RNSVGLength *> *mYs_;
// Current <list-of-lengths> SVGLengthList
// https://www.w3.org/TR/SVG/types.html#DataTypeLengths
// https://www.w3.org/TR/SVG/text.html#TSpanElementDXAttribute
NSArray<RNSVGLength*> *mDXs_;
NSArray<RNSVGLength *> *mDXs_;
// https://www.w3.org/TR/SVG/text.html#TSpanElementDYAttribute
NSArray<RNSVGLength*> *mDYs_;
NSArray<RNSVGLength *> *mDYs_;
// Current <list-of-numbers> SVGLengthList
// https://www.w3.org/TR/SVG/types.html#DataTypeNumbers
// https://www.w3.org/TR/SVG/text.html#TSpanElementRotateAttribute
NSArray<RNSVGLength*> *mRs_;
NSArray<RNSVGLength *> *mRs_;
// Current attribute list index
long mXsIndex_;
@@ -93,21 +93,21 @@
CGFloat mHeight_;
}
- (void)pushContext:(RNSVGText*)node
font:(NSDictionary*)font
x:(NSArray<RNSVGLength*>*)x
y:(NSArray<RNSVGLength*>*)y
deltaX:(NSArray<RNSVGLength*>*)deltaX
deltaY:(NSArray<RNSVGLength*>*)deltaY
rotate:(NSArray<RNSVGLength*>*)rotate;
- (void)pushContext:(RNSVGText *)node
font:(NSDictionary *)font
x:(NSArray<RNSVGLength *> *)x
y:(NSArray<RNSVGLength *> *)y
deltaX:(NSArray<RNSVGLength *> *)deltaX
deltaY:(NSArray<RNSVGLength *> *)deltaY
rotate:(NSArray<RNSVGLength *> *)rotate;
- (void)pushContext:(RNSVGGroup*)node
font:(NSDictionary *)font;
- (void)pushContext:(RNSVGGroup *)node font:(NSDictionary *)font;
@end
@implementation RNSVGGlyphContext
- (NSArray*)getFontContext {
- (NSArray *)getFontContext
{
return mFontContext_;
}
@@ -160,8 +160,7 @@
if (axisMinValue && CFGetTypeID(axisMinValue) == CFNumberGetTypeID()) {
CFNumberRef axisMinValueNumber = (CFNumberRef)axisMinValue;
double axisMinValueDouble;
if (CFNumberGetValue(axisMinValueNumber, kCFNumberDoubleType, &axisMinValueDouble))
{
if (CFNumberGetValue(axisMinValueNumber, kCFNumberDoubleType, &axisMinValueDouble)) {
weight = fmax(axisMinValueDouble, weight);
}
}
@@ -170,8 +169,7 @@
if (axisMaxValue && CFGetTypeID(axisMaxValue) == CFNumberGetTypeID()) {
CFNumberRef axisMaxValueNumber = (CFNumberRef)axisMaxValue;
double axisMaxValueDouble;
if (CFNumberGetValue(axisMaxValueNumber, kCFNumberDoubleType, &axisMaxValueDouble))
{
if (CFNumberGetValue(axisMaxValueNumber, kCFNumberDoubleType, &axisMaxValueDouble)) {
weight = fmin(axisMaxValueDouble, weight);
}
}
@@ -206,36 +204,36 @@
[self->mRsIndices_ addObject:[NSNumber numberWithLong:self->mRsIndex_]];
}
- (instancetype)initWithWidth:(CGFloat)width
height:(CGFloat)height {
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height
{
self = [super init];
self->mFontContext_ = [[NSMutableArray alloc]init];
self->mXsContext_ = [[NSMutableArray alloc]init];
self->mYsContext_ = [[NSMutableArray alloc]init];
self->mDXsContext_ = [[NSMutableArray alloc]init];
self->mDYsContext_ = [[NSMutableArray alloc]init];
self->mRsContext_ = [[NSMutableArray alloc]init];
self->mFontContext_ = [[NSMutableArray alloc] init];
self->mXsContext_ = [[NSMutableArray alloc] init];
self->mYsContext_ = [[NSMutableArray alloc] init];
self->mDXsContext_ = [[NSMutableArray alloc] init];
self->mDYsContext_ = [[NSMutableArray alloc] init];
self->mRsContext_ = [[NSMutableArray alloc] init];
self->mXIndices_ = [[NSMutableArray alloc]init];
self->mYIndices_ = [[NSMutableArray alloc]init];
self->mDXIndices_ = [[NSMutableArray alloc]init];
self->mDYIndices_ = [[NSMutableArray alloc]init];
self->mRIndices_ = [[NSMutableArray alloc]init];
self->mXIndices_ = [[NSMutableArray alloc] init];
self->mYIndices_ = [[NSMutableArray alloc] init];
self->mDXIndices_ = [[NSMutableArray alloc] init];
self->mDYIndices_ = [[NSMutableArray alloc] init];
self->mRIndices_ = [[NSMutableArray alloc] init];
self->mXsIndices_ = [[NSMutableArray alloc]init];
self->mYsIndices_ = [[NSMutableArray alloc]init];
self->mDXsIndices_ = [[NSMutableArray alloc]init];
self->mDYsIndices_ = [[NSMutableArray alloc]init];
self->mRsIndices_ = [[NSMutableArray alloc]init];
self->mXsIndices_ = [[NSMutableArray alloc] init];
self->mYsIndices_ = [[NSMutableArray alloc] init];
self->mDXsIndices_ = [[NSMutableArray alloc] init];
self->mDYsIndices_ = [[NSMutableArray alloc] init];
self->mRsIndices_ = [[NSMutableArray alloc] init];
self->mFontSize_ = RNSVGFontData_DEFAULT_FONT_SIZE;
self->topFont_ = [RNSVGFontData Defaults];
self->mXs_ = [[NSArray alloc]init];
self->mYs_ = [[NSArray alloc]init];
self->mDXs_ = [[NSArray alloc]init];
self->mDYs_ = [[NSArray alloc]init];
self->mRs_ = [[NSArray alloc]initWithObjects:[RNSVGLength lengthWithNumber:0], nil];
self->mXs_ = [[NSArray alloc] init];
self->mYs_ = [[NSArray alloc] init];
self->mDXs_ = [[NSArray alloc] init];
self->mDYs_ = [[NSArray alloc] init];
self->mRs_ = [[NSArray alloc] initWithObjects:[RNSVGLength lengthWithNumber:0], nil];
self->mXIndex_ = -1;
self->mYIndex_ = -1;
@@ -263,7 +261,8 @@
return self;
}
- (RNSVGFontData *)getFont {
- (RNSVGFontData *)getFont
{
return topFont_;
}
@@ -293,27 +292,27 @@
[self->mFontContext_ addObject:parent];
return;
}
RNSVGFontData *data = [RNSVGFontData initWithNSDictionary:font
parent:parent];
RNSVGFontData *data = [RNSVGFontData initWithNSDictionary:font parent:parent];
self->mFontSize_ = data->fontSize;
[self->mFontContext_ addObject:data];
self->topFont_ = data;
}
- (void)pushContext:(RNSVGGroup*)node
font:(NSDictionary*)font {
- (void)pushContext:(RNSVGGroup *)node font:(NSDictionary *)font
{
[self pushNode:node andFont:font];
[self pushIndices];
}
- (void)pushContext:(RNSVGText*)node
font:(NSDictionary*)font
x:(NSArray<RNSVGLength*>*)x
y:(NSArray<RNSVGLength*>*)y
deltaX:(NSArray<RNSVGLength*>*)deltaX
deltaY:(NSArray<RNSVGLength*>*)deltaY
rotate:(NSArray<RNSVGLength*>*)rotate {
[self pushNode:(RNSVGGroup*)node andFont:font];
- (void)pushContext:(RNSVGText *)node
font:(NSDictionary *)font
x:(NSArray<RNSVGLength *> *)x
y:(NSArray<RNSVGLength *> *)y
deltaX:(NSArray<RNSVGLength *> *)deltaX
deltaY:(NSArray<RNSVGLength *> *)deltaY
rotate:(NSArray<RNSVGLength *> *)rotate
{
[self pushNode:(RNSVGGroup *)node andFont:font];
if (x != nil && [x count] != 0) {
mXsIndex_++;
mXIndex_ = -1;
@@ -352,7 +351,8 @@
[self pushIndices];
}
- (void)popContext {
- (void)popContext
{
[mFontContext_ removeLastObject];
[mXsIndices_ removeLastObject];
[mYsIndices_ removeLastObject];
@@ -442,68 +442,66 @@
* Except for any additional information provided in this specification,
* the normative definition of the property is in CSS2 ([CSS2], section 15.2.4).
*/
- (CGFloat)getFontSize {
- (CGFloat)getFontSize
{
return mFontSize_;
}
- (CGFloat)nextXWithDouble:(CGFloat)advance {
- (CGFloat)nextXWithDouble:(CGFloat)advance
{
[RNSVGGlyphContext incrementIndices:mXIndices_ topIndex:mXsIndex_];
long nextIndex = mXIndex_ + 1;
if (nextIndex < [mXs_ count]) {
mDX_ = 0;
mXIndex_ = nextIndex;
RNSVGLength *length = [mXs_ objectAtIndex:nextIndex];
mX_ = [RNSVGPropHelper fromRelative:length
relative:mWidth_
fontSize:mFontSize_];
mX_ = [RNSVGPropHelper fromRelative:length relative:mWidth_ fontSize:mFontSize_];
}
mX_ += advance;
return mX_;
}
- (CGFloat)nextY {
- (CGFloat)nextY
{
[RNSVGGlyphContext incrementIndices:mYIndices_ topIndex:mYsIndex_];
long nextIndex = mYIndex_ + 1;
if (nextIndex < [mYs_ count]) {
mDY_ = 0;
mYIndex_ = nextIndex;
RNSVGLength *length = [mYs_ objectAtIndex:nextIndex];
mY_ = [RNSVGPropHelper fromRelative:length
relative:mHeight_
fontSize:mFontSize_];
mY_ = [RNSVGPropHelper fromRelative:length relative:mHeight_ fontSize:mFontSize_];
}
return mY_;
}
- (CGFloat)nextDeltaX {
- (CGFloat)nextDeltaX
{
[RNSVGGlyphContext incrementIndices:mDXIndices_ topIndex:mDXsIndex_];
long nextIndex = mDXIndex_ + 1;
if (nextIndex < [mDXs_ count]) {
mDXIndex_ = nextIndex;
RNSVGLength *length = [mDXs_ objectAtIndex:nextIndex];
CGFloat val = [RNSVGPropHelper fromRelative:length
relative:mWidth_
fontSize:mFontSize_];
CGFloat val = [RNSVGPropHelper fromRelative:length relative:mWidth_ fontSize:mFontSize_];
mDX_ += val;
}
return mDX_;
}
- (CGFloat)nextDeltaY {
- (CGFloat)nextDeltaY
{
[RNSVGGlyphContext incrementIndices:mDYIndices_ topIndex:mDYsIndex_];
long nextIndex = mDYIndex_ + 1;
if (nextIndex < [mDYs_ count]) {
mDYIndex_ = nextIndex;
RNSVGLength *length = [mDYs_ objectAtIndex:nextIndex];
CGFloat val = [RNSVGPropHelper fromRelative:length
relative:mHeight_
fontSize:mFontSize_];
CGFloat val = [RNSVGPropHelper fromRelative:length relative:mHeight_ fontSize:mFontSize_];
mDY_ += val;
}
return mDY_;
}
- (CGFloat)nextRotation {
- (CGFloat)nextRotation
{
[RNSVGGlyphContext incrementIndices:mRIndices_ topIndex:mRsIndex_];
long nextIndex = mRIndex_ + 1;
long count = [mRs_ count];
@@ -515,11 +513,13 @@
return [mRs_[mRIndex_] value];
}
- (CGFloat)getWidth {
- (CGFloat)getWidth
{
return mWidth_;
}
- (CGFloat)getHeight {
- (CGFloat)getHeight
{
return mHeight_;
}
@end

View File

@@ -7,16 +7,11 @@
@interface RNSVGPropHelper : NSObject
+ (CGFloat) fromRelativeWithNSString:(NSString *)length
relative:(CGFloat)relative
fontSize:(CGFloat)fontSize;
+ (CGFloat)fromRelativeWithNSString:(NSString *)length relative:(CGFloat)relative fontSize:(CGFloat)fontSize;
+ (CGFloat) fromRelative:(RNSVGLength*)length
relative:(CGFloat)relative
fontSize:(CGFloat)fontSize;
+ (CGFloat)fromRelative:(RNSVGLength *)length relative:(CGFloat)relative fontSize:(CGFloat)fontSize;
+ (CGFloat)fromRelative:(RNSVGLength*)length
relative:(CGFloat)relative;
+ (CGFloat)fromRelative:(RNSVGLength *)length relative:(CGFloat)relative;
@end
#endif

Some files were not shown because too many files have changed in this diff Show More