169 static QSGGeometry::Attribute attrs[] = {
170 QSGGeometry::Attribute::createWithAttributeType(0, 2, QSGGeometry::FloatType,
171 QSGGeometry::PositionAttribute),
172 QSGGeometry::Attribute::createWithAttributeType(1, 4, QSGGeometry::FloatType,
173 QSGGeometry::UnknownAttribute),
174 QSGGeometry::Attribute::createWithAttributeType(2, 4, QSGGeometry::FloatType,
175 QSGGeometry::UnknownAttribute),
178 static QSGGeometry::AttributeSet attrset = { 3,
sizeof(
RectangleVertex), attrs };
180 auto out = std::make_unique<QSGGeometry>(attrset, 6 * 9);
181 out->setDrawingMode(QSGGeometry::DrawTriangles);
195 auto outter = std::max({ radius[0], radius[1], radius[2], radius[3], 2.0f });
196 auto inner = -1.0f / outter;
198 set_left_top_corner(lt, size, radius[0], std::max(radius[0], 2.0f), inner);
199 set_right_top_corner(rt, size, radius[1], std::max(radius[1], 2.0f), inner);
200 set_left_bottom_corner(lb, size, radius[2], std::max(radius[2], 2.0f), inner);
201 set_right_bottom_corner(rb, size, radius[3], std::max(radius[3], 2.0f), inner);
203 auto top = v + u * 4;
204 auto left = v + u * 5;
205 auto bottom = v + u * 6;
206 auto right = v + u * 7;
207 auto middle = v + u * 8;
209 set_rect(top, lt + 5, rt + 0, lt + 4, rt + 2);
210 if (top[0].ce_distance_to_outter - top[1].ce_distance_to_outter > 0.1f) {
211 top[1].ce_distance_to_outter = top[0].ce_distance_to_outter * 10.0f;
213 set_rect_flip(bottom, lb + 1, rb + 0, lb + 4, rb + 2);
214 if (bottom[0].ce_distance_to_outter - bottom[1].ce_distance_to_outter > 0.1f) {
215 bottom[1].ce_distance_to_outter = bottom[0].ce_distance_to_outter * 10.0f;
217 set_rect(left, lt + 3, lt + 4, lb + 0, lb + 1);
218 if (left[0].ce_distance_to_outter - left[2].ce_distance_to_outter > 0.1f) {
219 left[2].ce_distance_to_outter = left[0].ce_distance_to_outter * 10.0f;
221 set_rect_flip(right, rt + 2, rt + 4, rb + 0, rb + 1);
222 if (right[0].ce_distance_to_outter - right[2].ce_distance_to_outter > 0.1f) {
223 right[2].ce_distance_to_outter = right[0].ce_distance_to_outter * 10.0f;
225 set_rect(middle, lt + 4, rt + 2, lb + 1, rb + 0);
227 for (
int i = 0; i < u * 9; i++) {
234 static QSGGeometry::Attribute attrs[] = {
235 QSGGeometry::Attribute::createWithAttributeType(0, 2, QSGGeometry::FloatType,
236 QSGGeometry::PositionAttribute),
237 QSGGeometry::Attribute::createWithAttributeType(1, 4, QSGGeometry::FloatType,
238 QSGGeometry::UnknownAttribute),
239 QSGGeometry::Attribute::createWithAttributeType(2, 3, QSGGeometry::FloatType,
240 QSGGeometry::UnknownAttribute),
243 static QSGGeometry::AttributeSet attrset = { 3,
sizeof(
ShadowVertex), attrs };
245 auto out = std::make_unique<QSGGeometry>(attrset, 0);
246 out->setDrawingMode(QSGGeometry::DrawTriangles);
254 bool transparent = (params.
flags & ShadowFlags::TransparentOccluder_ShadowFlag);
255 bool directional = (params.
flags & ShadowFlags::DirectionalLight_ShadowFlag);
257 auto max_radius = std::min(rect.width(), rect.height()) / 2.0;
258 bool is_oval = params.
radius.x() >= max_radius && params.
radius.y() >= max_radius
259 && params.
radius.z() >= max_radius && params.
radius.w() >= max_radius
260 && qFuzzyCompare(rect.width(), rect.height());
262 std::array<std::optional<Skia::ShadowCircularRRectOp>, 2> ops;
267 const scalar devSpaceAmbientBlur = devSpaceInsetWidth * umbraRecipAlpha;
270 scalar ambientPathOutset = devSpaceInsetWidth;
271 QRectF ambientRRect = rect.adjusted(-ambientPathOutset, -ambientPathOutset,
272 ambientPathOutset, ambientPathOutset);
273 QVector4D ambientRadii;
274 for (
int i = 0; i < 4; ++i)
275 ambientRadii[i] = std::min<float>(params.
radius[i] + ambientPathOutset, max_radius);
279 devSpaceInsetWidth = ambientRRect.width();
282 is_oval, devSpaceAmbientBlur, devSpaceInsetWidth);
288 QVector2D spotOffset;
291 devLightPos.z(), params.
light_radius, &devSpaceSpotBlur,
292 &spotScale, &spotOffset);
295 params.
light_radius, &devSpaceSpotBlur, &spotScale, &spotOffset);
298 const scalar srcSpaceSpotBlur = devSpaceSpotBlur;
311 QRectF spotShadowRRect;
313 auto dw = (spotScale - 1.0f) * rect.width() / 2.0f;
314 auto dh = (spotScale - 1.0f) * rect.height() / 2.0f;
316 rect.translated(spotOffset.x(), spotOffset.y()).adjusted(-dw, -dh, dw, dh);
321 QVector4D spotRadii = params.
radius * spotScale;
324 scalar blurOutset = srcSpaceSpotBlur;
325 scalar insetWidth = blurOutset;
328 insetWidth += spotShadowRRect.width();
344 if (params.
radius.length() == 0) {
346 maxOffset = std::max(std::max(std::abs(spotShadowRRect.left() - rect.left()),
347 std::abs(spotShadowRRect.top() - rect.top())),
348 std::max(std::abs(spotShadowRRect.right() - rect.right()),
349 std::abs(spotShadowRRect.bottom() - rect.bottom())));
352 for (
int i = 0; i < 4; ++i)
353 dr = std::max(dr, spotRadii[i] - params.
radius[i]);
354 QVector2D upperLeftOffset = QVector2D(spotShadowRRect.left() - rect.left() + dr,
355 spotShadowRRect.top() - rect.top() + dr);
356 QVector2D lowerRightOffset =
357 QVector2D(spotShadowRRect.right() - rect.right() - dr,
358 spotShadowRRect.bottom() - rect.bottom() - dr);
359 maxOffset = std::sqrt(std::max(upperLeftOffset.lengthSquared(),
360 lowerRightOffset.lengthSquared()))
363 insetWidth += std::max(blurOutset, maxOffset);
367 spotShadowRRect.adjust(-blurOutset, -blurOutset, blurOutset, blurOutset);
368 spotRadii += QVector4D(blurOutset, blurOutset, blurOutset, blurOutset);
371 is_oval, 2.0f * devSpaceSpotBlur, insetWidth);
374 int vertex_count = 0;
376 for (
auto &p : ops) {
378 vertex_count += p->fVertCount;
379 index_count += p->fIndexCount;
382 geo->allocate(vertex_count, index_count);
384 auto vertices =
static_cast<ShadowVertex *
>(geo->vertexData());
385 auto indexes = (std::uint16_t *)geo->indexData();
386 int vertice_offset = 0;
387 for (
auto &p : ops) {
389 auto type = p->fGeoData.type;
390 if (p->fGeoData.is_circle) {
392 p->fillInCircleVerts(isStroked, &vertices);
394 p->fillInRRectVerts(&vertices);
396 for (
int i = 0; i < p->fIndexCount; i++) {
397 indexes[i] = p->fIndexPtr[i] + vertice_offset;
399 indexes += p->fIndexCount;
400 vertice_offset += p->fVertCount;