Skip to content

Follow-Up Feature: Icon-Enablement with Rasterization of SVGs #1647

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,30 @@
import java.awt.RenderingHints.Key;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.internal.image.SVGRasterizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import com.github.weisj.jsvg.SVGDocument;
import com.github.weisj.jsvg.geometry.size.FloatSize;
import com.github.weisj.jsvg.parser.LoaderContext;
Expand Down Expand Up @@ -71,7 +86,19 @@ public class JSVGRasterizer implements SVGRasterizer {
);

@Override
public ImageData rasterizeSVG(InputStream inputStream, int zoom) throws IOException {
public ImageData rasterizeSVG(InputStream inputStream, int zoom, int flag) throws IOException {
switch(flag) {
case SWT.IMAGE_DISABLE:
inputStream = applyDisabledLook(inputStream);
break;
case SWT.IMAGE_GRAY:
inputStream = applyGrayLook(inputStream);
break;
case SWT.IMAGE_COPY:
break;
default:
SWT.error(SWT.ERROR_INVALID_IMAGE);
}
SVGDocument svgDocument = loadSVG(inputStream);
if (svgDocument == null) {
SWT.error(SWT.ERROR_INVALID_IMAGE);
Expand Down Expand Up @@ -133,4 +160,80 @@ private ImageData convertToSWTImageData(BufferedImage rasterizedImage) {
}
return imageData;
}

private static InputStream applyDisabledLook(InputStream svgInputStream) throws IOException {
Document svgDocument = parseSVG(svgInputStream);
addDisabledFilter(svgDocument);
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
writeSVG(svgDocument, outputStream);
return new ByteArrayInputStream(outputStream.toByteArray());
}
}

private static InputStream applyGrayLook(InputStream svgInputStream) throws IOException {
Document svgDocument = parseSVG(svgInputStream);
addGrayFilter(svgDocument);
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
writeSVG(svgDocument, outputStream);
return new ByteArrayInputStream(outputStream.toByteArray());
}
}

private static Document parseSVG(InputStream inputStream) throws IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
try {
builder = factory.newDocumentBuilder();
return builder.parse(inputStream);
} catch (SAXException | IOException | ParserConfigurationException e) {
throw new IOException(e.getMessage());
}
}

private static void addDisabledFilter(Document document) {
addFilter(document, 0.64f, 0.4f);
}

private static void addGrayFilter(Document document) {
addFilter(document, 0.64f, 0.1f);
}

private static void addFilter(Document document, float slope, float intercept) {
Element defs = (Element) document.getElementsByTagName("defs").item(0);
if (defs == null) {
defs = document.createElement("defs");
document.getDocumentElement().appendChild(defs);
}

Element filter = document.createElement("filter");
filter.setAttribute("id", "customizedLook");

Element colorMatrix = document.createElement("feColorMatrix");
colorMatrix.setAttribute("type", "saturate");
colorMatrix.setAttribute("values", "0");
filter.appendChild(colorMatrix);

Element componentTransfer = document.createElement("feComponentTransfer");
for (String channel : new String[] { "R", "G", "B" }) {
Element func = document.createElement("feFunc" + channel);
func.setAttribute("type", "linear");
func.setAttribute("slope", Float.toString(slope));
func.setAttribute("intercept", Float.toString(intercept));
componentTransfer.appendChild(func);
}
filter.appendChild(componentTransfer);
defs.appendChild(filter);
document.getDocumentElement().setAttribute("filter", "url(#customizedLook)");
}

private static void writeSVG(Document document, OutputStream outputStream) throws IOException {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer;
try {
transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult(outputStream));
} catch (TransformerException e) {
throw new IOException(e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ public static ImageData load(String filename) {
return data[0];
}

public static ElementAtZoom<ImageData> load(InputStream stream, int fileZoom, int targetZoom) {
List<ElementAtZoom<ImageData>> data = new ImageLoader().load(stream, fileZoom, targetZoom);
public static ElementAtZoom<ImageData> load(InputStream stream, int fileZoom, int targetZoom, int flag) {
List<ElementAtZoom<ImageData>> data = new ImageLoader().load(stream, fileZoom, targetZoom, flag);
if (data.isEmpty()) SWT.error(SWT.ERROR_INVALID_IMAGE);
return data.get(0);
}

public static ElementAtZoom<ImageData> load(String filename, int fileZoom, int targetZoom) {
List<ElementAtZoom<ImageData>> data = new ImageLoader().load(filename, fileZoom, targetZoom);
public static ElementAtZoom<ImageData> load(String filename, int fileZoom, int targetZoom, int flag) {
List<ElementAtZoom<ImageData>> data = new ImageLoader().load(filename, fileZoom, targetZoom, flag);
if (data.isEmpty()) SWT.error(SWT.ERROR_INVALID_IMAGE);
return data.get(0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,17 @@ public interface ImageDataProvider {
*/
ImageData getImageData (int zoom);

// /**
// * @since 4.0
// */
// default ImageData getCustomizedImageData(int zoom, int flag) {
// throw new UnsupportedOperationException();
// }
//
// /**
// * @since 4.0
// */
// default boolean supportsRasterizationFlag(int flag) {
// return false;
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,14 @@ void reset() {
* </ul>
*/
public ImageData[] load(InputStream stream) {
load(stream, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM);
load(stream, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM, SWT.IMAGE_COPY);
return data;
}

List<ElementAtZoom<ImageData>> load(InputStream stream, int fileZoom, int targetZoom) {
List<ElementAtZoom<ImageData>> load(InputStream stream, int fileZoom, int targetZoom, int flag) {
if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
reset();
List<ElementAtZoom<ImageData>> images = InternalImageLoader.load(stream, this, fileZoom, targetZoom);
List<ElementAtZoom<ImageData>> images = InternalImageLoader.load(stream, this, fileZoom, targetZoom, flag);
data = images.stream().map(ElementAtZoom::element).toArray(ImageData[]::new);
return images;
}
Expand All @@ -181,14 +181,14 @@ List<ElementAtZoom<ImageData>> load(InputStream stream, int fileZoom, int target
* </ul>
*/
public ImageData[] load(String filename) {
load(filename, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM);
load(filename, FileFormat.DEFAULT_ZOOM, FileFormat.DEFAULT_ZOOM, SWT.IMAGE_COPY);
return data;
}

List<ElementAtZoom<ImageData>> load(String filename, int fileZoom, int targetZoom) {
List<ElementAtZoom<ImageData>> load(String filename, int fileZoom, int targetZoom, int flag) {
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
try (InputStream stream = new FileInputStream(filename)) {
return load(stream, fileZoom, targetZoom);
return load(stream, fileZoom, targetZoom, flag);
} catch (IOException e) {
SWT.error(SWT.ERROR_IO, e);
}
Expand Down
Loading
Loading