SVGPathElement.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <LibGfx/Bitmap.h>
  8. #include <LibWeb/HTML/HTMLElement.h>
  9. #include <LibWeb/SVG/SVGGeometryElement.h>
  10. namespace Web::SVG {
  11. enum class PathInstructionType {
  12. Move,
  13. ClosePath,
  14. Line,
  15. HorizontalLine,
  16. VerticalLine,
  17. Curve,
  18. SmoothCurve,
  19. QuadraticBezierCurve,
  20. SmoothQuadraticBezierCurve,
  21. EllipticalArc,
  22. Invalid,
  23. };
  24. struct PathInstruction {
  25. PathInstructionType type;
  26. bool absolute;
  27. Vector<float> data;
  28. };
  29. class PathDataParser final {
  30. public:
  31. PathDataParser(const String& source);
  32. ~PathDataParser() = default;
  33. Vector<PathInstruction> parse();
  34. private:
  35. void parse_drawto();
  36. void parse_moveto();
  37. void parse_closepath();
  38. void parse_lineto();
  39. void parse_horizontal_lineto();
  40. void parse_vertical_lineto();
  41. void parse_curveto();
  42. void parse_smooth_curveto();
  43. void parse_quadratic_bezier_curveto();
  44. void parse_smooth_quadratic_bezier_curveto();
  45. void parse_elliptical_arc();
  46. float parse_coordinate();
  47. Vector<float> parse_coordinate_pair();
  48. Vector<float> parse_coordinate_sequence();
  49. Vector<Vector<float>> parse_coordinate_pair_sequence();
  50. Vector<float> parse_coordinate_pair_double();
  51. Vector<float> parse_coordinate_pair_triplet();
  52. Vector<float> parse_elliptical_arg_argument();
  53. void parse_whitespace(bool must_match_once = false);
  54. void parse_comma_whitespace();
  55. float parse_fractional_constant();
  56. float parse_number();
  57. float parse_flag();
  58. // -1 if negative, +1 otherwise
  59. int parse_sign();
  60. bool match_whitespace() const;
  61. bool match_comma_whitespace() const;
  62. bool match_coordinate() const;
  63. bool match(char c) const { return !done() && ch() == c; }
  64. bool done() const { return m_cursor >= m_source.length(); }
  65. char ch() const { return m_source[m_cursor]; }
  66. char consume() { return m_source[m_cursor++]; }
  67. String m_source;
  68. size_t m_cursor { 0 };
  69. Vector<PathInstruction> m_instructions;
  70. };
  71. class SVGPathElement final : public SVGGeometryElement {
  72. public:
  73. using WrapperType = Bindings::SVGPathElementWrapper;
  74. SVGPathElement(DOM::Document&, QualifiedName);
  75. virtual ~SVGPathElement() override = default;
  76. virtual RefPtr<Layout::Node> create_layout_node() override;
  77. virtual void parse_attribute(const FlyString& name, const String& value) override;
  78. Gfx::Path& get_path();
  79. private:
  80. Vector<PathInstruction> m_instructions;
  81. Gfx::FloatPoint m_previous_control_point = {};
  82. Optional<Gfx::Path> m_path;
  83. };
  84. }