Loading custom fonts at runtime for use with JTextPane - java

Thanks for your time. My question is regarding the display of different fonts within the one JTextPane. My client wishes to view a word in two different languages within the one field. They've explicitly specified that they wish the different languages (namely Amharic, Arabic, Coptic and Hebrew) to be shown with different fonts. These are obviously non-standard fonts and I can't rely on the user having the required fonts installed on their OS.
From my research I've found that I can load a font file at runtime and set the JTextPane's font accordingly, which is fine if I just wanted to use one font, not two. I've also read about adding fonts to the OS' font directory or the JRE's font directory, outlined here.
I was hoping however, that there might be away to use the fonts without altering the user's OS. Am I out of luck?
Thanks again for your time and I look forward to any replies with bright ideas!

From my research I've found that I can load a font file at runtime and set the JTextPane's font accordingly, which is fine if I just wanted to use one font, not two.
A JTextPane can use multiple fonts.
Check out the section from the Swing tutorial on Text Component Features for an example of playing with the attributes of the text in the text pane.
Edit:
However to use multiple fonts, the only way I have worked out to set the font is by creating a MutableAttributeSet and setting the "FontFamily" attribute (a string) to the desired font name, and then assigning the Attribute set to the text using the StyledDocument.setCharacterAttributes
Reading the API for the createFont() method it looks like you should be able to use:
GraphicsEnvironment.registerFont(Font)

Related

What is the default styling for html in components like JLabel

Swing has a nice feature where some components allow text to be specified using html. For example, the JLabel component can use html formatting simply using:
JLabel jl = new JLabel("<html><body><h1>Hello World</h1></body></html>");
I find this feature to be really convenient and I am using it in several places in my app.
I would like to know what the default styling is when I use this feature. I know that I can easily override these by adding my own style attributes, but I would like to know what the starting set is, because it is different than most browser defaults.
Where can I find out the default styling (font, line spacing, etc)? I have not seen anything in the documentation. I tried to browse through the source code, but I was unable to see where the tag gets parsed and the styling gets applied.
Can someone give me a pointer as to where to look for this information, possibly in the OpenJDK source?
The default style sheet is default.css, which can be found in resources.jar under the directory javax/swing/text/html/default.css.
You can also obtain the styles programmatically:
StyleSheet sheet = new HTMLEditorKit().getStyleSheet();
I believe the first answer is correct but incomplete.
Check out SwingUtilities2.displayPropertiesToCSS().
It adds a rule to the document stylesheet based on the component's font and foreground color. It is used by BasicHTML.BasicDocument.

PDF/iText : replace font defs

I'm using iText (Java lib) to process an already created PDF file.
What I would like to achieve is to replace fonts that are metric-compatible with a PDF base font with that PDF base font. This would make the PDF more "compliant" and potentially also smaller.
Here's how it would go:
Loop through the fonts used in the PDF.
If font is metric-compatible
with a PDF base font then replace font name with that font (but maintain the PDF resource name, e.g. /F13, so that we do not need to touch any text
objects). Since iText embeds in its jar the AFM files for the PDF
base fonts I'm assuming that iText actually has enough knowledge to
make this assesment. I would probably have to look at
serif/sans-serif and monotype flags as well to know if I should swap
in Helvetica, Times or Courier.
Further if metric-compatible: Remove
any font embeds for that font. (since we've replaced with a PDF base
font there's no need to embed anything .. size matters!)
An example:
An existing PDF file uses "Calibri", "Arial" and "Times". Here's how each of those should be handled.
Calibri. This font doesn't have a metric-compatible cousin among the PDF base fonts so processing for this font resource will be skipped.
Arial. This font has a metric-compatible cousin among the PDF base fonts, namely "Helvetica". The name of the font resource (attribute BaseFont I suppose) will be changed to "Helvetica" and any potential embeds will be removed.
Times. This font is already a PDF base font. Skip processing. (we may consider unembedding here if there's something to unembed, but I already know how to do that so not part of the question)
I basically get stuck on the step which is to determine metric-compatibility. Any help is greatly appreciated.
(Note: An answer based on iText 5.x is perfectly ok as I feel the recent iText 7 is still somewhat undocumented)
UPDATE
As pointed out a number of checks would need to be carried out in addition in order to do a safe replacement:
Font encoding compatibility. Not really a problem for me as fonts in the documents I'll be processing will be using WinAnsiEncoding.
Available chars in font. Not really a problem for me as I'll only be processing documents that use only ISO 8859-1 chars. Furthermore: If the PDF contains an embedded subset of a font then I'll have easily accessible knowledge about exactly which chars is used in the document for that font.
I'm sure I can figure out to check for both these conditions. (I'm blissfully naive)
I'm not trying to do a general tool. I know where the PDF's I'll be processing comes from. In any case I guess it is possible to have enough information from the PDF to skip the font substitution if it can't be determined that the substitution will be "safe".

getting square emoticons instead of actual emoticons

I am working a java chat application and I am adding emoticons by replacing the emoticon shortcut, like :) ,with ◕‿◕ . Its not an image that I am replacing it with but simple text. Now the problem that I am facing is that sometimes I get just Square boxes instead of the actual thing that I want. I am making these images/texts in MS Word by converting the unicode to the actual image. I am also using various online resources to get these images/text.
Can anyone tell me how to get rid of the boxes and get the actual text.
My encoding is in UTF-8 and my font is also set to monospaced.
Your unicode-character is probably not supported by your font. Either the font implements the character as a box, or the operating system / font-renderer draws a box instead of the glyph.
I would say the Font used in your application just cannot show some chars. Find one which font really can and use it there.
Font has boolean canDisplay(char c) method which you can use.
See also the doc about font

