B4J Question prism.lcdtext always false [Font Antialiasing]

jmon

Well-Known Member
Licensed User
Longtime User
Hello,

I have been trying (for years now) to improve the font anti-aliasing in Javafx. I have read several times that there are 3 ways to change the font anti-aliasing:

CSS (gray / lcd)
B4X:
.text{
    -fx-font-smoothing-type: gray;
}
Jar Arguments (true/false)
B4X:
-Dprism.lcdtext=false
Code properties (true/false)
B4X:
System.setProperty("prism.lcdtext", "false");

The problem is that regardless of what I do, it actually never changes anything when I run the program. I know that it's always false using this function:
B4X:
Sub getAllSystemProperties
    ' Declare the javaobject and init the class
    Dim JO As JavaObject
    JO.InitializeStatic("java.lang.System")
    ' Get the system properties into one object
    Dim objProperties As Object = JO.RunMethod("getProperties", Null)
    ' Convert the properties object into a list of strings
    Dim s As String = objProperties
    s.SubString(1)
    Dim l As List
    l = Regex.Split(", ", s)
    l.Sort(True)
    ' List the properties
    For i = 0 To l.Size - 1
        Log(l.Get(i))
    Next
End Sub
which returns this:
Prism pipeline init order: d3d sw
Using Double Precision Marlin Rasterizer
Using dirty region optimizations
Not using texture mask for primitives
Not forcing power of 2 sizes for textures
Using hardware CLAMP_TO_ZERO mode
Opting in for HiDPI pixel scaling
Prism pipeline name = com.sun.prism.d3d.D3DPipeline
Loading D3D native library ...
succeeded.
D3DPipelineManager: Created D3D9Ex device
Direct3D initialization succeeded
(X) Got class = class com.sun.prism.d3d.D3DPipeline
Initialized prism pipeline: com.sun.prism.d3d.D3DPipeline
Maximum supported texture size: 16384
Maximum texture size clamped to 4096
OS Information:
Windows 7 build 7601
D3D Driver Information:
NVIDIA GeForce GTX 1080
\\.\DISPLAY2
Driver nvd3dumx.dll, version 26.21.14.3086
Pixel Shader version 3.0
Device : ven_10DE, dev_1B80, subsys_859B1043
Max Multisamples supported: 4
vsync: true vpipe: true
Waiting for debugger to connect...
Program started.
awt.toolkit=sun.awt.windows.WToolkit
file.encoding=UTF-8
file.separator=\
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.awt.printerjob=sun.awt.windows.WPrinterJob
java.class.path=C:\Program Files (x86)\Anywhere Software\B4J\libraries\jDebug.jar;C:\Program Files (x86)\Anywhere Software\B4J\libraries\jcore.jar;C:\Program Files (x86)\Anywhere Software\B4J\libraries\jfx.jar;C:\Program Files (x86)\Anywhere Software\B4J\libraries\javaobject.jar;C:\Program Files (x86)\Anywhere Software\B4J\libraries\json.jar;;bin\classes\;bin/classes/;../;b4xlibs
java.class.version=55.0
java.home=C:\Program Files\Java\jdk-11.0.1\jdk-11.0.1
java.io.tmpdir=C:\Users\xxx\AppData\Local\Temp\
java.library.path=xxx
java.runtime.name=OpenJDK Runtime Environment
java.runtime.version=11.0.1+13
java.specification.name=Java Platform API Specification
java.specification.vendor=Oracle Corporation
java.vendor.url.bug=http://bugreport.java.com/bugreport/
java.vendor.url=http://java.oracle.com/
java.vendor.version=18.9
java.vendor=Oracle Corporation
java.version.date=2018-10-16
java.version=11.0.1
java.vm.compressedOopsMode=Zero based
java.vm.info=mixed mode
java.vm.name=OpenJDK 64-Bit Server VM
java.vm.specification.name=Java Virtual Machine Specification
java.vm.specification.vendor=Oracle Corporation
java.vm.specification.version=11
java.vm.vendor=Oracle Corporation
java.vm.version=11.0.1+13}
javafx.runtime.version=11.0.1+1
javafx.version=11.0.1
jdk.debug=release
jdk.module.path=C:\Program Files\Java\jdk-11.0.1\jdk-11.0.1\bin\..\javafx\lib
line.separator=
os.arch=amd64
os.name=Windows 7
os.version=6.1
path.separator=;
prism.lcdtext=false
prism.verbose=true
sun.arch.data.model=64
sun.boot.library.path=C:\Program Files\Java\jdk-11.0.1\jdk-11.0.1\bin
sun.cpu.endian=little
sun.cpu.isalist=amd64
sun.desktop=windows
sun.io.unicode.encoding=UnicodeLittle
sun.java.command=b4j.example.main
sun.java.launcher=SUN_STANDARD
sun.jnu.encoding=Cp1252
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
sun.os.patch.level=Service Pack 1
user.country=GB
user.dir=M:\B4j\Tests\TestAntialiasing\Objects
user.home=C:\Users\jo
user.language=en
user.name=xx
user.script=
user.timezone=
user.variant=
{java.specification.version=11
new alphas with length = 4096
QuantumRenderer: shutdown

Now, if I change the " -fx-font-smoothing-type" in CSS and preview my CSS in SceneBuilder, I can see it changing.
To illustrate the problem, please see this example:

Left is SceneBuilder, Right is the jar ran:
AntialisaingProblem1.jpg

We can see that sceneBuilder has the "LCD" antialiasing applied (Which spills some RGB colors), but my JAR is always "GRAY" antialiasing:
AntialisaingProblem2.jpg


Anyone has an idea why I can't change my jar to "LCD" ? I'm using Java 11.

Thanks for your help

(Edit: the screenshots are not very obvious, I think the jpeg compression actually did a smoothing on top)
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
I've tried several things, including this:
B4X:
Dim text As JavaObject
text.InitializeNewInstance("javafx.scene.text.Text", Null)
text.RunMethod("setFontSmoothingType", Array("LCD"))
text.RunMethod("setText", Array("Testing 123"))
MainForm.RootPane.AddNode(text, 10, 10, 100, 100)
Didn't change anything...
 
Upvote 0

jmon

Well-Known Member
Licensed User
Longtime User
To illustrate the result I'm trying to achieve, you can test in JavaFX scene builder.

1) create a text file, name it "style.txt"
2) Go to Javafx scene builder, create a label
3) Go to (Menu) "Preview/Scene Style Sheets/Add Style Sheet" >> Select "Style.txt"
4) Press CTRL+P , that should open the preview window
5) in "style.txt" type this and save the file:
B4X:
.text  {
    -fx-font-size: 48px;
    -fx-font-smoothing-type: gray;
}

