mirror of
				https://github.com/LadybirdBrowser/ladybird.git
				synced 2025-11-03 23:00:58 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			107 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 * 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>
 | 
						|
 | 
						|
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.to_px(node, rect.width());
 | 
						|
        });
 | 
						|
    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.to_px(node, rect.height());
 | 
						|
        });
 | 
						|
    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 {};
 | 
						|
}
 | 
						|
 | 
						|
}
 |