Forum > SynEdit

Idea for my component optimization, related to SynEdit

(1/1)

AlexTP:
@Martin,
I need your advice on this idea.
Idea about optimizing my own component ATSynEdit.
https://github.com/Alexey-T/CudaText/issues/5177

Did you do something similar in SynEdit?
Or original authors maybe did it?

Martin_fr:
Not currently. Though I have similar ideas on my mind (and not just for speed, but other reasons too).

In any case, it is not straight forward. Some fonts (especially scripts, I tested with Arabic) have ligatures. So you actually have to output the entire text (or at least a larger piece of it) with every paint. That includes outputting text that has a different style.  The part with the different style can be omitted using clipping)

You also have italics overlapping into the next token. This would be reduced by collecting tokens => but ultimately may have to first paint the background (including always at least one next token's background ahead), and then the text on top.
Yet, that may need double buffer... I have not tested, if this could otherwise flicker (since on each paint, the text will be removed (even if the same text is repainted).

On Windows there is an alternative API (scribe?) which can pre-compute the tokens (this would maybe make output of scripts easier). But I have not looked at this at all yet....

The other question is: How much time does changing the color of the pen actually take?
As for bold vs non-bold => you might be able to cache the different fonts (not sure if the lcl does somewhere).

Assuming that you cache the pixelmap overview in a bitmap, you usually only paint a few line at a time => that shouldn't be a speed issue.

So long as you take care with scrolling. ScrollWindowEx will only invalidate a few lines.
Except => if you do additional invalidations (I recently found SynEdits syncro edit seems to do that => it flickers when scrolling).

So, if you scroll up, new text comes in on the bottom. That is fine. But if you invalidate any small part at the top of the window at the same time => then the entire window may need a repaint.
That is usually no problem when it happens once. e.g. synedits topline function-name hint during scrolling => it is not part of the ScrollWindowEx, it only invalidates if the underlying function changes. (once every x lines scrolled)>
But if it happens on each and every scrolled line, then it is an issue.


So make sure,

- when you scroll, you only scroll the region you need.
- absolutely no other invalidates unless really unavoidable

Things that don't scroll shouldn't be part of the rect passed to ScrollWindowEx.

The minimap may be easier to deal with, if put into a nested wincontrol (excluded from scrolling). SynEdits right overview gutter is in a sub panel.
Because if the main edit scrolls, the overview gets updated in the vertical middle of the screen => and that is an extra invalidate, which increases the total repaint rect.



Martin_fr:

--- Quote ---The minimap may be easier to deal with, if put into a nested wincontrol (excluded from scrolling). SynEdits right overview gutter is in a sub panel.
Because if the main edit scrolls, the overview gets updated in the vertical middle of the screen => and that is an extra invalidate, which increases the total repaint rect.
--- End quote ---

To clarify

You have your window rect

--- Code: Text  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---|------|-||      | ||      | ||      |o||      | ||      | ||      | ||------|-| 
On the right is the overview/minimap.
The "o" is the highlight for the current visible page (that is where the visible main text is in the overview)

Now you scroll up
- new lines come in at the bottom: Invalidate rect (top: 500, Left: 0, Right 600; bottom 600 // full width, some lines at the bottom)
- the "o" area moves => invalidate rect (top: 200, Left: 600, Right 650; bottom 250 // full width, some lines at the bottom)

Total repaint rect: (top: 200, Left: 0, Right 650; bottom 600 // full width, some lines at the bottom)

That is a lot of extra repaint. If the overview has it's own wincontrol then that is 2 small repaints instead.

---------------
Just adding, I don't know, if your minimap is in the same wincontrol or not.

The 2nd wincontrol can be a child of the first => just tell ScrollWindowEx not to scroll child wincontrols.


Navigation

[0] Message Index

Go to full version