ImageBox.cpp 2.4 KB

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