Start a new topic

Crunching lines of text

Just thought i'd share this technique for getting 12 lines of "large" text onto a 2.4" nextion display (24 lines deep).  The font I use is actually 24 lines deep - but the trick is to understand that not all 24 lines are actually used - at least in the fonts I have tried.  In fact, with a bit of judicious overlap, you can reduce the height of each character to 19 lines or less.

The trick is to overlap lines of text, and adjust the priorities of lines so that they draw over each other.  In particular, this requires a bit of understanding as to how the Nextion actually draws stuff on the screen.  The 'id' you see associated with any of the objects (button, text, etc) is actualy a *draw order* as well as a unique identifier.  Objects are drawn in order, lowest id first.  The up and down arrow on the top left of the toolbar of the editor change this order.

The trick to get lots of lines of text on the display is to have the top few scanlines of each "text line" covered up (or overdrawn) by the bottom few scanlines of the text line above it.  To do this, instead of spacing the text lines 24 apart, space them 19 apart and make sure that the ID of the lower line is less than the ID of the upper line. This will cause the lower line to be drawn first, and then the upper line after that - doing the overlap.  With (say) 12 lines of text on the screen, the ids go from the bottom up low to high, and the Nextion draws the lines in that order, too.  With judicious font usage and close attention to spacing, you can squish your 12x24 font into the 12x19, as I said. 

Also, another neat thing to do is to mark each text line as x-centred. This means that based on variable width text in each line, the horizontal offset of characters changes. This staggered effect reduces the impression of fixed-width characters.

I offer a screenshot to show the effect of vertically-overlapped text lines and horizontally staggered lines.  Hopefully these ideas might help some others playing with the Nextion and needing to put a lot of text onscreen.


xstr does exactly this, but even pixel based and more easy  ...



Funny, I used to work for a company named BEAM.

I assume that's an 8x16 font, with 15 lines = 240 pixels.  That picture is not using the same concept - you could use that font and probably get another 3 or 4 rows if you did the overlap/shrinking, or as Gerry says, the xstr.  Although I didn't know of xstr I don't think it applies if you use the editor with text objects for layout.  Anyway, just sharing my experiences and findings, some of which may be interesting to others. Or not.

honestly, we are happy about every contribution, especially when we can see that a user played around by himself instead of just copy and paste existing without own thinking ...

Learning by doing is a guarantor for lots of fun ...


First, my mircoTerm is for a bit of technical humour.

Sharing Experiences and Knowledge is a good thing

  - Discussing them leads to wisdom and understanding.

To get more info on a display only requires using smaller fonts ...


Your concept of overlapping introduces a few less desirable side-effects

 - but first I will offer up a technique.

The b[.id] component array was discovered by Steve (indev2)

 - this is present in several threads and example code

So with the b[.id].attribute array, your 10 lines of text when sequential





With it, Text could also even be updated in a more programmatic fashion

Now discussing the pros and cons of overlapping text or any other in Nextion

It isn't just a page that has such a *draw order*, hence the component's .id

  - every component also has its own mini draw order.

    A button for example has a background, a border, and optional text

    Text also has background, borders and text.

It is exactly this mini draw order for why you can't stack three Gauge components

   to make a three handed analog clock, yet it can indeed be accomplished



When we start overlapping components or drawing space, one runs the risk that any

update to a component that has area tucked underneath another, is going to cause

its mini draw order to wipe out the component's area (.x,.y) to (.x+.w-1,.y+.h-1).

This is going to either damage part or all of another component.  Less desirable.

Many font scenarios will still render partial font if its component space height is shy.


And still render on the Nextion device even though font matrix is taller


This technique will avoid the overdrawing that can damage adjacent text

- by setting the 10 Text components to .h of 19 and then squeezing out

  the vertical spacing using the "decrease vertical spacing" on the

  toolbar until there is no space between them.


I will touch on speed just for a moment.  Every pixel used to render costs cycles

Without getting too deep into the font concept, I want to point out that every use of

pixels costs time.  The fastest rendering comes from constant solid color background.

Overlapping causes some delay, in that the same area of the screen needs to be

redrawn again - but there is more to it than that.

Font matricies are in multiples of 8 for a reason, width is 1/2 height for a reason.

And the Text Component is actually quite bloated with things that chew cycles.

- a crop image or image background now has to take more cycles to fetch from

  SPI flash the picture resource that is compared to pic pixel and font pixel.

- x center/right chews up a subroutine to align, fastest is to set it to left (natural)

- y center/down chews up a subroutine to align, fastest is to set it to up (natural)

