void onDrawContent(SkCanvas* canvas) override { fLightAngle += 0.015f; fColorFactor += 0.01f; if (fColorFactor > 1.0f) { fColorFactor = 0.0f; } SkLightingShader::Light light; light.fColor = SkColor3f::Make(1.0f, 1.0f, fColorFactor); light.fDirection.fX = SkScalarSin(fLightAngle)*SkScalarSin(SK_ScalarPI*0.25f); light.fDirection.fY = SkScalarCos(fLightAngle)*SkScalarSin(SK_ScalarPI*0.25f); light.fDirection.fZ = SkScalarCos(SK_ScalarPI*0.25f); fShader.reset(SkLightingShader::Create(fDiffuseBitmap, fNormalBitmap, light, fAmbientColor, nullptr)); SkPaint paint; paint.setShader(fShader); paint.setColor(SK_ColorBLACK); SkRect r = SkRect::MakeWH((SkScalar)fDiffuseBitmap.width(), (SkScalar)fDiffuseBitmap.height()); canvas->drawRect(r, paint); // so we're constantly updating this->inval(NULL); }
static SkPoint3 GetDistantDirection() { static SkScalar azimuthRad = SkDegreesToRadians(SkIntToScalar(225)); static SkScalar elevationRad = SkDegreesToRadians(SkIntToScalar(5)); static SkPoint3 distantDirection = SkPoint3::Make(SkScalarMul(SkScalarCos(azimuthRad), SkScalarCos(elevationRad)), SkScalarMul(SkScalarSin(azimuthRad), SkScalarCos(elevationRad)), SkScalarSin(elevationRad)); return distantDirection; }
static const SkLightingShader::Lights* create_lights(SkScalar angle, SkScalar blue) { const SkVector3 dir = SkVector3::Make(SkScalarSin(angle)*SkScalarSin(SK_ScalarPI*0.25f), SkScalarCos(angle)*SkScalarSin(SK_ScalarPI*0.25f), SkScalarCos(SK_ScalarPI*0.25f)); SkLightingShader::Lights::Builder builder; builder.add(SkLight(SkColor3f::Make(1.0f, 1.0f, blue), dir)); builder.add(SkLight(SkColor3f::Make(0.1f, 0.1f, 0.1f))); return builder.finish(); }
static sk_sp<SkLights> create_lights(SkScalar angle, SkScalar blue) { const SkVector3 dir = SkVector3::Make(SkScalarSin(angle)*SkScalarSin(SK_ScalarPI*0.25f), SkScalarCos(angle)*SkScalarSin(SK_ScalarPI*0.25f), SkScalarCos(SK_ScalarPI*0.25f)); SkLights::Builder builder; builder.add(SkLights::Light::MakeDirectional(SkColor3f::Make(1.0f, 1.0f, blue), dir)); builder.setAmbientLightColor(SkColor3f::Make(0.1f, 0.1f, 0.1f)); return builder.finish(); }
virtual void onDraw(SkCanvas* canvas) { SkScalar angle = kAngle*SK_ScalarPI + SkScalarHalf(SK_ScalarPI); SkScalar size = SkIntToScalar(SkMin32(kWidth, kHeight)); SkPoint center = SkPoint::Make(SkScalarHalf(kWidth), SkScalarHalf(kHeight)); SkScalar length = 5; SkScalar step = angle; SkPath path; path.moveTo(center); while (length < (SkScalarHalf(size) - 10.f)) { SkPoint rp = SkPoint::Make(length*SkScalarCos(step) + center.fX, length*SkScalarSin(step) + center.fY); path.lineTo(rp); length += SkScalarDiv(angle, SkScalarHalf(SK_ScalarPI)); step += angle; } path.close(); SkPaint paint; paint.setAntiAlias(true); paint.setStyle(SkPaint::kStroke_Style); paint.setColor(0xFF007700); canvas->drawPath(path, paint); }
void onDraw(SkCanvas* canvas) override { SkScalar angle = kAngle*SK_ScalarPI + SkScalarHalf(SK_ScalarPI); SkScalar size = SkIntToScalar(SkMin32(kWidth, kHeight)); SkPoint center = SkPoint::Make(SkScalarHalf(kWidth), SkScalarHalf(kHeight)); SkScalar length = 5; SkScalar step = angle; SkPath path; path.moveTo(center); for (int i = 0; i < fNumSteps && length < (SkScalarHalf(size) - 10.f); ++i) { SkPoint rp = SkPoint::Make(length*SkScalarCos(step) + center.fX, length*SkScalarSin(step) + center.fY); path.lineTo(rp); length += angle / SkScalarHalf(SK_ScalarPI); step += angle; } SkPaint paint; paint.setAntiAlias(true); paint.setStyle(SkPaint::kStroke_Style); paint.setColor(sk_tool_utils::color_to_565(0xFF007700)); canvas->drawPath(path, paint); }
void onDrawContent(SkCanvas* canvas) override { SkScalar angle = fAngle*SK_ScalarPI + SkScalarHalf(SK_ScalarPI); SkPoint center = SkPoint::Make(SkScalarHalf(this->width()), SkScalarHalf(this->height())); SkScalar length = 5; SkScalar step = angle; SkPath path; path.moveTo(center); while (length < (SkScalarHalf(SkMinScalar(this->width(), this->height())) - 10.f)) { SkPoint rp = SkPoint::Make(length*SkScalarCos(step) + center.fX, length*SkScalarSin(step) + center.fY); path.lineTo(rp); length += SkScalarDiv(angle, SkScalarHalf(SK_ScalarPI)); step += angle; } path.close(); SkPaint paint; paint.setAntiAlias(true); paint.setStyle(SkPaint::kStroke_Style); paint.setColor(0xFF007700); canvas->drawPath(path, paint); }
static SkScalar drawCell(SkCanvas* canvas, SkXfermode* mode, SkAlpha a0, SkAlpha a1) { SkPaint paint; paint.setAntiAlias(true); SkRect r = SkRect::MakeWH(W, H); r.inset(W/10, H/10); paint.setColor(SK_ColorBLUE); paint.setAlpha(a0); canvas->drawOval(r, paint); paint.setColor(SK_ColorRED); paint.setAlpha(a1); paint.setXfermode(mode); for (int angle = 0; angle < 24; ++angle) { SkScalar x = SkScalarCos(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gWidth; SkScalar y = SkScalarSin(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gHeight; paint.setStrokeWidth(SK_Scalar1 * angle * 2 / 24); canvas->drawLine(W/2, H/2, W/2 + x, H/2 + y, paint); } return H; }
LightingView() { SkString diffusePath = GetResourcePath("brickwork-texture.jpg"); SkImageDecoder::DecodeFile(diffusePath.c_str(), &fDiffuseBitmap); SkString normalPath = GetResourcePath("brickwork_normal-map.jpg"); SkImageDecoder::DecodeFile(normalPath.c_str(), &fNormalBitmap); fLightAngle = 0.0f; fColorFactor = 0; LightingShader::Light light; light.fColor = SkColorSetRGB(0xff, 0xff, 0xff); light.fDirection.fX = SkScalarSin(fLightAngle)*SkScalarSin(SK_ScalarPI*0.25f); light.fDirection.fY = SkScalarCos(fLightAngle)*SkScalarSin(SK_ScalarPI*0.25f); light.fDirection.fZ = SkScalarCos(SK_ScalarPI*0.25f); SkColor ambient = SkColorSetRGB(0x1f, 0x1f, 0x1f); fShader.reset(SkNEW_ARGS(LightingShader, (fDiffuseBitmap, fNormalBitmap, light, ambient))); }
/* Solve coeff(t) == 0, returning the number of roots that lie withing 0 < t < 1. coeff[0]t^3 + coeff[1]t^2 + coeff[2]t + coeff[3] Eliminates repeated roots (so that all tValues are distinct, and are always in increasing order. */ static int solve_cubic_poly(const SkScalar coeff[4], SkScalar tValues[3]) { if (SkScalarNearlyZero(coeff[0])) { // we're just a quadratic return SkFindUnitQuadRoots(coeff[1], coeff[2], coeff[3], tValues); } SkScalar a, b, c, Q, R; { SkASSERT(coeff[0] != 0); SkScalar inva = SkScalarInvert(coeff[0]); a = coeff[1] * inva; b = coeff[2] * inva; c = coeff[3] * inva; } Q = (a*a - b*3) / 9; R = (2*a*a*a - 9*a*b + 27*c) / 54; SkScalar Q3 = Q * Q * Q; SkScalar R2MinusQ3 = R * R - Q3; SkScalar adiv3 = a / 3; SkScalar* roots = tValues; SkScalar r; if (R2MinusQ3 < 0) { // we have 3 real roots SkScalar theta = SkScalarACos(R / SkScalarSqrt(Q3)); SkScalar neg2RootQ = -2 * SkScalarSqrt(Q); r = neg2RootQ * SkScalarCos(theta/3) - adiv3; if (is_unit_interval(r)) { *roots++ = r; } r = neg2RootQ * SkScalarCos((theta + 2*SK_ScalarPI)/3) - adiv3; if (is_unit_interval(r)) { *roots++ = r; } r = neg2RootQ * SkScalarCos((theta - 2*SK_ScalarPI)/3) - adiv3; if (is_unit_interval(r)) { *roots++ = r; } SkDEBUGCODE(test_collaps_duplicates();)
LightingView() { SkString diffusePath = GetResourcePath("brickwork-texture.jpg"); SkImageDecoder::DecodeFile(diffusePath.c_str(), &fDiffuseBitmap); SkString normalPath = GetResourcePath("brickwork_normal-map.jpg"); SkImageDecoder::DecodeFile(normalPath.c_str(), &fNormalBitmap); fLightAngle = 0.0f; fColorFactor = 0.0f; SkLightingShader::Light light; light.fColor = SkColor3f::Make(1.0f, 1.0f, 1.0f); light.fDirection.fX = SkScalarSin(fLightAngle)*SkScalarSin(SK_ScalarPI*0.25f); light.fDirection.fY = SkScalarCos(fLightAngle)*SkScalarSin(SK_ScalarPI*0.25f); light.fDirection.fZ = SkScalarCos(SK_ScalarPI*0.25f); fAmbientColor = SkColor3f::Make(0.1f, 0.1f, 0.1f); fShader.reset(SkLightingShader::Create(fDiffuseBitmap, fNormalBitmap, light, fAmbientColor, nullptr)); }
SkPath make_star(const SkRect& bounds, int numPts, int step) { SkPath path; path.setFillType(SkPath::kEvenOdd_FillType); path.moveTo(0,-1); for (int i = 1; i < numPts; ++i) { int idx = i*step; SkScalar theta = idx * 2*SK_ScalarPI/numPts + SK_ScalarPI/2; SkScalar x = SkScalarCos(theta); SkScalar y = -SkScalarSin(theta); path.lineTo(x, y); } path.transform(SkMatrix::MakeRectToRect(path.getBounds(), bounds, SkMatrix::kFill_ScaleToFit)); return path; }
virtual void onDraw(SkCanvas* canvas) { if (!fInitialized) { make_bitmap(); fInitialized = true; } canvas->clear(0xFF101010); SkPaint checkPaint; checkPaint.setColor(0xFF202020); for (int y = 0; y < HEIGHT; y += 16) { for (int x = 0; x < WIDTH; x += 16) { canvas->save(); canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); canvas->drawRect(SkRect::MakeXYWH(8, 0, 8, 8), checkPaint); canvas->drawRect(SkRect::MakeXYWH(0, 8, 8, 8), checkPaint); canvas->restore(); } } SkPoint3 pointLocation(0, 0, SkIntToScalar(10)); SkScalar azimuthRad = SkDegreesToRadians(SkIntToScalar(225)); SkScalar elevationRad = SkDegreesToRadians(SkIntToScalar(5)); SkPoint3 distantDirection(SkScalarMul(SkScalarCos(azimuthRad), SkScalarCos(elevationRad)), SkScalarMul(SkScalarSin(azimuthRad), SkScalarCos(elevationRad)), SkScalarSin(elevationRad)); SkPoint3 spotLocation(SkIntToScalar(-10), SkIntToScalar(-10), SkIntToScalar(20)); SkPoint3 spotTarget(SkIntToScalar(40), SkIntToScalar(40), 0); SkScalar spotExponent = SK_Scalar1; SkScalar cutoffAngle = SkIntToScalar(15); SkScalar kd = SkIntToScalar(2); SkScalar ks = SkIntToScalar(1); SkScalar shininess = SkIntToScalar(8); SkScalar surfaceScale = SkIntToScalar(1); SkColor white(0xFFFFFFFF); SkPaint paint; SkImageFilter::CropRect cropRect(SkRect::MakeXYWH(20, 10, 60, 65)); int y = 0; for (int i = 0; i < 2; i++) { const SkImageFilter::CropRect* cr = (i == 0) ? NULL : &cropRect; paint.setImageFilter(SkLightingImageFilter::CreatePointLitDiffuse(pointLocation, white, surfaceScale, kd, NULL, cr))->unref(); drawClippedBitmap(canvas, paint, 0, y); paint.setImageFilter(SkLightingImageFilter::CreateDistantLitDiffuse(distantDirection, white, surfaceScale, kd, NULL, cr))->unref(); drawClippedBitmap(canvas, paint, 110, y); paint.setImageFilter(SkLightingImageFilter::CreateSpotLitDiffuse(spotLocation, spotTarget, spotExponent, cutoffAngle, white, surfaceScale, kd, NULL, cr))->unref(); drawClippedBitmap(canvas, paint, 220, y); y += 110; paint.setImageFilter(SkLightingImageFilter::CreatePointLitSpecular(pointLocation, white, surfaceScale, ks, shininess, NULL, cr))->unref(); drawClippedBitmap(canvas, paint, 0, y); paint.setImageFilter(SkLightingImageFilter::CreateDistantLitSpecular(distantDirection, white, surfaceScale, ks, shininess, NULL, cr))->unref(); drawClippedBitmap(canvas, paint, 110, y); paint.setImageFilter(SkLightingImageFilter::CreateSpotLitSpecular(spotLocation, spotTarget, spotExponent, cutoffAngle, white, surfaceScale, ks, shininess, NULL, cr))->unref(); drawClippedBitmap(canvas, paint, 220, y); y += 110; } }
void onOnceBeforeDraw() override { { SkPath* lineAnglesPath = &fPaths.push_back(); enum { kNumAngles = 15, kRadius = 40, }; for (int i = 0; i < kNumAngles; ++i) { SkScalar angle = SK_ScalarPI * SkIntToScalar(i) / kNumAngles; SkScalar x = kRadius * SkScalarCos(angle); SkScalar y = kRadius * SkScalarSin(angle); lineAnglesPath->moveTo(x, y); lineAnglesPath->lineTo(-x, -y); } } { SkPath* kindaTightQuad = &fPaths.push_back(); kindaTightQuad->moveTo(0, -10 * SK_Scalar1); kindaTightQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), -10 * SK_Scalar1, 0); } { SkPath* tightQuad = &fPaths.push_back(); tightQuad->moveTo(0, -5 * SK_Scalar1); tightQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), -5 * SK_Scalar1, 0); } { SkPath* tighterQuad = &fPaths.push_back(); tighterQuad->moveTo(0, -2 * SK_Scalar1); tighterQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), -2 * SK_Scalar1, 0); } { SkPath* unevenTighterQuad = &fPaths.push_back(); unevenTighterQuad->moveTo(0, -1 * SK_Scalar1); SkPoint p; p.set(-2 * SK_Scalar1 + 3 * SkIntToScalar(102) / 4, SkIntToScalar(75)); unevenTighterQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), p.fX, p.fY); } { SkPath* reallyTightQuad = &fPaths.push_back(); reallyTightQuad->moveTo(0, -1 * SK_Scalar1); reallyTightQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), -1 * SK_Scalar1, 0); } { SkPath* closedQuad = &fPaths.push_back(); closedQuad->moveTo(0, -0); closedQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), 0, 0); } { SkPath* unevenClosedQuad = &fPaths.push_back(); unevenClosedQuad->moveTo(0, -0); unevenClosedQuad->quadTo(SkIntToScalar(100), SkIntToScalar(100), SkIntToScalar(75), SkIntToScalar(75)); } // Two problem cases for gpu hairline renderer found by shapeops testing. These used // to assert that the computed bounding box didn't contain all the vertices. { SkPath* problem1 = &fPaths.push_back(); problem1->moveTo(SkIntToScalar(4), SkIntToScalar(6)); problem1->cubicTo(SkIntToScalar(5), SkIntToScalar(6), SkIntToScalar(5), SkIntToScalar(4), SkIntToScalar(4), SkIntToScalar(0)); problem1->close(); } { SkPath* problem2 = &fPaths.push_back(); problem2->moveTo(SkIntToScalar(5), SkIntToScalar(1)); problem2->lineTo(4.32787323f, 1.67212653f); problem2->cubicTo(2.75223875f, 3.24776125f, 3.00581908f, 4.51236057f, 3.7580452f, 4.37367964f); problem2->cubicTo(4.66472578f, 3.888381f, 5.f, 2.875f, 5.f, 1.f); problem2->close(); } // Three paths that show the same bug (missing end caps) { // A caret (crbug.com/131770) SkPath* bug0 = &fPaths.push_back(); bug0->moveTo(6.5f,5.5f); bug0->lineTo(3.5f,0.5f); bug0->moveTo(0.5f,5.5f); bug0->lineTo(3.5f,0.5f); } { // An X (crbug.com/137317) SkPath* bug1 = &fPaths.push_back(); bug1->moveTo(1, 1); bug1->lineTo(6, 6); bug1->moveTo(1, 6); bug1->lineTo(6, 1); } { // A right angle (crbug.com/137465 and crbug.com/256776) SkPath* bug2 = &fPaths.push_back(); bug2->moveTo(5.5f, 5.5f); bug2->lineTo(5.5f, 0.5f); bug2->lineTo(0.5f, 0.5f); } { // Arc example to test imperfect truncation bug (crbug.com/295626) static const SkScalar kRad = SkIntToScalar(2000); static const SkScalar kStartAngle = 262.59717f; static const SkScalar kSweepAngle = SkScalarHalf(17.188717f); SkPath* bug = &fPaths.push_back(); // Add a circular arc SkRect circle = SkRect::MakeLTRB(-kRad, -kRad, kRad, kRad); bug->addArc(circle, kStartAngle, kSweepAngle); // Now add the chord that should cap the circular arc SkScalar cosV, sinV = SkScalarSinCos(SkDegreesToRadians(kStartAngle), &cosV); SkPoint p0 = SkPoint::Make(kRad * cosV, kRad * sinV); sinV = SkScalarSinCos(SkDegreesToRadians(kStartAngle + kSweepAngle), &cosV); SkPoint p1 = SkPoint::Make(kRad * cosV, kRad * sinV); bug->moveTo(p0); bug->lineTo(p1); } }
void SkDisplayMath::executeFunction(SkDisplayable* target, int index, SkTDArray<SkScriptValue>& parameters, SkDisplayTypes type, SkScriptValue* scriptValue) { if (scriptValue == NULL) return; SkASSERT(target == this); SkScriptValue* array = parameters.begin(); SkScriptValue* end = parameters.end(); SkScalar input = parameters[0].fOperand.fScalar; SkScalar scalarResult; switch (index) { case SK_FUNCTION(abs): scalarResult = SkScalarAbs(input); break; case SK_FUNCTION(acos): scalarResult = SkScalarACos(input); break; case SK_FUNCTION(asin): scalarResult = SkScalarASin(input); break; case SK_FUNCTION(atan): scalarResult = SkScalarATan2(input, SK_Scalar1); break; case SK_FUNCTION(atan2): scalarResult = SkScalarATan2(input, parameters[1].fOperand.fScalar); break; case SK_FUNCTION(ceil): scalarResult = SkIntToScalar(SkScalarCeil(input)); break; case SK_FUNCTION(cos): scalarResult = SkScalarCos(input); break; case SK_FUNCTION(exp): scalarResult = SkScalarExp(input); break; case SK_FUNCTION(floor): scalarResult = SkIntToScalar(SkScalarFloor(input)); break; case SK_FUNCTION(log): scalarResult = SkScalarLog(input); break; case SK_FUNCTION(max): scalarResult = -SK_ScalarMax; while (array < end) { scalarResult = SkMaxScalar(scalarResult, array->fOperand.fScalar); array++; } break; case SK_FUNCTION(min): scalarResult = SK_ScalarMax; while (array < end) { scalarResult = SkMinScalar(scalarResult, array->fOperand.fScalar); array++; } break; case SK_FUNCTION(pow): // not the greatest -- but use x^y = e^(y * ln(x)) scalarResult = SkScalarLog(input); scalarResult = SkScalarMul(parameters[1].fOperand.fScalar, scalarResult); scalarResult = SkScalarExp(scalarResult); break; case SK_FUNCTION(random): scalarResult = fRandom.nextUScalar1(); break; case SK_FUNCTION(round): scalarResult = SkIntToScalar(SkScalarRound(input)); break; case SK_FUNCTION(sin): scalarResult = SkScalarSin(input); break; case SK_FUNCTION(sqrt): { SkASSERT(parameters.count() == 1); SkASSERT(type == SkType_Float); scalarResult = SkScalarSqrt(input); } break; case SK_FUNCTION(tan): scalarResult = SkScalarTan(input); break; default: SkASSERT(0); scalarResult = SK_ScalarNaN; } scriptValue->fOperand.fScalar = scalarResult; scriptValue->fType = SkType_Float; }
static SkPoint unit_vec(int degrees) { SkScalar rad = SkDegreesToRadians(SkIntToScalar(degrees)); return SkPoint::Make(SkScalarCos(rad), SkScalarSin(rad)); }