How I use a custom font with the Batik SVG library? - java

I'm working on a Java program which creates templates for clothes. The user enters the word they want to see on the item of clothing and the system creates a PDF template. To create the template I create an SVG document programatically then use Batik to transcode the SVG to the PDF format.
My client now wants to be able to use custom fonts to create the templates. I was wondering if it's possible to use fonts like a TTF with the Batik transcoder? If so how do you go about setting up the SVG?

First you need to transform the font file from TTF to SVG with batik's ttf2svg, once you have the converted file you have to add reference in the 'defs' section of your SVG document.
this is how i did it:
Element defs = doc.createElementNS(svgNS, "defs");
Element fontface = doc.createElementNS(svgNS, "font-face");
fontface.setAttributeNS(null, "font-family", "DroidSansRegular");
Element fontfacesrc = doc.createElementNS(svgNS, "font-face-src");
Element fontfaceuri = doc.createElementNS(svgNS, "font-face-uri");
fontfaceuri.setAttributeNS(svgNS, "xlink:href", "fonts/DroidSans-webfont.svg#DroidSansRegular");
Element fontfaceformat = doc.createElementNS(svgNS, "font-face-format");
fontfaceformat.setAttributeNS(svgNS, "string", "svg");
fontfaceuri.appendChild(fontfaceformat);
fontfacesrc.appendChild(fontfaceuri);
fontface.appendChild(fontfacesrc);
defs.appendChild(fontface);
svgRoot.appendChild(defs);
when creating the text element set the font family just like any other font
Element txtElem = doc.createElementNS(svgNS, "text");
txtElem.setAttributeNS(svgNS, "style", "font-family:DroidSansRegular;font-size:" + fontsize + ";stroke:#000000;#fill:#00ff00;");
txtElem.setTextContent("some text");
svgRoot.appendChild(txtElem);
i got the info from this article: http://frabru.de/c.php/article/SVGFonts-usage hope it helps.

Just add the following element as a child of <svg/>: <style type="text/css"> Then, similar to HTML...

Related

Add HTML Markup using java Apache PDFBOX

I have been using PDFBOX and EasyTable which extends PDFBOX to draw datatables. I have hit a problem whereby I have a java object with a string of HTML data that I need to be added to the PDF using PDFBOX. A dig at the documentation seems not to bear any fruits.
The code below is a snippet hello world, which I want on the pdf been generated to have H1 formatting.
// Create a document and add a page to it
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage( page );
// Create a new font object selecting one of the PDF base fonts
PDFont font = PDType1Font.HELVETICA_BOLD;
// Start a new content stream which will "hold" the to be created content
PDPageContentStream contentStream = new PDPageContentStream(document, page);
// Define a text content stream using the selected font, moving the cursor and drawing the text "Hello World"
contentStream.beginText();
contentStream.setFont( font, 12 );
contentStream.moveTextPositionByAmount( 100, 700 );
contentStream.drawString( "<h1>HelloWorld</h1>" );
contentStream.endText();
// Make sure that the content stream is closed:
contentStream.close();
// Save the results and ensure that the document is properly closed:
document.save( "Hello World.pdf");
document.close();
}
Use jerico to format the html to free text while mapping correctly the output of tags.
sample
public String extractAllText(String htmlText){
return new net.htmlparser.jericho
.Source(htmlText)
.getRenderer()
.setMaxLineLength(Integer.MAX_VALUE)
.setNewLine(null)
.toString();
}
Include on your gradle or maven:
compile group: 'net.htmlparser.jericho', name: 'jericho-html', version: '3.4'
PDFBox does not know HTML, at least not for creating content.
Thus, with plain PDFBox you have to parse the HTML yourself and derive special text drawing characteristics from the tags text is in.
E.g. when you encounter "<h1>HelloWorld</h1>", you have to extract the text "HelloWorld" and use the information that it is in a h1 tag to select an appropriate prime header font and font size to draw that "HelloWorld".
Alternatively you can look for a library doing that HTML parsing and transforming to PDF text drawing instructions for PDFBox, e.g. Open HTML to PDF.

