Implementing QAbstractTextDocumentLayout::draw
-
Hello, everyone.
I'm having a lot of trouble understanding what am I supposed to to on the
draw
implementation of aQAbstractTextDocumentLayout
specialization I'm writing.The problem is that I only receive a
QPainter
and aPaintContext
. I don't know much about all the things aQPainter
is capable of doing, as I'm still learning, but I believe there is not enough information for me to determine which block of the document I'm supposed to print first... The only thing I get is the cursor position, which is not enough information.Should I just draw the whole document an then clip by the context's clip rectangle? Isn't this a waste of effort?
I'm implementing a document layout to be associated with a
QTextDocument
that will be shown by aQTextEdit
widget.I really need your help... What would help is an explanation about what is what in the parameters I get and how everything connects with the
QTextEdit
viewport, because the documentation of this method is terrible!!Thank you.
-
Hi Arthur,
Sorry you did not get any feedback for your issue after so long, shows there must be a minimal use or understanding of this class. Did you get help or find solution you can share. I'm also trying to find help using this class and lack of doc is still there I'm afraid.One possibility is to look at KoTextDocumentLayout.h and cpp files, these might help with some information.
https://github.com/JeremiasE/KFormula/blob/gsoc/libs/kotext/KoTextDocumentLayout.h
-
This is a pretty old post, but I recently tried to tackle this and wanted to write down some of my findings about this obscure corner of Qt. It is probable that not all of this correct, this is just my current understanding.
The purpose of
QAbstractTextDocumentLayout::draw
is to paint all of the relevant text blocks in the document (typically by means of delegating toQTextLayout::draw
which does the actual heavy lifting) as well as any additional decorations and elements that surround the actual text objects (e.g. frame borders, list bullets, etc). It is also responsible for drawing the text cursor marker if needed.The layout class operates in document coordinates, so the position or size of the viewport of the actual widget (if it is even a widget, it could be drawing to a printer) is of no concern. The given
QPainter
is already pre-configured to accept the document's coordinate system.What defines what elements the view wants painted is the
context.clip
rectangle. At least those elements that intersect with it should be painted, so a straightforward thing to do would be to iterate over all blocks in the document, and check if their bounding rectangle intersects with the clip rectangle. Given that all blocks should already have their layout in place by the timedraw
is called, this is relatively fast. Of course this can be further optimized based on the layout class' knowledge of how blocks are laid out, for example a plain-text-like layout that arranges blocks linearly can use some sort of binary search.It is allowed to draw more than the clip, so drawing all blocks every time is a valid approach, although inefficient. It is also possible that the given clip rectangle is invalid, in which case everything needs to be drawn anyway. Though, I haven't seen
QTextEdit
not provide a valid clip.Other members of the
PaintContext
:-
palette
- if you want to use the view's palette pens and brushes to paint something, they are available through here, although most colors will be determined by the character format. -
selections
- for the text editing widgets, those are the "extra selections". For each painted block, you'll want to check if any of the extra selections' cursor is relevant to that block, turn it into block-relative start and end positions, and collect into a list that will be provided toQTextLayout::draw
. -
cursorPosition
- position in characters (relative to the document) where the text cursor marker should be drawn. Straightforward implementation would figure out the relevant block containing that position, and if relevant to the draw call, delegate to its' layout'sQTextLayout::drawCursor
method. You can also paint your own cursor directly with thepainter
if you'd like something custom. It is-1
if no cursor is required. One thing I noticed is thatQTextEdit
repeatedly callsdraw
on the text cursor's immediate area on a timer, alternatingcursorPosition
between -1 and the actual position, so that' how it makes a blinking cursor. There is also something with additional negative values, that seems related to pre-edit text, which is something I don't fully understand yet.
-