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 run: yarn
- name: Build - name: Build
run: yarn bob run: yarn bob
- name: Lint - name: Test and lint
run: yarn lint run: yarn test
- name: Tests
run: yarn jest
- name: Build Example App - name: Build Example App
working-directory: Example/ working-directory: Example/
run: yarn && yarn tsc 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 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662 DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
FBLazyVector: bcdeff523be9f87a135b7c6fde8736db94904716 FBLazyVector: bcdeff523be9f87a135b7c6fde8736db94904716
FBReactNativeSpec: 226f8b0f1a2e736a49301883ee34bca88cdc24f6 FBReactNativeSpec: 0c3f104f594b34d7b3a923cd12e03b0d4e12eaf5
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0 Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
Flipper-DoubleConversion: 57ffbe81ef95306cc9e69c4aa3aeeeeb58a6a28c Flipper-DoubleConversion: 57ffbe81ef95306cc9e69c4aa3aeeeeb58a6a28c

View File

@@ -112,7 +112,7 @@ export default function TestComponent() {
onError={onError} onError={onError}
onLoad={onLoad} 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'; import { SvgUri } from 'react-native-svg';
export default () => { 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 ( return (
<SvgUri <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%" width="100%"
height="100%" height="100%"
uri={uri} uri={uri}
/> />
); );
} };
``` ```
# Use with svg files # Use with svg files

View File

