Embed font in PDF rendering plugin in Grails - pdf

I want to embed 'HelveticaNeueLTCom-BdCn.ttf' in a PDF document. I'm using Grails rendering 0.4.4 Plugin to generate PDF file.
I tried following,
#font-face {
font-family: 'Helvetica';
src: url('${grailsApplication.config.grails.serverURL}/fonts/HelveticaNeueLTCom-BdCn.ttf');
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
but it doesn't work.

The font embedding requires the below steps to be followed. This worked for me.
Try and tell me your feedback
The PdfRenderingService class present inside the plugin should be
edited for this font simulation as below.
protected doRender(Map args, Document document, OutputStream outputStream)
{
def renderer = new ITextRenderer()
// add the real font path from the server to be deployed to.
//I have it in the assets folder of my project
def path=servletContext.getRealPath("/")+"assets/HelveticaNeueLTCom-BdCn.ttf"
ITextFontResolver fontResolver=renderer.getFontResolver();
//add the encoding and embedded types to the font
fontResolver.addFont(path,BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
configureRenderer(renderer)
renderer.setDocument(document, args.base)
renderer.layout()
renderer.createPDF(outputStream)
outputStream.close();
}
Add the below code in your template file
#font-face {
font-family: "Helvetica";
src: url("${grailsApplication.config.grails.serverURL}/assets/HelveticaNeueLTCom-BdCn.ttf") format("truetype"),
url("${grailsApplication.config.grails.serverURL}/assets/HelveticaNeueLTCom-BdCn.woff") format("woff"),
url("${grailsApplication.config.grails.serverURL}/assets/HelveticaNeueLTCom-BdCn.svg#HelveticaNeueLTCom-BdCn") format("svg");
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}

#font-face { src:url(${grailsApplication.config.app.serverUrl}/arialuni.ttf) ; -fs-pdf-font-embed: embed; -fs-pdf-font-encoding: Identity-H; }
This worked for me.

Probably the problem is that you have your url value surrounded by ' instead of ".
The difference between them is that, though in Groovy string literals can be made with both, only the ones surrounded by " create GString, which evaluates statements between ${}

This worked for me
#font-face {
src: url("path/to/KF-Kiran.ttf");
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: cp1250;
}
div {
font-family: 'KF-Kiran'; // here give the same name of .ttf file.
}

Related

Export UTF-8 chars PDF with Bootstrap-Table