How to locate an <image> tag within a webpage using Selenium and Java

I want to locate the image tag in a webpage. The application contains a VIEW ICON. While inspecting the view icon, it is coded as image tag. I am not sure how to locate that particular tag.
Below is the image tag I want to locate:
<svg width="1em" height="1em" class="user-dropdown-icon" viewBox="0 0 14 8">
<image data-name="Vector Smart Object copy 3" width="14" height="8" xlink:href="data:img/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAICAYAAADJEc7MAAAAx0lEQVQYlY2Pv2oCAQyHP//s9waZfIF7j+PG3nbDFQfB7ufaxV3c3BxcFaRduzj5GL/Z5Tr0j1AoKZGeoGggEJLvI0mnqqoDsDCzCXeEpCkw7AJroJb0fEsLpnanl6bpKzAAxk3TfCdJsrsiueDiCnjsmtkPUAIbYCrp6YLkPT/RmdIdP5WQC2ALzCSNWpLXs5gVwdI/AWZ2lOTyCzCX9B6jOfAGPDhz4v82tuRPIAP8z2Wk15mZfbXZMzHkDyAH9pF59P4D+AX710oK5f6gzQAAAABJRU5ErkJggg=="></image>
</svg>
I tried with the below xpath:
xpath="(//*[#class='user-view-icon'])[11]")
But it did not work out
I want to locate the view icon
Try this:
Selenium - Java
/*get element by tag name*/
WebElement image = driver.findElement(By.tagName("image"));
If there are more than one image on the page , use
/*get all elements by tag name*/
List<WebElement> images = driver.findElements(By.tagName("image"));
from the list above determine which one do you want to use(tip : use a foreach loop to iterate)
<image>
The <image> SVG element includes images inside SVG documents. It can display raster image files or other SVG files.
The only image formats SVG software must support are JPEG, PNG and other SVG files. Animated GIF behavior is undefined.
SVG files displayed with <image> are treated as an image: external resources aren't loaded, :visited styles aren't applied, and they cannot be interactive. To include dynamic SVG elements, try <use> with an external URL. To include SVG files and run scripts inside them, try <object> inside of <foreignObject>.
Note: The HTML spec defines as a synonym for while parsing HTML. This specific element and its behavior only apply inside SVG documents or inline SVG.
This usecase
As the <image> element is a SVG element so to locate such elements you have to explicitly specify the SVG namespace when accessing the elements using xpath as follows:
For <svg> elements:
//*[name()="svg"]
For <g> elements:
//*[name()="svg"]/*[name()="g"]
For <image> elements:
//*[name()="svg"]/*[name()="image"]
References
You can find a couple of relevant detailed discussions in:
How to access to 'rect' type element through Selenium-Python
How to click on SVG elements using XPath and Selenium WebDriver through Java
Unable to locate SVG elements through xpath on Kendo UI chart
You image doesn't have the "user-view-icon" CSS class assigned and XPath doesn't work.
you could do:
WebElement image = driver.findElement(By.cssSelector("svg.user-dropdown-icon > image"));
Can you please execute the code below and let me know what you get. System.out.println(driver.findElements(By.tagName(“image”)).size());
if you still get null pointer exception , there is something wrong with your driver object . This code should return 0 if no image tag found on page , else the number of image tags on that page
Depending on the number of image tags , you can decide on the index of image tag you want to click , and then execute click on that element

Convert html to pdf automatically using ASPOSE in Java

