Skip to content

Commit

Permalink
transcoder: support the KEY_USER_STYLESHEET_URI hint in `CSSTransco…
Browse files Browse the repository at this point in the history
…dingHelper`
  • Loading branch information
carlosame committed Sep 5, 2023
1 parent 906fbb2 commit bd4c06b
Show file tree
Hide file tree
Showing 9 changed files with 313 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
See the NOTICE file distributed with this work for additional
information regarding copyright ownership.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package io.sf.carte.echosvg.test.svg;

import java.net.URL;

import io.sf.carte.echosvg.transcoder.SVGAbstractTranscoder;
import io.sf.carte.echosvg.transcoder.image.ImageTranscoder;

/**
* Checks for regressions in rendering of SVG with alternate style sheets and/or
* a user style sheet.
*
* @author See Git history.
* @version $Id$
*/
class AltUserSheetRenderingTest extends RenderingTest {

static final String DEFAULT_USER_SHEET = "/io/sf/carte/echosvg/transcoder/UserAgentStyleSheet.css";

/**
* Alternate sheet name.
*/
private String altSheet = null;

/**
* Classpath to user sheet.
*/
private String userSheetClasspath = null;

public AltUserSheetRenderingTest() {
super();
}

/**
* Set the name of the alternate style sheet(s).
*
* @param altSheet the name of the alternate style sheet.
*/
public void setAlternateSheet(String altSheet) {
this.altSheet = altSheet;
}

/**
* Set the classpath for the user style sheet.
*
* @param userSheetClasspath the location of the user style sheet in classpath.
*/
public void setUserSheetClasspath(String userSheetClasspath) {
this.userSheetClasspath = userSheetClasspath;
}

/**
* Returns the <code>ImageTranscoder</code> the Test should use
*/
@Override
ImageTranscoder getTestImageTranscoder() {
ImageTranscoder t = super.getTestImageTranscoder();

if (userSheetClasspath != null) {
URL userSheet = AltUserSheetRenderingTest.class.getResource(userSheetClasspath);
t.addTranscodingHint(SVGAbstractTranscoder.KEY_USER_STYLESHEET_URI,
userSheet.toExternalForm());
}

if (altSheet != null) {
t.addTranscodingHint(SVGAbstractTranscoder.KEY_ALTERNATE_STYLESHEET, altSheet);
}

return t;
}

@Override
protected String getImageSuffix() {
StringBuilder buf = null;

if (altSheet != null) {
buf = new StringBuilder();
buf.append('_').append(altSheet);
}

String medium = getMedia();
if (medium != null && !DEFAULT_MEDIUM.equals(medium)) {
if (buf == null) {
buf = new StringBuilder();
}
buf.append('-').append(medium);
}

if (buf == null) {
return "";
}
return buf.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,16 @@ public void testAlternateStylesheet() throws TranscoderException, IOException {
test("samples/tests/spec/styling/alternateStylesheet.svg");
}

@Test
public void testAlternateStylesheet_Hot() throws TranscoderException, IOException {
testAlternateSheet("samples/tests/spec/styling/alternateStylesheet.svg", "Hot", true);
}

@Test
public void testAlternateStylesheet_Cold() throws TranscoderException, IOException {
testAlternateSheet("samples/tests/spec/styling/alternateStylesheet.svg", "Cold", true);
}

@Test
public void testCssMedia() throws TranscoderException, IOException {
test("samples/tests/spec/styling/cssMedia.svg");
Expand Down Expand Up @@ -946,6 +956,11 @@ public void testDefaultFontFamily() throws TranscoderException, IOException {
test("samples/tests/spec/styling/defaultFontFamily.svg");
}

@Test
public void testUserSheet() throws TranscoderException, IOException {
testUserSheet("samples/tests/spec/styling/userStylesheet.svg", true);
}

@Test
public void testHTMLEmbed() throws TranscoderException, IOException {
testHTML("samples/tests/spec/styling/css2.html");
Expand Down Expand Up @@ -1594,6 +1609,24 @@ private void testNVErrIgnore(String file, String media, int expectedErrorCount)
runner.runTest(0.000001f, 0.000001f);
}

private void testAlternateSheet(String file, String alt, boolean validating)
throws TranscoderException, IOException {
AltUserSheetRenderingTest runner = new AltUserSheetRenderingTest();
runner.setValidating(validating);
runner.setAlternateSheet(alt);
runner.setFile(file);
runner.runTest(0.00001f, 0.000001f);
}

private void testUserSheet(String file, boolean validating)
throws TranscoderException, IOException {
AltUserSheetRenderingTest runner = new AltUserSheetRenderingTest();
runner.setValidating(validating);
runner.setUserSheetClasspath(AltUserSheetRenderingTest.DEFAULT_USER_SHEET);
runner.setFile(file);
runner.runTest(0.00001f, 0.000001f);
}

/**
* Test the rendering of a SVG image inside an XHTML document.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

import io.sf.carte.echosvg.test.TestFonts;
import io.sf.carte.echosvg.transcoder.DummyErrorHandler;
import io.sf.carte.echosvg.transcoder.SVGAbstractTranscoder;
import io.sf.carte.echosvg.transcoder.TranscoderException;
import io.sf.carte.echosvg.transcoder.TranscoderInput;
import io.sf.carte.echosvg.transcoder.TranscoderOutput;
Expand Down Expand Up @@ -881,6 +882,11 @@ public void testStyleElement() throws TranscoderException, IOException {
test("samples/tests/spec/styling/styleElement.svg");
}

@Test
public void testUserSheet() throws TranscoderException, IOException {
testUserSheet("samples/tests/spec/styling/userStylesheet.svg", true, 0);
}

/*
* Text
*/
Expand Down Expand Up @@ -1452,6 +1458,45 @@ private void test(String file, String medium, String lang, int expectedErrorCoun
runner.runTest(0.00001f, 0.00001f);
}

/**
* Test rendering with a user style sheet.
*
* @param file the SVG file to test.
* @param alt the alternate style sheet name.
* @param validating validate if true.
* @param expectedErrorCount the expected error count.
* @throws TranscoderException
* @throws IOException
*/
private void testAlternate(String file, String alt, boolean validating, int expectedErrorCount)
throws TranscoderException, IOException {
BypassRenderingTest runner = new BypassRenderingTest(
SVGRenderingAccuracyTest.DEFAULT_MEDIUM, expectedErrorCount);
runner.setValidating(validating);
runner.setAlternateSheet(alt);
runner.setFile(file);
runner.runTest(0.00001f, 0.000001f);
}

/**
* Test rendering with a user style sheet.
*
* @param file the SVG file to test.
* @param validating validate if true.
* @param expectedErrorCount the expected error count.
* @throws TranscoderException
* @throws IOException
*/
private void testUserSheet(String file, boolean validating, int expectedErrorCount)
throws TranscoderException, IOException {
BypassRenderingTest runner = new BypassRenderingTest(
SVGRenderingAccuracyTest.DEFAULT_MEDIUM, expectedErrorCount);
runner.setValidating(validating);
runner.setUserSheetClasspath(AltUserSheetRenderingTest.DEFAULT_USER_SHEET);
runner.setFile(file);
runner.runTest(0.00001f, 0.000001f);
}

/**
* Test the rendering of a SVG file.
*
Expand Down Expand Up @@ -1542,6 +1587,16 @@ private class BypassRenderingTest extends RenderingTest {
*/
String selector = null;

/**
* Alternate sheet name.
*/
private String altSheet = null;

/**
* Classpath to user sheet.
*/
private String userSheetClasspath = null;

private transient Document renderDocument;

BypassRenderingTest(String medium, int expectedErrorCount) {
Expand Down Expand Up @@ -1571,6 +1626,24 @@ public void setRenderDocument(Document renderDocument) {
this.renderDocument = renderDocument;
}

/**
* Set the name of the alternate style sheet.
*
* @param altSheet the name of the alternate style sheet.
*/
public void setAlternateSheet(String altSheet) {
this.altSheet = altSheet;
}

/**
* Set the classpath for the user style sheet.
*
* @param userSheetClasspath the location of the user style sheet in classpath.
*/
public void setUserSheetClasspath(String userSheetClasspath) {
this.userSheetClasspath = userSheetClasspath;
}

@Override
protected void encode(URL srcURL, FileOutputStream fos)
throws TranscoderException, IOException {
Expand Down Expand Up @@ -1610,22 +1683,59 @@ void encode(CSSTranscodingHelper helper, TranscoderOutput dst)
renderDocument = dst.getDocument();
}

/**
* Returns the <code>ImageTranscoder</code> the Test should use
*/
@Override
ImageTranscoder getTestImageTranscoder() {
ImageTranscoder t = super.getTestImageTranscoder();

if (userSheetClasspath != null) {
URL userSheet = AltUserSheetRenderingTest.class.getResource(userSheetClasspath);
t.addTranscodingHint(SVGAbstractTranscoder.KEY_USER_STYLESHEET_URI,
userSheet.toExternalForm());
}

if (altSheet != null) {
t.addTranscodingHint(SVGAbstractTranscoder.KEY_ALTERNATE_STYLESHEET, altSheet);
}

return t;
}

@Override
ImageTranscoder createTestImageTranscoder() {
return new NoStackTraceTranscoder();
}

@Override
protected String getImageSuffix() {
StringBuilder buf = null;

if (altSheet != null) {
buf = new StringBuilder();
buf.append('_').append(altSheet);
}

String medium = getMedia();
if (medium != null && !DEFAULT_MEDIUM.equals(medium)) {
return '-' + medium + getDarkModeSuffix();
if (buf == null) {
buf = new StringBuilder();
}
buf.append('-').append(medium);
}
return getDarkModeSuffix();
}

private String getDarkModeSuffix() {
return darkMode ? "-dark" : "";
if (darkMode) {
if (buf == null) {
buf = new StringBuilder();
}
buf.append("-dark");
}

if (buf == null) {
return "";
}
return buf.toString();
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
Expand Down Expand Up @@ -56,6 +57,7 @@
import io.sf.carte.doc.style.css.CSSComputedProperties;
import io.sf.carte.doc.style.css.CSSDocument;
import io.sf.carte.doc.style.css.CSSMediaException;
import io.sf.carte.doc.style.css.CSSStyleSheetFactory;
import io.sf.carte.doc.style.css.CSSTypedValue;
import io.sf.carte.doc.style.css.CSSUnit;
import io.sf.carte.doc.style.css.CSSValue;
Expand All @@ -81,7 +83,9 @@
import io.sf.carte.echosvg.transcoder.TranscodingHints;
import io.sf.carte.echosvg.transcoder.image.ImageTranscoder;
import io.sf.carte.echosvg.transcoder.image.PNGTranscoder;
import io.sf.carte.echosvg.util.ParsedURL;
import io.sf.carte.echosvg.util.SVGConstants;
import io.sf.carte.util.agent.AgentUtil;

/**
* Utility for transcoding documents that use modern CSS, bypassing the EchoSVG
Expand Down Expand Up @@ -741,6 +745,10 @@ private void transcodeDOMDocument(DOMDocument document, TranscoderOutput output,
String alt = (String) transcoder.getTranscodingHints()
.get(SVGAbstractTranscoder.KEY_ALTERNATE_STYLESHEET);

// Check for user style sheet
String userSheetUri = (String) transcoder.getTranscodingHints()
.get(SVGAbstractTranscoder.KEY_USER_STYLESHEET_URI);

// Check for a target medium
String medium = (String) transcoder.getTranscodingHints()
.get(SVGAbstractTranscoder.KEY_MEDIA);
Expand All @@ -758,6 +766,18 @@ private void transcodeDOMDocument(DOMDocument document, TranscoderOutput output,
devFactory.setHints(svgRoot);
document.getImplementation().setDeviceFactory(devFactory);

// Set the user style sheet, if any
if (userSheetUri != null) {
ParsedURL purl = new ParsedURL(userSheetUri);
try (InputStream is = purl.openStream()) {
String conType = purl.getContentType();
String conEnc = purl.getContentEncoding();
Reader userRe = AgentUtil.inputStreamToReader(is, conType, conEnc,
StandardCharsets.UTF_8);
((CSSStyleSheetFactory) document.getImplementation()).setUserStyleSheet(userRe);
}
}

// If there is an alternate style sheet, set it
if (alt != null && (alt = alt.trim()).length() != 0) {
document.enableStyleSheetsForSet(alt);
Expand Down
Loading

0 comments on commit bd4c06b

Please sign in to comment.