SkGradientShaderBase::GradientShaderBaseContext::GradientShaderBaseContext( const SkGradientShaderBase& shader, const ContextRec& rec) : INHERITED(shader, rec) #ifdef SK_SUPPORT_LEGACY_GRADIENT_DITHERING , fDither(true) #else , fDither(rec.fPaint->isDither()) #endif , fCache(shader.refCache(getPaintAlpha(), fDither)) { const SkMatrix& inverse = this->getTotalInverse(); fDstToIndex.setConcat(shader.fPtsToUnit, inverse); fDstToIndexProc = fDstToIndex.getMapXYProc(); fDstToIndexClass = (uint8_t)SkShader::Context::ComputeMatrixClass(fDstToIndex); // now convert our colors in to PMColors unsigned paintAlpha = this->getPaintAlpha(); fFlags = this->INHERITED::getFlags(); if (shader.fColorsAreOpaque && paintAlpha == 0xFF) { fFlags |= kOpaqueAlpha_Flag; } // we can do span16 as long as our individual colors are opaque, // regardless of the paint's alpha if (shader.fColorsAreOpaque) { fFlags |= kHasSpan16_Flag; } }
SkScalar SkPerlinNoiseShader::PerlinNoiseShaderContext::calculateTurbulenceValueForPoint( int channel, StitchData& stitchData, const SkPoint& point) const { const SkPerlinNoiseShader& perlinNoiseShader = static_cast<const SkPerlinNoiseShader&>(fShader); if (perlinNoiseShader.fStitchTiles) { // Set up TurbulenceInitial stitch values. stitchData = fPaintingData->fStitchDataInit; } SkScalar turbulenceFunctionResult = 0; SkPoint noiseVector(SkPoint::Make(SkScalarMul(point.x(), fPaintingData->fBaseFrequency.fX), SkScalarMul(point.y(), fPaintingData->fBaseFrequency.fY))); SkScalar ratio = SK_Scalar1; for (int octave = 0; octave < perlinNoiseShader.fNumOctaves; ++octave) { SkScalar noise = noise2D(channel, stitchData, noiseVector); SkScalar numer = (perlinNoiseShader.fType == kFractalNoise_Type) ? noise : SkScalarAbs(noise); turbulenceFunctionResult += numer / ratio; noiseVector.fX *= 2; noiseVector.fY *= 2; ratio *= 2; if (perlinNoiseShader.fStitchTiles) { // Update stitch values stitchData.fWidth *= 2; stitchData.fWrapX = stitchData.fWidth + kPerlinNoise; stitchData.fHeight *= 2; stitchData.fWrapY = stitchData.fHeight + kPerlinNoise; } } // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult) + 1) / 2 // by fractalNoise and (turbulenceFunctionResult) by turbulence. if (perlinNoiseShader.fType == kFractalNoise_Type) { turbulenceFunctionResult = SkScalarMul(turbulenceFunctionResult, SK_ScalarHalf) + SK_ScalarHalf; } if (channel == 3) { // Scale alpha by paint value turbulenceFunctionResult *= SkIntToScalar(getPaintAlpha()) / 255; } // Clamp result return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1); }