Trouble with fonts

151 views
Skip to first unread message

Lucio

unread,
Dec 7, 2016, 1:49:00 AM12/7/16
to golang-nuts
The first issue is one of documentation. It says in <https://godoc.org/golang.org/x/image/font> that:

DrawBytes draws s at the dot and advances the dot's location.

But it leaves the question of what exactly those bytes are supposed to represent. Line 132 in <https://github.com/golang/image/blob/master/font/font.go> provides some illumination, but one wonders what the idea is of passing encoded runes as bytes instead of using more direct runes for the purpose. More cryptically, how does one convert a single rune (which I happen to need "measured" in the code I'm working on) to a byte slice for the benefit of DrawBytes' (it's actually MeasureBytes, in my case)? Do I seriously need to find a utf8.RuneEncode function somewhere?

The second issue is I'm sure even more due to a lack of understanding on my part. Using the "UbuntuMono-RI.ttf" file I sourced somewhere, I get a "panic: runtime error: index out of range" when executing (specifically for debugging) ``font.MeasureString(instance, "\u2502")'' where "\u2501" and lower seem to work OK.

Obviously, such factors as the input from file, the generated "instance" of the font, etc. are factors here. Thing is, I have no idea where to look for this problem. I'd be grateful for any suggestions on how to approach this. It does seem a little strange that the font utilities do not supply some of the more useful details, at least from my search through the documentation, such as the highest valued rune in a font and the like.

Of course, fontforge reveals that the given file (I'd better check, I'm not using the same file object) does have characters beyond 0x2501 (9473).

Thanks to all.

Lucio.

Nigel Tao

unread,
Dec 7, 2016, 8:10:33 PM12/7/16
to Lucio, golang-nuts
On Wed, Dec 7, 2016 at 5:49 PM, Lucio <lucio...@gmail.com> wrote:
> The first issue is one of documentation. It says in
> <https://godoc.org/golang.org/x/image/font> that:
>
> DrawBytes draws s at the dot and advances the dot's location.
>
> But it leaves the question of what exactly those bytes are supposed to
> represent.

The bytes are presumed to be UTF-8 text. (What else would it be?) In
any case, I sent out https://go-review.googlesource.com/34095


> but one wonders what the idea is of passing encoded runes as
> bytes instead of using more direct runes for the purpose.

A text editor widget might expose its text content as a []byte,
instead of a []rune, since in the latter representation, the
underlying array takes 4x the memory for ASCII text, a common case.


> how does one convert a single rune (which I happen to need "measured" in the
> code I'm working on) to a byte slice for the benefit of DrawBytes' (it's
> actually MeasureBytes, in my case)? Do I seriously need to find a
> utf8.RuneEncode function somewhere?

Yes, it's in the standard library:
https://golang.org/pkg/unicode/utf8/#EncodeRune

Or, if you're less concerned about unnecessary memory allocations and
only want a simple API, to draw a single rune r, use DrawString
instead of DrawBytes:

d.DrawString(string(r))


> The second issue is I'm sure even more due to a lack of understanding on my
> part. Using the "UbuntuMono-RI.ttf" file I sourced somewhere, I get a
> "panic: runtime error: index out of range" when executing (specifically for
> debugging) ``font.MeasureString(instance, "\u2502")'' where "\u2501" and
> lower seem to work OK.

Can you mail me (off-list) that ttf file?

Lucio

unread,
Dec 7, 2016, 11:32:09 PM12/7/16
to golang-nuts, lucio...@gmail.com


On Thursday, 8 December 2016 03:10:33 UTC+2, Nigel Tao wrote:
On Wed, Dec 7, 2016 at 5:49 PM, Lucio <lucio...@gmail.com> wrote:
> The first issue is one of documentation. It says in
> <https://godoc.org/golang.org/x/image/font> that:
>
> DrawBytes draws s at the dot and advances the dot's location.
>
> But it leaves the question of what exactly those bytes are supposed to
> represent.

The bytes are presumed to be UTF-8 text. (What else would it be?) In
any case, I sent out https://go-review.googlesource.com/34095

Thank you for taking the trouble, I appreciate it. 

> but one wonders what the idea is of passing encoded runes as
> bytes instead of using more direct runes for the purpose.

A text editor widget might expose its text content as a []byte,
instead of a []rune, since in the latter representation, the
underlying array takes 4x the memory for ASCII text, a common case.

I would choose to err on the side of intuition by first documenting a MeasureRunes function, then add MeasureBytes for the undeniably useful role it plays and explain that as an optimisation. Perhaps I can help with that, if you feel this would be a positive contribution?

> how does one convert a single rune (which I happen to need "measured" in the
> code I'm working on) to a byte slice for the benefit of DrawBytes' (it's
> actually MeasureBytes, in my case)? Do I seriously need to find a
> utf8.RuneEncode function somewhere?

Yes, it's in the standard library:
https://golang.org/pkg/unicode/utf8/#EncodeRune

Or, if you're less concerned about unnecessary memory allocations and
only want a simple API, to draw a single rune r, use DrawString
instead of DrawBytes:

d.DrawString(string(r))

I inefficiently, but perhaps unavoidably, resorted to measuring the full length of a string as I assembled it from individual font characters. In my case, it is not an operation that is executed frequently, so I took a lazy approach. Thank you for the hint about runes, it will be filed for future use.


> The second issue is I'm sure even more due to a lack of understanding on my
> part. Using the "UbuntuMono-RI.ttf" file I sourced somewhere, I get a
> "panic: runtime error: index out of range" when executing (specifically for
> debugging) ``font.MeasureString(instance, "\u2502")'' where "\u2501" and
> lower seem to work OK.

Can you mail me (off-list) that ttf file?

I have done that. It turns out, for the record, that I have a copy from a day later (I really can't recall the circumstances) that does not cause the parsing to crash. I can only presume that there are internal differences that fontforge did not reveal, since the two files are identical in size, but differ in their checksums.

If you need the more recent copy for comparison, let me know.

Lucio.
 

Nigel Tao

unread,
Dec 8, 2016, 1:55:36 AM12/8/16
to Lucio, golang-nuts
On Thu, Dec 8, 2016 at 3:32 PM, Lucio <lucio...@gmail.com> wrote:
>> A text editor widget might expose its text content as a []byte,
>> instead of a []rune, since in the latter representation, the
>> underlying array takes 4x the memory for ASCII text, a common case.
>>
> I would choose to err on the side of intuition by first documenting a
> MeasureRunes function, then add MeasureBytes for the undeniably useful role
> it plays and explain that as an optimisation. Perhaps I can help with that,
> if you feel this would be a positive contribution?

x/image/font/font.go already has a

// TODO: have DrawRunes(s []rune)? DrawRuneReader(io.RuneReader)?? If we take
// io.RuneReader, we can't assume that we can rewind the stream.

comment, but I'm not convinced that it's necessary yet. Using
utf8.EncodeRune should be straightforward, or just convert to string.
Reply all
Reply to author
Forward
0 new messages