#font-face custom font not rendering properly with xhtml2pdf for django - html

I'm trying to use a custom font in my attempts to render a pdf from HTML.
I've tried it out in HTML, the font shows up, so the path to the font must be correct, and it's probably being used correctly. The font is of type .ttf, and according to the docs on http://xhtml2pdf-base.googlecode.com/hg/doc/xhtml2pdf-en.html, it should render, but it doesn't.
Here's what I have in my style tags:
#font-face {
font-family: "Swiss";
src: url("/static/font/swiss.ttf");
}
body {
font-family: "Swiss";
font-size: 12px;
}
And the html:
<body>
asdf
</body>
I've tried many things, stripping the quotes off the font url and font family, my body is wrapped inside HTML tags so the html is properly formatted. Everything renders fine when rendering in a web page, but it's not being rendered properly when converting to PDF. Can anyone help me spot the error?

Best way is to use a callback to fetch fonts using filesystem path. Is more accurate and also you wan't be hitting webserver for each resource (resource meaning, fonts, images, etc)
pisa.CreatePDF(html.encode("UTF-8"), file_object , encoding='UTF-8',
link_callback=fetch_resources)
def fetch_resources(uri, rel):
find_file_in_path_using_uri
return path
By the way, I think your problem is you haven't done collect static so fonts are not really at /static/font/swiss.ttf. I mean they are not there outside django, and xhtml2pdf it's outside django. I'm not 100% sure.

I have had the same problem. gdrimes was right. After changing the url from relative:
#font-face {
font-family: FreeSans;
src: url("./FreeSans.ttf");
}
to absolute
#font-face {
font-family: FreeSans;
src: url("/home/rok/Documents/Muzey/muzey/website/templates/pdf/FreeSans.ttf");
}
the font in my PDF document was updated.

I am late to this thread but I recently had the same problem. The suggestion to use a callback to provide the font definition does work (but in my case case had some limitations because I needed some logic to use different fonts depending on external conditions). However, I found that the problem was that the url("/static/font/swiss.ttf") needs to be an absolute file location, not relative to your application location, as is shown. For example, in my case, my application location was '/home/user/app' the url needs to be:
url("/home/user/app/static/font/swiss.ttf").

Related

Font error: file not found with font-face