I'm trying to generate a PDF with Bootstrap-table, for this the documentation said to use tableExport.js which in turn uses jsPDF to generate the pdfs. The actual problem is that the data is in spanish containing chars such as á,é,í,ó,ú and ñ that are not shown correctly in the pdf. Reading jsPDF's documentation it mentions that the 14 standard fonts in PDF are limited to the ASCII-codepage.
Looking further into it jsPDF's documentation says it can be done. If you want to use UTF-8 you have to integrate a custom font, which provides the needed glyphs. jsPDF supports .ttf-files. So if you want to have for example Chinese text in your pdf, your font has to have the necessary Chinese glyphs. So, check if your font supports the wanted glyphs or else it will show garbled characters instead of the right text.
To add the font to jsPDF use our fontconverter in /fontconverter/fontconverter.html. The fontconverter will create a js-file with the content of the provided ttf-file as base64 encoded string and additional code for jsPDF. You just have to add this generated js-File to your project. You are then ready to go to use setFont-method in your code and write your UTF-8 encoded text.
Alternatively you can just load the content of the *.ttf file as a binary string using fetch or XMLHttpRequest and add the font to the PDF file:
But I have no idea how to integrate both codes. The PDF generates perfectly with my code exept for the fact that some chars dont look correct. As you can see in the section of my code I never instanciate jsPDF, I use Bootstrap-table options
Im Working on a .net project on Visual Studio
------------This is my code----------------------------------------------
$(function () {
function DoCellData(cell, row, col, data) { }
function DoBeforeAutotable(table, headers, rows, AutotableSettings) { }
$("#frm-Search").on("submit", function (event) {
event.preventDefault();
var $frm = $(this);
var formData = $frm.serializeObject();
if ($frm.valid()) {
/*loading(true);*/
GetSpanishData(formData).then(function (result) {
$("#tbReport").bootstrapTable({
search: true,
pagination: true,
export: true,
exportOptions: {
fileName: 'TheSpanishReport',
jspdf: {
format: 'bestfit',
margins: { left: 20, right: 20, top: 20, bottom: 20 },
autotable: {
styles: { overflow: 'linebreak' },
tableWidth: 'wrap',
tableExport: {
onBeforeAutotable: DoBeforeAutotable,
onCellData: DoCellData
}
}
},
},
exportTypes: ['csv', 'excel', 'pdf'],
data: result
});
$("#tbReport").bootstrapTable('refreshOptions', {
data: result
});
$("#tableReport").attr("hidden", false);
});
}
return false;
}).validate();
});
function GetSpanishData(data) {
return $.ajax({
url: ServerAdress/GetSpanishData',
type: 'POST',
dataType: 'json',
data: AntiForgeryToken(data)
});
}`
---------Code to integare font into PDF as described on jsPDF's Documentation----------
`const doc = new jsPDF();
const myFont = ... // load the *.ttf font file as binary string`
// add the font to jsPDF
doc.addFileToVFS("MyFont.ttf", myFont);
doc.addFont("MyFont.ttf", "MyFont", "normal");
doc.setFont("MyFont");
-----------------I've tryed converting a font to base64 as asked in the documentation and loading the js to the project then adding to the jsPDF section of the Bootstrap-Table parametes the option setFont, but it does not work---------------------------------------
jspdf: {
setFont:'MyFontName',
format: 'bestfit',
margins: { left: 20, right: 20, top: 20, bottom: 20 },
autotable: {
styles: { overflow: 'linebreak' },
tableWidth: 'wrap',
tableExport: {
onBeforeAutotable: DoBeforeAutotable,
onCellData: DoCellData
}
}
},
I had a similar problem today (exporting pdfs but with german umlaute ä ö ü from bootstrap-table), this worked for me:
you can use pdfmake instead of jspdf with tableExport.
include pdfmake instead of jspdf:
Many HTML stylings can be converted to PDF with jsPDF, but support for
non-western character sets is almost non-existent. Especially if you
want to export Arabic or Chinese characters to your PDF file, you can
use pdfmake as an alternative PDF producer. The disadvantage compared
to jspdf is that using pdfmake has a reduced styling capability. To
use pdfmake enable the pdfmake option and instead of the jsPDF files
include
<script type="text/javascript" src="libs/pdfmake/pdfmake.min.js"></script>
<script type="text/javascript" src="libs/pdfmake/vfs_fonts.js"></script>
<!-- To export arabic characters include mirza_fonts.js _instead_ of vfs_fonts.js
<script type="text/javascript" src="libs/pdfmake/mirza_fonts.js"></script>
-->
<!-- For a chinese font include either gbsn00lp_fonts.js or ZCOOLXiaoWei_fonts.js _instead_ of vfs_fonts.js
<script type="text/javascript" src="libs/pdfmake/gbsn00lp_fonts.js"></script>
-->
(from https://github.com/hhurz/tableExport.jquery.plugin#installation)
npm pdfmake
adapt your bootstrapTable exportOptions:
exportOptions: {
fileName: 'TheGermanReport',
pdfmake: {
enabled: true,
docDefinition: {
pageMargins: [ 20, 20, 20, 20 ]
}
}
},
pdfmake documentation

Access src from public in vue

I need to access to src/assets/fonts/... in public/paymentVerifyCallback.html.
I've written it in this way :
#font-face {
font-family: "IRANSansWeb";
src: url("../src/assets/fonts/ttf/IRANSansWeb.ttf") format("truetype");
}
but it doesn't work, returns " Failed to decode downloaded font: http://localhost:8080/src/assets/fonts/ttf/IRANSansWeb.ttf "
but I have this font file in this address.
what is the problem?

Trying to set Montserrat font on all pages of my React-Native App

I'm trying to apply the Montserrat font to all elements in my react-native app but can't seem to do it.
I've downloaded all 18 of the ttf files and put them into my assets/fonts folder.
I then tried using react-native-global-props:
import { setCustomText } from 'react-native-global-props';
const customTextProps = {
style: {
fontFamily: 'Montserrat'
}
}
setCustomText(customTextProps);
This didn't do anything to the text components of my app.
I then tried using defaultProps:
Text.defaultProps.style = { fontFamily: 'Montserrat' }
Also had no effect.
I also followed all the steps in this medium post about using custom fonts:
https://medium.com/react-native-training/react-native-custom-fonts-ccc9aacf9e5e
My main aim is to apply Montserrat font to every element of my entire app. I have a feeling it might have something to do with the font-type itself as Google Fonts say to apply fonts using this:
font-family: 'Montserrat', sans-serif;
However, react-native doesn't like the sans-serif as it has a hiphon so I just excluded it instead.
Any advice on this would be much appreciated.

Rendering PDF not working on prod environment

