Changing font size in skin - java

I am writing a game using libgdx, and I borrowed the skin.json (and related files) from a tutorial.
The font being used (default) was scaling in an ugly manner on denser screens, so I generated by own very large font - and in the game itself, I scale it to a reasonable size (basically I use BitmapFont.scale). The font I'm now using is 3 times as large as the previous one.
I changed the reference to which font to use in the skin.json file, and as a result, all my buttons, titles and other things have a massive font being shown.
Is there a way of scaling the font in the .json file? Or anywhere else in the code? Skin doesn't have a setFont() functionality, so I can't create a scaled BitmapFont and assign it)

Libgdx changed this back in April 2015 so that the set answer doesn't work anymore. Took a little bit to find the answer, so I thought I'd leave it here for others since this answer pops up first in Google.
this.getSkin().getFont("default-font").getData().setScale(0.33f,0.33f);

Documentation says that any gets will return a handle to the actual object. So changes will persist.
So I changed the font in skin.json to point to my new font.
Then I used this code
this.getSkin().getFont("default-font").setScale(0.33f, 0.33f);
To scale the 'default-font' (as defined in the skin.json) to the scale I wanted (in my case its 0.33f)

As of 2017 i had to use
skin.getFont("default-font").getData().setScale(0.5f);
for future users.

Related

How do you all deal with the accessibility settings of font size and display size?

Whenever I test these accessibility settings with a larger display size or font size, it seems to almost always break parts of my layout and make it look awful. I really like the feature of autosizing text but these settings being changed seem to making autosizing text useless. Changing the display size also creates issues like weird holes in my table rows for reasons I can't figure out. Weighted views seem to break down in how they should work as well.
I have seen there are a couple of ways to work around these settings and making it so that the user's preferences of these settings do not affect your app. Do you all do this?
I understand the utility of the settings for the users. But, it seems kind of arbitrarily implemented because in order to make the layout work with these settings as a developer you might have to make your text size smaller from the beginning (in order to fit a larger font if user chooses to do this), which would lead to the exact same text size you, as a developer, would have chosen in the first place if you weren't trying to accommodate a larger font size being able to fit. I also believe I have heard that IOS doesn't allow for these accessibility settings to affect third party apps.
I am just curious how you all go about dealing with this. Thanks.
It is possible to ignore the user's preferred font sizing, by using dp instead of sp. Same for display size, if you really want to, you could check the current density and draw something according to that, still sizing things smaller. That's not a good approach. While your layouts will not break that way, the user who prefers a larger font/display sizes will still not be able to use your app, as they need a bigger text size.
There are some different techniques you can use to make layouts scale better:
Use minHeight/minWidth attributes in layouts, instead of hardcoding the sizes of the views.
Check that the constraints in constraint layouts are bound in both directions, not just start.
Allow text views to take up multiple lines, add ellipsis option where user can click through to see more information.
I wrote a blog post covering some of these in a bit more detail: Accessible Text Scaling for Android
Sometimes, however, fixing it for all scenarios will involve rethinking the design.
For iOS, the font settings also affect all third-party apps, it's not just an Android thing.
In general, you should always used scale-independent pixels, especially for a large body of text.
However if your text has to fit into a bounding-box of known size then you should use density independent pixels in order to ensure that the text always fits properly and that all characters are visible regardless of the users' setting.
Actually, Settings font size affects only sizes in sp. So all You need to do - define textSize in dp instead of sp, then settings won't change text size in Your app.
Here's a link to the documentation: Dimensions

Respecting Font Ligatures in Java/Swing

