feat(windows): add fabric support (#2321)

# Summary
This PR adds Fabric support and a FabricExample app for Windows.

Windows support for Fabric is experimental and as such APIs are subject
to change/break.

## Test Plan


https://github.com/software-mansion/react-native-svg/assets/1422161/2a7db119-44a8-4ee1-a837-41ca8320d8fa

## Compatibility

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

## Checklist
- [x] I have tested this on a device and a simulator
- [ ] I added documentation in `README.md`
- [ ] I updated the typed files (typescript)
- [ ] I added a test for the API in the `__tests__` folder
This commit is contained in:
Marlene Cota
2024-08-18 23:18:45 -07:00
committed by GitHub
parent e87d22f49e
commit b80f102b09
124 changed files with 14920 additions and 1127 deletions

View File

@@ -17,7 +17,7 @@ jobs:
runs-on: windows-2022
strategy:
matrix:
working-directory: [example]
working-directory: [example, fabric-windows-example]
concurrency:
group: windows-${{ matrix.working-directory }}-${{ github.ref }}
cancel-in-progress: true

View File

@@ -0,0 +1,45 @@
import * as Svg from './examples/Svg';
import * as Rect from './examples/Rect';
import * as Circle from './examples/Circle';
import * as Ellipse from './examples/Ellipse';
import * as Line from './examples/Line';
import * as Polygon from './examples/Polygon';
import * as Polyline from './examples/Polyline';
import * as Path from './examples/Path';
import * as Text from './examples/Text';
import * as G from './examples/G';
import * as Stroking from './examples/Stroking';
import * as Gradients from './examples/Gradients';
import * as Clipping from './examples/Clipping';
import * as Image from './examples/Image';
import * as Reusable from './examples/Reusable';
import * as TouchEvents from './examples/TouchEvents';
import * as PanResponder from './examples/PanResponder';
import * as Reanimated from './examples/Reanimated';
import * as Transforms from './examples/Transforms';
import * as Markers from './examples/Markers';
import * as Mask from './examples/Mask';
export {
Svg,
Rect,
Circle,
Ellipse,
Line,
Polygon,
Polyline,
Path,
Text,
Stroking,
G,
Gradients,
Clipping,
Image,
TouchEvents,
Reusable,
PanResponder,
Reanimated,
Transforms,
Markers,
Mask,
};

74
fabric-windows-example/.gitignore vendored Normal file
View File

@@ -0,0 +1,74 @@
# OSX
#
.DS_Store
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
**/.xcode.env.local
# Android/IntelliJ
#
build/
.idea
.gradle
local.properties
*.iml
*.hprof
.cxx/
*.keystore
!debug.keystore
# node.js
#
node_modules/
npm-debug.log
yarn-error.log
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/
**/fastlane/report.xml
**/fastlane/Preview.html
**/fastlane/screenshots
**/fastlane/test_output
# Bundle artifact
*.jsbundle
# Ruby / CocoaPods
**/Pods/
/vendor/bundle/
# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*
# testing
/coverage
# Yarn
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

View File

@@ -0,0 +1,7 @@
module.exports = {
arrowParens: 'avoid',
bracketSameLine: true,
bracketSpacing: false,
singleQuote: true,
trailingComma: 'all',
};

View File

@@ -0,0 +1 @@
2.7.6

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1,3 @@
import App from '../apps/examples';
export default App;

View File

@@ -0,0 +1,4 @@
{
"name": "FabricExample",
"displayName": "FabricWindowsExample"
}

View File

@@ -0,0 +1,6 @@
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: [
'react-native-reanimated/plugin',
],
};

View File

@@ -0,0 +1,9 @@
/**
* @format
*/
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);

View File

@@ -0,0 +1,3 @@
module.exports = {
preset: 'react-native',
};

View File

@@ -0,0 +1,3 @@
const config = {};
module.exports = require('@rnx-kit/jest-preset')('windows', config);

View File

@@ -0,0 +1,62 @@
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
/**
* Metro configuration
* https://facebook.github.io/metro/docs/configuration
*
* @type {import('metro-config').MetroConfig}
*/
const path = require('path');
const exclusionList = require('metro-config/src/defaults/exclusionList');
const escape = require('escape-string-regexp');
const pack = require('../package.json');
const root = path.resolve(__dirname, '..');
const projectNodeModules = path.join(__dirname, 'node_modules');
const fs = require('fs');
const rnwPath = fs.realpathSync(
path.resolve(require.resolve('react-native-windows/package.json'), '..')
);
const modules = [...Object.keys(pack.peerDependencies), 'react-native-windows'];
const config = {
projectRoot: __dirname,
watchFolders: [root],
// We need to make sure that only one version is loaded for peerDependencies
// So we exclude them at the root, and alias them to the versions in example's node_modules
resolver: {
blockList: exclusionList(
modules.map(
(m) =>
new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`)
),
// This stops "react-native run-windows" from causing the metro server to
// crash if its already running
new RegExp(`${path.join(__dirname, 'windows').replace(/[/\\]+/g, '/')}.*`),
// This prevents "react-native run-windows" from hitting: EBUSY: resource busy or locked, open msbuild.ProjectImports.zip or other files produced by msbuild
new RegExp(`${rnwPath}/build/.*`),
new RegExp(`${rnwPath}/target/.*`),
/.*\.ProjectImports\.zip/
),
nodeModulesPaths: [projectNodeModules, path.join(__dirname, '../../')],
extraNodeModules: modules.reduce((acc, name) => {
acc[name] = path.join(__dirname, 'node_modules', name);
return acc;
}, {}),
},
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
},
}),
// This fixes the 'missing-asset-registry-path` error (see https://github.com/microsoft/react-native-windows/issues/11437)
assetRegistryPath: 'react-native/Libraries/Image/AssetRegistry',
},
};
module.exports = mergeConfig(getDefaultConfig(__dirname), config);

View File

@@ -0,0 +1,39 @@
{
"name": "FabricWindowsExample",
"version": "0.0.1",
"private": true,
"scripts": {
"windows": "react-native run-windows",
"lint": "eslint .",
"start": "react-native start",
"test": "jest"
},
"dependencies": {
"react": "18.2.0",
"react-native": "0.74.2",
"react-native-windows": "0.74.9",
"react-native-reanimated": "3.9.0",
"react-native-svg": "link:../"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/babel-preset": "0.74.81",
"@react-native/eslint-config": "0.74.81",
"@react-native/metro-config": "0.74.81",
"@react-native/typescript-config": "0.74.81",
"@types/react": "^18.2.6",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.6.3",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react-test-renderer": "18.2.0",
"typescript": "5.0.4",
"@rnx-kit/jest-preset": "^0.1.16"
},
"engines": {
"node": ">=18"
}
}

View File

@@ -0,0 +1,41 @@
*AppPackages*
*BundleArtifacts*
#OS junk files
[Tt]humbs.db
*.DS_Store
#Visual Studio files
*.[Oo]bj
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
*.opensdf
*.opendb
*.unsuccessfulbuild
ipch/
[Oo]bj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad
.vs/
# Visual C++ cache files
#Files generated by the VS build
**/Generated Files/**

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Microsoft.ReactNative Experimental Features">
<UseFabric>true</UseFabric>
<UseWinUI3>true</UseWinUI3>
<ReactExperimentalFeaturesSet>true</ReactExperimentalFeaturesSet>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)\ExperimentalFeatures.props" Condition="Exists('$(SolutionDir)\ExperimentalFeatures.props')" />
<PropertyGroup>
<ProjectGuid>{9cf487c7-8a97-4df0-ac99-d53cfcf1d59b}</ProjectGuid>
<DefaultLanguage>en-US</DefaultLanguage>
<EntryPointProjectUniqueName>..\FabricExample\FabricExample.vcxproj</EntryPointProjectUniqueName>
<DebuggerType>NativeOnly</DebuggerType>
<BackgroundTaskDebugEngines>NativeOnly</BackgroundTaskDebugEngines>
</PropertyGroup>
<PropertyGroup Label="ReactNativeWindowsProps">
<ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
</PropertyGroup>
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.WindowsSdk.Default.props" />
<PropertyGroup>
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
</PropertyGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ImportGroup Label="ReactNativeWindowsPropertySheets">
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.Package.props" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.Package.props')" />
</ImportGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Content Include="Images\SplashScreen.scale-200.png" />
<Content Include="Images\LockScreenLogo.scale-200.png" />
<Content Include="Images\Square150x150Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Images\StoreLogo.png" />
<Content Include="Images\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FabricExample\FabricExample.vcxproj">
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
</ProjectReference>
</ItemGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
<ImportGroup Label="ReactNativeWindowsTargets">
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.Package.targets" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.Package.targets')" />
</ImportGroup>
<Target Name="EnsureReactNativeWindowsTargets" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references targets in your node_modules\react-native-windows folder that are missing. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.Package.props')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.Package.props'))" />
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.Package.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.Package.targets'))" />
</Target>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="FabricExample"
Publisher="CN=mcota"
Version="1.0.0.0" />
<Properties>
<DisplayName>FabricExample</DisplayName>
<PublisherDisplayName>mcota</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.17763.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="FabricExample"
Description="FabricExample"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" />
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

View File

@@ -0,0 +1,53 @@
{
"version": 1,
"dependencies": {
"UAP,Version=v10.0.17763": {
"common": {
"type": "Project"
},
"fabricexample": {
"type": "Project",
"dependencies": {
"Microsoft.ReactNative": "[1.0.0, )",
"RNSVG": "[1.0.0, )"
}
},
"fmt": {
"type": "Project"
},
"folly": {
"type": "Project",
"dependencies": {
"fmt": "[1.0.0, )"
}
},
"microsoft.reactnative": {
"type": "Project",
"dependencies": {
"Common": "[1.0.0, )",
"Folly": "[1.0.0, )",
"ReactCommon": "[1.0.0, )"
}
},
"reactcommon": {
"type": "Project",
"dependencies": {
"Folly": "[1.0.0, )"
}
},
"rnsvg": {
"type": "Project",
"dependencies": {
"Microsoft.ReactNative": "[1.0.0, )"
}
}
},
"UAP,Version=v10.0.17763/win10-arm": {},
"UAP,Version=v10.0.17763/win10-arm-aot": {},
"UAP,Version=v10.0.17763/win10-arm64-aot": {},
"UAP,Version=v10.0.17763/win10-x64": {},
"UAP,Version=v10.0.17763/win10-x64-aot": {},
"UAP,Version=v10.0.17763/win10-x86": {},
"UAP,Version=v10.0.17763/win10-x86-aot": {}
}
}

View File

@@ -0,0 +1,204 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32929.385
MinimumVisualStudioVersion = 10.0.40219.1
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "FabricExample.Package", "FabricExample.Package\FabricExample.Package.wapproj", "{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FabricExample", "FabricExample\FabricExample.vcxproj", "{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}"
ProjectSection(ProjectDependencies) = postProject
{F7D32BD0-2749-483E-9A0D-1635EF7E3136} = {F7D32BD0-2749-483E-9A0D-1635EF7E3136}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Folly", "..\node_modules\react-native-windows\Folly\Folly.vcxproj", "{A990658C-CE31-4BCC-976F-0FC6B1AF693D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmt", "..\node_modules\react-native-windows\fmt\fmt.vcxproj", "{14B93DC8-FD93-4A6D-81CB-8BC96644501C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReactCommon", "..\node_modules\react-native-windows\ReactCommon\ReactCommon.vcxproj", "{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}"
ProjectSection(ProjectDependencies) = postProject
{A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {A990658C-CE31-4BCC-976F-0FC6B1AF693D}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Chakra", "..\node_modules\react-native-windows\Chakra\Chakra.vcxitems", "{C38970C0-5FBF-4D69-90D8-CBAC225AE895}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative", "..\node_modules\react-native-windows\Microsoft.ReactNative\Microsoft.ReactNative.vcxproj", "{F7D32BD0-2749-483E-9A0D-1635EF7E3136}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative.Cxx", "..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems", "{DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Common", "..\node_modules\react-native-windows\Common\Common.vcxproj", "{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ReactNative", "ReactNative", "{5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.ReactNative.Shared", "..\node_modules\react-native-windows\Shared\Shared.vcxitems", "{2049DBE9-8D13-42C9-AE4B-413AE38FFFD0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Mso", "..\node_modules\react-native-windows\Mso\Mso.vcxitems", "{84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Include", "..\node_modules\react-native-windows\include\Include.vcxitems", "{EF074BA1-2D54-4D49-A28E-5E040B47CD2E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RNSVG", "..\node_modules\react-native-svg\windows\RNSVG\RNSVG.vcxproj", "{7ACF84EC-EFBA-4043-8E14-40B159508902}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Debug|ARM64.ActiveCfg = Debug|ARM64
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Debug|ARM64.Build.0 = Debug|ARM64
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Debug|ARM64.Deploy.0 = Debug|ARM64
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Debug|x64.ActiveCfg = Debug|x64
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Debug|x64.Build.0 = Debug|x64
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Debug|x64.Deploy.0 = Debug|x64
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Debug|x86.ActiveCfg = Debug|x86
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Debug|x86.Build.0 = Debug|x86
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Debug|x86.Deploy.0 = Debug|x86
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Release|ARM64.ActiveCfg = Release|ARM64
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Release|ARM64.Build.0 = Release|ARM64
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Release|ARM64.Deploy.0 = Release|ARM64
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Release|x64.ActiveCfg = Release|x64
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Release|x64.Build.0 = Release|x64
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Release|x64.Deploy.0 = Release|x64
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Release|x86.ActiveCfg = Release|x86
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Release|x86.Build.0 = Release|x86
{9CF487C7-8A97-4DF0-AC99-D53CFCF1D59B}.Release|x86.Deploy.0 = Release|x86
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Debug|ARM64.ActiveCfg = Debug|ARM64
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Debug|ARM64.Build.0 = Debug|ARM64
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Debug|ARM64.Deploy.0 = Debug|ARM64
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Debug|x64.ActiveCfg = Debug|x64
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Debug|x64.Build.0 = Debug|x64
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Debug|x64.Deploy.0 = Debug|x64
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Debug|x86.ActiveCfg = Debug|Win32
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Debug|x86.Build.0 = Debug|Win32
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Debug|x86.Deploy.0 = Debug|Win32
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Release|ARM64.ActiveCfg = Release|ARM64
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Release|ARM64.Build.0 = Release|ARM64
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Release|ARM64.Deploy.0 = Release|ARM64
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Release|x64.ActiveCfg = Release|x64
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Release|x64.Build.0 = Release|x64
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Release|x64.Deploy.0 = Release|x64
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Release|x86.ActiveCfg = Release|Win32
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Release|x86.Build.0 = Release|Win32
{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}.Release|x86.Deploy.0 = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.Build.0 = Debug|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.ActiveCfg = Debug|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.Build.0 = Debug|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.ActiveCfg = Debug|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x86.Build.0 = Debug|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.ActiveCfg = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|ARM64.Build.0 = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.ActiveCfg = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.Build.0 = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.ActiveCfg = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.Build.0 = Release|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|ARM64.ActiveCfg = Debug|ARM64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|ARM64.Build.0 = Debug|ARM64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x64.ActiveCfg = Debug|x64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x64.Build.0 = Debug|x64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.ActiveCfg = Debug|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.Build.0 = Debug|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.Deploy.0 = Debug|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|ARM64.ActiveCfg = Release|ARM64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|ARM64.Build.0 = Release|ARM64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x64.ActiveCfg = Release|x64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x64.Build.0 = Release|x64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.ActiveCfg = Release|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.Build.0 = Release|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.Deploy.0 = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.Build.0 = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.ActiveCfg = Debug|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.Build.0 = Debug|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.ActiveCfg = Debug|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x86.Build.0 = Debug|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.ActiveCfg = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|ARM64.Build.0 = Release|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.ActiveCfg = Release|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x64.Build.0 = Release|x64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.ActiveCfg = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Release|x86.Build.0 = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.ActiveCfg = Debug|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|ARM64.Build.0 = Debug|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.ActiveCfg = Debug|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x64.Build.0 = Debug|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.ActiveCfg = Debug|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Debug|x86.Build.0 = Debug|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.ActiveCfg = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|ARM64.Build.0 = Release|ARM64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.ActiveCfg = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x64.Build.0 = Release|x64
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.ActiveCfg = Release|Win32
{F7D32BD0-2749-483E-9A0D-1635EF7E3136}.Release|x86.Build.0 = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|ARM64.Build.0 = Debug|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.ActiveCfg = Debug|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x64.Build.0 = Debug|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.ActiveCfg = Debug|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Debug|x86.Build.0 = Debug|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.ActiveCfg = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|ARM64.Build.0 = Release|ARM64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.ActiveCfg = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.Build.0 = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.ActiveCfg = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.Build.0 = Release|Win32
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Debug|ARM64.ActiveCfg = Debug|ARM64
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Debug|ARM64.Build.0 = Debug|ARM64
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Debug|x64.ActiveCfg = Debug|x64
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Debug|x64.Build.0 = Debug|x64
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Debug|x86.ActiveCfg = Debug|Win32
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Debug|x86.Build.0 = Debug|Win32
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Debug|x86.Deploy.0 = Debug|Win32
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Release|ARM64.ActiveCfg = Release|ARM64
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Release|ARM64.Build.0 = Release|ARM64
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Release|x64.ActiveCfg = Release|x64
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Release|x64.Build.0 = Release|x64
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Release|x86.ActiveCfg = Release|Win32
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Release|x86.Build.0 = Release|Win32
{85E8B53A-3B4C-40A6-97D7-67CA7082EC78}.Release|x86.Deploy.0 = Release|Win32
{7ACF84EC-EFBA-4043-8E14-40B159508902}.Debug|ARM64.ActiveCfg = Debug|ARM64
{7ACF84EC-EFBA-4043-8E14-40B159508902}.Debug|ARM64.Build.0 = Debug|ARM64
{7ACF84EC-EFBA-4043-8E14-40B159508902}.Debug|x64.ActiveCfg = Debug|x64
{7ACF84EC-EFBA-4043-8E14-40B159508902}.Debug|x64.Build.0 = Debug|x64
{7ACF84EC-EFBA-4043-8E14-40B159508902}.Debug|x86.ActiveCfg = Debug|Win32
{7ACF84EC-EFBA-4043-8E14-40B159508902}.Debug|x86.Build.0 = Debug|Win32
{7ACF84EC-EFBA-4043-8E14-40B159508902}.Release|ARM64.ActiveCfg = Release|ARM64
{7ACF84EC-EFBA-4043-8E14-40B159508902}.Release|ARM64.Build.0 = Release|ARM64
{7ACF84EC-EFBA-4043-8E14-40B159508902}.Release|x64.ActiveCfg = Release|x64
{7ACF84EC-EFBA-4043-8E14-40B159508902}.Release|x64.Build.0 = Release|x64
{7ACF84EC-EFBA-4043-8E14-40B159508902}.Release|x86.ActiveCfg = Release|Win32
{7ACF84EC-EFBA-4043-8E14-40B159508902}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{14B93DC8-FD93-4A6D-81CB-8BC96644501C} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{C38970C0-5FBF-4D69-90D8-CBAC225AE895} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{F7D32BD0-2749-483E-9A0D-1635EF7E3136} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{DA8B35B3-DA00-4B02-BDE6-6A397B3FD46B} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{2049DBE9-8D13-42C9-AE4B-413AE38FFFD0} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{EF074BA1-2D54-4D49-A28E-5E040B47CD2E} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D43FAD39-F619-437D-BB40-04A3982ACB6A}
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
..\node_modules\react-native-windows\Shared\Shared.vcxitems*{2049dbe9-8d13-42c9-ae4b-413ae38fffd0}*SharedItemsImports = 9
..\node_modules\react-native-windows\Mso\Mso.vcxitems*{84e05bfa-cbaf-4f0d-bfb6-4ce85742a57e}*SharedItemsImports = 9
..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{c38970c0-5fbf-4d69-90d8-cbac225ae895}*SharedItemsImports = 9
..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{da8b35b3-da00-4b02-bde6-6a397b3fd46b}*SharedItemsImports = 9
..\node_modules\react-native-windows\include\Include.vcxitems*{ef074ba1-2d54-4d49-a28e-5e040b47cd2e}*SharedItemsImports = 9
..\node_modules\react-native-windows\Chakra\Chakra.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
..\node_modules\react-native-windows\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
..\node_modules\react-native-windows\Mso\Mso.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
..\node_modules\react-native-windows\Shared\Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1 @@
/Bundle

View File

@@ -0,0 +1,18 @@
// AutolinkedNativeModules.g.cpp contents generated by "react-native autolink-windows"
// clang-format off
#include "pch.h"
#include "AutolinkedNativeModules.g.h"
// Includes from react-native-svg
#include <winrt/RNSVG.h>
namespace winrt::Microsoft::ReactNative
{
void RegisterAutolinkedNativeModulePackages(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::ReactNative::IReactPackageProvider> const& packageProviders)
{
// IReactPackageProviders from react-native-svg
packageProviders.Append(winrt::RNSVG::ReactPackageProvider());
}
}

View File

@@ -0,0 +1,10 @@
// AutolinkedNativeModules.g.h contents generated by "react-native autolink-windows"
// clang-format off
#pragma once
namespace winrt::Microsoft::ReactNative
{
void RegisterAutolinkedNativeModulePackages(winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::ReactNative::IReactPackageProvider> const& packageProviders);
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- AutolinkedNativeModules.g.props contents generated by "react-native autolink-windows" -->
<PropertyGroup>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- AutolinkedNativeModules.g.targets contents generated by "react-native autolink-windows" -->
<ItemGroup>
<!-- Projects from react-native-svg -->
<ProjectReference Include="$(ProjectDir)..\..\node_modules\react-native-svg\windows\RNSVG\RNSVG.vcxproj">
<Project>{7acf84ec-efba-4043-8e14-40b159508902}</Project>
</ProjectReference>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,165 @@
// FabricExample.cpp : Defines the entry point for the application.
//
#include "pch.h"
#include "FabricExample.h"
#include "AutolinkedNativeModules.g.h"
#include "NativeModules.h"
struct CompReactPackageProvider
: winrt::implements<CompReactPackageProvider, winrt::Microsoft::ReactNative::IReactPackageProvider> {
public: // IReactPackageProvider
void CreatePackage(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept {
AddAttributedModules(packageBuilder, true);
}
};
// Global Variables:
constexpr PCWSTR windowTitle = L"FabricExample";
constexpr PCWSTR mainComponentName = L"FabricExample";
float ScaleFactor(HWND hwnd) noexcept {
return GetDpiForWindow(hwnd) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
}
void UpdateRootViewSizeToAppWindow(
winrt::Microsoft::ReactNative::ReactNativeIsland const &rootView,
winrt::Microsoft::UI::Windowing::AppWindow const &window) {
auto hwnd = winrt::Microsoft::UI::GetWindowFromWindowId(window.Id());
auto scaleFactor = ScaleFactor(hwnd);
winrt::Windows::Foundation::Size size{
window.ClientSize().Width / scaleFactor, window.ClientSize().Height / scaleFactor};
// Do not relayout when minimized
if (window.Presenter().as<winrt::Microsoft::UI::Windowing::OverlappedPresenter>().State() !=
winrt::Microsoft::UI::Windowing::OverlappedPresenterState::Minimized) {
winrt::Microsoft::ReactNative::LayoutConstraints constraints;
constraints.MaximumSize = constraints.MinimumSize = size;
rootView.Arrange(constraints, {0, 0});
}
}
// Create and configure the ReactNativeHost
winrt::Microsoft::ReactNative::ReactNativeHost CreateReactNativeHost(
HWND hwnd,
const winrt::Microsoft::UI::Composition::Compositor &compositor) {
WCHAR appDirectory[MAX_PATH];
GetModuleFileNameW(NULL, appDirectory, MAX_PATH);
PathCchRemoveFileSpec(appDirectory, MAX_PATH);
auto host = winrt::Microsoft::ReactNative::ReactNativeHost();
// Include any autolinked modules
RegisterAutolinkedNativeModulePackages(host.PackageProviders());
host.PackageProviders().Append(winrt::make<CompReactPackageProvider>());
#if BUNDLE
host.InstanceSettings().JavaScriptBundleFile(L"index.windows");
host.InstanceSettings().BundleRootPath(std::wstring(L"file://").append(appDirectory).append(L"\\Bundle\\").c_str());
host.InstanceSettings().UseFastRefresh(false);
#else
host.InstanceSettings().JavaScriptBundleFile(L"index");
host.InstanceSettings().UseFastRefresh(true);
#endif
#if _DEBUG
host.InstanceSettings().UseDirectDebugger(true);
host.InstanceSettings().UseDeveloperSupport(true);
#else
host.InstanceSettings().UseDirectDebugger(false);
host.InstanceSettings().UseDeveloperSupport(false);
#endif
winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
host.InstanceSettings().Properties(), reinterpret_cast<uint64_t>(hwnd));
winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositor(
host.InstanceSettings(), compositor);
return host;
}
_Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE, PSTR /* commandLine */, int showCmd) {
// Initialize WinRT.
winrt::init_apartment(winrt::apartment_type::single_threaded);
// Enable per monitor DPI scaling
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
// Create a DispatcherQueue for this thread. This is needed for Composition, Content, and
// Input APIs.
auto dispatcherQueueController{winrt::Microsoft::UI::Dispatching::DispatcherQueueController::CreateOnCurrentThread()};
// Create a Compositor for all Content on this thread.
auto compositor{winrt::Microsoft::UI::Composition::Compositor()};
// Create a top-level window.
auto window = winrt::Microsoft::UI::Windowing::AppWindow::Create();
window.Title(windowTitle);
window.Resize({1000, 1000});
window.Show();
auto hwnd = winrt::Microsoft::UI::GetWindowFromWindowId(window.Id());
auto scaleFactor = ScaleFactor(hwnd);
auto host = CreateReactNativeHost(hwnd, compositor);
// Start the react-native instance, which will create a JavaScript runtime and load the applications bundle
host.ReloadInstance();
// Create a RootView which will present a react-native component
winrt::Microsoft::ReactNative::ReactViewOptions viewOptions;
viewOptions.ComponentName(mainComponentName);
auto rootView = winrt::Microsoft::ReactNative::ReactNativeIsland(compositor);
rootView.ReactViewHost(winrt::Microsoft::ReactNative::ReactCoreInjection::MakeViewHost(host, viewOptions));
// Update the size of the RootView when the AppWindow changes size
window.Changed([wkRootView = winrt::make_weak(rootView)](
winrt::Microsoft::UI::Windowing::AppWindow const &window,
winrt::Microsoft::UI::Windowing::AppWindowChangedEventArgs const &args) {
if (args.DidSizeChange() || args.DidVisibilityChange()) {
if (auto rootView = wkRootView.get()) {
UpdateRootViewSizeToAppWindow(rootView, window);
}
}
});
// Quit application when main window is closed
window.Destroying(
[host](winrt::Microsoft::UI::Windowing::AppWindow const &window, winrt::IInspectable const & /*args*/) {
// Before we shutdown the application - unload the ReactNativeHost to give the javascript a chance to save any
// state
auto async = host.UnloadInstance();
async.Completed([host](auto asyncInfo, winrt::Windows::Foundation::AsyncStatus asyncStatus) {
assert(asyncStatus == winrt::Windows::Foundation::AsyncStatus::Completed);
host.InstanceSettings().UIDispatcher().Post([]() { PostQuitMessage(0); });
});
});
// DesktopChildSiteBridge create a ContentSite that can host the RootView ContentIsland
auto bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(compositor, window.Id());
bridge.Connect(rootView.Island());
bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
rootView.ScaleFactor(scaleFactor);
// Set the intialSize of the root view
UpdateRootViewSizeToAppWindow(rootView, window);
bridge.Show();
// Run the main application event loop
dispatcherQueueController.DispatcherQueue().RunEventLoop();
// Rundown the DispatcherQueue. This drains the queue and raises events to let components
// know the message loop has finished.
dispatcherQueueController.ShutdownQueue();
bridge.Close();
bridge = nullptr;
// Destroy all Composition objects
compositor.Close();
compositor = nullptr;
}

View File

@@ -0,0 +1,3 @@
#pragma once
#include "resource.h"

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This project was created with react-native-windows 0.74.1 -->
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)\ExperimentalFeatures.props" Condition="Exists('$(SolutionDir)\ExperimentalFeatures.props')" />
<PropertyGroup Label="Globals">
<CppWinRTOptimized>true</CppWinRTOptimized>
<MinimalCoreWin>true</MinimalCoreWin>
<ProjectGuid>{BD8F3BA2-CD81-4BA7-BAA0-B76D6E9EA0C4}</ProjectGuid>
<ProjectName>FabricExample</ProjectName>
<Keyword>Win32Proj</Keyword>
<RootNamespace>FabricExample</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>17.0</MinimumVisualStudioVersion>
<AppxPackage>false</AppxPackage>
</PropertyGroup>
<PropertyGroup Label="ReactNativeWindowsProps">
<ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
</PropertyGroup>
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.WindowsSdk.Default.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="ReactNativeWindowsPropertySheets">
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.props" />
</ImportGroup>
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>shell32.lib;user32.lib;windowsapp.lib;%(AdditionalDependenices)</AdditionalDependencies>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions Condition="'$(UseFabric)'=='true'">USE_FABRIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<PropertyGroup Label="UserMacros" />
<ItemGroup>
<ClInclude Include="FabricExample.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="AutolinkedNativeModules.g.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="FabricExample.cpp" />
<ClCompile Include="AutolinkedNativeModules.g.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="FabricExample.rc" />
</ItemGroup>
<ItemGroup>
<Image Include="FabricExample.ico" />
<Image Include="small.ico" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ReactNativeWindowsTargets">
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.targets" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.targets')" />
</ImportGroup>
<ItemGroup>
</ItemGroup>
<Target Name="EnsureReactNativeWindowsTargets" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references targets in your node_modules\react-native-windows folder. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.props')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.props'))" />
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppApp.targets'))" />
</Target>
</Project>

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FabricExample.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="AutolinkedNativeModules.g.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="FabricExample.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="AutolinkedNativeModules.g.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="FabricExample.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Image Include="small.ico">
<Filter>Resource Files</Filter>
</Image>
<Image Include="FabricExample.ico">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,156 @@
{
"version": 1,
"dependencies": {
"native,Version=v0.0": {
"boost": {
"type": "Direct",
"requested": "[1.76.0, )",
"resolved": "1.76.0",
"contentHash": "p+w3YvNdXL8Cu9Fzrmexssu0tZbWxuf6ywsQqHjDlKFE5ojXHof1HIyMC3zDLfLnh80dIeFcEUAuR2Asg/XHRA=="
},
"Microsoft.JavaScript.Hermes": {
"type": "Direct",
"requested": "[0.1.21, )",
"resolved": "0.1.21",
"contentHash": "5njCh+3eXTLOv7+8nOnp6nJ5C0r6it5ze54c0nuWleeDptuK8t3dEDB79XTU4D5DKNvAPlqJpgXRDOak5nYIug=="
},
"Microsoft.VCRTForwarders.140": {
"type": "Direct",
"requested": "[1.0.2-rc, )",
"resolved": "1.0.2-rc",
"contentHash": "/r+sjtEeCIGyDhobIZ5hSmYhC/dSyGZxf1SxYJpElUhB0LMCktOMFs9gXrauXypIFECpVynNyVjAmJt6hjJ5oQ=="
},
"Microsoft.Windows.CppWinRT": {
"type": "Direct",
"requested": "[2.0.230706.1, )",
"resolved": "2.0.230706.1",
"contentHash": "l0D7oCw/5X+xIKHqZTi62TtV+1qeSz7KVluNFdrJ9hXsst4ghvqQ/Yhura7JqRdZWBXAuDS0G0KwALptdoxweQ=="
},
"Microsoft.WindowsAppSDK": {
"type": "Direct",
"requested": "[1.5.240227000, )",
"resolved": "1.5.240227000",
"contentHash": "6rESOsREi8534J7IDpNfFYPvxQaSleXKt4A7ZYPeQyckNMQ0o1W0jZ420bJbEMz9Cw/S/8IbpPftLLZ9w/GTCQ==",
"dependencies": {
"Microsoft.Windows.SDK.BuildTools": "10.0.22621.756"
}
},
"Microsoft.Windows.SDK.BuildTools": {
"type": "Transitive",
"resolved": "10.0.22621.756",
"contentHash": "7ZL2sFSioYm1Ry067Kw1hg0SCcW5kuVezC2SwjGbcPE61Nn+gTbH86T73G3LcEOVj0S3IZzNuE/29gZvOLS7VA=="
},
"common": {
"type": "Project",
"dependencies": {
"boost": "[1.76.0, )"
}
},
"fmt": {
"type": "Project"
},
"folly": {
"type": "Project",
"dependencies": {
"Fmt": "[1.0.0, )",
"boost": "[1.76.0, )"
}
},
"microsoft.reactnative": {
"type": "Project",
"dependencies": {
"Common": "[1.0.0, )",
"Folly": "[1.0.0, )",
"Microsoft.JavaScript.Hermes": "[0.1.21, )",
"Microsoft.WindowsAppSDK": "[1.5.240227000, )",
"ReactCommon": "[1.0.0, )",
"boost": "[1.76.0, )"
}
},
"reactcommon": {
"type": "Project",
"dependencies": {
"Folly": "[1.0.0, )",
"boost": "[1.76.0, )"
}
},
"rnsvg": {
"type": "Project",
"dependencies": {
"Microsoft.ReactNative": "[1.0.0, )",
"Microsoft.VCRTForwarders.140": "[1.0.2-rc, )",
"Microsoft.WindowsAppSDK": "[1.5.240227000, )",
"boost": "[1.76.0, )"
}
}
},
"native,Version=v0.0/win": {
"Microsoft.VCRTForwarders.140": {
"type": "Direct",
"requested": "[1.0.2-rc, )",
"resolved": "1.0.2-rc",
"contentHash": "/r+sjtEeCIGyDhobIZ5hSmYhC/dSyGZxf1SxYJpElUhB0LMCktOMFs9gXrauXypIFECpVynNyVjAmJt6hjJ5oQ=="
},
"Microsoft.WindowsAppSDK": {
"type": "Direct",
"requested": "[1.5.240227000, )",
"resolved": "1.5.240227000",
"contentHash": "6rESOsREi8534J7IDpNfFYPvxQaSleXKt4A7ZYPeQyckNMQ0o1W0jZ420bJbEMz9Cw/S/8IbpPftLLZ9w/GTCQ==",
"dependencies": {
"Microsoft.Windows.SDK.BuildTools": "10.0.22621.756"
}
}
},
"native,Version=v0.0/win-arm64": {
"Microsoft.VCRTForwarders.140": {
"type": "Direct",
"requested": "[1.0.2-rc, )",
"resolved": "1.0.2-rc",
"contentHash": "/r+sjtEeCIGyDhobIZ5hSmYhC/dSyGZxf1SxYJpElUhB0LMCktOMFs9gXrauXypIFECpVynNyVjAmJt6hjJ5oQ=="
},
"Microsoft.WindowsAppSDK": {
"type": "Direct",
"requested": "[1.5.240227000, )",
"resolved": "1.5.240227000",
"contentHash": "6rESOsREi8534J7IDpNfFYPvxQaSleXKt4A7ZYPeQyckNMQ0o1W0jZ420bJbEMz9Cw/S/8IbpPftLLZ9w/GTCQ==",
"dependencies": {
"Microsoft.Windows.SDK.BuildTools": "10.0.22621.756"
}
}
},
"native,Version=v0.0/win-x64": {
"Microsoft.VCRTForwarders.140": {
"type": "Direct",
"requested": "[1.0.2-rc, )",
"resolved": "1.0.2-rc",
"contentHash": "/r+sjtEeCIGyDhobIZ5hSmYhC/dSyGZxf1SxYJpElUhB0LMCktOMFs9gXrauXypIFECpVynNyVjAmJt6hjJ5oQ=="
},
"Microsoft.WindowsAppSDK": {
"type": "Direct",
"requested": "[1.5.240227000, )",
"resolved": "1.5.240227000",
"contentHash": "6rESOsREi8534J7IDpNfFYPvxQaSleXKt4A7ZYPeQyckNMQ0o1W0jZ420bJbEMz9Cw/S/8IbpPftLLZ9w/GTCQ==",
"dependencies": {
"Microsoft.Windows.SDK.BuildTools": "10.0.22621.756"
}
}
},
"native,Version=v0.0/win-x86": {
"Microsoft.VCRTForwarders.140": {
"type": "Direct",
"requested": "[1.0.2-rc, )",
"resolved": "1.0.2-rc",
"contentHash": "/r+sjtEeCIGyDhobIZ5hSmYhC/dSyGZxf1SxYJpElUhB0LMCktOMFs9gXrauXypIFECpVynNyVjAmJt6hjJ5oQ=="
},
"Microsoft.WindowsAppSDK": {
"type": "Direct",
"requested": "[1.5.240227000, )",
"resolved": "1.5.240227000",
"contentHash": "6rESOsREi8534J7IDpNfFYPvxQaSleXKt4A7ZYPeQyckNMQ0o1W0jZ420bJbEMz9Cw/S/8IbpPftLLZ9w/GTCQ==",
"dependencies": {
"Microsoft.Windows.SDK.BuildTools": "10.0.22621.756"
}
}
}
}
}

