I'am trying to solve a font issue on heroku using PDFkit since few days and nothing seem to work for me....
I've already did few solutions such as :
Convert LucidaHW from Squirrel and do as follow ...
#font-face {
font-family: 'lucida_handwritingitalic';
src: url(data:application/x....
or this solution with .font on that website: http://www.mobalean.com/blog/2011/08/02/pdf-generation-and-heroku
or using :
kit.stylesheets << "#{Rails.root.join("public","stylesheets", "pdf", "pdf.css.scss")}"
I also moved my pdf.css.scss into vendor folder, into public folder and nothing ...
Right now, i am a bit confused because almost all of it work in dev mode (on my localhost) but nothing on heroku.
I'am aware this is not the first ticket about that issue but nobody found a solution that worked for me.
I ran into a similar issue a few months back.
This is what I'm doing right now and it has been working great for me:
1.Serve assets in base64:
add this helper method:
def asset_data_base64(path)
asset = Rails.application.assets.find_asset(path)
throw "Could not find asset '#{path}'" if asset.nil?
base64 = Base64.encode64(asset.to_s).gsub(/\s+/, "")
"data:#{asset.content_type};base64,#{Rack::Utils.escape(base64)}"
end
and in your template, include assets like this: (the example uses haml)
= stylesheet_link_tag(asset_data_base64('pdf/pdf.css'))
= javascript_include_tag(asset_data_base64('pdf/pdf.js'))
2.custom fonts
move all your fonts to a folder in your project. (I put mine under vendor/assets/fonts) then add a new initializer file in your config/initializers
if Rails.env.production?
font_dir = File.join(Dir.home, ".fonts")
Dir.mkdir(font_dir) unless Dir.exists?(font_dir)
Dir.glob(Rails.root.join("vendor","assets","fonts", "*")).each do |font|
target = File.join(font_dir, File.basename(font))
File.symlink(font, target) unless File.exists?(target)
end
end
replace Rails.root.join("vendor","assets","fonts", "*") withe the path to the folder where you put all your font files.
then in your css, do not use font-face, use the font name directly, e.g. font-family: Gotham;
Also, do not user fallback fonts! In some versions of wkhtmltopdf, it always uses the fallback font if one is provided.
=============================================
I learned the base64 trick from here: https://github.com/mileszs/wicked_pdf/issues/257
Custom fonts solution was found here: http://www.mobalean.com/blog/2011/08/02/pdf-generation-and-heroku
Try putting the font in a .fonts folder in you app root and push it to Heroku - just refer to the font via the font family and not with a src. That's how I use custom fonts on Heroku with wkhtmltopdf and it works for me.
Related
I have a webapp that uses #font-face to display TinyMCE icons. When running the app locally, these icons appear as intended in IE11. However, when deploying to a cloud server, the icons do not appear in IE11. I have edited my #font-face to take the .eot file out of the equation so that all browsers just grab the .woff. Also, on both local and remote versions of my app, the icons load and appear as intended on Chrome, Safari, and Firefox. I have noticed 2 key things:
On local app (which is over HTTP), IE11 GETs the icon file, tinymce.woff, without an issue. Before I changed this to get the .woff rather than the .eot, the .eot worked fine too. However, on the remote version of the app (which is over HTTPS), IE11 GETs the tinymce.eot, the tinymce.woff, and the tinymce.ttf (in that order) and all have a 200 Response Code. Why is IE11 downloading 3 different versions of the icon file? Is it possible there is some kind of conflict between these three files and that's causing the icons to not display? If so, how do I fix this? Keeping in mind that on the local version of the app, IE11 only GETs one of the icon files (tinymce.woff) which I believe is the behavior I want.
Research has led me to believe that the issue may be with the "Pragma" and "Cache-Control" headers that are being sent back as a response to the app's GET requests for the icon file. However, I am having trouble figuring out how to remove these headers for the HTTP Response. My application uses Spring MVC.
My current #font-face configuration:
#font-face{font-family:'tinymce';
src:url('fonts/tinymce.woff') format('woff'),
url('fonts/tinymce.ttf')format('truetype'),
url('fonts/tinymce.svg#tinymce') format('svg');
font-weight:normal;
font-style:normal}
It's hard to guess without being able to look at a demo. But since IE11 downloads an EOT, which isn't present in your #font-face rule, it looks like the CSS you think is being executed is not the CSS the browser uses.
If the #font-face rule is okay (but you copy/pasted the wrong one here), then perhaps the installable bit isn't set on the font. IE11 needs that, but on the other hand, you would expect an icon font to have taken care of this.
It's also possible the mime type isn't set correctly on the fonts served. See this thread for some troubleshooting options.
And, if you find the solution, please post it here so others can learn too! :-)
The solution was indeed getting rid of the "pragma" header. Since my project was a Spring Boot application, I created a header filter in my security configuration class. To create a Spring security configuration class:
1. Create a class that extends org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.
2. Give the class the following annotations:
-#Configuration (org.springframework.context.annotation.Configuration)
-#EnableWebSecurity (org.springframework.security.config.annotation.web.configuration.EnableWebSecurity)
-#EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) (org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity)
Within the class, create a method with #Bean annotation. Here is my complete definition:
public HeaderWriter cacheControlHeaderWriter()
{
return new DelegatingRequestMatcherHeaderWriter(
new NegatedRequestMatcher(new RegexRequestMatcher(".+\\.((eot(\\?)?)|(woff2?)|(ttf)|(svg))", "GET")),
new CacheControlHeadersWriter()
);
}
I am creating a local project so all the fonts I used should be just locally existed. I am using a Mac and I can find them in /Library/Fonts. But I guess it's not gonna work if I just put the filename to my CSS property. For example, there is a font named 华文黑体 and if I directly use:
font-family: "华文黑体"
it's not working.
How do I know all the names that can be used in a value of CSS property?
Thanks,
You can probably open the font('s properties) to find an english (Latin script) name that will be recognized by CSS.
I'm working with the following paradigm for handling my CDN caching:
Each path contains "?version", for example: http://mycdn.com/some-javascript-file.js?123
The same paradigm is used for all of my resources (js, css, images), the problem I'm encountering is images paths in a css file.
For example, I have the following snippet in one of my css's:
"url (../../Images/example.png)"
The problem is that this image path doesn't use the version paradigm, I would like to add the version to the path somehow, is there a nice way to do this, except of the following methods:
1) For each image change - also change the css with some dummy version.
"url (../../Images/example.png?1)" - change 1
"url (../../Images/example.png?55)" - change 2
2) Transfer all of my css's files to be aspx files and to use the code-behind in order to define the version:
"<%= html.VersionUrl("../../Images/example.png")%>"
3) Use dotless lib: http://www.dotlesscss.org/
Any other simple/nice idea?
The best solution which I've found was to change the version tag to be at the beginning of the url and to use url rewrite in order to process the requests.
So if for example I used to had:
http://website/Content/Images/1.png?123456
this will become to:
http://website/123456/Content/Images/1.png
Notice that I use url rewrite in order the process the request so that http://website/123456/Content/Images/1.png will actually bring the data from http://website/Content/Images/1.png
Is there a way to copy (from Firebug for example) the absolute instead of the relative URL of a web font specified within an #font-face rule?
Example:
I'm viewing the main.css file for a site in Firebug and I get this:
#font-face {
font-family: "myfont";
src: url("myfont__-webfont.eot");
}
How would I find the absolute path for this font?
I know that it should be next to the CSS file in this case, but I can't seem to find it.
Firebug's CSS panel currently doesn't offer an option to copy the URL of the webfont yet. So I created an issue, which was copied over to GitHub as issue #7320 asking for this feature.
Though there's another way to reach this:
Switch to the Net panel and enable it
Reload the page via Ctrl+F5 (or ⌘+F5 on Mac OS X, I guess; circumvents the fonts cache)
Click the Fonts filter
Right-click the request for the font and choose Copy Location
Step 1- Go myfont_-webfont.eot
Step 2- Go Font-Face Generator service
Step 3- myfont_-webfont.eot convert to web font.
I've changed my fonts in the server, but the browser get the old version of the css file where fonts are writed, how to reset the cache?, i've tried to delete browser cache and delete the old file css, but they still are getting the old cs, i've tried to reload the server, how to fix that?
I've noticed this happen only in Firefox, which is very annoying, however, if this is the same situation as you here, refresh with SHIFT + CMD + R (if you're on a mac, I presume the windows alternative is CTRL + SHIFT + R)
That'll clear your cache for that page too + SHOULD show your fonts :)
Make sure your browser isn't displaying local fonts — I spent almost one hour trying to figure out how to clear the font cache in Firefox, while the issue had nothing to do with that.
Check your webserver logs : are font files downloaded ? If not, then it's likely you're using local fonts.
Consider this real case scenario :
#font-face{
font-family: SuperFont;
src: url('../fonts/Superfont.ttf'),
}
I copypasted this code from somewhere, removing part of the src definition, not noticing the ending comma which made this line invalid CSS. Therefore the font was not downloaded.
However, since I had Superfont already installed locally, it seemed to work because the browser recognized the font-family. Well, until I decided to change the font file, but keeping the font-family definition to spare further modifications of the CSS file…
Morality : when testing fonts, use an unambiguous custom font-family name.
Have you tried viewing the page in a different browser to ensure the old font isn't still being added to the page?
If you're still using the same CSS file, you can navigate to the CSS file and do a hard refresh on that Ctrl+F5.
Also, I've found that closing the page completely before clearing your cache can help too!
Do a : Ctrl + F5 on your browser