Flutter Impeller
impeller::StrokeRectGeometry Class Referencefinal

#include <rect_geometry.h>

Inheritance diagram for impeller::StrokeRectGeometry:
impeller::Geometry

Public Member Functions

 StrokeRectGeometry (const Rect &rect, const StrokeParameters &stroke)
 
 ~StrokeRectGeometry () override
 
GeometryResult GetPositionBuffer (const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
 
std::optional< RectGetCoverage (const Matrix &transform) const override
 
- Public Member Functions inherited from impeller::Geometry
virtual ~Geometry ()
 
virtual GeometryResult::Mode GetResultMode () const
 
virtual bool CoversArea (const Matrix &transform, const Rect &rect) const
 Determines if this geometry, transformed by the given transform, will completely cover all surface area of the given rect. More...
 
virtual bool IsAxisAlignedRect () const
 
virtual bool CanApplyMaskFilter () const
 
virtual Scalar ComputeAlphaCoverage (const Matrix &transform) const
 

Additional Inherited Members

- Static Public Member Functions inherited from impeller::Geometry
static std::unique_ptr< GeometryMakeFillPath (const flutter::DlPath &path, std::optional< Rect > inner_rect=std::nullopt)
 
static std::unique_ptr< GeometryMakeStrokePath (const flutter::DlPath &path, const StrokeParameters &stroke={})
 
static std::unique_ptr< GeometryMakeCover ()
 
static std::unique_ptr< GeometryMakeRect (const Rect &rect)
 
static std::unique_ptr< GeometryMakeOval (const Rect &rect)
 
static std::unique_ptr< GeometryMakeLine (const Point &p0, const Point &p1, const StrokeParameters &stroke)
 
static std::unique_ptr< GeometryMakeCircle (const Point &center, Scalar radius)
 
static std::unique_ptr< GeometryMakeStrokedCircle (const Point &center, Scalar radius, Scalar stroke_width)
 
static std::unique_ptr< GeometryMakeFilledArc (const Rect &oval_bounds, Degrees start, Degrees sweep, bool include_center)
 
static std::unique_ptr< GeometryMakeStrokedArc (const Rect &oval_bounds, Degrees start, Degrees sweep, const StrokeParameters &stroke)
 
static std::unique_ptr< GeometryMakeRoundRect (const Rect &rect, const Size &radii)
 
static std::unique_ptr< GeometryMakeRoundSuperellipse (const Rect &rect, Scalar corner_radius)
 
static Scalar ComputeStrokeAlphaCoverage (const Matrix &entity, Scalar stroke_width)
 Compute an alpha value to simulate lower coverage of fractional pixel strokes. More...
 
static GeometryResult ComputePositionGeometry (const ContentContext &renderer, const Tessellator::VertexGenerator &generator, const Entity &entity, RenderPass &pass)
 

Detailed Description

Definition at line 37 of file rect_geometry.h.

Constructor & Destructor Documentation

◆ StrokeRectGeometry()

impeller::StrokeRectGeometry::StrokeRectGeometry ( const Rect rect,
const StrokeParameters stroke 
)
explicit

Definition at line 49 of file rect_geometry.cc.

51  : rect_(rect),
52  stroke_width_(stroke.width),
53  stroke_join_(AdjustStrokeJoin(stroke)) {}

◆ ~StrokeRectGeometry()

impeller::StrokeRectGeometry::~StrokeRectGeometry ( )
overridedefault

Member Function Documentation

◆ GetCoverage()

std::optional< Rect > impeller::StrokeRectGeometry::GetCoverage ( const Matrix transform) const
overridevirtual

Implements impeller::Geometry.

Definition at line 205 of file rect_geometry.cc.

206  {
207  return rect_.TransformBounds(transform);
208 }
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:476

References transform, and impeller::TRect< T >::TransformBounds().

◆ GetPositionBuffer()

GeometryResult impeller::StrokeRectGeometry::GetPositionBuffer ( const ContentContext renderer,
const Entity entity,
RenderPass pass 
) const
overridevirtual

Implements impeller::Geometry.

Definition at line 57 of file rect_geometry.cc.

60  {
61  if (stroke_width_ < 0.0) {
62  return {};
63  }
64  Scalar max_basis = entity.GetTransform().GetMaxBasisLengthXY();
65  if (max_basis == 0) {
66  return {};
67  }
68 
69  Scalar min_size = kMinStrokeSize / max_basis;
70  Scalar half_stroke_width = std::max(stroke_width_, min_size) * 0.5f;
71 
72  auto& host_buffer = renderer.GetTransientsBuffer();
73  const Rect& rect = rect_;
74 
75  switch (stroke_join_) {
76  case Join::kRound: {
77  Tessellator::Trigs trigs =
78  renderer.GetTessellator().GetTrigsForDeviceRadius(half_stroke_width *
79  max_basis);
80 
81  FML_DCHECK(trigs.size() >= 2u);
82 
83  // We use all but the first entry in trigs for each corner.
84  auto vertex_count = trigs.size() - 1;
85  // Every other point has a center vertex added.
86  vertex_count = vertex_count + (vertex_count >> 1);
87  // The loop also adds 3 points of its own.
88  vertex_count += 3;
89  // We do that for each of the 4 corners.
90  vertex_count = vertex_count * 4;
91  // We then add 2 more points at the end to close the last edge.
92  vertex_count += 2;
93 
94  return GeometryResult{
96  .vertex_buffer =
97  {
98  .vertex_buffer = host_buffer.Emplace(
99  vertex_count * sizeof(Point), alignof(Point),
100  [hsw = half_stroke_width, &rect, vertex_count,
101  &trigs](uint8_t* buffer) {
102  auto vertices = reinterpret_cast<Point*>(buffer);
103  [[maybe_unused]]
104  auto vertices_end = vertices + vertex_count;
105 
106  vertices =
107  AppendRoundCornerJoin(vertices, rect.GetLeftTop(),
108  Vector2(-hsw, 0), trigs);
109  vertices =
110  AppendRoundCornerJoin(vertices, rect.GetRightTop(),
111  Vector2(0, -hsw), trigs);
112  vertices = AppendRoundCornerJoin(
113  vertices, rect.GetRightBottom(), Vector2(hsw, 0),
114  trigs);
115  vertices = AppendRoundCornerJoin(
116  vertices, rect.GetLeftBottom(), Vector2(0, hsw),
117  trigs);
118 
119  // Repeat the first 2 points from the first corner to
120  // close the last edge.
121  *vertices++ = rect.GetLeftTop() - Vector2(hsw, 0);
122  *vertices++ = rect.GetLeftTop() + Vector2(hsw, 0);
123 
124  // Make sure our estimate is always up to date.
125  FML_DCHECK(vertices == vertices_end);
126  }),
127  .vertex_count = vertex_count,
128  .index_type = IndexType::kNone,
129  },
130  .transform = entity.GetShaderTransform(pass),
131  };
132  }
133 
134  case Join::kBevel: {
135  return GeometryResult{
137  .vertex_buffer =
138  {
139  .vertex_buffer = host_buffer.Emplace(
140  17 * sizeof(Point), alignof(Point),
141  [hsw = half_stroke_width, &rect](uint8_t* buffer) {
142  Scalar left = rect.GetLeft();
143  Scalar top = rect.GetTop();
144  Scalar right = rect.GetRight();
145  Scalar bottom = rect.GetBottom();
146  auto vertices = reinterpret_cast<Point*>(buffer);
147  vertices[0] = Point(left, top - hsw);
148  vertices[1] = Point(left, top + hsw);
149  vertices[2] = Point(right, top - hsw);
150  vertices[3] = Point(right, top + hsw);
151  vertices[4] = Point(right + hsw, top);
152  vertices[5] = Point(right - hsw, top);
153  vertices[6] = Point(right + hsw, bottom);
154  vertices[7] = Point(right - hsw, bottom);
155  vertices[8] = Point(right, bottom + hsw);
156  vertices[9] = Point(right, bottom - hsw);
157  vertices[10] = Point(left, bottom + hsw);
158  vertices[11] = Point(left, bottom - hsw);
159  vertices[12] = Point(left - hsw, bottom);
160  vertices[13] = Point(left + hsw, bottom);
161  vertices[14] = Point(left - hsw, top);
162  vertices[15] = Point(left + hsw, top);
163  vertices[16] = Point(left, top - hsw);
164  }),
165  .vertex_count = 17u,
166  .index_type = IndexType::kNone,
167  },
168  .transform = entity.GetShaderTransform(pass),
169  };
170  }
171 
172  case Join::kMiter: {
173  return GeometryResult{
175  .vertex_buffer =
176  {
177  .vertex_buffer = host_buffer.Emplace(
178  10 * sizeof(Point), alignof(Point),
179  [hsw = half_stroke_width, &rect](uint8_t* buffer) {
180  Scalar left = rect.GetLeft();
181  Scalar top = rect.GetTop();
182  Scalar right = rect.GetRight();
183  Scalar bottom = rect.GetBottom();
184  auto vertices = reinterpret_cast<Point*>(buffer);
185  vertices[0] = Point(left - hsw, top - hsw);
186  vertices[1] = Point(left + hsw, top + hsw);
187  vertices[2] = Point(right + hsw, top - hsw);
188  vertices[3] = Point(right - hsw, top + hsw);
189  vertices[4] = Point(right + hsw, bottom + hsw);
190  vertices[5] = Point(right - hsw, bottom - hsw);
191  vertices[6] = Point(left - hsw, bottom + hsw);
192  vertices[7] = Point(left + hsw, bottom - hsw);
193  vertices[8] = Point(left - hsw, top - hsw);
194  vertices[9] = Point(left + hsw, top + hsw);
195  }),
196  .vertex_count = 10u,
197  .index_type = IndexType::kNone,
198  },
199  .transform = entity.GetShaderTransform(pass),
200  };
201  }
202  }
203 }
@ kNone
Does not use the index buffer.
Point Vector2
Definition: point.h:331
float Scalar
Definition: scalar.h:19
TRect< Scalar > Rect
Definition: rect.h:792
TPoint< Scalar > Point
Definition: point.h:327
static constexpr Scalar kMinStrokeSize
Definition: geometry.h:19

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetLeftBottom(), impeller::TRect< T >::GetLeftTop(), impeller::Matrix::GetMaxBasisLengthXY(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetRightBottom(), impeller::TRect< T >::GetRightTop(), impeller::Entity::GetShaderTransform(), impeller::ContentContext::GetTessellator(), impeller::TRect< T >::GetTop(), impeller::Entity::GetTransform(), impeller::ContentContext::GetTransientsBuffer(), impeller::Tessellator::GetTrigsForDeviceRadius(), impeller::kBevel, impeller::kMinStrokeSize, impeller::kMiter, impeller::kNone, impeller::kRound, impeller::kTriangleStrip, impeller::Tessellator::Trigs::size(), and impeller::GeometryResult::type.


The documentation for this class was generated from the following files: