B4J Question Faux bold and faux italic

xulihang

Active Member
Licensed User
Longtime User
Setting the bold and italic of a font is effective only if the font supports bold and italic. Most Chinese fonts do not have italic glyphs.

I wonder if we can make the text bold/italic even if the font does not support it. This is called faux bold/italic in Photoshop.

未标题-1.png
 

kimstudio

Active Member
Licensed User
Longtime User
Very interesting. Does Google "faux algorithm" give anything? My first thought would be image processing algorithms based on normal font image, like bold: dilation? italic: skew transformation?
To keep the quality of antialiasing, using big font size first then zoom out?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
It looks like PerspectiveTransform may be what you are after.

Try the attached, it's not perfect, but seems to be on the right lines. Not sure how it will work for all characters.

Have a play and see if you can improve it.
 

Attachments

  • FauxText.zip
    2.1 KB · Views: 122
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I think Bold should use image morphology processing method like dilation
This is way above my head. The transform just stretches the existing character. I haven't looked on Github to see if anything more advanced is available..
 
Upvote 0

Sandman

Expert
Licensed User
Longtime User
For bold I would simply try redrawing one or two copies a pixel shifted to the right. It's not great, but perhaps it's good enough?
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Just had a thought, for Bold it may be good enough just to add a second label over the first one with the same text. you can sync the two texts using an invalidation listener. You could easily create a custom view to manage it.

Shifting the text 1 px, still makes it a little blurred.

Try the attached. Click on the form to change the text.
 

Attachments

  • FauxText2.zip
    2.4 KB · Views: 116
Upvote 0

xulihang

Active Member
Licensed User
Longtime User
Thanks, guys. I am trying to make it work in TextFlow.

The problem I meet is that I cannot get the size of the text node.

In the screenshot, I just give it a size I guessed.

textflow.png
 

Attachments

  • TextFlow.zip
    1.8 KB · Views: 105
Upvote 0

xulihang

Active Member
Licensed User
Longtime User
I've updated the project to set the text item italic after the textflow is created and use snapshot to get the text's width and height. Let me know if there are better ways.
 

Attachments

  • TextFlow.zip
    1.9 KB · Views: 110
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Added a method to get the Text size without an image if it helps, and a test of bold using stroke and strokewidth. I'm not sure if it is legible on the Yahei font for small sizes.
 

Attachments

  • TextFlow_SL.zip
    1.9 KB · Views: 126
Upvote 0

xulihang

Active Member
Licensed User
Longtime User
Added a method to get the Text size without an image if it helps, and a test of bold using stroke and strokewidth. I'm not sure if it is legible on the Yahei font for small sizes.

Thanks. This works great!
 
Upvote 0

xulihang

Active Member
Licensed User
Longtime User
If I set the line spacing property for text flow, the faux italic does not work properly.

B4X:
tf.RunMethod("setLineSpacing",Array(5.0))

Before:

1680420778995.png


After:


1680420757491.png
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Try adjusting the height parameter in SetItalic to be Bounds.Height + LineSpacing

B4X:
Public Sub SetItalic(index As Int, hAdj As Double) As TextFlow
    Dim item As JavaObject = texts.Get(index)
    Dim n As Node = item
    Dim TR As JavaObject
    TR.InitializeNewInstance("javafx.scene.effect.PerspectiveTransform",Null)
    Dim width As Double = n.PrefWidth
    Dim height As Double = n.PrefHeight
    
    Dim img As Image = n.Snapshot
    Log(n.PrefWidth)
    Log(n.PrefHeight)
    Log(img.Width)
    Log(img.Height)
    
    Dim Bounds As B4XRect = GetLayoutBounds(item)
    Log(Bounds.Width)
    Log(Bounds.Height)
        
    width = Bounds.Width
    height = Bounds.Height + hAdj
    
    TR.Runmethod("setUlx",Array(2.0))
    TR.Runmethod("setUly",Array(0.0))
    TR.Runmethod("setUrx",Array(width + 2))
    TR.Runmethod("setUry",Array(0.0))
    TR.Runmethod("setLrx",Array(width))
    TR.Runmethod("setLry",Array(height))
    TR.Runmethod("setLlx",Array(0.0))
    TR.Runmethod("setLly",Array(height))
    item.RunMethod("setEffect", Array(TR))
    Return Me
End Sub

Pass the line spacing value to hAdj.
 
Upvote 0

xulihang

Active Member
Licensed User
Longtime User
I have a new problem.

If I set the text to bold as well as italic. It does not have a correct height.

1680703231810.png


It works okay when only faux bold or faux italic is set.

1680703268876.png

1680703286805.png
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Neither of the states can know if the other is set, I suggest you create a new sub to do both bold and italic at the same time and play with the parameters of the italic effect to compensate for the adjustments made for the bold setting. This is a fudge after all, you should be able to get it close though.
 
Upvote 0
Top