Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
greubel
Visitor

Re: Issues with roFont.getOneLineWidth

Test to check width value of Default font returned from "getOneLineWidth".
You can modify the width value by a fudge factor to increase the size of the box

Change font size - Up and Down buttons. (goes from 1 to whatever, starts at 35)
Change font face - Left and Right buttons. (normal,bold,italic,bold-italic)
Change Fudge Factor = REW and FF buttons. (bumps fudge +- 0.01)
* If you don't get BOLD, change the value of 75 to 63 in the font string at button of code.

Function Font_Test_2()

reg = CreateObject("roFontRegistry")
face = ["Normal","Italic","Bold","Bold-Italic"]

scr = CreateObject("roImageCanvas")
port = CreateObject( "roMessagePort" )
scr.SetMessagePort( port )

scr.SetLayer( 0, { color: "#FF808080" } )
scr.Show()

usage = "Left/Right chg Face, Up/Dn chg Size, FF/REW chg Fudge Factor"
size = 35
s = "Hello foo foo enjoy"
loop = true
mode = 0
fudge = 1.0

while loop

bold = Int(mode/2)
italic = Mod( mode, 2 )

f = reg.GetDefaultFont( size, bold, italic )
w = Int( f.GetOneLineWidth( s, 10000 ) * fudge )
h = f.GetOneLineHeight()
font = reg.Get( "", size, bold, italic )
if Int(mode/2) = 1
font = Set_Bold( font )
end if

a = Int(fudge / 1.0).ToStr()
b = Mod( Int(fudge*10), 10 ).ToStr()
c = Mod( Int(fudge*100), 10 ).ToStr()
val = a+"."+b+c

txt = face[mode]+" Fudge Factor = "+val+Chr(10)
txt = txt + "w = "+w.ToStr()+" h = "+h.ToStr()+Chr(10)
txt = txt + font + " font string"

items = CreateObject( "roArray", 100, 1 )

items.Push( { color: "#FFFFFFFF", TargetRect:{x:100,y:200,w:w,h:h}} )
items.Push( { Text:s,
TextAttrs:{ Color:"#FFFF0000", Font:font, HAlign:"Left", VAlign:"Middle" },
TargetRect:{ x:100,y:200,w:w,h:h }} )

items.Push( { Text:txt,
TextAttrs:{ Color:"#FF000000", Font:"Large", HAlign:"Left", VAlign:"Top" },
TargetRect:{ x:100,y:10,w:600,h:200 }} )

items.Push( { Text:usage,
TextAttrs:{ Color:"#FF000000", Font:"Medium", HAlign:"Left", VAlign:"Middle" },
TargetRect:{ x:100,y:300,w:720,h:40 }} )

scr.SetLayer( 1, items )

while true
msg = wait( 1000, port )
if msg <> invalid AND msg.GetType() = 7
i = msg.GetIndex()
if i = 2 ' up
size = size + 1
exit while
elseif i = 3 ' down
size = size - 1
exit while
elseif i = 4 ' left
mode = Mod(mode+1, 4)
exit while
elseif i = 5 ' right
mode = Mod(mode-1, 4)
exit while
elseif i = 6 ' select
exit while
elseif i = 8 ' reverse
fudge = fudge * 0.99
exit while
elseif i = 9 ' forward
fudge = fudge * 1.01
exit while
else
loop = false
exit while
end if
end if
end while

items.Clear()
scr.ClearLayer( 1 )
sleep( 200 )
end while

End Function

Sub Set_Bold( in as object ) as object

p = in.Tokenize( "," )
p[3] = "75" ' <<<<<<<<<<< ********* Set this to "63" on some boxes
out = ""
for i=0 to p.Count()-1
out = out + "," + p[i]
end for
return out

End Sub


0 Kudos
RokuMarkn
Visitor

Re: Issues with roFont.getOneLineWidth

