From d309eac2828e10d453385e73e37f2ed2d9e38a22 Mon Sep 17 00:00:00 2001 From: "Klare, Heiko" Date: Wed, 11 Mar 2026 09:30:36 +0100 Subject: [PATCH] Make an independent bundle out of SWT SVG fragment org.eclipse.swt.svg was implemented as a fragment for the SWT host. This requires a complex setup due to the SVG fragment depending on the effective SWT API provided by the native fragments. With the SVG rasterizer being provided via an OSGi capability anyway, the reason for having the SVG bundle as a fragment became obsolete. This change makes org.eclipse.swt.svg an ordinary bundle. The according tests are extracted into a separate bundle as well, making the SWT tests properly independent from the tests for the specific SVG rasterizer. Contributes to https://github.com/eclipse-platform/eclipse.platform.swt/issues/3129 --- .../org.eclipse.swt.svg/META-INF/MANIFEST.MF | 12 ++- bundles/org.eclipse.swt.svg/META-INF/p2.inf | 32 ------ bundles/org.eclipse.swt.svg/build.properties | 13 +-- ...{fragment.properties => plugin.properties} | 2 +- bundles/org.eclipse.swt/META-INF/MANIFEST.MF | 4 +- pom.xml | 1 + tests/org.eclipse.swt.svg.tests/.classpath | 11 ++ tests/org.eclipse.swt.svg.tests/.project | 41 +++++++ .../org.eclipse.core.resources.prefs | 2 + .../META-INF/MANIFEST.MF | 12 +++ .../build.properties | 7 ++ .../src/org/eclipse/swt/svg/AllSVGTests.java | 21 ++++ .../eclipse/swt/svg/JSVGRasterizerTest.java | 102 ++++++++++++++++++ 13 files changed, 209 insertions(+), 51 deletions(-) delete mode 100644 bundles/org.eclipse.swt.svg/META-INF/p2.inf rename bundles/org.eclipse.swt.svg/{fragment.properties => plugin.properties} (93%) create mode 100644 tests/org.eclipse.swt.svg.tests/.classpath create mode 100644 tests/org.eclipse.swt.svg.tests/.project create mode 100644 tests/org.eclipse.swt.svg.tests/.settings/org.eclipse.core.resources.prefs create mode 100644 tests/org.eclipse.swt.svg.tests/META-INF/MANIFEST.MF create mode 100644 tests/org.eclipse.swt.svg.tests/build.properties create mode 100644 tests/org.eclipse.swt.svg.tests/src/org/eclipse/swt/svg/AllSVGTests.java create mode 100644 tests/org.eclipse.swt.svg.tests/src/org/eclipse/swt/svg/JSVGRasterizerTest.java diff --git a/bundles/org.eclipse.swt.svg/META-INF/MANIFEST.MF b/bundles/org.eclipse.swt.svg/META-INF/MANIFEST.MF index f51e06d1b83..bb431eae3c9 100644 --- a/bundles/org.eclipse.swt.svg/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.swt.svg/META-INF/MANIFEST.MF @@ -3,11 +3,12 @@ Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.swt.svg Bundle-Version: 3.133.100.qualifier Automatic-Module-Name: org.eclipse.swt.svg -Bundle-Name: %fragmentName +Bundle-ActivationPolicy: lazy +Bundle-Name: %pluginName Bundle-Vendor: %providerName -Bundle-Localization: fragment +Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-21 -Fragment-Host: org.eclipse.swt +Require-Bundle: org.eclipse.swt Import-Package: com.github.weisj.jsvg;version="[2.1.0,3.0.0)", com.github.weisj.jsvg.logging;version="[2.1.0,3.0.0)", com.github.weisj.jsvg.parser;version="[2.1.0,3.0.0)", @@ -22,5 +23,6 @@ Provide-Capability: effective:=active, osgi.serviceloader; osgi.serviceloader="com.github.weisj.jsvg.logging.LogManager"; - register:="org.eclipse.swt.svg.logging.JVSGLoggerLogManager" - + register:="org.eclipse.swt.svg.logging.JVSGLoggerLogManager", + osgi.serviceloader;osgi.serviceloader="org.eclipse.swt.internal.image.SVGRasterizer" +Require-Capability: osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)" diff --git a/bundles/org.eclipse.swt.svg/META-INF/p2.inf b/bundles/org.eclipse.swt.svg/META-INF/p2.inf deleted file mode 100644 index 9818f97c079..00000000000 --- a/bundles/org.eclipse.swt.svg/META-INF/p2.inf +++ /dev/null @@ -1,32 +0,0 @@ -# ensure that the applicable implementation fragment gets installed (https://github.com/eclipse-platform/eclipse.platform.releng.aggregator/issues/3006) -requires.1.namespace = org.eclipse.equinox.p2.iu -requires.1.name = org.eclipse.swt.win32.win32.x86_64 -requires.1.filter = (&(osgi.os=win32)(osgi.ws=win32)(osgi.arch=x86_64)) - -requires.2.namespace = org.eclipse.equinox.p2.iu -requires.2.name = org.eclipse.swt.cocoa.macosx.x86_64 -requires.2.filter = (&(osgi.os=macosx)(osgi.ws=cocoa)(osgi.arch=x86_64)) - -requires.3.namespace = org.eclipse.equinox.p2.iu -requires.3.name = org.eclipse.swt.gtk.linux.x86_64 -requires.3.filter = (&(osgi.os=linux)(osgi.ws=gtk)(osgi.arch=x86_64)) - -requires.4.namespace = org.eclipse.equinox.p2.iu -requires.4.name = org.eclipse.swt.gtk.linux.ppc64le -requires.4.filter = (&(osgi.os=linux)(osgi.ws=gtk)(osgi.arch=ppc64le)) - -requires.5.namespace = org.eclipse.equinox.p2.iu -requires.5.name = org.eclipse.swt.gtk.linux.aarch64 -requires.5.filter = (&(osgi.os=linux)(osgi.ws=gtk)(osgi.arch=aarch64)) - -requires.6.namespace = org.eclipse.equinox.p2.iu -requires.6.name = org.eclipse.swt.cocoa.macosx.aarch64 -requires.6.filter = (&(osgi.os=macosx)(osgi.ws=cocoa)(osgi.arch=aarch64)) - -requires.7.namespace = org.eclipse.equinox.p2.iu -requires.7.name = org.eclipse.swt.win32.win32.aarch64 -requires.7.filter = (&(osgi.os=win32)(osgi.ws=win32)(osgi.arch=aarch64)) - -requires.8.namespace = org.eclipse.equinox.p2.iu -requires.8.name = org.eclipse.swt.gtk.linux.riscv64 -requires.8.filter = (&(osgi.os=linux)(osgi.ws=gtk)(osgi.arch=riscv64)) diff --git a/bundles/org.eclipse.swt.svg/build.properties b/bundles/org.eclipse.swt.svg/build.properties index b314a4ad438..816374508f3 100644 --- a/bundles/org.eclipse.swt.svg/build.properties +++ b/bundles/org.eclipse.swt.svg/build.properties @@ -17,17 +17,6 @@ source.. = src/,\ output.. = bin/ bin.includes = META-INF/,\ .,\ - fragment.properties,\ + plugin.properties,\ about.html src.includes = about.html - -pom.model.property.tycho.extraClasspathJars=IGNORE - -jars.extra.classpath = platform:/plugin/org.eclipse.swt.cocoa.macosx.aarch64,\ - platform:/plugin/org.eclipse.swt.cocoa.macosx.x86_64,\ - platform:/plugin/org.eclipse.swt.gtk.linux.aarch64,\ - platform:/plugin/org.eclipse.swt.gtk.linux.ppc64le,\ - platform:/plugin/org.eclipse.swt.gtk.linux.riscv64,\ - platform:/plugin/org.eclipse.swt.gtk.linux.x86_64,\ - platform:/plugin/org.eclipse.swt.win32.win32.aarch64,\ - platform:/plugin/org.eclipse.swt.win32.win32.x86_64 diff --git a/bundles/org.eclipse.swt.svg/fragment.properties b/bundles/org.eclipse.swt.svg/plugin.properties similarity index 93% rename from bundles/org.eclipse.swt.svg/fragment.properties rename to bundles/org.eclipse.swt.svg/plugin.properties index 1ae8d5b50da..aca08332f56 100644 --- a/bundles/org.eclipse.swt.svg/fragment.properties +++ b/bundles/org.eclipse.swt.svg/plugin.properties @@ -10,5 +10,5 @@ # Contributors: # Michael Bangas (Vector Informatik GmbH) - initial API and implementation ############################################################################### -fragmentName = SWT SVG Rendering Support +pluginName = SWT SVG Rendering Support providerName = Eclipse.org diff --git a/bundles/org.eclipse.swt/META-INF/MANIFEST.MF b/bundles/org.eclipse.swt/META-INF/MANIFEST.MF index dc21e745e09..686e8391ac1 100644 --- a/bundles/org.eclipse.swt/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.swt/META-INF/MANIFEST.MF @@ -16,7 +16,7 @@ Export-Package: org.eclipse.swt.events, org.eclipse.swt.graphics, org.eclipse.swt.internal;x-internal:=true, - org.eclipse.swt.internal.image;x-internal:=true, + org.eclipse.swt.internal.image;x-friends:="org.eclipse.swt.svg", org.eclipse.swt.layout, org.eclipse.swt.opengl, org.eclipse.swt.printing, @@ -25,3 +25,5 @@ Export-Package: Eclipse-ExtensibleAPI: true Bundle-RequiredExecutionEnvironment: JavaSE-21 Automatic-Module-Name: org.eclipse.swt +Require-Capability: osgi.extender;filter:="(&(osgi.extender=osgi.serviceloader.processor)(version>=1.0.0)(!(version>=2.0.0)))", + osgi.serviceloader;filter:="(osgi.serviceloader=org.eclipse.swt.internal.image.SVGRasterizer)";resolution:=optional diff --git a/pom.xml b/pom.xml index e632b7e0846..93f3cf91a93 100644 --- a/pom.xml +++ b/pom.xml @@ -175,6 +175,7 @@ examples/org.eclipse.swt.examples.ole.win32 examples/org.eclipse.swt.examples.views tests/org.eclipse.swt.tests + tests/org.eclipse.swt.svg.tests features/org.eclipse.swt.tools.feature diff --git a/tests/org.eclipse.swt.svg.tests/.classpath b/tests/org.eclipse.swt.svg.tests/.classpath new file mode 100644 index 00000000000..1aa9eca95a0 --- /dev/null +++ b/tests/org.eclipse.swt.svg.tests/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/tests/org.eclipse.swt.svg.tests/.project b/tests/org.eclipse.swt.svg.tests/.project new file mode 100644 index 00000000000..4362fd58090 --- /dev/null +++ b/tests/org.eclipse.swt.svg.tests/.project @@ -0,0 +1,41 @@ + + + org.eclipse.swt.svg.tests + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + + + .settings/org.eclipse.jdt.core.prefs + 1 + SHARED_SETTINGS/org.eclipse.jdt.core.prefs + + + + + SHARED_SETTINGS + $%7BPARENT-2-PROJECT_LOC%7D/examples/.settings_shared + + + diff --git a/tests/org.eclipse.swt.svg.tests/.settings/org.eclipse.core.resources.prefs b/tests/org.eclipse.swt.svg.tests/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000000..99f26c0203a --- /dev/null +++ b/tests/org.eclipse.swt.svg.tests/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/tests/org.eclipse.swt.svg.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.swt.svg.tests/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..84b5294b599 --- /dev/null +++ b/tests/org.eclipse.swt.svg.tests/META-INF/MANIFEST.MF @@ -0,0 +1,12 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Eclipse SWT Tests SVG +Fragment-Host: org.eclipse.swt.svg +Bundle-SymbolicName: org.eclipse.swt.svg.tests +Bundle-Version: 3.0.0.qualifier +Automatic-Module-Name: org.eclipse.swt.svg.tests +Bundle-RequiredExecutionEnvironment: JavaSE-21 +Import-Package: org.junit.jupiter.api;version="[5.14.0,6.0.0)", + org.junit.jupiter.api.function;version="[5.14.0,6.0.0)", + org.junit.platform.suite.api;version="[1.14.0,2.0.0)" + diff --git a/tests/org.eclipse.swt.svg.tests/build.properties b/tests/org.eclipse.swt.svg.tests/build.properties new file mode 100644 index 00000000000..46e29c2929a --- /dev/null +++ b/tests/org.eclipse.swt.svg.tests/build.properties @@ -0,0 +1,7 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . + +pom.model.packaging = eclipse-test-plugin +pom.model.property.testClass = org.eclipse.swt.svg.AllSVGTests diff --git a/tests/org.eclipse.swt.svg.tests/src/org/eclipse/swt/svg/AllSVGTests.java b/tests/org.eclipse.swt.svg.tests/src/org/eclipse/swt/svg/AllSVGTests.java new file mode 100644 index 00000000000..a8b9e4f241a --- /dev/null +++ b/tests/org.eclipse.swt.svg.tests/src/org/eclipse/swt/svg/AllSVGTests.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2026 Vector Informatik GmbH and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.swt.svg; + +import org.junit.platform.suite.api.SelectClasses; +import org.junit.platform.suite.api.Suite; + +@Suite +@SelectClasses({ // + JSVGRasterizerTest.class, // +}) +public class AllSVGTests { +} diff --git a/tests/org.eclipse.swt.svg.tests/src/org/eclipse/swt/svg/JSVGRasterizerTest.java b/tests/org.eclipse.swt.svg.tests/src/org/eclipse/swt/svg/JSVGRasterizerTest.java new file mode 100644 index 00000000000..e2c9b4aa04f --- /dev/null +++ b/tests/org.eclipse.swt.svg.tests/src/org/eclipse/swt/svg/JSVGRasterizerTest.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2025 Yatta Solutions and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Yatta Solutions - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.svg; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.ImageData; +<<<<<<<< HEAD:bundles/org.eclipse.swt.svg/test/org/eclipse/swt/svg/JSVGRasterizerTest.java +import org.eclipse.swt.graphics.RGB; +======== +>>>>>>>> cb670d6b1f (Make an independent bundle out of SWT SVG fragment):tests/org.eclipse.swt.svg.tests/src/org/eclipse/swt/svg/JSVGRasterizerTest.java +import org.junit.jupiter.api.Test; + +class JSVGRasterizerTest { + + private final JSVGRasterizer rasterizer = new JSVGRasterizer(); + private String svgString = """ + + + + """; + + private ByteArrayInputStream svgStream(String svg) { + return new ByteArrayInputStream(svg.getBytes(StandardCharsets.UTF_8)); + } + + private ByteArrayInputStream invalidSvg = new ByteArrayInputStream(new byte[0]); + + @Test + void testRasterizeWithZoom() { + ImageData data = rasterizer.rasterizeSVG(svgStream(svgString), 200); + assertEquals(200, data.width); + assertEquals(200, data.height); + } + + @Test + void testRasterizeWithZoomNegative() { + assertThrows(IllegalArgumentException.class, () -> rasterizer.rasterizeSVG(svgStream(svgString), -100)); + } + + @Test + void testRasterizeWithZoomWithInvalidSVG() { + + SWTException exception = assertThrows(SWTException.class, () -> { + rasterizer.rasterizeSVG(invalidSvg, 100); + }); + assertEquals(SWT.ERROR_INVALID_IMAGE, exception.code); + } + + @Test + void testRasterizeWithTargetSize() { + ImageData data = rasterizer.rasterizeSVG(svgStream(svgString), 300, 150); + assertEquals(300, data.width); + assertEquals(150, data.height); + } + + @Test + void testRasterizeWithTargetSizeHavingInvalidHeight() { + assertThrows(IllegalArgumentException.class, () -> { + rasterizer.rasterizeSVG(svgStream(svgString), -1, 150); + }); + } + + @Test + void testRasterizeWithTargetSizeHavingInvalidWidth() { + assertThrows(IllegalArgumentException.class, () -> { + rasterizer.rasterizeSVG(svgStream(svgString), 150, -1); + }); + } + + @Test + void testRasterizeWithTargetSizeWithInvalidSVG() { + SWTException exception = assertThrows(SWTException.class, () -> { + rasterizer.rasterizeSVG(invalidSvg, 150, 150); + }); + assertEquals(SWT.ERROR_INVALID_IMAGE, exception.code); + } + + @Test + void testDefaultCurrentColorIsBlack() { + ImageData data = rasterizer.rasterizeSVG(svgStream(svgString), 100); + RGB rgb = data.palette.getRGB(data.getPixel(0, 0)); + assertEquals(new RGB(0, 0, 0), rgb); + } +}