Sizing.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. /*
  2. * Copyright (c) 2022, MacDue <macdue@dueutil.tech>
  3. * Copyright (c) 2024, Sam Atkins <sam@ladybird.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include "Sizing.h"
  8. namespace Web::CSS {
  9. // https://drafts.csswg.org/css-images/#default-sizing
  10. CSSPixelSize run_default_sizing_algorithm(
  11. Optional<CSSPixels> specified_width, Optional<CSSPixels> specified_height,
  12. Optional<CSSPixels> natural_width, Optional<CSSPixels> natural_height,
  13. Optional<CSSPixelFraction> natural_aspect_ratio,
  14. CSSPixelSize default_size)
  15. {
  16. // If the specified size is a definite width and height, the concrete object size is given that width and height.
  17. if (specified_width.has_value() && specified_height.has_value())
  18. return CSSPixelSize { specified_width.value(), specified_height.value() };
  19. // If the specified size is only a width or height (but not both) then the concrete object size is given that specified width or height.
  20. // The other dimension is calculated as follows:
  21. if (specified_width.has_value() || specified_height.has_value()) {
  22. // 1. If the object has a natural aspect ratio,
  23. // the missing dimension of the concrete object size is calculated using that aspect ratio and the present dimension.
  24. if (natural_aspect_ratio.has_value() && !natural_aspect_ratio->might_be_saturated()) {
  25. if (specified_width.has_value())
  26. return CSSPixelSize { specified_width.value(), (CSSPixels(1) / natural_aspect_ratio.value()) * specified_width.value() };
  27. if (specified_height.has_value())
  28. return CSSPixelSize { specified_height.value() * natural_aspect_ratio.value(), specified_height.value() };
  29. }
  30. // 2. Otherwise, if the missing dimension is present in the object’s natural dimensions,
  31. // the missing dimension is taken from the object’s natural dimensions.
  32. if (specified_height.has_value() && natural_width.has_value())
  33. return CSSPixelSize { natural_width.value(), specified_height.value() };
  34. if (specified_width.has_value() && natural_height.has_value())
  35. return CSSPixelSize { specified_width.value(), natural_height.value() };
  36. // 3. Otherwise, the missing dimension of the concrete object size is taken from the default object size.
  37. if (specified_height.has_value())
  38. return CSSPixelSize { default_size.width(), specified_height.value() };
  39. if (specified_width.has_value())
  40. return CSSPixelSize { specified_width.value(), default_size.height() };
  41. VERIFY_NOT_REACHED();
  42. }
  43. // If the specified size has no constraints:
  44. // 1. If the object has a natural height or width, its size is resolved as if its natural dimensions were given as the specified size.
  45. if (natural_width.has_value() || natural_height.has_value())
  46. return run_default_sizing_algorithm(natural_width, natural_height, natural_width, natural_height, natural_aspect_ratio, default_size);
  47. // FIXME: 2. Otherwise, its size is resolved as a contain constraint against the default object size.
  48. return default_size;
  49. }
  50. }