mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-12 10:40:39 +09:00
LibWeb: Move PositionValue into its own files
It's in Position.{h,cpp} because it represents a <position> in CSS, even though it's currently named PositionValue to avoid collisions.
This commit is contained in:
parent
bcebca62d3
commit
d64ddeaec4
Notes:
sideshowbarker
2024-07-16 23:52:22 +09:00
Author: https://github.com/AtkinsSJ
Commit: d64ddeaec4
Pull-request: https://github.com/SerenityOS/serenity/pull/18104
8 changed files with 165 additions and 133 deletions
|
@ -52,6 +52,7 @@ set(SOURCES
|
|||
CSS/Parser/Token.cpp
|
||||
CSS/Parser/Tokenizer.cpp
|
||||
CSS/Percentage.cpp
|
||||
CSS/Position.cpp
|
||||
CSS/PreferredColorScheme.cpp
|
||||
CSS/Ratio.cpp
|
||||
CSS/Resolution.cpp
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <LibWeb/CSS/Parser/Rule.h>
|
||||
#include <LibWeb/CSS/Parser/TokenStream.h>
|
||||
#include <LibWeb/CSS/Parser/Tokenizer.h>
|
||||
#include <LibWeb/CSS/Position.h>
|
||||
#include <LibWeb/CSS/PropertyID.h>
|
||||
#include <LibWeb/CSS/Ratio.h>
|
||||
#include <LibWeb/CSS/Selector.h>
|
||||
|
|
108
Userland/Libraries/LibWeb/CSS/Position.cpp
Normal file
108
Userland/Libraries/LibWeb/CSS/Position.cpp
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "Position.h"
|
||||
#include <LibGfx/Point.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibWeb/CSS/StyleValue.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
CSSPixelPoint PositionValue::resolved(Layout::Node const& node, CSSPixelRect const& rect) const
|
||||
{
|
||||
// Note: A preset + a none default x/y_relative_to is impossible in the syntax (and makes little sense)
|
||||
CSSPixels x = horizontal_position.visit(
|
||||
[&](HorizontalPreset preset) -> CSSPixels {
|
||||
return rect.width() * [&] {
|
||||
switch (preset) {
|
||||
case HorizontalPreset::Left:
|
||||
return 0.0f;
|
||||
case HorizontalPreset::Center:
|
||||
return 0.5f;
|
||||
case HorizontalPreset::Right:
|
||||
return 1.0f;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}();
|
||||
},
|
||||
[&](LengthPercentage length_percentage) -> CSSPixels {
|
||||
return length_percentage.resolved(node, Length::make_px(rect.width())).to_px(node);
|
||||
});
|
||||
CSSPixels y = vertical_position.visit(
|
||||
[&](VerticalPreset preset) -> CSSPixels {
|
||||
return rect.height() * [&] {
|
||||
switch (preset) {
|
||||
case VerticalPreset::Top:
|
||||
return 0.0f;
|
||||
case VerticalPreset::Center:
|
||||
return 0.5f;
|
||||
case VerticalPreset::Bottom:
|
||||
return 1.0f;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}();
|
||||
},
|
||||
[&](LengthPercentage length_percentage) -> CSSPixels {
|
||||
return length_percentage.resolved(node, Length::make_px(rect.height())).to_px(node);
|
||||
});
|
||||
if (x_relative_to == HorizontalEdge::Right)
|
||||
x = rect.width() - x;
|
||||
if (y_relative_to == VerticalEdge::Bottom)
|
||||
y = rect.height() - y;
|
||||
return CSSPixelPoint { rect.x() + x, rect.y() + y };
|
||||
}
|
||||
|
||||
ErrorOr<void> PositionValue::serialize(StringBuilder& builder) const
|
||||
{
|
||||
// Note: This means our serialization with simplify any with explicit edges that are just `top left`.
|
||||
bool has_relative_edges = x_relative_to == HorizontalEdge::Right || y_relative_to == VerticalEdge::Bottom;
|
||||
if (has_relative_edges)
|
||||
TRY(builder.try_append(x_relative_to == HorizontalEdge::Left ? "left "sv : "right "sv));
|
||||
TRY(horizontal_position.visit(
|
||||
[&](HorizontalPreset preset) -> ErrorOr<void> {
|
||||
return builder.try_append([&] {
|
||||
switch (preset) {
|
||||
case HorizontalPreset::Left:
|
||||
return "left"sv;
|
||||
case HorizontalPreset::Center:
|
||||
return "center"sv;
|
||||
case HorizontalPreset::Right:
|
||||
return "right"sv;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}());
|
||||
},
|
||||
[&](LengthPercentage length_percentage) -> ErrorOr<void> {
|
||||
return builder.try_appendff(TRY(length_percentage.to_string()));
|
||||
}));
|
||||
TRY(builder.try_append(' '));
|
||||
if (has_relative_edges)
|
||||
TRY(builder.try_append(y_relative_to == VerticalEdge::Top ? "top "sv : "bottom "sv));
|
||||
TRY(vertical_position.visit(
|
||||
[&](VerticalPreset preset) -> ErrorOr<void> {
|
||||
return builder.try_append([&] {
|
||||
switch (preset) {
|
||||
case VerticalPreset::Top:
|
||||
return "top"sv;
|
||||
case VerticalPreset::Center:
|
||||
return "center"sv;
|
||||
case VerticalPreset::Bottom:
|
||||
return "bottom"sv;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}());
|
||||
},
|
||||
[&](LengthPercentage length_percentage) -> ErrorOr<void> {
|
||||
return builder.try_append(TRY(length_percentage.to_string()));
|
||||
}));
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
53
Userland/Libraries/LibWeb/CSS/Position.h
Normal file
53
Userland/Libraries/LibWeb/CSS/Position.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/CSS/Percentage.h>
|
||||
#include <LibWeb/PixelUnits.h>
|
||||
|
||||
namespace Web::CSS {
|
||||
|
||||
// FIXME: Named PositionValue to avoid conflicts with enums, but this represents a <position>
|
||||
struct PositionValue {
|
||||
enum class HorizontalPreset {
|
||||
Left,
|
||||
Center,
|
||||
Right
|
||||
};
|
||||
|
||||
enum class VerticalPreset {
|
||||
Top,
|
||||
Center,
|
||||
Bottom
|
||||
};
|
||||
|
||||
enum class HorizontalEdge {
|
||||
Left,
|
||||
Right
|
||||
};
|
||||
|
||||
enum class VerticalEdge {
|
||||
Top,
|
||||
Bottom
|
||||
};
|
||||
|
||||
static PositionValue center()
|
||||
{
|
||||
return PositionValue { HorizontalPreset::Center, VerticalPreset::Center };
|
||||
}
|
||||
|
||||
Variant<HorizontalPreset, LengthPercentage> horizontal_position { HorizontalPreset::Left };
|
||||
Variant<VerticalPreset, LengthPercentage> vertical_position { VerticalPreset::Top };
|
||||
HorizontalEdge x_relative_to { HorizontalEdge::Left };
|
||||
VerticalEdge y_relative_to { VerticalEdge::Top };
|
||||
|
||||
CSSPixelPoint resolved(Layout::Node const& node, CSSPixelRect const& rect) const;
|
||||
ErrorOr<void> serialize(StringBuilder&) const;
|
||||
bool operator==(PositionValue const&) const = default;
|
||||
};
|
||||
|
||||
}
|
|
@ -1021,100 +1021,6 @@ CalculatedStyleValue::CalculationResult CalculatedStyleValue::CalcNumberSumPartW
|
|||
return value->resolve(layout_node, percentage_basis);
|
||||
}
|
||||
|
||||
CSSPixelPoint PositionValue::resolved(Layout::Node const& node, CSSPixelRect const& rect) const
|
||||
{
|
||||
// Note: A preset + a none default x/y_relative_to is impossible in the syntax (and makes little sense)
|
||||
CSSPixels x = horizontal_position.visit(
|
||||
[&](HorizontalPreset preset) -> CSSPixels {
|
||||
return rect.width() * [&] {
|
||||
switch (preset) {
|
||||
case HorizontalPreset::Left:
|
||||
return 0.0f;
|
||||
case HorizontalPreset::Center:
|
||||
return 0.5f;
|
||||
case HorizontalPreset::Right:
|
||||
return 1.0f;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}();
|
||||
},
|
||||
[&](LengthPercentage length_percentage) -> CSSPixels {
|
||||
return length_percentage.resolved(node, Length::make_px(rect.width())).to_px(node);
|
||||
});
|
||||
CSSPixels y = vertical_position.visit(
|
||||
[&](VerticalPreset preset) -> CSSPixels {
|
||||
return rect.height() * [&] {
|
||||
switch (preset) {
|
||||
case VerticalPreset::Top:
|
||||
return 0.0f;
|
||||
case VerticalPreset::Center:
|
||||
return 0.5f;
|
||||
case VerticalPreset::Bottom:
|
||||
return 1.0f;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}();
|
||||
},
|
||||
[&](LengthPercentage length_percentage) -> CSSPixels {
|
||||
return length_percentage.resolved(node, Length::make_px(rect.height())).to_px(node);
|
||||
});
|
||||
if (x_relative_to == HorizontalEdge::Right)
|
||||
x = rect.width() - x;
|
||||
if (y_relative_to == VerticalEdge::Bottom)
|
||||
y = rect.height() - y;
|
||||
return CSSPixelPoint { rect.x() + x, rect.y() + y };
|
||||
}
|
||||
|
||||
ErrorOr<void> PositionValue::serialize(StringBuilder& builder) const
|
||||
{
|
||||
// Note: This means our serialization with simplify any with explicit edges that are just `top left`.
|
||||
bool has_relative_edges = x_relative_to == HorizontalEdge::Right || y_relative_to == VerticalEdge::Bottom;
|
||||
if (has_relative_edges)
|
||||
TRY(builder.try_append(x_relative_to == HorizontalEdge::Left ? "left "sv : "right "sv));
|
||||
TRY(horizontal_position.visit(
|
||||
[&](HorizontalPreset preset) -> ErrorOr<void> {
|
||||
return builder.try_append([&] {
|
||||
switch (preset) {
|
||||
case HorizontalPreset::Left:
|
||||
return "left"sv;
|
||||
case HorizontalPreset::Center:
|
||||
return "center"sv;
|
||||
case HorizontalPreset::Right:
|
||||
return "right"sv;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}());
|
||||
},
|
||||
[&](LengthPercentage length_percentage) -> ErrorOr<void> {
|
||||
return builder.try_appendff(TRY(length_percentage.to_string()));
|
||||
}));
|
||||
TRY(builder.try_append(' '));
|
||||
if (has_relative_edges)
|
||||
TRY(builder.try_append(y_relative_to == VerticalEdge::Top ? "top "sv : "bottom "sv));
|
||||
TRY(vertical_position.visit(
|
||||
[&](VerticalPreset preset) -> ErrorOr<void> {
|
||||
return builder.try_append([&] {
|
||||
switch (preset) {
|
||||
case VerticalPreset::Top:
|
||||
return "top"sv;
|
||||
case VerticalPreset::Center:
|
||||
return "center"sv;
|
||||
case VerticalPreset::Bottom:
|
||||
return "bottom"sv;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}());
|
||||
},
|
||||
[&](LengthPercentage length_percentage) -> ErrorOr<void> {
|
||||
return builder.try_append(TRY(length_percentage.to_string()));
|
||||
}));
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<CSS::Length> absolutized_length(CSS::Length const& length, CSSPixelRect const& viewport_rect, Gfx::FontPixelMetrics const& font_metrics, CSSPixels font_size, CSSPixels root_font_size, CSSPixels line_height, CSSPixels root_line_height)
|
||||
{
|
||||
if (length.is_px())
|
||||
|
|
|
@ -36,45 +36,6 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
|
||||
// FIXME: Named PositionValue to avoid conflicts with enums, but this represents a <position>
|
||||
struct PositionValue {
|
||||
enum class HorizontalPreset {
|
||||
Left,
|
||||
Center,
|
||||
Right
|
||||
};
|
||||
|
||||
enum class VerticalPreset {
|
||||
Top,
|
||||
Center,
|
||||
Bottom
|
||||
};
|
||||
|
||||
enum class HorizontalEdge {
|
||||
Left,
|
||||
Right
|
||||
};
|
||||
|
||||
enum class VerticalEdge {
|
||||
Top,
|
||||
Bottom
|
||||
};
|
||||
|
||||
static PositionValue center()
|
||||
{
|
||||
return PositionValue { HorizontalPreset::Center, VerticalPreset::Center };
|
||||
}
|
||||
|
||||
Variant<HorizontalPreset, LengthPercentage> horizontal_position { HorizontalPreset::Left };
|
||||
Variant<VerticalPreset, LengthPercentage> vertical_position { VerticalPreset::Top };
|
||||
HorizontalEdge x_relative_to { HorizontalEdge::Left };
|
||||
VerticalEdge y_relative_to { VerticalEdge::Top };
|
||||
|
||||
CSSPixelPoint resolved(Layout::Node const& node, CSSPixelRect const& rect) const;
|
||||
ErrorOr<void> serialize(StringBuilder&) const;
|
||||
bool operator==(PositionValue const&) const = default;
|
||||
};
|
||||
|
||||
// FIXME: Find a better place for this helper.
|
||||
inline Gfx::Painter::ScalingMode to_gfx_scaling_mode(CSS::ImageRendering css_value)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/CSS/Position.h>
|
||||
#include <LibWeb/CSS/StyleValues/AbstractImageStyleValue.h>
|
||||
#include <LibWeb/Painting/GradientPainting.h>
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <AK/Vector.h>
|
||||
#include <LibWeb/CSS/Enums.h>
|
||||
#include <LibWeb/CSS/Position.h>
|
||||
#include <LibWeb/CSS/StyleValues/AbstractImageStyleValue.h>
|
||||
#include <LibWeb/Painting/GradientPainting.h>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue