/src/serenity/Userland/Libraries/LibWeb/Layout/ImageBox.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2018-2022, Andreas Kling <kling@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <LibWeb/HTML/BrowsingContext.h> |
8 | | #include <LibWeb/HTML/DecodedImageData.h> |
9 | | #include <LibWeb/Layout/ImageBox.h> |
10 | | #include <LibWeb/Layout/ImageProvider.h> |
11 | | #include <LibWeb/Painting/ImagePaintable.h> |
12 | | #include <LibWeb/Platform/FontPlugin.h> |
13 | | |
14 | | namespace Web::Layout { |
15 | | |
16 | | JS_DEFINE_ALLOCATOR(ImageBox); |
17 | | |
18 | | ImageBox::ImageBox(DOM::Document& document, DOM::Element& element, NonnullRefPtr<CSS::StyleProperties> style, ImageProvider const& image_provider) |
19 | 0 | : ReplacedBox(document, element, move(style)) |
20 | 0 | , m_image_provider(image_provider) |
21 | 0 | { |
22 | 0 | } |
23 | | |
24 | 0 | ImageBox::~ImageBox() = default; |
25 | | |
26 | | void ImageBox::visit_edges(JS::Cell::Visitor& visitor) |
27 | 0 | { |
28 | 0 | Base::visit_edges(visitor); |
29 | 0 | visitor.visit(m_image_provider.to_html_element()); |
30 | 0 | } |
31 | | |
32 | | void ImageBox::prepare_for_replaced_layout() |
33 | 0 | { |
34 | 0 | set_natural_width(m_image_provider.intrinsic_width()); |
35 | 0 | set_natural_height(m_image_provider.intrinsic_height()); |
36 | 0 | set_natural_aspect_ratio(m_image_provider.intrinsic_aspect_ratio()); |
37 | |
|
38 | 0 | if (renders_as_alt_text()) { |
39 | 0 | auto const& element = verify_cast<HTML::HTMLElement>(dom_node()); |
40 | 0 | auto alt = element.get_attribute_value(HTML::AttributeNames::alt); |
41 | |
|
42 | 0 | if (alt.is_empty()) { |
43 | 0 | set_natural_width(0); |
44 | 0 | set_natural_height(0); |
45 | 0 | } else { |
46 | 0 | auto const& font = Platform::FontPlugin::the().default_font(); |
47 | 0 | CSSPixels alt_text_width = 0; |
48 | 0 | if (!m_cached_alt_text_width.has_value()) |
49 | 0 | m_cached_alt_text_width = CSSPixels::nearest_value_for(font.width(alt)); |
50 | 0 | alt_text_width = m_cached_alt_text_width.value(); |
51 | |
|
52 | 0 | set_natural_width(alt_text_width + 16); |
53 | 0 | set_natural_height(CSSPixels::nearest_value_for(font.pixel_size()) + 16); |
54 | 0 | } |
55 | 0 | } |
56 | |
|
57 | 0 | if (!has_natural_width() && !has_natural_height()) { |
58 | | // FIXME: Do something. |
59 | 0 | } |
60 | 0 | } |
61 | | |
62 | | void ImageBox::dom_node_did_update_alt_text(Badge<ImageProvider>) |
63 | 0 | { |
64 | 0 | m_cached_alt_text_width = {}; |
65 | 0 | } |
66 | | |
67 | | bool ImageBox::renders_as_alt_text() const |
68 | 0 | { |
69 | 0 | if (auto const* image_provider = dynamic_cast<ImageProvider const*>(&dom_node())) |
70 | 0 | return !image_provider->is_image_available(); |
71 | 0 | return false; |
72 | 0 | } |
73 | | |
74 | | JS::GCPtr<Painting::Paintable> ImageBox::create_paintable() const |
75 | 0 | { |
76 | 0 | return Painting::ImagePaintable::create(*this); |
77 | 0 | } |
78 | | |
79 | | } |