SVGSVGBox.cpp 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
  3. * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <LibWeb/CSS/Parser/Parser.h>
  8. #include <LibWeb/Layout/ReplacedBox.h>
  9. #include <LibWeb/Layout/SVGGeometryBox.h>
  10. #include <LibWeb/Painting/SVGSVGPaintable.h>
  11. namespace Web::Layout {
  12. SVGSVGBox::SVGSVGBox(DOM::Document& document, SVG::SVGSVGElement& element, NonnullRefPtr<CSS::StyleProperties> properties)
  13. : ReplacedBox(document, element, move(properties))
  14. {
  15. }
  16. JS::GCPtr<Painting::Paintable> SVGSVGBox::create_paintable() const
  17. {
  18. return Painting::SVGSVGPaintable::create(*this);
  19. }
  20. void SVGSVGBox::prepare_for_replaced_layout()
  21. {
  22. // https://www.w3.org/TR/SVG2/coords.html#SizingSVGInCSS
  23. // The intrinsic dimensions must also be determined from the width and height sizing properties.
  24. // If either width or height are not specified, the used value is the initial value 'auto'.
  25. // 'auto' and percentage lengths must not be used to determine an intrinsic width or intrinsic height.
  26. auto const& computed_width = computed_values().width();
  27. if (computed_width.is_length() && !computed_width.contains_percentage()) {
  28. set_natural_width(computed_width.to_px(*this, 0));
  29. }
  30. auto const& computed_height = computed_values().height();
  31. if (computed_height.is_length() && !computed_height.contains_percentage()) {
  32. set_natural_height(computed_height.to_px(*this, 0));
  33. }
  34. set_natural_aspect_ratio(calculate_intrinsic_aspect_ratio());
  35. }
  36. Optional<float> SVGSVGBox::calculate_intrinsic_aspect_ratio() const
  37. {
  38. // https://www.w3.org/TR/SVG2/coords.html#SizingSVGInCSS
  39. // The intrinsic aspect ratio must be calculated using the following algorithm. If the algorithm returns null, then there is no intrinsic aspect ratio.
  40. auto const& computed_width = computed_values().width();
  41. auto const& computed_height = computed_values().height();
  42. // 1. If the width and height sizing properties on the ‘svg’ element are both absolute values:
  43. if (computed_width.is_length() && !computed_width.contains_percentage() && computed_height.is_length() && !computed_height.contains_percentage()) {
  44. auto width = computed_width.to_px(*this, 0);
  45. auto height = computed_height.to_px(*this, 0);
  46. if (width != 0 && height != 0) {
  47. // 1. return width / height
  48. return width.to_double() / height.to_double();
  49. }
  50. return {};
  51. }
  52. // FIXME: 2. If an SVG View is active:
  53. // FIXME: 1. let viewbox be the viewbox defined by the active SVG View
  54. // FIXME: 2. return viewbox.width / viewbox.height
  55. // 3. If the ‘viewBox’ on the ‘svg’ element is correctly specified:
  56. if (dom_node().view_box().has_value()) {
  57. // 1. let viewbox be the viewbox defined by the ‘viewBox’ attribute on the ‘svg’ element
  58. auto const& viewbox = dom_node().view_box().value();
  59. // 2. return viewbox.width / viewbox.height
  60. return viewbox.width / viewbox.height;
  61. }
  62. // 4. return null
  63. return {};
  64. }
  65. }