Skip to content

Commit b42c2ca

Browse files
authored
Implement recursive bezier curve subdivision algorithm (#22)
1 parent b27bf9f commit b42c2ca

118 files changed

Lines changed: 78736 additions & 14 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build.yml

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,50 +71,79 @@ jobs:
7171
run: dotnet restore
7272

7373
- name: Build AffinityPluginLoader
74-
run: dotnet build AffinityPluginLoader/AffinityPluginLoader.csproj -c Release
74+
run: dotnet build AffinityPluginLoader/AffinityPluginLoader.csproj -c Debug
7575

7676
- name: Build WineFix
77-
run: dotnet build WineFix/WineFix.csproj -c Release
77+
run: dotnet build WineFix/WineFix.csproj -c Debug
7878

7979
- name: Build AffinityHook
80-
run: dotnet build AffinityHook/AffinityHook.csproj -c Release
80+
run: dotnet build AffinityHook/AffinityHook.csproj -c Debug
8181

8282
- name: Upload AffinityPluginLoader artifacts
8383
uses: actions/upload-artifact@v4
8484
with:
8585
name: AffinityPluginLoader
8686
path: |
87-
AffinityPluginLoader/bin/Release/net48/win-x64/AffinityPluginLoader.dll
88-
AffinityPluginLoader/bin/Release/net48/win-x64/0Harmony.dll
87+
AffinityPluginLoader/bin/Debug/net48/win-x64/AffinityPluginLoader.dll
88+
AffinityPluginLoader/bin/Debug/net48/win-x64/0Harmony.dll
8989
if-no-files-found: error
9090

9191
- name: Upload AffinityHook artifacts
9292
uses: actions/upload-artifact@v4
9393
with:
9494
name: AffinityHook
95-
path: AffinityHook/bin/Release/net48/win-x64/AffinityHook.exe
95+
path: AffinityHook/bin/Debug/net48/win-x64/AffinityHook.exe
9696
if-no-files-found: error
9797

9898
- name: Upload WineFix artifacts
9999
uses: actions/upload-artifact@v4
100100
with:
101101
name: WineFix
102-
path: WineFix/bin/Release/net48/win-x64/WineFix.dll
102+
path: WineFix/bin/Debug/net48/win-x64/WineFix.dll
103+
if-no-files-found: error
104+
105+
# Build d2d1.dll for Wine (x86_64-unix)
106+
build-d2d1:
107+
name: Build d2d1.dll (Wine Native)
108+
runs-on: ubuntu-latest
109+
110+
steps:
111+
- name: Checkout code
112+
uses: actions/checkout@v4
113+
114+
- name: Install Wine development tools
115+
run: |
116+
sudo dpkg --add-architecture i386
117+
sudo mkdir -pm755 /etc/apt/keyrings
118+
sudo wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key
119+
sudo wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/ubuntu/dists/jammy/winehq-jammy.sources
120+
sudo apt update
121+
sudo apt install -y --install-recommends wine64-tools
122+
123+
- name: Build d2d1.dll for x86_64-unix
124+
working-directory: WineFix/lib/d2d1
125+
run: make TARGET=x86_64-unix
126+
127+
- name: Upload d2d1 artifact
128+
uses: actions/upload-artifact@v4
129+
with:
130+
name: d2d1
131+
path: WineFix/lib/d2d1/build/x86_64-unix/d2d1.dll.so
103132
if-no-files-found: error
104133

105134
# Package all artifacts into release archives
106135
package:
107136
name: Package Release Artifacts
108137
runs-on: ubuntu-latest
109-
needs: [build-bootstrap, build-csharp]
138+
needs: [build-bootstrap, build-csharp, build-d2d1]
110139

111140
steps:
112141
- name: Checkout code
113142
uses: actions/checkout@v4
114143

115144
- name: Get short commit hash
116145
id: commit
117-
run: echo "short_sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
146+
run: echo "short_sha=$(echo ${{ github.event.pull_request.head.sha }} | cut -c1-7)" >> $GITHUB_OUTPUT
118147

119148
- name: Download AffinityBootstrap artifact
120149
uses: actions/download-artifact@v4
@@ -140,6 +169,12 @@ jobs:
140169
name: WineFix
141170
path: build/winefix
142171

172+
- name: Download d2d1 artifact
173+
uses: actions/download-artifact@v4
174+
with:
175+
name: d2d1
176+
path: build/d2d1
177+
143178
- name: Create affinitypluginloader package structure
144179
run: |
145180
mkdir -p package/affinitypluginloader
@@ -155,6 +190,7 @@ jobs:
155190
mkdir -p package/winefix/plugins
156191
cp build/winefix/WineFix.dll package/winefix/plugins/
157192
cp WineFix/LICENSE package/winefix/plugins/LICENSE
193+
cp build/d2d1/d2d1.dll.so package/winefix/d2d1.dll
158194
159195
- name: Create combined package structure
160196
run: |
@@ -164,6 +200,7 @@ jobs:
164200
cp build/pluginloader/AffinityPluginLoader.dll package/combined/
165201
cp build/pluginloader/0Harmony.dll package/combined/
166202
cp build/winefix/WineFix.dll package/combined/plugins/
203+
cp build/d2d1/d2d1.dll.so package/combined/d2d1.dll
167204
168205
- name: Create release archives
169206
run: |

.github/workflows/pr-comment-complete.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,16 @@ jobs:
3030
PR_NUMBER=$(gh pr view "$PR_BRANCH" --repo ${{ github.repository }} --json number --jq '.number')
3131
echo "number=$PR_NUMBER" >> $GITHUB_OUTPUT
3232
33+
- name: Download commit SHA artifact
34+
uses: actions/download-artifact@v4
35+
with:
36+
name: commit_sha
37+
run-id: ${{ github.event.workflow_run.id }}
38+
3339
- name: Get commit and run info
3440
id: run-info
3541
run: |
36-
echo "short_sha=$(echo ${{ github.event.workflow_run.head_sha }} | cut -c1-7)" >> $GITHUB_OUTPUT
42+
echo "short_sha=$(cat commit_sha.txt | cut -c1-7)" >> $GITHUB_OUTPUT
3743
echo "run_id=${{ github.event.workflow_run.id }}" >> $GITHUB_OUTPUT
3844
echo "conclusion=${{ github.event.workflow_run.conclusion }}" >> $GITHUB_OUTPUT
3945

WineFix/README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,16 @@ especially if the bug needs to be patched in native code.
2727

2828
## Licensing
2929

30-
WineFix is licensed under the terms of the GPLv2 except for the exemption noted below. You can find a copy of the license in the LICENSE file.
30+
WineFix is licensed under the terms of the GPLv2 except for the exclusion and exemption noted below. You can find a copy of the license in the LICENSE file.
31+
32+
### License Exclusion
33+
34+
WineFix includes source code from the Wine project for d2d1.dll under `/WineFix/lib/d2d1`. In accordance with the original project, the code in this directory are instead licensed under the LGPLv2.1. A copy of this license can be found at `/WineFix/lib/d2d1/LICENSE`. Changes have been applied to the d2d1 source code to implement a recursive cubic bezier subdivision algorithm to correct cubic bezier rendering in Affinity, and to allow building d2d1.dll standalone from the full Wine source code repository.
3135

3236
### License Exemption
3337

34-
[Canva](https://github.com/canva) and it's subsidiaries are exempt from MIT licensing and may (at its option) instead license any source code authored for the WineFix project under the Zero-Clause BSD license.
38+
[Canva](https://github.com/canva) and it's subsidiaries are exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the WineFix project under the Zero-Clause BSD license.
39+
- Due to requirements of the upstream Wine licensing, this exemption **does not apply** to the d2d1.dll implementation source code, ie. all code under `WineFix/lib/d2d1/` is excluded from this exemption.
3540

3641

3742
# Credits

WineFix/lib/d2d1/.gitignore

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Build directories
2+
build/
3+
build-*/
4+
5+
# Object files
6+
*.o
7+
*.obj
8+
*.lo
9+
10+
# Libraries
11+
*.lib
12+
*.a
13+
*.la
14+
15+
# Shared objects (DLLs)
16+
*.dll
17+
*.dll.so
18+
*.so
19+
*.dylib
20+
21+
# Executables
22+
*.exe
23+
*.out
24+
*.app
25+
26+
# Generated files
27+
*.res
28+
*.rc.tmp
29+
*_processed.rc
30+
31+
# IDL generated headers
32+
include/generated/
33+
34+
# CMake
35+
CMakeCache.txt
36+
CMakeFiles/
37+
cmake_install.cmake
38+
install_manifest.txt
39+
40+
# IDE files
41+
.vscode/
42+
.idea/
43+
*.swp
44+
*.swo
45+
*~
46+
47+
# OS files
48+
.DS_Store
49+
Thumbs.db
50+
51+
# Dependency files
52+
*.d
53+
54+
# Log files
55+
*.log

WineFix/lib/d2d1/CMakeLists.txt

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
project(d2d1 VERSION 10.18 LANGUAGES C)
3+
4+
# Options for build configuration
5+
option(BUILD_FOR_UNIX "Build Unix PE format (requires winegcc)" OFF)
6+
option(BUILD_SYSWOW64 "Build for SysWoW64 mode" OFF)
7+
set(TARGET_ARCH "x86_64" CACHE STRING "Target architecture (x86_64 or i386)")
8+
9+
# Set compiler based on architecture
10+
if(TARGET_ARCH STREQUAL "i386")
11+
set(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
12+
set(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
13+
set(ARCH_FLAGS -m32 -D__i386__)
14+
else()
15+
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
16+
set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
17+
set(ARCH_FLAGS -m64 -D__x86_64__)
18+
endif()
19+
20+
# Source files
21+
set(D2D1_SOURCES
22+
src/bitmap.c
23+
src/bitmap_render_target.c
24+
src/brush.c
25+
src/command_list.c
26+
src/dc_render_target.c
27+
src/device.c
28+
src/effect.c
29+
src/factory.c
30+
src/geometry.c
31+
src/hwnd_render_target.c
32+
src/layer.c
33+
src/mesh.c
34+
src/state_block.c
35+
src/stroke.c
36+
src/wic_render_target.c
37+
)
38+
39+
# IDL files to process
40+
file(GLOB IDL_FILES "include/windows/*.idl")
41+
42+
# Create custom command to process IDL files
43+
set(IDL_HEADERS "")
44+
foreach(IDL_FILE ${IDL_FILES})
45+
get_filename_component(IDL_NAME ${IDL_FILE} NAME_WE)
46+
set(IDL_HEADER "${CMAKE_BINARY_DIR}/include/${IDL_NAME}.h")
47+
add_custom_command(
48+
OUTPUT ${IDL_HEADER}
49+
COMMAND widl -I${CMAKE_SOURCE_DIR}/include/windows -h -o ${IDL_HEADER} ${IDL_FILE}
50+
DEPENDS ${IDL_FILE}
51+
COMMENT "Processing IDL: ${IDL_NAME}.idl"
52+
)
53+
list(APPEND IDL_HEADERS ${IDL_HEADER})
54+
endforeach()
55+
56+
# Create a custom target for IDL headers
57+
add_custom_target(idl_headers DEPENDS ${IDL_HEADERS})
58+
59+
# Create the DLL
60+
add_library(d2d1 SHARED ${D2D1_SOURCES})
61+
62+
# Make sure IDL headers are generated before compiling
63+
add_dependencies(d2d1 idl_headers)
64+
65+
# Include directories
66+
target_include_directories(d2d1 PRIVATE
67+
${CMAKE_SOURCE_DIR}/include/wine
68+
${CMAKE_SOURCE_DIR}/include/windows
69+
${CMAKE_BINARY_DIR}/include
70+
${CMAKE_SOURCE_DIR}/src
71+
)
72+
73+
# Compiler definitions
74+
target_compile_definitions(d2d1 PRIVATE
75+
__WINE__
76+
_REENTRANT
77+
WINE_UNICODE_NATIVE
78+
$<$<BOOL:${BUILD_FOR_UNIX}>:__unix__>
79+
$<$<BOOL:${BUILD_SYSWOW64}>:__WINE_SYSWOW64__>
80+
)
81+
82+
# Compiler flags
83+
target_compile_options(d2d1 PRIVATE
84+
${ARCH_FLAGS}
85+
-Wall
86+
-O2
87+
)
88+
89+
# Linker flags
90+
target_link_options(d2d1 PRIVATE
91+
${ARCH_FLAGS}
92+
$<$<NOT:$<BOOL:${BUILD_FOR_UNIX}>>:-shared>
93+
)
94+
95+
# Link libraries
96+
target_link_libraries(d2d1 PRIVATE
97+
d3d11
98+
dxgi
99+
d3d10_1
100+
d3dcompiler
101+
dwrite
102+
gdi32
103+
user32
104+
advapi32
105+
ole32
106+
xmllite
107+
uuid
108+
)
109+
110+
# Set output name
111+
set_target_properties(d2d1 PROPERTIES
112+
OUTPUT_NAME "d2d1"
113+
PREFIX ""
114+
SUFFIX ".dll"
115+
)
116+
117+
# Resource file handling
118+
if(EXISTS "${CMAKE_SOURCE_DIR}/src/version.rc")
119+
target_sources(d2d1 PRIVATE src/version.rc)
120+
endif()
121+
122+
# Install rules
123+
install(TARGETS d2d1
124+
RUNTIME DESTINATION bin
125+
LIBRARY DESTINATION lib
126+
ARCHIVE DESTINATION lib
127+
)
128+
129+
# Print configuration
130+
message(STATUS "D2D1 Build Configuration:")
131+
message(STATUS " Architecture: ${TARGET_ARCH}")
132+
message(STATUS " Build for Unix PE: ${BUILD_FOR_UNIX}")
133+
message(STATUS " SysWoW64 mode: ${BUILD_SYSWOW64}")
134+
message(STATUS " Compiler: ${CMAKE_C_COMPILER}")

WineFix/lib/d2d1/LICENSE

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
GNU LESSER GENERAL PUBLIC LICENSE
2+
Version 2.1, February 1999
3+
4+
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6+
Everyone is permitted to copy and distribute verbatim copies
7+
of this license document, but changing it is not allowed.
8+
9+
[This is the first released version of the Lesser GPL. It also counts
10+
as the successor of the GNU Library Public License, version 2, hence
11+
the version number 2.1.]
12+
13+
This library is free software; you can redistribute it and/or
14+
modify it under the terms of the GNU Lesser General Public
15+
License as published by the Free Software Foundation; either
16+
version 2.1 of the License, or (at your option) any later version.
17+
18+
This library is distributed in the hope that it will be useful,
19+
but WITHOUT ANY WARRANTY; without even the implied warranty of
20+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21+
Lesser General Public License for more details.
22+
23+
You should have received a copy of the GNU Lesser General Public
24+
License along with this library; if not, write to the Free Software
25+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26+
27+
---
28+
29+
This code is extracted from Wine 10.18
30+
Copyright (c) 1993-2025 the Wine project authors
31+
32+
For a complete list of Wine authors, see:
33+
https://www.winehq.org/
34+
35+
The Wine project is licensed under the LGPL 2.1.
36+
For the full license text, see:
37+
https://www.winehq.org/license

0 commit comments

Comments
 (0)