I am trying to convert html to pdf using aspose,also i have to use PageSize A1,A2,A3,A4 .this is worked perfectly..but i dont want set pagesize for pdf generation.So far i have tried below code
HtmlLoadOptions htmloptions = new HtmlLoadOptions(basePath);
htmloptions.getPageInfo().setWidth(PageSize.getA2().getWidth());
htmloptions.getPageInfo().setHeight(PageSize.getA2().getHeight());
// Load HTML file
Document doc = new Document(basePath + "400010_DOC002_L_10_2508016.html", htmloptions);
// Save HTML file
doc.save("D:/Web+URL_output.pdf");
Can anyone suggest with out set page size i have convert html to pdf conversion ? or else please let me know what tools are available for this. Please let me know any other tools for this conversion.
#Shankar, you may use the below code sample in order to convert an HTML file to a PDF file without setting page size. By default, the page size of the rendered PDF file will be as of the A4 page size.
Simply omit the code which is setting a page size, else remains the same.
HtmlLoadOptions htmloptions = new HtmlLoadOptions(basePath);
// Load HTML file
Document doc = new Document(basePath + "400010_DOC002_L_10_2508016.html", htmloptions);
// Save HTML file
doc.save("D:/Web+URL_output.pdf");
Please let us know if you need any further assistance. I work with Aspose as Developer Evangelist.

JavaFx WebEngine - Overwriting a website's stylesheet with (local) files

I'd like to customise the appearance of a website that I am loading, so I created a little test.css file that does nothing but changing the look of all table rows:
tr {
height: 22px;
background-image: url("test.png");
}
How do I get he WebEngine to load this file and replace the page's own CSS rules with mine?
Also, i'd like to be able to load page-specific css files and not one huge file for all pages.
I found this page, but it only shows how to run through the DOM and assign a new style to the desired elements by hand. This is, of course, not what I want. Instead, I'd like the browser to use my files as 'user defaults'.
Thx for any help :)
First of I have to state, that I hope you know what you are doing, as these things can seriously damage a web site.
So here is what you can do:
You grab the Document from the WebEngine, retrieve the head element and add a style child element to it, containing the src location of the stylesheet you want to add.
Document doc = webView.getEngine().getDocument();
URL scriptUrl = getClass().getResource(pathToAttachedDocument); // pathToAttachedDocument = CSS file you want to attach
String content = IOUtils.toString(scriptUrl); // Use Apache IO commons for conveniance
Element appendContent = doc.createElement("style");
appendContent.appendChild(doc.createTextNode(content));
doc.getElementsByTagName("head").item(0).appendChild(appendContent);
By the way, JavaScript can be added in a similar way, it's just 'script' instead of 'style'
I would do like this to ADD or REPLACE any rules :
String css = getFileAsString("style.css");
Document doc = webEngine.getDocument();
Element e = doc.getElementById("my_style");
e.setTextContent(css);
... given a
<style id="my_style"></style>
tag in the HTML document.
setUserStyleSheetLocation()was designed for that very purpose: to let the user of the web page, style it as they want.
Usage:
webEngine.setUserStyleSheetLocation(styleSheetURL.toString());

How to set colour of text from a certain point forward

I'm building a small conversation agent, where the text looks like follows:
I would like to set the System's text to always be red. The text is all placed in a JTextPane.
How can I accomplish this? I have tried doing the following:
agentTextPane.setForeground(Color.red); after the system's text is added, and then switching back to black, however that changes all the text in the JTextPane.
This is how the system's text is added:
//'output' is a stringBuilder
output.append("\nSystem: ").append(tempOutput).append("\n");
agentTextPane.setText(output.toString());
As shown here, you can define an attribute set representing a desired style. For example,
StyledDocument doc = (StyledDocument) jtp.getDocument();
SimpleAttributeSet system = new SimpleAttributeSet();
StyleConstants.setFontFamily(system, "Serif");
StyleConstants.setForeground(system, Color.red);
doc.insertString(doc.getLength(), "...", system);
The styles can be progressive, as shown here.
See Text Component Features for more examples.
You may want to use HTML tags to format your Strings in terms of colour. The following reference may be useful. setting JTextPane to content type HTML and using string builders
output.append("<font color=\"red\">");
output.append("\nSystem: ").append(tempOutput).append("\n");
output.append("</font>");

Categories