blob: 223535f3c0ff2a3214e586d3c4a1e34024e68117 [file] [log] [blame]
/*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "LayoutUnit.h"
#include <optional>
namespace WebCore {
namespace Layout {
struct ComputedVerticalMargin {
std::optional<LayoutUnit> before;
std::optional<LayoutUnit> after;
};
struct UsedVerticalMargin {
struct NonCollapsedValues {
LayoutUnit before;
LayoutUnit after;
};
NonCollapsedValues nonCollapsedValues;
struct CollapsedValues {
std::optional<LayoutUnit> before;
std::optional<LayoutUnit> after;
bool isCollapsedThrough { false };
};
CollapsedValues collapsedValues;
// FIXME: This structure might need to change to indicate that the cached value is not necessarily the same as the box's computed margin value.
// This only matters in case of collapse through margins when they collapse into another sibling box.
// <div style="margin: 1px"></div><div style="margin: 10px"></div> <- the second div's before/after marings collapse through and the same time they collapse into
// the first div. When the parent computes its before margin, it should see the second div's collapsed through margin as the value to collapse width (adjoining margin value).
// So while the first div's before margin is not 10px, the cached value is 10px so that when we compute the parent's margin we just need to check the first
// inflow child's cached margin values.
struct PositiveAndNegativePair {
struct Values {
bool isNonZero() const { return positive.value_or(0) || negative.value_or(0); }
std::optional<LayoutUnit> positive;
std::optional<LayoutUnit> negative;
bool isQuirk { false };
};
Values before;
Values after;
};
PositiveAndNegativePair positiveAndNegativeValues;
};
static inline LayoutUnit marginBefore(const UsedVerticalMargin& usedVerticalMargin)
{
return usedVerticalMargin.collapsedValues.before.value_or(usedVerticalMargin.nonCollapsedValues.before);
}
static inline LayoutUnit marginAfter(const UsedVerticalMargin& usedVerticalMargin)
{
if (usedVerticalMargin.collapsedValues.isCollapsedThrough)
return 0_lu;
return usedVerticalMargin.collapsedValues.after.value_or(usedVerticalMargin.nonCollapsedValues.after);
}
struct ComputedHorizontalMargin {
std::optional<LayoutUnit> start;
std::optional<LayoutUnit> end;
};
struct UsedHorizontalMargin {
LayoutUnit start;
LayoutUnit end;
};
struct PrecomputedMarginBefore {
LayoutUnit usedValue() const { return collapsedValue.value_or(nonCollapsedValue); }
LayoutUnit nonCollapsedValue;
std::optional<LayoutUnit> collapsedValue;
UsedVerticalMargin::PositiveAndNegativePair::Values positiveAndNegativeMarginBefore;
};
}
}
#endif