Thanks for posting that. I've modified it to use roScreen rather than roImageCanvas and it seems to work perfectly (except possibly for a slight overdraw with italic). So the issue seems to be with roImageCanvas. I don't know much about roImageCanvas but I'll pass this along to the right people. The GetOneLine* functions were intended to be used with roScreen so I'm not sure if they're supposed to work with roImageCanvas. roScreen is really a better choice if you're trying to do pixel-accurate drawing.

Here's the roScreen version of your code.


function main()
reg = CreateObject("roFontRegistry")
scr = CreateObject("roScreen")
port = CreateObject( "roMessagePort" )
scr.SetMessagePort( port )
usage = "Left/Right chg Face, Up/Dn chg Size, FF/REW chg Fudge Factor"
size = 35
s = "Hello foo foo enjoy"
loop = true
mode = 0
fudge = 1.0

while loop
scr.Clear(&hFF808080)

bold = Int(mode/2)
italic = mode mod 2

f = reg.GetDefaultFont( size, bold, italic )
w = Int( f.GetOneLineWidth( s, 10000 ) * fudge )
h = f.GetOneLineHeight()

txt = "w = "+w.ToStr()+" h = "+h.ToStr()

scr.DrawRect(100, 200, w, h, &hFFFFFFFF)
scr.DrawText(s, 100, 200, &h00FFFFFF, f)
scr.DrawText(txt, 100, 40, &h000000FF, f)
scr.DrawText(usage, 100, 300, &h000000FF, f)
scr.Finish()

while true
msg = wait( 0, port )
if msg <> invalid and type(msg) = "roUniversalControlEvent" then
i = msg.GetInt()
if i = 2 ' up
size = size + 1
exit while
elseif i = 3 ' down
size = size - 1
exit while
elseif i = 4 ' left
mode = (mode+1) mod 4
exit while
elseif i = 5 ' right
mode = (mode-1) mod 4
exit while
elseif i = 6 ' select
exit while
elseif i = 8 ' reverse
fudge = fudge * 0.99
exit while
elseif i = 9 ' forward
fudge = fudge * 1.01
exit while
end if
end if
end while

end while

End Function

--Mark
0 Kudos
greubel
Visitor

Re: Issues with roFont.getOneLineWidth

Ok, that works.
Question: Can you get "wrapped" text with the DrawText() function ? You only give it an X and Y coordinate.

I think the value returned by getOneLineWidth() is maybe correct.
It's just that the text rendering, doesn't think it will fit in the box.

The SD is better, if I increase the width by a factor of 1.03, all the font sizes and faces work with that canned text. (no wrapping)
But the HD, is a different story.
0 Kudos
RokuMarkn
Visitor

Re: Issues with roFont.getOneLineWidth

DrawText doesn't wrap, it just draws a single line of text. If you want it to wrap you have to break it up into lines yourself and call DrawText for each line. I posted some code to do this a couple of days ago.

--Mark
0 Kudos
greubel
Visitor

Re: Issues with roFont.getOneLineWidth

Using my test, going through all the font faces (normal,bold,italic,bold-italic) for font sizes of 1 to 70. I don't know why anyone would use a font size less than 12.
On a SD display, you have to increase your box length by 3% to prevent word wrapping. On a HD display, you have to increase it by 15% to guarantee no wrapping.
Now this is just with the text in the test. Different text may produce other results.

Is there some sort of padding that should be applied to the value returned by "getOneLineWidth" ?

Also the function is slow, about 40ms !
I had to dynamically build an index table of character sizes for different fonts sizes and faces. This reduced my get size function down to 1ms once the index was built.
Makes a big difference if you have a lot of fields and refreshes.

There is definitely something wrong with the word wrap algorithm. Could you pass this thread and my test on to the analyst in charge of fonts ?
0 Kudos
greubel
Visitor

Re: Issues with roFont.getOneLineWidth

Is anyone at Roku looking at this ?
Would it be possible to add a flag for NOWRAP ?
0 Kudos
Need Assistance?
Welcome to the Roku Community! Feel free to search our Community for answers or post your question to get help.

Become a Roku Streaming Expert!

Share your expertise, help fellow streamers, and unlock exclusive rewards as part of the Roku Community. Learn more.