View File

@@ -0,0 +1 @@
#include "pch.h"

View File

@@ -0,0 +1,38 @@
// pch.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#define NOMINMAX 1
#define WIN32_LEAN_AND_MEAN 1
#define WINRT_LEAN_AND_MEAN 1
// Windows Header Files
#include <windows.h>
#undef GetCurrentTime
#include <pathcch.h>
#include <unknwn.h>
// WinRT Header Files
#include <winrt/base.h>
#include <CppWinRTIncludes.h>
#include <winrt/Microsoft.ReactNative.Composition.h>
#include <winrt/Microsoft.ReactNative.h>
#include <winrt/Microsoft.UI.Composition.h>
#include <winrt/Microsoft.UI.Content.h>
#include <winrt/Microsoft.UI.Dispatching.h>
#include <winrt/Microsoft.UI.Windowing.h>
#include <winrt/Microsoft.UI.interop.h>
// C RunTime Header Files
#include <malloc.h>
#include <memory.h>
#include <stdlib.h>
#include <tchar.h>
// Reference additional headers your project requires here

View File

@@ -0,0 +1,17 @@
//
// Microsoft Visual C++ generated include file.
// Used by FabricExample.rc
#define IDI_ICON1 1008
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 130
#define _APS_NEXT_RESOURCE_VALUE 129
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

View File

@@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,18 @@
#include "pch.h"
#include "BrushView.h"
#if __has_include("BrushView.g.cpp")
#include "BrushView.g.cpp"
#endif
#include "D2DHelpers.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
BrushView::BrushView(
const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
#endif
void BrushView::SaveDefinition() {
if (auto const &root{SvgRoot()}) {
CreateBrush();
@@ -21,7 +29,7 @@ void BrushView::Unload() {
if (m_brush) {
m_brush = nullptr;
}
__super::Unload();
}
} // namespace winrt::RNSVG::implementation

View File

@@ -8,6 +8,11 @@ struct BrushView : BrushViewT<BrushView, RNSVG::implementation::GroupView> {
public:
BrushView() = default;
#ifdef USE_FABRIC
BrushView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
#endif
// IRenderable
void SaveDefinition();
RNSVG::D2DBrush Brush() { return m_brush; }

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "CircleView.h"
#if __has_include("CircleView.g.cpp")
#include "CircleView.g.cpp"
#endif
#include "JSValueXaml.h"
#include "Utils.h"
@@ -9,6 +11,48 @@ using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
CircleProps::CircleProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void CircleProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
CircleView::CircleView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
void CircleView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGCircle", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::CircleProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::CircleView>(args);
});
});
}
void CircleView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto circleProps = props.try_as<CircleProps>();
if (circleProps) {
m_props = circleProps;
m_cx = m_props->cx;
m_cy = m_props->cy;
m_r = m_props->r;
}
base_type::UpdateProperties(props, oldProps, forceUpdate, invalidate);
}
#else
void CircleView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, bool invalidate) {
const JSValueObject &propertyMap{JSValue::ReadObjectFrom(reader)};
@@ -17,25 +61,29 @@ void CircleView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate
auto const &propertyValue{pair.second};
if (propertyName == "r") {
m_r = SVGLength::From(propertyValue);
m_r = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "cx") {
m_cx = SVGLength::From(propertyValue);
m_cx = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "cy") {
m_cy = SVGLength::From(propertyValue);
m_cy = propertyValue.To<RNSVG::SVGLength>();
}
}
__super::UpdateProperties(reader, forceUpdate, invalidate);
}
#endif
void CircleView::CreateGeometry() {
void CircleView::CreateGeometry(RNSVG::D2DDeviceContext const &context) {
auto const root{SvgRoot()};
float cx{Utils::GetAbsoluteLength(m_cx, root.ActualWidth())};
float cy{Utils::GetAbsoluteLength(m_cy, root.ActualHeight())};
float r{Utils::GetAbsoluteLength(m_r, Utils::GetCanvasDiagonal(root.ActualSize()))};
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(root.DeviceContext())->Get()};
float width{root.CanvasSize().Width};
float height{root.CanvasSize().Height};
float cx{Utils::GetAbsoluteLength(m_cx, width)};
float cy{Utils::GetAbsoluteLength(m_cy, height)};
float r{Utils::GetAbsoluteLength(m_r, Utils::GetCanvasDiagonal(root.CanvasSize()))};
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(context)->Get()};
com_ptr<ID2D1Factory> factory;
deviceContext->GetFactory(factory.put());

View File

@@ -1,18 +1,65 @@
#pragma once
#ifdef USE_FABRIC
#include "CircleProps.g.h"
#endif
#include "CircleView.g.h"
#include "RenderableView.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(CircleProps)
struct CircleProps : CirclePropsT<CircleProps, SvgRenderableCommonProps> {
CircleProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_FIELD(r)
RNSVG::SVGLength r{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(cx)
RNSVG::SVGLength cx{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(cy)
RNSVG::SVGLength cy{0, winrt::RNSVG::LengthType::Unknown};
};
#endif
struct CircleView : CircleViewT<CircleView, RNSVG::implementation::RenderableView> {
public:
CircleView() = default;
#ifdef USE_FABRIC
CircleView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept override;
#else
// IRenderablePaper
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate, bool invalidate);
void CreateGeometry();
#endif
// IRenderable
void CreateGeometry(RNSVG::D2DDeviceContext const &context);
private:
RNSVG::SVGLength m_r{};
RNSVG::SVGLength m_cx{};
RNSVG::SVGLength m_cy{};
#ifdef USE_FABRIC
com_ptr<CircleProps> m_props;
#endif
};
} // namespace winrt::RNSVG::implementation
namespace winrt::RNSVG::factory_implementation {

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "CircleViewManager.h"
#if __has_include("CircleViewManager.g.cpp")
#include "CircleViewManager.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::ReactNative;

View File

@@ -1,9 +1,34 @@
#include "pch.h"
#include "ClipPathView.h"
#if __has_include("ClipPathView.g.cpp")
#include "ClipPathView.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
ClipPathProps::ClipPathProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void ClipPathProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
ClipPathView::ClipPathView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
void ClipPathView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGClipPath", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::ClipPathProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::ClipPathView>(args);
});
});
}
#endif
} // namespace winrt::RNSVG::implementation

View File

@@ -1,13 +1,37 @@
#pragma once
#ifdef USE_FABRIC
#include "ClipPathProps.g.h"
#endif
#include "ClipPathView.g.h"
#include "GroupView.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(ClipPathProps)
struct ClipPathProps : ClipPathPropsT<ClipPathProps, SvgGroupCommonProps> {
ClipPathProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_SVG_GROUP_COMMON_PROPS;
};
#endif
struct ClipPathView : ClipPathViewT<ClipPathView, RNSVG::implementation::GroupView> {
public:
ClipPathView() = default;
// RenderableView
#ifdef USE_FABRIC
ClipPathView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
#endif
// IRenderable
void Draw(RNSVG::D2DDeviceContext const & /*deviceContext*/, Windows::Foundation::Size const & /*size*/){};
};
} // namespace winrt::RNSVG::implementation

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "ClipPathViewManager.h"
#if __has_include("ClipPathViewManager.g.cpp")
#include "ClipPathViewManager.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::ReactNative;

View File

@@ -8,7 +8,7 @@ namespace winrt::RNSVG {
struct D2DHelpers {
public:
static void PushOpacityLayer(
static void PushOpacityLayer(
ID2D1DeviceContext *deviceContext,
ID2D1Geometry *clipPathGeometry,
float opacity) {
@@ -25,7 +25,7 @@ struct D2DHelpers {
deviceContext->PushLayer(layerParams, opacityLayer.get());
}
static void PushOpacityLayer(
static void PushOpacityLayer(
ID2D1DeviceContext *deviceContext,
ID2D1Geometry *clipPathGeometry,
float opacity,
@@ -42,185 +42,191 @@ struct D2DHelpers {
}
deviceContext->PushLayer(layerParams, opacityLayer.get());
}
}
static D2D1_CAP_STYLE GetLineCap(RNSVG::LineCap const &lineCap) {
switch (lineCap) {
case RNSVG::LineCap::Square:
return D2D1_CAP_STYLE_SQUARE;
case RNSVG::LineCap::Round:
return D2D1_CAP_STYLE_ROUND;
case RNSVG::LineCap::Butt:
default:
return D2D1_CAP_STYLE_FLAT;
}
}
static D2D1_CAP_STYLE GetLineCap(RNSVG::LineCap const &lineCap) {
switch (lineCap) {
case RNSVG::LineCap::Square:
return D2D1_CAP_STYLE_SQUARE;
case RNSVG::LineCap::Round:
return D2D1_CAP_STYLE_ROUND;
case RNSVG::LineCap::Butt:
default:
return D2D1_CAP_STYLE_FLAT;
}
}
static D2D1_LINE_JOIN GetLineJoin(RNSVG::LineJoin const &lineJoin) {
switch (lineJoin) {
case RNSVG::LineJoin::Bevel:
return D2D1_LINE_JOIN_BEVEL;
case RNSVG::LineJoin::Round:
return D2D1_LINE_JOIN_ROUND;
case RNSVG::LineJoin::Miter:
default:
return D2D1_LINE_JOIN_MITER;
}
}
static D2D1_LINE_JOIN GetLineJoin(RNSVG::LineJoin const &lineJoin) {
switch (lineJoin) {
case RNSVG::LineJoin::Bevel:
return D2D1_LINE_JOIN_BEVEL;
case RNSVG::LineJoin::Round:
return D2D1_LINE_JOIN_ROUND;
case RNSVG::LineJoin::Miter:
default:
return D2D1_LINE_JOIN_MITER;
}
}
static D2D1_FILL_MODE GetFillRule(RNSVG::FillRule const &fillRule) {
switch (fillRule) {
case RNSVG::FillRule::EvenOdd:
return D2D1_FILL_MODE_ALTERNATE;
case RNSVG::FillRule::NonZero:
default:
return D2D1_FILL_MODE_WINDING;
}
}
static D2D1_FILL_MODE GetFillRule(RNSVG::FillRule const &fillRule) {
switch (fillRule) {
case RNSVG::FillRule::EvenOdd:
return D2D1_FILL_MODE_ALTERNATE;
case RNSVG::FillRule::NonZero:
default:
return D2D1_FILL_MODE_WINDING;
}
}
static D2D1::ColorF AsD2DColor(Windows::UI::Color const &color) {
return {
color.R / 255.0f,
color.G / 255.0f,
color.B / 255.0f,
color.A / 255.0f};
}
static D2D1::ColorF AsD2DColor(winrt::Windows::UI::Color const &color) {
return {
color.R / 255.0f,
color.G / 255.0f,
color.B / 255.0f,
color.A / 255.0f};
}
static Windows::UI::Color FromD2DColor(D2D1::ColorF const color) {
return Windows::UI::Color{
static_cast<uint8_t>(color.a),
static_cast<uint8_t>(color.r),
static_cast<uint8_t>(color.g),
static_cast<uint8_t>(color.b),
};
}
static winrt::Windows::UI::Color FromD2DColor(D2D1::ColorF const color) {
return winrt::Windows::UI::Color{
static_cast<uint8_t>(color.a * 255),
static_cast<uint8_t>(color.r * 255),
static_cast<uint8_t>(color.g * 255),
static_cast<uint8_t>(color.b * 255)};
}
static D2D1_RECT_F AsD2DRect(Rect const &rect) {
return {rect.X, rect.Y, rect.Width + rect.X, rect.Height + rect.Y};
}
static D2D1_RECT_F AsD2DRect(Rect const &rect) {
return {rect.X, rect.Y, rect.Width + rect.X, rect.Height + rect.Y};
}
static Rect FromD2DRect(D2D1_RECT_F const rect) {
return {rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top};
}
static Rect FromD2DRect(D2D1_RECT_F const rect) {
return {rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top};
}
static Size SizeFromD2DRect(D2D1_RECT_F const rect) {
return {rect.right - rect.left, rect.bottom - rect.top};
}
static Size SizeFromD2DRect(D2D1_RECT_F const rect) {
return {rect.right - rect.left, rect.bottom - rect.top};
}
static float WidthFromD2DRect(D2D1_RECT_F const rect) {
return rect.right - rect.left;
}
static float WidthFromD2DRect(D2D1_RECT_F const rect) {
return rect.right - rect.left;
}
static float HeightFromD2DRect(D2D1_RECT_F const rect) {
return rect.bottom - rect.top;
}
static float HeightFromD2DRect(D2D1_RECT_F const rect) {
return rect.bottom - rect.top;
}
static Numerics::float3x2 FromD2DTransform(D2D1_MATRIX_3X2_F const transform) {
return Numerics::float3x2(
transform.m11, transform.m12, transform.m21, transform.m22, transform._31, transform._32);
}
static Numerics::float3x2 FromD2DTransform(D2D1_MATRIX_3X2_F const transform) {
return Numerics::float3x2(
transform.m11, transform.m12, transform.m21, transform.m22, transform._31, transform._32);
}
static D2D1::Matrix3x2F AsD2DTransform(Numerics::float3x2 const &transform) {
return D2D1::Matrix3x2F(transform.m11, transform.m12, transform.m21, transform.m22, transform.m31, transform.m32);
}
static D2D1::Matrix3x2F AsD2DTransform(Numerics::float3x2 const &transform) {
return D2D1::Matrix3x2F(transform.m11, transform.m12, transform.m21, transform.m22, transform.m31, transform.m32);
}
static D2D1_MATRIX_3X2_F GetTransform(ID2D1DeviceContext* deviceContext) {
D2D1_MATRIX_3X2_F transform;
deviceContext->GetTransform(&transform);
static D2D1_MATRIX_3X2_F GetTransform(ID2D1DeviceContext *deviceContext) {
D2D1_MATRIX_3X2_F transform;
deviceContext->GetTransform(&transform);
return transform;
}
return transform;
}
static DWRITE_FONT_WEIGHT FontWeightFrom(hstring const &weight, xaml::FrameworkElement const &parent) {
if (weight == L"normal") {
return DWRITE_FONT_WEIGHT_NORMAL;
} else if (weight == L"bold") {
return DWRITE_FONT_WEIGHT_BOLD;
}
static DWRITE_FONT_WEIGHT FontWeightFrom(
#ifdef USE_FABRIC
winrt::Microsoft::ReactNative::ComponentView const &parent,
#else
xaml::FrameworkElement const &parent,
#endif
hstring const &weight) {
if (weight == L"normal") {
return DWRITE_FONT_WEIGHT_NORMAL;
} else if (weight == L"bold") {
return DWRITE_FONT_WEIGHT_BOLD;
}
auto const &groupView{parent.try_as<RNSVG::GroupView>()};
DWRITE_FONT_WEIGHT parentWeight{
groupView ? D2DHelpers::FontWeightFrom(groupView.FontWeight(), groupView.SvgParent()) : DWRITE_FONT_WEIGHT_NORMAL};
auto const &groupView{parent.try_as<RNSVG::GroupView>()};
DWRITE_FONT_WEIGHT parentWeight{
groupView ? D2DHelpers::FontWeightFrom(groupView.SvgParent(), groupView.FontWeight())
: DWRITE_FONT_WEIGHT_NORMAL};
if (weight == L"bolder") {
return D2DHelpers::Bolder(parentWeight);
} else if (weight == L"lighter") {
return D2DHelpers::Lighter(parentWeight);
} else if (weight == L"auto") {
return parentWeight;
}
if (weight == L"bolder") {
return D2DHelpers::Bolder(parentWeight);
} else if (weight == L"lighter") {
return D2DHelpers::Lighter(parentWeight);
} else if (weight == L"auto") {
return parentWeight;
}
return D2DHelpers::GetClosestFontWeight(std::stof(weight.c_str(), nullptr));
}
return D2DHelpers::GetClosestFontWeight(std::stof(weight.c_str(), nullptr));
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#meaning_of_relative_weights
static DWRITE_FONT_WEIGHT Bolder(DWRITE_FONT_WEIGHT weight) {
switch (weight) {
case DWRITE_FONT_WEIGHT_THIN:
case DWRITE_FONT_WEIGHT_EXTRA_LIGHT:
case DWRITE_FONT_WEIGHT_LIGHT:
case DWRITE_FONT_WEIGHT_SEMI_LIGHT:
return DWRITE_FONT_WEIGHT_NORMAL;
case DWRITE_FONT_WEIGHT_NORMAL:
case DWRITE_FONT_WEIGHT_MEDIUM:
case DWRITE_FONT_WEIGHT_SEMI_BOLD:
return DWRITE_FONT_WEIGHT_BOLD;
case DWRITE_FONT_WEIGHT_BOLD:
case DWRITE_FONT_WEIGHT_EXTRA_BOLD:
return DWRITE_FONT_WEIGHT_BLACK;
case DWRITE_FONT_WEIGHT_BLACK:
default:
return DWRITE_FONT_WEIGHT_EXTRA_BLACK;
}
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#meaning_of_relative_weights
static DWRITE_FONT_WEIGHT Bolder(DWRITE_FONT_WEIGHT weight) {
switch (weight) {
case DWRITE_FONT_WEIGHT_THIN:
case DWRITE_FONT_WEIGHT_EXTRA_LIGHT:
case DWRITE_FONT_WEIGHT_LIGHT:
case DWRITE_FONT_WEIGHT_SEMI_LIGHT:
return DWRITE_FONT_WEIGHT_NORMAL;
case DWRITE_FONT_WEIGHT_NORMAL:
case DWRITE_FONT_WEIGHT_MEDIUM:
case DWRITE_FONT_WEIGHT_SEMI_BOLD:
return DWRITE_FONT_WEIGHT_BOLD;
case DWRITE_FONT_WEIGHT_BOLD:
case DWRITE_FONT_WEIGHT_EXTRA_BOLD:
return DWRITE_FONT_WEIGHT_BLACK;
case DWRITE_FONT_WEIGHT_BLACK:
default:
return DWRITE_FONT_WEIGHT_EXTRA_BLACK;
}
}
static DWRITE_FONT_WEIGHT Lighter(DWRITE_FONT_WEIGHT weight) {
switch (weight) {
case DWRITE_FONT_WEIGHT_THIN:
case DWRITE_FONT_WEIGHT_EXTRA_LIGHT:
case DWRITE_FONT_WEIGHT_LIGHT:
case DWRITE_FONT_WEIGHT_SEMI_LIGHT:
case DWRITE_FONT_WEIGHT_NORMAL:
case DWRITE_FONT_WEIGHT_MEDIUM:
return DWRITE_FONT_WEIGHT_THIN;
case DWRITE_FONT_WEIGHT_SEMI_BOLD:
case DWRITE_FONT_WEIGHT_BOLD:
return DWRITE_FONT_WEIGHT_NORMAL;
case DWRITE_FONT_WEIGHT_EXTRA_BOLD:
case DWRITE_FONT_WEIGHT_BLACK:
default:
return DWRITE_FONT_WEIGHT_BOLD;
}
}
static DWRITE_FONT_WEIGHT Lighter(DWRITE_FONT_WEIGHT weight) {
switch (weight) {
case DWRITE_FONT_WEIGHT_THIN:
case DWRITE_FONT_WEIGHT_EXTRA_LIGHT:
case DWRITE_FONT_WEIGHT_LIGHT:
case DWRITE_FONT_WEIGHT_SEMI_LIGHT:
case DWRITE_FONT_WEIGHT_NORMAL:
case DWRITE_FONT_WEIGHT_MEDIUM:
return DWRITE_FONT_WEIGHT_THIN;
case DWRITE_FONT_WEIGHT_SEMI_BOLD:
case DWRITE_FONT_WEIGHT_BOLD:
return DWRITE_FONT_WEIGHT_NORMAL;
case DWRITE_FONT_WEIGHT_EXTRA_BOLD:
case DWRITE_FONT_WEIGHT_BLACK:
default:
return DWRITE_FONT_WEIGHT_BOLD;
}
}
static DWRITE_FONT_WEIGHT GetClosestFontWeight(float weight) {
if (weight > 325 && weight < 375) {
return DWRITE_FONT_WEIGHT_SEMI_LIGHT;
} else if (weight > 925) {
return DWRITE_FONT_WEIGHT_EXTRA_BLACK;
} else {
switch (static_cast<uint16_t>(std::round(weight / 100.0f))) {
case 1:
return DWRITE_FONT_WEIGHT_THIN;
case 2:
return DWRITE_FONT_WEIGHT_EXTRA_LIGHT;
case 3:
return DWRITE_FONT_WEIGHT_LIGHT;
case 4:
return DWRITE_FONT_WEIGHT_NORMAL;
case 5:
return DWRITE_FONT_WEIGHT_MEDIUM;
case 6:
return DWRITE_FONT_WEIGHT_SEMI_BOLD;
case 7:
return DWRITE_FONT_WEIGHT_BOLD;
case 8:
return DWRITE_FONT_WEIGHT_EXTRA_BOLD;
case 9:
default:
return DWRITE_FONT_WEIGHT_BLACK;
}
}
}
static DWRITE_FONT_WEIGHT GetClosestFontWeight(float weight) {
if (weight > 325 && weight < 375) {
return DWRITE_FONT_WEIGHT_SEMI_LIGHT;
} else if (weight > 925) {
return DWRITE_FONT_WEIGHT_EXTRA_BLACK;
} else {
switch (static_cast<uint16_t>(std::round(weight / 100.0f))) {
case 1:
return DWRITE_FONT_WEIGHT_THIN;
case 2:
return DWRITE_FONT_WEIGHT_EXTRA_LIGHT;
case 3:
return DWRITE_FONT_WEIGHT_LIGHT;
case 4:
return DWRITE_FONT_WEIGHT_NORMAL;
case 5:
return DWRITE_FONT_WEIGHT_MEDIUM;
case 6:
return DWRITE_FONT_WEIGHT_SEMI_BOLD;
case 7:
return DWRITE_FONT_WEIGHT_BOLD;
case 8:
return DWRITE_FONT_WEIGHT_EXTRA_BOLD;
case 9:
default:
return DWRITE_FONT_WEIGHT_BLACK;
}
}
}
};
} // namespace winrt::RNSVG

View File

@@ -1,9 +1,37 @@
#include "pch.h"
#include "DefsView.h"
#if __has_include("DefsView.g.cpp")
#include "DefsView.g.cpp"
#endif
using namespace winrt;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
DefsProps::DefsProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void DefsProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
DefsView::DefsView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
void DefsView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGDefs", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::DefsProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::DefsView>(args);
});
});
}
#endif
void DefsView::Draw(RNSVG::D2DDeviceContext const& /*deviceContext*/, Size const & /*size*/) {}
} // namespace winrt::RNSVG::implementation

