I've got a panel displaying a JTextPane backed by a StyledDocument. When I print a string of text in, say Arial 16, the text it prints is the same size as the Arial 16 Word prints. However, the Arial 16 in the JTextPane appears to be smaller than the Arial 16 Word displays. Is there some sort of flaw in the translation of Swing fonts to Windows system fonts or something of the sort that makes it difficult (or impossible) to print accurately?
I can achieve an approximation by scaling down the size of my font before printing, but this never quite gets me the results I would like, as it's not possible in all cases to reproduce things like equivalent numbers of words on a line, etc.
Has anybody run into this before?
Related
Java's String.format does not appear to be aware of double-width characters, such as Japanese or Chinese:
System.out.println(String.format("%1$9s: %2$20s : %3$20s\n", "field", "expected", "actual"));
System.out.println(String.format("%1$9s: %2$20s : %3$20s\n", "surface", "駆け", "駆け"));
The output is not aligned correctly:
field: expected : actual
surface: 駆け : 駆け
Is there a correct way to format double-width characters with String.format? If not, is there an alternative method or library which is capable of doing this correctly?
There is no issue with Java's String.format() since it can't "know" how you want to render the text, or the font that will be used. Its role is purely to assemble a formatted string of text to be subsequently displayed. The visual appearance of that formatted text is controlled (primarily) by the display font, and the developer must explicitly set the formatting accordingly.
A simple solution would be to use a font that renders both Latin and CJK characters with glyphs of constant width, but I couldn't find one. See a Unicode Technical Report titled "East Asian Width" for more details:
For a traditional East Asian fixed pitch font, this width translates
to a display width of either one half or a whole unit width. A common
name for this unit width is “Em”. While an Em is customarily the
height of the letter “M”, it is the same as the unit width in East
Asian fonts, because in these fonts the standard character cell is
square. In contrast, the character width for a fixed-pitch Latin font
like Courier is generally 3/5 of an Em.
I'm guessing that there might not be any monospace font displaying CJK characters and Latin characters with the same width simply because it would look very strange. For example, imagine the two Latin characters "li" occupying the same width as the two Japanese characters "駆け". So even if you use a monospaced font to render both Latin and CJK characters, although the characters for each language are monospaced, the widths for each language are probably still different.
Google has a very helpful site for evaluating their fonts, which allows you to:
Filter the fonts by language: Japanese, Chinese, etc.
View a large number of characters being rendered. For example this page for Noto Sans JP shows:
The Japanese glyphs are wider than the Latin glyphs.
The Japanese glyphs are fixed width, whereas the Latin glyphs are not.
Enter any text you wish, and apply it to all selected fonts for comparison. For example, this screen shot shows how the Latin glyphs for AEIOUY look alongside some Japanese glyphs using different fonts. Note that the width of the Latin glyphs is always smaller, though by varying amounts, depending on the font being used and the specific glyph to be rendered:
Here's a possible solution to your alignment problem:
With the Kosugi Maru font (middle of top row in the screen shot above), Japanese characters seem to be exactly twice as wide as Latin characters, so use that font to render the output.
When rendering the formatted text, the leading spaces must be reduced by one for each Japanese character to be displayed to ensure column alignment (since Japanese glyphs are twice as wide).
So in the code reduce the number of leading spaces by the number of Japanese glyphs to be rendered:
System.out.println("* The display font is named MotoyaLMaru, created by installing Google font KosugiMaru-Regular.ttf.");
System.out.println("* With this font Japanese glyphs seem to be twice the width of Latin glyphs.");
System.out.println("* Downloaded from https://fonts.google.com/specimen/Kosugi+Maru?selection.family=Kosugi+Maru");
System.out.println(" ");
System.out.println(String.format("%1$9s: %2$20s : %3$20s\n", "field", "expected", "actual"));
System.out.println(String.format("%1$9s: %2$18s : %3$18s\n", "surface", "駆け", "駆け")); // 18, not 20!
System.out.println(String.format("%1$9s: %2$12s : %3$12s\n", "1234567", "川土空田天生花草", "川土空田天生花草")); // 12, not 20!
This is the output from running that code in NetBeans on Windows 10, showing the columns properly aligned:
Notes:
The format strings were hard-coded in this example to ensure column alignment, but it would be simple to dynamically build the format string based on the number of Japanese characters to be rendered.
Also see Monospace font that supports both English and Japanese.
our Java project has a problem and I need your advice:
We have a JTextPane component which is customized to support pagination. The component's content must be printed using JasperReport. The problem is: although we have used the same font's name, size, style, and page's height and width for the JTextPane and JasperReport, but the print-page is always different from the contents in the screen, typically a few characters are not aligned properly between the 2 devices (print-page and screen-page); as a result the content may be displayed in only 1 screen-page but will be printed into 2 pages.
EDIT:
There is a JTextarea (First text) with the same Font as the Jasper print (Second text) (DejaVu Serif 10), but the length of the texts are different.
The question is: I need the same text length on the screen and on the Jasper Print, but i dont know how to do that. For example I have a JTextarea with a fix width of pixel maybe 700. The jasper textfield has also a width of 700 pixel. Now I expect the text on the screen and on jasper ist exactly the same if I configure the same font, but there are different. What can I do to solve this problem?
I have hexdump view in my application:
I use Courier New font in java:
private final Text contentText;
contentText.setFont(Font.font("Courier New"));
But as you can see some unicode signs have more width.
There is some way or another font which make all signs with equal width?
You're seeing the results of font fallback, which substitutes something other than the original font you specified when you try to render characters that aren't in that font. In this case, the kana and several other characters (Won sign, others) are not present in Courier New, so you get some other font whose metrics do not match those of Courier New.
There's no simple solution to this, particularly if you expect to be displaying a wide range of characters. What you could possibly do is set up a filter, as many hex editors do, and just show a '.' or similar for anything non-ASCII (or in this case you might be able to do a little detective work and set it up to show '.' for anything that is not present in Courier New font).
I have JTextPane and if i write something into it with e.g. font size 12 then it looks smaller than text in e.g. MS Word with same size and same font family.
I've searched on the internet and I found that this is not just my specific problem. But I can't find any solution.
Set the bigger font size is not a solution for me.
Is it possible to change measure or something like that?
Actually there is DPI difference of java (72pixels per inch) and windows (96 pixels per inch). To reflect your fonts properly you can multiply them on the 96/72 on Windows.
You can override
public Font getFont(AttributeSet attr)
method of DefaultStyledDocument where retrieve font size from the attribute set and increase it with the proportion.
Actually, there is a trick for that. Through the Document of the JTextPane, you're able to specify the font-size of each character with setCharacterAttributes. Now imagine that you have some text with font-size 12 and then a text with font-size 14 inside your JTextPane. What happens if you edit the global font-size of the JTextPane using
myTextPane.setFont(myTextPane.getFont().deriveFont(newFontSize));
The answer is that your text will still be considered sized 12 and 14, but will be displayed bigger !
WARNING : I didn't try with a StyledDocument. Only with an HTMLDocument.
Good Day! I am currently working on a program that prints a string in the printer. I am having problems regarding the display of the string to be printed. Ideally I want the font width of every character to be uniform. The problem occurs when when other language characters are set to be displayed. I've noticed that japanese characters are larger in width than the normal characters. Can I set these japanese characters to follow the font width of the normal characters?
Example:
NNNNN
NPD事本
Notice that the string with japanese encoding is larger in width. How can I make this string to follow the font width of my designated font? Is there a way? or is my case hopeless? Thanks in advance.
There are such things as monospace fonts, where each character takes the same width. I do not know if Japanese has such a font, or if there are English fonts and Japanese fonts that are both monospace and have the same width in pixels.
https://stackoverflow.com/questions/586503/complete-monospaced-unicode-font
The above question was closed as "off-topic" but it has some good links. The general consensus seemed to be you are either hosed, or in for a nightmare of working with different fonts in the same document.