- spax and spay again more subroutines and calculations, fastest is at 0

- isbr set default to true, faster is to turn it off set to false

- style other than flat triggers more gui commands, more time

- .pw was in my opinion a total waste, a font change would be quicker and would

   not have cost on every single component (1 or 2 passwords per HMI, many texts)

But perhaps the worst is a default width and height that don't align to any valid

   Nextion ZI font size.  Width 100 would mean height 200 - 160 is max generated.

   and 30 is not the required multiple of 8.

So in a 30x100 pixel space for a font is 3000 pixels that need be dragged into render

   when an 8x16 font for 10 chars is used of this space (1280) this is 1720 (57%) waste.

   even 12x24 by 8 chars 96/100 24/30 leads to 2304/3000 - 696 pixels or 23.2% waste.

People soon wonder why their HMI designs become sluggish or less responsive

   and it usually boils down to how their pixels were used, or overused.

   in proper use for speed, a font is known as 12x24 by 10 chars

    - then .w of 120 .h of 24 for 0% waste, and with most bloat options turned off.

Setting the height to an undersize is not going to prevent pixel comparisons

   - but it will at least contain the text so that it doesn't interfere in other component space.

As for why a Font is a font - that is another topic

 - hope some of this has been useful.

Thanks Patrick - a comprehensive and interesting reply.

One comment on your example with the yellow bars and "crunched" text. You have used a height of 19 (I use 23).  This works for your example because the font you have used *does not have descenders*.  For example, lower-case "g".  So you get by without overlap and the smaller height.  However, with height of 19 on my font, all of the descenders are cut off - yet I use the same line spacing (19) in my example.  In the overlap system, you can have descenders - in the example you give, it appears you cannot (with the same line spacing).

In my analysis, a character in a font 32 high is roughly centred within that height.  In the font I have used, you can reduce the height to 19 and have no descenders, or you can reduce to 23 with descenders. Regardless of the height you choose, there are several (4 or so) unused lines at the very top of the font. I believe in your example, the top of the font is the gap between your lines.   In my method, the top of the font is UNDER the line above, so the descenders are drawn.

It's a slight distinction, but I think using a font without descenders is missing the reason for overlap.

Thanks again for your detailed comment/reply - very useful!

Gerry covered xstr, so there wasn't more I could add to it, so I discuss other points.

I will again try to not go deep into font concept and why a Font is a font ...

Indeed, the entire point of showing that font will render even with height being shy

is to show how to gain what you desire 10 lines in 190 pixels without needing overlap.

10 lines of 12x24 is 240 height - the ZI font indeed needs to be multiple of 8.

Regardless of what the "contents" of that 12x24 is, it indeed is "crunched" from 24.

Overlap will cause more issues than needed.  It prevents quick access to a single line.

When someone needs to update a temperature reading in the 3rd line

  5 chars, 60x19, 1140 pixels, it shows more waste to update 76,800 (98.52%) 

  and this scenario would be indeed higher than 100% with over drawing.

Your algorithm is to redraw from the bottom up, but the overlap causes the screen to

  need to be refreshed or lose some extenders and descenders on a line not refreshed.

The methodology for your analysis of a 32 high font is wrong and skewed

 - you are massaging your data for a subset of font specific to what you are using.

 - you are not making allowances for the general font

     - in your supporting argument, you discard general that is not within your subset.

But in the confines of the Nextion ZI font, I think all font cases need be considered.

 - I can show cases where there is no height, top or bottom to spare pixels - zero

 - I can show cases where extenders have more weight than descenders

    as such, an algorithm based on favoring descenders fails as extenders are lost.

As such an algorithm for font needs be mathematical, regardless of content.

    would need to address all scenarios, regardless of font.

I think that to travel a path that is known problematic is less desired - overlapping.

    I presented how to accomplish similar, without breaching a problematic barrier.

But, I might argue, each programmer is their own designer, free to chose their path.

  - in one path, does it become a contest to see how just packed and overdrawn a

    design can become?  to bring the Nextion to the brink before breakage

  - or maybe another path, where problems can be avoided, execution speed is quick

    so that Nextion has even more time for additional tasks without becoming bogged

    down, where overruns and overflows occur because one task takes too long.

I argue that by only exercising a few design choices which font to use, and its height.

    I provided more visual space, avoided conflict areas, and the info is disseminated.

Although not so problematic on the selected text of your example,

   extenders and descenders have indeed collided and caused collision and overwritten.

You have indeed proven in one specific case that it works,   but it needs to be

   acknowledged that in other cases will not work out with the same successes.

Login or Signup to post a comment