I want to use the fonts poppins and open-sans in doxygen, and am fairly new to CSS.
My font-face code for Open_Sans below.
#font-face {
font-family: 'Open_Sans';
src: url('fonts\Open_Sans\OpenSans-Regular.ttf') format('truetype');
}
My DIR structure has the fonts folder in the same folder as the css file.
DIR structure 1
Dir structure 2
I can click on my path and open the file in the VS Code editor, but when I open the webpage the console throws the error:
`net::ERR_FILE_NOT_FOUND'
From research I tried:
/fonts/
./fonts/
C:/complete-path/fonts/
with no success. I'm sorry if this question is redundant, but I can't seem to find a syntax error anywhere and am thinking it might have to do with doxygen.
EDIT
So I tried using an online open sans, and this threw no errors on the console, however it still did not work. You can verify to see the link works. I really think it has to do with doxygen at this point.
#font-face {
font-family: 'Open_Sans';
src: url('https://fonts.gstatic.com/s/opensans/v20/mem8YaGs126MiZpBA-UFWJ0bbck.woff2') format('woff2');
}
#font-face {
font-family: 'Open_Sans';
src: url('Open_Sans/OpenSans-Regular.ttf') format('truetype');
}
Remove "fonts/" from path.
Your CSS file inside the "fonts" folder, in your example the path becomes 'fonts/fonts/Open_Sans/OpenSans-Regular.ttf'
Ok, so I found the fix, but forgot to update.
Doxygen throws all files into the output directory when it is done, and will not put any files in there that you don't specify you need.
All you have to do is under the HTML_EXTRA_FILES tag in your doxyfile, specify the file(s) or directories you need, and it will place copies into the output dir.
In my case, it looks like this: HTML_EXTRA_FILES = fonts\Open_Sans\OpenSans-Regular.ttf
Just adding fonts\ would work as well. I am stil confused as to why the online url did not work, though.

How do you upload a font to your webpage (is the server needed)?

I am trying to upload a custom font to my site, but keep failing and I am not sure if I need to add routing in my server for it to work (I am using python flask).
The font is in static/fonts/Sofia_Handwritten.otf in my computer, before launching the server.
And the way I am trying to access it is:
#font-face {
font-family: "Sofia_Handwritten";
src: url("fonts/Sofia_Handwritten.otf");
}
#greeter {
font-size: 50px;
font-family: 'Sofia_Handwritten';
}
But no matter what the font doesn't display.
The server replies with 200, so it;s finding it just fine.
Edit:
The error was in the file itself.
The #font-face should be in your static/fonts/Sofia_Handwritten.css. After doing so, you go to your HTML and add something like this:
<link href="static/fonts/Sofia_Handwritten.css" rel="stylesheet">
and then you will be able to use your font.

Using Imported Fonts in a Google App

I am creating a web app using Google Apps Script. When I wanted to import a photo from Google Docs, I followed the advice from this question and it worked perfectly. I thought a similar process would work for using a custom font hosted on Docs, but it throws a CORS exception.
The relevant code:
#font-face {
font-family: MyCustomFont;
src: url("https://drive.google.com/uc?export=download&id=1r2a5nd6om75url39428dfju4");
}
#headBanner {
font-family: MyCustomFont;
}
<div id="headBanner">
<p>This text should be in MyCustomFont</p>
</div>
The error it throws is: "Access to Font at '[URL in font]' from origin '[Google Script page I'm using]' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '[Google Script page I'm using]' is therefore not allowed access."
How could I fix this? I just find it perplexing that it would throw a CORS exception for the font file but not for the picture.
Font files, along with AJAX requests using fetch are the only things that use CORS. Image requests and static inline requests for JavaScript (via tags) and CSS do not invoke CORS.
In this case, there is nothing you can do, short of (as #andrei-gheorghiu suggests) downloading the font file manually, saving it to your server and then accessing it from there. Whilst you can do that technically, it would technically be stealing. Hence his use of "Can, not may"...
Fun fact - CORS was basically invented for the specific use-case you've come across - so that 'font factories' could design fonts (which cost them money, obviously) and then be able to allow/deny access to those font files, depending on whether you have paid a license fee.
No doubt not the answer you wanted, but the answer nevertheless.

Why is font extension working only for PDF but not for other formats (HTML, XLS, DOC)?

Through Jaspersoft Studio we exported the built-in Windows Calibri font variants for use in a webapp into a font extension JAR, using the following settings:
The directory structure within the exported jrfontextensions.jar is as follows:
--jrfontextensions
--jasperreports_extension.properties
--fonts
--fontsfamily1505796949749.xml
--Custom_Font
--calibri.ttf
--calibrib.ttf
--calibrii.ttf
--calibriz.ttf
Contents of jasperreports_extension.properties:
net.sf.jasperreports.extension.registry.factory.fonts=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.ireportfamily1505796949749=fonts/fontsfamily1505796949749.xml
Contents of fontsfamily1505796949749.xml:
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
<fontFamily name="Custom-Font">
<normal><![CDATA[fonts/Custom_Font/calibri.ttf]]></normal>
<bold><![CDATA[fonts/Custom_Font/calibrib.ttf]]></bold>
<italic><![CDATA[fonts/Custom_Font/calibrii.ttf]]></italic>
<boldItalic><![CDATA[fonts/Custom_Font/calibriz.ttf]]></boldItalic>
<pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
<pdfEmbedded><![CDATA[true]]></pdfEmbedded>
<exportFonts>
<export key="html"><![CDATA[Custom-Font]]></export>
<export key="rtf"><![CDATA[Custom-Font]]></export>
<export key="xhtml"><![CDATA[Custom-Font]]></export>
</exportFonts>
</fontFamily>
</fontFamilies>
Now when we export this report as PDF, the Calibri font embedded into the PDF as the Custom-Font displays correctly, as expected.
But we ran into problems when trying to export the report to other formats like HTML, DOC, and XLS. It seems the web browser or office apps don't recognize the "Custom-Font" and falls back to one of their default fonts: the XLS report defaults to DejaVu Sans, while the HTML, and DOC reports default to Times New Roman. The outputs in PDF, XLS, DOC, and HTML respectively are as follows:
I feel like we must be missing something obvious here - perhaps we're lacking some obscure JRExporter configuration?
Some background
Fonts normally exists outside of the document (installed on pc) and not all document types will allow you to embed (include) font in the document itself. Related to your document types this is the possibility to embed fonts into the document.
PDF, yes you can embed the font
HTML, font can not be directly embedded but jasper-report will create
a css that contains #font-face with url, hence if broswer supports
it, font will be downloaded
Office (xls,xlsx,doc,docx,ppt), to embed font in apache-poi
(library used by jasper report) is probably
possibile
but AFIK (99% sure) jasper-reports have not developed code to try and
use this, since not directly supported by the library.
What should I do now
You are misunderstanding the font-mapping interface
Specify replacement fonts to use ... when not available
In this interface you should not put the name of your font, the font name, font-family you indicate will be used when your font is not available, you need to specify other standard default fonts that should be used if your font is not found.
Another good design rule (not well-documented) is to use as "Family name" (when you configure the font family) the exact name of font (if installed), hence if the computer has the font installed it will be found, since your name will map the name installed. In your case it looks like that you should replace "Custom-Font" with "Calibri"
Why is my html not working?, as indicated in comment by dada67 you should not use font-mapping for html if you like to use custom font (the mapping will redirect to mapped font), then search for the css, using code like
JasperReport report = JasperCompileManager.compileReport("jasper/FontExportTest.jrxml");
JasperPrint jasperPrint = JasperFillManager.fillReport(report, new HashMap<String, Object>(), new JREmptyDataSource());
HtmlExporter exporter = new HtmlExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleHtmlExporterOutput(new File("myHtml.html")));
SimpleHtmlExporterConfiguration configuration = new SimpleHtmlExporterConfiguration();
exporter.setConfiguration(configuration);
exporter.exportReport();
JasperReport will create both the file myHtml.html but also a folder with the name myHtml_htmlfiles, in this folder the css should be present, together with your .ttf font. If you deploy it on server naturally you need to deploy both.

What is the purpose of data URIs?

Why are resources sometimes embedded in data URIs, rather than using a regular URI that links to a resource stored as a file on a server?
1. Reducing server requests
Data URIs can be used to decrease server load and improve client performance, by reducing the number of HTTP requests required to acquire resources. For example, this HTML:
<img src="assets/bullet.png">
... can be replaced with this:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAA
ABFklEQVQY022RoW4CURBFD2ETymYFigRDEEgcFoNBIcAj0AQLH0AVfAEOQ0IgCP6C7L5ZWlpBG5
o2paJJ01JR/6aCbrI03GTcmZk7c+GfAkj54PqQDsDhkgSuDNQ3njff5vO7bS4XCgx9KJ2B5gReG9
D30UiPy6UeFwt96/X0Nps9+FCNw3UDakCfWy37WKvpU7Npv1cr+zEe600msw/AQyAlMJcTbKMmA3
pfLOrPeq0PlYoaaGDAFdgJaLwMaAD6OZnoodvV0HEGCKQFwj/IxmED+jWb2Zd2WyWZ7CPgGBhegj
eua187Hb0rFNRAOTqwJHAw51ZsZMXAVBIJJ/7nqsA+mhrbMBXIXQrGE2gYGAj0BcoSS/EXVfKm38
k6jyMAAAAASUVORK5CYII="
>
... to produce an image like this: with one fewer HTTP request.
Note: it appears to be impossible to embed data URI images in a Stack Overflow post; however, the image above was uploaded to an image hosting service using the data URI shown.
If, for example, your site uses many small icons, specifying them all as data URIs in a stylesheet:
.icon-bullet-red { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAABFklEQVQY022RoW4CURBFD2ETymYFigRDEEgcFoNBIcAj0AQLH0AVfAEOQ0IgCP6C7L5ZWlpBG5o2paJJ01JR/6aCbrI03GTcmZk7c+GfAkj54PqQDsDhkgSuDNQ3njff5vO7bS4XCgx9KJ2B5gReG9D30UiPy6UeFwt96/X0Nps9+FCNw3UDakCfWy37WKvpU7Npv1cr+zEe600msw/AQyAlMJcTbKMmA3pfLOrPeq0PlYoaaGDAFdgJaLwMaAD6OZnoodvV0HEGCKQFwj/IxmED+jWb2Zd2WyWZ7CPgGBhegjeua187Hb0rFNRAOTqwJHAw51ZsZMXAVBIJJ/7nqsA+mhrbMBXIXQrGE2gYGAj0BcoSS/EXVfKm38k6jyMAAAAASUVORK5CYII=) }
.icon-bullet-green { background-image: /* ... */ }
.icon-save { background-image: /* ... */ }
.icon-load { background-image: /* ... */ }
.icon-delete { background-image: /* ... */ }
/* ... etc. */
... can eliminate a large number of HTTP requests, at the cost of overall download size, legibility, and an increased likelihood that a bad edit might render the URI nonsensical (and difficult to fix).
An alternative method to achieve the same result for images is the use of CSS sprites.
2. Embedding content in a single file
A data URI can be used to contain all of the resources required to correctly display a page in a single document. This may be useful in e.g. a README file distributed alongside a piece of software. In theory, data URIs could also be used as an alternative to the use of attachments to embed resources in HTML email, but in practice client support for data URIs is too unreliable for this to be a useful technique.
3. Avoiding browser warnings
Some browsers display a warning if a page contains content served over a mixture of HTTP and HTTPS. If your server is set up so that static content like images is typically served over HTTP, but dynamic content is served over HTTPS, embedding that static content with a data URI is a possible workaround.
In addition to the previous answer (which is a very good summary), one thing I've been using this for lately is fonts. If I need to use just a small subset of characters from a font (say, a design-y font for a logo, or a special dingbat bullet icon), I can encode just the characters I need into a CSS #font-face declaration and not make the user download the entire font file.
For example, if I only want the devil (d) and angel (e) faces from Eggfaces ( http://www.dingbatdepot.com/details/EggfacesTFB ) , then I can use FontSquirrel's webfont generator tool ( http://www.fontsquirrel.com/tools/webfont-generator ) to create something like this:
#font-face {
font-family: 'eggfaces';
src: url(data:application/x-font-woff;charset=utf-8;base64,ENCODED_FONT_HERE) format('woff');
font-weight: normal;
font-style: normal;
}
See this fiddle for an example: http://jsfiddle.net/vuuVh/