I have a very strange problem with rendering PDF working everywhere, but not on prod. Developer and test environments are working without problems, but prod just can't handle it. The only changes that are now on prod: higher Grails version than the last war (2.1.0->2.3.8 [but this change has been introduced to the test environment ~2 months ago and all the problems were resolved then]) with few upgraded plugins, especially
compile ":rendering:0.4.3"
changed to
compile ":rendering:1.0.0"
Stacktrace I get on prod:
java.lang.NullPointerException
at org.xhtmlrenderer.swing.NaiveUserAgent.getBinaryResource(NaiveUserAgent.java:228)
at org.xhtmlrenderer.pdf.ITextFontResolver.importFontFaces(ITextFontResolver.java:97)
at org.xhtmlrenderer.pdf.ITextRenderer.setDocument(ITextRenderer.java:178)
at org.xhtmlrenderer.pdf.ITextRenderer.setDocument(ITextRenderer.java:142)
at grails.plugin.rendering.pdf.PdfRenderingService.doRender(PdfRenderingService.groovy:36)
at grails.plugin.rendering.RenderingService.render(RenderingService.groovy:43)
at grails.plugin.rendering.RenderingService.render(RenderingService.groovy:37)
at grails.plugin.rendering.RenderingService.render(RenderingService.groovy:35)
at grails.plugin.rendering.RenderingService.render(RenderingService.groovy:65)
at GrailsMelodyGrailsPlugin$_closure4_closure16_closure17.doCall(GrailsMelodyGrailsPlugin.groovy:184)
at RenderingGrailsPlugin$_closure3.doCall(RenderingGrailsPlugin.groovy:59)
at com.my.app.ReportController$_closure8.doCall(ReportController.groovy:169)
at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:200)
at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:150)
at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:285)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:198)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:176)
My ReportController method for generating pdfs (nothing's really happening here and, yes, pdfShow file starts with an underscore):
def generatePdf = {
if (!params.id) {
throw new IllegalArgumentException("PDF Generation: an instance identifier has not been passed.")
}
def reportInstance = Report.findById(params.id)
renderPdf(template: "pdfShow", model: [reportInstance: reportInstance], filename: reportInstance?.reportFilename + '.pdf')
}
I have already done quite some research and found indications that it might be the problem with fonts declared in .css file which is used by the pdf template.
Well, this is the .css:
#font-face {
src: url("../fonts/DejaVuSansCondensed.ttf");
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
#font-face {
src: url(../fonts/DejaVuSansCondensed-Bold.ttf);
-fs-pdf-font-embed: embed;
-fs-pdf-font-encoding: Identity-H;
}
body {
font-family: "DejaVu Sans Condensed", Arial, sans-serif;
}
And the fonts are there, both on test and prod. And did not change their location.
I have tried downgrading rendering plugin back to 0.4.3, but it didn't work, complaining about not available classes:
plugins\rendering-0.4.3\grails-app\services\grails\plugin\rendering\document\XhtmlDocumentService.groovy: 20: unable to resolve class org.xhtmlrenderer.resource.XMLResource
(...)\plugin\rendering\pdf\PdfRenderingService.groovy: 25: unable to resolve class com.lowagie.text.pdf.BaseFont
(...)\plugin\rendering\pdf\PdfRenderingService.groovy: 19: unable to resolve class org.xhtmlrenderer.pdf.ITextRenderer
...and few others etc.
setting in the BuildConfig.groovy
legacyResolve true
inside grails.project.dependency.resolution { ... also did not work.
Do you have any idea what could be wrong?
The thing which solved the problem, was adding one line to the Config.groovy:
environments {
production {
(...)
grails.resources.processing.enabled = false
We had this line in the test and development environments, but before, with Grails 2.1.0 it worked anyway.

PhantomJS not rendering screenshots with webfonts?

So I have been looking around and can't seem to find a solution on how to get PhantomJS to actually display webfonts on screenshots, can anyone tell me if there is a way to do this?
I have been testing and testing for about a week now and finally came up with the answer, know that this might also be a result of me running PhantomJS on a Windows machine. I am currently running PhantomJS v1.9.7 and have found the following solution:
Using this in my CSS file:
#font-face {
font-family: 'Vampiro One';
src: url(http://themes.googleusercontent.com/static/fonts/vampiroone/v3/Ho2Xld8UbQyBA8XLxF1_NYbN6UDyHWBl620a-IRfuBk.woff) format('woff');
}
.vamp {
font-family: "Vampiro One";
font-size: 1.5em;
}
Instead of the Google recommended "failsafe":
#font-face {
font-family: 'Vampiro One';
font-style: normal;
font-weight: 400;
src: local('Vampiro One'), local('VampiroOne-Regular'), url(http://themes.googleusercontent.com/static/fonts/vampiroone/v3/Ho2Xld8UbQyBA8XLxF1_NYbN6UDyHWBl620a-IRfuBk.woff) format('woff');
}
.vamp {
font-family: 'Vampiro One', cursive;
font-size: 1.5em;
}
seems to do the trick. I hope this saves someone from being as frustrated as I have been.
To those who have a hard time spotting the difference, I removed the "local()" fonts to it only point to the one font I really want, as well as removing fallback fonts, I am thinking this has to do with some false positive in either PhantomJS or the WebKit engine.