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

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

91
.clang-format Normal file
View File

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

View File

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

4
.husky/pre-commit Executable file
View File

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

View File

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

View File

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

View File

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

Binary file not shown.

View File

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

240
android/gradlew vendored Executable file
View File

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

91
android/gradlew.bat vendored Normal file
View File

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

9
android/spotless.gradle Normal file
View File

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

View File

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

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.graphics.Bitmap;
@@ -19,7 +18,6 @@ import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
@@ -63,7 +61,8 @@ class Brush {
USER_SPACE_ON_USE
}
private static void parseGradientStops(ReadableArray value, int stopsCount, float[] stops, int[] stopsColors, float opacity) {
private static void parseGradientStops(
ReadableArray value, int stopsCount, float[] stops, int[] stopsColors, float opacity) {
for (int i = 0; i < stopsCount; i++) {
int stopIndex = i * 2;
stops[i] = (float) value.getDouble(stopIndex);
@@ -102,8 +101,12 @@ class Brush {
}
private double getVal(SVGLength length, double relative, float scale, float textSize) {
return PropHelper.fromRelative(length, relative, 0, mUseObjectBoundingBox &&
length.unit == SVGLength.UnitType.NUMBER ? relative : scale, textSize);
return PropHelper.fromRelative(
length,
relative,
0,
mUseObjectBoundingBox && length.unit == SVGLength.UnitType.NUMBER ? relative : scale,
textSize);
}
void setupPaint(Paint paint, RectF pathBoundingBox, float scale, float opacity) {
@@ -124,16 +127,14 @@ class Brush {
return;
}
Bitmap bitmap = Bitmap.createBitmap(
(int) w,
(int) h,
Bitmap.Config.ARGB_8888);
Bitmap bitmap = Bitmap.createBitmap((int) w, (int) h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
RectF vbRect = mPattern.getViewBox();
if (vbRect != null && vbRect.width() > 0 && vbRect.height() > 0) {
RectF eRect = new RectF((float) x, (float) y, (float) w, (float) h);
Matrix mViewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mPattern.mAlign, mPattern.mMeetOrSlice);
Matrix mViewBoxMatrix =
ViewBox.getTransform(vbRect, eRect, mPattern.mAlign, mPattern.mMeetOrSlice);
canvas.concat(mViewBoxMatrix);
}
@@ -148,7 +149,8 @@ class Brush {
patternMatrix.preConcat(mMatrix);
}
BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
BitmapShader bitmapShader =
new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
bitmapShader.setLocalMatrix(patternMatrix);
paint.setShader(bitmapShader);
return;
@@ -181,7 +183,8 @@ class Brush {
double x2 = getVal(mPoints[2], width, scale, textSize) + offsetX;
double y2 = getVal(mPoints[3], height, scale, textSize) + offsetY;
Shader linearGradient = new LinearGradient(
Shader linearGradient =
new LinearGradient(
(float) x1,
(float) y1,
(float) x2,
@@ -210,14 +213,9 @@ class Brush {
// double fx = PropHelper.fromRelative(mPoints[0], width, offsetX, scale);
// double fy = PropHelper.fromRelative(mPoints[1], height, offsetY, scale) / (ry / rx);
Shader radialGradient = new RadialGradient(
(float) cx,
(float) cy,
(float) rx,
stopsColors,
stops,
Shader.TileMode.CLAMP
);
Shader radialGradient =
new RadialGradient(
(float) cx, (float) cy, (float) rx, stopsColors, stops, Shader.TileMode.CLAMP);
Matrix radialMatrix = new Matrix();
radialMatrix.preScale(1f, (float) ratio);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -15,9 +14,7 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;
import androidx.annotation.NonNull;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;

View File

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

View File

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

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -19,12 +18,9 @@ import android.graphics.RectF;
import android.graphics.Region;
import android.os.Build;
import android.view.View;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.view.ReactViewGroup;
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
@@ -58,8 +54,7 @@ class GroupView extends RenderableView {
}
private static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
if (obj == null) throw new NullPointerException();
return obj;
}

View File

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

View File

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

View File

@@ -6,19 +6,16 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Matrix;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.annotations.ReactProp;
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
@@ -31,7 +28,8 @@ class LinearGradientView extends DefinitionView {
private ReadableArray mGradient;
private Brush.BrushUnits mGradientUnits;
private static final float[] sRawMatrix = new float[]{
private static final float[] sRawMatrix =
new float[] {
1, 0, 0,
0, 1, 0,
0, 0, 1

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -15,7 +14,6 @@ import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
@@ -149,7 +147,8 @@ class MarkerView extends GroupView {
}
}
void renderMarker(Canvas canvas, Paint paint, float opacity, RNSVGMarkerPosition position, float strokeWidth) {
void renderMarker(
Canvas canvas, Paint paint, float opacity, RNSVGMarkerPosition position, float strokeWidth) {
int count = saveAndSetupCanvas(canvas, mCTM);
markerTransform.reset();
@@ -169,7 +168,12 @@ class MarkerView extends GroupView {
double height = relativeOnHeight(mMarkerHeight) / mScale;
RectF eRect = new RectF(0, 0, (float) width, (float) height);
if (mAlign != null) {
RectF vbRect = new RectF(mMinX * mScale, mMinY * mScale, (mMinX + mVbWidth) * mScale, (mMinY + mVbHeight) * mScale);
RectF vbRect =
new RectF(
mMinX * mScale,
mMinY * mScale,
(mMinX + mVbWidth) * mScale,
(mMinY + mVbHeight) * mScale);
Matrix viewBoxMatrix = ViewBox.getTransform(vbRect, eRect, mAlign, mMeetOrSlice);
float[] values = new float[9];
viewBoxMatrix.getValues(values);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,16 +6,16 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import static com.facebook.react.common.StandardCharsets.UTF_8;
import android.content.res.Resources;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.graphics.Region;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
@@ -23,15 +23,11 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.annotation.Nonnull;
import static com.facebook.react.common.StandardCharsets.UTF_8;
class RNSVGRenderableManager extends ReactContextBaseJavaModule {
RNSVGRenderableManager(ReactApplicationContext reactContext) {
super(reactContext);

View File

@@ -6,19 +6,16 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
import android.graphics.Matrix;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.annotations.ReactProp;
import javax.annotation.Nullable;
@SuppressLint("ViewConstructor")
@@ -32,7 +29,8 @@ class RadialGradientView extends DefinitionView {
private ReadableArray mGradient;
private Brush.BrushUnits mGradientUnits;
private static final float[] sRawMatrix = new float[]{
private static final float[] sRawMatrix =
new float[] {
1, 0, 0,
0, 1, 0,
0, 0, 1

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,17 +2,16 @@ package com.horcrux.svg;
// TODO implement https://www.w3.org/TR/SVG2/text.html#TextLayoutAlgorithm
import static com.horcrux.svg.TextProperties.Direction;
import static com.horcrux.svg.TextProperties.TextAnchor;
import static com.horcrux.svg.TextProperties.TextPathSide;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.PointF;
import android.view.View;
import java.util.ArrayList;
import static com.horcrux.svg.TextProperties.Direction;
import static com.horcrux.svg.TextProperties.TextAnchor;
import static com.horcrux.svg.TextProperties.TextPathSide;
@SuppressWarnings("ALL")
class TextLayoutAlgorithm {
class CharacterInformation {
@@ -49,14 +48,14 @@ class TextLayoutAlgorithm {
ArrayList<TextView> subtree,
StringBuilder line,
View node,
TextPathView textPath
) {
TextPathView textPath) {
if (node instanceof TSpanView) {
final TSpanView tSpanView = (TSpanView) node;
String content = tSpanView.mContent;
if (content == null) {
for (int i = 0; i < tSpanView.getChildCount(); i++) {
getSubTreeTypographicCharacterPositions(inTextPath, subtree, line, tSpanView.getChildAt(i), textPath);
getSubTreeTypographicCharacterPositions(
inTextPath, subtree, line, tSpanView.getChildAt(i), textPath);
}
} else {
for (int i = 0; i < content.length(); i++) {
@@ -68,7 +67,8 @@ class TextLayoutAlgorithm {
} else {
textPath = node instanceof TextPathView ? (TextPathView) node : textPath;
for (int i = 0; i < textPath.getChildCount(); i++) {
getSubTreeTypographicCharacterPositions(inTextPath, subtree, line, textPath.getChildAt(i), textPath);
getSubTreeTypographicCharacterPositions(
inTextPath, subtree, line, textPath.getChildAt(i), textPath);
}
}
}
@@ -265,8 +265,7 @@ class TextLayoutAlgorithm {
String[] resolve_x,
String[] resolve_y,
String[] resolve_dx,
String[] resolve_dy
) {
String[] resolve_dy) {
this.result = result;
this.resolve_x = resolve_x;
this.resolve_y = resolve_y;
@@ -499,13 +498,8 @@ class TextLayoutAlgorithm {
}
}
CharacterPositioningResolver resolver = new CharacterPositioningResolver(
result,
resolve_x,
resolve_y,
resolve_dx,
resolve_dy
);
CharacterPositioningResolver resolver =
new CharacterPositioningResolver(result, resolve_x, resolve_y, resolve_dx, resolve_dy);
/*
Adjust positions: dx, dy
@@ -581,10 +575,7 @@ class TextLayoutAlgorithm {
*/
final Class<? extends TextView> nodeClass = node.getClass();
final boolean validTextLength = node.mTextLength != null;
if (
(nodeClass == TSpanView.class)
&& validTextLength
) {
if ((nodeClass == TSpanView.class) && validTextLength) {
/*
Let a = +∞ and b = −∞.
*/
@@ -738,7 +729,8 @@ class TextLayoutAlgorithm {
character then shift = shift
+ δ.
*/
if (!result[k].middle && (!result[k].resolved || result[k].firstCharacterInResolvedDescendant)) {
if (!result[k].middle
&& (!result[k].resolved || result[k].firstCharacterInResolvedDescendant)) {
shift += perCharacterAdjustment;
}
}
@@ -906,7 +898,8 @@ class TextLayoutAlgorithm {
(middle, ltr) or (middle, rtl)
Set shift = shift (a + b) / 2.
*/
if ((k > 0 && result[k].anchoredChunk && prevA != Double.POSITIVE_INFINITY) || k == count - 1) {
if ((k > 0 && result[k].anchoredChunk && prevA != Double.POSITIVE_INFINITY)
|| k == count - 1) {
TextAnchor anchor = TextAnchor.start;
Direction direction = Direction.ltr;
@@ -1012,9 +1005,8 @@ class TextLayoutAlgorithm {
TODO reverse path.
*/
Path path = textPath;
if (textPathView.getSide() == TextPathSide.right) {
if (textPathView.getSide() == TextPathSide.right) {}
}
/*
Let length be the length
of path.
@@ -1237,7 +1229,6 @@ class TextLayoutAlgorithm {
result[index].y = result[index - 1].y;
result[index].rotate = result[index - 1].rotate;
}
}
/*
If the character at index i is not within a

View File

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

View File

@@ -2,7 +2,6 @@ package com.horcrux.svg;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nonnull;
class TextProperties {
@@ -85,13 +84,15 @@ class TextProperties {
enum FontVariantLigatures {
normal,
@SuppressWarnings("unused")none
@SuppressWarnings("unused")
none
}
enum FontStyle {
normal,
italic,
@SuppressWarnings("unused")oblique
@SuppressWarnings("unused")
oblique
}
enum FontWeight {
@@ -112,6 +113,7 @@ class TextProperties {
Lighter("lighter");
private final String weight;
FontWeight(String weight) {
this.weight = weight;
}
@@ -125,6 +127,7 @@ class TextProperties {
}
private static final Map<String, FontWeight> weightToEnum = new HashMap<>();
static {
for (final FontWeight en : FontWeight.values()) {
weightToEnum.put(en.weight, en);
@@ -138,15 +141,13 @@ class TextProperties {
}
}
enum TextAnchor
{
enum TextAnchor {
start,
middle,
end
}
enum TextDecoration
{
enum TextDecoration {
None("none"),
Underline("underline"),
Overline("overline"),
@@ -154,6 +155,7 @@ class TextProperties {
Blink("blink");
private final String decoration;
TextDecoration(String decoration) {
this.decoration = decoration;
}
@@ -166,6 +168,7 @@ class TextProperties {
}
private static final Map<String, TextDecoration> decorationToEnum = new HashMap<>();
static {
for (final TextDecoration en : TextDecoration.values()) {
decorationToEnum.put(en.decoration, en);
@@ -179,15 +182,15 @@ class TextProperties {
}
}
enum TextLengthAdjust
{
enum TextLengthAdjust {
spacing,
spacingAndGlyphs
}
enum TextPathMethod {
align,
@SuppressWarnings("unused")stretch
@SuppressWarnings("unused")
stretch
}
/*
@@ -198,16 +201,19 @@ class TextProperties {
*/
enum TextPathMidLine {
sharp,
@SuppressWarnings("unused")smooth
@SuppressWarnings("unused")
smooth
}
enum TextPathSide {
@SuppressWarnings("unused")left,
@SuppressWarnings("unused")
left,
right
}
enum TextPathSpacing {
@SuppressWarnings("unused")auto,
@SuppressWarnings("unused")
auto,
exact
}
}

View File

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

View File

@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.annotation.SuppressLint;
@@ -14,7 +13,6 @@ import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
@@ -88,8 +86,12 @@ class UseView extends RenderableView {
VirtualView template = getSvgView().getDefinedTemplate(mHref);
if (template == null) {
FLog.w(ReactConstants.TAG, "`Use` element expected a pre-defined svg template as `href` prop, " +
"template named: " + mHref + " is not defined.");
FLog.w(
ReactConstants.TAG,
"`Use` element expected a pre-defined svg template as `href` prop, "
+ "template named: "
+ mHref
+ " is not defined.");
return;
}
@@ -104,7 +106,8 @@ class UseView extends RenderableView {
if (template instanceof SymbolView) {
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 {
template.draw(canvas, paint, opacity * mOpacity);
}
@@ -129,8 +132,12 @@ class UseView extends RenderableView {
VirtualView template = getSvgView().getDefinedTemplate(mHref);
if (template == null) {
FLog.w(ReactConstants.TAG, "`Use` element expected a pre-defined svg template as `href` prop, " +
"template named: " + mHref + " is not defined.");
FLog.w(
ReactConstants.TAG,
"`Use` element expected a pre-defined svg template as `href` prop, "
+ "template named: "
+ mHref
+ " is not defined.");
return -1;
}
@@ -146,8 +153,12 @@ class UseView extends RenderableView {
Path getPath(Canvas canvas, Paint paint) {
VirtualView template = getSvgView().getDefinedTemplate(mHref);
if (template == null) {
FLog.w(ReactConstants.TAG, "`Use` element expected a pre-defined svg template as `href` prop, " +
"template named: " + mHref + " is not defined.");
FLog.w(
ReactConstants.TAG,
"`Use` element expected a pre-defined svg template as `href` prop, "
+ "template named: "
+ mHref
+ " is not defined.");
return null;
}
Path path = template.getPath(canvas, paint);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,8 +8,8 @@
#import "RCTConvert+RNSVG.h"
#import "RNSVGBrushType.h"
#import "RNSVGUnits.h"
#import "RNSVGLength.h"
#import "RNSVGUnits.h"
@class RNSVGPattern;

View File

@@ -10,8 +10,7 @@
#import "RNSVGPattern.h"
#import "RNSVGViewBox.h"
@implementation RNSVGPainter
{
@implementation RNSVGPainter {
NSArray<RNSVGLength *> *_points;
NSArray<NSNumber *> *_colors;
RNSVGBrushType _type;
@@ -122,8 +121,7 @@ void PatternFunction(void* info, CGContextRef context)
CGFloat vbHeight = _pattern.vbHeight;
if (vbWidth > 0 && vbHeight > 0) {
CGRect vbRect = CGRectMake(minX, minY, vbWidth, vbHeight);
CGAffineTransform _viewBoxTransform = [RNSVGViewBox
getTransform:vbRect
CGAffineTransform _viewBoxTransform = [RNSVGViewBox getTransform:vbRect
eRect:rect
align:_pattern.align
meetOrSlice:_pattern.meetOrSlice];
@@ -141,10 +139,8 @@ void PatternFunction(void* info, CGContextRef context)
- (CGFloat)getVal:(RNSVGLength *)length relative:(CGFloat)relative
{
RNSVGLengthUnitType unit = [length unit];
CGFloat val = [RNSVGPropHelper fromRelative:length
relative:relative];
return _useObjectBoundingBox &&
unit == SVG_LENGTHTYPE_NUMBER ? val * relative : val;
CGFloat val = [RNSVGPropHelper fromRelative:length relative:relative];
return _useObjectBoundingBox && unit == SVG_LENGTHTYPE_NUMBER ? val * relative : val;
}
- (void)paintPattern:(CGContextRef)context bounds:(CGRect)bounds
@@ -175,7 +171,8 @@ void PatternFunction(void* info, CGContextRef context)
CGContextSetFillColorSpace(context, patternSpace);
CGColorSpaceRelease(patternSpace);
CGPatternRef pattern = CGPatternCreate((__bridge void * _Nullable)(self),
CGPatternRef pattern = CGPatternCreate(
(__bridge void *_Nullable)(self),
newBounds,
viewbox,
size.width,
@@ -252,4 +249,3 @@ void PatternFunction(void* info, CGContextRef context)
}
@end

View File

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

View File

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

View File

@@ -10,9 +10,9 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -55,7 +55,6 @@ using namespace facebook::react;
[self.svgView defineClipPath:self clipPathName:self.name];
}
- (BOOL)isSimpleClipPath
{
NSArray<RNSVGView *> *children = self.subviews;

View File

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

View File

@@ -12,9 +12,9 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -43,8 +43,12 @@ using namespace facebook::react;
{
const auto &newProps = *std::static_pointer_cast<const RNSVGForeignObjectProps>(props);
self.x = RCTNSStringFromStringNilIfEmpty(newProps.x) ? [RNSVGLength lengthWithString:RCTNSStringFromString(newProps.x)] : nil;
self.y = RCTNSStringFromStringNilIfEmpty(newProps.y) ? [RNSVGLength lengthWithString:RCTNSStringFromString(newProps.y)] : nil;
self.x = RCTNSStringFromStringNilIfEmpty(newProps.x)
? [RNSVGLength lengthWithString:RCTNSStringFromString(newProps.x)]
: nil;
self.y = RCTNSStringFromStringNilIfEmpty(newProps.y)
? [RNSVGLength lengthWithString:RCTNSStringFromString(newProps.y)]
: nil;
if (RCTNSStringFromStringNilIfEmpty(newProps.foreignObjectheight)) {
self.foreignObjectheight = [RNSVGLength lengthWithString:RCTNSStringFromString(newProps.foreignObjectheight)];
}
@@ -85,11 +89,7 @@ using namespace facebook::react;
[self clip:context];
CGContextTranslateCTM(context, [self relativeOnWidth:self.x], [self relativeOnHeight:self.y]);
CGRect clip = CGRectMake(
0,
0,
[self relativeOnWidth:self.foreignObjectwidth],
[self relativeOnHeight:self.foreignObjectheight]
);
0, 0, [self relativeOnWidth:self.foreignObjectwidth], [self relativeOnHeight:self.foreignObjectheight]);
CGContextClipToRect(context, clip);
[super renderLayerTo:context rect:rect];
}

View File

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

View File

@@ -10,17 +10,15 @@
#import "RNSVGClipPath.h"
#import "RNSVGMask.h"
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@implementation RNSVGGroup
{
@implementation RNSVGGroup {
RNSVGGlyphContext *_glyphContext;
}
@@ -156,8 +154,7 @@ using namespace facebook::react;
CGFloat width = CGRectGetWidth(clipBounds);
CGFloat height = CGRectGetHeight(clipBounds);
_glyphContext = [[RNSVGGlyphContext alloc] initWithWidth:width
height:height];
_glyphContext = [[RNSVGGlyphContext alloc] initWithWidth:width height:height];
}
- (RNSVGGlyphContext *)getGlyphContext
@@ -228,7 +225,8 @@ using namespace facebook::react;
}
if (!event) {
NSPredicate *const anyActive = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@ AND active == TRUE", [RNSVGNode class]];
NSPredicate *const anyActive =
[NSPredicate predicateWithFormat:@"self isKindOfClass: %@ AND active == TRUE", [RNSVGNode class]];
NSArray *const filtered = [self.subviews filteredArrayUsingPredicate:anyActive];
if ([filtered count] != 0) {
return [filtered.lastObject hitTest:transformed withEvent:event];

View File

@@ -9,9 +9,9 @@
#import <Foundation/Foundation.h>
#import <React/RCTBridge.h>
#import "RNSVGLength.h"
#import "RNSVGRenderable.h"
#import "RNSVGVBMOS.h"
#import "RNSVGLength.h"
#import <React/RCTImageSource.h>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,14 +10,13 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@implementation RNSVGPath
{
@implementation RNSVGPath {
CGPathRef _path;
}

View File

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

View File

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

View File

@@ -9,9 +9,9 @@
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -55,7 +55,13 @@ using namespace facebook::react;
}
self.gradientUnits = newProps.gradientUnits == 0 ? kRNSVGUnitsObjectBoundingBox : kRNSVGUnitsUserSpaceOnUse;
if (newProps.gradientTransform.size() == 6) {
self.gradientTransform = CGAffineTransformMake(newProps.gradientTransform.at(0), newProps.gradientTransform.at(1), newProps.gradientTransform.at(2), newProps.gradientTransform.at(3), newProps.gradientTransform.at(4), newProps.gradientTransform.at(5));
self.gradientTransform = CGAffineTransformMake(
newProps.gradientTransform.at(0),
newProps.gradientTransform.at(1),
newProps.gradientTransform.at(2),
newProps.gradientTransform.at(3),
newProps.gradientTransform.at(4),
newProps.gradientTransform.at(5));
}
setCommonNodeProps(newProps, self);

View File

@@ -8,8 +8,8 @@
#import "RNSVGUIKit.h"
#import "RNSVGPainter.h"
#import "RNSVGContainer.h"
#import "RNSVGPainter.h"
#import "RNSVGVBMOS.h"
#ifdef RN_FABRIC_ENABLED

View File

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

View File

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

View File

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

View File

@@ -6,14 +6,14 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGUse.h"
#import "RNSVGSymbol.h"
#import <React/RCTLog.h>
#import "RNSVGSymbol.h"
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@@ -102,7 +102,6 @@ using namespace facebook::react;
_y = y;
}
- (void)setUsewidth:(RNSVGLength *)usewidth
{
if ([usewidth isEqualTo:_usewidth]) {
@@ -137,7 +136,9 @@ using namespace facebook::react;
if ([definedTemplate class] == [RNSVGSymbol class]) {
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 {
[definedTemplate renderTo:context rect:rect];
}
@@ -149,7 +150,9 @@ using namespace facebook::react;
[self endTransparencyLayer:context];
} else if (self.href) {
// TODO: calling yellow box here
RCTLogWarn(@"`Use` element expected a pre-defined svg template as `href` prop, template named: %@ is not defined.", self.href);
RCTLogWarn(
@"`Use` element expected a pre-defined svg template as `href` prop, template named: %@ is not defined.",
self.href);
return;
} else {
return;
@@ -174,7 +177,8 @@ using namespace facebook::react;
self.frame = bounds;
}
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
transformed = CGPointApplyAffineTransform(transformed, self.invTransform);
RNSVGNode const *definedTemplate = [self.svgView getDefinedTemplate:self.href];
@@ -193,7 +197,8 @@ using namespace facebook::react;
- (CGPathRef)getPath:(CGContextRef)context
{
CGAffineTransform transform = CGAffineTransformMakeTranslation([self relativeOnWidth:self.x], [self relativeOnHeight:self.y]);
CGAffineTransform transform =
CGAffineTransformMakeTranslation([self relativeOnWidth:self.x], [self relativeOnHeight:self.y]);
RNSVGNode const *definedTemplate = [self.svgView getDefinedTemplate:self.href];
if (!definedTemplate) {
return nil;

View File

@@ -6,10 +6,11 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGSvgView.h"
#import <React/UIView+React.h>
#import <React/RCTPointerEvents.h>
#import "RNSVGCGFCRule.h"
#import "RNSVGSvgView.h"
#import <React/RCTPointerEvents.h>
#import <React/UIView+React.h>
#ifdef RN_FABRIC_ENABLED
#import <React/RCTViewComponentView.h>
@@ -73,7 +74,6 @@ extern CGFloat const RNSVG_DEFAULT_FONT_SIZE;
@property (nonatomic, assign) CGRect markerBounds;
@property (nonatomic, copy) RCTDirectEventBlock onLayout;
/**
* RNSVGSvgView which ownes current RNSVGNode
*/

View File

@@ -7,18 +7,17 @@
*/
#import "RNSVGNode.h"
#import "RNSVGContainer.h"
#import "RNSVGClipPath.h"
#import "RNSVGGroup.h"
#import "RNSVGContainer.h"
#import "RNSVGGlyphContext.h"
#import "RNSVGGroup.h"
@interface RNSVGNode ()
@property (nonatomic, readwrite, weak) RNSVGSvgView *svgView;
@property (nonatomic, readwrite, weak) RNSVGGroup *textRoot;
@end
@implementation RNSVGNode
{
@implementation RNSVGNode {
RNSVGGlyphContext *glyphContext;
BOOL _transparent;
RNSVGClipPath *_clipNode;
@@ -233,7 +232,8 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
}
}
- (void)setClientRect:(CGRect)clientRect {
- (void)setClientRect:(CGRect)clientRect
{
if (CGRectEqualToRect(_clientRect, clientRect)) {
return;
}
@@ -247,7 +247,6 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
@"height" : @(_clientRect.size.height),
}
});
}
}
@@ -376,7 +375,6 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
// hitTest delagate
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
// abstract
return nil;
}
@@ -465,7 +463,8 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return [self fromRelative:length];
}
- (CGFloat)fromRelative:(RNSVGLength*)length {
- (CGFloat)fromRelative:(RNSVGLength *)length
{
CGFloat unit;
switch (length.unit) {
case SVG_LENGTHTYPE_EMS:
@@ -512,7 +511,8 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return CGRectGetHeight([self getContextBounds]);
}
- (CGFloat)getContextDiagonal {
- (CGFloat)getContextDiagonal
{
CGRect bounds = [self getContextBounds];
CGFloat width = CGRectGetWidth(bounds);
CGFloat height = CGRectGetHeight(bounds);
@@ -522,7 +522,8 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return r;
}
- (CGFloat) getCanvasWidth {
- (CGFloat)getCanvasWidth
{
if (canvasWidth != -1) {
return canvasWidth;
}
@@ -536,7 +537,8 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return canvasWidth;
}
- (CGFloat) getCanvasHeight {
- (CGFloat)getCanvasHeight
{
if (canvasHeight != -1) {
return canvasHeight;
}
@@ -550,7 +552,8 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return canvasHeight;
}
- (CGFloat) getCanvasDiagonal {
- (CGFloat)getCanvasDiagonal
{
if (canvasDiagonal != -1) {
return canvasDiagonal;
}
@@ -636,7 +639,6 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
_svgView = nil;
_textRoot = nil;
glyphContext = nil;
_transparent = NO;
_clipNode = nil;

View File

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

View File

@@ -6,18 +6,17 @@
* LICENSE file in the root directory of this source tree.
*/
#import <React/RCTPointerEvents.h>
#import "RNSVGRenderable.h"
#import "RNSVGClipPath.h"
#import "RNSVGMask.h"
#import "RNSVGViewBox.h"
#import "RNSVGVectorEffect.h"
#import <React/RCTPointerEvents.h>
#import "RNSVGBezierElement.h"
#import "RNSVGClipPath.h"
#import "RNSVGMarker.h"
#import "RNSVGMarkerPosition.h"
#import "RNSVGMask.h"
#import "RNSVGVectorEffect.h"
#import "RNSVGViewBox.h"
@implementation RNSVGRenderable
{
@implementation RNSVGRenderable {
NSMutableDictionary *_originProperties;
NSArray<NSString *> *_lastMergedList;
NSArray<NSString *> *_attributeList;
@@ -27,8 +26,14 @@
}
static RNSVGRenderable *_contextElement;
+ (RNSVGRenderable *)contextElement { return _contextElement; }
+ (void)setContextElement:(RNSVGRenderable *)contextElement { _contextElement = contextElement; }
+ (RNSVGRenderable *)contextElement
{
return _contextElement;
}
+ (void)setContextElement:(RNSVGRenderable *)contextElement
{
_contextElement = contextElement;
}
- (id)init
{
@@ -217,7 +222,8 @@ static RNSVGRenderable * _contextElement;
}
#endif // RN_FABRIC_ENABLED
UInt32 saturate(CGFloat value) {
UInt32 saturate(CGFloat value)
{
return value <= 0 ? 0 : value >= 255 ? 255 : (UInt32)value;
}
@@ -258,18 +264,21 @@ UInt32 saturate(CGFloat value) {
NSUInteger bytesPerRow = bytesPerPixel * scaledWidth;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
UInt32 *pixels = (UInt32 *)calloc(npixels, sizeof(UInt32));
CGContextRef bcontext = CGBitmapContextCreate(pixels, scaledWidth, scaledHeight, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextRef bcontext = CGBitmapContextCreate(
pixels,
scaledWidth,
scaledHeight,
bitsPerComponent,
bytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextScaleCTM(bcontext, iscale, iscale);
// Clip to mask bounds and render the mask
CGFloat x = [self relativeOn:[_maskNode x]
relative:width];
CGFloat y = [self relativeOn:[_maskNode y]
relative:height];
CGFloat w = [self relativeOn:[_maskNode maskwidth]
relative:width];
CGFloat h = [self relativeOn:[_maskNode maskheight]
relative:height];
CGFloat x = [self relativeOn:[_maskNode x] relative:width];
CGFloat y = [self relativeOn:[_maskNode y] relative:height];
CGFloat w = [self relativeOn:[_maskNode maskwidth] relative:width];
CGFloat h = [self relativeOn:[_maskNode maskheight] relative:height];
CGRect maskBounds = CGRectMake(x, y, w, h);
CGContextClipToRect(bcontext, maskBounds);
[_maskNode renderLayerTo:bcontext rect:rect];
@@ -334,7 +343,8 @@ UInt32 saturate(CGFloat value) {
[self renderMarkers:context path:self.path rect:&rect];
}
- (void)prepareStrokeDash:(NSUInteger)count strokeDasharray:(NSArray<RNSVGLength *> *)strokeDasharray {
- (void)prepareStrokeDash:(NSUInteger)count strokeDasharray:(NSArray<RNSVGLength *> *)strokeDasharray
{
if (strokeDasharray != _sourceStrokeDashArray) {
CGFloat *dash = _strokeDashArrayData;
_strokeDashArrayData = (CGFloat *)realloc(dash, sizeof(CGFloat) * count);
@@ -349,7 +359,8 @@ 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 *markerEnd = (RNSVGMarker *)[self.svgView getDefinedMarker:self.markerEnd];
@@ -467,8 +478,7 @@ UInt32 saturate(CGFloat value) {
[self.fill paint:context
opacity:self.fillOpacity
painter:[self.svgView getDefinedPainter:self.fill.brushRef]
bounds:pathBounds
];
bounds:pathBounds];
CGContextRestoreGState(context);
if (!self.stroke) {
@@ -524,8 +534,7 @@ UInt32 saturate(CGFloat value) {
[self.stroke paint:context
opacity:self.strokeOpacity
painter:[self.svgView getDefinedPainter:self.stroke.brushRef]
bounds:pathBounds
];
bounds:pathBounds];
return;
}
}
@@ -547,9 +556,11 @@ UInt32 saturate(CGFloat value) {
if (self.stroke && self.strokeWidth) {
// Add stroke to hitArea
CGFloat width = [self relativeOnOther:self.strokeWidth];
self.strokePath = CGPathRetain((CGPathRef)CFAutorelease(CGPathCreateCopyByStrokingPath(path, nil, width, self.strokeLinecap, self.strokeLinejoin, self.strokeMiterlimit)));
self.strokePath = CGPathRetain((CGPathRef)CFAutorelease(CGPathCreateCopyByStrokingPath(
path, nil, width, self.strokeLinecap, self.strokeLinejoin, self.strokeMiterlimit)));
// TODO add dashing
// CGPathCreateCopyByDashingPath(CGPathRef _Nullable path, const CGAffineTransform * _Nullable transform, CGFloat phase, const CGFloat * _Nullable lengths, size_t count)
// CGPathCreateCopyByDashingPath(CGPathRef _Nullable path, const CGAffineTransform * _Nullable transform, CGFloat
// phase, const CGFloat * _Nullable lengths, size_t count)
}
}
@@ -580,8 +591,7 @@ UInt32 saturate(CGFloat value) {
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
transformed = CGPointApplyAffineTransform(transformed, self.invTransform);
if (!CGRectContainsPoint(self.pathBounds, transformed) &&
!CGRectContainsPoint(self.markerBounds, transformed)) {
if (!CGRectContainsPoint(self.pathBounds, transformed) && !CGRectContainsPoint(self.markerBounds, transformed)) {
return nil;
}

View File

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

View File

@@ -1,7 +1,6 @@
#import "RNSVGUIKit.h"
@implementation RNSVGView
{
@implementation RNSVGView {
NSColor *_tintColor;
}
@@ -46,7 +45,6 @@
@end
@implementation NSImage (RNSVGMacOSExtensions)
- (CGImageRef)CGImage
@@ -56,7 +54,6 @@
@end
@implementation NSValue (RNSVGMacOSExtensions)
+ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform

View File

@@ -17,4 +17,3 @@
@property (nonatomic, strong) RNSVGLength *r;
@end

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,8 +2,8 @@
#import "RNSVGUIKit.h"
#import "RNSVGTextProperties.h"
#import "RNSVGPropHelper.h"
#import "RNSVGTextProperties.h"
@interface RNSVGFontData : NSObject {
@public
@@ -26,11 +26,9 @@
+ (instancetype)Defaults;
+ (CGFloat)toAbsoluteWithNSString:(NSString *)string
fontSize:(CGFloat)fontSize;
+ (CGFloat)toAbsoluteWithNSString:(NSString *)string fontSize:(CGFloat)fontSize;
+ (instancetype)initWithNSDictionary:(NSDictionary *)font
parent:(RNSVGFontData *)parent;
+ (instancetype)initWithNSDictionary:(NSDictionary *)font parent:(RNSVGFontData *)parent;
@end

View File

@@ -1,7 +1,7 @@
#import "RNSVGFontData.h"
#import "RNSVGNode.h"
#import "RNSVGPropHelper.h"
#import "RNSVGTextProperties.h"
#import "RNSVGNode.h"
#define RNSVG_DEFAULT_KERNING 0.0
#define RNSVG_DEFAULT_WORD_SPACING 0.0
@@ -23,7 +23,8 @@ RNSVGFontData *RNSVGFontData_Defaults;
@implementation RNSVGFontData
+ (instancetype)Defaults {
+ (instancetype)Defaults
{
if (!RNSVGFontData_Defaults) {
RNSVGFontData *self = [RNSVGFontData alloc];
self->fontData = nil;
@@ -45,23 +46,24 @@ RNSVGFontData *RNSVGFontData_Defaults;
return RNSVGFontData_Defaults;
}
+ (CGFloat)toAbsoluteWithNSString:(NSString *)string
fontSize:(CGFloat)fontSize {
return [RNSVGPropHelper fromRelativeWithNSString:string
relative:0
fontSize:fontSize];
+ (CGFloat)toAbsoluteWithNSString:(NSString *)string fontSize:(CGFloat)fontSize
{
return [RNSVGPropHelper fromRelativeWithNSString:string relative:0 fontSize:fontSize];
}
- (void)setInheritedWeight:(RNSVGFontData*) parent {
- (void)setInheritedWeight:(RNSVGFontData *)parent
{
absoluteFontWeight = parent->absoluteFontWeight;
fontWeight = parent->fontWeight;
}
RNSVGFontWeight nearestFontWeight(int absoluteFontWeight) {
RNSVGFontWeight nearestFontWeight(int absoluteFontWeight)
{
return RNSVGFontWeights[(int)round(absoluteFontWeight / 100.0)];
}
- (void)handleNumericWeight:(RNSVGFontData*)parent weight:(double)weight {
- (void)handleNumericWeight:(RNSVGFontData *)parent weight:(double)weight
{
long roundWeight = round(weight);
if (roundWeight >= 1 && roundWeight <= 1000) {
absoluteFontWeight = (int)roundWeight;
@@ -72,7 +74,8 @@ RNSVGFontWeight nearestFontWeight(int absoluteFontWeight) {
}
// https://drafts.csswg.org/css-fonts-4/#relative-weights
int AbsoluteFontWeight(RNSVGFontWeight fontWeight, RNSVGFontData* parent) {
int AbsoluteFontWeight(RNSVGFontWeight fontWeight, RNSVGFontData *parent)
{
if (fontWeight == RNSVGFontWeightBolder) {
return bolder(parent->absoluteFontWeight);
} else if (fontWeight == RNSVGFontWeightLighter) {
@@ -82,7 +85,8 @@ int AbsoluteFontWeight(RNSVGFontWeight fontWeight, RNSVGFontData* parent) {
}
}
int bolder(int inherited) {
int bolder(int inherited)
{
if (inherited < 350) {
return 400;
} else if (inherited < 550) {
@@ -94,7 +98,8 @@ int bolder(int inherited) {
}
}
int lighter(int inherited) {
int lighter(int inherited)
{
if (inherited < 100) {
return inherited;
} else if (inherited < 550) {
@@ -106,8 +111,8 @@ int lighter(int inherited) {
}
}
+ (instancetype)initWithNSDictionary:(NSDictionary *)font
parent:(RNSVGFontData *)parent {
+ (instancetype)initWithNSDictionary:(NSDictionary *)font parent:(RNSVGFontData *)parent
{
RNSVGFontData *data = [RNSVGFontData alloc];
CGFloat parentFontSize = parent->fontSize;
if ([font objectForKey:FONT_SIZE]) {
@@ -120,8 +125,7 @@ int lighter(int inherited) {
relative:parentFontSize
fontSize:parentFontSize];
}
}
else {
} else {
data->fontSize = parentFontSize;
}
@@ -165,10 +169,7 @@ int lighter(int inherited) {
NSNumber *kern = kerning;
data->kerning = (CGFloat)[kern doubleValue];
} else {
data->kerning = kerning ?
[RNSVGFontData toAbsoluteWithNSString:kerning
fontSize:fontSize]
: parent->kerning;
data->kerning = kerning ? [RNSVGFontData toAbsoluteWithNSString:kerning fontSize:fontSize] : parent->kerning;
}
id wordSpacing = [font objectForKey:WORD_SPACING];
@@ -176,10 +177,8 @@ int lighter(int inherited) {
NSNumber *ws = wordSpacing;
data->wordSpacing = (CGFloat)[ws doubleValue];
} else {
data->wordSpacing = wordSpacing ?
[RNSVGFontData toAbsoluteWithNSString:wordSpacing
fontSize:fontSize]
: parent->wordSpacing;
data->wordSpacing =
wordSpacing ? [RNSVGFontData toAbsoluteWithNSString:wordSpacing fontSize:fontSize] : parent->wordSpacing;
}
id letterSpacing = [font objectForKey:LETTER_SPACING];
@@ -187,14 +186,11 @@ int lighter(int inherited) {
NSNumber *ls = letterSpacing;
data->wordSpacing = (CGFloat)[ls doubleValue];
} else {
data->letterSpacing = letterSpacing ?
[RNSVGFontData toAbsoluteWithNSString:letterSpacing
fontSize:fontSize]
: parent->letterSpacing;
data->letterSpacing =
letterSpacing ? [RNSVGFontData toAbsoluteWithNSString:letterSpacing fontSize:fontSize] : parent->letterSpacing;
}
return data;
}
@end

View File

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

View File

@@ -1,8 +1,8 @@
#import "RNSVGGlyphContext.h"
#import <React/RCTFont.h>
#import "RNSVGFontData.h"
#import "RNSVGNode.h"
#import "RNSVGPropHelper.h"
#import "RNSVGFontData.h"
#import "RNSVGText.h"
// https://www.w3.org/TR/SVG/text.html#TSpanElement
@@ -101,13 +101,13 @@
deltaY:(NSArray<RNSVGLength *> *)deltaY
rotate:(NSArray<RNSVGLength *> *)rotate;
- (void)pushContext:(RNSVGGroup*)node
font:(NSDictionary *)font;
- (void)pushContext:(RNSVGGroup *)node font:(NSDictionary *)font;
@end
@implementation RNSVGGlyphContext
- (NSArray*)getFontContext {
- (NSArray *)getFontContext
{
return mFontContext_;
}
@@ -160,8 +160,7 @@
if (axisMinValue && CFGetTypeID(axisMinValue) == CFNumberGetTypeID()) {
CFNumberRef axisMinValueNumber = (CFNumberRef)axisMinValue;
double axisMinValueDouble;
if (CFNumberGetValue(axisMinValueNumber, kCFNumberDoubleType, &axisMinValueDouble))
{
if (CFNumberGetValue(axisMinValueNumber, kCFNumberDoubleType, &axisMinValueDouble)) {
weight = fmax(axisMinValueDouble, weight);
}
}
@@ -170,8 +169,7 @@
if (axisMaxValue && CFGetTypeID(axisMaxValue) == CFNumberGetTypeID()) {
CFNumberRef axisMaxValueNumber = (CFNumberRef)axisMaxValue;
double axisMaxValueDouble;
if (CFNumberGetValue(axisMaxValueNumber, kCFNumberDoubleType, &axisMaxValueDouble))
{
if (CFNumberGetValue(axisMaxValueNumber, kCFNumberDoubleType, &axisMaxValueDouble)) {
weight = fmin(axisMaxValueDouble, weight);
}
}
@@ -206,8 +204,8 @@
[self->mRsIndices_ addObject:[NSNumber numberWithLong:self->mRsIndex_]];
}
- (instancetype)initWithWidth:(CGFloat)width
height:(CGFloat)height {
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height
{
self = [super init];
self->mFontContext_ = [[NSMutableArray alloc] init];
self->mXsContext_ = [[NSMutableArray alloc] init];
@@ -263,7 +261,8 @@
return self;
}
- (RNSVGFontData *)getFont {
- (RNSVGFontData *)getFont
{
return topFont_;
}
@@ -293,15 +292,14 @@
[self->mFontContext_ addObject:parent];
return;
}
RNSVGFontData *data = [RNSVGFontData initWithNSDictionary:font
parent:parent];
RNSVGFontData *data = [RNSVGFontData initWithNSDictionary:font parent:parent];
self->mFontSize_ = data->fontSize;
[self->mFontContext_ addObject:data];
self->topFont_ = data;
}
- (void)pushContext:(RNSVGGroup*)node
font:(NSDictionary*)font {
- (void)pushContext:(RNSVGGroup *)node font:(NSDictionary *)font
{
[self pushNode:node andFont:font];
[self pushIndices];
}
@@ -312,7 +310,8 @@
y:(NSArray<RNSVGLength *> *)y
deltaX:(NSArray<RNSVGLength *> *)deltaX
deltaY:(NSArray<RNSVGLength *> *)deltaY
rotate:(NSArray<RNSVGLength*>*)rotate {
rotate:(NSArray<RNSVGLength *> *)rotate
{
[self pushNode:(RNSVGGroup *)node andFont:font];
if (x != nil && [x count] != 0) {
mXsIndex_++;
@@ -352,7 +351,8 @@
[self pushIndices];
}
- (void)popContext {
- (void)popContext
{
[mFontContext_ removeLastObject];
[mXsIndices_ removeLastObject];
[mYsIndices_ removeLastObject];
@@ -442,68 +442,66 @@
* Except for any additional information provided in this specification,
* the normative definition of the property is in CSS2 ([CSS2], section 15.2.4).
*/
- (CGFloat)getFontSize {
- (CGFloat)getFontSize
{
return mFontSize_;
}
- (CGFloat)nextXWithDouble:(CGFloat)advance {
- (CGFloat)nextXWithDouble:(CGFloat)advance
{
[RNSVGGlyphContext incrementIndices:mXIndices_ topIndex:mXsIndex_];
long nextIndex = mXIndex_ + 1;
if (nextIndex < [mXs_ count]) {
mDX_ = 0;
mXIndex_ = nextIndex;
RNSVGLength *length = [mXs_ objectAtIndex:nextIndex];
mX_ = [RNSVGPropHelper fromRelative:length
relative:mWidth_
fontSize:mFontSize_];
mX_ = [RNSVGPropHelper fromRelative:length relative:mWidth_ fontSize:mFontSize_];
}
mX_ += advance;
return mX_;
}
- (CGFloat)nextY {
- (CGFloat)nextY
{
[RNSVGGlyphContext incrementIndices:mYIndices_ topIndex:mYsIndex_];
long nextIndex = mYIndex_ + 1;
if (nextIndex < [mYs_ count]) {
mDY_ = 0;
mYIndex_ = nextIndex;
RNSVGLength *length = [mYs_ objectAtIndex:nextIndex];
mY_ = [RNSVGPropHelper fromRelative:length
relative:mHeight_
fontSize:mFontSize_];
mY_ = [RNSVGPropHelper fromRelative:length relative:mHeight_ fontSize:mFontSize_];
}
return mY_;
}
- (CGFloat)nextDeltaX {
- (CGFloat)nextDeltaX
{
[RNSVGGlyphContext incrementIndices:mDXIndices_ topIndex:mDXsIndex_];
long nextIndex = mDXIndex_ + 1;
if (nextIndex < [mDXs_ count]) {
mDXIndex_ = nextIndex;
RNSVGLength *length = [mDXs_ objectAtIndex:nextIndex];
CGFloat val = [RNSVGPropHelper fromRelative:length
relative:mWidth_
fontSize:mFontSize_];
CGFloat val = [RNSVGPropHelper fromRelative:length relative:mWidth_ fontSize:mFontSize_];
mDX_ += val;
}
return mDX_;
}
- (CGFloat)nextDeltaY {
- (CGFloat)nextDeltaY
{
[RNSVGGlyphContext incrementIndices:mDYIndices_ topIndex:mDYsIndex_];
long nextIndex = mDYIndex_ + 1;
if (nextIndex < [mDYs_ count]) {
mDYIndex_ = nextIndex;
RNSVGLength *length = [mDYs_ objectAtIndex:nextIndex];
CGFloat val = [RNSVGPropHelper fromRelative:length
relative:mHeight_
fontSize:mFontSize_];
CGFloat val = [RNSVGPropHelper fromRelative:length relative:mHeight_ fontSize:mFontSize_];
mDY_ += val;
}
return mDY_;
}
- (CGFloat)nextRotation {
- (CGFloat)nextRotation
{
[RNSVGGlyphContext incrementIndices:mRIndices_ topIndex:mRsIndex_];
long nextIndex = mRIndex_ + 1;
long count = [mRs_ count];
@@ -515,11 +513,13 @@
return [mRs_[mRIndex_] value];
}
- (CGFloat)getWidth {
- (CGFloat)getWidth
{
return mWidth_;
}
- (CGFloat)getHeight {
- (CGFloat)getHeight
{
return mHeight_;
}
@end

View File

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

View File

@@ -1,26 +1,22 @@
#include "RNSVGPropHelper.h"
@implementation RNSVGPropHelper
+ (CGFloat)fromRelativeWithNSString:(NSString *)length
relative:(CGFloat)relative
fontSize:(CGFloat)fontSize {
+ (CGFloat)fromRelativeWithNSString:(NSString *)length relative:(CGFloat)relative fontSize:(CGFloat)fontSize
{
length = [length stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSUInteger stringLength = [length length];
NSInteger percentIndex = stringLength - 1;
if (stringLength == 0) {
return 0;
}
else if ([length characterAtIndex:percentIndex] == '%') {
} else if ([length characterAtIndex:percentIndex] == '%') {
return (CGFloat)[[length substringWithRange:NSMakeRange(0, percentIndex)] doubleValue] / 100 * relative;
}
else {
} else {
NSInteger twoLetterUnitIndex = stringLength - 2;
if (twoLetterUnitIndex > 0) {
NSString *lastTwo = [length substringFromIndex:twoLetterUnitIndex];
NSUInteger end = twoLetterUnitIndex;
CGFloat unit = 1;
if ([lastTwo isEqualToString:@"px"]) {
} else if ([lastTwo isEqualToString:@"em"]) {
unit = fontSize;
} else if ([lastTwo isEqualToString:@"ex"]) {
@@ -46,9 +42,8 @@
}
}
+ (CGFloat)fromRelative:(RNSVGLength*)length
relative:(CGFloat)relative
fontSize:(CGFloat)fontSize {
+ (CGFloat)fromRelative:(RNSVGLength *)length relative:(CGFloat)relative fontSize:(CGFloat)fontSize
{
RNSVGLengthUnitType unitType = length.unit;
CGFloat value = length.value;
CGFloat unit = 1;
@@ -91,8 +86,8 @@
return value * unit;
}
+ (CGFloat)fromRelative:(RNSVGLength*)length
relative:(CGFloat)relative {
+ (CGFloat)fromRelative:(RNSVGLength *)length relative:(CGFloat)relative
{
RNSVGLengthUnitType unitType = length.unit;
CGFloat value = length.value;
CGFloat unit = 1;

View File

@@ -6,8 +6,8 @@
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <CoreText/CoreText.h>
#import <Foundation/Foundation.h>
#import "RNSVGUIKit.h"

View File

@@ -6,27 +6,26 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGTSpan.h"
#import "RNSVGUIKit.h"
#import "RNSVGFontData.h"
#import "RNSVGPathMeasure.h"
#import "RNSVGText.h"
#import "RNSVGTextPath.h"
#import "RNSVGTextProperties.h"
#import "RNSVGTopAlignedLabel.h"
#import "RNSVGPathMeasure.h"
#import "RNSVGFontData.h"
#import "RNSVGUIKit.h"
static NSCharacterSet *RNSVGTSpan_separators = nil;
static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@implementation RNSVGTSpan
{
@implementation RNSVGTSpan {
CGFloat startOffset;
RNSVGTextPath *textPath;
NSMutableArray *emoji;
@@ -108,7 +107,6 @@ using namespace facebook::react;
emojiTransform = [NSMutableArray arrayWithCapacity:0];
measure = [[RNSVGPathMeasure alloc] init];
RNSVGTSpan_separators = [NSCharacterSet whitespaceCharacterSet];
}
#endif // RN_FABRIC_ENABLED
@@ -190,7 +188,8 @@ using namespace facebook::react;
}
}
- (NSMutableDictionary *)getAttributes:(RNSVGFontData *)fontdata {
- (NSMutableDictionary *)getAttributes:(RNSVGFontData *)fontdata
{
NSMutableDictionary *attrs = [[NSMutableDictionary alloc] init];
if (fontRef != nil) {
@@ -206,11 +205,9 @@ using namespace facebook::react;
float kern = (float)(letterSpacing + kerning);
NSNumber *kernAttr = [NSNumber numberWithFloat:kern];
#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES
if (___useiOS6Attributes)
{
if (___useiOS6Attributes) {
[attrs setObject:kernAttr forKey:NSKernAttributeName];
}
else
} else
#endif // DTCORETEXT_SUPPORT_NS_ATTRIBUTES
{
[attrs setObject:kernAttr forKey:(id)kCTKernAttributeName];
@@ -220,7 +217,8 @@ using namespace facebook::react;
}
RNSVGTopAlignedLabel *label;
- (void)drawWrappedText:(CGContextRef)context gc:(RNSVGGlyphContext *)gc rect:(CGRect)rect color:(CGColorRef)color {
- (void)drawWrappedText:(CGContextRef)context gc:(RNSVGGlyphContext *)gc rect:(CGRect)rect color:(CGColorRef)color
{
[self pushGlyphContext];
if (fontRef != nil) {
CFRelease(fontRef);
@@ -269,12 +267,9 @@ RNSVGTopAlignedLabel *label;
CGFloat fontSize = [gc getFontSize];
CGFloat height = CGRectGetHeight(rect);
CGFloat width = [RNSVGPropHelper fromRelative:self.inlineSize
relative:[gc getWidth]
fontSize:fontSize];
CGFloat width = [RNSVGPropHelper fromRelative:self.inlineSize relative:[gc getWidth] fontSize:fontSize];
CGRect constrain = CGRectMake(0, 0, width, height);
CGRect s = [self.content
boundingRectWithSize:constrain.size
CGRect s = [self.content boundingRectWithSize:constrain.size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attrs
context:nil];
@@ -518,11 +513,9 @@ RNSVGTopAlignedLabel *label;
NSNumber *noAutoKern = [NSNumber numberWithFloat:0.0f];
#if DTCORETEXT_SUPPORT_NS_ATTRIBUTES
if (___useiOS6Attributes)
{
if (___useiOS6Attributes) {
[attrs setObject:noAutoKern forKey:NSKernAttributeName];
}
else
} else
#endif // DTCORETEXT_SUPPORT_NS_ATTRIBUTES
{
[attrs setObject:noAutoKern forKey:(id)kCTKernAttributeName];
@@ -726,12 +719,9 @@ RNSVGTopAlignedLabel *label;
RNSVGLength *mTextLength = [self textLength];
enum RNSVGTextLengthAdjust mLengthAdjust = RNSVGTextLengthAdjustFromString([self lengthAdjust]);
if (mTextLength != nil) {
CGFloat author = [RNSVGPropHelper fromRelative:mTextLength
relative:[gc getWidth]
fontSize:fontSize];
CGFloat author = [RNSVGPropHelper fromRelative:mTextLength relative:[gc getWidth] fontSize:fontSize];
if (author < 0) {
NSException *e = [NSException
exceptionWithName:@"NegativeTextLength"
NSException *e = [NSException exceptionWithName:@"NegativeTextLength"
reason:@"Negative textLength value"
userInfo:nil];
@throw e;
@@ -829,8 +819,8 @@ RNSVGTopAlignedLabel *label;
break;
case RNSVGAlignmentBaselineMiddle:
// Align the vertical midpoint of the box with the baseline of the parent box plus half the x-height of the parent. TODO
// middle = x height / 2
// Align the vertical midpoint of the box with the baseline of the parent box plus half the x-height of the
// parent. TODO middle = x height / 2
baselineShift = xHeight / 2;
break;
@@ -1055,7 +1045,8 @@ RNSVGTopAlignedLabel *label;
transform = CGAffineTransformConcat(CGAffineTransformMakeTranslation(px, py), transform);
transform = CGAffineTransformConcat(CGAffineTransformMakeRotation(angle + r), transform);
transform = CGAffineTransformScale(transform, scaledDirection, side);
transform = CGAffineTransformConcat(CGAffineTransformMakeTranslation(-halfWay, y + dy + baselineShift), transform);
transform =
CGAffineTransformConcat(CGAffineTransformMakeTranslation(-halfWay, y + dy + baselineShift), transform);
} else {
transform = CGAffineTransformMakeTranslation(startPoint, y + dy + baselineShift);
transform = CGAffineTransformConcat(CGAffineTransformMakeRotation(r), transform);
@@ -1079,8 +1070,7 @@ RNSVGTopAlignedLabel *label;
label.backgroundColor = RNSVGColor.clearColor;
UIFont *customFont = [UIFont systemFontOfSize:fontSize];
CGSize measuredSize = [currChars sizeWithAttributes:
@{NSFontAttributeName:customFont}];
CGSize measuredSize = [currChars sizeWithAttributes:@{NSFontAttributeName : customFont}];
label.font = customFont;
CGFloat width = ceil(measuredSize.width);
CGFloat height = ceil(measuredSize.height);

View File

@@ -7,22 +7,21 @@
*/
#import "RNSVGText.h"
#import "RNSVGTextPath.h"
#import <React/RCTFont.h>
#import <CoreText/CoreText.h>
#import <React/RCTFont.h>
#import "RNSVGGlyphContext.h"
#import "RNSVGTextPath.h"
#import "RNSVGTextProperties.h"
#ifdef RN_FABRIC_ENABLED
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import "RCTFabricComponentsPlugins.h"
#import "RCTConversions.h"
#import <react/renderer/components/view/conversions.h>
#import "RCTConversions.h"
#import "RCTFabricComponentsPlugins.h"
#import "RNSVGFabricConversions.h"
#endif // RN_FABRIC_ENABLED
@implementation RNSVGText
{
@implementation RNSVGText {
RNSVGGlyphContext *_glyphContext;
NSString *_alignmentBaseline;
NSString *_baselineShift;
@@ -219,8 +218,7 @@ using namespace facebook::react;
{
CGRect bounds = CGContextGetClipBoundingBox(context);
CGSize size = bounds.size;
_glyphContext = [[RNSVGGlyphContext alloc] initWithWidth:size.width
height:size.height];
_glyphContext = [[RNSVGGlyphContext alloc] initWithWidth:size.width height:size.height];
}
- (CGPathRef)getGroupPath:(CGContextRef)context
@@ -352,8 +350,7 @@ using namespace facebook::react;
RNSVGPlatformView *parent = [self superview];
for (NSInteger i = [font count] - 1; i >= 0; i--) {
RNSVGFontData *fontData = [font objectAtIndex:i];
if (![parent isKindOfClass:[RNSVGText class]] ||
fontData->textAnchor == RNSVGTextAnchorStart ||
if (![parent isKindOfClass:[RNSVGText class]] || fontData->textAnchor == RNSVGTextAnchorStart ||
node.positionX != nil) {
return node;
}

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