model object (SwNode) These are double linked (pNext, pPrev) Contains a double linked list of SwLayoutFrames • At least a SwBodyFrame for the text content • Optional SwHeaderFrame and SwFooterFrame • Order as expected: header, body, footer
frame: SwTextFrame Layout counterpart an SwTextNode object mnOffset member refers to the m_Text of SwTextNode • Unless some redlines are hidden SwTextFrame is registered in an SwTextNode • notified in case the SwTextNode changes
from SwFrame, but also from SwFlowFrame These are the frames that are allowed at page breaks May continue on the next page, e.g., paragraphs, tables Floating table: table in allowed-to-split fly frame • A recent addition in 2023, SwFlyAtContentFrame wasn’t an SwFlowFrame before Also used for chained fly frames
text frames, graphics, OLE objects and drawing objects Are anchored at a certain SwFrame, page frame or text frame SwAnchoredObject with SwFlyFrame and SwAnchoredDrawObject subclasses SwFlyFrame subclasses: SwFlyAtContentFrame for at-char, SwFlyInContentFrame for as-char Anchor frame: m_pDrawObjs stores what is anchored at here My anchor: mpAnchorFrame All fly frames are also tracked per-page (expect as-char fly frames)
frame area and the frame print area for each frame Debugging starting points: • MakeAll(): does everything • MakePos(): just the position, not the size nor the frame print area • Format(): frame area size and the print area • Also: layout XML dump
you can register into this, used for nodes SwClient: you can listen with this SwTextNode ↔ SwTextFrame SwTableNode <-> SwTabFrame Mostly 1 node → N frames Exception: hidden redlines may result in 1 frame → N nodes • See work from Michael Stahl
These create and insert new SwFrames into an existing layout E.g. press "ENTER" at the end of a paragraph • A new SwTextNode will be inserted into the nodes array • This new SwTextNode executes MakeFrames() • Creates SwTextFrame(s) and inserts it into the layout
may be split (table frame → SwTable) Inside: row frames (row frame → SwTableLine) Inside: cell frames (cell frame → SwTableBox) There are no columns, they are a UI-level concept in Writer
Twips: 1/20th of a point Origo: top left corner of the root frame Inside a frame: frame area is also absolute Frame print area: relative position
a character: SwTextNode is modified, pings its clients SwTextFrame::SwClientNotify is called SwCharRange is constructed SwTextFrame::Format() is performed SwTextFormatter is created SwTextFormatter::BuildPortions re-creates the frame’s portions
SwTextFrame::GetCharRect(): twips coordinates from an SwPosition (node index, content index) • Inherently may not be perfect, think of e.g. headers SwTextFrame::GetModelPositionForViewPoint(): SwPosition from coordinates
Fields are a single dummy character in the model May expand to multiple characters Cursor is always at a model position, so you can’t move your cursor inside a field, typically Accessibility still needs the position of each & every layout character • SwSpecialPos helps with this
a cache? All portions inside a text frame are in SwCache, so we limit memory usage by not storing all portions of a long document At the same time, always possible to re-create these portions Kind of a cache
Visit the tree by following the upper, lower, next and previous pointers SwFlowFrame is not an SwFrame • Follow/precede pointers there, AKA previous leaf, next leaf Split frames: first is master, everybody else is a follow
codebase Take notes as you work in a problem, otherwise you won’t solve the bug • https://people.gnome.org/~michael/data/2016-04-29-solvi ng-problems.pdf Use the layout XML dump Once the problem is fixed, always cover your fix with a test