-
• #2
Looks like bug, there is now new vector font which is larger for same point size (e.g. size 26 now is similar to older size 30) so maybe some line pixel size constant was not updated somewhere in drawString code
-
• #3
Thanks for your comment, would be my 1st reported bug ;-)
BTW. Running latest version 2V06, but 2v05.97 of the Emulator has the same behaviour.
-
• #4
well it uses customHeight here https://github.com/espruino/Espruino/blob/master/libs/graphics/jswrap_graphics.c#L1374 and it is read here https://github.com/espruino/Espruino/blob/master/libs/graphics/jswrap_graphics.c#L1322 and this call returns value 'scale' here https://github.com/espruino/Espruino/blob/master/libs/graphics/jswrap_graphics.c#L1280
so maybe the real issue is that the new font is now larger for same scale than before as mentioned here -
• #5
Yes, this sounds like the new vector font...
@NebbishHacker any strong feelings about this? I think it makes sense to keep the line height the same as the vector font height, so I guess we should just tweak the font size down slightly?
-
• #6
Currently the font size accurately represents the height of letters like A, but it doesn't take into account accented characters (like À) or descenders (like j). Accents and descenders both currently protrude by about 1/4 of the font height, so the actual maximum height of a line of text is 1.5 times what you might expect.
For some stuff I'm currently working on it would be convenient if
g.clearRect(x, y, x+g.stringWidth(text), y+g.getFontHeight())
was always guaranteed to cover a single line drawn viag.drawString(text)
, which isn't currently the case.Overall, though, I don't have very strong feelings about whether we should tweak the font size.
-
• #7
As can be seen in the picture the beginletters of the lines (T B C) have zero spacing.
And in the case of "accents and descenders" the characters in successive line overlap.
I am too using g.clearRect to clear the result of a g.drawString and would expect to clear all pixels of drawString characters. Didn't know that this currently NOT the case.
-
• #8
In analogy with http://forum.espruino.com/conversations/302392/ I coded a "drawString" override that introduces proper line spacing in Strings witch "\n" newlines in it. In this case I have chosen for 5 pixels of space between each line..
Rather new to Espruino so maybe not the best solution, but it works for me.
Hopefully Gordon will come up with a structural solution.
Example code:
// override drawString function to allocate line spacing g._ds = g.drawString; g.drawString = function(s,x,y) { s=s.toString(); sa=s.split("\n"); print(sa); spacing=5+g.getFontHeight(); sa.forEach(function(line){ g._ds(line,x,y); y+=spacing; }); }; g.clear(); g.setFontVector(20); g.setColor(1,1,1); g.drawString("Temp:\nBattery:%\nCharging\nUptime: 0.00\nFreeFlash: \nFreeStor:",0,30);
And the resulting output:
1 Attachment
-
• #9
So for reference: I flashed 2v05.1 onto a watch for comparison, and it looks like the old vector font exhibited the same issue with descenders overlapping the next line.
1 Attachment
-
• #10
OK, but in your picture at least there is 1 pixel between each successive line (between the T, B and C character).
I'm running 2V06 on Bangle, and the 1 pixel spacing between the T,B, and C char is not there.
-
• #12
If you look closely the B and the C are touching at one point, so even the 1 pixel space is not always there.
In any case, I imagine you would generally want a bit more space between lines than that.
-
• #13
Fair enough, your suggestion is cleaner.
But I wanted a "fix" for the drawString problem.
Found my inspiration here http://forum.espruino.com/conversations/302392/ and thought "hey that's clever" and coded away.
I'm a lazy coder, so in this way I did not have to change my code ;-)
And if Gordon comes up with a fix to "drawString" I delete the override and I'm ready.
-
• #14
Agree, 1 pixel of line-spacing is not enough, so in my override I used 5 pixels, that seems also enough for descendents. For now ...., have been using the "fix" only for a few hours.
Output looks like this now:
1 Attachment
-
• #15
Hmm, that's tricky.
it would be convenient if
g.clearRect(x, y, x+g.stringWidth(text), y+g.getFontHeight())
was always guaranteed to cover a single line drawn viag.drawString(text)
While not quite as pretty, I think that is probably the best solution here, and it's definitely the least hacky :) I'll see about tweaking that...
-
• #16
@Gordon - I guess this means that we can forget about a "structural solution"for the problem on the short term, and I will have to live with my
drawString
override for now. Right?Maybe I will add the
g.clearRect(x, y, x+g.stringWidth(text), y+g.getFontHeight())
to my override, in my case it's always required with everydrawstring
. -
• #17
Well some settable line space setting would solve it as mentioned in first post? there is
https://www.espruino.com/Reference#l_Graphics_setFontAlign maybe this could remember line height/spacing preference too? -
• #19
Well then this would be not a bug but feature, you would need to set your preferred additional space to compensate for that font feature as e.g. without using accented letters the reserved space would be otherwise too big for you (on the top). This could be used both for handling '\n' in drawString automatically and could be read for g.clearRect when trying to clear area occupied by the text.
-
• #20
One approach to making sure you clear the right area would be to take advantage of g.getModified:
g.getModified(true); // Reset modified area // Insert whatever draw calls you want here g.drawString(...); let m = g.getModified(); // Save modified area for later g.clearRect(m.x1, m.y1, m.x2, m.y2); // Will clear the precise area affected by the above draw calls
-
• #21
@NebbishHacker
I was thinking about this strategy for my drawstring override:- get the area that is going to be covered by the string using fontHeight/fontWidth accounting for newlines in the string
- clear this area with clearRect
- then call the original drawstring
- done, nice and simple, no further bookkeeping.
But using getModified is more universal as it seems to cover all graphics. I have an App that uses many screens, so I would have to do a lot of bookkeeping with the different getModified areas.
Hmmmmm...... pondering .........
- get the area that is going to be covered by the string using fontHeight/fontWidth accounting for newlines in the string
-
• #22
Changed my
drawString
override function toclearRect
the area where the string is going to be displayed.Not extensively tested, but seems to work ok for me. It saves a lot of
clearRect
s in my code :-)Comments and suggestions welcome!
Code is like this:
// override drawString function to: // - allocate proper line spacing between successive lines // - clear the area where the string will be displayed g._ds = g.drawString; g.drawString = function(s,x,y) { s=s.toString(); sa=s.split("\n"); spacing=5+g.getFontHeight(); sa.forEach(function(line){ // clear the area where the string will be written g.clearRect(x,y,x+g.stringWidth(line), y + spacing); // now call the original drawString g._ds(line,x,y); y+=spacing; }); };
-
• #23
@NebbishHacker
As you can see in the post above I did not use yourgetModified
suggestion at the moment.My app is currently limited to text, I'm a lazy programmer, so this was the most efficient solution for me now.
When I get to the graphics part of my app I will remember your suggestion, thanks!
-
• #24
Fixed a bug in my override function, updated the code in the post above.
And also found some flaws in my override code.
If the
drawString
string is replacing a previous WIDER string the `clearRect' area is to narrow, so parts of the previous string will still be visible.Back to the drawing board :-(
-
• #25
@NebbishHacker
Your suggestion on usinggetModified
was "spot on", shame on me ;-)Here's my latest code including a random 'drawString` to check that the override is now OK. Seems that it's perfect for me now.
Ofcourse it requires some bookkeeping of the m variable if you change to a complete different screen.
var m=0; // override drawString function to: // - allocate proper line spacing between successive lines (here 5 pixels) // - clear the area where the previous drawString was displayed g._ds = g.drawString; g.drawString = function(s,x,y) { s=s.toString(); sa=s.split("\n"); spacing=5+g.getFontHeight(); g.clearRect(m.x1, m.y1, m.x2, m.y2); // Will clear the precise area affected by the previous drawString calls g.getModified(true); // Reset modified area sa.forEach(function(line){ //call the original drawString g._ds(line,x,y); y+=spacing; }); m=g.getModified(); // save modified area for clearing on next drawString }; // write a random string of random size at random x and y positions setInterval(function () { g.setFontVector(80*Math.random()); g.setColor(1,0,0); getal=1000*Math.random(); getal=getal.toFixed(0); g.drawString(getal,Math.random()*239,Math.random()*239); }, 1000); g.clear();
Hi,
When I use code like this
the "\n" creates a newline, works fine, nice feature.
But there is no spacing between the lines so the result is not very readable. In all cases the characters of the lines "touch" and in some cases characters of lines even "overlap" ( see picture in annex ).
Searched the documentation for a line-space setting, but did not find it.
Is there a line-space setting, and if not, is it a suggestion to add one?
1 Attachment