View File

@@ -1,11 +1,38 @@
#pragma once
#ifdef USE_FABRIC
#include "DefsProps.g.h"
#endif
#include "DefsView.g.h"
#include "GroupView.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(DefsProps)
struct DefsProps : DefsPropsT<DefsProps, SvgGroupCommonProps> {
DefsProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
};
#endif
struct DefsView : DefsViewT<DefsView, RNSVG::implementation::GroupView> {
public:
DefsView() = default;
#ifdef USE_FABRIC
DefsView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
#endif
// IRenderable
void Draw(RNSVG::D2DDeviceContext const &deviceContext, Windows::Foundation::Size const &size);
};
} // namespace winrt::RNSVG::implementation

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "DefsViewManager.h"
#if __has_include("DefsViewManager.g.cpp")
#include "DefsViewManager.g.cpp"
#endif
namespace winrt::RNSVG::implementation {
DefsViewManager::DefsViewManager() {

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "EllipseView.h"
#if __has_include("EllipseView.g.cpp")
#include "EllipseView.g.cpp"
#endif
#include "JSValueXaml.h"
#include "Utils.h"
@@ -9,6 +11,48 @@ using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
EllipseProps::EllipseProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void EllipseProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
EllipseView::EllipseView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
void EllipseView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGEllipse", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::EllipseProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::EllipseView>(args);
});
});
}
void EllipseView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto ellipseProps = props.try_as<EllipseProps>();
if (ellipseProps) {
m_props = ellipseProps;
m_cx = m_props->cx;
m_cy = m_props->cy;
m_rx = m_props->rx;
m_ry = m_props->ry;
}
base_type::UpdateProperties(props, oldProps, forceUpdate, invalidate);
}
#else
void EllipseView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, bool invalidate) {
const JSValueObject &propertyMap{JSValue::ReadObjectFrom(reader)};
@@ -17,28 +61,32 @@ void EllipseView::UpdateProperties(IJSValueReader const &reader, bool forceUpdat
auto const &propertyValue{pair.second};
if (propertyName == "cx") {
m_cx = SVGLength::From(propertyValue);
m_cx = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "cy") {
m_cy = SVGLength::From(propertyValue);
m_cy = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "rx") {
m_rx = SVGLength::From(propertyValue);
m_rx = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "ry") {
m_ry = SVGLength::From(propertyValue);
m_ry = propertyValue.To<RNSVG::SVGLength>();
}
}
__super::UpdateProperties(reader, forceUpdate, invalidate);
}
#endif
void EllipseView::CreateGeometry() {
void EllipseView::CreateGeometry(RNSVG::D2DDeviceContext const &context) {
auto const root{SvgRoot()};
float cx{Utils::GetAbsoluteLength(m_cx, root.ActualWidth())};
float cy{Utils::GetAbsoluteLength(m_cy, root.ActualHeight())};
float rx{Utils::GetAbsoluteLength(m_rx, root.ActualWidth())};
float ry{Utils::GetAbsoluteLength(m_ry, root.ActualHeight())};
float width{root.CanvasSize().Width};
float height{root.CanvasSize().Height};
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(root.DeviceContext())->Get()};
float cx{Utils::GetAbsoluteLength(m_cx, width)};
float cy{Utils::GetAbsoluteLength(m_cy, height)};
float rx{Utils::GetAbsoluteLength(m_rx, width)};
float ry{Utils::GetAbsoluteLength(m_ry, height)};
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(context)->Get()};
com_ptr<ID2D1Factory> factory;
deviceContext->GetFactory(factory.put());

View File