@@ -10,6 +10,7 @@ buildscript {
dependencies { dependencies {
classpath("com.android.tools.build:gradle:3.6.1") 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" apply plugin: "com.facebook.react"
} }
if (project == rootProject) {
apply from: 'spotless.gradle'
}
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
def safeExtGet(prop, fallback) { 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; package com.horcrux.svg;
import android.content.Context; import android.content.Context;
import android.view.ViewGroup;
import androidx.annotation.UiThread; import androidx.annotation.UiThread;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap; import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.uimanager.FabricViewStateManager; 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.HasFabricViewStateManager;
import com.facebook.react.uimanager.FabricViewStateManager.StateUpdateCallback; import com.facebook.react.uimanager.FabricViewStateManager.StateUpdateCallback;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.views.view.ReactViewGroup; import com.facebook.react.views.view.ReactViewGroup;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; 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(); private final FabricViewStateManager mFabricViewStateManager = new FabricViewStateManager();
@NotNull @NotNull
@@ -30,30 +29,34 @@ public abstract class FabricEnabledViewGroup extends ReactViewGroup implements H
@UiThread @UiThread
public final void updateState(int width, int height) { public final void updateState(int width, int height) {
final float realWidth = PixelUtil.toDIPFromPixel((float)width); final float realWidth = PixelUtil.toDIPFromPixel((float) width);
final float realHeight = PixelUtil.toDIPFromPixel((float)height); final float realHeight = PixelUtil.toDIPFromPixel((float) height);
ReadableMap currentState = this.mFabricViewStateManager.getStateData(); ReadableMap currentState = this.mFabricViewStateManager.getStateData();
if (currentState != null) { if (currentState != null) {
float delta = 0.9F; float delta = 0.9F;
float stateFrameHeight = currentState.hasKey("frameHeight") ? (float)currentState.getDouble("frameHeight") : 0.0F; float stateFrameHeight =
float stateFrameWidth = currentState.hasKey("frameWidth") ? (float)currentState.getDouble("frameWidth") : 0.0F; currentState.hasKey("frameHeight") ? (float) currentState.getDouble("frameHeight") : 0.0F;
if (Math.abs(stateFrameWidth - realWidth) < delta && float stateFrameWidth =
Math.abs(stateFrameHeight - realHeight) < delta) { currentState.hasKey("frameWidth") ? (float) currentState.getDouble("frameWidth") : 0.0F;
if (Math.abs(stateFrameWidth - realWidth) < delta
&& Math.abs(stateFrameHeight - realHeight) < delta) {
return; return;
} }
} }
this.mFabricViewStateManager.setState((StateUpdateCallback)(new StateUpdateCallback() { this.mFabricViewStateManager.setState(
(StateUpdateCallback)
(new StateUpdateCallback() {
public final WritableMap getStateUpdate() { public final WritableMap getStateUpdate() {
WritableMap map = (WritableMap)(new WritableNativeMap()); WritableMap map = (WritableMap) (new WritableNativeMap());
map.putDouble("frameWidth", (double)realWidth); map.putDouble("frameWidth", (double) realWidth);
map.putDouble("frameHeight", (double)realHeight); map.putDouble("frameHeight", (double) realHeight);
return map; return map;
} }
})); }));
} }
public FabricEnabledViewGroup(@Nullable ReactContext context) { 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. * LICENSE file in the root directory of this source tree.
*/ */
package com.horcrux.svg; package com.horcrux.svg;
import android.graphics.Bitmap; import android.graphics.Bitmap;
@@ -19,7 +18,6 @@ import android.graphics.RadialGradient;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.Shader; import android.graphics.Shader;
import com.facebook.common.logging.FLog; import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants; import com.facebook.react.common.ReactConstants;
@@ -63,13 +61,14 @@ class Brush {
USER_SPACE_ON_USE 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++) { for (int i = 0; i < stopsCount; i++) {
int stopIndex = i * 2; int stopIndex = i * 2;
stops[i] = (float) value.getDouble(stopIndex); stops[i] = (float) value.getDouble(stopIndex);
int color = value.getInt(stopIndex + 1); int color = value.getInt(stopIndex + 1);
int alpha = color >>> 24; int alpha = color >>> 24;
int combined = Math.round((float)alpha * opacity); int combined = Math.round((float) alpha * opacity);
stopsColors[i] = combined << 24 | (color & 0x00ffffff); stopsColors[i] = combined << 24 | (color & 0x00ffffff);
} }
} }
@@ -102,8 +101,12 @@ class Brush {
} }
private double getVal(SVGLength length, double relative, float scale, float textSize) { private double getVal(SVGLength length, double relative, float scale, float textSize) {
return PropHelper.fromRelative(length, relative, 0, mUseObjectBoundingBox && return PropHelper.fromRelative(
length.unit == SVGLength.UnitType.NUMBER ? relative : scale, textSize); length,
relative,
0,
mUseObjectBoundingBox && length.unit == SVGLength.UnitType.NUMBER ? relative : scale,
textSize);
} }
void setupPaint(Paint paint, RectF pathBoundingBox, float scale, float opacity) { void setupPaint(Paint paint, RectF pathBoundingBox, float scale, float opacity) {
@@ -124,16 +127,14 @@ class Brush {
return; return;
} }
Bitmap bitmap = Bitmap.createBitmap( Bitmap bitmap = Bitmap.createBitmap((int) w, (int) h, Bitmap.Config.ARGB_8888);
(int) w,
(int) h,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap); Canvas canvas = new Canvas(bitmap);
RectF vbRect = mPattern.getViewBox(); RectF vbRect = mPattern.getViewBox();
if (vbRect != null && vbRect.width() > 0 && vbRect.height() > 0) { if (vbRect != null && vbRect.width() > 0 && vbRect.height() > 0) {
RectF eRect = new RectF((float) x, (float) y, (float) w, (float) h); 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); canvas.concat(mViewBoxMatrix);
} }
@@ -148,7 +149,8 @@ class Brush {
patternMatrix.preConcat(mMatrix); 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); bitmapShader.setLocalMatrix(patternMatrix);
paint.setShader(bitmapShader); paint.setShader(bitmapShader);
return; return;
@@ -170,8 +172,8 @@ class Brush {
// two stops at the same spot (see lib/extract/extractGradient.js). // two stops at the same spot (see lib/extract/extractGradient.js).
// Although it's mistake SVGs like this can be produced by vector // Although it's mistake SVGs like this can be produced by vector
// editors or other tools, so let's handle that gracefully. // editors or other tools, so let's handle that gracefully.
stopsColors = new int[] { stopsColors[0], stopsColors[0] }; stopsColors = new int[] {stopsColors[0], stopsColors[0]};
stops = new float[] { stops[0], stops[0] }; stops = new float[] {stops[0], stops[0]};
FLog.w(ReactConstants.TAG, "Gradient contains only one stop"); 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 x2 = getVal(mPoints[2], width, scale, textSize) + offsetX;
double y2 = getVal(mPoints[3], height, scale, textSize) + offsetY; double y2 = getVal(mPoints[3], height, scale, textSize) + offsetY;
Shader linearGradient = new LinearGradient( Shader linearGradient =
new LinearGradient(
(float) x1, (float) x1,
(float) y1, (float) y1,
(float) x2, (float) x2,
@@ -207,17 +210,12 @@ class Brush {
double cy = getVal(mPoints[5], height / ratio, scale, textSize) + offsetY / ratio; double cy = getVal(mPoints[5], height / ratio, scale, textSize) + offsetY / ratio;
// TODO: support focus point. // TODO: support focus point.
//double fx = PropHelper.fromRelative(mPoints[0], width, offsetX, scale); // double fx = PropHelper.fromRelative(mPoints[0], width, offsetX, scale);
//double fy = PropHelper.fromRelative(mPoints[1], height, offsetY, scale) / (ry / rx); // double fy = PropHelper.fromRelative(mPoints[1], height, offsetY, scale) / (ry / rx);
Shader radialGradient = new RadialGradient( Shader radialGradient =
(float) cx, new RadialGradient(
(float) cy, (float) cx, (float) cy, (float) rx, stopsColors, stops, Shader.TileMode.CLAMP);
(float) rx,
stopsColors,
stops,
Shader.TileMode.CLAMP
);
Matrix radialMatrix = new Matrix(); Matrix radialMatrix = new Matrix();
radialMatrix.preScale(1f, (float) ratio); radialMatrix.preScale(1f, (float) ratio);

View File

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

View File

@@ -6,13 +6,11 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.horcrux.svg; package com.horcrux.svg;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import com.facebook.common.logging.FLog; import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
import com.facebook.react.common.ReactConstants; import com.facebook.react.common.ReactConstants;
@@ -26,7 +24,9 @@ class ClipPathView extends GroupView {
@Override @Override
void draw(Canvas canvas, Paint paint, float opacity) { 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 @Override

View File

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

View File

@@ -6,14 +6,12 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.horcrux.svg; package com.horcrux.svg;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.view.View; import android.view.View;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
@SuppressLint("ViewConstructor") @SuppressLint("ViewConstructor")
@@ -30,7 +28,7 @@ class DefsView extends DefinitionView {
for (int i = 0; i < getChildCount(); i++) { for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i); View child = getChildAt(i);
if (child instanceof VirtualView) { 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. * LICENSE file in the root directory of this source tree.
*/ */
package com.horcrux.svg; package com.horcrux.svg;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@@ -14,7 +13,6 @@ import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.RectF; import android.graphics.RectF;
import com.facebook.react.bridge.Dynamic; import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;
@@ -81,7 +79,8 @@ class EllipseView extends RenderableView {
double cy = relativeOnHeight(mCy); double cy = relativeOnHeight(mCy);
double rx = relativeOnWidth(mRx); double rx = relativeOnWidth(mRx);
double ry = relativeOnHeight(mRy); 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); path.addOval(oval, Path.Direction.CW);
return path; return path;

View File

@@ -1,21 +1,22 @@
package com.horcrux.svg; 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_FAMILY;
import static com.facebook.react.uimanager.ViewProps.FONT_SIZE; 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_STYLE;
import static com.facebook.react.uimanager.ViewProps.FONT_WEIGHT; import static com.facebook.react.uimanager.ViewProps.FONT_WEIGHT;
import static com.horcrux.svg.TextProperties.*; import static com.horcrux.svg.TextProperties.*;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
class FontData { class FontData {
static class AbsoluteFontWeight { static class AbsoluteFontWeight {
static final int normal = 400; static final int normal = 400;
private static final FontWeight[] WEIGHTS = new FontWeight[]{ private static final FontWeight[] WEIGHTS =
new FontWeight[] {
FontWeight.w100, FontWeight.w100,
FontWeight.w100, FontWeight.w100,
FontWeight.w200, FontWeight.w200,
@@ -33,9 +34,8 @@ class FontData {
return WEIGHTS[Math.round(absoluteFontWeight / 100f)]; return WEIGHTS[Math.round(absoluteFontWeight / 100f)];
} }
private static final int[] absoluteFontWeights = new int[]{ private static final int[] absoluteFontWeights =
400, 700, 100, 200, 300, 400, 500, 600, 700, 800, 900 new int[] {400, 700, 100, 200, 300, 400, 500, 600, 700, 800, 900};
};
// https://drafts.csswg.org/css-fonts-4/#relative-weights // https://drafts.csswg.org/css-fonts-4/#relative-weights
static int from(FontWeight fontWeight, FontData parent) { static int from(FontWeight fontWeight, FontData parent) {
@@ -132,18 +132,14 @@ class FontData {
letterSpacing = DEFAULT_LETTER_SPACING; 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); ReadableType propType = font.getType(prop);
if (propType == ReadableType.Number) { if (propType == ReadableType.Number) {
return font.getDouble(prop); return font.getDouble(prop);
} else { } else {
String string = font.getString(prop); String string = font.getString(prop);
return PropHelper.fromRelative( return PropHelper.fromRelative(string, relative, scale, fontSize);
string,
relative,
scale,
fontSize
);
} }
} }
@@ -155,7 +151,7 @@ class FontData {
private void handleNumericWeight(FontData parent, double number) { private void handleNumericWeight(FontData parent, double number) {
long weight = Math.round(number); long weight = Math.round(number);
if (weight >= 1 && weight <= 1000) { if (weight >= 1 && weight <= 1000) {
absoluteFontWeight = (int)weight; absoluteFontWeight = (int) weight;
fontWeight = AbsoluteFontWeight.nearestFontWeight(absoluteFontWeight); fontWeight = AbsoluteFontWeight.nearestFontWeight(absoluteFontWeight);
} else { } else {
setInheritedWeight(parent); setInheritedWeight(parent);
@@ -193,13 +189,29 @@ class FontData {
fontData = font.hasKey(FONT_DATA) ? font.getMap(FONT_DATA) : parent.fontData; fontData = font.hasKey(FONT_DATA) ? font.getMap(FONT_DATA) : parent.fontData;
fontFamily = font.hasKey(FONT_FAMILY) ? font.getString(FONT_FAMILY) : parent.fontFamily; fontFamily = font.hasKey(FONT_FAMILY) ? font.getString(FONT_FAMILY) : parent.fontFamily;
fontStyle = font.hasKey(FONT_STYLE) ? FontStyle.valueOf(font.getString(FONT_STYLE)) : parent.fontStyle; fontStyle =
fontFeatureSettings = font.hasKey(FONT_FEATURE_SETTINGS) ? font.getString(FONT_FEATURE_SETTINGS) : parent.fontFeatureSettings; font.hasKey(FONT_STYLE) ? FontStyle.valueOf(font.getString(FONT_STYLE)) : parent.fontStyle;
fontVariationSettings = font.hasKey(FONT_VARIATION_SETTINGS) ? font.getString(FONT_VARIATION_SETTINGS) : parent.fontVariationSettings; fontFeatureSettings =
fontVariantLigatures = font.hasKey(FONT_VARIANT_LIGATURES) ? FontVariantLigatures.valueOf(font.getString(FONT_VARIANT_LIGATURES)) : parent.fontVariantLigatures; 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; textAnchor =
textDecoration = font.hasKey(TEXT_DECORATION) ? TextDecoration.getEnum(font.getString(TEXT_DECORATION)) : parent.textDecoration; 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); final boolean hasKerning = font.hasKey(KERNING);
manualKerning = hasKerning || parent.manualKerning; manualKerning = hasKerning || parent.manualKerning;
@@ -208,7 +220,13 @@ class FontData {
// https://drafts.csswg.org/css-text-3/#spacing // https://drafts.csswg.org/css-text-3/#spacing
// calculated values for units in: kerning, word-spacing, and, letter-spacing. // calculated values for units in: kerning, word-spacing, and, letter-spacing.
kerning = hasKerning ? toAbsolute(font, KERNING, scale, fontSize, 0) : parent.kerning; kerning = hasKerning ? toAbsolute(font, KERNING, scale, fontSize, 0) : parent.kerning;
wordSpacing = font.hasKey(WORD_SPACING) ? toAbsolute(font, WORD_SPACING, scale, fontSize, 0) : parent.wordSpacing; wordSpacing =
letterSpacing = font.hasKey(LETTER_SPACING) ? toAbsolute(font, LETTER_SPACING, scale, fontSize, 0) : parent.letterSpacing; 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. * LICENSE file in the root directory of this source tree.
*/ */
package com.horcrux.svg; package com.horcrux.svg;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@@ -15,9 +14,7 @@ import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.RectF; import android.graphics.RectF;
import android.view.View; import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.facebook.react.bridge.Dynamic; import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;
@@ -36,10 +33,10 @@ class ForeignObjectView extends GroupView {
@Override @Override
void draw(Canvas canvas, Paint paint, float opacity) { void draw(Canvas canvas, Paint paint, float opacity) {
float x = (float)relativeOnWidth(mX); float x = (float) relativeOnWidth(mX);
float y = (float)relativeOnHeight(mY); float y = (float) relativeOnHeight(mY);
float w = (float)relativeOnWidth(mW); float w = (float) relativeOnWidth(mW);
float h = (float)relativeOnHeight(mH); float h = (float) relativeOnHeight(mH);
canvas.translate(x, y); canvas.translate(x, y);
canvas.clipRect(0, 0, w, h); canvas.clipRect(0, 0, w, h);
super.draw(canvas, paint, opacity); super.draw(canvas, paint, opacity);
@@ -106,12 +103,12 @@ class ForeignObjectView extends GroupView {
continue; continue;
} }
if (child instanceof VirtualView) { if (child instanceof VirtualView) {
VirtualView node = ((VirtualView)child); VirtualView node = ((VirtualView) child);
if ("none".equals(node.mDisplay)) { if ("none".equals(node.mDisplay)) {
continue; continue;
} }
if (node instanceof RenderableView) { if (node instanceof RenderableView) {
((RenderableView)node).mergeProperties(self); ((RenderableView) node).mergeProperties(self);
} }
int count = node.saveAndSetupCanvas(canvas, mCTM); int count = node.saveAndSetupCanvas(canvas, mCTM);
@@ -124,14 +121,14 @@ class ForeignObjectView extends GroupView {
node.restoreCanvas(canvas, count); node.restoreCanvas(canvas, count);
if (node instanceof RenderableView) { if (node instanceof RenderableView) {
((RenderableView)node).resetProperties(); ((RenderableView) node).resetProperties();
} }
if (node.isResponsible()) { if (node.isResponsible()) {
svg.enableTouchEvents(); svg.enableTouchEvents();
} }
} else if (child instanceof SvgView) { } else if (child instanceof SvgView) {
SvgView svgView = (SvgView)child; SvgView svgView = (SvgView) child;
svgView.drawChildren(canvas); svgView.drawChildren(canvas);
if (svgView.isResponsible()) { if (svgView.isResponsible()) {
svg.enableTouchEvents(); svg.enableTouchEvents();

View File

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

View File

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

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.horcrux.svg; package com.horcrux.svg;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@@ -19,12 +18,9 @@ import android.graphics.RectF;
import android.graphics.Region; import android.graphics.Region;
import android.os.Build; import android.os.Build;
import android.view.View; import android.view.View;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.view.ReactViewGroup;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@SuppressLint("ViewConstructor") @SuppressLint("ViewConstructor")
@@ -58,8 +54,7 @@ class GroupView extends RenderableView {
} }
private static <T> T requireNonNull(T obj) { private static <T> T requireNonNull(T obj) {
if (obj == null) if (obj == null) throw new NullPointerException();
throw new NullPointerException();
return obj; return obj;
} }
@@ -92,12 +87,12 @@ class GroupView extends RenderableView {
continue; continue;
} }
if (child instanceof VirtualView) { if (child instanceof VirtualView) {
VirtualView node = ((VirtualView)child); VirtualView node = ((VirtualView) child);
if ("none".equals(node.mDisplay)) { if ("none".equals(node.mDisplay)) {
continue; continue;
} }
if (node instanceof RenderableView) { if (node instanceof RenderableView) {
((RenderableView)node).mergeProperties(self); ((RenderableView) node).mergeProperties(self);
} }
int count = node.saveAndSetupCanvas(canvas, mCTM); int count = node.saveAndSetupCanvas(canvas, mCTM);
@@ -110,14 +105,14 @@ class GroupView extends RenderableView {
node.restoreCanvas(canvas, count); node.restoreCanvas(canvas, count);
if (node instanceof RenderableView) { if (node instanceof RenderableView) {
((RenderableView)node).resetProperties(); ((RenderableView) node).resetProperties();
} }
if (node.isResponsible()) { if (node.isResponsible()) {
svg.enableTouchEvents(); svg.enableTouchEvents();
} }
} else if (child instanceof SvgView) { } else if (child instanceof SvgView) {
SvgView svgView = (SvgView)child; SvgView svgView = (SvgView) child;
svgView.drawChildren(canvas); svgView.drawChildren(canvas);
if (svgView.isResponsible()) { if (svgView.isResponsible()) {
svg.enableTouchEvents(); svg.enableTouchEvents();
@@ -145,7 +140,7 @@ class GroupView extends RenderableView {
continue; continue;
} }
if (node instanceof VirtualView) { if (node instanceof VirtualView) {
VirtualView n = (VirtualView)node; VirtualView n = (VirtualView) node;
Matrix transform = n.mMatrix; Matrix transform = n.mMatrix;
mPath.addPath(n.getPath(canvas, paint), transform); mPath.addPath(n.getPath(canvas, paint), transform);
} }
@@ -165,11 +160,11 @@ class GroupView extends RenderableView {
continue; continue;
} }
if (node instanceof VirtualView) { if (node instanceof VirtualView) {
VirtualView n = (VirtualView)node; VirtualView n = (VirtualView) node;
Matrix transform = n.mMatrix; Matrix transform = n.mMatrix;
Path p2; Path p2;
if (n instanceof GroupView) { if (n instanceof GroupView) {
p2 = ((GroupView)n).getPath(canvas, paint, op); p2 = ((GroupView) n).getPath(canvas, paint, op);
} else { } else {
p2 = n.getPath(canvas, paint); p2 = n.getPath(canvas, paint);
} }
@@ -187,11 +182,11 @@ class GroupView extends RenderableView {
continue; continue;
} }
if (node instanceof VirtualView) { if (node instanceof VirtualView) {
VirtualView n = (VirtualView)node; VirtualView n = (VirtualView) node;
Matrix transform = n.mMatrix; Matrix transform = n.mMatrix;
Path p2; Path p2;
if (n instanceof GroupView) { if (n instanceof GroupView) {
p2 = ((GroupView)n).getPath(canvas, paint, op); p2 = ((GroupView) n).getPath(canvas, paint, op);
} else { } else {
p2 = n.getPath(canvas, paint); p2 = n.getPath(canvas, paint);
} }
@@ -269,7 +264,7 @@ class GroupView extends RenderableView {
for (int i = 0; i < getChildCount(); i++) { for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i); View node = getChildAt(i);
if (node instanceof VirtualView) { 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++) { for (int i = 0; i < getChildCount(); i++) {
View node = getChildAt(i); View node = getChildAt(i);
if (node instanceof RenderableView) { 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. * LICENSE file in the root directory of this source tree.
*/ */
package com.horcrux.svg; package com.horcrux.svg;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@@ -17,7 +16,6 @@ import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.RectF; import android.graphics.RectF;
import android.net.Uri; import android.net.Uri;
import com.facebook.common.executors.UiThreadImmediateExecutorService; import com.facebook.common.executors.UiThreadImmediateExecutorService;
import com.facebook.common.logging.FLog; import com.facebook.common.logging.FLog;
import com.facebook.common.references.CloseableReference; 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.uimanager.annotations.ReactProp;
import com.facebook.react.views.imagehelper.ImageSource; import com.facebook.react.views.imagehelper.ImageSource;
import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper; import com.facebook.react.views.imagehelper.ResourceDrawableIdHelper;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -102,14 +98,13 @@ class ImageView extends RenderableView {
invalidate(); invalidate();
} }
@ReactProp(name = "src") @ReactProp(name = "src")
public void setSrc(@Nullable ReadableMap src) { public void setSrc(@Nullable ReadableMap src) {
if (src != null) { if (src != null) {
uriString = src.getString("uri"); uriString = src.getString("uri");
if (uriString == null || uriString.isEmpty()) { if (uriString == null || uriString.isEmpty()) {
//TODO: give warning about this // TODO: give warning about this
return; return;
} }
@@ -164,9 +159,10 @@ class ImageView extends RenderableView {
private void loadBitmap(final ImagePipeline imagePipeline, final ImageRequest request) { private void loadBitmap(final ImagePipeline imagePipeline, final ImageRequest request) {
mLoading.set(true); mLoading.set(true);
final DataSource<CloseableReference<CloseableImage>> dataSource final DataSource<CloseableReference<CloseableImage>> dataSource =
= imagePipeline.fetchDecodedImage(request, mContext); imagePipeline.fetchDecodedImage(request, mContext);
BaseBitmapDataSubscriber subscriber = new BaseBitmapDataSubscriber() { BaseBitmapDataSubscriber subscriber =
new BaseBitmapDataSubscriber() {
@Override @Override
public void onNewResultImpl(Bitmap bitmap) { public void onNewResultImpl(Bitmap bitmap) {
mLoading.set(false); mLoading.set(false);
@@ -181,7 +177,10 @@ class ImageView extends RenderableView {
// No cleanup required here. // No cleanup required here.
// TODO: more details about this failure // TODO: more details about this failure
mLoading.set(false); 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()); dataSource.subscribe(subscriber, UiThreadImmediateExecutorService.getInstance());
@@ -228,9 +227,14 @@ class ImageView extends RenderableView {
this.setClientRect(vbRect); this.setClientRect(vbRect);
} }
private void tryRenderFromBitmapCache(ImagePipeline imagePipeline, ImageRequest request, Canvas canvas, Paint paint, float opacity) { private void tryRenderFromBitmapCache(
final DataSource<CloseableReference<CloseableImage>> dataSource ImagePipeline imagePipeline,
= imagePipeline.fetchImageFromBitmapCache(request, mContext); ImageRequest request,
Canvas canvas,
Paint paint,
float opacity) {
final DataSource<CloseableReference<CloseableImage>> dataSource =
imagePipeline.fetchImageFromBitmapCache(request, mContext);
try { try {
final CloseableReference<CloseableImage> imageReference = dataSource.getResult(); final CloseableReference<CloseableImage> imageReference = dataSource.getResult();
@@ -265,5 +269,4 @@ class ImageView extends RenderableView {
dataSource.close(); dataSource.close();
} }
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.horcrux.svg; package com.horcrux.svg;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@@ -15,7 +14,6 @@ import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.RectF; import android.graphics.RectF;
import android.os.Build; import android.os.Build;
import com.facebook.react.bridge.Dynamic; import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp; import com.facebook.react.uimanager.annotations.ReactProp;
@@ -129,13 +127,25 @@ class RectView extends RenderableView {
ry = h / 2; ry = h / 2;
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 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 { } 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 { } else {
path.addRect((float) x, (float) y, (float) (x + w), (float) (y + h), Path.Direction.CW); 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; return path;
} }

View File

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

View File

@@ -6,77 +6,8 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.horcrux.svg; 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.determinant;
import static com.facebook.react.uimanager.MatrixMathHelper.inverse; import static com.facebook.react.uimanager.MatrixMathHelper.inverse;
import static com.facebook.react.uimanager.MatrixMathHelper.multiplyVectorByMatrix; 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.FILL_RULE_NONZERO;
import static com.horcrux.svg.RenderableView.JOIN_ROUND; import static com.horcrux.svg.RenderableView.JOIN_ROUND;
/** import android.graphics.Matrix;
* ViewManager for DefinitionView RNSVG views 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> { class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<VirtualView> {
protected final SVGClass svgClass; protected final SVGClass svgClass;
@@ -212,7 +206,6 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
PADDING_BOTTOM, PADDING_BOTTOM,
PADDING_START, PADDING_START,
PADDING_END, PADDING_END,
BORDER_WIDTH, BORDER_WIDTH,
BORDER_START_WIDTH, BORDER_START_WIDTH,
BORDER_END_WIDTH, BORDER_END_WIDTH,
@@ -220,8 +213,7 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
BORDER_BOTTOM_WIDTH, BORDER_BOTTOM_WIDTH,
BORDER_LEFT_WIDTH, BORDER_LEFT_WIDTH,
BORDER_RIGHT_WIDTH, BORDER_RIGHT_WIDTH,
} })
)
public void ignoreLayoutProps(int index, Dynamic value) {} 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])) { if (!isZero(matrix[0][3]) || !isZero(matrix[1][3]) || !isZero(matrix[2][3])) {
// rightHandSide is the right hand side of the equation. // rightHandSide is the right hand side of the equation.
// rightHandSide is a vector, or point in 3d space relative to the origin. // 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 // Solve the equation by inverting perspectiveMatrix and multiplying
// rightHandSide by the inverse. // rightHandSide by the inverse.
double[] inversePerspectiveMatrix = inverse( double[] inversePerspectiveMatrix = inverse(perspectiveMatrix);
perspectiveMatrix double[] transposedInversePerspectiveMatrix = transpose(inversePerspectiveMatrix);
);
double[] transposedInversePerspectiveMatrix = transpose(
inversePerspectiveMatrix
);
multiplyVectorByMatrix(rightHandSide, transposedInversePerspectiveMatrix, perspective); multiplyVectorByMatrix(rightHandSide, transposedInversePerspectiveMatrix, perspective);
} else { } else {
// no perspective // no perspective
@@ -365,7 +353,10 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
// Based on: http://nghiaho.com/?page_id=846 // Based on: http://nghiaho.com/?page_id=846
double conv = 180 / Math.PI; double conv = 180 / Math.PI;
rotationDegrees[0] = roundTo3Places(-Math.atan2(row[2][1], row[2][2]) * conv); 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); 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; double[] perspectiveArray = sMatrixDecompositionContext.perspective;
if (perspectiveArray.length > PERSPECTIVE_ARRAY_INVERTED_CAMERA_DISTANCE_INDEX) { 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) { if (invertedCameraDistance == 0) {
// Default camera distance, before scale multiplier (1280) // Default camera distance, before scale multiplier (1280)
invertedCameraDistance = 0.00078125f; invertedCameraDistance = 0.00078125f;
@@ -399,9 +391,9 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
// calculation, so squaring and a normalization value of // calculation, so squaring and a normalization value of
// sqrt(5) produces an exact replica with iOS. // sqrt(5) produces an exact replica with iOS.
// For more information, see https://github.com/facebook/react-native/pull/18302 // 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); view.setCameraDistance(normalizedCameraDistance);
} }
} }
@@ -487,7 +479,6 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
node.setDisplay(display); node.setDisplay(display);
} }
@ReactProp(name = "matrix") @ReactProp(name = "matrix")
public void setMatrix(V node, Dynamic matrixArray) { public void setMatrix(V node, Dynamic matrixArray) {
node.setMatrix(matrixArray); node.setMatrix(matrixArray);
@@ -515,18 +506,20 @@ class VirtualViewManager<V extends VirtualView> extends ViewGroupManager<Virtual
private void invalidateSvgView(V node) { private void invalidateSvgView(V node) {
SvgView view = node.getSvgView(); SvgView view = node.getSvgView();
if (view!= null) { if (view != null) {
view.invalidate(); view.invalidate();
} }
if (node instanceof TextView) { if (node instanceof TextView) {
((TextView)node).getTextContainer().clearChildCache(); ((TextView) node).getTextContainer().clearChildCache();
} }
} }
@Override @Override
protected void addEventEmitters(@Nonnull ThemedReactContext reactContext, @Nonnull VirtualView view) { protected void addEventEmitters(
@Nonnull ThemedReactContext reactContext, @Nonnull VirtualView view) {
super.addEventEmitters(reactContext, view); super.addEventEmitters(reactContext, view);
view.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() { view.setOnHierarchyChangeListener(
new ViewGroup.OnHierarchyChangeListener() {
@Override @Override
public void onChildViewAdded(View view, View view1) { public void onChildViewAdded(View view, View view1) {
if (view instanceof VirtualView) { 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 * 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 * (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 * you want to override this method you should call super.onAfterUpdateTransaction from it as the
* the parent class of the ViewManager may rely on callback being executed. * parent class of the ViewManager may rely on callback being executed.
*/ */
protected void onAfterUpdateTransaction(@Nonnull V node) { protected void onAfterUpdateTransaction(@Nonnull V node) {
super.onAfterUpdateTransaction(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<RenderableView> mTagToRenderableView = new SparseArray<>();
private static final SparseArray<Runnable> mTagToRunnable = 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); super.onDropViewInstance(view);
mTagToRenderableView.remove(view.getId()); mTagToRenderableView.remove(view.getId());
} }
} }
/** /** ViewManager for Renderable RNSVG views */
* ViewManager for Renderable RNSVG views
*/
class RenderableViewManager<T extends RenderableView> extends VirtualViewManager<T> { class RenderableViewManager<T extends RenderableView> extends VirtualViewManager<T> {
RenderableViewManager(SVGClass svgclass) { RenderableViewManager(SVGClass svgclass) {
super(svgclass); super(svgclass);
} }
static class GroupViewManagerAbstract<U extends GroupView> extends RenderableViewManager<U> { static class GroupViewManagerAbstract<U extends GroupView> extends RenderableViewManager<U> {
GroupViewManagerAbstract(SVGClass svgClass) { GroupViewManagerAbstract(SVGClass svgClass) {
super(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() { GroupViewManager() {
super(SVGClass.RNSVGGroup); super(SVGClass.RNSVGGroup);
mDelegate = new RNSVGGroupManagerDelegate(this); mDelegate = new RNSVGGroupManagerDelegate(this);
@@ -725,13 +716,13 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<GroupView> mDelegate; private final ViewManagerDelegate<GroupView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; return mDelegate;
} }
} }
static class PathViewManager extends RenderableViewManager<PathView> implements RNSVGPathManagerInterface<PathView> { static class PathViewManager extends RenderableViewManager<PathView>
implements RNSVGPathManagerInterface<PathView> {
PathViewManager() { PathViewManager() {
super(SVGClass.RNSVGPath); super(SVGClass.RNSVGPath);
mDelegate = new RNSVGPathManagerDelegate(this); mDelegate = new RNSVGPathManagerDelegate(this);
@@ -739,7 +730,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<PathView> mDelegate; private final ViewManagerDelegate<PathView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; 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() { TextViewManager() {
super(SVGClass.RNSVGText); super(SVGClass.RNSVGText);
mDelegate = new RNSVGTextManagerDelegate(this); mDelegate = new RNSVGTextManagerDelegate(this);
@@ -871,7 +863,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<TextView> mDelegate; private final ViewManagerDelegate<TextView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; return mDelegate;
} }
@@ -879,10 +871,10 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
super(svgClass); super(svgClass);
mDelegate = new RNSVGTextManagerDelegate(this); mDelegate = new RNSVGTextManagerDelegate(this);
} }
} }
static class TSpanViewManager extends TextViewManagerAbstract<TSpanView> implements RNSVGTSpanManagerInterface<TSpanView> { static class TSpanViewManager extends TextViewManagerAbstract<TSpanView>
implements RNSVGTSpanManagerInterface<TSpanView> {
TSpanViewManager() { TSpanViewManager() {
super(SVGClass.RNSVGTSpan); super(SVGClass.RNSVGTSpan);
mDelegate = new RNSVGTSpanManagerDelegate(this); mDelegate = new RNSVGTSpanManagerDelegate(this);
@@ -895,7 +887,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<TSpanView> mDelegate; private final ViewManagerDelegate<TSpanView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; return mDelegate;
} }
@@ -903,10 +895,10 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
public void setContent(TSpanView node, @Nullable String content) { public void setContent(TSpanView node, @Nullable String content) {
node.setContent(content); node.setContent(content);
} }
} }
static class TextPathViewManager extends TextViewManagerAbstract<TextPathView> implements RNSVGTextPathManagerInterface<TextPathView> { static class TextPathViewManager extends TextViewManagerAbstract<TextPathView>
implements RNSVGTextPathManagerInterface<TextPathView> {
TextPathViewManager() { TextPathViewManager() {
super(SVGClass.RNSVGTextPath); super(SVGClass.RNSVGTextPath);
mDelegate = new RNSVGTextPathManagerDelegate(this); mDelegate = new RNSVGTextPathManagerDelegate(this);
@@ -914,12 +906,12 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
TextPathViewManager(SVGClass svgClass) { TextPathViewManager(SVGClass svgClass) {
super(svgClass); super(svgClass);
mDelegate = new RNSVGTextPathManagerDelegate (this); mDelegate = new RNSVGTextPathManagerDelegate(this);
} }
private final ViewManagerDelegate<TextPathView> mDelegate; private final ViewManagerDelegate<TextPathView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; 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() { ImageViewManager() {
super(SVGClass.RNSVGImage); super(SVGClass.RNSVGImage);
mDelegate = new RNSVGImageManagerDelegate(this); mDelegate = new RNSVGImageManagerDelegate(this);
@@ -972,7 +965,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<ImageView> mDelegate; private final ViewManagerDelegate<ImageView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; return mDelegate;
} }
@@ -1031,7 +1024,6 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
node.setSrc(src); node.setSrc(src);
} }
@ReactProp(name = "align") @ReactProp(name = "align")
public void setAlign(ImageView node, String align) { public void setAlign(ImageView node, String align) {
node.setAlign(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() { CircleViewManager() {
super(SVGClass.RNSVGCircle); super(SVGClass.RNSVGCircle);
mDelegate = new RNSVGCircleManagerDelegate(this); mDelegate = new RNSVGCircleManagerDelegate(this);
@@ -1051,7 +1044,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<CircleView> mDelegate; private final ViewManagerDelegate<CircleView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; 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() { EllipseViewManager() {
super(SVGClass.RNSVGEllipse); super(SVGClass.RNSVGEllipse);
mDelegate = new RNSVGEllipseManagerDelegate(this); mDelegate = new RNSVGEllipseManagerDelegate(this);
@@ -1094,7 +1088,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<EllipseView> mDelegate; private final ViewManagerDelegate<EllipseView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; 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() { LineViewManager() {
super(SVGClass.RNSVGLine); super(SVGClass.RNSVGLine);
@@ -1148,7 +1143,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<LineView> mDelegate; private final ViewManagerDelegate<LineView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; 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() { RectViewManager() {
super(SVGClass.RNSVGRect); super(SVGClass.RNSVGRect);
@@ -1202,7 +1198,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<RectView> mDelegate; private final ViewManagerDelegate<RectView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; return mDelegate;
} }
@@ -1244,47 +1240,41 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
@Override @Override
public void setY(RectView view, @Nullable String value) { public void setY(RectView view, @Nullable String value) {
view.setY(value); view.setY(value);
} }
@Override @Override
public void setRectheight(RectView view, @Nullable String value) { public void setRectheight(RectView view, @Nullable String value) {
view.setHeight(value); view.setHeight(value);
} }
@Override @Override
public void setRectwidth(RectView view, @Nullable String value) { public void setRectwidth(RectView view, @Nullable String value) {
view.setWidth(value); view.setWidth(value);
} }
@Override @Override
public void setHeight(RectView view, @Nullable String value) { public void setHeight(RectView view, @Nullable String value) {
view.setHeight(value); view.setHeight(value);
} }
@Override @Override
public void setWidth(RectView view, @Nullable String value) { public void setWidth(RectView view, @Nullable String value) {
view.setWidth(value); view.setWidth(value);
} }
@Override @Override
public void setRx(RectView view, @Nullable String value) { public void setRx(RectView view, @Nullable String value) {
view.setRx(value); view.setRx(value);
} }
@Override @Override
public void setRy(RectView view, @Nullable String value) { public void setRy(RectView view, @Nullable String value) {
view.setRy(value); view.setRy(value);
} }
} }
static class ClipPathViewManager extends GroupViewManagerAbstract<ClipPathView> implements RNSVGClipPathManagerInterface<ClipPathView>{ static class ClipPathViewManager extends GroupViewManagerAbstract<ClipPathView>
implements RNSVGClipPathManagerInterface<ClipPathView> {
ClipPathViewManager() { ClipPathViewManager() {
super(SVGClass.RNSVGClipPath); super(SVGClass.RNSVGClipPath);
mDelegate = new RNSVGClipPathManagerDelegate(this); mDelegate = new RNSVGClipPathManagerDelegate(this);
@@ -1292,12 +1282,13 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<ClipPathView> mDelegate; private final ViewManagerDelegate<ClipPathView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; return mDelegate;
} }
} }
static class DefsViewManager extends VirtualViewManager<DefsView> implements RNSVGDefsManagerInterface<DefsView> { static class DefsViewManager extends VirtualViewManager<DefsView>
implements RNSVGDefsManagerInterface<DefsView> {
DefsViewManager() { DefsViewManager() {
super(SVGClass.RNSVGDefs); super(SVGClass.RNSVGDefs);
@@ -1306,12 +1297,13 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<DefsView> mDelegate; private final ViewManagerDelegate<DefsView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; return mDelegate;
} }
} }
static class UseViewManager extends RenderableViewManager<UseView> implements RNSVGUseManagerInterface<UseView> { static class UseViewManager extends RenderableViewManager<UseView>
implements RNSVGUseManagerInterface<UseView> {
UseViewManager() { UseViewManager() {
super(SVGClass.RNSVGUse); super(SVGClass.RNSVGUse);
@@ -1320,7 +1312,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<UseView> mDelegate; private final ViewManagerDelegate<UseView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; 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() { SymbolManager() {
super(SVGClass.RNSVGSymbol); super(SVGClass.RNSVGSymbol);
mDelegate = new RNSVGSymbolManagerDelegate(this); mDelegate = new RNSVGSymbolManagerDelegate(this);
@@ -1388,7 +1381,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<SymbolView> mDelegate; private final ViewManagerDelegate<SymbolView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; 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() { PatternManager() {
super(SVGClass.RNSVGPattern); super(SVGClass.RNSVGPattern);
mDelegate = new RNSVGPatternManagerDelegate(this); mDelegate = new RNSVGPatternManagerDelegate(this);
@@ -1431,7 +1425,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<PatternView> mDelegate; private final ViewManagerDelegate<PatternView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; 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() { MaskManager() {
super(SVGClass.RNSVGMask); super(SVGClass.RNSVGMask);
mDelegate = new RNSVGMaskManagerDelegate(this); mDelegate = new RNSVGMaskManagerDelegate(this);
@@ -1539,7 +1534,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<MaskView> mDelegate; private final ViewManagerDelegate<MaskView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; 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() { ForeignObjectManager() {
super(SVGClass.RNSVGForeignObject); super(SVGClass.RNSVGForeignObject);
mDelegate = new RNSVGForeignObjectManagerDelegate(this); mDelegate = new RNSVGForeignObjectManagerDelegate(this);
@@ -1617,9 +1613,10 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<ForeignObjectView> mDelegate; private final ViewManagerDelegate<ForeignObjectView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; return mDelegate;
} }
@ReactProp(name = "x") @ReactProp(name = "x")
public void setX(ForeignObjectView node, Dynamic x) { public void setX(ForeignObjectView node, Dynamic x) {
node.setX(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() { MarkerManager() {
super(SVGClass.RNSVGMarker); super(SVGClass.RNSVGMarker);
mDelegate = new RNSVGMarkerManagerDelegate(this); mDelegate = new RNSVGMarkerManagerDelegate(this);
@@ -1679,7 +1677,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<MarkerView> mDelegate; private final ViewManagerDelegate<MarkerView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; 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() { LinearGradientManager() {
super(SVGClass.RNSVGLinearGradient); super(SVGClass.RNSVGLinearGradient);
@@ -1773,11 +1772,10 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<RectView> mDelegate; private final ViewManagerDelegate<RectView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; return mDelegate;
} }
@ReactProp(name = "x1") @ReactProp(name = "x1")
public void setX1(LinearGradientView node, Dynamic x1) { public void setX1(LinearGradientView node, Dynamic x1) {
node.setX1(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() { RadialGradientManager() {
super(SVGClass.RNSVGRadialGradient); super(SVGClass.RNSVGRadialGradient);
@@ -1843,7 +1842,7 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
private final ViewManagerDelegate<RectView> mDelegate; private final ViewManagerDelegate<RectView> mDelegate;
protected ViewManagerDelegate getDelegate(){ protected ViewManagerDelegate getDelegate() {
return mDelegate; return mDelegate;
} }
@@ -1942,7 +1941,6 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
node.setFillRule(fillRule); node.setFillRule(fillRule);
} }
@ReactProp(name = "stroke") @ReactProp(name = "stroke")
public void setStroke(T node, @Nullable Dynamic strokeColors) { public void setStroke(T node, @Nullable Dynamic strokeColors) {
node.setStroke(strokeColors); node.setStroke(strokeColors);
@@ -2000,5 +1998,4 @@ class RenderableViewManager<T extends RenderableView> extends VirtualViewManager
public void setPropList(T node, @Nullable ReadableArray propList) { public void setPropList(T node, @Nullable ReadableArray propList) {
node.setPropList(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.Dynamic;
import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableArray;
import java.util.ArrayList; import java.util.ArrayList;
class SVGLength { class SVGLength {
@@ -121,12 +120,14 @@ class SVGLength {
static ArrayList<SVGLength> arrayFrom(Dynamic dynamic) { static ArrayList<SVGLength> arrayFrom(Dynamic dynamic) {
switch (dynamic.getType()) { switch (dynamic.getType()) {
case Number: { case Number:
{
ArrayList<SVGLength> list = new ArrayList<>(1); ArrayList<SVGLength> list = new ArrayList<>(1);
list.add(new SVGLength(dynamic.asDouble())); list.add(new SVGLength(dynamic.asDouble()));
return list; return list;
} }
case Array: { case Array:
{
ReadableArray arr = dynamic.asArray(); ReadableArray arr = dynamic.asArray();
int size = arr.size(); int size = arr.size();
ArrayList<SVGLength> list = new ArrayList<>(size); ArrayList<SVGLength> list = new ArrayList<>(size);
@@ -136,7 +137,8 @@ class SVGLength {
} }
return list; return list;
} }
case String: { case String:
{
ArrayList<SVGLength> list = new ArrayList<>(1); ArrayList<SVGLength> list = new ArrayList<>(1);
list.add(new SVGLength(dynamic.asString())); list.add(new SVGLength(dynamic.asString()));
return list; return list;

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package com.horcrux.svg; package com.horcrux.svg;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
@@ -14,7 +13,6 @@ import android.graphics.Canvas;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.RectF; import android.graphics.RectF;
import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp; 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) { void drawSymbol(Canvas canvas, Paint paint, float opacity, float width, float height) {
if (mAlign != null) { 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); RectF eRect = new RectF(0, 0, width, height);
Matrix viewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mAlign, mMeetOrSlice); Matrix viewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mAlign, mMeetOrSlice);
canvas.concat(viewBoxMatrix); canvas.concat(viewBoxMatrix);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -19,6 +19,9 @@
@property (nonatomic, strong) NSString *align; @property (nonatomic, strong) NSString *align;
@property (nonatomic, assign) RNSVGVBMOS meetOrSlice; @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 @end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -9,9 +9,9 @@
#ifdef RN_FABRIC_ENABLED #ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h> #import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h> #import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h" #import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED #endif // RN_FABRIC_ENABLED
@@ -55,7 +55,13 @@ using namespace facebook::react;
} }
self.gradientUnits = newProps.gradientUnits == 0 ? kRNSVGUnitsObjectBoundingBox : kRNSVGUnitsUserSpaceOnUse; self.gradientUnits = newProps.gradientUnits == 0 ? kRNSVGUnitsObjectBoundingBox : kRNSVGUnitsUserSpaceOnUse;
if (newProps.gradientTransform.size() == 6) { 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); setCommonNodeProps(newProps, self);
@@ -177,7 +183,7 @@ using namespace facebook::react;
- (void)parseReference - (void)parseReference
{ {
self.dirty = false; 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]; RNSVGPainter *painter = [[RNSVGPainter alloc] initWithPointsArray:points];
[painter setUnits:self.gradientUnits]; [painter setUnits:self.gradientUnits];
[painter setTransform:self.gradientTransform]; [painter setTransform:self.gradientTransform];

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,18 +6,17 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#import <React/RCTPointerEvents.h>
#import "RNSVGRenderable.h" #import "RNSVGRenderable.h"
#import "RNSVGClipPath.h" #import <React/RCTPointerEvents.h>
#import "RNSVGMask.h"
#import "RNSVGViewBox.h"
#import "RNSVGVectorEffect.h"
#import "RNSVGBezierElement.h" #import "RNSVGBezierElement.h"
#import "RNSVGClipPath.h"
#import "RNSVGMarker.h" #import "RNSVGMarker.h"
#import "RNSVGMarkerPosition.h" #import "RNSVGMarkerPosition.h"
#import "RNSVGMask.h"
#import "RNSVGVectorEffect.h"
#import "RNSVGViewBox.h"
@implementation RNSVGRenderable @implementation RNSVGRenderable {
{
NSMutableDictionary *_originProperties; NSMutableDictionary *_originProperties;
NSArray<NSString *> *_lastMergedList; NSArray<NSString *> *_lastMergedList;
NSArray<NSString *> *_attributeList; NSArray<NSString *> *_attributeList;
@@ -26,9 +25,15 @@
CGPathRef _srcHitPath; CGPathRef _srcHitPath;
} }
static RNSVGRenderable * _contextElement; static RNSVGRenderable *_contextElement;
+ (RNSVGRenderable *)contextElement { return _contextElement; } + (RNSVGRenderable *)contextElement
+ (void)setContextElement:(RNSVGRenderable *)contextElement { _contextElement = contextElement; } {
return _contextElement;
}
+ (void)setContextElement:(RNSVGRenderable *)contextElement
{
_contextElement = contextElement;
}
- (id)init - (id)init
{ {
@@ -97,7 +102,7 @@ static RNSVGRenderable * _contextElement;
_strokeOpacity = strokeOpacity; _strokeOpacity = strokeOpacity;
} }
- (void)setStrokeWidth:(RNSVGLength*)strokeWidth - (void)setStrokeWidth:(RNSVGLength *)strokeWidth
{ {
if ([strokeWidth isEqualTo:_strokeWidth]) { if ([strokeWidth isEqualTo:_strokeWidth]) {
return; return;
@@ -217,7 +222,8 @@ static RNSVGRenderable * _contextElement;
} }
#endif // RN_FABRIC_ENABLED #endif // RN_FABRIC_ENABLED
UInt32 saturate(CGFloat value) { UInt32 saturate(CGFloat value)
{
return value <= 0 ? 0 : value >= 255 ? 255 : (UInt32)value; return value <= 0 ? 0 : value >= 255 ? 255 : (UInt32)value;
} }
@@ -234,7 +240,7 @@ UInt32 saturate(CGFloat value) {
if (self.mask) { if (self.mask) {
// https://www.w3.org/TR/SVG11/masking.html#MaskElement // 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); CGRect bounds = CGContextGetClipBoundingBox(context);
CGSize boundsSize = bounds.size; CGSize boundsSize = bounds.size;
CGFloat height = boundsSize.height; CGFloat height = boundsSize.height;
@@ -257,26 +263,29 @@ UInt32 saturate(CGFloat value) {
NSUInteger bitsPerComponent = 8; NSUInteger bitsPerComponent = 8;
NSUInteger bytesPerRow = bytesPerPixel * scaledWidth; NSUInteger bytesPerRow = bytesPerPixel * scaledWidth;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UInt32 * pixels = (UInt32 *) calloc(npixels, sizeof(UInt32)); UInt32 *pixels = (UInt32 *)calloc(npixels, sizeof(UInt32));
CGContextRef bcontext = CGBitmapContextCreate(pixels, scaledWidth, scaledHeight, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); CGContextRef bcontext = CGBitmapContextCreate(
pixels,
scaledWidth,
scaledHeight,
bitsPerComponent,
bytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextScaleCTM(bcontext, iscale, iscale); CGContextScaleCTM(bcontext, iscale, iscale);
// Clip to mask bounds and render the mask // Clip to mask bounds and render the mask
CGFloat x = [self relativeOn:[_maskNode x] CGFloat x = [self relativeOn:[_maskNode x] relative:width];
relative:width]; CGFloat y = [self relativeOn:[_maskNode y] relative:height];
CGFloat y = [self relativeOn:[_maskNode y] CGFloat w = [self relativeOn:[_maskNode maskwidth] relative:width];
relative:height]; CGFloat h = [self relativeOn:[_maskNode maskheight] 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); CGRect maskBounds = CGRectMake(x, y, w, h);
CGContextClipToRect(bcontext, maskBounds); CGContextClipToRect(bcontext, maskBounds);
[_maskNode renderLayerTo:bcontext rect:rect]; [_maskNode renderLayerTo:bcontext rect:rect];
// Apply luminanceToAlpha filter primitive // Apply luminanceToAlpha filter primitive
// https://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement // https://www.w3.org/TR/SVG11/filters.html#feColorMatrixElement
UInt32 * currentPixel = pixels; UInt32 *currentPixel = pixels;
for (NSUInteger i = 0; i < npixels; i++) { for (NSUInteger i = 0; i < npixels; i++) {
UInt32 color = *currentPixel; UInt32 color = *currentPixel;
@@ -334,7 +343,8 @@ UInt32 saturate(CGFloat value) {
[self renderMarkers:context path:self.path rect:&rect]; [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) { if (strokeDasharray != _sourceStrokeDashArray) {
CGFloat *dash = _strokeDashArrayData; CGFloat *dash = _strokeDashArrayData;
_strokeDashArrayData = (CGFloat *)realloc(dash, sizeof(CGFloat) * count); _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 { - (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 *markerStart = (RNSVGMarker *)[self.svgView getDefinedMarker:self.markerStart];
RNSVGMarker *markerEnd = (RNSVGMarker*)[self.svgView getDefinedMarker:self.markerEnd]; RNSVGMarker *markerMid = (RNSVGMarker *)[self.svgView getDefinedMarker:self.markerMid];
RNSVGMarker *markerEnd = (RNSVGMarker *)[self.svgView getDefinedMarker:self.markerEnd];
if (markerStart || markerMid || markerEnd) { if (markerStart || markerMid || markerEnd) {
_contextElement = self; _contextElement = self;
NSArray<RNSVGMarkerPosition*>* positions = [RNSVGMarkerPosition fromCGPath:path]; NSArray<RNSVGMarkerPosition *> *positions = [RNSVGMarkerPosition fromCGPath:path];
CGFloat width = self.strokeWidth ? [self relativeOnOther:self.strokeWidth] : 1; CGFloat width = self.strokeWidth ? [self relativeOnOther:self.strokeWidth] : 1;
__block CGRect bounds = CGRectNull; __block CGRect bounds = CGRectNull;
CGMutablePathRef markerPath = CGPathCreateMutable(); CGMutablePathRef markerPath = CGPathCreateMutable();
for (RNSVGMarkerPosition* position in positions) { for (RNSVGMarkerPosition *position in positions) {
RNSVGMarkerType type = [position type]; RNSVGMarkerType type = [position type];
RNSVGMarker *marker; RNSVGMarker *marker;
switch (type) { switch (type) {
@@ -467,8 +478,7 @@ UInt32 saturate(CGFloat value) {
[self.fill paint:context [self.fill paint:context
opacity:self.fillOpacity opacity:self.fillOpacity
painter:[self.svgView getDefinedPainter:self.fill.brushRef] painter:[self.svgView getDefinedPainter:self.fill.brushRef]
bounds:pathBounds bounds:pathBounds];
];
CGContextRestoreGState(context); CGContextRestoreGState(context);
if (!self.stroke) { if (!self.stroke) {
@@ -482,7 +492,7 @@ UInt32 saturate(CGFloat value) {
CGContextSetLineWidth(context, width); CGContextSetLineWidth(context, width);
CGContextSetLineCap(context, self.strokeLinecap); CGContextSetLineCap(context, self.strokeLinecap);
CGContextSetLineJoin(context, self.strokeLinejoin); CGContextSetLineJoin(context, self.strokeLinejoin);
NSArray<RNSVGLength *>* strokeDasharray = self.strokeDasharray; NSArray<RNSVGLength *> *strokeDasharray = self.strokeDasharray;
NSUInteger count = strokeDasharray.count; NSUInteger count = strokeDasharray.count;
if (count) { if (count) {
@@ -501,7 +511,7 @@ UInt32 saturate(CGFloat value) {
BOOL strokeColor; BOOL strokeColor;
if (self.stroke.class == RNSVGBrush.class) { if (self.stroke.class == RNSVGBrush.class) {
CGContextSetStrokeColorWithColor(context,[self.tintColor CGColor]); CGContextSetStrokeColorWithColor(context, [self.tintColor CGColor]);
strokeColor = YES; strokeColor = YES;
} else { } else {
strokeColor = [self.stroke applyStrokeColor:context opacity:self.strokeOpacity]; strokeColor = [self.stroke applyStrokeColor:context opacity:self.strokeOpacity];
@@ -524,8 +534,7 @@ UInt32 saturate(CGFloat value) {
[self.stroke paint:context [self.stroke paint:context
opacity:self.strokeOpacity opacity:self.strokeOpacity
painter:[self.svgView getDefinedPainter:self.stroke.brushRef] painter:[self.svgView getDefinedPainter:self.stroke.brushRef]
bounds:pathBounds bounds:pathBounds];
];
return; return;
} }
} }
@@ -547,9 +556,11 @@ UInt32 saturate(CGFloat value) {
if (self.stroke && self.strokeWidth) { if (self.stroke && self.strokeWidth) {
// Add stroke to hitArea // Add stroke to hitArea
CGFloat width = [self relativeOnOther:self.strokeWidth]; 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 // 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]); BOOL canReceiveTouchEvents = (self.pointerEvents != RCTPointerEventsNone && ![self isHidden]);
if(!canReceiveTouchEvents) { if (!canReceiveTouchEvents) {
return nil; return nil;
} }
@@ -580,8 +591,7 @@ UInt32 saturate(CGFloat value) {
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix); CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
transformed = CGPointApplyAffineTransform(transformed, self.invTransform); transformed = CGPointApplyAffineTransform(transformed, self.invTransform);
if (!CGRectContainsPoint(self.pathBounds, transformed) && if (!CGRectContainsPoint(self.pathBounds, transformed) && !CGRectContainsPoint(self.markerBounds, transformed)) {
!CGRectContainsPoint(self.markerBounds, transformed)) {
return nil; return nil;
} }
@@ -593,14 +603,14 @@ UInt32 saturate(CGFloat value) {
} }
if (self.clipPath) { if (self.clipPath) {
RNSVGClipPath *clipNode = (RNSVGClipPath*)[self.svgView getDefinedClipPath:self.clipPath]; RNSVGClipPath *clipNode = (RNSVGClipPath *)[self.svgView getDefinedClipPath:self.clipPath];
if ([clipNode isSimpleClipPath]) { if ([clipNode isSimpleClipPath]) {
CGPathRef clipPath = [self getClipPath]; CGPathRef clipPath = [self getClipPath];
if (clipPath && !CGPathContainsPoint(clipPath, nil, transformed, clipNode.clipRule == kRNSVGCGFCRuleEvenodd)) { if (clipPath && !CGPathContainsPoint(clipPath, nil, transformed, clipNode.clipRule == kRNSVGCGFCRuleEvenodd)) {
return nil; return nil;
} }
} else { } else {
RNSVGRenderable *clipGroup = (RNSVGRenderable*)clipNode; RNSVGRenderable *clipGroup = (RNSVGRenderable *)clipNode;
if (![clipGroup hitTest:transformed withEvent:event]) { if (![clipGroup hitTest:transformed withEvent:event]) {
return nil; return nil;
} }
@@ -624,7 +634,7 @@ UInt32 saturate(CGFloat value) {
} }
self.merging = true; 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]; _originProperties = [[NSMutableDictionary alloc] init];
for (NSString *key in targetAttributeList) { 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. // Most (if not all) of this file could probably go away once react-native-macos's version of RCTUIKit.h makes its way
// https://github.com/microsoft/react-native-macos/issues/242 // upstream. https://github.com/microsoft/react-native-macos/issues/242
#if !TARGET_OS_OSX #if !TARGET_OS_OSX
@@ -12,9 +12,9 @@
#else // TARGET_OS_OSX [ #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" // Due to name mangling, calling c-style functions from .mm files will fail, therefore we need to wrap them with extern
// so they are handled correctly. We also need to have imports positioned in a correct way, // "C" so they are handled correctly. We also need to have imports positioned in a correct way, so that this extern "C"
// so that this extern "C" wrapper is used before the functions from RCTUIKit are used. // wrapper is used before the functions from RCTUIKit are used.
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@@ -37,7 +37,8 @@ extern "C" {
@end @end
// TODO: These could probably be a part of react-native-macos // 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) @interface NSImage (RNSVGMacOSExtensions)
@property (readonly) CGImageRef CGImage; @property (readonly) CGImageRef CGImage;
@end @end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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