mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Bug 1647851 Part 2 - Apply CSS page-size when printing r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D115843
This commit is contained in:
parent
82b5e35dae
commit
d3535c7be9
@ -49,12 +49,13 @@ nsPageFrame::~nsPageFrame() = default;
|
||||
|
||||
nsReflowStatus nsPageFrame::ReflowPageContent(
|
||||
nsPresContext* aPresContext, const ReflowInput& aPageReflowInput) {
|
||||
nsIFrame* const frame = PageContentFrame();
|
||||
// XXX Pay attention to the page's border and padding...
|
||||
//
|
||||
// Reflow our ::-moz-page-content frame, allowing it only to be as big as we
|
||||
// are (minus margins).
|
||||
nsIFrame* const frame = PageContentFrame();
|
||||
nsSize maxSize = aPresContext->GetPageSize();
|
||||
nsSize maxSize = ComputePageSize();
|
||||
|
||||
float scale = aPresContext->GetPageScale();
|
||||
// When the reflow size is NS_UNCONSTRAINEDSIZE it means we are reflowing
|
||||
// a single page to print selection. So this means we want to use
|
||||
@ -475,8 +476,8 @@ static std::tuple<uint32_t, uint32_t> GetRowAndColFromIdx(uint32_t aIdxOnSheet,
|
||||
}
|
||||
|
||||
// Helper for BuildDisplayList:
|
||||
static gfx::Matrix4x4 ComputePagesPerSheetTransform(const nsIFrame* aFrame,
|
||||
float aAppUnitsPerPixel) {
|
||||
static gfx::Matrix4x4 ComputePagesPerSheetAndPageSizeTransform(
|
||||
const nsIFrame* aFrame, float aAppUnitsPerPixel) {
|
||||
MOZ_ASSERT(aFrame->IsPageFrame());
|
||||
auto* pageFrame = static_cast<const nsPageFrame*>(aFrame);
|
||||
|
||||
@ -487,10 +488,31 @@ static gfx::Matrix4x4 ComputePagesPerSheetTransform(const nsIFrame* aFrame,
|
||||
uint32_t rowIdx = 0;
|
||||
uint32_t colIdx = 0;
|
||||
|
||||
// Compute scaling due to a possible mismatch in the paper size we are
|
||||
// printing to (from the pres context) and the specified page size when the
|
||||
// content uses "@page {size: ...}" to specify a page size for the content.
|
||||
const nsSize actualPaperSize = pageFrame->PresContext()->GetPageSize();
|
||||
const nsSize contentPageSize = pageFrame->ComputePageSize();
|
||||
{
|
||||
nscoord contentPageHeight = contentPageSize.height;
|
||||
// Scale down if the target is too wide.
|
||||
if (contentPageSize.width > actualPaperSize.width) {
|
||||
scale *= float(actualPaperSize.width) / float(contentPageSize.width);
|
||||
contentPageHeight = NSToCoordRound(contentPageHeight * scale);
|
||||
}
|
||||
// Scale down if the target is too tall.
|
||||
if (contentPageHeight > actualPaperSize.height) {
|
||||
scale *= float(actualPaperSize.height) / float(contentPageHeight);
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(
|
||||
scale <= 1.0f,
|
||||
"Page-size mismatches should only have caused us to scale down, not up.");
|
||||
|
||||
if (nsSharedPageData* pd = pageFrame->GetSharedPageData()) {
|
||||
const auto* ppsInfo = pd->PagesPerSheetInfo();
|
||||
if (ppsInfo->mNumPages > 1) {
|
||||
scale = pd->mPagesPerSheetScale;
|
||||
scale *= pd->mPagesPerSheetScale;
|
||||
gridOrigin = pd->mPagesPerSheetGridOrigin;
|
||||
std::tie(rowIdx, colIdx) = GetRowAndColFromIdx(pageFrame->IndexOnSheet(),
|
||||
pd->mPagesPerSheetNumCols);
|
||||
@ -501,10 +523,12 @@ static gfx::Matrix4x4 ComputePagesPerSheetTransform(const nsIFrame* aFrame,
|
||||
auto transform = gfx::Matrix4x4::Scaling(scale, scale, 1);
|
||||
|
||||
// Draw the page at an offset, to get it in its pages-per-sheet "cell":
|
||||
nsSize pageSize = pageFrame->PresContext()->GetPageSize();
|
||||
transform.PreTranslate(
|
||||
NSAppUnitsToFloatPixels(colIdx * pageSize.width, aAppUnitsPerPixel),
|
||||
NSAppUnitsToFloatPixels(rowIdx * pageSize.height, aAppUnitsPerPixel), 0);
|
||||
NSAppUnitsToFloatPixels(colIdx * contentPageSize.width,
|
||||
aAppUnitsPerPixel),
|
||||
NSAppUnitsToFloatPixels(rowIdx * contentPageSize.height,
|
||||
aAppUnitsPerPixel),
|
||||
0);
|
||||
|
||||
// Also add the grid origin as an offset (so that we're not drawing into the
|
||||
// sheet's unwritable area). Note that this is a PostTranslate operation
|
||||
@ -517,10 +541,10 @@ static gfx::Matrix4x4 ComputePagesPerSheetTransform(const nsIFrame* aFrame,
|
||||
}
|
||||
|
||||
nsIFrame::ComputeTransformFunction nsPageFrame::GetTransformGetter() const {
|
||||
return ComputePagesPerSheetTransform;
|
||||
return ComputePagesPerSheetAndPageSizeTransform;
|
||||
}
|
||||
|
||||
nsPageContentFrame* nsPageFrame::PageContentFrame() {
|
||||
nsPageContentFrame* nsPageFrame::PageContentFrame() const {
|
||||
nsIFrame* const frame = mFrames.FirstChild();
|
||||
MOZ_ASSERT(frame, "pageFrame must have one child");
|
||||
MOZ_ASSERT(frame->IsPageContentFrame(),
|
||||
@ -528,6 +552,37 @@ nsPageContentFrame* nsPageFrame::PageContentFrame() {
|
||||
return static_cast<nsPageContentFrame*>(frame);
|
||||
}
|
||||
|
||||
nsSize nsPageFrame::ComputePageSize() const {
|
||||
const nsPageContentFrame* const pcf = PageContentFrame();
|
||||
nsSize size = PresContext()->GetPageSize();
|
||||
|
||||
// Compute the expected page-size.
|
||||
const nsStylePage* const stylePage = pcf->StylePage();
|
||||
const StylePageSize& pageSize = stylePage->mSize;
|
||||
|
||||
if (pageSize.IsSize()) {
|
||||
// Use the specified size
|
||||
return nsSize{pageSize.AsSize().width.ToAppUnits(),
|
||||
pageSize.AsSize().height.ToAppUnits()};
|
||||
}
|
||||
if (pageSize.IsOrientation()) {
|
||||
// Ensure the correct orientation is applied.
|
||||
if (pageSize.AsOrientation() == StyleOrientation::Portrait) {
|
||||
if (size.width > size.height) {
|
||||
std::swap(size.width, size.height);
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(pageSize.AsOrientation() == StyleOrientation::Landscape);
|
||||
if (size.width < size.height) {
|
||||
std::swap(size.width, size.height);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(pageSize.IsAuto(), "Impossible page-size value?");
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
void nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists) {
|
||||
nsPresContext* pc = PresContext();
|
||||
@ -578,7 +633,7 @@ void nsPageFrame::PaintHeaderFooter(gfxContext& aRenderingContext, nsPoint aPt,
|
||||
bool aDisableSubpixelAA) {
|
||||
nsPresContext* pc = PresContext();
|
||||
|
||||
nsRect rect(aPt, mRect.Size());
|
||||
nsRect rect(aPt, ComputePageSize());
|
||||
aRenderingContext.SetColor(sRGBColor::OpaqueBlack());
|
||||
|
||||
DrawTargetAutoDisableSubpixelAntialiasing disable(
|
||||
|
@ -68,7 +68,9 @@ class nsPageFrame final : public nsContainerFrame {
|
||||
|
||||
ComputeTransformFunction GetTransformGetter() const override;
|
||||
|
||||
nsPageContentFrame* PageContentFrame();
|
||||
nsPageContentFrame* PageContentFrame() const;
|
||||
|
||||
nsSize ComputePageSize() const;
|
||||
|
||||
protected:
|
||||
explicit nsPageFrame(ComputedStyle* aStyle, nsPresContext* aPresContext);
|
||||
|
Loading…
Reference in New Issue
Block a user