AttributeParser.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
  3. * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
  4. * Copyright (c) 2024, Tim Ledbetter <timledbetter@gmail.com>
  5. *
  6. * SPDX-License-Identifier: BSD-2-Clause
  7. */
  8. #pragma once
  9. #include <AK/GenericLexer.h>
  10. #include <AK/Variant.h>
  11. #include <AK/Vector.h>
  12. #include <LibGfx/Point.h>
  13. namespace Web::SVG {
  14. enum class PathInstructionType {
  15. Move,
  16. ClosePath,
  17. Line,
  18. HorizontalLine,
  19. VerticalLine,
  20. Curve,
  21. SmoothCurve,
  22. QuadraticBezierCurve,
  23. SmoothQuadraticBezierCurve,
  24. EllipticalArc,
  25. Invalid,
  26. };
  27. struct PathInstruction {
  28. PathInstructionType type;
  29. bool absolute;
  30. Vector<float> data;
  31. };
  32. struct Transform {
  33. struct Translate {
  34. float x;
  35. float y;
  36. };
  37. struct Scale {
  38. float x;
  39. float y;
  40. };
  41. struct Rotate {
  42. float a;
  43. float x;
  44. float y;
  45. };
  46. struct SkewX {
  47. float a;
  48. };
  49. struct SkewY {
  50. float a;
  51. };
  52. struct Matrix {
  53. float a;
  54. float b;
  55. float c;
  56. float d;
  57. float e;
  58. float f;
  59. };
  60. using Operation = Variant<Translate, Scale, Rotate, SkewX, SkewY, Matrix>;
  61. Operation operation;
  62. };
  63. struct PreserveAspectRatio {
  64. enum class Align {
  65. None,
  66. xMinYMin,
  67. xMidYMin,
  68. xMaxYMin,
  69. xMinYMid,
  70. xMidYMid,
  71. xMaxYMid,
  72. xMinYMax,
  73. xMidYMax,
  74. xMaxYMax
  75. };
  76. enum class MeetOrSlice {
  77. Meet,
  78. Slice
  79. };
  80. Align align { Align::xMidYMid };
  81. MeetOrSlice meet_or_slice { MeetOrSlice::Meet };
  82. };
  83. enum class SVGUnits {
  84. ObjectBoundingBox,
  85. UserSpaceOnUse
  86. };
  87. using GradientUnits = SVGUnits;
  88. using MaskUnits = SVGUnits;
  89. using MaskContentUnits = SVGUnits;
  90. enum class SpreadMethod {
  91. Pad,
  92. Repeat,
  93. Reflect
  94. };
  95. class NumberPercentage {
  96. public:
  97. NumberPercentage(float value, bool is_percentage)
  98. : m_value(is_percentage ? value / 100 : value)
  99. , m_is_percentage(is_percentage)
  100. {
  101. }
  102. static NumberPercentage create_percentage(float value)
  103. {
  104. return NumberPercentage(value, true);
  105. }
  106. static NumberPercentage create_number(float value)
  107. {
  108. return NumberPercentage(value, false);
  109. }
  110. float resolve_relative_to(float length) const;
  111. float value() const { return m_value; }
  112. private:
  113. float m_value;
  114. bool m_is_percentage { false };
  115. };
  116. enum class FillRule {
  117. Nonzero,
  118. Evenodd
  119. };
  120. enum class TextAnchor {
  121. Start,
  122. Middle,
  123. End
  124. };
  125. class AttributeParser final {
  126. public:
  127. ~AttributeParser() = default;
  128. static Optional<float> parse_coordinate(StringView input);
  129. static Optional<float> parse_length(StringView input);
  130. static Optional<NumberPercentage> parse_number_percentage(StringView input);
  131. static Optional<float> parse_positive_length(StringView input);
  132. static Vector<Gfx::FloatPoint> parse_points(StringView input);
  133. static Vector<PathInstruction> parse_path_data(StringView input);
  134. static Optional<Vector<Transform>> parse_transform(StringView input);
  135. static Optional<PreserveAspectRatio> parse_preserve_aspect_ratio(StringView input);
  136. static Optional<SVGUnits> parse_units(StringView input);
  137. static Optional<SpreadMethod> parse_spread_method(StringView input);
  138. private:
  139. AttributeParser(StringView source);
  140. ErrorOr<void> parse_drawto();
  141. ErrorOr<void> parse_moveto();
  142. void parse_closepath();
  143. ErrorOr<void> parse_lineto();
  144. ErrorOr<void> parse_horizontal_lineto();
  145. ErrorOr<void> parse_vertical_lineto();
  146. ErrorOr<void> parse_curveto();
  147. ErrorOr<void> parse_smooth_curveto();
  148. ErrorOr<void> parse_quadratic_bezier_curveto();
  149. ErrorOr<void> parse_smooth_quadratic_bezier_curveto();
  150. ErrorOr<void> parse_elliptical_arc();
  151. Optional<Vector<Transform>> parse_transform();
  152. ErrorOr<float> parse_length();
  153. ErrorOr<float> parse_coordinate();
  154. ErrorOr<Vector<float>> parse_coordinate_pair();
  155. ErrorOr<Vector<float>> parse_coordinate_sequence();
  156. ErrorOr<Vector<Vector<float>>> parse_coordinate_pair_sequence();
  157. ErrorOr<Vector<float>> parse_coordinate_pair_double();
  158. ErrorOr<Vector<float>> parse_coordinate_pair_triplet();
  159. ErrorOr<Vector<float>> parse_elliptical_arc_argument();
  160. void parse_whitespace(bool must_match_once = false);
  161. void parse_comma_whitespace();
  162. ErrorOr<float> parse_number();
  163. ErrorOr<float> parse_nonnegative_number();
  164. ErrorOr<float> parse_flag();
  165. // -1 if negative, +1 otherwise
  166. int parse_sign();
  167. bool match_whitespace() const;
  168. bool match_comma_whitespace() const;
  169. bool match_coordinate() const;
  170. bool match_length() const;
  171. bool match_number() const;
  172. bool match(char c) const { return !done() && ch() == c; }
  173. bool done() const { return m_lexer.is_eof(); }
  174. char ch(size_t offset = 0) const { return m_lexer.peek(offset); }
  175. char consume() { return m_lexer.consume(); }
  176. GenericLexer m_lexer;
  177. Vector<PathInstruction> m_instructions;
  178. };
  179. }