// Copyright 2017 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_PAGINATED_ROOT_LAYOUT_ALGORITHM_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_PAGINATED_ROOT_LAYOUT_ALGORITHM_H_ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/layout/box_fragment_builder.h" #include "third_party/blink/renderer/core/layout/layout_algorithm.h" #include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" namespace blink { class BlockBreakToken; class BlockNode; class ConstraintSpace; struct PageAreaLayoutParams; // This is the root layout algorithm when the document is paginated (for // printing or PDF generation). It creates a series of page box child fragments, // one per page. // // The fragment structure is different when paginating. The root fragment is // generated by the LayoutView, as normally, but then there will be additional // container fragments between the root fragment and the document contents, to // support fragmentation, page properties and margins. // // This algorithm will create page container fragments, one for each page. Each // page container contains a page border box fragment, and fragments for any // page margin boxes (e.g. for author-specified headers and footers). A page // border contains a page area box, which is a fragmentainer, into which // document contents flow. The document root (e.g. <html>) and all descendants // will be placed inside the page area fragmentainers. // // Example: // // <!DOCTYPE html> // <style> // @page { size:600px 800px; margin: 50px; border: 10px solid; } // </style> // <div id="a">...</div> // <div id="b" style="break-before:page; height:100px;"></div> // // Fragment tree: // // LayoutView // Page container 0,0 600x800 // Page border box 50,50 500x700 // Page area 0,0 480x680 // HTML 0,0 480x680 // BODY 8,8 464x672 // DIV id="a" // Line with "..." // Page container 0,0 600x800 // Page border box 50,50 500x700 // Page area 0,0 480x680 // HTML 0,0 480x108 // BODY 8,0 464x100 // DIV id="b" 0,0 464x100 // // A page area can be seen as the content box of a page box, although its offset // doesn't reflect that (there's a 10px page border, but the offset is still // 0,0). A page area fragment (and its entire subtree, which represents some of // the document contents) lives in a different coordinate system than the rest. // // The page container fragments are sized and positioned with respect to the // destination output size. If printing to an actual printer, there's a given // physical paper size, and no @page size can change that fact (the output may // need to be scaled and/or centered on paper). The page border box and page // area, on the other hand, live in the coordinate system established by layout, // which honors @page size, input scale factor from print settings, and // additionally any shrink factor calculated by layout (if some content is too // wide to fit the page size, the layout viewport may be enlarged to prevent it // from overflowing (as much), an thus there needs to be an additional scale // factor to shrink it back down to the destination size). // // Note that, although the page border box is in the coordinate system of layout // as far as scaling is concerned, the page border box *offset* is in the // destination coordinate system. Example: The paper size is 816x1056 (US // Letter). Input scale factor is 2. Margins are 50px on each side. The size of // the page container becomes 816x1056. The offset to the page border box // becomes 50,50. The size of the page border box (and page area) becomes // 358x478 - subtract margins from 816x1056, then divide by 2 (the inverse scale // factor used by layout). // // When painted, the page areas are "stitched" together in the block direction, // so that content that overflows from one page correctly overflows into the // other pages, rather than being lost. Overflowing content may for instance be // tall monolithic content, or transformed elements. // // See also https://drafts.csswg.org/css-page-3/#page-model class CORE_EXPORT PaginatedRootLayoutAlgorithm : public LayoutAlgorithm<BlockNode, BoxFragmentBuilder, BlockBreakToken> { … }; } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_PAGINATED_ROOT_LAYOUT_ALGORITHM_H_