Android Question BCTextEngine with Monospace letters. They don't have the same width!

vecino

Well-Known Member
Licensed User
Longtime User
Hi, I am trying to use a BCTextEngine to store text that I will then save as an image and finally print on bluetooth ticket printer.
I need the width to be always 48 columns.
For this I am using the type "Monospace", however I have a surprise, and that is that not all characters are monospace.
Considering that the maximum width is 48 columns, how can I get all the rows to have the same width?
I am attaching some screenshots so that you can understand the problem:

aa1.png


B4X:
Private Sub Button1_Click   
    TextEngine.Initialize(Activity)
    BBC.TextEngine = TextEngine
    BBC.Text = _
$"
123456789*123456789*123456789*123456789*12345678
Hola, mundo ÑÑÑñññññññññññññññññññññññññññññññññ
ÁÉÍÓÚ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€
111111111111111111111111111111111111111111111111
222222222222222222222222222222222222222222222222
333333333333333333333333333333333333333333333333
444444444444444444444444444444444444444444444444
555555555555555555555555555555555555555555555555
666666666666666666666666666666666666666666666666
777777777777777777777777777777777777777777777777
888888888888888888888888888888888888888888888888
999999999999999999999999999999999999999999999999
000000000000000000000000000000000000000000000000
123456789*123456789*123456789*123456789*12345678
________________________________________________
------------------------------------------------
123456789*123456789*123456789*123456789*12345678
================================================
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
çÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñ
================================================
123456789*123456789*123456789*123456789*12345678
"$
    
End Sub

The result is not correct, all the rows should have the same width, because they have 48 characters each:

aa2.jpg
 

TILogistic

Expert
Licensed User
Longtime User
Hi, I am trying to use a BCTextEngine to store text that I will then save as an image and finally print on bluetooth ticket printer.
I need the width to be always 48 columns.
For this I am using the type "Monospace", however I have a surprise, and that is that not all characters are monospace.
Considering that the maximum width is 48 columns, how can I get all the rows to have the same width?
I am attaching some screenshots so that you can understand the problem:

View attachment 143898

B4X:
Private Sub Button1_Click
    TextEngine.Initialize(Activity)
    BBC.TextEngine = TextEngine
    BBC.Text = _
$"
123456789*123456789*123456789*123456789*12345678
Hola, mundo ÑÑÑñññññññññññññññññññññññññññññññññ
ÁÉÍÓÚ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€
111111111111111111111111111111111111111111111111
222222222222222222222222222222222222222222222222
333333333333333333333333333333333333333333333333
444444444444444444444444444444444444444444444444
555555555555555555555555555555555555555555555555
666666666666666666666666666666666666666666666666
777777777777777777777777777777777777777777777777
888888888888888888888888888888888888888888888888
999999999999999999999999999999999999999999999999
000000000000000000000000000000000000000000000000
123456789*123456789*123456789*123456789*12345678
________________________________________________
------------------------------------------------
123456789*123456789*123456789*123456789*12345678
================================================
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
çÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñ
================================================
123456789*123456789*123456789*123456789*12345678
"$
 
End Sub

The result is not correct, all the rows should have the same width, because they have 48 characters each:

View attachment 143899
My Friend ;)
Use custom font Courier
ref:
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
A casual glance at your image, shows that * is narrower and - is narrowest, everything else seems alright.
Do you need them or could you replace these with other characters?

The euro character is slightly wider. But not by much. You'll definitely need Euros!

Courier or another monospaced font might work for all characters of interest?

You can't pad with spaces since they are the normal width.
 
Last edited:
Upvote 0

vecino

Well-Known Member
Licensed User
Longtime User
Hello, what I need is a source as similar as possible to the condensed ones of thermal printers, something like this:

aaa.png
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
I have looked and ultimately the width of characters of all fonts are measured by their glyph boundaries.
So currently Monospaced chars vary in width. No amount of tweaking can change that.

Edit: Removed my note about MonoSpaced characters in BBCodeView. See #8
 
Last edited:
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
I tested this without using BBCodeView.
The Euro is different (too narrow). I tried to selectively change its font size in CSBuilder.
Unfortunately, for other fonts as 20, it needs to be somewhere between 21 and 22 to match other characters.

B4X:
    Dim lines As String = _
$"
123456789*123456789*123456789*123456789*12345678
Hola, mundo ÑÑÑñññññññññññññññññññññññññññññññññ
ÁÉÍÓÚ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€
111111111111111111111111111111111111111111111111
222222222222222222222222222222222222222222222222
333333333333333333333333333333333333333333333333
444444444444444444444444444444444444444444444444
555555555555555555555555555555555555555555555555
666666666666666666666666666666666666666666666666
777777777777777777777777777777777777777777777777
888888888888888888888888888888888888888888888888
999999999999999999999999999999999999999999999999
000000000000000000000000000000000000000000000000
123456789*123456789*123456789*123456789*12345678
________________________________________________
------------------------------------------------
123456789*123456789*123456789*123456789*12345678
================================================
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
çÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñ
================================================
123456789*123456789*123456789*123456789*12345678
"$

    Dim lbl As Label: lbl.initialize("")
    lbl.SingleLine = False
    Dim lblx As B4XView = lbl
    Root.AddView(lblx, 0, 0, Root.Width, Root.Height)

    Dim cs As CSBuilder: cs.Initialize
    cs.Typeface(Typeface.MONOSPACE).Size(20)
    Dim v() As String = Regex.Split(CRLF, lines)
    For i = 0 To v.Length - 1
        cs.Append(v(i)).Append(CRLF)
    Next
    cs.popAll
    lblx.Text = cs
    
    'Dim bmp As B4XBitmap = lblx.Snapshot

