mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-10 13:00:29 +03:00
360c0eb509
In general it is not safe to convert any arbitrary floating-point value to CSSPixels. CSSPixels has a resolution of 0.015625, which for small values (e.g. scale factors between 0 and 1), can produce bad results if converted to CSSPixels then scaled back up. In the worst case values can underflow to zero and produce incorrect results.
115 lines
3.0 KiB
C++
115 lines
3.0 KiB
C++
/*
|
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/DeprecatedString.h>
|
|
#include <AK/Format.h>
|
|
#include <LibWeb/Forward.h>
|
|
#include <LibWeb/PixelUnits.h>
|
|
|
|
namespace Web::Layout {
|
|
|
|
class AvailableSize {
|
|
public:
|
|
enum class Type {
|
|
Definite,
|
|
Indefinite,
|
|
MinContent,
|
|
MaxContent,
|
|
};
|
|
|
|
static AvailableSize make_definite(CSSPixels);
|
|
static AvailableSize make_indefinite();
|
|
static AvailableSize make_min_content();
|
|
static AvailableSize make_max_content();
|
|
|
|
bool is_definite() const { return m_type == Type::Definite; }
|
|
bool is_indefinite() const { return m_type == Type::Indefinite; }
|
|
bool is_min_content() const { return m_type == Type::MinContent; }
|
|
bool is_max_content() const { return m_type == Type::MaxContent; }
|
|
bool is_intrinsic_sizing_constraint() const { return is_min_content() || is_max_content(); }
|
|
|
|
CSSPixels to_px_or_zero() const
|
|
{
|
|
if (!is_definite())
|
|
return 0;
|
|
return m_value;
|
|
}
|
|
|
|
DeprecatedString to_deprecated_string() const;
|
|
|
|
bool operator==(AvailableSize const& other) const = default;
|
|
bool operator<(AvailableSize const& other) const { return m_value < other.m_value; }
|
|
|
|
private:
|
|
AvailableSize(Type type, CSSPixels);
|
|
|
|
Type m_type {};
|
|
CSSPixels m_value {};
|
|
};
|
|
|
|
inline bool operator>(CSSPixels left, AvailableSize const& right)
|
|
{
|
|
if (right.is_max_content() || right.is_indefinite())
|
|
return false;
|
|
if (right.is_min_content())
|
|
return true;
|
|
return left > right.to_px_or_zero();
|
|
}
|
|
|
|
inline bool operator<(CSSPixels left, AvailableSize const& right)
|
|
{
|
|
if (right.is_max_content() || right.is_indefinite())
|
|
return true;
|
|
if (right.is_min_content())
|
|
return false;
|
|
return left < right.to_px_or_zero();
|
|
}
|
|
|
|
inline bool operator<(AvailableSize const& left, CSSPixels right)
|
|
{
|
|
if (left.is_min_content())
|
|
return true;
|
|
if (left.is_max_content() || left.is_indefinite())
|
|
return false;
|
|
return left.to_px_or_zero() < right;
|
|
}
|
|
|
|
class AvailableSpace {
|
|
public:
|
|
AvailableSpace(AvailableSize w, AvailableSize h)
|
|
: width(move(w))
|
|
, height(move(h))
|
|
{
|
|
}
|
|
|
|
bool operator==(AvailableSpace const& other) const = default;
|
|
|
|
AvailableSize width;
|
|
AvailableSize height;
|
|
|
|
DeprecatedString to_deprecated_string() const;
|
|
};
|
|
|
|
}
|
|
|
|
template<>
|
|
struct AK::Formatter<Web::Layout::AvailableSize> : Formatter<StringView> {
|
|
ErrorOr<void> format(FormatBuilder& builder, Web::Layout::AvailableSize const& available_size)
|
|
{
|
|
return Formatter<StringView>::format(builder, available_size.to_deprecated_string());
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct AK::Formatter<Web::Layout::AvailableSpace> : Formatter<StringView> {
|
|
ErrorOr<void> format(FormatBuilder& builder, Web::Layout::AvailableSpace const& available_space)
|
|
{
|
|
return Formatter<StringView>::format(builder, available_space.to_deprecated_string());
|
|
}
|
|
};
|