250 {
251 if (componentString.size() > 4) {
253 maskPos.endOffset()),
254 "too many components in swizzle mask");
255 return nullptr;
256 }
257
258
260 for (
size_t i = 0;
i < componentString.length(); ++
i) {
261 char field = componentString[
i];
262 switch (field) {
281 default:
283 maskPos.startOffset() +
i + 1),
285 return nullptr;
286 }
287 }
288
291 return nullptr;
292 }
293
294 const Type& baseType =
base->type().scalarTypeForLiteral();
295
296 if (!baseType.isVector() && !baseType.isScalar()) {
297 context.fErrors->error(
pos,
"cannot swizzle value of type '" +
298 baseType.displayName() + "'");
299 return nullptr;
300 }
301
303 bool foundXYZW = false;
308
309 break;
314 foundXYZW = true;
316 break;
321 foundXYZW = true;
322 if (baseType.columns() >= 2) {
324 break;
325 }
326 [[fallthrough]];
331 foundXYZW = true;
332 if (baseType.columns() >= 3) {
334 break;
335 }
336 [[fallthrough]];
341 foundXYZW = true;
342 if (baseType.columns() >= 4) {
344 break;
345 }
346 [[fallthrough]];
347 default:
348
350 maskPos.startOffset() +
i + 1),
353 return nullptr;
354 }
355 }
356
357 if (!foundXYZW) {
358 context.fErrors->error(maskPos, "swizzle must refer to base expression");
359 return nullptr;
360 }
361
362
363 base = baseType.coerceExpression(std::move(
base), context);
365 return nullptr;
366 }
367
368
369
370
371
372
373
374
375
376
377
378
379 std::unique_ptr<Expression> expr =
Swizzle::Make(context,
pos, std::move(
base), maskComponents);
380
381
383 return expr;
384 }
385
386
387
388
389
390
391
392
393 ExpressionArray constructorArgs;
394 constructorArgs.reserve_exact(3);
395 constructorArgs.push_back(std::move(expr));
396
397
398
399
400
401
402 const Type* scalarType = &baseType.componentType();
404 int maskFieldIdx = 0;
405 int constantFieldIdx = maskComponents.
size();
406 int constantZeroIdx = -1, constantOneIdx = -1;
407
411 if (constantZeroIdx == -1) {
412
414 constantZeroIdx = constantFieldIdx++;
415 }
416 swizzleComponents.push_back(constantZeroIdx);
417 break;
419 if (constantOneIdx == -1) {
420
422 constantOneIdx = constantFieldIdx++;
423 }
424 swizzleComponents.push_back(constantOneIdx);
425 break;
426 default:
427
428 swizzleComponents.push_back(maskFieldIdx++);
429 break;
430 }
431 }
432
434 scalarType->toCompound(context, constantFieldIdx, 1),
435 std::move(constructorArgs));
436
437
439}
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, ExpressionArray args)
static std::unique_ptr< Literal > Make(Position pos, double value, const Type *type)
static Position Range(int startOffset, int endOffset)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, std::unique_ptr< Expression > expr, ComponentArray inComponents)
static std::string MaskString(const ComponentArray &inComponents)
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
static bool validate_swizzle_domain(const ComponentArray &fields)
static char mask_char(int8_t component)
skia_private::FixedArray< 4, int8_t > ComponentArray