0

In the DirectWrite guides and examples I only found solutions for creating layout and rendering relatively small strings, i.e. with not a big number of characters.

Currently I understand that the method with the best performance is to create and cache IDWriteTextLayout and draw it using ID2D1DeviceContext::DrawTextLayout. Layout is needed to be recreated only when display text is need to be updated: when changing font size, family, text string itself, etc.

This method works fine for less then about 50 000 characters string, but starting from here, fps significantly drops. But I want more than 50K chars, I want 50M chars, for example. At my pc ID2D1DeviceContext::DrawTextLayout takes about 23ms to draw 55 000 character string, which means that the result fps (there are another ui elements) will be already less then 1000/23 = 43 fps.

How, for example in classic notepad.exe there is no delay when I input some character in 10 000 000 characters text and all is rendering at 60fps? Maybe there I need to separate strings on chunks and draw individual but display as one string? I currently barely can imaging how to deal with ending position of one string and starting of another.

Ngdgvcb
  • 155
  • 6
  • Crom. Fifty million characters is an odd use case. Can you even fit that many characters on a screen at the present time? – user4581301 Sep 01 '22 at 17:08
  • @user4581301, umm, no, they will not fit, I will scroll to see them all, as in notepad. And what do You mean by *"Fifty million characters is an odd use case"*? I have an input field, I want to write as many characters as I want, 50M - then 50M. Notepad or similar programs gives me that ability with no lags – Ngdgvcb Sep 01 '22 at 17:13
  • Drawing such many characters on a window is a waste of time, because you know in advance that you need scrolling. So, find out the portion to be seen an draw only this portion. – Ripi2 Sep 01 '22 at 17:19
  • In that case, why render all 50 million characters? Only render that which you need to show. – user4581301 Sep 01 '22 at 17:19
  • @Ripi2 and user4581301, good idea, but unfortunately, there is no ability to restrict `ID2D1DeviceContext::DrawTextLayout` result call area. Also there is still problem with recreating the layout, it also takes a time – Ngdgvcb Sep 01 '22 at 17:23
  • In fact it’s more the opposite. All performance examples are using large texts because small texts are unusual slow. Tried to draw a chart with 10000 two word texts. Impossible. Well direct2d and directwrite are immediate modes so you can/must create your own graph engine on top of it. They are neither Text editor nor CAD system – Lothar May 27 '23 at 20:37

1 Answers1

0

I don't think layout object was particularly designed for that. I'd think about it as a DrawText() replacement with much fancier configuration options. If you want a text editor level of complexity, you'll have to implement layout logic yourself. You would use lower level shaping functionality for that (GetGlyphs/GetGlyphPlacements), applying line breaking, bidi logic, etc. Then you can optimizing and render only visible parts, without updating everything.

Notepad example while valid is also much simpler, it only supports a single font and no formatting options. Still I'm sure it's not that naive and doesn't e.g. reshape when it does not have to.

bunglehead
  • 1,104
  • 1
  • 14
  • 22