chromium/third_party/blink/renderer/core/layout/paginated_root_layout_algorithm.h

// 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_