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);
Related
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..
I am using iTextPdf 5.5.3 to create PDF/A documents, I want the user to select custom fonts by uploading the .ttf file of the font, and becuase FontFactory.getFont() method only takes the font name as a string I have to write the uploaded file to the user's drive (I KNOW, I ASKED MY CUSTOMER FOR PERMISSION TO WRITE TO THE DRIVE) and then pass the path of the uploaded file to the getFont() method, after everything is finished I want to delete the uploaded files from the drive. Here is my code:
File fontFile = new File("d:/temp/testFont.ttf");
try {
FileOutputStream outStream = new FileOutputStream(fontFile);
outStream.write(the bytes of the uploaded font file);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Font font = FontFactory.getFont(fontFile.getAbsolutePath(), BaseFont.CP1250 , BaseFont.EMBEDDED);
fontFile.delete();
This code is not working, somehow the getFont() method is locking the font file and therefore the file is not being deleted. I tried lots of ways to do this, like: fontFile.deleteOnExit(); or FileDeleteStrategy.FORCE.delete("file path"); but nothing is working for me. Please advise. Thanks
I am not going to answer the question mentioned in the title of your post (because it is a secondary). Instead I am going to answer the question in the body (which is the essential question).
You claim that FontFactory.getFont() requires a font file on the file system. That is not incorrect. However, that doesn't mean you can't create a font from a byte[].
You are trying to solve your problem by saving a ttf on disk (which is forbidden by your customer), but that isn't necessary. In a way, your customer is right: it's not a good idea to save the TTF as a temporary file on disk (which is why I'm ignoring your secondary question).
Take a look at the following createFont() method:
public static BaseFont createFont(String name,
String encoding,
boolean embedded,
boolean cached,
byte[] ttfAfm,
byte[] pfb)
throws DocumentException,
IOException
This is how you should interpret the parameters in your case:
name - the name of the font (not the location)
encoding - the encoding to be applied to this font
embedded - true if the font is to be embedded in the PDF
cached - probably false in your case, as you won't be reusing the font in the JVM
ttfAfm - the bytes of the .ttf file
pfb - in your case, this value will benull (it only makes sense in the context of Type1 fonts).
Now you can meet the requirements of your customer and you do not need to introduce a suboptimal workaround.
Note: you are using iText 5.5.3 which is available under the AGPL. Please be aware that your customer will need to purchase a commercial license with iText Software as soon as he starts using iText in a web service, in a product,...
It bothered me a whole day afternoon.
I encounter many problems and by now i cannot overcome them.
my code:
public void pdf2jpg(){
try {
File pdfFile =new File("c://tmp//1.pdf");
PDFDocument document = new PDFDocument();
document.load(pdfFile);
SimpleRenderer renderer = new SimpleRenderer();
renderer.setResolution(300);
List<Image> images = renderer.render(document);
for (int i = 0; i < images.size(); i++) {
Image img= images.get(i);
ImageIO.write((RenderedImage)img, "jpg", new File(i+".jpg"));
}
} catch (IOException | RendererException | DocumentException e) {
e.printStackTrace();
}
}
My box: Windows 7, jdk:1.7.0_45(64bit), GPL ghostscript 9.0.4.
when I use ghost4j 0.4.4, I got error "net.sf.ghost4j.renderer.RendererException: net.sf.ghost4j.GhostscriptException: Cannot initialize Ghostscript interpreter. Error code is -20"
on List<Image> images = renderer.render(document);
Some thread here mentions it's about ghost4j version. so i change to 0.4.6, error 20 disappears, but comes Warning: An error occurred while reading an XREF table. on the same sentence.
I cannot figure out how to get out of this 'mud',
Thanks very much for your help.
I'd guess that the returned bitmap is simply too large for memory, given that you get an out of memory error.
You should try using Ghostscript directly from the command line for 2 reasons, firstly you will be able to see if there is a real error message about the xref, which would indicate your PDF file is damaged, secondly you might reasonably just run a shell command to invoke GhostScript to render the PDF directly to JPEG rather than going through an in-memory bitmap. Its probably faster apart from anything else.
gswin32c -sDEVICE=jpeg -o out.jpg input.pdf
I have used this code below, and it comes up with this stack trace:
java.io.FileNotFoundException: font.ttf (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:146)
at java.io.FileInputStream.<init>(FileInputStream.java:101)
at com.ominious.core.graphics.Assets.getFont(Assets.java:55)
at com.ominious.core.graphics.Assets.loadImages(Assets.java:37)
at com.ominious.core.GamePanel.init(GamePanel.java:63)
at com.ominious.core.GamePanel.run(GamePanel.java:69)
at java.lang.Thread.run(Thread.java:744)
Exception in thread "Thread-1" java.lang.NullPointerException
at com.ominious.core.graphics.Assets.loadImages(Assets.java:49)
at com.ominious.core.GamePanel.init(GamePanel.java:63)
at com.ominious.core.GamePanel.run(GamePanel.java:69)
at java.lang.Thread.run(Thread.java:744)
I use this code (I call the method in a resource file that I know works)
private static Font getFont(String name) throws Exception {
Font font = Font.createFont(Font.TRUETYPE_FONT, new FileInputStream(name));
return font;
}
And I call it here:
try {
FONT = getFont("font.ttf");
tileSprites = ImageIO.read(getClass().getResourceAsStream("/mom.gif"));
SPLASH_BACKGROUND = ImageIO.read(getClass().getResourceAsStream("/swag.gif"));
} catch (Exception e) {
Game.logger.log(LogType.ERROR_STACKTRACE);
e.printStackTrace();
}
(The class above works, my image loads)
Is there a reason why this doesn't work? Is there a better method? (And yes, I do have it in my directory)
It isn't that difficult to load a font from resources the same way you are loading the images. I know this question was asked a year ago, but i hope to finally provide an answer.
Simply use the documentation here, which details how to load custom fonts into a GraphicsEnvironment. It should look something like the following:
GraphicsEnvironment ge = null;
try{
ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, game.getClass().getResourceAsStream("/fonts/fantasy.TTF")));
} catch(FontFormatException e){} catch (IOException e){}
Note: I use classInstance.getClass().getResourceAsStream(String fileDir) to load the file from my resources directory in the Jar file.
After registering the font with the graphics environment, the font is available in calls to getAvailableFontFamilyNames() and can be used in font constructors.
Hope this answers your question finally!
Most probably because you're running this out of a jar, and there's no File object to get. Compare how you're loading your images with getResourceAsStream, which can find resources that are either unpacked as files (usually for development) or packaged into a jar. Use the same getResourceAsStream call in createFont.
I have an application which has a font stored within a jar file. It is loaded with:
public Font getChessFont()
{
InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream("fonts\\MERIFONTNEW.TTF");
Font toReturn;
try
{
toReturn = Font.createFont(Font.TRUETYPE_FONT, in);
}
catch (Exception e)
{
toReturn = gameInformation;
}
toReturn = toReturn.deriveFont(Font.PLAIN, squareSize);
return toReturn;
}
When running the program from Eclipse or a jar file this code loads the font sucessfuly. However, after I put the jar files into an ISO image and mount them to a disk the files fail to load. Any ideas as to what I'm doing wrong?
Apparently my comment was enough to solve this. So the question can be "answered", I have added the comment as an answer:
Resource paths usually should use forward slash (/) in the path (more like a URL) as this is platform independent.
Are the files/JARs on the disk on the classpath?