Skip to content

Commit

Permalink
feat(svg): enable SVG on Windows (revery-ui#30)
Browse files Browse the repository at this point in the history
* Skia: enable building tools on Windows

* Build: disable component build on Windows

* Build: print tree (debug)

* Build: tree -> find (debug)

* Build: build static library on Windows

* Install: rename skia.lib -> libskia.a

* Skia: expose SVG in DLL, modify BUILD.gn

* Install: copy correct files

* Patches: add BUILD.gn patch

* Build: define ESY_SKIA_SVG

* Patches; update SVG patch

* Skia: create C bindings for SVGDOM w/ patch

* Build/Install: don't build separate SVG library on macOS

* Skia: include SVGDOM.h

* Build: include SVG model path

* Patches: update BUILD.gn patch

* Skia: include SVGNode alongside SVGDOM

* Patches: update SVG C bindings patch
  • Loading branch information
zbaylin authored Apr 27, 2021
1 parent f167b63 commit 9846aa2
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 10 deletions.
39 changes: 39 additions & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ declare_args() {
skia_use_angle = false
skia_use_egl = false
skia_use_expat = true
esy_skia_enable_svg = false
skia_use_fontconfig = is_linux
skia_use_freetype = is_android || is_fuchsia || is_linux
skia_use_icu = !is_fuchsia && !is_ios && !is_win # TODO: Windows
Expand Down Expand Up @@ -164,6 +165,10 @@ config("skia_private") {
include_dirs += [ "$skia_llvm_path/include" ]
}

if (esy_skia_enable_svg) {
include_dirs += [ "experimental/svg/model" ]
}

defines = [ "SK_GAMMA_APPLY_TO_A8" ]
if (is_android) {
defines += [
Expand Down Expand Up @@ -806,6 +811,39 @@ optional("xml") {
]
}

optional("svg") {
enabled = esy_skia_enable_svg
public_defines = [ "ESY_SKIA_SVG" ]
sources = [
"experimental/svg/model/SkSVGAttribute.cpp",
"experimental/svg/model/SkSVGAttributeParser.cpp",
"experimental/svg/model/SkSVGCircle.cpp",
"experimental/svg/model/SkSVGClipPath.cpp",
"experimental/svg/model/SkSVGContainer.cpp",
"experimental/svg/model/SkSVGDOM.cpp",
"experimental/svg/model/SkSVGEllipse.cpp",
"experimental/svg/model/SkSVGGradient.cpp",
"experimental/svg/model/SkSVGLine.cpp",
"experimental/svg/model/SkSVGLinearGradient.cpp",
"experimental/svg/model/SkSVGNode.cpp",
"experimental/svg/model/SkSVGPath.cpp",
"experimental/svg/model/SkSVGPattern.cpp",
"experimental/svg/model/SkSVGPoly.cpp",
"experimental/svg/model/SkSVGRadialGradient.cpp",
"experimental/svg/model/SkSVGRect.cpp",
"experimental/svg/model/SkSVGRenderContext.cpp",
"experimental/svg/model/SkSVGSVG.cpp",
"experimental/svg/model/SkSVGShape.cpp",
"experimental/svg/model/SkSVGStop.cpp",
"experimental/svg/model/SkSVGTransformableNode.cpp",
"experimental/svg/model/SkSVGUse.cpp",
"experimental/svg/model/SkSVGValue.cpp",
]
deps = [
":xml",
]
}

if (skia_enable_gpu && skia_generate_workarounds) {
action("workaround_list") {
script = "tools/build_workaround_header.py"
Expand Down Expand Up @@ -861,6 +899,7 @@ component("skia") {
":ssse3",
":webp",
":xml",
":svg",
]

# We need the public deps here for Vulkan. Our third_party/vulkan target sets some defines that
Expand Down
13 changes: 5 additions & 8 deletions esy/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ ln -s third_party/externals/gyp tools/gyp
if [[ $OS == "windows" ]]
then
WINDOWS_PYTHON_PATH="$(cygpath -w $(which $PYTHON_BINARY))"
bin/gn gen $cur__target_dir/out/Shared --script-executable="$WINDOWS_PYTHON_PATH" --args='is_debug=false is_component_build=true' || exit -1
ninja.exe -C $cur__target_dir/out/Shared skia skia.h experimental_svg_model
mv $cur__target_dir/out/Shared/libskia.dll $cur__target_dir/out/Shared/skia.dll # TODO this might not be required once we merge upstream
bin/gn gen $cur__target_dir/out/Shared --script-executable="$WINDOWS_PYTHON_PATH" --args='is_debug=false is_component_build=true esy_skia_enable_svg=true' || exit -1
ninja.exe -C $cur__target_dir/out/Shared
mv $cur__target_dir/out/Shared/libskia.dll $cur__target_dir/out/Shared/skia.dll
esy/gendef.exe - $cur__target_dir/out/Shared/skia.dll > $cur__target_dir/out/Shared/skia.def
x86_64-W64-mingw32-dlltool.exe -D $cur__target_dir/out/Shared/skia.dll -d $cur__target_dir/out/Shared/skia.def -A -l $cur__target_dir/out/Shared/libskia.a
else
Expand All @@ -41,9 +41,6 @@ else
echo "llvm toolset-7.0 does not need to be manually activated"
fi

bin/gn gen $cur__target_dir/out/Static --script-executable="$PYTHON_BINARY" "--args=cc=\"$CC\" cxx=\"$CXX\" skia_use_system_libjpeg_turbo=true skia_enable_tools=true is_debug=false extra_cflags=[\"-I${ESY_LIBJPEG_TURBO_PREFIX}/include\"] extra_ldflags=[\"-L${ESY_LIBJPEG_TURBO_PREFIX}/lib\", \"-ljpeg\" ]" || exit -1
ninja.exe -C $cur__target_dir/out/Static skia skia.h experimental_svg_model || exit -1

# Create a new library from the svg object file
ar rcs $cur__target_dir/out/Static/libskiasvg.a $cur__target_dir/out/Static/obj/experimental/svg/model/*.o
bin/gn gen $cur__target_dir/out/Static --script-executable="$PYTHON_BINARY" "--args=cc=\"$CC\" cxx=\"$CXX\" skia_use_system_libjpeg_turbo=true esy_skia_enable_svg=true is_debug=false extra_cflags=[\"-I${ESY_LIBJPEG_TURBO_PREFIX}/include\"] extra_ldflags=[\"-L${ESY_LIBJPEG_TURBO_PREFIX}/lib\", \"-ljpeg\" ]" || exit -1
ninja.exe -C $cur__target_dir/out/Static || exit -1
fi
1 change: 0 additions & 1 deletion esy/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ then
cp $cur__target_dir/out/Shared/skia.dll $cur__bin
else
cp $cur__target_dir/out/Static/libskia.a $cur__lib
cp $cur__target_dir/out/Static/libskiasvg.a $cur__lib
fi

# Create pkg-config file skia.pc
Expand Down
2 changes: 1 addition & 1 deletion experimental/svg/model/SkSVGDOM.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SkDOM;
class SkStream;
class SkSVGNode;

class SkSVGDOM : public SkRefCnt {
class SK_API SkSVGDOM : public SkRefCnt {
public:
SkSVGDOM();
~SkSVGDOM() = default;
Expand Down
9 changes: 9 additions & 0 deletions include/c/sk_svg.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ SK_C_PLUS_PLUS_BEGIN_GUARD

SK_C_API sk_canvas_t* sk_svgcanvas_create(const sk_rect_t* bounds, sk_xmlwriter_t* writer);

#ifdef ESY_SKIA_SVG
// esy-skia additions
SK_C_API void sk_svgdom_render(sk_svgdom_t *svgdom, sk_canvas_t *canvas);
SK_C_API void sk_svgdom_set_container_size(sk_svgdom_t *svgdom, float width, float height);
SK_C_API float sk_svgdom_get_container_width(sk_svgdom_t *svgdom);
SK_C_API float sk_svgdom_get_container_height(sk_svgdom_t *svgdom);
SK_C_API sk_svgdom_t *sk_svgdom_create_from_stream(sk_stream_t *stream);
#endif

SK_C_PLUS_PLUS_END_GUARD

#endif
1 change: 1 addition & 0 deletions include/c/sk_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,7 @@ typedef struct sk_xmlstreamwriter_t sk_xmlstreamwriter_t;
typedef struct sk_xmlwriter_t sk_xmlwriter_t;

typedef struct sk_svgcanvas_t sk_svgcanvas_t;
typedef struct sk_svgdom_t sk_svgdom_t;

typedef struct sk_3dview_t sk_3dview_t;

Expand Down
71 changes: 71 additions & 0 deletions patches/build-svg.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
diff --git a/BUILD.gn b/BUILD.gn
index 057b8b0d89..8808059a93 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -22,6 +22,7 @@ declare_args() {
skia_use_angle = false
skia_use_egl = false
skia_use_expat = true
+ esy_skia_enable_svg = false
skia_use_fontconfig = is_linux
skia_use_freetype = is_android || is_fuchsia || is_linux
skia_use_icu = !is_fuchsia && !is_ios && !is_win # TODO: Windows
@@ -164,6 +165,10 @@ config("skia_private") {
include_dirs += [ "$skia_llvm_path/include" ]
}

+ if (esy_skia_enable_svg) {
+ include_dirs += [ "experimental/svg/model" ]
+ }
+
defines = [ "SK_GAMMA_APPLY_TO_A8" ]
if (is_android) {
defines += [
@@ -806,6 +811,39 @@ optional("xml") {
]
}

+optional("svg") {
+ enabled = esy_skia_enable_svg
+ public_defines = [ "ESY_SKIA_SVG" ]
+ sources = [
+ "experimental/svg/model/SkSVGAttribute.cpp",
+ "experimental/svg/model/SkSVGAttributeParser.cpp",
+ "experimental/svg/model/SkSVGCircle.cpp",
+ "experimental/svg/model/SkSVGClipPath.cpp",
+ "experimental/svg/model/SkSVGContainer.cpp",
+ "experimental/svg/model/SkSVGDOM.cpp",
+ "experimental/svg/model/SkSVGEllipse.cpp",
+ "experimental/svg/model/SkSVGGradient.cpp",
+ "experimental/svg/model/SkSVGLine.cpp",
+ "experimental/svg/model/SkSVGLinearGradient.cpp",
+ "experimental/svg/model/SkSVGNode.cpp",
+ "experimental/svg/model/SkSVGPath.cpp",
+ "experimental/svg/model/SkSVGPattern.cpp",
+ "experimental/svg/model/SkSVGPoly.cpp",
+ "experimental/svg/model/SkSVGRadialGradient.cpp",
+ "experimental/svg/model/SkSVGRect.cpp",
+ "experimental/svg/model/SkSVGRenderContext.cpp",
+ "experimental/svg/model/SkSVGSVG.cpp",
+ "experimental/svg/model/SkSVGShape.cpp",
+ "experimental/svg/model/SkSVGStop.cpp",
+ "experimental/svg/model/SkSVGTransformableNode.cpp",
+ "experimental/svg/model/SkSVGUse.cpp",
+ "experimental/svg/model/SkSVGValue.cpp",
+ ]
+ deps = [
+ ":xml",
+ ]
+}
+
if (skia_enable_gpu && skia_generate_workarounds) {
action("workaround_list") {
script = "tools/build_workaround_header.py"
@@ -861,6 +899,7 @@ component("skia") {
":ssse3",
":webp",
":xml",
+ ":svg",
]

# We need the public deps here for Vulkan. Our third_party/vulkan target sets some defines that
13 changes: 13 additions & 0 deletions patches/expose-svgdom.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/experimental/svg/model/SkSVGDOM.h b/experimental/svg/model/SkSVGDOM.h
index 8904c1799d..117d15ec33 100644
--- a/experimental/svg/model/SkSVGDOM.h
+++ b/experimental/svg/model/SkSVGDOM.h
@@ -18,7 +18,7 @@ class SkDOM;
class SkStream;
class SkSVGNode;

-class SkSVGDOM : public SkRefCnt {
+class SK_API SkSVGDOM : public SkRefCnt {
public:
SkSVGDOM();
~SkSVGDOM() = default;
88 changes: 88 additions & 0 deletions patches/svg-c-bindings.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
diff --git a/include/c/sk_svg.h b/include/c/sk_svg.h
index f0e384423e..5e0ccc519f 100644
--- a/include/c/sk_svg.h
+++ b/include/c/sk_svg.h
@@ -16,6 +16,15 @@ SK_C_PLUS_PLUS_BEGIN_GUARD

SK_C_API sk_canvas_t* sk_svgcanvas_create(const sk_rect_t* bounds, sk_xmlwriter_t* writer);

+#ifdef ESY_SKIA_SVG
+// esy-skia additions
+SK_C_API void sk_svgdom_render(sk_svgdom_t *svgdom, sk_canvas_t *canvas);
+SK_C_API void sk_svgdom_set_container_size(sk_svgdom_t *svgdom, float width, float height);
+SK_C_API float sk_svgdom_get_container_width(sk_svgdom_t *svgdom);
+SK_C_API float sk_svgdom_get_container_height(sk_svgdom_t *svgdom);
+SK_C_API sk_svgdom_t *sk_svgdom_create_from_stream(sk_stream_t *stream);
+#endif
+
SK_C_PLUS_PLUS_END_GUARD

#endif
diff --git a/include/c/sk_types.h b/include/c/sk_types.h
index fa24d1ce0d..4cfeda87ed 100644
--- a/include/c/sk_types.h
+++ b/include/c/sk_types.h
@@ -813,6 +813,7 @@ typedef struct sk_xmlstreamwriter_t sk_xmlstreamwriter_t;
typedef struct sk_xmlwriter_t sk_xmlwriter_t;

typedef struct sk_svgcanvas_t sk_svgcanvas_t;
+typedef struct sk_svgdom_t sk_svgdom_t;

typedef struct sk_3dview_t sk_3dview_t;

diff --git a/src/c/sk_svg.cpp b/src/c/sk_svg.cpp
index 01799b8799..1a89349784 100644
--- a/src/c/sk_svg.cpp
+++ b/src/c/sk_svg.cpp
@@ -9,6 +9,11 @@

#include "SkSVGCanvas.h"

+#ifdef ESY_SKIA_SVG
+#include "SkSVGDOM.h"
+#include "SkSVGNode.h"
+#endif
+
#include "sk_svg.h"

#include "sk_types_priv.h"
@@ -18,3 +23,26 @@
sk_canvas_t* sk_svgcanvas_create(const sk_rect_t* bounds, sk_xmlwriter_t* writer) {
return ToCanvas(SkSVGCanvas::Make(*AsRect(bounds), AsXMLWriter(writer)).release());
}
+
+#ifdef ESY_SKIA_SVG
+void sk_svgdom_render(sk_svgdom_t *svgdom, sk_canvas_t *canvas) {
+ AsSVGDOM(svgdom)->render(AsCanvas(canvas));
+}
+
+void sk_svgdom_set_container_size(sk_svgdom_t *svgdom, float width, float height) {
+ AsSVGDOM(svgdom)->setContainerSize(SkSize::Make(width, height));
+}
+
+float sk_svgdom_get_container_width(sk_svgdom_t *svgdom) {
+ return AsSVGDOM(svgdom)->containerSize().width();
+}
+
+float sk_svgdom_get_container_height(sk_svgdom_t *svgdom) {
+ return AsSVGDOM(svgdom)->containerSize().height();
+}
+
+sk_svgdom_t *sk_svgdom_create_from_stream(sk_stream_t *stream) {
+ std::unique_ptr<SkStream> skstream(AsStream(stream));
+ return ToSVGDOM(SkSVGDOM::MakeFromStream(*skstream).release());
+}
+#endif
diff --git a/src/c/sk_types_priv.h b/src/c/sk_types_priv.h
index f2b8d6a1ea..bc9b580a7e 100644
--- a/src/c/sk_types_priv.h
+++ b/src/c/sk_types_priv.h
@@ -110,6 +110,8 @@ DEF_CLASS_MAP(GrContext, gr_context_t, GrContext)
DEF_CLASS_MAP(GrBackendTexture, gr_backendtexture_t, GrBackendTexture)
DEF_CLASS_MAP(GrBackendRenderTarget, gr_backendrendertarget_t, GrBackendRenderTarget)

+DEF_CLASS_MAP(SkSVGDOM, sk_svgdom_t, SVGDOM)
+
DEF_STRUCT_MAP(SkColorSpacePrimaries, sk_colorspaceprimaries_t, ColorSpacePrimaries)
DEF_STRUCT_MAP(SkColorSpaceTransferFn, sk_colorspace_transfer_fn_t, ColorSpaceTransferFn)
DEF_STRUCT_MAP(SkHighContrastConfig, sk_highcontrastconfig_t, HighContrastConfig)
28 changes: 28 additions & 0 deletions src/c/sk_svg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@

#include "SkSVGCanvas.h"

#ifdef ESY_SKIA_SVG
#include "SkSVGDOM.h"
#include "SkSVGNode.h"
#endif

#include "sk_svg.h"

#include "sk_types_priv.h"
Expand All @@ -18,3 +23,26 @@
sk_canvas_t* sk_svgcanvas_create(const sk_rect_t* bounds, sk_xmlwriter_t* writer) {
return ToCanvas(SkSVGCanvas::Make(*AsRect(bounds), AsXMLWriter(writer)).release());
}

#ifdef ESY_SKIA_SVG
void sk_svgdom_render(sk_svgdom_t *svgdom, sk_canvas_t *canvas) {
AsSVGDOM(svgdom)->render(AsCanvas(canvas));
}

void sk_svgdom_set_container_size(sk_svgdom_t *svgdom, float width, float height) {
AsSVGDOM(svgdom)->setContainerSize(SkSize::Make(width, height));
}

float sk_svgdom_get_container_width(sk_svgdom_t *svgdom) {
return AsSVGDOM(svgdom)->containerSize().width();
}

float sk_svgdom_get_container_height(sk_svgdom_t *svgdom) {
return AsSVGDOM(svgdom)->containerSize().height();
}

sk_svgdom_t *sk_svgdom_create_from_stream(sk_stream_t *stream) {
std::unique_ptr<SkStream> skstream(AsStream(stream));
return ToSVGDOM(SkSVGDOM::MakeFromStream(*skstream).release());
}
#endif
2 changes: 2 additions & 0 deletions src/c/sk_types_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ DEF_CLASS_MAP(GrContext, gr_context_t, GrContext)
DEF_CLASS_MAP(GrBackendTexture, gr_backendtexture_t, GrBackendTexture)
DEF_CLASS_MAP(GrBackendRenderTarget, gr_backendrendertarget_t, GrBackendRenderTarget)

DEF_CLASS_MAP(SkSVGDOM, sk_svgdom_t, SVGDOM)

DEF_STRUCT_MAP(SkColorSpacePrimaries, sk_colorspaceprimaries_t, ColorSpacePrimaries)
DEF_STRUCT_MAP(SkColorSpaceTransferFn, sk_colorspace_transfer_fn_t, ColorSpaceTransferFn)
DEF_STRUCT_MAP(SkHighContrastConfig, sk_highcontrastconfig_t, HighContrastConfig)
Expand Down

0 comments on commit 9846aa2

Please sign in to comment.