ladybird/Userland/Libraries/LibWeb/Layout/AvailableSpace.h
Andreas Kling 9c44634ca5 LibWeb: Reorganize layout algorithms around available space
This is a big and messy change, and here's the gist:

- AvaliableSpace is now 2x AvailableSize (width and height)

- Layout algorithms are redesigned around the idea of available space

- When doing layout across nested formatting contexts, the parent
  context tells the child context how much space is available for the
  child's root box in both axes.

- "Available space" replaces "containing block width" in most places.

- The width and height in a box's UsedValues are considered to be
  definite after they're assigned to. Marking something as having
  definite size is no longer a separate step,

This probably introduces various regressions, but the big win here is
that our layout system now works with available space, just like the
specs are written. Fixing issues will be much easier going forward,
since you don't need to do nearly as much conversion from "spec logic"
to "LibWeb logic" as you previously did.
2022-10-02 21:14:02 +02:00

87 lines
2.0 KiB
C++

/*
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Format.h>
#include <AK/String.h>
#include <LibWeb/Forward.h>
namespace Web::Layout {
class AvailableSize {
public:
enum class Type {
Definite,
Indefinite,
MinContent,
MaxContent,
};
static AvailableSize make_definite(float);
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(); }
float to_px() const
{
return m_value;
}
float to_px_or_zero() const
{
if (!is_definite())
return 0.0f;
return m_value;
}
String to_string() const;
private:
AvailableSize(Type type, float);
Type m_type {};
float m_value {};
};
class AvailableSpace {
public:
AvailableSpace(AvailableSize w, AvailableSize h)
: width(move(w))
, height(move(h))
{
}
AvailableSize width;
AvailableSize height;
String to_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_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_string());
}
};