I've run into a problem that has me really scratching my head when dealing with Swing objects in java (and JFX as well, but I'll worry about that later...).
Here is the code that I am using to open fonts in my program. It's pretty standard.
public static Font getFontFromFile(String filePath) throws FontFormatException, IOException {
File fontFile = new File(filePath);
return Font.createFont(Font.TRUETYPE_FONT, fontFile);
}
My problem is that when I actually go to use these fonts, ligatures within them are not respected. One of the core features of my program allows users to load custom fonts, many of which have specialized ligatures. These are not being respected, and I'm not sure what I am doing wrong. If the user types two characters that should reduce to a single ligature, the second character just appears normally, with no transformation taking place. When I load the fonts into any other program or text editor I'm seeing the ligatures be respected exactly as I would anticipate.
I've stripped down code where I'm actually setting the font in a few places to the absolute bare bones and I'm seeing the (wrong) behavior even in places where I'm doing something as simple as:
jTextField.setFont(myFont);
Is there some setting on import that I am missing? Or that needs to be globally flipped on the 2D graphics object? Any assistance would be really appreciated. Thanks,
FOUND IT.
Ok. So. This one was frustrating, as I had been correctly setting the TextAttributes, while loading fonts via a method which is plagued by a long standing bug... Ligatures are supposed to be represented in JTextField and JTextArea objects, but under certain circumstances, they will not be. There are two things to keep in mind.
There is an old bug (https://bugs.openjdk.java.net/browse/JDK-8139741) which prevents ligatures from being respected when using the pattern
// BROKEN PATTERN
Font myFont = new Font(<FONT_FAMILY_NAME>, Font.PLAIN, 72);
Instead, the font ligatures will only be respected if it is loaded from a binary location:
// WORKING PATTERN
File myFontFile = new File(<FILE_LOCATION>);
Font fixed = Font.createFont(Font.TRUETYPE_FONT, myFontFile);
Once the font is loaded from binary, ligatures must be set via TextAttributes like so:
Map attributes = fixed.getAttributes();
attributes.put(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON);
fixed = fixed.deriveFont(attributes);
When loading fonts directly from the OS, I've taken to finding the actual font file on the system and loading it as a binary. It's cumbersome, but it functions.
At least with respect to Java2D, I read this - see Figure 4-13 as suggesting that Java will simply take the list of code points provided and render the glyph for each without combining to make ligatures.
Back before JavaFX 2, there used to be a boolean ligatures property on javafx.scene.text.Font that claimed to control whether ligatures were used, but that doesn't appear to be there anymore.
Historically (it's been at least 7 years) I've had to parse TT/OT fonts for ligatures and do the combining manually (and sometimes even pair kerning).

Difference between Label.setScale and Label.setFontScale?

Both methods are not documented both and does not seem to behave as I would expect.
mylabel.setFontScale(3f); makes the apparent text 3 times larger (what I'm looking for) but does not center properly when using it with Align.center.
mylabel.setScale(3f); does nothing as far as I could see.
What is the difference between those 2 methods and what one should I use to make my label bigger and properly centered ?
setFontScale() indeed enlarges the font, this is often unwanted since scaling up pixelizes the font.
label.setScale() does work if you are not using a layout actor like a table. When actors go inside a layout then the layout is responsible for setting the sizes and position. For example, you have control over this once you put it inside a table cell.
table.add(myLabel).width(300).height(80).padLeft(100).expandX();
Detailed documentation on working with a table.
This however just sizes the label, not the text inside. You can still do setFontScale(3f) but this will pixelate the font. You have 2 better options:
create a extra bitmap font in Hiero 3 times larger.
Use Gdx.Freetype to import a .ttf and generate fonts on run-time.

Toolkit.getDefaultToolkit().createImage() vs ImageIO.read()

I'm creating a UI using Swing and I want to display an image in a JLabel. The code I use is the following:
JLabel label = new JLabel(new ImageIcon(ImageIO.read(new File("img.jpg"))));
This works fine if I use png images but when it comes to jpg (only some of them), I get a redish image (a different one than the one I see in Paint.NET).
The image I used is this one: img.jpg
So I tried (as an alternative):
Toolkit.getDefaultToolkit().createImage(new File("img.jpg").getAbsolutePath());
Does anyone have an idea of why this happening? Is it a special JPEG format which is not supported?
I've read on this forum that most people recommend to use ImageIO (here for example). Why?
Thanks a lot
As discussed here, your JPEG image may contain spurious transparency information. One simple expedient is to render the image in a buffer having a compatible color model, as shown here.
It looks like you have found a bug in ImageIO.read... (I can reproduce the red tint, and it is definitely not how it should look like).
You can try to
save the JPEG files with other settings
open/re-save the file with other programs (hoping to get a more common JPEG-encoding)
or use the Toolkit method (if you don't control the images).
The only problem with the Toolkit method is that the getImage() method returns immediately after it is invoked and the loading is happening on a background thread, so you cannot start working with the Image object immediately.

How to use fonts in opengl in java?

The title pretty much sums it up - its the easiest thing in the
world in C++ and Windows, but Java seems to struggle with this issue.
I would like to stay away from solutions involving loading bitmaps of fonts, and instead try go for a native truetype font loader, if possible. Kerning and antialiasing is quite important in my application.
JOGL has a class, TextRenderer, which should do what you want. It accepts a Java "Font" object, and I think you can specify any ttf file for such objects. It does also support antialiasing, I'm not sure what kerning is but probably that too. :)
Unfortunately the JOGL docs are currently... missing. Dunno where they went, hopefully they'll be back soon (in a day or two). Otherwise I would link you to the documentation for the class. Sorry!
Use the JOGL/Java 2D bridge: render the font on a texture.
Check out "Java 2D and JOGL"[1]
[1]: http://weblogs.java.net/blog/campbell/archive/2007/01/java_2d_and_jog.html ""
Another thing you can do (e.g. if you want full lighting functionality for the text) is construct a GlyphVector from the font and string and use a GLUtessellator to render it as a set of triangles.
JOGL is pretty good. I've used Processing (processing.org) before that renders nice text. Yes, C++ and OpenGL under Windows does seem easy as the Font management is different (Linux and MacOSX = Much harder to do text with OpenGL I've found)

Categories