fixedFontsScreen.png
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
Brilliant! It was the space as a word boundary. Who would have guessed? You did - may be not even a guess.

B4X:
BBCodeView1.TextEngine.WordBoundaries = Chr(160) & TAB & CRLF & Chr(13)
 
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
B4X:
Public Sub Test   
    BBCodeView1.TextEngine.Initialize(Root)
    BBCodeView1.TextEngine.SpaceBetweenLines = DipToCurrent(12)
'    BBCodeView1.TextEngine.MinGapBetweenLines = DipToCurrent(6)
'    BBCodeView1.TextEngine.WordBoundaries = "&*+-/<>=\' :{}" & TAB & CRLF & Chr(13)
    BBCodeView1.TextEngine.WordBoundaries = Chr(160) & TAB & CRLF & Chr(13)

    Dim s As String = _
$"
123456789*123456789*123456789*123456789*12345678
Hola, mundo ÑÑÑñññññññññññññññññññññññññññññññññ
ÁÉÍÓÚ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€
111111111111111111111111111111111111111111111111
222222222222222222222222222222222222222222222222
333333333333333333333333333333333333333333333333
444444444444444444444444444444444444444444444444
555555555555555555555555555555555555555555555555
666666666666666666666666666666666666666666666666
777777777777777777777777777777777777777777777777
888888888888888888888888888888888888888888888888
999999999999999999999999999999999999999999999999
000000000000000000000000000000000000000000000000
123456789*123456789*123456789*123456789*12345678
________________________________________________
------------------------------------------------
123456789*123456789*123456789*123456789*12345678
================================================
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
çÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñ
================================================
123456789*123456789*123456789*123456789*12345678
"$
    
    BBCodeView1.Text = s
    TextArea1.Text = s

    Dim html As String = _
$"
<!DOCTYPE html>
<html>
<head>
<style>
body {
    font-family: 'monospace';
    font-size: 12px;
}
</style>
</head>
<body>
123456789*123456789*123456789*123456789*12345678<br>
Hola, mundo ÑÑÑñññññññññññññññññññññññññññññññññ<br>
ÁÉÍÓÚ €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€<br>
111111111111111111111111111111111111111111111111<br>
222222222222222222222222222222222222222222222222<br>
333333333333333333333333333333333333333333333333<br>
444444444444444444444444444444444444444444444444<br>
555555555555555555555555555555555555555555555555<br>
666666666666666666666666666666666666666666666666<br>
777777777777777777777777777777777777777777777777<br>
888888888888888888888888888888888888888888888888<br>
999999999999999999999999999999999999999999999999<br>
000000000000000000000000000000000000000000000000<br>
123456789*123456789*123456789*123456789*12345678<br>
________________________________________________<br>
------------------------------------------------<br>
123456789*123456789*123456789*123456789*12345678<br>
================================================<br>
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<br>
çÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñÑáéíóúçÇñ<br>
================================================<br>
123456789*123456789*123456789*123456789*12345678<br>
</body>
</html>
"$

    WebView1.LoadHtml(html)
    #if B4A
    WebView1.ZoomEnabled = False
    #End If
    
End Sub
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
The Euro is different (too narrow).

It might be that the Euro is not in the monospaced font being used: I have a vague recollection that some renderers will substitute missing characters using a near-matching font (by characteristics such as serif, italic, cursive) and that the substitute x-point font has a different proportion and therefore different width.

It might be worth trying different monospace fonts, see if the problem changes or (even better) is resolved. The font B4X IDE font looks like a good starting point.
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
@emexes

With the line (by @TILogistic) in post #9, it works. Without it doesn't. Do I understand? Probably not. But it could be that word boundaries are smaller than spaces?
Even the Euro works with that line in BBCodeView.

In any case the OP can take it one step further, and see if his printer can print the image.
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Brilliant! It was the space as a word boundary.
With the line (by @TILogistic) in post #9, it works. Without it doesn't.

I misunderstood: I thought you were saying that having a space as a word boundary fixed the problem, but now I realize that it might be not having a space as a word boundary fixed the problem.

Perhaps lines that don't have any word boundary characters are not subjected to kerning or microspacing, and the characters are just positioned according to their unadjusted widths specified in the font file.

In any case the OP can take it one step further, and see if his printer can print the image.

It'd be interesting to see if the problem comes back when adding back the original word boundary characters, and which word boundary characters cause the problem.

Also to see if the problem then goes away again if the spaces are removed from the Euro line.
 
Upvote 0

vecino

Well-Known Member
Licensed User
Longtime User
Hi folks, I see you have been working hard.
So, at first glance, it seems that you have succeeded.
But right now I don't understand how it works, there is code that I don't know what it is for.
I'd better go have my coffee and study everything you guys have done.
I'll tell you later.
Thank you very much!!!!
 
Upvote 0

vecino

Well-Known Member
Licensed User
Longtime User
Hello, I don't understand how to get all the characters to occupy the same, that is, that each line of 48 characters occupies the same amount of space.
Specifically I do not understand this line:
BBCodeView1.TextEngine.WordBoundaries = Chr(160) & TAB & CRLF & Chr(13)
The chr(160) is the "á", what is the point of indicating that plus Tab?
There are days when I think that I am more and more a novice.
 
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
Sorry, it's from other tests I was doing.
you can take it out

B4X:
BBCodeView1.TextEngine.WordBoundaries = TAB & CRLF & Chr(13)
 
Upvote 0
Top