Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Writer layout in Collabora Online

Avatar for Miklos V Miklos V
June 27, 2025
0

Writer layout in Collabora Online

Avatar for Miklos V

Miklos V

June 27, 2025
Tweet

Transcript

  1. 5 Page frame Parent: root frame  Without a corresponding

    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
  2. 6 Text frame Typical parent: body frame  Most important

    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
  3. 7 Frame area, frame print area It’s all about margins

     Frame area • Absolute rectangle, includes the margins  Frame print area • Relative rectangle, excludes the margins
  4. 8 Layout frame Frame with children are layout frames 

    Normal SwFrame has no lowers  Examples: body frame, table frame
  5. 9 Flow frame Allowed to split:  Derived not only

    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
  6. 10 Anchored objects Fly or draw  An anchored object:

    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)
  7. 11 Layout algorithm Heavily simplified  First goal: determine the

    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
  8. 12 Relationship: nodes and frames Model and view  SwModify:

    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
  9. 13 Creation of frames MakeFrames() at some SwNode classes 

    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
  10. 14 Table layout Table, headers, rows, cells  Table frame:

    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
  11. 15 Indexes and Positions Type safety pays off  Paragraph

    index: SwNodeOffset  Inside that: character index  Layout level: text frame index, TextFrameIndex • Again, important for hidden redlines
  12. 17 Coordinate system All frames are in absolute units 

    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
  13. 19 Fonts Script type adds complexity  SwFont is actually

    3 fonts  SubSubFont is 1 font  Separate for Latin, CTL and CJK script types  Layout goes with the relevant font, automatically
  14. 20 How incremental update works An example (simplified)  Insert

    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
  15. 21 Model vs View positions Canvas coordinates ↔ paragraph numbers

     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
  16. 22 Field layout A single character, except when not 

    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
  17. 23 Caches A speed vs memory trade-off  Is SwCache

    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
  18. 25 Layout tree navigation What wasn’t mentioned so far 

    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
  19. 26 Working with the layout A complex part of the

    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
  20. 27 Further reading OOo wiki & in-code documentation  https://web.archive.org/web/20240703103909/https://wiki.openo

    ffice.org/wiki/Writer/Core_And_Layout  https://web.archive.org/web/20240703234819/https://wiki.openo ffice.org/wiki/Writer/Text_Formatting  Core.git sw/README.md