Now, in the preview window, you should see the antialiasing changing.

Try changing between: "gray" / "lcd" modes (save the file each time), I think the difference is quite obvious.

It seems that the executed Jar is locked to "lcd" mode, and I'd like to change it to "lcd" :confused:
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I've checked the source code. The jFX library doesn't set the smoothing method. I guess that JavaFX engine decides based on unknown parameters to use the GRAY method.

BTW, the method is set to LCD as tested with:
B4X:
    Dim text As JavaObject
   text.InitializeNewInstance("javafx.scene.text.Text", Null)
   text.RunMethod("setFontSmoothingType", Array("LCD"))
   text.RunMethod("setText", Array("Testing 123"))
   text.RunMethod("setFont", Array(fx.CreateFont("", 40, False, False)))
   Log(text.RunMethod("getFontSmoothingType", Null))
   MainForm.RootPane.AddNode(text, 10, 10, 100, 100)
   MainForm.Show
 
Upvote 0

jmon

Well-Known Member
Licensed User
Longtime User
BTW, the method is set to LCD as tested with:
It seems that with TEXT nodes, it the antialiasing is nice and smooth.

Here they say, I just saw it:
Note: LCD mode doesn't apply in numerous cases, such as various compositing modes, where effects are applied and very large glyphs.

In my case, I think I get the problems on labels and buttons. I'll test with replacing the label with text. Here we can see the default behavior between Label/Text (see the "e" is quite aliased on the label):
capture9.PNG


Damn, I was hoping for years that they would fix that in Java 11! :(
 
Upvote 0

jmon

Well-Known Member
Licensed User
Longtime User
wow, I missed some update at some point! I didn't even know if was in B4J, maybe I found the culprit:
B4X:
#Region Project Attributes
    #MainFormWidth: 600
    #MainFormHeight: 600
    #LcdFontSmoothing: True
#End Region
So this #LcdFontSmoothing is overriding other "SetSystemProperty", CSS tricks and command line arguments.

It works if I set #LcdFontSmoothing to True. Now it seems that with big fonts, it's better to set #LcdFontSmoothing=false, but for my project, and small fonts, #LcdFontSmoothing=true works better in my opinion (See the words "button" and "Label").

In my opinion, they should do the opposite, True for small fonts, and false for big fonts.
LCDFontSmoothingOnOff.PNG


LCDFontSmoothingOnOff2.PNG
 
Upvote 0

jmon

Well-Known Member
Licensed User
Longtime User
I see the Tooltip for #LcdFontSmoothing is "Disabled by default as small fonts appear less smooth", but I think it's the opposite don't you? Small seem smoother, but big feel too sharp?

edit another example, font is at 13px:
LCDFontSmoothingOnOff3.png


edit: we can see some letters are almost lost when set to false (l, T, Y, F...)
LCDFontSmoothingOnOff4.PNG
 
Last edited:
Upvote 0
Top