I am using iText7 trying to load a font which is in src/main/resources/pdf/fonts, when I give the full path to the font on my filesystem and run my code from a main method I don't have any problems, the issues occur when I am running the code inside a war file with tomcat.
I have tried a few different ways to load the font but none of them seem to work.
Either iText complains that the font is not recognised com.itextpdf.io.IOException: font.is.not.recognized (example one below) or I get a null pointer exception with example two (below) as the code is unable to load the font using the supplied path (although this works when giving the full file system path and running via a main method).
I can see that the font is definitely being included in the war file in the correct directory (/WEB-INF/classes/pdf/fonts). Below is what I am trying to do:
private static final String FONT = "/pdf/fonts/Frutiger-LT-Std-55-Roman_18821.ttf";
try (InputStream is = MyClass.class.getClassLoader().getResourceAsStream(FONT))
{
byte[] fontBytes = IOUtils.toByteArray(is);
final PdfFont font = PdfFontFactory.createFont(fontBytes, PdfEncodings.IDENTITY_H);
}
Or:
private static final String FONT = "/pdf/fonts/Frutiger-LT-Std-55-Roman_18821.ttf";
final PdfFont font = PdfFontFactory.createFont(FONT, PdfEncodings.IDENTITY_H);
I am not sure what it is that I need to do to load the font for iText to use when running in a web app.
I am thinking that maybe as the font does seem to have been read into the input stream that I need to somehow register the font with iText before passing it the byte array..
Related
I want to load a font in a SWT. My ttf file is in the resources/fonts directory of my Maven project. I try to load it like this:
URL fontURL = MyClass.class.getResource("/fonts/myfont.ttf");
boolean fontLoaded = display.loadFont(fontURL.getPath());
But the resulting boolean is always false. I tried to prompt the result of fontURL.getPath(), and it is something like /C:/Users/myuser/Documents/.... If I copy this result in a String, remove the first / and try to call display.loadFont() with it, it works.
Another weird thing is that this is not the only resource I load this way. For example, this is how I load the icon of the window:
URL iconURL = MyClass.class.getResource("/images/myicon.png");
Image icon = new Image(display, iconURL.getPath());
shell.setImage(icon);
And it works fine. The only file posing problem is the font file. Does anybody know why ?
The reason for / at the beginning is that getPath of the URL class returns the URL path defined by RFC 2396 (see javadocs).
As for why it's working for the Image constructor and not for loadFont() method, the answer can be found in the implementation.
The constructor uses FileInputStream which internally normalizes the path, whereas loadFont() has a native implementation for loading which does not support such path.
Since in both cases a file path is expected, what you want to do is normalize the path yourself using either File constructor or Paths.get(url.toURI()).toString() method.
I'm implementing a GUI for a chess program I'm writing for a class. To make it look polished, I want to utilize a Chess Piece Font I obtained from the internet.
The file, chess.ttf, is located at the path Chess/resources/chess.ttf. I utilize the following code per Oracle's instructions (https://docs.oracle.com/javase/tutorial/2d/text/fonts.html):
try {
File file = new File("resources/chess.ttf");
//Returned font is of pt size 1
Font font = Font.createFont(Font.TRUETYPE_FONT, file);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, file));
//Derive and return a 12 pt version:
//Need to use float otherwise
//it would be interpreted as style
return font.deriveFont(12f);
}
catch (IOException|FontFormatException e) {
System.out.println("-Font Error-");
return null;
}
However, this throws an IOException. I ran getAbsolutePath() on the file and received /Users/[me]/eclipse-workspace/Chess/resources/chess.ttf so I'm assuming the file is being loaded correctly. Does anyone know what's going wrong with my code?
edit: Problem resolved? I tried InputStreams as suggested but that didn't work, yet upon reverting my code the computer finally stopped throwing IOExceptions. Isn't code the best?
You'd better copy the ttf using build script like ant or maven /Users/[me]/eclipse-workspace/Chess/bin/resources
ClassLoader loader = Thread.currentThread().getContextClassLoader();
System.out.println(loader.getResource(".").getPath()); // for tracing the working folder only
java.io.InputStream ins = loader.getResourceAsStream("resources/chess.ttf");
//Returned font is of pt size 1
Font font = Font.createFont(Font.TRUETYPE_FONT, ins);
I am trying to load a specific font in my itext pdf. But I keep getting an error.
The logo.png and OpenSans-Bold.ttf are in the same folder. But if I try to run the code, the font file can not be found at location C:/somepatch/core/target/classes/OpenSans-Bold.ttf. But If i look at that folder, the file is there.
private static final String LOGO_LOCATION = PdfBuilder.class.getClassLoader().getResource("logo.png").toString();
private static final String FONT_FS_JOEY_BOLD = PdfBuilder.class.getClassLoader().getResource("OpenSans-Bold.ttf").toString();
I've also tried googeling the problem and some say I need to use getResourceAsStream. So I use:
private static final String FONT_FS_JOEY_BOLD = PdfBuilder.class.getClassLoader().getResourceAsStream("OpenSans-Bold.ttf").toString();
This gives me a java.lang.IllegalStateException: Invalid font type.
There is noting wrong with the fonts because
private static final String FONT_FS_JOEY_BOLD = "./src/main/resources/fonts/fs_joey-bold-webfont.ttf";
works. Unfotunately I can not use this method because I need to build the pdf in different packages. (and I really want to know wat is going wrong with the first two examples)
I'm using Apache FOP 1.0. The code is running on different servers, so I put the fonts in each server's instance root. My plan is to set the font base programmatically (to the server instance root, plus "/fonts/"), and in my fop configuration file, set font paths relative to this font base. Here's the code snippet that makes the FopFactory:
private static final String FONT_BASE = System.getProperty("com.sun.aas.instanceRoot") + "/fonts/";
public FOPWrapperBean() throws Exception {
ClassLoader loader = this.getClass().getClassLoader();
InputStream fopStream = loader.getResourceAsStream("META-INF/fop.xconf");
logger.log(Level.FINE, "InputStream: {0}", fopStream.toString());
DefaultConfigurationBuilder cfgBuilder = new DefaultConfigurationBuilder();
Configuration cfg = cfgBuilder.build(fopStream);
this.fopFactory = FopFactory.newInstance();
this.fopFactory.setUserConfig(cfg);
fopFactory.getFontManager().setFontBaseURL("file://" + FONT_BASE);
logger.log(Level.FINE, "Font base url: {0}", fopFactory.getFontManager().getFontBaseURL());
fopStream.close();
}
fop.xconf is almost entirely default. It contains
<base>.</base>
and
<fonts>
<directory>DejaVuTtf</directory>
</fonts>
(There are several fonts in {instance-root}/fonts/DejaVuTtf , which I can load correctly if I just give an absolute path -- but that doesn't work with having multiple servers, each of which may have different instance root directories).
How do I load in a font with a programmatically-determined path?
Thanks!
Your java code should work fine, since FONT_BASE is determined at runtime, dependent on the server - we are doing something very similar to this and it works fine. Perhaps your system property is not giving you the directory you think it is?
I decided to to use a "preprocessor" to do some variable replacement after loading the fopStream and before feeding it into the DefaultConfigurationBuilder
<fonts>
<directory>${com.sun.aas.instanceRoot}/fonts/DejaVuTtf</directory>
</fonts>
I ended up solving this problem in the obvious way that didn't occur to me: use the system fonts directory.
Is it possible to use a font not on the user's machine for text displayed in a java applet.
Like linking to a ttf font file in the same location as the java applet almost in an #fontface fashion.
You can use Font.createFont with fontFormat TRUETYPE_FONT:
Font f = Font.createFont( Font.TRUETYPE_FONT, new FileInputStream("font.ttf") );
As also described in Sun-Tutorial Working with Text APIs the returned font size is 1 pt, you can change this afterwards:
f = font.deriveFont(12f);