How to use Character.UnicodeBlock while I set some strings in a JEditorpane

I need to display some Bengali characters. I've tried to set the font to a Bengali Unicode font but It does not work properly. The last hope to fulfill my project is to use Character.UnicodeBlock. But I do not have any idea about it. Is it really possible to get the actual display of any Unicode character in Java? How can I use Character.UnicodeBlock in a component?
I assume Java 7.
First one needs a Unicode font.
If this font goes into the Windows fonts, and there is no name clash with an already existing font, everything should work.
Otherwise one might store the font as resource file in the application:
InputStream fontIn = getClass().getResourceAsStream("/.../... .ttf");
Font font = Font.createFont(Font.TRUETYPE_FONT, file);
GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(font);
After this jEditorPane.setFont(font) should work. Mind, the text in the JEditorPane should not be HTML, where own fonts might be set.
It is tricky, because of font substitution, on font decoding using names.
Another problem might be hard-coded strings in the java source: the encoding of the java source (the editor) must be the same as is used by the javac compiler. For international projects best both UTF-8 (javac -encoding=UTF-8 ...). To test whether there is a problem with that one can test with "\u099C" for জ.

Is it safe to use Unicode characters in Java GUI?

For a play button in a Java GUI I currently use a button with the label set to ' ▻ ' (found this symbol in a Unicode symbol table). As I understand, it is better to not use such symbols directly in source code but rather use the explicit unicode representation like \u25BB in this example, because some tools (editor, ...) might not be able to handle files with non-ASCII content (is that correct?).
Assuming the compiled class contains the correct character, under which circumstances would the GUI not show the intended symbol on a current PC operating system? Linux, Windows, Mac should all support UTF-16, right? Do available fonts or font settings cause problems to this approach?
(Of course I could add an icon, but why add extra resources if a symbol should already be available... given that this is a portable solution)
Do available fonts or font settings cause problems to this approach?
Unfortunately they do. You can use unicode in the source code of course, but the problem is that currently unicode has 246,943 code points assigned so obviously no font has even a fraction of those defined. You'll get squares or some other weird rendering when the glyph isn't available. I've had cases where relatively simple symbols such as ³ render fine on one Windows computer and show up as squares in the next, almost identical computer. All sort of language and locale settings and minor version changes affect this, so it's quite fragile.
AFAIK there are few, if any, characters guaranteed to be always available. Java's Font class has some methods such as canDisplay and canDisplayUpTo, which can be useful to check this at runtime.
Instead of using icons, you could bundle some good TrueType font that has the special characters you need, and then use that font everywhere in your app.
I currently use a button with the label set to ' ▻ '
rather than I always use JButton(String text, Icon icon), and Icon doesn't matter if is there this Font or another Font, UTF-16 or Unicode
Most of editors have support for unicode, so go on.
Look at this post: Eclipse French support
If you are using simple editor like notepad then when you save type name and below it choose UTF encoding ( http://www.sevenforums.com/software/72727-how-make-notepad-save-txt-files-unicode.html )

Categories