@@ -1,19 +1,68 @@
#pragma once
#ifdef USE_FABRIC
#include "EllipseProps.g.h"
#endif
#include "EllipseView.g.h"
#include "RenderableView.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(EllipseProps)
struct EllipseProps : EllipsePropsT<EllipseProps, SvgRenderableCommonProps> {
EllipseProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_FIELD(cx)
RNSVG::SVGLength cx{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(cy)
RNSVG::SVGLength cy{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(rx)
RNSVG::SVGLength rx{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(ry)
RNSVG::SVGLength ry{0, winrt::RNSVG::LengthType::Unknown};
};
#endif
struct EllipseView : EllipseViewT<EllipseView, RNSVG::implementation::RenderableView> {
public:
EllipseView() = default;
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate, bool invalidate);
void CreateGeometry();
#ifdef USE_FABRIC
EllipseView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept override;
#else
// IRenderablePaper
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate, bool invalidate);
#endif
// IRenderable
void CreateGeometry(RNSVG::D2DDeviceContext const &context);
private:
RNSVG::SVGLength m_cx{};
RNSVG::SVGLength m_cy{};
RNSVG::SVGLength m_rx{};
RNSVG::SVGLength m_ry{};
#ifdef USE_FABRIC
com_ptr<EllipseProps> m_props;
#endif
};
} // namespace winrt::RNSVG::implementation
namespace winrt::RNSVG::factory_implementation {

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "EllipseViewManager.h"
#if __has_include("EllipseViewManager.g.cpp")
#include "EllipseViewManager.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::ReactNative;

166
windows/RNSVG/Fabric.idl Normal file
View File

@@ -0,0 +1,166 @@
import "Views.idl";
namespace RNSVG
{
[experimental]
interface IRenderableFabric
{
Microsoft.ReactNative.ComponentView SvgParent { get; };
void UpdateProperties(Microsoft.ReactNative.IComponentProps props, Microsoft.ReactNative.IComponentProps oldProps, Boolean forceUpdate, Boolean invalidate);
};
[experimental]
[default_interface]
runtimeclass SvgView : Microsoft.ReactNative.Composition.ViewComponentView,
Microsoft.ReactNative.Composition.Experimental.IInternalCreateVisual, IRenderable, IRenderableFabric, ISvgView
{
SvgView(Microsoft.ReactNative.Composition.CreateCompositionComponentViewArgs args);
GroupView Group;
Microsoft.ReactNative.Color CurrentColor{ get; };
};
[experimental]
[default_interface]
unsealed runtimeclass RenderableView : Microsoft.ReactNative.ComponentView, IRenderable, IRenderableFabric, IRenderableView
{
RenderableView(Microsoft.ReactNative.CreateComponentViewArgs args);
SvgView SvgRoot{ get; };
Microsoft.ReactNative.Color Fill{ get; };
Microsoft.ReactNative.Color Stroke{ get; };
};
[experimental]
[default_interface]
runtimeclass RectView : RenderableView
{
RectView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass CircleView : RenderableView
{
CircleView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass EllipseView : RenderableView
{
EllipseView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass LineView : RenderableView
{
LineView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass PathView : RenderableView
{
PathView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass UseView : RenderableView
{
UseView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass ImageView : RenderableView
{
ImageView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
unsealed runtimeclass GroupView : RenderableView, IGroupView
{
GroupView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
unsealed runtimeclass TextView : GroupView, ITextView
{
TextView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass TSpanView : TextView, ITSpanView
{
TSpanView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass DefsView : GroupView
{
DefsView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass SymbolView : GroupView, ISymbolView
{
SymbolView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass ClipPathView : GroupView
{
ClipPathView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass MarkerView : GroupView
{
MarkerView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass MaskView : GroupView
{
MaskView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
unsealed runtimeclass BrushView : GroupView, IBrushView
{
BrushView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass LinearGradientView : BrushView
{
LinearGradientView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass RadialGradientView : BrushView
{
RadialGradientView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
[experimental]
[default_interface]
runtimeclass PatternView : BrushView
{
PatternView(Microsoft.ReactNative.CreateComponentViewArgs args);
};
}

View File

@@ -14,6 +14,87 @@ using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
SvgGroupCommonProps::SvgGroupCommonProps(
const winrt::Microsoft::ReactNative::ViewProps &props)
: base_type(props) {}
void SvgGroupCommonProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
GroupView::GroupView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args)
: base_type(args), m_reactContext(args.ReactContext()) {}
void GroupView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGGroup", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::SvgGroupCommonProps>(props);
});
builder.SetCreateComponentView(
[](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::GroupView>(args);
});
});
}
void GroupView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto groupProps = props.as<SvgGroupCommonProps>();
auto oldGroupProps = oldProps ? oldProps.as<SvgGroupCommonProps>() : nullptr;
auto const &parent{Parent().try_as<RNSVG::GroupView>()};
if (!oldGroupProps || groupProps->font != oldGroupProps->font) {
if (forceUpdate || !m_fontPropMap[RNSVG::FontProp::FontSize]) {
if (groupProps->font.fontSize) {
m_fontSize = groupProps->font.fontSize != std::nullopt
? *groupProps->font.fontSize
: (parent ? parent.FontSize() : 12.0f);
}
m_fontPropMap[RNSVG::FontProp::FontSize] = !!groupProps->font.fontSize;
}
if (forceUpdate || !m_fontPropMap[RNSVG::FontProp::FontFamily]) {
if (groupProps->font.fontFamily) {
m_fontFamily = !(*groupProps->font.fontFamily).empty()
? winrt::to_hstring(*groupProps->font.fontFamily)
: (parent ? parent.FontFamily() : L"Segoe UI");
m_fontPropMap[RNSVG::FontProp::FontFamily] = !(*groupProps->font.fontFamily).empty();
}
}
if (forceUpdate || !m_fontPropMap[RNSVG::FontProp::FontWeight]) {
if (groupProps->font.fontWeight) {
m_fontWeight = !(*groupProps->font.fontWeight).empty()
? winrt::to_hstring(*groupProps->font.fontWeight)
: (parent ? parent.FontWeight() : L"auto");
m_fontPropMap[RNSVG::FontProp::FontWeight] = !(*groupProps->font.fontWeight).empty();
}
}
}
base_type::UpdateProperties(props, oldProps, forceUpdate, false);
for (auto const &child : Children()) {
child.as<IRenderableFabric>().UpdateProperties(props, oldProps, false, false);
}
if (invalidate && Parent()) {
SvgRoot().Invalidate();
}
}
#else
void GroupView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, bool invalidate) {
const JSValueObject &propertyMap{JSValue::ReadObjectFrom(reader)};
@@ -92,19 +173,21 @@ void GroupView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate,
__super::UpdateProperties(reader, forceUpdate, false);
for (auto const &child : Children()) {
child.UpdateProperties(reader, false, false);
child.as<IRenderablePaper>().UpdateProperties(reader, false, false);
}
if (invalidate && SvgParent()) {
SvgRoot().Invalidate();
}
}
#endif
void GroupView::CreateGeometry() {
std::vector<ID2D1Geometry*> geometries;
for (auto const child : Children()) {
void GroupView::CreateGeometry(RNSVG::D2DDeviceContext const &context) {
std::vector<ID2D1Geometry *> geometries;
for (auto const childComponent : Children()) {
auto const child = childComponent.as<IRenderable>();
if (!child.Geometry()) {
child.CreateGeometry();
child.CreateGeometry(context);
}
if (child.Geometry()) {
@@ -117,7 +200,7 @@ void GroupView::CreateGeometry() {
}
if (!geometries.empty()) {
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(SvgRoot().DeviceContext())->Get()};
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(context)->Get()};
com_ptr<ID2D1Factory> factory;
deviceContext->GetFactory(factory.put());
@@ -134,15 +217,15 @@ void GroupView::SaveDefinition() {
__super::SaveDefinition();
for (auto const &child : Children()) {
child.SaveDefinition();
child.as<IRenderable>().SaveDefinition();
}
}
void GroupView::MergeProperties(RNSVG::RenderableView const &other) {
void GroupView::MergeProperties(RNSVG::IRenderable const &other) {
__super::MergeProperties(other);
for (auto const &child : Children()) {
child.MergeProperties(*this);
child.as<IRenderable>().MergeProperties(*this);
}
}
@@ -157,8 +240,8 @@ void GroupView::Draw(RNSVG::D2DDeviceContext const &context, Size const &size) {
com_ptr<ID2D1Geometry> clipPathGeometry;
if (ClipPathGeometry()) {
clipPathGeometry = get_self<D2DGeometry>(ClipPathGeometry())->Get();
if (ClipPathGeometry(context)) {
clipPathGeometry = get_self<D2DGeometry>(ClipPathGeometry(context))->Get();
}
D2DHelpers::PushOpacityLayer(deviceContext.get(), clipPathGeometry.get(), m_opacity);
@@ -176,24 +259,27 @@ void GroupView::Draw(RNSVG::D2DDeviceContext const &context, Size const &size) {
void GroupView::DrawGroup(RNSVG::D2DDeviceContext const &context, Size const &size) {
for (auto const &child : Children()) {
child.Draw(context, size);
child.as<IRenderable>().Draw(context, size);
}
}
void GroupView::CreateResources() {
for (auto const &child : Children()) {
child.CreateResources();
child.as<IRenderable>().CreateResources();
}
}
void GroupView::Unload() {
for (auto const &child : Children()) {
child.Unload();
child.as<IRenderable>().Unload();
}
m_reactContext = nullptr;
m_fontPropMap.clear();
#ifndef USE_FABRIC
m_children.Clear();
#endif
__super::Unload();
}
@@ -202,24 +288,19 @@ winrt::RNSVG::IRenderable GroupView::HitTest(Point const &point) {
RNSVG::IRenderable renderable{nullptr};
if (IsResponsible()) {
for (auto const &child : Children()) {
if (auto const &hit{child.HitTest(point)}) {
if (auto const &hit{child.as<IRenderable>().HitTest(point)}) {
renderable = hit;
}
}
if (renderable && !renderable.IsResponsible()) {
return *this;
} else if (!renderable) {
if (!Geometry()) {
CreateGeometry();
}
if (Geometry()) {
com_ptr<ID2D1Geometry> geometry{get_self<D2DGeometry>(Geometry())->Get()};
D2D1_RECT_F bounds;
check_hresult(geometry->GetBounds(nullptr, &bounds));
if (xaml::RectHelper::Contains(D2DHelpers::FromD2DRect(bounds), point)) {
return *this;
}

View File

@@ -2,44 +2,136 @@
#include "GroupView.g.h"
#include "RenderableView.h"
#ifdef USE_FABRIC
#include "SvgGroupCommonProps.g.h"
#endif
namespace winrt::RNSVG::implementation {
struct GroupView : GroupViewT<GroupView, RNSVG::implementation::RenderableView> {
#ifdef USE_FABRIC
REACT_STRUCT(FontObject)
struct FontObject {
REACT_FIELD(fontStyle)
std::optional<std::string> fontStyle;
REACT_FIELD(fontVariant)
std::optional<std::string> fontVariant;
REACT_FIELD(fontWeight)
std::optional<std::string> fontWeight;
REACT_FIELD(fontStretch)
std::optional<std::string> fontStretch;
REACT_FIELD(fontSize)
std::optional<float> fontSize;
REACT_FIELD(fontFamily)
std::optional<std::string> fontFamily;
REACT_FIELD(textAnchor)
std::optional<std::string> textAnchor;
REACT_FIELD(textDecoration)
std::optional<std::string> textDecoration;
REACT_FIELD(letterSpacing)
std::optional<float> letterSpacing;
REACT_FIELD(wordSpacing)
std::optional<float> wordSpacing;
REACT_FIELD(kerning)
std::optional<float> kerning;
REACT_FIELD(fontFeatureSettings)
std::optional<std::string> fontFeatureSettings;
REACT_FIELD(fontVariantLigatures)
std::optional<std::string> fontVariantLigatures;
REACT_FIELD(fontVariationSettings)
std::optional<std::string> fontVariationSettings;
bool operator==(const FontObject &rhs) const {
return fontStyle == rhs.fontStyle && fontVariant == rhs.fontVariant &&
fontWeight == rhs.fontWeight && fontStretch == rhs.fontStretch &&
fontSize == rhs.fontSize && fontFamily == rhs.fontFamily &&
textAnchor == rhs.textAnchor && textDecoration == rhs.textDecoration &&
letterSpacing == rhs.letterSpacing && wordSpacing == rhs.wordSpacing &&
kerning == rhs.kerning &&
fontFeatureSettings == rhs.fontFeatureSettings &&
fontVariantLigatures == rhs.fontVariantLigatures &&
fontVariationSettings == rhs.fontVariationSettings;
}
bool operator!=(const FontObject &rhs) const {
return !(*this == rhs);
}
};
#define REACT_SVG_GROUP_COMMON_PROPS \
REACT_FIELD(fontSize) \
REACT_FIELD(fontWeight) \
REACT_FIELD(font)
REACT_STRUCT(SvgGroupCommonProps)
struct SvgGroupCommonProps
: SvgGroupCommonPropsT<SvgGroupCommonProps, SvgRenderableCommonProps> {
SvgGroupCommonProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_SVG_GROUP_COMMON_PROPS;
std::string fontSize;
std::string fontWeight;
FontObject font;
};
#endif
struct GroupView
: GroupViewT<GroupView, RNSVG::implementation::RenderableView> {
public:
GroupView() = default;
#ifdef USE_FABRIC
GroupView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept override;
#else
GroupView(Microsoft::ReactNative::IReactContext const &context) : m_reactContext(context) {}
Windows::Foundation::Collections::IVector<RNSVG::IRenderable> Children() { return m_children; }
// IRenderablePaper
virtual void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate, bool invalidate);
#endif
hstring FontFamily() { return m_fontFamily; }
void FontFamily(hstring const &value) { m_fontFamily = value; }
float FontSize() { return m_fontSize; }
void FontSize(float value) { m_fontSize = value; }
hstring FontWeight(){ return m_fontWeight; }
hstring FontWeight() { return m_fontWeight; }
void FontWeight(hstring const &value) { m_fontWeight = value; }
virtual void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate, bool invalidate);
virtual void CreateGeometry();
// IRenderable
virtual void CreateResources();
virtual void MergeProperties(RNSVG::IRenderable const &other);
virtual void SaveDefinition();
virtual void MergeProperties(RNSVG::RenderableView const &other);
virtual void CreateGeometry(RNSVG::D2DDeviceContext const &context);
virtual void Unload();
virtual RNSVG::IRenderable HitTest(Windows::Foundation::Point const &point);
void Draw(RNSVG::D2DDeviceContext const &deviceContext, Windows::Foundation::Size const &size);
virtual void DrawGroup(RNSVG::D2DDeviceContext const &deviceContext, Windows::Foundation::Size const &size);
virtual void CreateResources();
virtual void Unload();
virtual RNSVG::IRenderable HitTest(Windows::Foundation::Point const &point);
private:
Microsoft::ReactNative::IReactContext m_reactContext{nullptr};
#ifndef USE_FABRIC
Windows::Foundation::Collections::IVector<RNSVG::IRenderable> m_children{
winrt::single_threaded_vector<RNSVG::IRenderable>()};
#endif
float m_fontSize{12.0f};
hstring m_fontFamily{L"Segoe UI"};

View File

@@ -39,7 +39,7 @@ IMapView<hstring, ViewManagerPropertyType> GroupViewManager::NativeProps() {
void GroupViewManager::AddView(FrameworkElement const &parent, UIElement const &child, int64_t /*index*/) {
if (auto const &groupView{parent.try_as<RNSVG::GroupView>()}) {
if (auto const &childView{child.try_as<IRenderable>()}) {
childView.SvgParent(parent);
childView.as<IRenderablePaper>().SvgParent(parent);
groupView.Children().Append(childView);
childView.MergeProperties(groupView);
@@ -58,7 +58,7 @@ void GroupViewManager::RemoveAllChildren(FrameworkElement const &parent) {
if (auto const &groupView{parent.try_as<RNSVG::GroupView>()}) {
for (auto const &child : groupView.Children()) {
child.Unload();
child.SvgParent(nullptr);
child.as<IRenderablePaper>().SvgParent(nullptr);
}
groupView.Children().Clear();
@@ -74,7 +74,7 @@ void GroupViewManager::RemoveChildAt(FrameworkElement const &parent, int64_t ind
if (!groupView.IsUnloaded()) {
auto const &child{groupView.Children().GetAt(static_cast<uint32_t>(index))};
child.Unload();
child.SvgParent(nullptr);
child.as<IRenderablePaper>().SvgParent(nullptr);
groupView.Children().RemoveAt(static_cast<uint32_t>(index));
}
@@ -99,8 +99,8 @@ void GroupViewManager::ReplaceChild(
if (groupView.Children().IndexOf(oldChildView, index)) {
groupView.Children().RemoveAt(index);
oldChildView.Unload();
oldChildView.SvgParent(nullptr);
newChildView.SvgParent(parent);
oldChildView.as<IRenderablePaper>().SvgParent(nullptr);
newChildView.as<IRenderablePaper>().SvgParent(parent);
groupView.Children().Append(newChildView);
newChildView.MergeProperties(groupView);

View File

@@ -12,8 +12,7 @@ struct GroupViewManager : GroupViewManagerT<GroupViewManager, RNSVG::implementat
Windows::Foundation::Collections::IMapView<hstring, Microsoft::ReactNative::ViewManagerPropertyType> NativeProps();
// IViewManagerWithChildren
void
AddView(xaml::FrameworkElement const &parent, xaml::UIElement const &child, int64_t index);
void AddView(xaml::FrameworkElement const &parent, xaml::UIElement const &child, int64_t index);
void RemoveAllChildren(xaml::FrameworkElement const &parent);
void RemoveChildAt(xaml::FrameworkElement const &parent, int64_t index);
void ReplaceChild(

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "ImageView.h"
#if __has_include("ImageView.g.cpp")
#include "ImageView.g.cpp"
#endif
#include <winrt/Windows.Security.Cryptography.h>
#include <winrt/Windows.Storage.Streams.h>
@@ -11,7 +13,10 @@
#include <d2d1effects.h>
#include <shcore.h>
#ifndef USE_FABRIC
#include <wincodec.h>
#endif
using namespace winrt::Microsoft::ReactNative;
using namespace winrt::Windows::Security::Cryptography;
@@ -19,6 +24,65 @@ using namespace winrt::Windows::Storage::Streams;
using namespace winrt::Windows::Web::Http;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
ImageProps::ImageProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void ImageProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
ImageView::ImageView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
void ImageView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGImage", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::ImageProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::ImageView>(args);
});
});
}
void ImageView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto imageProps = props.try_as<ImageProps>();
auto oldImageProps = oldProps.try_as<ImageProps>();
if (imageProps) {
m_props = imageProps;
m_x = m_props->x;
m_y = m_props->y;
m_width = m_props->width;
m_height = m_props->height;
// preserveAspectRatio
m_align = m_props->align;
m_meetOrSlice = m_props->meetOrSlice;
// IamgeSource
m_source.uri = m_props->src.uri;
m_source.method = m_props->src.method;
m_source.width = m_props->src.width;
m_source.height = m_props->src.height;
m_source.scale = m_props->src.scale;
if (!oldImageProps || (oldImageProps->src.uri != imageProps->src.uri)) {
LoadImageSourceAsync(true);
}
}
base_type::UpdateProperties(props, oldProps, forceUpdate, invalidate);
}
#else
void ImageView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, bool invalidate) {
const JSValueObject &propertyMap{JSValue::ReadObjectFrom(reader)};
@@ -34,9 +98,9 @@ void ImageView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate,
auto const &value{item.second};
if (key == "uri") {
m_source.uri = to_hstring(Utils::JSValueAsString(value));
m_source.type = ImageSourceType::Uri;
m_source.format = ImageSourceFormat::Bitmap;
m_source.uri = Utils::JSValueAsString(value);
m_type = ImageSourceType::Uri;
m_format = ImageSourceFormat::Bitmap;
m_source.width = 0;
m_source.height = 0;
@@ -50,7 +114,7 @@ void ImageView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate,
} else if (key == "scale") {
m_source.scale = Utils::JSValueAsFloat(value);
} else if (key == "method") {
m_source.method = to_hstring(Utils::JSValueAsString(value));
m_source.method = Utils::JSValueAsString(value);
} else if (key == "headers") {
m_source.headers.clear();
for (auto const &header : value.AsObject()) {
@@ -61,13 +125,13 @@ void ImageView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate,
}
}
} else if (propertyName == "x") {
m_x = SVGLength::From(propertyValue);
m_x = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "y") {
m_y = SVGLength::From(propertyValue);
m_y = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "width") {
m_width = SVGLength::From(propertyValue);
m_width = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "height") {
m_height = SVGLength::From(propertyValue);
m_height = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "align") {
m_align = Utils::JSValueAsString(propertyValue);
} else if (propertyName == "meetOrSlice") {
@@ -77,6 +141,7 @@ void ImageView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate,
__super::UpdateProperties(reader, forceUpdate, invalidate);
}
#endif
void ImageView::Draw(RNSVG::D2DDeviceContext const &context, Size const &size) {
if (!m_wicbitmap) {
@@ -85,7 +150,8 @@ void ImageView::Draw(RNSVG::D2DDeviceContext const &context, Size const &size) {
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(context)->Get()};
uint32_t imgWidth, imgHeight;
uint32_t imgWidth{0};
uint32_t imgHeight{0};
check_hresult(m_wicbitmap->GetSize(&imgWidth, &imgHeight));
m_source.width = static_cast<float>(imgWidth);
@@ -113,13 +179,13 @@ void ImageView::Draw(RNSVG::D2DDeviceContext const &context, Size const &size) {
}
com_ptr<ID2D1Geometry> clipPathGeometry;
if (ClipPathGeometry()) {
clipPathGeometry = get_self<D2DGeometry>(ClipPathGeometry())->Get();
if (ClipPathGeometry(context)) {
clipPathGeometry = get_self<D2DGeometry>(ClipPathGeometry(context))->Get();
}
D2DHelpers::PushOpacityLayer(deviceContext.get(), clipPathGeometry.get(), m_opacity);
if (m_source.format == ImageSourceFormat::Bitmap) {
if (m_format == ImageSourceFormat::Bitmap) {
D2D1_MATRIX_3X2_F transform{D2DHelpers::GetTransform(deviceContext.get())};
if (m_propSetMap[RNSVG::BaseProp::Matrix]) {
@@ -167,26 +233,26 @@ void ImageView::Unload() {
}
IAsyncAction ImageView::LoadImageSourceAsync(bool invalidate) {
Uri uri{m_source.uri};
Uri uri{winrt::to_hstring(m_source.uri)};
hstring scheme{uri ? uri.SchemeName() : L""};
hstring ext{uri ? uri.Extension() : L""};
if (ext == L".svg" || ext == L".svgz") {
m_source.format = ImageSourceFormat::Svg;
m_format = ImageSourceFormat::Svg;
co_return;
}
if (scheme == L"http" || scheme == L"https") {
m_source.type = ImageSourceType::Download;
m_type = ImageSourceType::Download;
} else if (scheme == L"data") {
m_source.type = ImageSourceType::InlineData;
if (to_string(m_source.uri).find("image/svg+xml") != std::string::npos) {
m_source.format = ImageSourceFormat::Svg;
m_type = ImageSourceType::InlineData;
if (m_source.uri.find("image/svg+xml") != std::string::npos) {
m_format = ImageSourceFormat::Svg;
co_return;
}
}
const bool fromStream{m_source.type == ImageSourceType::Download || m_source.type == ImageSourceType::InlineData};
const bool fromStream{m_type == ImageSourceType::Download || m_type == ImageSourceType::InlineData};
InMemoryRandomAccessStream stream{nullptr};
@@ -216,7 +282,7 @@ IAsyncAction ImageView::LoadImageSourceAsync(bool invalidate) {
IAsyncOperation<InMemoryRandomAccessStream> ImageView::GetImageMemoryStreamAsync(
ImageSource source) {
switch (source.type) {
switch (m_type) {
case ImageSourceType::Download:
co_return co_await GetImageStreamAsync(source);
case ImageSourceType::InlineData:
@@ -231,11 +297,12 @@ IAsyncOperation<InMemoryRandomAccessStream> ImageView::GetImageStreamAsync(
try {
co_await resume_background();
auto httpMethod{source.method.empty() ? HttpMethod::Get() : HttpMethod{source.method}};
auto httpMethod{source.method.empty() ? HttpMethod::Get() : HttpMethod{winrt::to_hstring(source.method)}};
Uri uri{source.uri};
Uri uri{winrt::to_hstring(source.uri)};
HttpRequestMessage request{httpMethod, uri};
#ifndef USE_FABRIC
if (!source.headers.empty()) {
for (auto const &header : source.headers) {
if (_stricmp(to_string(header.first).c_str(), "authorization") == 0) {
@@ -245,6 +312,7 @@ IAsyncOperation<InMemoryRandomAccessStream> ImageView::GetImageStreamAsync(
}
}
}
#endif
HttpClient httpClient;
HttpResponseMessage response{co_await httpClient.SendRequestAsync(request)};
@@ -265,7 +333,7 @@ IAsyncOperation<InMemoryRandomAccessStream> ImageView::GetImageStreamAsync(
IAsyncOperation<InMemoryRandomAccessStream> ImageView::GetImageInlineDataAsync(
ImageSource source) {
std::string uri{to_string(source.uri)};
std::string uri{source.uri};
size_t start = uri.find(',');
if (start == std::string::npos || start + 1 > uri.length()) {

View File

@@ -1,13 +1,80 @@
#pragma once
#ifdef USE_FABRIC
#include "ImageProps.g.h"
#endif
#include "ImageView.g.h"
#include "RenderableView.h"
#include <wincodec.h>
namespace winrt::RNSVG::implementation {
enum class ImageSourceType { Uri = 0, Download = 1, InlineData = 2 };
enum class ImageSourceFormat { Bitmap = 0, Svg = 1 };
#ifdef USE_FABRIC
REACT_STRUCT(ImageSource)
struct ImageSource {
hstring uri{L""};
hstring method{L""};
REACT_FIELD(uri)
std::string uri{""};
REACT_FIELD(method)
std::string method{""};
//REACT_FIELD(headers)
//std::vector<winrt::Microsoft::ReactNative::JSValue> headers;
REACT_FIELD(body)
std::string body{""};
REACT_FIELD(width)
float width{0.0f};
REACT_FIELD(height)
float height{0.0f};
REACT_FIELD(scale)
float scale{1.0f};
/*REACT_FIELD(packagerAsset)
bool packagerAsset{false};
REACT_FIELD(type)
ImageSourceType type{ImageSourceType::Uri};
REACT_FIELD(format)
ImageSourceFormat format{ImageSourceFormat::Bitmap};*/
bool operator==(const ImageSource &rhs) const {
return uri == rhs.uri && method == rhs.method && width == rhs.width && height == rhs.height && scale == rhs.scale;
}
bool operator!=(const ImageSource &rhs) const {
return !(*this == rhs);
}
};
REACT_STRUCT(ImageProps)
struct ImageProps : ImagePropsT<ImageProps, SvgRenderableCommonProps> {
ImageProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_FIELD(x)
RNSVG::SVGLength x{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(y)
RNSVG::SVGLength y{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(width)
RNSVG::SVGLength width{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(height)
RNSVG::SVGLength height{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(src)
ImageSource src;
REACT_FIELD(align)
std::string align{""};
REACT_FIELD(meetOrSlice)
RNSVG::MeetOrSlice meetOrSlice{RNSVG::MeetOrSlice::Meet};
};
#else
struct ImageSource {
std::string uri{""};
std::string method{""};
std::vector<std::pair<hstring, hstring>> headers{};
float width{0.0f};
float height{0.0f};
@@ -16,12 +83,29 @@ struct ImageSource {
ImageSourceType type{ImageSourceType::Uri};
ImageSourceFormat format{ImageSourceFormat::Bitmap};
};
#endif
struct ImageView : ImageViewT<ImageView, RNSVG::implementation::RenderableView> {
public:
ImageView() = default;
#ifdef USE_FABRIC
ImageView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept override;
#else
// IRenderablePaper
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate, bool invalidate);
#endif
// IRenderable
void Draw(RNSVG::D2DDeviceContext const &deviceContext, Windows::Foundation::Size const &size);
void CreateResources();
void Unload();
@@ -31,12 +115,18 @@ struct ImageView : ImageViewT<ImageView, RNSVG::implementation::RenderableView>
RNSVG::SVGLength m_y{};
RNSVG::SVGLength m_width{};
RNSVG::SVGLength m_height{};
ImageSource m_source{};
ImageSourceType m_type{ImageSourceType::Uri};
ImageSourceFormat m_format{ImageSourceFormat::Bitmap};
#ifdef USE_FABRIC
com_ptr<ImageProps> m_props;
#endif
// preserveAspectRatio
std::string m_align{""};
RNSVG::MeetOrSlice m_meetOrSlice{RNSVG::MeetOrSlice::Meet};
ImageSource m_source{};
com_ptr<IWICBitmap> m_wicbitmap;
Windows::Foundation::IAsyncAction LoadImageSourceAsync(bool invalidate);
@@ -46,7 +136,7 @@ struct ImageView : ImageViewT<ImageView, RNSVG::implementation::RenderableView>
GetImageStreamAsync(ImageSource source);
Windows::Foundation::IAsyncOperation<Windows::Storage::Streams::InMemoryRandomAccessStream>
GetImageInlineDataAsync(ImageSource source);
com_ptr<IWICBitmapSource> ImageView::wicBitmapSourceFromStream(
com_ptr<IWICBitmapSource> wicBitmapSourceFromStream(
Windows::Storage::Streams::InMemoryRandomAccessStream const &stream);
void generateBitmap(
Windows::Storage::Streams::InMemoryRandomAccessStream const &results);

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "ImageViewManager.h"
#if __has_include("ImageViewManager.g.cpp")
#include "ImageViewManager.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::ReactNative;

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "LineView.h"
#if __has_include("LineView.g.cpp")
#include "LineView.g.cpp"
#endif
#include "JSValueXaml.h"
#include "Utils.h"
@@ -9,6 +11,49 @@ using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
LineProps::LineProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void LineProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
LineView::LineView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
void LineView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGLine", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::LineProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::LineView>(args);
});
});
}
void LineView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto lineProps = props.try_as<LineProps>();
if (lineProps) {
m_props = lineProps;
m_x1 = m_props->x1;
m_y1 = m_props->y1;
m_x2 = m_props->x2;
m_y2 = m_props->y2;
}
base_type::UpdateProperties(props, oldProps, forceUpdate, invalidate);
}
#else
void LineView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, bool invalidate) {
const JSValueObject &propertyMap{JSValue::ReadObjectFrom(reader)};
@@ -17,27 +62,32 @@ void LineView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate,
auto const &propertyValue{pair.second};
if (propertyName == "x1") {
m_x1 = SVGLength::From(propertyValue);
m_x1 = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "y1") {
m_y1 = SVGLength::From(propertyValue);
m_y1 = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "x2") {
m_x2 = SVGLength::From(propertyValue);
m_x2 = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "y2") {
m_y2 = SVGLength::From(propertyValue);
m_y2 = propertyValue.To<RNSVG::SVGLength>();
}
}
__super::UpdateProperties(reader, forceUpdate, invalidate);
}
void LineView::CreateGeometry() {
#endif
void LineView::CreateGeometry(RNSVG::D2DDeviceContext const &context) {
auto const &root{SvgRoot()};
float x1{Utils::GetAbsoluteLength(m_x1, root.ActualWidth())};
float y1{Utils::GetAbsoluteLength(m_y1, root.ActualHeight())};
float x2{Utils::GetAbsoluteLength(m_x2, root.ActualWidth())};
float y2{Utils::GetAbsoluteLength(m_y2, root.ActualHeight())};
float width{root.CanvasSize().Width};
float height{root.CanvasSize().Height};
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(root.DeviceContext())->Get()};
float x1{Utils::GetAbsoluteLength(m_x1, width)};
float y1{Utils::GetAbsoluteLength(m_y1, height)};
float x2{Utils::GetAbsoluteLength(m_x2, width)};
float y2{Utils::GetAbsoluteLength(m_y2, height)};
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(context)->Get()};
com_ptr<ID2D1Factory> factory;
deviceContext->GetFactory(factory.put());

View File

@@ -1,19 +1,69 @@
#pragma once
#ifdef USE_FABRIC
#include "LineProps.g.h"
#endif
#include "LineView.g.h"
#include "RenderableView.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(LineProps)
struct LineProps : LinePropsT<LineProps, SvgRenderableCommonProps> {
LineProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_FIELD(x1)
RNSVG::SVGLength x1{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(y1)
RNSVG::SVGLength y1{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(x2)
RNSVG::SVGLength x2{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(y2)
RNSVG::SVGLength y2{0, winrt::RNSVG::LengthType::Unknown};
};
#endif
struct LineView : LineViewT<LineView, RNSVG::implementation::RenderableView> {
public:
LineView() = default;
#ifdef USE_FABRIC
LineView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept override;
#else
// IRenderablePaper
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate, bool invalidate);
void CreateGeometry();
#endif
// IRenderable
void CreateGeometry(RNSVG::D2DDeviceContext const &context);
private:
RNSVG::SVGLength m_x1{};
RNSVG::SVGLength m_y1{};
RNSVG::SVGLength m_x2{};
RNSVG::SVGLength m_y2{};
#ifdef USE_FABRIC
com_ptr<LineProps> m_props;
#endif
};
} // namespace winrt::RNSVG::implementation
namespace winrt::RNSVG::factory_implementation {

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "LineViewManager.h"
#if __has_include("LineViewManager.g.cpp")
#include "LineViewManager.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::ReactNative;

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "LinearGradientView.h"
#if __has_include("LinearGradientView.g.cpp")
#include "LinearGradientView.g.cpp"
#endif
#include "Utils.h"
@@ -8,6 +10,55 @@ using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
LinearGradientProps::LinearGradientProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void LinearGradientProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
LinearGradientView::LinearGradientView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
void LinearGradientView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGLinearGradient", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::LinearGradientProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::LinearGradientView>(args);
});
});
}
void LinearGradientView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto linearGradientProps = props.try_as<LinearGradientProps>();
if (linearGradientProps) {
m_props = linearGradientProps;
m_x1 = m_props->x1;
m_y1 = m_props->y1;
m_x2 = m_props->x2;
m_y2 = m_props->y2;
m_stops = Utils::JSValueAsGradientStops(m_props->gradient);
m_gradientUnits = Utils::JSValueAsBrushUnits(m_props->gradientUnits);
m_transform = Utils::JSValueAsD2DTransform(m_props->gradientTransform);
}
base_type::UpdateProperties(props, oldProps, forceUpdate, invalidate);
SaveDefinition();
}
#else
void LinearGradientView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, bool invalidate) {
const JSValueObject &propertyMap{JSValue::ReadObjectFrom(reader)};
@@ -16,13 +67,13 @@ void LinearGradientView::UpdateProperties(IJSValueReader const &reader, bool for
auto const &propertyValue{pair.second};
if (propertyName == "x1") {
m_x1 = SVGLength::From(propertyValue);
m_x1 = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "y1") {
m_y1 = SVGLength::From(propertyValue);
m_y1 = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "x2") {
m_x2 = SVGLength::From(propertyValue);
m_x2 = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "y2") {
m_y2 = SVGLength::From(propertyValue);
m_y2 = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "gradient") {
m_stops = Utils::JSValueAsStops(propertyValue);
} else if (propertyName == "gradientUnits") {
@@ -40,6 +91,7 @@ void LinearGradientView::UpdateProperties(IJSValueReader const &reader, bool for
SaveDefinition();
}
#endif
void LinearGradientView::Unload() {
m_stops.clear();
@@ -54,7 +106,7 @@ void LinearGradientView::CreateBrush() {
winrt::com_ptr<ID2D1GradientStopCollection> stopCollection;
winrt::check_hresult(deviceContext->CreateGradientStopCollection(&m_stops[0], static_cast<uint32_t>(m_stops.size()), stopCollection.put()));
Size size{static_cast<float>(root.ActualWidth()), static_cast<float>(root.ActualHeight())};
Size size{root.CanvasSize()};
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES brushProperties;
brushProperties.startPoint = {0, 0};
@@ -77,7 +129,7 @@ void LinearGradientView::UpdateBounds() {
}
}
void LinearGradientView::SetPoints(ID2D1LinearGradientBrush * brush, D2D1_RECT_F bounds) {
void LinearGradientView::SetPoints(ID2D1LinearGradientBrush *brush, D2D1_RECT_F bounds) {
float width{D2DHelpers::WidthFromD2DRect(bounds)};
float height{D2DHelpers::HeightFromD2DRect(bounds)};

View File

@@ -1,14 +1,64 @@
#pragma once
#ifdef USE_FABRIC
#include "LinearGradientProps.g.h"
#endif
#include "LinearGradientView.g.h"
#include "BrushView.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(LinearGradientProps)
struct LinearGradientProps : LinearGradientPropsT<LinearGradientProps, SvgGroupCommonProps> {
LinearGradientProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_SVG_GROUP_COMMON_PROPS;
REACT_FIELD(x1)
RNSVG::SVGLength x1{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(y1)
RNSVG::SVGLength y1{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(x2)
RNSVG::SVGLength x2{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(y2)
RNSVG::SVGLength y2{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(gradient)
std::optional<std::vector<float>> gradient{};
REACT_FIELD(gradientUnits)
std::optional<int32_t> gradientUnits;
REACT_FIELD(gradientTransform)
std::optional<std::vector<float>> gradientTransform;
};
#endif
struct LinearGradientView : LinearGradientViewT<LinearGradientView, RNSVG::implementation::BrushView> {
public:
LinearGradientView() = default;
// RenderableView
#ifdef USE_FABRIC
LinearGradientView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept override;
#else
// IRenderablePaper
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate, bool invalidate);
#endif
// IRenderable
void Unload();
private:
@@ -19,6 +69,11 @@ struct LinearGradientView : LinearGradientViewT<LinearGradientView, RNSVG::imple
std::vector<D2D1_GRADIENT_STOP> m_stops{};
std::string m_gradientUnits{"objectBoundingBox"};
#ifdef USE_FABRIC
com_ptr<LinearGradientProps> m_props;
#endif
// BrushView
void CreateBrush();
void UpdateBounds();
void SetPoints(ID2D1LinearGradientBrush *brush, D2D1_RECT_F bounds);

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "LinearGradientViewManager.h"
#if __has_include("LinearGradientViewManager.g.cpp")
#include "LinearGradientViewManager.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::ReactNative;

View File

@@ -1,8 +1,50 @@
#include "pch.h"
#include "MarkerView.h"
#if __has_include("MarkerView.g.cpp")
#include "MarkerView.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {} // namespace winrt::RNSVG::implementation
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
MarkerProps::MarkerProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void MarkerProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
MarkerView::MarkerView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
void MarkerView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGMarker", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::MarkerProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::MarkerView>(args);
});
});
}
void MarkerView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto markerProps = props.try_as<MarkerProps>();
if (markerProps) {
m_props = markerProps;
}
base_type::UpdateProperties(props, oldProps, forceUpdate, invalidate);
}
#else
#endif
} // namespace winrt::RNSVG::implementation

View File

@@ -1,14 +1,78 @@
#pragma once
#ifdef USE_FABRIC
#include "MarkerProps.g.h"
#endif
#include "MarkerView.g.h"
#include "GroupView.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(MarkerProps)
struct MarkerProps : MarkerPropsT<MarkerProps, SvgGroupCommonProps> {
MarkerProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_FIELD(refX)
RNSVG::SVGLength refX{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(refY)
RNSVG::SVGLength refY{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(markerHeight)
RNSVG::SVGLength markerHeight{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(markerWidth)
RNSVG::SVGLength markerWidth{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(markerUnits)
std::string markerUnits{""};
REACT_FIELD(orient)
std::string orient{""};
REACT_FIELD(minX)
float minX{0.0f};
REACT_FIELD(minY)
float minY{0.0f};
REACT_FIELD(vbWidth)
float vbWidth{0.0f};
REACT_FIELD(vbHeight)
float vbHeight{0.0f};
REACT_FIELD(align)
std::string align{""};
REACT_FIELD(meetOrSlice)
RNSVG::MeetOrSlice meetOrSlice{RNSVG::MeetOrSlice::Meet};
};
#endif
struct MarkerView : MarkerViewT<MarkerView, RNSVG::implementation::GroupView> {
public:
MarkerView() = default;
// RenderableView
#ifdef USE_FABRIC
MarkerView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept override;
#endif
// IRenderable
void Draw(RNSVG::D2DDeviceContext const & /*deviceContext*/, Windows::Foundation::Size const & /*size*/){};
private:
#ifdef USE_FABRIC
com_ptr<MarkerProps> m_props;
#endif
};
} // namespace winrt::RNSVG::implementation

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "MarkerViewManager.h"
#if __has_include("MarkerViewManager.g.cpp")
#include "MarkerViewManager.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::ReactNative;

View File

@@ -5,6 +5,46 @@
#endif
using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {} // namespace winrt::RNSVG::implementation
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
MaskProps::MaskProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void MaskProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
MaskView::MaskView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
void MaskView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGMask", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::MaskProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::MaskView>(args);
});
});
}
void MaskView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto maskProps = props.try_as<MaskProps>();
if (maskProps) {
m_props = maskProps;
}
base_type::UpdateProperties(props, oldProps, forceUpdate, invalidate);
}
#else
#endif
} // namespace winrt::RNSVG::implementation

View File

@@ -1,14 +1,66 @@
#pragma once
#ifdef USE_FABRIC
#include "MaskProps.g.h"
#endif
#include "MaskView.g.h"
#include "GroupView.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(MaskProps)
struct MaskProps : MaskPropsT<MaskProps, SvgGroupCommonProps> {
MaskProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_FIELD(x)
RNSVG::SVGLength x{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(y)
RNSVG::SVGLength y{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(height)
RNSVG::SVGLength height{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(width)
RNSVG::SVGLength width{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(maskUnits)
uint32_t maskUnits{0};
REACT_FIELD(maskContentUnits)
uint32_t maskContentUnits{0};
};
#endif
struct MaskView : MaskViewT<MaskView, RNSVG::implementation::GroupView> {
public:
MaskView() = default;
// RenderableView
#ifdef USE_FABRIC
MaskView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept override;
#endif
// IRenderable
void Draw(RNSVG::D2DDeviceContext const & /*deviceContext*/, Windows::Foundation::Size const & /*size*/){};
private:
#ifdef USE_FABRIC
com_ptr<MaskProps> m_props;
#endif
};
} // namespace winrt::RNSVG::implementation

167
windows/RNSVG/Paper.idl Normal file
View File

@@ -0,0 +1,167 @@
import "Views.idl";
#include <NamespaceRedirect.h>
namespace RNSVG
{
[experimental]
interface IRenderablePaper
{
XAML_NAMESPACE.FrameworkElement SvgParent;
void UpdateProperties(Microsoft.ReactNative.IJSValueReader reader, Boolean forceUpdate, Boolean invalidate);
};
[experimental]
[default_interface]
runtimeclass SvgView : XAML_NAMESPACE.Controls.Panel, IRenderable, IRenderablePaper, ISvgView
{
SvgView(Microsoft.ReactNative.IReactContext context);
GroupView Group;
Windows.UI.Color CurrentColor{ get; };
};
[experimental]
[default_interface]
unsealed runtimeclass RenderableView : XAML_NAMESPACE.FrameworkElement, IRenderable, IRenderablePaper, IRenderableView
{
RenderableView(Microsoft.ReactNative.IReactContext context);
SvgView SvgRoot{ get; };
Windows.UI.Color Fill{ get; };
Windows.UI.Color Stroke{ get; };
};
[experimental]
[default_interface]
runtimeclass RectView : RenderableView
{
RectView();
};
[experimental]
[default_interface]
runtimeclass CircleView : RenderableView
{
CircleView();
};
[experimental]
[default_interface]
runtimeclass EllipseView : RenderableView
{
EllipseView();
};
[experimental]
[default_interface]
runtimeclass LineView : RenderableView
{
LineView();
};
[experimental]
[default_interface]
runtimeclass PathView : RenderableView
{
PathView();
};
[experimental]
[default_interface]
runtimeclass UseView : RenderableView
{
UseView();
};
[experimental]
[default_interface]
runtimeclass ImageView : RenderableView
{
ImageView();
};
[experimental]
[default_interface]
unsealed runtimeclass GroupView : RenderableView, IGroupView
{
GroupView(Microsoft.ReactNative.IReactContext context);
Windows.Foundation.Collections.IVector<IRenderable> Children { get; };
};
[experimental]
[default_interface]
unsealed runtimeclass TextView : GroupView, ITextView
{
TextView();
};
[experimental]
[default_interface]
runtimeclass TSpanView : TextView, ITSpanView
{
TSpanView();
};
[experimental]
[default_interface]
runtimeclass DefsView : GroupView
{
DefsView();
};
[experimental]
[default_interface]
runtimeclass SymbolView : GroupView, ISymbolView
{
SymbolView();
};
[experimental]
[default_interface]
runtimeclass ClipPathView : GroupView
{
ClipPathView();
};
[experimental]
[default_interface]
runtimeclass MarkerView : GroupView
{
MarkerView();
};
[experimental]
[default_interface]
runtimeclass MaskView : GroupView
{
MaskView();
};
[experimental]
[default_interface]
unsealed runtimeclass BrushView : GroupView, IBrushView
{
BrushView();
};
[experimental]
[default_interface]
runtimeclass LinearGradientView : BrushView
{
LinearGradientView();
};
[experimental]
[default_interface]
runtimeclass RadialGradientView : BrushView
{
RadialGradientView();
};
[experimental]
[default_interface]
runtimeclass PatternView : BrushView
{
PatternView();
};
}

View File

@@ -14,6 +14,50 @@ using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
PathProps::PathProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void PathProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
PathView::PathView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
void PathView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGPath", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::PathProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::PathView>(args);
});
});
}
void PathView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto pathProps = props.try_as<PathProps>();
if (pathProps) {
m_props = pathProps;
m_d = m_props->d;
m_commands.clear();
m_segmentData.clear();
ParsePath();
}
base_type::UpdateProperties(props, oldProps, forceUpdate, invalidate);
}
#else
void PathView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, bool invalidate) {
const JSValueObject &propertyMap{JSValue::ReadObjectFrom(reader)};
@@ -37,16 +81,18 @@ void PathView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate,
__super::UpdateProperties(reader, forceUpdate, invalidate);
}
#endif
void PathView::CreateGeometry() {
void PathView::CreateGeometry(RNSVG::D2DDeviceContext const &context) {
auto const &root{SvgRoot()};
com_ptr<ID2D1SvgDocument> doc;
com_ptr<ID2D1DeviceContext5> deviceContext{get_self<D2DDeviceContext>(root.DeviceContext())->Get().as<ID2D1DeviceContext5>()};
com_ptr<ID2D1DeviceContext5> deviceContext{get_self<D2DDeviceContext>(context)->Get().as<ID2D1DeviceContext5>()};
auto size{root.CanvasSize()};
check_hresult(deviceContext->CreateSvgDocument(
nullptr,
D2D1::SizeF(static_cast<float>(root.ActualWidth()), static_cast<float>(root.ActualHeight())),
D2D1::SizeF(size.Width, size.Height),
doc.put()));
m_segmentData.resize(m_segmentData.size());

View File

@@ -1,21 +1,62 @@
#pragma once
#ifdef USE_FABRIC
#include "PathProps.g.h"
#endif
#include "PathView.g.h"
#include "RenderableView.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(PathProps)
struct PathProps : PathPropsT<PathProps, SvgRenderableCommonProps> {
PathProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_FIELD(d)
std::string d;
};
#endif
struct PathView : PathViewT<PathView, RNSVG::implementation::RenderableView> {
public:
PathView() = default;
#ifdef USE_FABRIC
PathView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept override;
#else
// IRenderablePaper
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate, bool invalidate);
void CreateGeometry();
#endif
// IRenderable
void CreateGeometry(RNSVG::D2DDeviceContext const &context);
private:
std::string m_d;
std::vector<float> m_segmentData;
std::vector<D2D1_SVG_PATH_COMMAND> m_commands;
#ifdef USE_FABRIC
com_ptr<PathProps> m_props;
#endif
std::unordered_map<char, D2D1_SVG_PATH_COMMAND> m_cmds{
{'M', D2D1_SVG_PATH_COMMAND_MOVE_ABSOLUTE},
{'m', D2D1_SVG_PATH_COMMAND_MOVE_RELATIVE},

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "PatternView.h"
#if __has_include("PatternView.g.cpp")
#include "PatternView.g.cpp"
#endif
#include "Utils.h"
#include "D2DDevice.h"
@@ -9,6 +11,68 @@ using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
PatternProps::PatternProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void PatternProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
PatternView::PatternView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
void PatternView::RegisterComponent(
const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGPattern", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::PatternProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::PatternView>(args);
});
});
}
void PatternView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto patternProps = props.try_as<PatternProps>();
if (patternProps) {
m_props = patternProps;
m_x = m_props->x;
m_y = m_props->y;
m_width = m_props->width;
m_height = m_props->height;
m_minX = m_props->minX;
m_minY = m_props->minY;
m_vbWidth = m_props->vbWidth;
m_vbHeight = m_props->vbHeight;
m_align = m_props->align;
m_meetOrSlice = m_props->meetOrSlice;
m_patternUnits = Utils::JSValueAsBrushUnits(m_props->patternUnits);
m_patternContentUnits = Utils::JSValueAsBrushUnits(m_props->patternContentUnits, "userSpaceOnUse");
m_transform = Utils::JSValueAsD2DTransform(m_props->patternTransform);
}
base_type::UpdateProperties(props, oldProps, forceUpdate, invalidate);
SaveDefinition();
if (auto const &root{SvgRoot()}) {
root.Invalidate();
}
}
#else
void PatternView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, bool invalidate) {
const JSValueObject &propertyMap{JSValue::ReadObjectFrom(reader)};
@@ -17,13 +81,13 @@ void PatternView::UpdateProperties(IJSValueReader const &reader, bool forceUpdat
auto const &propertyValue{pair.second};
if (propertyName == "x") {
m_x = SVGLength::From(propertyValue);
m_x = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "y") {
m_y = SVGLength::From(propertyValue);
m_y = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "width") {
m_width = SVGLength::From(propertyValue);
m_width = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "height") {
m_height = SVGLength::From(propertyValue);
m_height = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "patternUnits") {
m_patternUnits = Utils::JSValueAsBrushUnits(propertyValue);
} else if (propertyName == "patternContentUnits") {
@@ -57,6 +121,7 @@ void PatternView::UpdateProperties(IJSValueReader const &reader, bool forceUpdat
root.Invalidate();
}
}
#endif
void PatternView::UpdateBounds() {
if (m_patternUnits == "objectBoundingBox") {
@@ -69,8 +134,9 @@ void PatternView::UpdateBounds() {
void PatternView::CreateBrush() {
auto const root{SvgRoot()};
auto const size{root.CanvasSize()};
D2D1_RECT_F elRect{GetAdjustedRect({0, 0, static_cast<float>(root.ActualWidth()), static_cast<float>(root.ActualHeight())})};
D2D1_RECT_F elRect{GetAdjustedRect({0, 0, size.Width, size.Height})};
CreateBrush(elRect);
}
@@ -142,16 +208,12 @@ com_ptr<ID2D1CommandList> PatternView::GetCommandList(ID2D1Device* device, D2D1_
auto context = make<D2DDeviceContext>(deviceContext);
for (auto const &child : Children()) {
child.Draw(context, D2DHelpers::SizeFromD2DRect(rect));
child.as<IRenderable>().Draw(context, D2DHelpers::SizeFromD2DRect(rect));
}
cmdList->Close();
deviceContext->EndDraw();
return cmdList;
}
} // namespace winrt::RNSVG::implementation

View File

@@ -1,14 +1,76 @@
#pragma once
#ifdef USE_FABRIC
#include "PatternProps.g.h"
#endif
#include "PatternView.g.h"
#include "BrushView.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(PatternProps)
struct PatternProps : PatternPropsT<PatternProps, SvgGroupCommonProps> {
PatternProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_FIELD(x)
RNSVG::SVGLength x{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(y)
RNSVG::SVGLength y{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(width)
RNSVG::SVGLength width{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(height)
RNSVG::SVGLength height{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(patternUnits)
std::optional<int32_t> patternUnits;
REACT_FIELD(patternContentUnits)
std::optional<int32_t> patternContentUnits;
REACT_FIELD(patternTransform)
std::optional<std::vector<float>> patternTransform;
REACT_FIELD(minX)
float minX{0.0f};
REACT_FIELD(minY)
float minY{0.0f};
REACT_FIELD(vbWidth)
float vbWidth{0.0f};
REACT_FIELD(vbHeight)
float vbHeight{0.0f};
REACT_FIELD(align)
std::string align{""};
REACT_FIELD(meetOrSlice)
RNSVG::MeetOrSlice meetOrSlice{RNSVG::MeetOrSlice::Meet};
};
#endif
struct PatternView : PatternViewT<PatternView, RNSVG::implementation::BrushView> {
public:
PatternView() = default;
#ifdef USE_FABRIC
PatternView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
// RenderableView
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept override;
#else
// IRenderablePaper
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate, bool invalidate);
#endif
// IRenderable
void Draw(RNSVG::D2DDeviceContext const & /*deviceContext*/, Windows::Foundation::Size const & /*size*/){};
private:
@@ -26,6 +88,10 @@ struct PatternView : PatternViewT<PatternView, RNSVG::implementation::BrushView>
float m_vbHeight{0.0f};
std::string m_align{""};
RNSVG::MeetOrSlice m_meetOrSlice{RNSVG::MeetOrSlice::Meet};
#ifdef USE_FABRIC
com_ptr<PatternProps> m_props;
#endif
// BrushView
void CreateBrush();

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "PatternViewManager.h"
#if __has_include("PatternViewManager.g.cpp")
#include "PatternViewManager.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::ReactNative;

99
windows/RNSVG/RNSVG.rc Normal file
View File

@@ -0,0 +1,99 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#include "versionoverrides.rc"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION RC_VER
PRODUCTVERSION RC_VER
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "software-mansion"
VALUE "FileDescription", "RNSVG.dll provides SVG support to React Native on Windows."
VALUE "FileVersion", RC_FILE_VER
VALUE "InternalName", "RNSVG.dll"
VALUE "LegalCopyright", "Copyright (C) 2023"
VALUE "OriginalFilename", "RNSVG.dll"
VALUE "ProductName", "react-native-svg"
VALUE "ProductVersion", RC_PRODUCT_VER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -2,78 +2,98 @@
<!-- This project was created with react-native-windows 0.74.9 -->
<Project ToolsVersion="Current" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)\ExperimentalFeatures.props" Condition="Exists('$(SolutionDir)\ExperimentalFeatures.props')" />
<PropertyGroup Label="Globals">
<CppWinRTOptimized>true</CppWinRTOptimized>
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
<MinimalCoreWin>true</MinimalCoreWin>
<ProjectGuid>{7acf84ec-efba-4043-8e14-40b159508902}</ProjectGuid>
<ProjectName>RNSVG</ProjectName>
<RootNamespace>RNSVG</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>17.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
</PropertyGroup>
<Choose>
<When Condition="'$(UseFabric)'!='true'">
<PropertyGroup Label="Globals">
<CppWinRTOptimized>true</CppWinRTOptimized>
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
<MinimalCoreWin>true</MinimalCoreWin>
<ProjectGuid>{7acf84ec-efba-4043-8e14-40b159508902}</ProjectGuid>
<ProjectName>RNSVG</ProjectName>
<RootNamespace>RNSVG</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>17.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup Label="Globals">
<CppWinRTOptimized>true</CppWinRTOptimized>
<MinimalCoreWin>true</MinimalCoreWin>
<ProjectGuid>{7acf84ec-efba-4043-8e14-40b159508902}</ProjectGuid>
<ProjectName>RNSVG</ProjectName>
<Keyword>Win32Proj</Keyword>
<RootNamespace>RNSVG</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>17.0</MinimumVisualStudioVersion>
<AppxPackage>false</AppxPackage>
</PropertyGroup>
</Otherwise>
</Choose>
<PropertyGroup Label="ReactNativeWindowsProps">
<ReactNativeWindowsDir Condition="'$(ReactNativeWindowsDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(SolutionDir), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\</ReactNativeWindowsDir>
<RunAutolinkCheck Condition="'$(UseFabric)'=='true'">false</RunAutolinkCheck>
</PropertyGroup>
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.WindowsSdk.Default.props" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.WindowsSdk.Default.props')" />
<PropertyGroup Label="Fallback Windows SDK Versions">
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.WindowsSdk.Default.props" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.WindowsSdk.Default.props')"/>
<PropertyGroup Label="Fallback Windows SDK Versions" Condition="'$(UseFabric)'!='true'">
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.19041.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion Condition=" '$(WindowsTargetPlatformMinVersion)' == '' ">10.0.17763.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v143</PlatformToolset>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"></ImportGroup>
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets">
<ImportGroup Label="PropertySheets" Condition="'$(UseFabric)'!='true'">
<Import Project="PropertySheet.props" />
</ImportGroup>
<ImportGroup Label="ReactNativeWindowsPropertySheets">
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\external\Microsoft.ReactNative.Uwp.CppLib.props" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.props')" />
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\external\Microsoft.ReactNative.Uwp.CppLib.props" Condition="'$(UseFabric)'!='true' And Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.props')" />
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppLib.props" Condition="'$(UseFabric)'=='true' And Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppLib.props')" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
@@ -82,17 +102,19 @@
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
<WarningLevel>Level4</WarningLevel>
<SDLCheck>true</SDLCheck>
<AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
<PreprocessorDefinitions>_WINRT_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalUsingDirectories>$(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Midl>
<Midl Condition="'$(UseFabric)'!='true'">
<!-- This allows applications targetting older Windows SDKs (e.g. RNW 0.65 apps) to consume the library generated WinMD -->
<AdditionalOptions>%(AdditionalOptions) /noattributename</AdditionalOptions>
</Midl>
<Link>
<AdditionalDependencies>dxguid.lib;windowsapp.lib;%(AdditionalDependenices)</AdditionalDependencies>
<AdditionalDependencies>dxguid.lib;shell32.lib;user32.lib;windowsapp.lib;%(AdditionalDependenices)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
<GenerateWindowsMetadata>true</GenerateWindowsMetadata>
<ModuleDefinitionFile>RNSVG.def</ModuleDefinitionFile>
@@ -108,10 +130,14 @@
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions Condition="'$(UseFabric)'=='true'">USE_FABRIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="BrushView.h" />
<ClInclude Include="CircleView.h" />
<ClInclude Include="CircleViewManager.h" />
<ClInclude Include="ClipPathView.h" />
<ClInclude Include="D2DBrush.h" />
<ClInclude Include="D2DDevice.h" />
@@ -119,129 +145,139 @@
<ClInclude Include="D2DGeometry.h" />
<ClInclude Include="D2DHelpers.h" />
<ClInclude Include="DefsView.h" />
<ClInclude Include="DefsViewManager.h" />
<ClInclude Include="EllipseView.h" />
<ClInclude Include="EllipseViewManager.h" />
<ClInclude Include="GroupView.h" />
<ClInclude Include="GroupViewManager.h" />
<ClInclude Include="ClipPathViewManager.h" />
<ClInclude Include="ImageView.h" />
<ClInclude Include="ImageViewManager.h" />
<ClInclude Include="LinearGradientView.h" />
<ClInclude Include="LinearGradientViewManager.h" />
<ClInclude Include="LineView.h" />
<ClInclude Include="LineViewManager.h" />
<ClInclude Include="MarkerView.h" />
<ClInclude Include="MarkerViewManager.h" />
<ClInclude Include="MaskView.h" />
<ClInclude Include="MaskViewManager.h" />
<ClInclude Include="PathView.h" />
<ClInclude Include="PathViewManager.h" />
<ClInclude Include="PatternView.h" />
<ClInclude Include="PatternViewManager.h" />
<ClInclude Include="RadialGradientView.h" />
<ClInclude Include="RadialGradientViewManager.h" />
<ClInclude Include="RectView.h" />
<ClInclude Include="RectViewManager.h" />
<ClInclude Include="RenderableView.h" />
<ClInclude Include="RenderableViewManager.h" />
<ClInclude Include="SVGLength.h" />
<ClInclude Include="SvgView.h" />
<ClInclude Include="SvgViewManager.h" />
<ClInclude Include="SymbolView.h" />
<ClInclude Include="SymbolViewManager.h" />
<ClInclude Include="TextView.h" />
<ClInclude Include="TextViewManager.h" />
<ClInclude Include="TSpanView.h" />
<ClInclude Include="TSpanViewManager.h" />
<ClInclude Include="UseView.h" />
<ClInclude Include="UseViewManager.h" />
<ClInclude Include="Utils.h" />
<ClInclude Include="ReactPackageProvider.h">
<DependentUpon>ReactPackageProvider.idl</DependentUpon>
</ClInclude>
<ClInclude Include="RectView.h" />
<ClInclude Include="RenderableView.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="RNSVGModule.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="SVGLength.h" />
<ClInclude Include="SvgView.h" />
<ClInclude Include="SymbolView.h" />
<ClInclude Include="targetver.h" Condition="'$(UseFabric)'=='true'" />
<ClInclude Include="TextView.h" />
<ClInclude Include="TSpanView.h" />
<ClInclude Include="UseView.h" />
<ClInclude Include="Utils.h" />
</ItemGroup>
<ItemGroup Condition="'$(UseFabric)'!='true'">
<ClInclude Include="CircleViewManager.h" />
<ClInclude Include="ClipPathViewManager.h" />
<ClInclude Include="DefsViewManager.h" />
<ClInclude Include="EllipseViewManager.h" />
<ClInclude Include="GroupViewManager.h" />
<ClInclude Include="ImageViewManager.h" />
<ClInclude Include="LinearGradientViewManager.h" />
<ClInclude Include="LineViewManager.h" />
<ClInclude Include="MarkerViewManager.h" />
<ClInclude Include="MaskViewManager.h" />
<ClInclude Include="PathViewManager.h" />
<ClInclude Include="PatternViewManager.h" />
<ClInclude Include="RadialGradientViewManager.h" />
<ClInclude Include="RectViewManager.h" />
<ClInclude Include="RenderableViewManager.h" />
<ClInclude Include="SvgViewManager.h" />
<ClInclude Include="SymbolViewManager.h" />
<ClInclude Include="TextViewManager.h" />
<ClInclude Include="TSpanViewManager.h" />
<ClInclude Include="UseViewManager.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="BrushView.cpp" />
<ClCompile Include="CircleView.cpp" />
<ClCompile Include="CircleViewManager.cpp" />
<ClCompile Include="ClipPathView.cpp" />
<ClCompile Include="ClipPathViewManager.cpp" />
<ClCompile Include="D2DBrush.cpp" />
<ClCompile Include="D2DDevice.cpp" />
<ClCompile Include="D2DDeviceContext.cpp" />
<ClCompile Include="D2DGeometry.cpp" />
<ClCompile Include="DefsView.cpp" />
<ClCompile Include="DefsViewManager.cpp" />
<ClCompile Include="EllipseView.cpp" />
<ClCompile Include="EllipseViewManager.cpp" />
<ClCompile Include="GroupView.cpp" />
<ClCompile Include="GroupViewManager.cpp" />
<ClCompile Include="ImageView.cpp" />
<ClCompile Include="ImageViewManager.cpp" />
<ClCompile Include="LinearGradientView.cpp" />
<ClCompile Include="LinearGradientViewManager.cpp" />
<ClCompile Include="LineView.cpp" />
<ClCompile Include="LineViewManager.cpp" />
<ClCompile Include="MarkerView.cpp" />
<ClCompile Include="MarkerViewManager.cpp" />
<ClCompile Include="MaskView.cpp" />
<ClCompile Include="MaskViewManager.cpp" />
<ClCompile Include="PathView.cpp" />
<ClCompile Include="PatternView.cpp" />
<ClCompile Include="PatternViewManager.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="PathViewManager.cpp" />
<ClCompile Include="RadialGradientView.cpp" />
<ClCompile Include="RadialGradientViewManager.cpp" />
<ClCompile Include="ReactPackageProvider.cpp">
<DependentUpon>ReactPackageProvider.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<ClCompile Include="RectView.cpp" />
<ClCompile Include="RectViewManager.cpp" />
<ClCompile Include="RenderableView.cpp" />
<ClCompile Include="RenderableViewManager.cpp" />
<ClCompile Include="SVGLength.cpp" />
<ClCompile Include="SvgView.cpp" />
<ClCompile Include="SvgViewManager.cpp" />
<ClCompile Include="SymbolView.cpp" />
<ClCompile Include="SymbolViewManager.cpp" />
<ClCompile Include="TextView.cpp" />
<ClCompile Include="TextViewManager.cpp" />
<ClCompile Include="TSpanView.cpp" />
<ClCompile Include="TSpanViewManager.cpp" />
<ClCompile Include="UseView.cpp" />
</ItemGroup>
<ItemGroup Condition="'$(UseFabric)'!='true'">
<ClCompile Include="CircleViewManager.cpp" />
<ClCompile Include="ClipPathViewManager.cpp" />
<ClCompile Include="DefsViewManager.cpp" />
<ClCompile Include="EllipseViewManager.cpp" />
<ClCompile Include="GroupViewManager.cpp" />
<ClCompile Include="ImageViewManager.cpp" />
<ClCompile Include="LinearGradientViewManager.cpp" />
<ClCompile Include="LineViewManager.cpp" />
<ClCompile Include="MarkerViewManager.cpp" />
<ClCompile Include="MaskViewManager.cpp" />
<ClCompile Include="PathViewManager.cpp" />
<ClCompile Include="PatternViewManager.cpp" />
<ClCompile Include="RadialGradientViewManager.cpp" />
<ClCompile Include="RectViewManager.cpp" />
<ClCompile Include="RenderableViewManager.cpp" />
<ClCompile Include="SvgViewManager.cpp" />
<ClCompile Include="SymbolViewManager.cpp" />
<ClCompile Include="TextViewManager.cpp" />
<ClCompile Include="TSpanViewManager.cpp" />
<ClCompile Include="UseViewManager.cpp" />
</ItemGroup>
<ItemGroup>
<Midl Include="Fabric.idl" Condition="'$(UseFabric)'=='true'" />
<Midl Include="Paper.idl" Condition="'$(UseFabric)'!='true'" />
<Midl Include="ReactPackageProvider.idl" />
<Midl Include="Types.idl" />
<Midl Include="Views.idl">
<SubType>Designer</SubType>
</Midl>
<Midl Include="ViewManagers.idl">
<SubType>Designer</SubType>
</Midl>
<Midl Include="ViewManagers.idl" Condition="'$(UseFabric)'!='true'" />
<Midl Include="ViewProps.idl" Condition="'$(UseFabric)'=='true'" />
<Midl Include="Views.idl" />
</ItemGroup>
<ItemGroup>
<ItemGroup Condition="'$(UseFabric)'!='true'">
<None Include="PropertySheet.props" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="RNSVG.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ReactNativeWindowsTargets">
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.targets" Condition="Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.targets')" />
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.targets" Condition="'$(UseFabric)'!='true' And Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.targets')" />
<Import Project="$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppLib.targets" Condition="'$(UseFabric)'=='true' And Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppLib.targets')" />
</ImportGroup>
<Target Name="EnsureReactNativeWindowsTargets" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references targets in your node_modules\react-native-windows folder that are missing. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.props')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.props'))" />
<Error Condition="!Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.targets'))" />
<Error Condition="'$(UseFabric)'!='true' And !Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.props')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.props'))" />
<Error Condition="'$(UseFabric)'!='true' And !Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Uwp.CppLib.targets'))" />
<Error Condition="'$(UseFabric)'=='true' And !Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppLib.props')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppLib.props'))" />
<Error Condition="'$(UseFabric)'=='true' And !Exists('$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppLib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(ReactNativeWindowsDir)\PropertySheets\External\Microsoft.ReactNative.Composition.CppLib.targets'))" />
</Target>
</Project>

View File

@@ -5,329 +5,355 @@
<Midl Include="Views.idl">
<Filter>IDLs</Filter>
</Midl>
<Midl Include="ViewProps.idl">
<Filter>IDLs</Filter>
</Midl>
<Midl Include="ViewManagers.idl">
<Filter>IDLs</Filter>
</Midl>
<Midl Include="Types.idl">
<Filter>IDLs</Filter>
</Midl>
<Midl Include="Paper.idl">
<Filter>IDLs</Filter>
</Midl>
<Midl Include="Fabric.idl">
<Filter>IDLs</Filter>
</Midl>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp" />
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<ClCompile Include="ReactPackageProvider.cpp" />
<ClCompile Include="RectView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="SVGLength.cpp">
<Filter>Utils</Filter>
</ClCompile>
<ClCompile Include="RectViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="PathViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="PathView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="GroupView.cpp">
<Filter>Views\GroupViews</Filter>
</ClCompile>
<ClCompile Include="TextView.cpp">
<Filter>Views\GroupViews</Filter>
</ClCompile>
<ClCompile Include="TSpanView.cpp">
<Filter>Views\GroupViews</Filter>
</ClCompile>
<ClCompile Include="CircleView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="CircleViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="DefsViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="EllipseViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="EllipseView.cpp">
<Filter>Views</Filter>
<ClCompile Include="ImageViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="LineViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="PathViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="RectViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="RenderableViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="SvgViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="UseViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="D2DBrush.cpp">
<Filter>D2DWrappers</Filter>
</ClCompile>
<ClCompile Include="D2DDevice.cpp">
<Filter>D2DWrappers</Filter>
</ClCompile>
<ClCompile Include="D2DDeviceContext.cpp">
<Filter>D2DWrappers</Filter>
</ClCompile>
<ClCompile Include="D2DGeometry.cpp">
<Filter>D2DWrappers</Filter>
</ClCompile>
<ClCompile Include="PathView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="LineView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="ImageView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="EllipseView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="CircleView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="ClipPathView.cpp">
<Filter>Views\Group</Filter>
</ClCompile>
<ClCompile Include="DefsView.cpp">
<Filter>Views\Group</Filter>
</ClCompile>
<ClCompile Include="GroupView.cpp">
<Filter>Views\Group</Filter>
</ClCompile>
<ClCompile Include="MarkerView.cpp">
<Filter>Views\Group</Filter>
</ClCompile>
<ClCompile Include="MaskView.cpp">
<Filter>Views\Group</Filter>
</ClCompile>
<ClCompile Include="SymbolView.cpp">
<Filter>Views\Group</Filter>
</ClCompile>
<ClCompile Include="BrushView.cpp">
<Filter>Views\Group\Brush</Filter>
</ClCompile>
<ClCompile Include="LinearGradientView.cpp">
<Filter>Views\Group\Brush</Filter>
</ClCompile>
<ClCompile Include="PatternView.cpp">
<Filter>Views\Group\Brush</Filter>
</ClCompile>
<ClCompile Include="RadialGradientView.cpp">
<Filter>Views\Group\Brush</Filter>
</ClCompile>
<ClCompile Include="RenderableView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="SvgView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="SymbolView.cpp">
<Filter>Views\GroupViews</Filter>
</ClCompile>
<ClCompile Include="SvgViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="RenderableViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="GroupViewManager.cpp">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClCompile>
<ClCompile Include="TextViewManager.cpp">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClCompile>
<ClCompile Include="TSpanViewManager.cpp">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClCompile>
<ClCompile Include="UseView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="SymbolViewManager.cpp">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClCompile>
<ClCompile Include="UseViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="DefsViewManager.cpp">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClCompile>
<ClCompile Include="LinearGradientViewManager.cpp">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClCompile>
<ClCompile Include="DefsView.cpp">
<Filter>Views\GroupViews</Filter>
</ClCompile>
<ClCompile Include="LinearGradientView.cpp">
<Filter>Views\GroupViews</Filter>
</ClCompile>
<ClCompile Include="BrushView.cpp">
<ClCompile Include="RectView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="PatternViewManager.cpp">
<Filter>ViewManagers\GroupViewManagers</Filter>
<ClCompile Include="TextView.cpp">
<Filter>Views\Group\Text</Filter>
</ClCompile>
<ClCompile Include="PatternView.cpp">
<Filter>Views\GroupViews</Filter>
<ClCompile Include="TSpanView.cpp">
<Filter>Views\Group\Text</Filter>
</ClCompile>
<ClCompile Include="ImageView.cpp">
<Filter>Views</Filter>
</ClCompile>
<ClCompile Include="ImageViewManager.cpp">
<Filter>ViewManagers</Filter>
</ClCompile>
<ClCompile Include="RadialGradientView.cpp">
<Filter>Views\GroupViews</Filter>
</ClCompile>
<ClCompile Include="RadialGradientViewManager.cpp">
<Filter>ViewManagers\GroupViewManagers</Filter>
<ClCompile Include="SVGLength.cpp">
<Filter>Utils</Filter>
</ClCompile>
<ClCompile Include="ClipPathViewManager.cpp">
<Filter>ViewManagers\GroupViewManagers</Filter>
<Filter>ViewManagers\Group</Filter>
</ClCompile>
<ClCompile Include="ClipPathView.cpp">
<Filter>Views\GroupViews</Filter>
</ClCompile>
<ClCompile Include="D2DGeometry.cpp">
<Filter>D2DWrappers</Filter>
<ClCompile Include="GroupViewManager.cpp">
<Filter>ViewManagers\Group</Filter>
</ClCompile>
<ClCompile Include="MarkerViewManager.cpp">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClCompile>
<ClCompile Include="MarkerView.cpp">
<Filter>Views\GroupViews</Filter>
</ClCompile>
<ClCompile Include="D2DDeviceContext.cpp">
<Filter>D2DWrappers</Filter>
</ClCompile>
<ClCompile Include="D2DDevice.cpp">
<Filter>D2DWrappers</Filter>
</ClCompile>
<ClCompile Include="D2DBrush.cpp">
<Filter>D2DWrappers</Filter>
</ClCompile>
<ClCompile Include="MaskView.cpp">
<Filter>Views\GroupViews</Filter>
<Filter>ViewManagers\Group</Filter>
</ClCompile>
<ClCompile Include="MaskViewManager.cpp">
<Filter>ViewManagers\GroupViewManagers</Filter>
<Filter>ViewManagers\Group</Filter>
</ClCompile>
<ClCompile Include="SymbolViewManager.cpp">
<Filter>ViewManagers\Group</Filter>
</ClCompile>
<ClCompile Include="LinearGradientViewManager.cpp">
<Filter>ViewManagers\Group\Brush</Filter>
</ClCompile>
<ClCompile Include="PatternViewManager.cpp">
<Filter>ViewManagers\Group\Brush</Filter>
</ClCompile>
<ClCompile Include="RadialGradientViewManager.cpp">
<Filter>ViewManagers\Group\Brush</Filter>
</ClCompile>
<ClCompile Include="TextViewManager.cpp">
<Filter>ViewManagers\Group\Text</Filter>
</ClCompile>
<ClCompile Include="TSpanViewManager.cpp">
<Filter>ViewManagers\Group\Text</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="ReactPackageProvider.h" />
<ClInclude Include="RNSVGModule.h" />
<ClInclude Include="RectView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="Utils.h">
<Filter>Utils</Filter>
</ClInclude>
<ClInclude Include="SVGLength.h">
<Filter>Utils</Filter>
</ClInclude>
<ClInclude Include="RectViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="PathViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="PathView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="GroupView.h">
<Filter>Views\GroupViews</Filter>
</ClInclude>
<ClInclude Include="TextView.h">
<Filter>Views\GroupViews</Filter>
</ClInclude>
<ClInclude Include="TSpanView.h">
<Filter>Views\GroupViews</Filter>
</ClInclude>
<ClInclude Include="CircleView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="resource.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="CircleViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="DefsViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="EllipseViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="EllipseView.h">
<Filter>Views</Filter>
<ClInclude Include="ImageViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="LineViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="LineView.h">
<Filter>Views</Filter>
<ClInclude Include="PathViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="RenderableView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="SvgView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="SymbolView.h">
<Filter>Views\GroupViews</Filter>
</ClInclude>
<ClInclude Include="SvgViewManager.h">
<ClInclude Include="RectViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="RenderableViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="GroupViewManager.h">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClInclude>
<ClInclude Include="TextViewManager.h">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClInclude>
<ClInclude Include="TSpanViewManager.h">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClInclude>
<ClInclude Include="UseView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="SymbolViewManager.h">
<Filter>ViewManagers\GroupViewManagers</Filter>
<ClInclude Include="SvgViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="UseViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="DefsViewManager.h">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClInclude>
<ClInclude Include="LinearGradientViewManager.h">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClInclude>
<ClInclude Include="DefsView.h">
<Filter>Views\GroupViews</Filter>
</ClInclude>
<ClInclude Include="LinearGradientView.h">
<Filter>Views\GroupViews</Filter>
</ClInclude>
<ClInclude Include="BrushView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="PatternViewManager.h">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClInclude>
<ClInclude Include="PatternView.h">
<Filter>Views\GroupViews</Filter>
</ClInclude>
<ClInclude Include="ImageView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="ImageViewManager.h">
<Filter>ViewManagers</Filter>
</ClInclude>
<ClInclude Include="RadialGradientView.h">
<Filter>Views\GroupViews</Filter>
</ClInclude>
<ClInclude Include="RadialGradientViewManager.h">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClInclude>
<ClInclude Include="ClipPathViewManager.h">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClInclude>
<ClInclude Include="ClipPathView.h">
<Filter>Views\GroupViews</Filter>
</ClInclude>
<ClInclude Include="D2DHelpers.h">
<Filter>Utils</Filter>
</ClInclude>
<ClInclude Include="D2DGeometry.h">
<Filter>D2DWrappers</Filter>
</ClInclude>
<ClInclude Include="MarkerViewManager.h">
<Filter>ViewManagers\GroupViewManagers</Filter>
</ClInclude>
<ClInclude Include="MarkerView.h">
<Filter>Views\GroupViews</Filter>
</ClInclude>
<ClInclude Include="D2DDeviceContext.h">
<ClInclude Include="D2DBrush.h">
<Filter>D2DWrappers</Filter>
</ClInclude>
<ClInclude Include="D2DDevice.h">
<Filter>D2DWrappers</Filter>
</ClInclude>
<ClInclude Include="D2DBrush.h">
<ClInclude Include="D2DDeviceContext.h">
<Filter>D2DWrappers</Filter>
</ClInclude>
<ClInclude Include="D2DGeometry.h">
<Filter>D2DWrappers</Filter>
</ClInclude>
<ClInclude Include="D2DHelpers.h">
<Filter>Utils</Filter>
</ClInclude>
<ClInclude Include="SVGLength.h">
<Filter>Utils</Filter>
</ClInclude>
<ClInclude Include="Utils.h">
<Filter>Utils</Filter>
</ClInclude>
<ClInclude Include="UseView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="SvgView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="RenderableView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="RectView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="PathView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="LineView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="ImageView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="EllipseView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="CircleView.h">
<Filter>Views</Filter>
</ClInclude>
<ClInclude Include="ClipPathView.h">
<Filter>Views\Group</Filter>
</ClInclude>
<ClInclude Include="DefsView.h">
<Filter>Views\Group</Filter>
</ClInclude>
<ClInclude Include="GroupView.h">
<Filter>Views\Group</Filter>
</ClInclude>
<ClInclude Include="MarkerView.h">
<Filter>Views\Group</Filter>
</ClInclude>
<ClInclude Include="MaskView.h">
<Filter>Views\GroupViews</Filter>
<Filter>Views\Group</Filter>
</ClInclude>
<ClInclude Include="SymbolView.h">
<Filter>Views\Group</Filter>
</ClInclude>
<ClInclude Include="BrushView.h">
<Filter>Views\Group\Brush</Filter>
</ClInclude>
<ClInclude Include="LinearGradientView.h">
<Filter>Views\Group\Brush</Filter>
</ClInclude>
<ClInclude Include="PatternView.h">
<Filter>Views\Group\Brush</Filter>
</ClInclude>
<ClInclude Include="RadialGradientView.h">
<Filter>Views\Group\Brush</Filter>
</ClInclude>
<ClInclude Include="TextView.h">
<Filter>Views\Group\Text</Filter>
</ClInclude>
<ClInclude Include="TSpanView.h">
<Filter>Views\Group\Text</Filter>
</ClInclude>
<ClInclude Include="ClipPathViewManager.h">
<Filter>ViewManagers\Group</Filter>
</ClInclude>
<ClInclude Include="GroupViewManager.h">
<Filter>ViewManagers\Group</Filter>
</ClInclude>
<ClInclude Include="MarkerViewManager.h">
<Filter>ViewManagers\Group</Filter>
</ClInclude>
<ClInclude Include="MaskViewManager.h">
<Filter>ViewManagers\GroupViewManagers</Filter>
<Filter>ViewManagers\Group</Filter>
</ClInclude>
<ClInclude Include="SymbolViewManager.h">
<Filter>ViewManagers\Group</Filter>
</ClInclude>
<ClInclude Include="LinearGradientViewManager.h">
<Filter>ViewManagers\Group\Brush</Filter>
</ClInclude>
<ClInclude Include="PatternViewManager.h">
<Filter>ViewManagers\Group\Brush</Filter>
</ClInclude>
<ClInclude Include="RadialGradientViewManager.h">
<Filter>ViewManagers\Group\Brush</Filter>
</ClInclude>
<ClInclude Include="TextViewManager.h">
<Filter>ViewManagers\Group\Text</Filter>
</ClInclude>
<ClInclude Include="TSpanViewManager.h">
<Filter>ViewManagers\Group\Text</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="PropertySheet.props" />
</ItemGroup>
<ItemGroup>
<Filter Include="Views">
<UniqueIdentifier>{e902587e-fe1d-4643-875b-d58996b40d98}</UniqueIdentifier>
</Filter>
<Filter Include="ViewManagers">
<UniqueIdentifier>{cb3ce7b2-9fdf-4578-8e0d-4d6853b727bc}</UniqueIdentifier>
</Filter>
<Filter Include="Utils">
<UniqueIdentifier>{8a4e0664-0d52-46ca-b476-a1ad90239a09}</UniqueIdentifier>
</Filter>
<Filter Include="Views\GroupViews">
<UniqueIdentifier>{96f26034-8559-4794-a806-4ecac541e02b}</UniqueIdentifier>
</Filter>
<Filter Include="ViewManagers\GroupViewManagers">
<UniqueIdentifier>{5942afc3-8b5d-4d8c-bb09-e82581f606b7}</UniqueIdentifier>
</Filter>
<Filter Include="IDLs">
<UniqueIdentifier>{50f81ae3-d543-477a-a60c-a0f310289f29}</UniqueIdentifier>
<UniqueIdentifier>{3cca2e46-5d4d-47f9-ab24-a74775813566}</UniqueIdentifier>
</Filter>
<Filter Include="D2DWrappers">
<UniqueIdentifier>{d4e16389-e870-4046-b1fe-61bc171edad9}</UniqueIdentifier>
<UniqueIdentifier>{11cd109d-9693-4379-b313-91e84a088dc8}</UniqueIdentifier>
</Filter>
<Filter Include="IDLs">
<UniqueIdentifier>{01cd3fc8-d908-49ea-ac93-8a059a60ee52}</UniqueIdentifier>
</Filter>
<Filter Include="Utils">
<UniqueIdentifier>{55dd67d5-d7d5-46de-9b24-19c9be48ccf0}</UniqueIdentifier>
</Filter>
<Filter Include="Views">
<UniqueIdentifier>{7ca32ee4-8ca3-4d97-bda7-0e97f99bc602}</UniqueIdentifier>
</Filter>
<Filter Include="Views\Group">
<UniqueIdentifier>{77129028-b876-41ef-8a85-ac26692ba778}</UniqueIdentifier>
</Filter>
<Filter Include="Views\Group\Brush">
<UniqueIdentifier>{6d94c69a-4512-4f21-9ae1-f69a4c26bef2}</UniqueIdentifier>
</Filter>
<Filter Include="Views\Group\Text">
<UniqueIdentifier>{e3339b4a-0b3f-462c-a379-5d273e5983c8}</UniqueIdentifier>
</Filter>
<Filter Include="ViewManagers\Group">
<UniqueIdentifier>{a05877e3-02b7-4cb9-9068-a53577e33c6d}</UniqueIdentifier>
</Filter>
<Filter Include="ViewManagers\Group\Brush">
<UniqueIdentifier>{c64cf11f-6756-40fa-ad9d-4b0a6ec9352a}</UniqueIdentifier>
</Filter>
<Filter Include="ViewManagers\Group\Text">
<UniqueIdentifier>{89263b15-eac2-4cbd-9e22-0ddbbb893da3}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="RNSVG.rc" />
</ItemGroup>
</Project>

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "RadialGradientView.h"
#if __has_include("RadialGradientView.g.cpp")
#include "RadialGradientView.g.cpp"
#endif
#include "Utils.h"
@@ -8,6 +10,59 @@ using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
RadialGradientProps::RadialGradientProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void RadialGradientProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
RadialGradientView::RadialGradientView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args)
: base_type(args) {}
void RadialGradientView::RegisterComponent(
const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGRadialGradient", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::RadialGradientProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::RadialGradientView>(args);
});
});
}
void RadialGradientView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto radialGradientProps = props.try_as<RadialGradientProps>();
if (radialGradientProps) {
m_props = radialGradientProps;
m_rx = m_props->rx;
m_ry = m_props->ry;
m_fx = m_props->fx;
m_fy = m_props->fy;
m_cx = m_props->cx;
m_cy = m_props->cy;
m_stops = Utils::JSValueAsGradientStops(m_props->gradient);
m_gradientUnits = Utils::JSValueAsBrushUnits(m_props->gradientUnits);
m_transform = Utils::JSValueAsD2DTransform(m_props->gradientTransform);
}
base_type::UpdateProperties(props, oldProps, forceUpdate, invalidate);
SaveDefinition();
}
#else
void RadialGradientView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, bool invalidate) {
const JSValueObject &propertyMap{JSValue::ReadObjectFrom(reader)};
@@ -16,17 +71,17 @@ void RadialGradientView::UpdateProperties(IJSValueReader const &reader, bool for
auto const &propertyValue{pair.second};
if (propertyName == "fx") {
m_fx = SVGLength::From(propertyValue);
m_fx = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "fy") {
m_fy = SVGLength::From(propertyValue);
m_fy = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "rx") {
m_rx = SVGLength::From(propertyValue);
m_rx = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "ry") {
m_ry = SVGLength::From(propertyValue);
m_ry = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "cx") {
m_cx = SVGLength::From(propertyValue);
m_cx = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "cy") {
m_cy = SVGLength::From(propertyValue);
m_cy = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "gradient") {
m_stops = Utils::JSValueAsStops(propertyValue);
} else if (propertyName == "gradientUnits") {
@@ -44,6 +99,7 @@ void RadialGradientView::UpdateProperties(IJSValueReader const &reader, bool for
SaveDefinition();
}
#endif
void RadialGradientView::Unload() {
m_stops.clear();
@@ -60,10 +116,10 @@ void RadialGradientView::CreateBrush() {
D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES brushProperties{};
winrt::com_ptr<ID2D1RadialGradientBrush> radialBrush;
winrt::check_hresult(
deviceContext->CreateRadialGradientBrush(brushProperties, stopCollection.get(), radialBrush.put()));
winrt::check_hresult(deviceContext->CreateRadialGradientBrush(brushProperties, stopCollection.get(), radialBrush.put()));
SetPoints(radialBrush.get(), {0, 0, static_cast<float>(root.ActualWidth()), static_cast<float>(root.ActualHeight())});
auto size{root.CanvasSize()};
SetPoints(radialBrush.get(), {0, 0, size.Width, size.Height});
if (!m_transform.IsIdentity()) {
radialBrush->SetTransform(m_transform);

View File

@@ -1,14 +1,67 @@
#pragma once
#ifdef USE_FABRIC
#include "RadialGradientProps.g.h"
#endif
#include "RadialGradientView.g.h"
#include "BrushView.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(RadialGradientProps)
struct RadialGradientProps : RadialGradientPropsT<RadialGradientProps, SvgGroupCommonProps> {
RadialGradientProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_FIELD(fx)
RNSVG::SVGLength fx{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(fy)
RNSVG::SVGLength fy{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(cx)
RNSVG::SVGLength cx{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(cy)
RNSVG::SVGLength cy{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(rx)
RNSVG::SVGLength rx{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(ry)
RNSVG::SVGLength ry{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(gradient)
std::optional<std::vector<float>> gradient{};
REACT_FIELD(gradientUnits)
std::optional<int32_t> gradientUnits;
REACT_FIELD(gradientTransform)
std::optional<std::vector<float>> gradientTransform;
};
#endif
struct RadialGradientView : RadialGradientViewT<RadialGradientView, RNSVG::implementation::BrushView> {
public:
RadialGradientView() = default;
// RenderableView
#ifdef USE_FABRIC
RadialGradientView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept override;
#else
// IRenderablePaper
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate, bool invalidate);
#endif
// IRenderable
void Unload();
private:
@@ -21,6 +74,11 @@ struct RadialGradientView : RadialGradientViewT<RadialGradientView, RNSVG::imple
std::vector<D2D1_GRADIENT_STOP> m_stops{};
std::string m_gradientUnits{"objectBoundingBox"};
#ifdef USE_FABRIC
com_ptr<RadialGradientProps> m_props;
#endif
// BrushView
void CreateBrush();
void UpdateBounds();
void SetPoints(ID2D1RadialGradientBrush *brush, D2D1_RECT_F bounds);

View File

@@ -1,6 +1,8 @@
#include "pch.h"
#include "RadialGradientViewManager.h"
#if __has_include("RadialGradientViewManager.g.cpp")
#include "RadialGradientViewManager.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::ReactNative;

View File

@@ -5,25 +5,48 @@
#endif
#include "RNSVGModule.h"
#ifdef USE_FABRIC
#include "SvgView.h"
#include "RectView.h"
#include "CircleView.h"
#include "EllipseView.h"
#include "LineView.h"
#include "PathView.h"
#include "ImageView.h"
#include "UseView.h"
#include "GroupView.h"
#include "SymbolView.h"
#include "DefsView.h"
#include "ClipPathView.h"
#include "MarkerView.h"
#include "MaskView.h"
#include "LinearGradientView.h"
#include "RadialGradientView.h"
#include "PatternView.h"
#include "TextView.h"
#include "TSpanView.h"
#else
#include "SvgViewManager.h"
#include "GroupViewManager.h"
#include "PathViewManager.h"
#include "RectViewManager.h"
#include "CircleViewManager.h"
#include "EllipseViewManager.h"
#include "LineViewManager.h"
#include "UseViewManager.h"
#include "PathViewManager.h"
#include "ImageViewManager.h"
#include "TextViewManager.h"
#include "TSpanViewManager.h"
#include "UseViewManager.h"
#include "SymbolViewManager.h"
#include "DefsViewManager.h"
#include "LinearGradientViewManager.h"
#include "RadialGradientViewManager.h"
#include "PatternViewManager.h"
#include "ClipPathViewManager.h"
#include "MarkerViewManager.h"
#include "MaskViewManager.h"
#include "LinearGradientViewManager.h"
#include "RadialGradientViewManager.h"
#include "PatternViewManager.h"
#include "TextViewManager.h"
#include "TSpanViewManager.h"
#endif
using namespace winrt::Microsoft::ReactNative;
@@ -32,25 +55,51 @@ namespace winrt::RNSVG::implementation
void ReactPackageProvider::CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept
{
AddAttributedModules(packageBuilder);
#ifdef USE_FABRIC
auto fabricPackageBuilder = packageBuilder.as<winrt::Microsoft::ReactNative::IReactPackageBuilderFabric>();
SvgView::RegisterComponent(fabricPackageBuilder);
RectView::RegisterComponent(fabricPackageBuilder);
CircleView::RegisterComponent(fabricPackageBuilder);
EllipseView::RegisterComponent(fabricPackageBuilder);
LineView::RegisterComponent(fabricPackageBuilder);
PathView::RegisterComponent(fabricPackageBuilder);
ImageView::RegisterComponent(fabricPackageBuilder);
UseView::RegisterComponent(fabricPackageBuilder);
GroupView::RegisterComponent(fabricPackageBuilder);
SymbolView::RegisterComponent(fabricPackageBuilder);
DefsView::RegisterComponent(fabricPackageBuilder);
ClipPathView::RegisterComponent(fabricPackageBuilder);
MarkerView::RegisterComponent(fabricPackageBuilder);
MaskView::RegisterComponent(fabricPackageBuilder);
LinearGradientView::RegisterComponent(fabricPackageBuilder);
RadialGradientView::RegisterComponent(fabricPackageBuilder);
PatternView::RegisterComponent(fabricPackageBuilder);
TextView::RegisterComponent(fabricPackageBuilder);
TSpanView::RegisterComponent(fabricPackageBuilder);
#else
packageBuilder.AddViewManager(L"SvgViewManager", []() { return winrt::make<SvgViewManager>(); });
packageBuilder.AddViewManager(L"GroupViewManager", []() { return winrt::make<GroupViewManager>(); });
packageBuilder.AddViewManager(L"PathViewManager", []() { return winrt::make<PathViewManager>(); });
packageBuilder.AddViewManager(L"RectViewManager", []() { return winrt::make<RectViewManager>(); });
packageBuilder.AddViewManager(L"CircleViewManager", []() { return winrt::make<CircleViewManager>(); });
packageBuilder.AddViewManager(L"EllipseViewManager", []() { return winrt::make<EllipseViewManager>(); });
packageBuilder.AddViewManager(L"LineViewManager", []() { return winrt::make<LineViewManager>(); });
packageBuilder.AddViewManager(L"UseViewManager", []() { return winrt::make<UseViewManager>(); });
packageBuilder.AddViewManager(L"PathViewManager", []() { return winrt::make<PathViewManager>(); });
packageBuilder.AddViewManager(L"ImageViewManager", []() { return winrt::make<ImageViewManager>(); });
packageBuilder.AddViewManager(L"TextViewManager", []() { return winrt::make<TextViewManager>(); });
packageBuilder.AddViewManager(L"TSpanViewManager", []() { return winrt::make<TSpanViewManager>(); });
packageBuilder.AddViewManager(L"UseViewManager", []() { return winrt::make<UseViewManager>(); });
packageBuilder.AddViewManager(L"GroupViewManager", []() { return winrt::make<GroupViewManager>(); });
packageBuilder.AddViewManager(L"SymbolViewManager", []() { return winrt::make<SymbolViewManager>(); });
packageBuilder.AddViewManager(L"DefsViewManager", []() { return winrt::make<DefsViewManager>(); });
packageBuilder.AddViewManager(L"LinearGradientViewManager", []() { return winrt::make<LinearGradientViewManager>(); });
packageBuilder.AddViewManager(L"RadialGradientViewManager", []() { return winrt::make<RadialGradientViewManager>(); });
packageBuilder.AddViewManager(L"PatternViewManager", []() { return winrt::make<PatternViewManager>(); });
packageBuilder.AddViewManager(L"ClipPathViewManager", []() { return winrt::make<ClipPathViewManager>(); });
packageBuilder.AddViewManager(L"MarkerViewManager", []() { return winrt::make<MarkerViewManager>(); });
packageBuilder.AddViewManager(L"MaskViewManager", []() { return winrt::make<MaskViewManager>(); });
packageBuilder.AddViewManager(L"LinearGradientViewManager", []() { return winrt::make<LinearGradientViewManager>(); });
packageBuilder.AddViewManager(L"RadialGradientViewManager", []() { return winrt::make<RadialGradientViewManager>(); });
packageBuilder.AddViewManager(L"PatternViewManager", []() { return winrt::make<PatternViewManager>(); });
packageBuilder.AddViewManager(L"TextViewManager", []() { return winrt::make<TextViewManager>(); });
packageBuilder.AddViewManager(L"TSpanViewManager", []() { return winrt::make<TSpanViewManager>(); });
#endif
}
} // namespace winrt::RNSVG::implementation

View File

@@ -11,6 +11,51 @@ using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
RectProps::RectProps(const winrt::Microsoft::ReactNative::ViewProps &props) : base_type(props) {}
void RectProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
RectView::RectView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) : base_type(args) {}
void RectView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(
L"RNSVGRect", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::RectProps>(props);
});
builder.SetCreateComponentView([](const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args) noexcept {
return winrt::make<winrt::RNSVG::implementation::RectView>(args);
});
});
}
void RectView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto rectProps = props.try_as<RectProps>();
if (rectProps) {
m_props = rectProps;
m_x = m_props->x;
m_y = m_props->y;
m_width = m_props->width;
m_height = m_props->height;
m_rx = m_props->rx;
m_ry = m_props->ry;
}
base_type::UpdateProperties(props, oldProps, forceUpdate, invalidate);
}
#else
void RectView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, bool invalidate) {
const JSValueObject &propertyMap{JSValue::ReadObjectFrom(reader)};
@@ -19,37 +64,40 @@ void RectView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate,
auto const &propertyValue{pair.second};
if (propertyName == "width") {
m_width = SVGLength::From(propertyValue);
m_width = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "height") {
m_height = SVGLength::From(propertyValue);
m_height = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "x") {
m_x = SVGLength::From(propertyValue);
m_x = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "y") {
m_y = SVGLength::From(propertyValue);
m_y = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "rx") {
m_rx = SVGLength::From(propertyValue);
m_rx = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "ry") {
m_ry = SVGLength::From(propertyValue);
m_ry = propertyValue.To<RNSVG::SVGLength>();
}
}
__super::UpdateProperties(reader, forceUpdate, invalidate);
}
#endif
void RectView::CreateGeometry() {
void RectView::CreateGeometry(RNSVG::D2DDeviceContext const &context) {
auto const &root{SvgRoot()};
auto const size{root.CanvasSize()};
float x{Utils::GetAbsoluteLength(m_x, root.ActualWidth())};
float y{Utils::GetAbsoluteLength(m_y, root.ActualHeight())};
float width{Utils::GetAbsoluteLength(m_width, root.ActualWidth())};
float height{Utils::GetAbsoluteLength(m_height, root.ActualHeight())};
float x{Utils::GetAbsoluteLength(m_x, size.Width)};
float y{Utils::GetAbsoluteLength(m_y, size.Height)};
float width{Utils::GetAbsoluteLength(m_width, size.Width)};
float height{Utils::GetAbsoluteLength(m_height, size.Height)};
auto const rxLength{m_rx.Unit() == RNSVG::LengthType::Unknown ? m_ry : m_rx};
auto const ryLength{m_ry.Unit() == RNSVG::LengthType::Unknown ? m_rx : m_ry};
float rx{Utils::GetAbsoluteLength(rxLength, root.ActualWidth())};
float ry{Utils::GetAbsoluteLength(ryLength, root.ActualHeight())};
auto const rxLength{m_rx.Unit == RNSVG::LengthType::Unknown ? m_ry : m_rx};
auto const ryLength{m_ry.Unit == RNSVG::LengthType::Unknown ? m_rx : m_ry};
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(root.DeviceContext())->Get()};
float rx{Utils::GetAbsoluteLength(rxLength, size.Width)};
float ry{Utils::GetAbsoluteLength(ryLength, size.Height)};
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(context)->Get()};
com_ptr<ID2D1Factory> factory;
deviceContext->GetFactory(factory.put());

View File

@@ -1,15 +1,62 @@
#pragma once
#ifdef USE_FABRIC
#include "RectProps.g.h"
#endif
#include "RectView.g.h"
#include "RenderableView.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(RectProps)
struct RectProps : RectPropsT<RectProps, SvgRenderableCommonProps> {
RectProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept
override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
REACT_FIELD(x)
RNSVG::SVGLength x{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(y)
RNSVG::SVGLength y{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(height)
RNSVG::SVGLength height{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(width)
RNSVG::SVGLength width{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(rx)
RNSVG::SVGLength rx{0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(ry)
RNSVG::SVGLength ry{0, winrt::RNSVG::LengthType::Unknown};
};
#endif
struct RectView : RectViewT<RectView, RNSVG::implementation::RenderableView> {
public:
RectView() = default;
#ifdef USE_FABRIC
RectView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept override;
#else
// IRenderablePaper
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate, bool invalidate);
void CreateGeometry();
#endif
// IRenderable
void CreateGeometry(RNSVG::D2DDeviceContext const &context);
private:
RNSVG::SVGLength m_width{};
@@ -18,6 +65,10 @@ struct RectView : RectViewT<RectView, RNSVG::implementation::RenderableView> {
RNSVG::SVGLength m_y{};
RNSVG::SVGLength m_rx{};
RNSVG::SVGLength m_ry{};
#ifdef USE_FABRIC
com_ptr<RectProps> m_props;
#endif
};
} // namespace winrt::RNSVG::implementation

View File

@@ -12,6 +12,399 @@ using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
SvgNodeCommonProps::SvgNodeCommonProps(
const winrt::Microsoft::ReactNative::ViewProps &props)
: m_props(props) {}
void SvgNodeCommonProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
SvgRenderableCommonProps::SvgRenderableCommonProps(
const winrt::Microsoft::ReactNative::ViewProps &props)
: base_type(props) {}
void SvgRenderableCommonProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
RenderableView::RenderableView(
const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args)
: base_type(args), m_reactContext(args.ReactContext()) {}
void RenderableView::MountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept {
const RNSVG::RenderableView &view{*this};
const auto &group{view.try_as<RNSVG::GroupView>()};
const auto &child{childComponentView.try_as<IRenderable>()};
if (group && child) {
base_type::MountChildComponentView(childComponentView, index);
child.MergeProperties(*this);
if (child.IsResponsible() && !IsResponsible()) {
IsResponsible(true);
}
if (auto const &root{SvgRoot()}) {
root.Invalidate();
}
}
}
void RenderableView::UnmountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept {
const RNSVG::RenderableView &view{*this};
const auto &group{view.try_as<RNSVG::GroupView>()};
const auto &child{childComponentView.try_as<IRenderable>()};
if (group && child) {
if (!IsUnloaded()) {
child.Unload();
}
base_type::UnmountChildComponentView(childComponentView, index);
if (auto const &root{SvgRoot()}) {
root.Invalidate();
}
}
}
void RenderableView::UpdateProps(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps) noexcept {
if (!props && !oldProps)
return;
UpdateProperties(props, oldProps);
}
void RenderableView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) noexcept {
auto renderableProps = props.as<SvgRenderableCommonProps>();
auto oldRenderableProps =
oldProps ? oldProps.as<SvgRenderableCommonProps>() : nullptr;
auto const &parent{Parent().try_as<RNSVG::RenderableView>()};
// propList
/*
auto const &propList{propertyMap.find("propList")};
if (propList != propertyMap.end()) {
m_propList.clear();
auto const &propValue{(*propList).second};
for (auto const &item : propValue.AsArray()) {
m_propList.push_back(Utils::JSValueAsString(item));
}
}
*/
/*******************************/
/* REACT_SVG_NODE_COMMON_PROPS */
/*******************************/
// name
// not a prop we want to propagate to child elements so we only set it when forceUpdate = true
if (forceUpdate && (!oldRenderableProps || renderableProps->name != oldRenderableProps->name)) {
if (parent) {
SvgRoot().Templates().Remove(m_id);
}
m_id = winrt::to_hstring(Utils::JSValueAsString(renderableProps->name));
if (parent) {
SaveDefinition();
}
}
// opacity
// not a prop we want to propagate to child elements so we only set it when forceUpdate = true
if (forceUpdate && (!oldRenderableProps || renderableProps->opacity != oldRenderableProps->opacity)) {
m_opacity = Utils::JSValueAsFloat(renderableProps->opacity, 1.0f);
}
// matrix
if (!oldRenderableProps || renderableProps->matrix != oldRenderableProps->matrix) {
if (forceUpdate) {
m_transformMatrix = renderableProps->matrix != std::nullopt
? Numerics::float3x2(
renderableProps->matrix->at(0),
renderableProps->matrix->at(1),
renderableProps->matrix->at(2),
renderableProps->matrix->at(3),
renderableProps->matrix->at(4),
renderableProps->matrix->at(5))
: (parent ? parent.SvgTransform() : Numerics::float3x2::identity());
if (forceUpdate) {
// If the optional is null, that generally means the prop was deleted
m_propSetMap[RNSVG::BaseProp::Matrix] = renderableProps->matrix != std::nullopt;
}
}
}
// mask - not implemented
//if (!oldRenderableProps || renderableProps->mask != oldRenderableProps->mask) {
// m_maskId = to_hstring(Utils::JSValueAsString(renderableProps->mask));
//}
// markerStart - not implemented
//if (!oldRenderableProps || renderableProps->markerStart != oldRenderableProps->markerStart) {
// m_markerStart = to_hstring(Utils::JSValueAsString(renderableProps->markerStart));
//}
// markerMid - not implemented
//if (!oldRenderableProps || renderableProps->markerMid != oldRenderableProps->markerMid) {
// m_markerMid = to_hstring(Utils::JSValueAsString(renderableProps->markerMid));
//}
// markerEnd - not implemented
//if (!oldRenderableProps || renderableProps->markerEnd != oldRenderableProps->markerEnd) {
// m_markerEnd = to_hstring(Utils::JSValueAsString(renderableProps->markerEnd));
//}
// clipPath
// not a prop we want to propagate to child elements so we only set it when forceUpdate = true
if (forceUpdate && (!oldRenderableProps || renderableProps->clipPath != oldRenderableProps->clipPath)) {
m_clipPathId = to_hstring(Utils::JSValueAsString(renderableProps->clipPath));
}
// responsible
if (!oldRenderableProps || renderableProps->responsible != oldRenderableProps->responsible) {
m_isResponsible = renderableProps->responsible != std::nullopt ? *renderableProps->responsible : false;
}
// display - not implemented
//if (!oldRenderableProps || renderableProps->display != oldRenderableProps->display) {
// m_display = Utils::JSValueAsString(renderableProps->display);
//}
// pointerEvents - not implemented
/*
if (!oldRenderableProps || renderableProps->pointerEvents != oldRenderableProps->pointerEvents) {
m_pointerEvents = Utils::JSValueAsString(renderableProps->pointerEvents);
}
*/
/*************************************/
/* REACT_SVG_RENDERABLE_COMMON_PROPS */
/*************************************/
// fill
if (!oldRenderableProps || renderableProps->fill != oldRenderableProps->fill) {
bool fillSet{
renderableProps->propList &&
std::find(renderableProps->propList->begin(), renderableProps->propList->end(), "fill") !=
renderableProps->propList->end()};
if (forceUpdate || !m_propSetMap[RNSVG::BaseProp::Fill]) {
winrt::Microsoft::ReactNative::Color fallbackColor{winrt::Microsoft::ReactNative::Color::Black()};
if (renderableProps->fill == std::nullopt && fillSet) {
fallbackColor = winrt::Microsoft::ReactNative::Color::Transparent();
} else if (parent) {
fallbackColor = parent.Fill();
}
if (!m_fillBrushId.empty()) {
m_fillBrushId.clear();
}
SetColor(renderableProps->fill, fallbackColor, "fill");
}
// forceUpdate = true means the property is being set on an element
// instead of being inherited from the parent.
if (forceUpdate) {
m_propSetMap[RNSVG::BaseProp::Fill] = fillSet;
}
}
// fillOpacity
if (!oldRenderableProps || renderableProps->fillOpacity != oldRenderableProps->fillOpacity) {
if (forceUpdate || !m_propSetMap[RNSVG::BaseProp::FillOpacity]) {
float fallbackValue{parent ? parent.FillOpacity() : 1.0f};
m_fillOpacity = Utils::JSValueAsFloat(renderableProps->fillOpacity, fallbackValue);
}
// forceUpdate = true means the property is being set on an element
// instead of being inherited from the parent.
if (forceUpdate) {
// If the optional is null, that generally means the prop was deleted
m_propSetMap[RNSVG::BaseProp::FillOpacity] = renderableProps->fillOpacity != std::nullopt;
}
}
// fillRule
if (!oldRenderableProps || renderableProps->fillRule != oldRenderableProps->fillRule) {
if (forceUpdate || !m_propSetMap[RNSVG::BaseProp::FillRule]) {
m_fillRule = renderableProps->fillRule != std::nullopt ? *renderableProps->fillRule
: (parent ? parent.FillRule() : RNSVG::FillRule::NonZero);
}
if (forceUpdate) {
// If the optional is null, that generally means the prop was deleted
m_propSetMap[RNSVG::BaseProp::FillRule] = renderableProps->fillRule != std::nullopt;
}
}
// stroke
if (!oldRenderableProps || renderableProps->stroke != oldRenderableProps->stroke) {
bool strokeSet{
renderableProps->propList &&
std::find(renderableProps->propList->begin(), renderableProps->propList->end(), "stroke") !=
renderableProps->propList->end()};
if (forceUpdate || !m_propSetMap[RNSVG::BaseProp::Stroke]) {
winrt::Microsoft::ReactNative::Color fallbackColor{
((parent && !strokeSet) ? parent.Stroke() : winrt::Microsoft::ReactNative::Color::Transparent())};
if (!m_strokeBrushId.empty()) {
m_strokeBrushId.clear();
}
SetColor(renderableProps->stroke, fallbackColor, "stroke");
}
// forceUpdate = true means the property is being set on an element
// instead of being inherited from the parent.
if (forceUpdate) {
m_propSetMap[RNSVG::BaseProp::Stroke] = strokeSet;
}
}
// strokeOpacity
if (!oldRenderableProps || renderableProps->strokeOpacity != oldRenderableProps->strokeOpacity) {
if (forceUpdate || !m_propSetMap[RNSVG::BaseProp::StrokeOpacity]) {
float fallbackValue{parent ? parent.StrokeOpacity() : 1.0f};
m_strokeOpacity = Utils::JSValueAsFloat(renderableProps->strokeOpacity, fallbackValue);
}
// forceUpdate = true means the property is being set on an element
// instead of being inherited from the parent.
if (forceUpdate) {
// If the optional is null, that generally means the prop was deleted
m_propSetMap[RNSVG::BaseProp::StrokeOpacity] = renderableProps->strokeOpacity != std::nullopt;
}
}
// strokeWidth
if (!oldRenderableProps || renderableProps->strokeWidth != oldRenderableProps->strokeWidth) {
if (forceUpdate || !m_propSetMap[RNSVG::BaseProp::StrokeWidth]) {
m_strokeWidth = (renderableProps->strokeWidth != std::nullopt)
? *renderableProps->strokeWidth
: (parent ? parent.StrokeWidth() : RNSVG::SVGLength{1.0f, RNSVG::LengthType::Pixel});
}
// forceUpdate = true means the property is being set on an element
// instead of being inherited from the parent.
if (forceUpdate) {
// If the optional is null, that generally means the prop was deleted
m_propSetMap[RNSVG::BaseProp::StrokeWidth] = renderableProps->strokeWidth != std::nullopt;
}
}
// strokeLinecap
if (!oldRenderableProps || renderableProps->strokeLinecap != oldRenderableProps->strokeLinecap) {
if (forceUpdate || !m_propSetMap[RNSVG::BaseProp::StrokeLineCap]) {
m_strokeLineCap = renderableProps->strokeLinecap != std::nullopt
? *renderableProps->strokeLinecap
: (parent ? parent.StrokeLineCap() : RNSVG::LineCap::Butt);
}
// forceUpdate = true means the property is being set on an element
// instead of being inherited from the parent.
if (forceUpdate) {
// If the optional is null, that generally means the prop was deleted
m_propSetMap[RNSVG::BaseProp::StrokeLineCap] = renderableProps->strokeLinecap != std::nullopt;
}
}
// strokeLinejoin
if (!oldRenderableProps || renderableProps->strokeLinejoin != oldRenderableProps->strokeLinejoin) {
if (forceUpdate || !m_propSetMap[RNSVG::BaseProp::StrokeLineJoin]) {
m_strokeLineJoin = renderableProps->strokeLinejoin != std::nullopt
? *renderableProps->strokeLinejoin
: (parent ? parent.StrokeLineJoin() : RNSVG::LineJoin::Miter);
}
// forceUpdate = true means the property is being set on an element
// instead of being inherited from the parent.
if (forceUpdate) {
// If the optional is null, that generally means the prop was deleted
m_propSetMap[RNSVG::BaseProp::StrokeLineJoin] = renderableProps->strokeLinejoin != std::nullopt;
}
}
// strokeDasharray
if (!oldRenderableProps || renderableProps->strokeDasharray != oldRenderableProps->strokeDasharray) {
if (forceUpdate || !m_propSetMap[RNSVG::BaseProp::StrokeDashArray]) {
if (renderableProps->strokeDasharray != std::nullopt) {
m_strokeDashArray.Clear();
for (auto const &item : *renderableProps->strokeDasharray) {
m_strokeDashArray.Append(item);
}
} else {
m_strokeDashArray = (parent ? parent.StrokeDashArray() : winrt::single_threaded_vector<RNSVG::SVGLength>());
}
if (forceUpdate) {
// If the optional is null, that generally means the prop was deleted
m_propSetMap[RNSVG::BaseProp::StrokeDashArray] = renderableProps->strokeDasharray != std::nullopt;
}
}
}
// strokeDashoffset
if (!oldRenderableProps || renderableProps->strokeDashoffset != oldRenderableProps->strokeDashoffset) {
if (forceUpdate || !m_propSetMap[RNSVG::BaseProp::StrokeDashOffset]) {
float fallbackValue{parent ? parent.StrokeDashOffset() : 0.0f};
m_strokeDashOffset = Utils::JSValueAsFloat(renderableProps->strokeDashoffset, fallbackValue);
}
if (forceUpdate) {
// If the optional is null, that generally means the prop was deleted
m_propSetMap[RNSVG::BaseProp::StrokeDashOffset] = renderableProps->strokeDashoffset != std::nullopt;
}
}
// strokeMiterlimit
if (!oldRenderableProps || renderableProps->strokeMiterlimit != oldRenderableProps->strokeMiterlimit) {
if (forceUpdate || !m_propSetMap[RNSVG::BaseProp::StrokeMiterLimit]) {
float fallbackValue{parent ? parent.StrokeMiterLimit() : 0.0f};
m_strokeMiterLimit = Utils::JSValueAsFloat(renderableProps->strokeMiterlimit, fallbackValue);
}
if (forceUpdate) {
// If the optional is null, that generally means the prop was deleted
m_propSetMap[RNSVG::BaseProp::StrokeMiterLimit] = renderableProps->strokeMiterlimit != std::nullopt;
}
}
// vectorEffect - not implemented
/*
if (!oldRenderableProps || renderableProps->vectorEffect != oldRenderableProps->vectorEffect) {
if (forceUpdate || !m_propSetMap[RNSVG::BaseProp::VectorEffect]) {
m_vectorEffect = renderableProps->vectorEffect != std::nullopt
? *renderableProps->vectorEffect
: (parent ? parent.VectorEffect() : RNSVG::VectorEffect::None);
}
// forceUpdate = true means the property is being set on an element
// instead of being inherited from the parent.
if (forceUpdate) {
// If the optional is null, that generally means the prop was deleted
m_propSetMap[RNSVG::BaseProp::VectorEffect] = renderableProps->vectorEffect != std::nullopt;
}
}
*/
m_recreateResources = true;
if (invalidate && Parent()) {
SvgRoot().Invalidate();
}
}
#else
void RenderableView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, bool invalidate) {
const JSValueObject &propertyMap{JSValue::ReadObjectFrom(reader)};
auto const &parent{SvgParent().try_as<RNSVG::RenderableView>()};
@@ -140,7 +533,7 @@ void RenderableView::UpdateProperties(IJSValueReader const &reader, bool forceUp
m_strokeDashArray.Clear();
for (auto const &item : asArray) {
m_strokeDashArray.Append(SVGLength::From(item));
m_strokeDashArray.Append(item.To<RNSVG::SVGLength>());
}
}
}
@@ -182,6 +575,7 @@ void RenderableView::UpdateProperties(IJSValueReader const &reader, bool forceUp
SvgRoot().Invalidate();
}
}
#endif
void RenderableView::SaveDefinition() {
if (m_id != L"") {
@@ -191,7 +585,7 @@ void RenderableView::SaveDefinition() {
void RenderableView::Draw(RNSVG::D2DDeviceContext const &context, Size const &size) {
if (m_recreateResources) {
CreateGeometry();
CreateGeometry(context);
}
if (!Geometry()) {
@@ -217,8 +611,8 @@ void RenderableView::Draw(RNSVG::D2DDeviceContext const &context, Size const &si
geometry = geometryGroup;
com_ptr<ID2D1Geometry> clipPathGeometry;
if (ClipPathGeometry()) {
clipPathGeometry = get_self<D2DGeometry>(ClipPathGeometry())->Get();
if (ClipPathGeometry(context)) {
clipPathGeometry = get_self<D2DGeometry>(ClipPathGeometry(context))->Get();
}
D2DHelpers::PushOpacityLayer(deviceContext.get(), clipPathGeometry.get(), m_opacity);
@@ -226,7 +620,7 @@ void RenderableView::Draw(RNSVG::D2DDeviceContext const &context, Size const &si
if (FillOpacity()) {
D2DHelpers::PushOpacityLayer(deviceContext.get(), clipPathGeometry.get(), FillOpacity());
auto fill{Utils::GetCanvasBrush(FillBrushId(), Fill(), SvgRoot(), geometry)};
auto fill{Utils::GetCanvasBrush(FillBrushId(), Fill(), SvgRoot(), geometry, context)};
deviceContext->FillGeometry(geometry.get(), fill.get());
deviceContext->PopLayer();
@@ -258,10 +652,9 @@ void RenderableView::Draw(RNSVG::D2DDeviceContext const &context, Size const &si
}
com_ptr<ID2D1StrokeStyle> strokeStyle;
check_hresult(
factory->CreateStrokeStyle(strokeStyleProperties, dashArray, m_strokeDashArray.Size(), strokeStyle.put()));
check_hresult(factory->CreateStrokeStyle(strokeStyleProperties, dashArray, m_strokeDashArray.Size(), strokeStyle.put()));
auto const stroke{Utils::GetCanvasBrush(StrokeBrushId(), Stroke(), SvgRoot(), geometry)};
auto const stroke{Utils::GetCanvasBrush(StrokeBrushId(), Stroke(), SvgRoot(), geometry, context)};
deviceContext->DrawGeometry(geometry.get(), stroke.get(), strokeWidth, strokeStyle.get());
deviceContext->PopLayer();
}
@@ -271,44 +664,46 @@ void RenderableView::Draw(RNSVG::D2DDeviceContext const &context, Size const &si
deviceContext->SetTransform(transform);
}
void RenderableView::MergeProperties(RNSVG::RenderableView const &other) {
void RenderableView::MergeProperties(RNSVG::IRenderable const &other) {
auto view{other.try_as<RNSVG::RenderableView>()};
for (auto const &prop : m_propSetMap) {
if (!prop.second) {
if (!prop.second && view) {
switch (prop.first) {
case RNSVG::BaseProp::Fill:
m_fill = other.Fill();
m_fillBrushId = other.FillBrushId();
m_fill = view.Fill();
m_fillBrushId = view.FillBrushId();
break;
case RNSVG::BaseProp::FillOpacity:
m_fillOpacity = other.FillOpacity();
m_fillOpacity = view.FillOpacity();
break;
case RNSVG::BaseProp::FillRule:
m_fillRule = other.FillRule();
m_fillRule = view.FillRule();
break;
case RNSVG::BaseProp::Stroke:
m_stroke = other.Stroke();
m_strokeBrushId = other.StrokeBrushId();
m_stroke = view.Stroke();
m_strokeBrushId = view.StrokeBrushId();
break;
case RNSVG::BaseProp::StrokeOpacity:
m_strokeOpacity = other.StrokeOpacity();
m_strokeOpacity = view.StrokeOpacity();
break;
case RNSVG::BaseProp::StrokeWidth:
m_strokeWidth = other.StrokeWidth();
m_strokeWidth = view.StrokeWidth();
break;
case RNSVG::BaseProp::StrokeMiterLimit:
m_strokeMiterLimit = other.StrokeMiterLimit();
m_strokeMiterLimit = view.StrokeMiterLimit();
break;
case RNSVG::BaseProp::StrokeDashOffset:
m_strokeDashOffset = other.StrokeDashOffset();
m_strokeDashOffset = view.StrokeDashOffset();
break;
case RNSVG::BaseProp::StrokeDashArray:
m_strokeDashArray = other.StrokeDashArray();
m_strokeDashArray = view.StrokeDashArray();
break;
case RNSVG::BaseProp::StrokeLineCap:
m_strokeLineCap = other.StrokeLineCap();
m_strokeLineCap = view.StrokeLineCap();
break;
case RNSVG::BaseProp::StrokeLineJoin:
m_strokeLineJoin = other.StrokeLineJoin();
m_strokeLineJoin = view.StrokeLineJoin();
break;
case RNSVG::BaseProp::Unknown:
default:
@@ -319,16 +714,18 @@ void RenderableView::MergeProperties(RNSVG::RenderableView const &other) {
}
RNSVG::SvgView RenderableView::SvgRoot() {
if (SvgParent()) {
if (auto const &svgView{SvgParent().try_as<RNSVG::SvgView>()}) {
if (svgView.SvgParent()) {
if (auto const &parent{svgView.SvgParent().try_as<RNSVG::RenderableView>()}) {
if (auto parent = SvgParent()) {
if (auto const &svgView{parent.try_as<RNSVG::SvgView>()}) {
if (auto const &svgViewParent = svgView.SvgParent()) {
if (auto const &parent{svgViewParent.try_as<RNSVG::RenderableView>()}) {
return parent.SvgRoot();
} else {
return svgView;
}
} else {
return svgView;
}
} else if (auto const &renderable{SvgParent().try_as<RNSVG::RenderableView>()}) {
} else if (auto const &renderable{parent.try_as<RNSVG::RenderableView>()}) {
return renderable.SvgRoot();
}
}
@@ -336,11 +733,11 @@ RNSVG::SvgView RenderableView::SvgRoot() {
return nullptr;
}
RNSVG::D2DGeometry RenderableView::ClipPathGeometry() {
RNSVG::D2DGeometry RenderableView::ClipPathGeometry(RNSVG::D2DDeviceContext const &context) {
if (!m_clipPathId.empty()) {
if (auto const &clipPath{SvgRoot().Templates().TryLookup(m_clipPathId)}) {
if (!clipPath.Geometry()) {
clipPath.CreateGeometry();
clipPath.CreateGeometry(context);
}
return clipPath.Geometry();
}
@@ -355,10 +752,13 @@ void RenderableView::Unload() {
m_parent = nullptr;
m_reactContext = nullptr;
m_propList.clear();
m_propSetMap.clear();
m_strokeDashArray.Clear();
m_isUnloaded = true;
#ifndef USE_FABRIC
m_propList.clear();
#endif
}
RNSVG::IRenderable RenderableView::HitTest(Point const &point) {
@@ -369,7 +769,7 @@ RNSVG::IRenderable RenderableView::HitTest(Point const &point) {
com_ptr<ID2D1Geometry> geometry{get_self<D2DGeometry>(m_geometry)->Get()};
if (auto const &svgRoot{SvgRoot()}) {
float canvasDiagonal{Utils::GetCanvasDiagonal(svgRoot.ActualSize())};
float canvasDiagonal{Utils::GetCanvasDiagonal(svgRoot.CanvasSize())};
float strokeWidth{Utils::GetAbsoluteLength(StrokeWidth(), canvasDiagonal)};
check_hresult(geometry->StrokeContainsPoint(pointD2D, strokeWidth, nullptr, nullptr, &strokeContainsPoint));
@@ -385,7 +785,41 @@ RNSVG::IRenderable RenderableView::HitTest(Point const &point) {
return nullptr;
}
void RenderableView::SetColor(const JSValueObject &propValue, Windows::UI::Color const &fallbackColor, std::string propName) {
#ifdef USE_FABRIC
void RenderableView::SetColor(
std::optional<ColorStruct> &color,
winrt::Microsoft::ReactNative::Color const &fallbackColor,
std::string propName) {
if (color == std::nullopt) {
propName == "fill" ? m_fill = fallbackColor : m_stroke = fallbackColor;
return;
}
switch (color->type) {
// https://github.com/software-mansion/react-native-svg/blob/main/src/lib/extract/extractBrush.ts#L29
case 1: {
propName == "fill" ? m_fillBrushId = winrt::to_hstring(color->brushRef)
: m_strokeBrushId = winrt::to_hstring(color->brushRef);
break;
}
// https://github.com/software-mansion/react-native-svg/blob/main/src/lib/extract/extractBrush.ts#L6-L8
case 2: // currentColor
case 3: // context-fill
case 4: // context-stroke
propName == "fill" ? m_fillBrushId = L"currentColor" : m_strokeBrushId = L"currentColor";
break;
default: {
auto const &c = color->payload ? color->payload : fallbackColor;
propName == "fill" ? m_fill = c : m_stroke = c;
break;
}
}
}
#else
void RenderableView::SetColor(
const JSValueObject &propValue,
Windows::UI::Color const &fallbackColor,
std::string propName) {
switch (propValue["type"].AsInt64()) {
// https://github.com/software-mansion/react-native-svg/blob/main/src/lib/extract/extractBrush.ts#L29
case 1: {
@@ -400,10 +834,12 @@ void RenderableView::SetColor(const JSValueObject &propValue, Windows::UI::Color
propName == "fill" ? m_fillBrushId = L"currentColor" : m_strokeBrushId = L"currentColor";
break;
default: {
auto const &color {Utils::JSValueAsColor(propValue["payload"], fallbackColor)};
auto const &color{Utils::JSValueAsColor(propValue["payload"], fallbackColor)};
propName == "fill" ? m_fill = color : m_stroke = color;
break;
}
}
}
#endif
} // namespace winrt::RNSVG::implementation

View File

@@ -5,17 +5,170 @@
#include "D2DDeviceContext.h"
#include "D2DGeometry.h"
#ifdef USE_FABRIC
#include "SvgNodeCommonProps.g.h"
#include "SvgRenderableCommonProps.g.h"
#include <JSValueComposition.h>
#endif
#include <NativeModules.h>
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(ColorStruct)
struct ColorStruct {
REACT_FIELD(type)
int32_t type{-1};
REACT_FIELD(payload)
winrt::Microsoft::ReactNative::Color payload{nullptr};
REACT_FIELD(brushRef)
std::string brushRef;
bool operator==(const ColorStruct &rhs) const {
return type == rhs.type && payload == rhs.payload && brushRef == rhs.brushRef;
}
bool operator!=(const ColorStruct &rhs) const {
return !(*this == rhs);
}
};
// Currently no good way to do inheritance in REACT_STRUCTS
#define REACT_SVG_NODE_COMMON_PROPS \
REACT_FIELD(name) \
REACT_FIELD(opacity) \
REACT_FIELD(matrix) \
REACT_FIELD(mask) \
REACT_FIELD(markerStart) \
REACT_FIELD(markerMid) \
REACT_FIELD(markerEnd) \
REACT_FIELD(clipPath) \
REACT_FIELD(clipRule) \
REACT_FIELD(responsible) \
REACT_FIELD(display) \
REACT_FIELD(pointerEvents)
REACT_STRUCT(SvgNodeCommonProps)
struct SvgNodeCommonProps : SvgNodeCommonPropsT<SvgNodeCommonProps> {
SvgNodeCommonProps(const winrt::Microsoft::ReactNative::ViewProps &props);
virtual void SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept;
REACT_SVG_NODE_COMMON_PROPS;
std::optional<std::string> name;
std::optional<float> opacity; // 1.0f
std::optional<std::vector<float>> matrix;
std::optional<std::string> mask;
std::optional<std::string> markerStart;
std::optional<std::string> markerMid;
std::optional<std::string> markerEnd;
std::optional<std::string> clipPath;
std::optional<RNSVG::FillRule> clipRule; // RNSVG::FillRule::EvenOdd
std::optional<bool> responsible;
std::optional<std::string> display;
std::optional<std::string> pointerEvents;
private:
winrt::Microsoft::ReactNative::ViewProps m_props{nullptr};
};
// Currently no good way to do inheritance in REACT_STRUCTS
#define REACT_SVG_RENDERABLE_COMMON_PROPS \
REACT_FIELD(fill) \
REACT_FIELD(fillOpacity) \
REACT_FIELD(fillRule) \
REACT_FIELD(stroke) \
REACT_FIELD(strokeOpacity) \
REACT_FIELD(strokeWidth) \
REACT_FIELD(strokeLinecap) \
REACT_FIELD(strokeLinejoin) \
REACT_FIELD(strokeDasharray) \
REACT_FIELD(strokeDashoffset) \
REACT_FIELD(strokeMiterlimit) \
REACT_FIELD(vectorEffect) \
REACT_FIELD(propList)
REACT_STRUCT(SvgRenderableCommonProps)
struct SvgRenderableCommonProps
: SvgRenderableCommonPropsT<SvgRenderableCommonProps, SvgNodeCommonProps> {
SvgRenderableCommonProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept override;
REACT_SVG_NODE_COMMON_PROPS;
REACT_SVG_RENDERABLE_COMMON_PROPS;
std::optional<ColorStruct> fill;
std::optional<float> fillOpacity; // 1.0f
std::optional<FillRule> fillRule; // RNSVG::FillRule::NonZero
std::optional<ColorStruct> stroke;
std::optional<float> strokeOpacity; // 1.0f
std::optional<RNSVG::SVGLength> strokeWidth;
std::optional<LineCap> strokeLinecap; // RNSVG::LineCap::Butt
std::optional<LineJoin> strokeLinejoin; // RNSVG::LineJoin::Miter
std::optional<std::vector<RNSVG::SVGLength>> strokeDasharray;
std::optional<float> strokeDashoffset;
std::optional<float> strokeMiterlimit;
std::optional<int32_t> vectorEffect; // 0
std::optional<std::vector<std::string>> propList;
};
#endif
struct RenderableView : RenderableViewT<RenderableView> {
public:
RenderableView() = default;
#ifdef USE_FABRIC
RenderableView(const winrt::Microsoft::ReactNative::CreateComponentViewArgs &args);
// IRenderableFabric
winrt::Microsoft::ReactNative::ComponentView SvgParent() { return Parent(); }
winrt::Microsoft::ReactNative::Color Fill() { return m_fill; }
winrt::Microsoft::ReactNative::Color Stroke() { return m_stroke; }
// ComponentView
void MountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept;
void UnmountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept;
virtual void UpdateProps(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps) noexcept;
// IRenderableFabric
virtual void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true) noexcept;
#else
RenderableView(Microsoft::ReactNative::IReactContext const &context) : m_reactContext(context) {}
RNSVG::SvgView SvgRoot();
// IRenderablePaper
xaml::FrameworkElement SvgParent() { return m_parent; }
void SvgParent(xaml::FrameworkElement const &value) { m_parent = value; }
Windows::UI::Color Fill() { return m_fill; }
Windows::UI::Color Stroke() { return m_stroke; }
virtual void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate = true, bool invalidate = true);
#endif
RNSVG::SvgView SvgRoot();
RNSVG::D2DGeometry Geometry() { return m_geometry; }
void Geometry(RNSVG::D2DGeometry const &value) { m_geometry = value; }
@@ -28,10 +181,8 @@ struct RenderableView : RenderableViewT<RenderableView> {
bool IsUnloaded() { return m_isUnloaded; }
hstring FillBrushId() { return m_fillBrushId; }
Windows::UI::Color Fill() { return m_fill; }
float FillOpacity() { return m_fillOpacity; }
hstring StrokeBrushId() { return m_strokeBrushId; }
Windows::UI::Color Stroke() { return m_stroke; }
float StrokeOpacity() { return m_strokeOpacity; }
float StrokeMiterLimit() { return m_strokeMiterLimit; }
float StrokeDashOffset() { return m_strokeDashOffset; }
@@ -40,11 +191,11 @@ struct RenderableView : RenderableViewT<RenderableView> {
RNSVG::LineCap StrokeLineCap() { return m_strokeLineCap; }
RNSVG::LineJoin StrokeLineJoin() { return m_strokeLineJoin; }
RNSVG::FillRule FillRule() { return m_fillRule; }
RNSVG::D2DGeometry ClipPathGeometry();
RNSVG::D2DGeometry ClipPathGeometry(RNSVG::D2DDeviceContext const &context);
virtual void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate = true, bool invalidate = true);
virtual void CreateGeometry() {}
virtual void MergeProperties(RNSVG::RenderableView const &other);
// IRenderable
virtual void CreateGeometry(RNSVG::D2DDeviceContext const & /*context*/) {}
virtual void MergeProperties(RNSVG::IRenderable const &other);
virtual void SaveDefinition();
virtual void Unload();
virtual void Draw(RNSVG::D2DDeviceContext const &deviceContext, Windows::Foundation::Size const &size);
@@ -52,8 +203,11 @@ struct RenderableView : RenderableViewT<RenderableView> {
virtual RNSVG::IRenderable HitTest(Windows::Foundation::Point const &point);
protected:
float m_opacity{1.0f};
#ifndef USE_FABRIC
std::vector<std::string> m_propList{};
#endif
float m_opacity{1.0f};
std::map<RNSVG::BaseProp, bool> m_propSetMap{
{RNSVG::BaseProp::Matrix, false},
{RNSVG::BaseProp::Fill, false},
@@ -70,8 +224,24 @@ struct RenderableView : RenderableViewT<RenderableView> {
};
private:
Microsoft::ReactNative::IReactContext m_reactContext{nullptr};
#ifdef USE_FABRIC
winrt::Microsoft::ReactNative::ComponentView m_parent{nullptr};
winrt::Microsoft::ReactNative::Color m_fill{winrt::Microsoft::ReactNative::Color::Black()};
winrt::Microsoft::ReactNative::Color m_stroke{winrt::Microsoft::ReactNative::Color::Transparent()};
void SetColor(
std::optional<ColorStruct> &propValue,
winrt::Microsoft::ReactNative::Color const &fallbackColor,
std::string propName);
#else
xaml::FrameworkElement m_parent{nullptr};
Windows::UI::Color m_fill{Colors::Black()};
Windows::UI::Color m_stroke{Colors::Transparent()};
void SetColor(const Microsoft::ReactNative::JSValueObject &propValue, Windows::UI::Color const &fallbackColor, std::string propName);
#endif
Microsoft::ReactNative::IReactContext m_reactContext{nullptr};
RNSVG::D2DGeometry m_geometry{nullptr};
bool m_recreateResources{true};
bool m_isResponsible{false};
@@ -79,9 +249,7 @@ struct RenderableView : RenderableViewT<RenderableView> {
hstring m_id{L""};
hstring m_clipPathId{L""};
Numerics::float3x2 m_transformMatrix{Numerics::make_float3x2_rotation(0)};
Windows::UI::Color m_fill{Colors::Black()};
Windows::UI::Color m_stroke{Colors::Transparent()};
Numerics::float3x2 m_transformMatrix{Numerics::float3x2::identity()};
hstring m_fillBrushId{L""};
hstring m_strokeBrushId{L""};
float m_fillOpacity{1.0f};
@@ -95,8 +263,6 @@ struct RenderableView : RenderableViewT<RenderableView> {
RNSVG::LineCap m_strokeLineCap{RNSVG::LineCap::Butt};
RNSVG::LineJoin m_strokeLineJoin{RNSVG::LineJoin::Miter};
RNSVG::FillRule m_fillRule{RNSVG::FillRule::NonZero};
void SetColor(const Microsoft::ReactNative::JSValueObject &propValue, Windows::UI::Color const &fallbackColor, std::string propName);
};
} // namespace winrt::RNSVG::implementation

View File

@@ -1,59 +1,107 @@
#pragma once
#include "pch.h"
#include "SVGLength.h"
#if __has_include("SVGLength.g.cpp")
#include "SVGLength.g.cpp"
#endif
namespace winrt::RNSVG::implementation {
SVGLength::SVGLength(float value) : m_value(value), m_unit(RNSVG::LengthType::Number) {}
#include <JSValueReader.h>
SVGLength::SVGLength(float value, RNSVG::LengthType const &type) : m_value(value), m_unit(type) {}
namespace winrt::Microsoft::ReactNative {
RNSVG::SVGLength SVGLength::From(std::string value) {
auto strLength{value.size()};
if (strLength == 0 || value == "normal") {
return {0.0, RNSVG::LengthType::Unknown};
} else if (value.back() == '%') {
return {std::stof(value.substr(0, strLength - 1), nullptr), RNSVG::LengthType::Percentage};
} else if (strLength > 2) {
auto end{strLength - 2};
auto lastTwo{value.substr(end)};
void WriteValue(IJSValueWriter const &writer, const winrt::RNSVG::SVGLength &value) noexcept {
switch (value.Unit) {
case RNSVG::LengthType::Unknown:
writer.WriteNull();
return;
case RNSVG::LengthType::EMS:
writer.WriteString(winrt::to_hstring(std::to_string(value.Value) + "em"));
return;
case RNSVG::LengthType::EXS:
writer.WriteString(winrt::to_hstring(std::to_string(value.Value) + "ex"));
return;
case RNSVG::LengthType::Centimeter:
writer.WriteString(winrt::to_hstring(std::to_string(value.Value) + "cm"));
return;
case RNSVG::LengthType::Millimeter:
writer.WriteString(winrt::to_hstring(std::to_string(value.Value) + "mm"));
return;
case RNSVG::LengthType::Inch:
writer.WriteString(winrt::to_hstring(std::to_string(value.Value) + "in"));
return;
case RNSVG::LengthType::Point:
writer.WriteString(winrt::to_hstring(std::to_string(value.Value) + "pt"));
return;
case RNSVG::LengthType::Pica:
writer.WriteString(winrt::to_hstring(std::to_string(value.Value) + "pc"));
return;
case RNSVG::LengthType::Number:
writer.WriteDouble(value.Value);
return;
default:
assert(false);
}
}
auto unit{RNSVG::LengthType::Unknown};
if (lastTwo == "px") {
unit = RNSVG::LengthType::Number;
} else if (lastTwo == "em") {
unit = RNSVG::LengthType::EMS;
} else if (lastTwo == "ex") {
unit = RNSVG::LengthType::EXS;
} else if (lastTwo == "cm") {
unit = RNSVG::LengthType::Centimeter;
} else if (lastTwo == "mm") {
unit = RNSVG::LengthType::Millimeter;
} else if (lastTwo == "in") {
unit = RNSVG::LengthType::Inch;
} else if (lastTwo == "pt") {
unit = RNSVG::LengthType::Point;
} else if (lastTwo == "pc") {
unit = RNSVG::LengthType::Pica;
} else {
unit = RNSVG::LengthType::Number;
end = strLength;
void ReadValue(IJSValueReader const &reader, /*out*/ winrt::RNSVG::SVGLength &value) noexcept {
switch (reader.ValueType()) {
case JSValueType::String: {
auto str = to_string(reader.GetString());
auto strLength{str.size()};
if (strLength == 0 || str == "normal") {
value.Unit = RNSVG::LengthType::Unknown;
value.Value = 0.0;
return;
} else if (str.back() == '%') {
value.Unit = RNSVG::LengthType::Percentage;
value.Value = std::stof(str.substr(0, strLength - 1), nullptr);
return;
} else if (strLength > 2) {
auto end{strLength - 2};
auto lastTwo{str.substr(end)};
value.Unit = RNSVG::LengthType::Unknown;
if (lastTwo == "px") {
value.Unit = RNSVG::LengthType::Number;
} else if (lastTwo == "em") {
value.Unit = RNSVG::LengthType::EMS;
} else if (lastTwo == "ex") {
value.Unit = RNSVG::LengthType::EXS;
} else if (lastTwo == "cm") {
value.Unit = RNSVG::LengthType::Centimeter;
} else if (lastTwo == "mm") {
value.Unit = RNSVG::LengthType::Millimeter;
} else if (lastTwo == "in") {
value.Unit = RNSVG::LengthType::Inch;
} else if (lastTwo == "pt") {
value.Unit = RNSVG::LengthType::Point;
} else if (lastTwo == "pc") {
value.Unit = RNSVG::LengthType::Pica;
} else {
value.Unit = RNSVG::LengthType::Number;
end = strLength;
}
value.Value = std::stof(str.substr(0, end), nullptr);
return;
}
value.Unit = RNSVG::LengthType::Number;
value.Value = std::stof(str, nullptr);
}
return {std::stof(value.substr(0, end), nullptr), unit};
}
return {std::stof(value, nullptr), RNSVG::LengthType::Number};
}
RNSVG::SVGLength SVGLength::From(Microsoft::ReactNative::JSValue const &propertyValue) {
if (propertyValue.IsNull()) {
return {0.0f, RNSVG::LengthType::Unknown};
} else if (propertyValue.Type() == Microsoft::ReactNative::JSValueType::String) {
return SVGLength::From(propertyValue.AsString());
} else {
return RNSVG::SVGLength(propertyValue.AsSingle());
return;
case JSValueType::Int64:
value.Unit = RNSVG::LengthType::Number;
value.Value = static_cast<float>(reader.GetInt64());
return;
case JSValueType::Double:
value.Unit = RNSVG::LengthType::Number;
value.Value = static_cast<float>(reader.GetDouble());
return;
default:
value.Unit = RNSVG::LengthType::Unknown;
value.Value = 0.0f;
return;
}
}
} // namespace winrt::RNSVG::implementation
} // namespace winrt::Microsoft::ReactNative

View File

@@ -1,28 +1,12 @@
#pragma once
#include "SVGLength.g.h"
#include <winrt/RNSVG.h>
#ifndef USE_FABRIC
#include "JSValueXaml.h"
#endif
namespace winrt::RNSVG::implementation {
struct SVGLength : SVGLengthT<SVGLength> {
public:
SVGLength() = default;
SVGLength(float value);
SVGLength(float value, RNSVG::LengthType const &type);
float Value() { return m_value; }
RNSVG::LengthType Unit() { return m_unit; }
static RNSVG::SVGLength From(std::string value);
static RNSVG::SVGLength From(Microsoft::ReactNative::JSValue const &value);
private:
float m_value{0.0f};
RNSVG::LengthType m_unit{RNSVG::LengthType::Unknown};
};
} // namespace winrt::RNSVG::implementation
namespace winrt::RNSVG::factory_implementation {
struct SVGLength : SVGLengthT<SVGLength, implementation::SVGLength> {};
} // namespace winrt::RNSVG::factory_implementation
namespace winrt::Microsoft::ReactNative {
void WriteValue(IJSValueWriter const &writer, const winrt::RNSVG::SVGLength &value) noexcept;
void ReadValue(IJSValueReader const &reader, /*out*/ winrt::RNSVG::SVGLength &value) noexcept;
} // namespace winrt::Microsoft::ReactNative

View File

@@ -17,14 +17,149 @@
#include "D2DDevice.h"
#include "D2DDeviceContext.h"
#include "GroupView.h"
#include "Utils.h"
#ifdef USE_FABRIC
#include <AutoDraw.h>
#include <CompositionSwitcher.Experimental.interop.h>
#endif
#include <d3d11_4.h>
using namespace winrt;
using namespace Microsoft::ReactNative;
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
SvgViewProps::SvgViewProps(
const winrt::Microsoft::ReactNative::ViewProps &props)
: m_props(props) {}
void SvgViewProps::SetProp(
uint32_t hash,
winrt::hstring propName,
winrt::Microsoft::ReactNative::IJSValueReader value) noexcept {
winrt::Microsoft::ReactNative::ReadProp(hash, propName, value, *this);
}
SvgView::SvgView(const winrt::Microsoft::ReactNative::Composition::CreateCompositionComponentViewArgs &args)
: base_type(args),
m_reactContext(args.ReactContext()),
m_compContext(
args.as<winrt::Microsoft::ReactNative::Composition::Experimental::IInternalCreateComponentViewArgs>()
.CompositionContext()) {}
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual SvgView::CreateInternalVisual() {
m_visual = m_compContext.CreateSpriteVisual();
m_visual.Comment(L"SVGRoot");
return m_visual;
}
void SvgView::MountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept {
auto const &group{childComponentView.try_as<RNSVG::GroupView>()};
if (group) {
// Every SvgView has exactly one child - a Group that gets
// all of Svg's children piped through.
Group(group);
}
base_type::MountChildComponentView(childComponentView, index);
}
void SvgView::UnmountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept {
if (Group()) {
Group().Unload();
}
Group(nullptr);
base_type::UnmountChildComponentView(childComponentView, index);
}
void SvgView::OnThemeChanged() noexcept {
Invalidate();
base_type::OnThemeChanged();
}
void SvgView::UpdateProps(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps) noexcept {
UpdateProperties(props, oldProps);
}
void SvgView::RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept {
builder.AddViewComponent(L"RNSVGSvgView", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept {
builder.SetCreateProps([](winrt::Microsoft::ReactNative::ViewProps props) noexcept {
return winrt::make<winrt::RNSVG::implementation::SvgViewProps>(props);
});
auto compBuilder = builder.as<winrt::Microsoft::ReactNative::Composition::IReactCompositionViewComponentBuilder>();
compBuilder.SetCreateViewComponentView([](const winrt::Microsoft::ReactNative::Composition::CreateCompositionComponentViewArgs &args) noexcept {
args.Features(args.Features() & ~winrt::Microsoft::ReactNative::Composition::ComponentViewFeatures::Background);
return winrt::make<winrt::RNSVG::implementation::SvgView>(args);
});
});
}
void SvgView::UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate,
bool invalidate) {
auto svgProps = props.try_as<SvgViewProps>();
auto oldSvgProps = oldProps ? oldProps.try_as<SvgViewProps>() : nullptr;
// If forceUpdate is false, that means this is a nested Svg
// and we're inheriting props. Pass those along to the group.
if (!forceUpdate && m_group) {
m_group.UpdateProperties(props, oldProps, forceUpdate, invalidate);
return;
}
if (!oldSvgProps || svgProps->bbWidth != oldSvgProps->bbWidth) {
m_bbWidth = svgProps->bbWidth;
}
if (!oldSvgProps || svgProps->bbHeight != oldSvgProps->bbHeight) {
m_bbHeight = svgProps->bbHeight;
}
if (!oldSvgProps || svgProps->vbWidth != oldSvgProps->vbWidth) {
m_vbWidth = svgProps->vbWidth;
}
if (!oldSvgProps || svgProps->vbHeight != oldSvgProps->vbHeight) {
m_vbHeight = svgProps->vbHeight;
}
if (!oldSvgProps || svgProps->minX != oldSvgProps->minX) {
m_minX = svgProps->minX;
}
if (!oldSvgProps || svgProps->minY != oldSvgProps->minY) {
m_minY = svgProps->minY;
}
if (!oldSvgProps || svgProps->align != oldSvgProps->align) {
m_align = svgProps->align;
}
if (!oldSvgProps || svgProps->meetOrSlice != oldSvgProps->meetOrSlice) {
m_meetOrSlice = svgProps->meetOrSlice;
}
if (!oldSvgProps || svgProps->color != oldSvgProps->color) {
m_currentColor = svgProps->color;
}
Invalidate();
}
void SvgView::UpdateLayoutMetrics(
const LayoutMetrics &metrics,
const LayoutMetrics &oldMetrics) {
m_layoutMetrics = metrics;
base_type::UpdateLayoutMetrics(metrics, oldMetrics);
if (metrics != oldMetrics) {
Invalidate();
}
}
#else
SvgView::SvgView(IReactContext const &context) : m_reactContext(context) {
uint32_t creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
@@ -95,15 +230,15 @@ void SvgView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, b
SaveDefinition();
}
} else if (propertyName == "width") {
m_width = SVGLength::From(propertyValue);
m_width = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "height") {
m_height = SVGLength::From(propertyValue);
m_height = propertyValue.To<RNSVG::SVGLength>();
} else if (propertyName == "bbWidth") {
m_bbWidth = SVGLength::From(propertyValue);
Width(m_bbWidth.Value());
m_bbWidth = propertyValue.To<RNSVG::SVGLength>();
Width(m_bbWidth.Value);
} else if (propertyName == "bbHeight") {
m_bbHeight = SVGLength::From(propertyValue);
Height(m_bbHeight.Value());
m_bbHeight = propertyValue.To<RNSVG::SVGLength>();
Height(m_bbHeight.Value);
} else if (propertyName == "vbWidth") {
m_vbWidth = Utils::JSValueAsFloat(propertyValue);
} else if (propertyName == "vbHeight") {
@@ -127,19 +262,6 @@ void SvgView::UpdateProperties(IJSValueReader const &reader, bool forceUpdate, b
}
}
void SvgView::SaveDefinition() {
if (m_id != L"" && m_group) {
m_group.SvgRoot().Templates().Insert(m_id, *this);
m_group.SaveDefinition();
}
}
void SvgView::MergeProperties(RNSVG::RenderableView const &other) {
if (m_group) {
m_group.MergeProperties(other);
}
}
Size SvgView::MeasureOverride(Size const &availableSize) {
for (auto const &child : Children()) {
child.Measure(availableSize);
@@ -154,6 +276,43 @@ Size SvgView::ArrangeOverride(Size const &finalSize) {
return finalSize;
}
void SvgView::Panel_Loaded(IInspectable const &sender, xaml::RoutedEventArgs const & ) {
if (auto const &svgView{sender.try_as<RNSVG::SvgView>()}) {
if (!m_loaded) {
m_loaded = true;
svgView.CreateResources();
}
}
}
void SvgView::Panel_Unloaded(IInspectable const &sender, xaml::RoutedEventArgs const & ) {
if (auto const &svgView{sender.try_as<RNSVG::SvgView>()}) {
svgView.Unload();
}
}
#endif
winrt::Windows::Foundation::Size SvgView::CanvasSize() noexcept {
#ifdef USE_FABRIC
return winrt::Windows::Foundation::Size{m_layoutMetrics.Frame.Width, m_layoutMetrics.Frame.Height};
#else
return ActualSize();
#endif
}
void SvgView::SaveDefinition() {
if (m_id != L"" && m_group) {
m_group.SvgRoot().Templates().Insert(m_id, *this);
m_group.SaveDefinition();
}
}
void SvgView::MergeProperties(RNSVG::IRenderable const &other) {
if (m_group) {
m_group.MergeProperties(other);
}
}
void SvgView::Draw(RNSVG::D2DDeviceContext const &context, Size const &size) {
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(context)->Get()};
@@ -164,7 +323,7 @@ void SvgView::Draw(RNSVG::D2DDeviceContext const &context, Size const &size) {
float width{size.Width};
float height{size.Height};
if (m_parent) {
if (SvgParent()) {
width = Utils::GetAbsoluteLength(m_bbWidth, width);
height = Utils::GetAbsoluteLength(m_bbHeight, height);
}
@@ -185,9 +344,9 @@ void SvgView::Draw(RNSVG::D2DDeviceContext const &context, Size const &size) {
deviceContext->SetTransform(transform);
}
void SvgView::CreateGeometry() {
void SvgView::CreateGeometry(RNSVG::D2DDeviceContext const &context) {
if (m_group) {
m_group.CreateGeometry();
m_group.CreateGeometry(context);
}
}
@@ -198,26 +357,12 @@ void SvgView::CreateResources() {
Invalidate();
#ifndef USE_FABRIC
m_image.Width(ActualWidth());
m_image.Height(ActualHeight());
m_image.Stretch(xaml::Media::Stretch::UniformToFill);
Children().Append(m_image);
}
void SvgView::Panel_Loaded(IInspectable const &sender, xaml::RoutedEventArgs const & /*args*/) {
if (auto const &svgView{sender.try_as<RNSVG::SvgView>()}) {
if (!m_loaded) {
m_loaded = true;
svgView.CreateResources();
}
}
}
void SvgView::Panel_Unloaded(IInspectable const &sender, xaml::RoutedEventArgs const & /*args*/) {
if (auto const &svgView{sender.try_as<RNSVG::SvgView>()}) {
svgView.Unload();
}
#endif
}
void SvgView::Unload() {
@@ -231,12 +376,54 @@ void SvgView::Unload() {
}
void SvgView::Invalidate() {
if (!m_loaded) {
m_brushes.Clear();
m_templates.Clear();
#ifdef USE_FABRIC
Size size = CanvasSize();
if (size.Height == 0 || size.Width == 0) {
return;
}
m_brushes.Clear();
m_templates.Clear();
if (Theme().IsEmpty()) {
return;
}
auto drawingSurface = m_compContext.CreateDrawingSurfaceBrush(
size,
winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized,
winrt::Windows::Graphics::DirectX::DirectXAlphaMode::Premultiplied);
POINT offset;
{
::Microsoft::ReactNative::Composition::AutoDrawDrawingSurface autoDraw(drawingSurface, 1.0, &offset);
if (auto deviceContext = autoDraw.GetRenderTarget()) {
auto transform = Numerics::make_float3x2_translation({static_cast<float>(offset.x), static_cast<float>(offset.y)});
deviceContext->SetTransform(D2DHelpers::AsD2DTransform(transform));
deviceContext->Clear(D2D1::ColorF(D2D1::ColorF::Black, 0.0f));
com_ptr<ID2D1DeviceContext> spDeviceContext;
spDeviceContext.copy_from(deviceContext);
m_deviceContext = winrt::make<RNSVG::implementation::D2DDeviceContext>(spDeviceContext);
com_ptr<ID2D1Device> spDevice;
spDeviceContext->GetDevice(spDevice.put());
m_device = winrt::make<RNSVG::implementation::D2DDevice>(spDevice);
Draw(m_deviceContext, size);
}
}
m_visual.Brush(drawingSurface);
#else
if (!m_loaded) {
return;
}
com_ptr<ID2D1DeviceContext> deviceContext{get_self<D2DDeviceContext>(DeviceContext())->Get()};
@@ -278,5 +465,6 @@ void SvgView::Invalidate() {
sisNativeWithD2D->EndDraw();
m_image.Source(surfaceImageSource);
#endif
}
} // namespace winrt::RNSVG::implementation

View File

@@ -2,16 +2,111 @@
#include "SvgView.g.h"
#ifdef USE_FABRIC
#include "SvgViewProps.g.h"
#include <JSValueComposition.h>
#include "NativeModules.h"
#endif
#include "SVGLength.h"
#include "Utils.h"
namespace winrt::RNSVG::implementation {
#ifdef USE_FABRIC
REACT_STRUCT(SvgViewProps)
struct SvgViewProps : SvgViewPropsT<SvgViewProps> {
SvgViewProps(const winrt::Microsoft::ReactNative::ViewProps &props);
void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept;
REACT_FIELD(bbWidth)
winrt::RNSVG::SVGLength bbWidth{0.0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(bbHeight)
winrt::RNSVG::SVGLength bbHeight{0.0, winrt::RNSVG::LengthType::Unknown};
REACT_FIELD(minX)
float minX;
REACT_FIELD(minY)
float minY;
REACT_FIELD(vbWidth)
float vbWidth;
REACT_FIELD(vbHeight)
float vbHeight;
REACT_FIELD(align)
std::string align;
REACT_FIELD(meetOrSlice)
RNSVG::MeetOrSlice meetOrSlice{RNSVG::MeetOrSlice::Meet};
REACT_FIELD(tintColor)
winrt::Microsoft::ReactNative::Color tintColor{nullptr};
REACT_FIELD(color)
winrt::Microsoft::ReactNative::Color color{nullptr};
private:
winrt::Microsoft::ReactNative::ViewProps m_props{nullptr};
};
#endif
struct SvgView : SvgViewT<SvgView> {
public:
SvgView() = default;
SvgView(Microsoft::ReactNative::IReactContext const &context);
#ifdef USE_FABRIC
SvgView(const winrt::Microsoft::ReactNative::Composition::CreateCompositionComponentViewArgs &args);
winrt::Microsoft::ReactNative::ComponentView SvgParent() { return Parent(); }
winrt::Microsoft::ReactNative::Color CurrentColor() { return m_currentColor; }
// IRenderableFabric
void UpdateProperties(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps,
bool forceUpdate = true,
bool invalidate = true);
// Overrides
// IInternalCreateVisual
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual CreateInternalVisual();
// ComponentView
void UpdateProps(
const winrt::Microsoft::ReactNative::IComponentProps &props,
const winrt::Microsoft::ReactNative::IComponentProps &oldProps) noexcept;
void UpdateLayoutMetrics(
const winrt::Microsoft::ReactNative::LayoutMetrics &metrics,
const winrt::Microsoft::ReactNative::LayoutMetrics &oldMetrics);
void MountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept;
void UnmountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept;
void OnThemeChanged() noexcept;
static void RegisterComponent(const winrt::Microsoft::ReactNative::IReactPackageBuilderFabric &builder) noexcept;
#else
SvgView(winrt::Microsoft::ReactNative::IReactContext const &context);
xaml::FrameworkElement SvgParent() { return m_parent; }
void SvgParent(xaml::FrameworkElement const &value);
Windows::UI::Color CurrentColor() { return m_currentColor; }
// IRenderablePaper
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate = true, bool invalidate = true);
// Overrides
winrt::Windows::Foundation::Size MeasureOverride(winrt::Windows::Foundation::Size const &availableSize);
winrt::Windows::Foundation::Size ArrangeOverride(winrt::Windows::Foundation::Size const &finalSize);
void Panel_Loaded(winrt::Windows::Foundation::IInspectable const &sender, xaml::RoutedEventArgs const &args);
void Panel_Unloaded(winrt::Windows::Foundation::IInspectable const &sender, xaml::RoutedEventArgs const &args);
#endif
winrt::Windows::Foundation::Size CanvasSize() noexcept;
RNSVG::GroupView Group() { return m_group; }
void Group(RNSVG::GroupView const &value) { m_group = value; }
@@ -22,66 +117,66 @@ struct SvgView : SvgViewT<SvgView> {
RNSVG::D2DGeometry Geometry() { return m_group ? m_group.Geometry() : nullptr; }
void Geometry(RNSVG::D2DGeometry const & /*value*/) {}
Windows::UI::Color CurrentColor() { return m_currentColor; }
bool IsResponsible() { return m_isResponsible; }
void IsResponsible(bool isResponsible) { m_isResponsible = isResponsible; }
Windows::Foundation::Collections::IMap<hstring, RNSVG::IRenderable> Templates() {
return m_templates;
}
Windows::Foundation::Collections::IMap<hstring, RNSVG::BrushView> Brushes() {
Windows::Foundation::Collections::IMap<hstring, RNSVG::IBrushView> Brushes() {
return m_brushes;
}
// IRenderable
void UpdateProperties(Microsoft::ReactNative::IJSValueReader const &reader, bool forceUpdate = true, bool invalidate = true);
void MergeProperties(RNSVG::RenderableView const &other);
void MergeProperties(RNSVG::IRenderable const &other);
void SaveDefinition();
void Unload();
void Draw(RNSVG::D2DDeviceContext const &deviceContext, Windows::Foundation::Size const &size);
void CreateResources();
void CreateGeometry();
void CreateGeometry(RNSVG::D2DDeviceContext const &deviceContext);
RNSVG::IRenderable HitTest(Windows::Foundation::Point const & /*point*/) { return nullptr; }
// Overrides
Windows::Foundation::Size MeasureOverride(Windows::Foundation::Size const &availableSize);
Windows::Foundation::Size ArrangeOverride(Windows::Foundation::Size const &finalSize);
void Panel_Loaded(Windows::Foundation::IInspectable const &sender, xaml::RoutedEventArgs const &args);
void Panel_Unloaded(Windows::Foundation::IInspectable const &sender, xaml::RoutedEventArgs const &args);
void Invalidate();
private:
#ifdef USE_FABRIC
winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual m_visual{nullptr};
winrt::Microsoft::ReactNative::Color m_currentColor{nullptr};
winrt::Microsoft::ReactNative::LayoutMetrics m_layoutMetrics{{0, 0, 0, 0}, 1.0};
winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext m_compContext{nullptr};
#else
bool m_loaded{false};
xaml::FrameworkElement m_parent{nullptr};
xaml::Controls::Image m_image;
Windows::UI::Color m_currentColor{Colors::Black()};
xaml::FrameworkElement::Loaded_revoker m_panelLoadedRevoker{};
xaml::FrameworkElement::Unloaded_revoker m_panelUnloadedRevoker{};
#endif
// Shared
Microsoft::ReactNative::IReactContext m_reactContext{nullptr};
bool m_hasRendered{false};
bool m_isResponsible{false};
Microsoft::ReactNative::IReactContext m_reactContext{nullptr};
xaml::FrameworkElement m_parent{nullptr};
RNSVG::D2DDevice m_device;
RNSVG::D2DDeviceContext m_deviceContext;
xaml::Controls::Image m_image;
RNSVG::GroupView m_group{nullptr};
hstring m_id{L""};
float m_minX{0.0f};
float m_minY{0.0f};
float m_vbWidth{0.0f};
float m_vbHeight{0.0f};
RNSVG::SVGLength m_bbWidth{};
RNSVG::SVGLength m_bbHeight{};
RNSVG::SVGLength m_width{};
RNSVG::SVGLength m_height{};
RNSVG::SVGLength m_bbWidth{0, RNSVG::LengthType::Unknown};
RNSVG::SVGLength m_bbHeight{0, RNSVG::LengthType::Unknown};
RNSVG::SVGLength m_width{0, RNSVG::LengthType::Unknown};
RNSVG::SVGLength m_height{0, RNSVG::LengthType::Unknown};
std::string m_align{""};
RNSVG::MeetOrSlice m_meetOrSlice{RNSVG::MeetOrSlice::Meet};
Windows::UI::Color m_currentColor{Colors::Black()};
Windows::Foundation::Collections::IMap<hstring, RNSVG::IRenderable> m_templates{
winrt::single_threaded_map<hstring, RNSVG::IRenderable>()};
Windows::Foundation::Collections::IMap<hstring, RNSVG::BrushView> m_brushes{
winrt::single_threaded_map<hstring, RNSVG::BrushView>()};
xaml::FrameworkElement::Loaded_revoker m_panelLoadedRevoker{};
xaml::FrameworkElement::Unloaded_revoker m_panelUnloadedRevoker{};
Windows::Foundation::Collections::IMap<hstring, RNSVG::IBrushView> m_brushes{
winrt::single_threaded_map<hstring, RNSVG::IBrushView>()};
};
} // namespace winrt::RNSVG::implementation

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