void AudioBufferSourceHandler::clampGrainParameters(const AudioBuffer* buffer)
{
    ASSERT(buffer);

    // We have a buffer so we can clip the offset and duration to lie within the buffer.
    double bufferDuration = buffer->duration();

    m_grainOffset = clampTo(m_grainOffset, 0.0, bufferDuration);

    // If the duration was not explicitly given, use the buffer duration to set the grain
    // duration. Otherwise, we want to use the user-specified value, of course.
    if (!m_isDurationGiven)
        m_grainDuration = bufferDuration - m_grainOffset;

    if (m_isDurationGiven && loop()) {
        // We're looping a grain with a grain duration specified. Schedule the loop to stop after
        // grainDuration seconds after starting, possibly running the loop multiple times if
        // grainDuration is larger than the buffer duration. The net effect is as if the user called
        // stop(when + grainDuration).
        m_grainDuration = clampTo(m_grainDuration, 0.0, std::numeric_limits<double>::infinity());
        m_endTime = m_startTime + m_grainDuration;
    } else {
        m_grainDuration = clampTo(m_grainDuration, 0.0, bufferDuration - m_grainOffset);
    }

    // We call timeToSampleFrame here since at playbackRate == 1 we don't want to go through
    // linear interpolation at a sub-sample position since it will degrade the quality. When
    // aligned to the sample-frame the playback will be identical to the PCM data stored in the
    // buffer. Since playbackRate == 1 is very common, it's worth considering quality.
    m_virtualReadIndex = AudioUtilities::timeToSampleFrame(m_grainOffset, buffer->sampleRate());
}
示例#2
0
AnimatableColorImpl::AnimatableColorImpl(float red, float green, float blue, float alpha)
    : m_alpha(clampTo(alpha, 0.0f, 1.0f))
    , m_red(clampTo(red, 0.0f, 1.0f))
    , m_green(clampTo(green, 0.0f, 1.0f))
    , m_blue(clampTo(blue, 0.0f, 1.0f))
{
}
void StereoPanner::panWithSampleAccurateValues(const AudioBus* inputBus, AudioBus* outputBus, const float* panValues, size_t framesToProcess)
{
    bool isInputSafe = inputBus
                       && (inputBus->numberOfChannels() == 1 || inputBus->numberOfChannels() == 2)
                       && framesToProcess <= inputBus->length();
    ASSERT(isInputSafe);
    if (!isInputSafe)
        return;

    unsigned numberOfInputChannels = inputBus->numberOfChannels();

    bool isOutputSafe = outputBus
                        && outputBus->numberOfChannels() == 2
                        && framesToProcess <= outputBus->length();
    ASSERT(isOutputSafe);
    if (!isOutputSafe)
        return;

    const float* sourceL = inputBus->channel(0)->data();
    const float* sourceR = numberOfInputChannels > 1 ? inputBus->channel(1)->data() : sourceL;
    float* destinationL = outputBus->channelByType(AudioBus::ChannelLeft)->mutableData();
    float* destinationR = outputBus->channelByType(AudioBus::ChannelRight)->mutableData();

    if (!sourceL || !sourceR || !destinationL || !destinationR)
        return;

    double gainL, gainR, panRadian;

    int n = framesToProcess;

    if (numberOfInputChannels == 1) { // For mono source case.
        while (n--) {
            float inputL = *sourceL++;
            m_pan = clampTo(*panValues++, -1.0, 1.0);
            // Pan from left to right [-1; 1] will be normalized as [0; 1].
            panRadian = (m_pan * 0.5 + 0.5) * piOverTwoDouble;
            gainL = std::cos(panRadian);
            gainR = std::sin(panRadian);
            *destinationL++ = static_cast<float>(inputL * gainL);
            *destinationR++ = static_cast<float>(inputL * gainR);
        }
    } else { // For stereo source case.
        while (n--) {
            float inputL = *sourceL++;
            float inputR = *sourceR++;
            m_pan = clampTo(*panValues++, -1.0, 1.0);
            // Normalize [-1; 0] to [0; 1]. Do nothing when [0; 1].
            panRadian = (m_pan <= 0 ? m_pan + 1 : m_pan) * piOverTwoDouble;
            gainL = std::cos(panRadian);
            gainR = std::sin(panRadian);
            if (m_pan <= 0) {
                *destinationL++ = static_cast<float>(inputL + inputR * gainL);
                *destinationR++ = static_cast<float>(inputR * gainR);
            } else {
                *destinationL++ = static_cast<float>(inputL * gainL);
                *destinationR++ = static_cast<float>(inputR + inputL * gainR);
            }
        }
    }
}
示例#4
0
FloatPoint PageViewportController::clampViewportToContents(const WebCore::FloatPoint& viewportPos, float viewportScale)
{
    const float horizontalRange = std::max(0.f, m_contentsSize.width() - m_viewportSize.width() / viewportScale);
    const float verticalRange = std::max(0.f, m_contentsSize.height() - m_viewportSize.height() / viewportScale);

    return FloatPoint(clampTo(viewportPos.x(), 0.f, horizontalRange), clampTo(viewportPos.y(), 0.f, verticalRange));
}
void OcclusionEngine::addOccluders( const Occluder occluderArray[], int numberOfOccluders )
{


	if( engineMode == NormalRasterization ) 
	{
		for( int i = 0 ; i < numberOfOccluders ; i++ ) 
		{

			const Occluder *currentOccluder;

			currentOccluder = &(occluderArray[i]);
			int triangleIndexOffset;

			//Create triangles based on occluder triangle strip.
			for( int t = 0 ; t < currentOccluder->numberOfPoints - 2 ; t++ ) {
			
				triangleIndexOffset = t + 1;

				//Rasterize every triangle that forms the occluder convex hull.
				rasterizer->rasterizeTriangle(  currentOccluder->points[0].x, currentOccluder->points[0].y,
												currentOccluder->points[triangleIndexOffset].x, currentOccluder->points[triangleIndexOffset].y,
												currentOccluder->points[triangleIndexOffset + 1].x, currentOccluder->points[triangleIndexOffset + 1].y,
												clampTo(currentOccluder->points[0].depth,0.0f,1.0f), //Clamp depth between 0 and 1 inclusive.
												clampTo(currentOccluder->points[triangleIndexOffset].depth,0.0f,1.0f),
												clampTo(currentOccluder->points[triangleIndexOffset + 1].depth,0.0f,1.0f) );

			}
		}
	}

	if( engineMode == Optimized ) 
	{

		int totalTilesDefferedFromRasterization = 0;

		for( int i = 0 ; i < numberOfOccluders ; i++ ) 
		{
			tiledRasterizer->rasterizeConvexHull(occluderArray[i]);

			totalTilesDefferedFromRasterization += tiledRasterizer->tilesDefferredFromRasterization;
		}

		if( drawAllTiles )
			tiledRasterizer->tempRasterFullyCoveredNotRasterized();

		//printf("Tiles avoided: %d\n", totalTilesDefferedFromRasterization);
	}

	
	
}
JSValue JSWebSocket::close(ExecState* exec)
{
    // FIXME: We should implement [Clamp] for IDL binding code generator, and
    // remove this custom method.
    WebSocket* webSocket = static_cast<WebSocket*>(impl());
    size_t argumentCount = exec->argumentCount();
    int code = WebSocketChannel::CloseEventCodeNotSpecified;
    String reason = "";
    if (argumentCount >= 1) {
        JSValue v = exec->argument(0);
        double x = v.toNumber(exec);
        double maxValue = static_cast<double>(std::numeric_limits<uint16_t>::max());
        double minValue = static_cast<double>(std::numeric_limits<uint16_t>::min());
        if (isnan(x))
            x = 0.0;
        else
            x = clampTo(x, minValue, maxValue);
        code = clampToInteger(x);
        if (argumentCount >= 2) {
            reason = ustringToString(exec->argument(1).toString(exec)->value(exec));
            if (exec->hadException()) {
                setDOMException(exec, SYNTAX_ERR);
                return jsUndefined();
            }
        }
    }
    ExceptionCode ec = 0;
    webSocket->close(code, reason, ec);
    setDOMException(exec, ec);
    return jsUndefined();
}
void adjustBoundingBox( Occludee::OccludeeAABB &boundingBox, const int width, const int height )
{

	boundingBox.xMin = clampTo(boundingBox.xMin, 0,  width - 1);
	boundingBox.yMin = clampTo(boundingBox.yMin, 0,  height - 1);

	boundingBox.xMax = clampTo(boundingBox.xMax, 0,  width - 1);
	boundingBox.yMax = clampTo(boundingBox.yMax, 0,  height- 1);
	
	if( boundingBox.xMin > boundingBox.xMax)
		boundingBox.xMin = boundingBox.xMax;

	if( boundingBox.yMin > boundingBox.yMax)
		boundingBox.yMin = boundingBox.yMax;
	
}
OcclusionEngine::OcclusionEngine(int pBufferWidth, int pBufferHeight, OcclusionEngineOptions options)
{
	int tileSize = clampTo(options.tileSize, MIN_TILE_SIZE, MAX_TILE_SIZE );

	if( tileSize % MIN_TILE_SIZE != 0 )
		tileSize = ((int)(tileSize / MIN_TILE_SIZE) + 1) * MIN_TILE_SIZE;

	drawAllTiles = options.drawAllTiles;
	engineMode = (EOcclusionEngineMode)options.engineMode;
	
	depthBuffer = NULL;
	tiledDepthBuffer = NULL;

	bufferWidth = pBufferWidth;
	bufferHeight = pBufferHeight;

	if( engineMode == NormalRasterization ) 
	{
		//Create the depth buffer.
		depthBuffer = new DepthBuffer(bufferWidth, bufferHeight);

		//Create a rasterizer.
		rasterizer = new Rasterizer(depthBuffer);
	}

	if( engineMode == Optimized ) 
	{
		tiledDepthBuffer = new TiledDepthBuffer(bufferWidth, bufferHeight, tileSize);
		tiledRasterizer = new TiledRasterizer(tiledDepthBuffer);

		tiledRasterizer->numberOfThreads = options.numberOfThreads;
	}
}
double AudioBufferSourceHandler::computePlaybackRate()
{
    // Incorporate buffer's sample-rate versus AbstractAudioContext's sample-rate.
    // Normally it's not an issue because buffers are loaded at the
    // AbstractAudioContext's sample-rate, but we can handle it in any case.
    double sampleRateFactor = 1.0;
    if (buffer()) {
        // Use doubles to compute this to full accuracy.
        sampleRateFactor = buffer()->sampleRate() / static_cast<double>(sampleRate());
    }

    // Use finalValue() to incorporate changes of AudioParamTimeline and
    // AudioSummingJunction from m_playbackRate AudioParam.
    double basePlaybackRate = m_playbackRate->finalValue();

    double finalPlaybackRate = sampleRateFactor * basePlaybackRate;

    // Take the detune value into account for the final playback rate.
    finalPlaybackRate *= pow(2, m_detune->finalValue() / 1200);

    // Sanity check the total rate.  It's very important that the resampler not
    // get any bad rate values.
    finalPlaybackRate = clampTo(finalPlaybackRate, 0.0, MaxRate);

    bool isPlaybackRateValid = !std::isnan(finalPlaybackRate) && !std::isinf(finalPlaybackRate);
    ASSERT(isPlaybackRateValid);

    if (!isPlaybackRateValid)
        finalPlaybackRate = 1.0;

    // Record the minimum playback rate for use by handleStoppableSourceNode.
    m_minPlaybackRate = std::min(finalPlaybackRate, m_minPlaybackRate);

    return finalPlaybackRate;
}
示例#10
0
v8::Handle<v8::Value> V8WebSocket::closeCallback(const v8::Arguments& args)
{
    // FIXME: We should implement [Clamp] for IDL binding code generator, and
    // remove this custom method.
    WebSocket* webSocket = toNative(args.Holder());
    int argumentCount = args.Length();
    int code = WebSocketChannel::CloseEventCodeNotSpecified;
    String reason = "";
    if (argumentCount >= 1) {
        double x = args[0]->NumberValue();
        double maxValue = static_cast<double>(std::numeric_limits<uint16_t>::max());
        double minValue = static_cast<double>(std::numeric_limits<uint16_t>::min());
        if (isnan(x))
            x = 0.0;
        else
            x = clampTo(x, minValue, maxValue);
        code = clampToInteger(x);
        if (argumentCount >= 2) {
            v8::TryCatch tryCatch;
            v8::Handle<v8::String> reasonValue = args[1]->ToString();
            if (tryCatch.HasCaught())
                return throwError(tryCatch.Exception());
            reason = toWebCoreString(reasonValue);
        }
    }
    ExceptionCode ec = 0;
    webSocket->close(code, reason, ec);
    if (ec)
        return throwError(ec);
    return v8::Undefined();
}
static void linear(unsigned char* values, const ComponentTransferFunction& transferFunction)
{
    for (unsigned i = 0; i < 256; ++i) {
        double val = transferFunction.slope * i + 255 * transferFunction.intercept;
        val = clampTo(val, 0.0, 255.0);
        values[i] = static_cast<unsigned char>(val);
    }
}
示例#12
0
void GroundAvoidanceAdvisory::updateAltitudeAdvisories(const double descent_velocity) {
	const double advance_altitude_loss = descent_velocity * 2.0;
	const double reaction_altitude_loss = descent_velocity * 1.0;  // TODO 0.45 in A-G mode
	const double roll_altitude_loss = descent_velocity * std::abs(b_Roll->value()) / m_RollRate;
	const double recovery_altitude_loss = b_Velocity->value().length2() * (1.0 - cos(b_Pitch->value())) * m_InverseG;
	const double predicted_altitude_loss = advance_altitude_loss + reaction_altitude_loss + roll_altitude_loss + recovery_altitude_loss;
	const double cas_factor = clampTo(375.0 - convert::mps_kts(b_CAS->value()), 0.0, 50.0);
	const double buffer_factor = cas_factor * (0.125 / 50.0);
	const double buffer_offset = convert::ft_m(cas_factor * 2.0 + 50.0);
	const double buffer = buffer_factor * predicted_altitude_loss + buffer_offset;
	const double alow = convert::ft_m(b_CaraAlow->value());
	const double maximum_loss = b_Position->value().z() - b_GroundZ->value() - buffer - alow;
	const double advance_alert_loss = std::max(maximum_loss - (predicted_altitude_loss - advance_altitude_loss), 0.0);
	b_AltitudeAdvisory->pushOnChange(maximum_loss < (predicted_altitude_loss - advance_altitude_loss));
	b_AdvanceAltitudeAdvisory->value() = maximum_loss < predicted_altitude_loss;
	b_PullupAnticipation->value() = 1.0 - clampTo(advance_alert_loss / descent_velocity * 0.125, 0.0, 1.000001);
}
static void gamma(unsigned char* values, const ComponentTransferFunction& transferFunction)
{
    for (unsigned i = 0; i < 256; ++i) {
        double exponent = transferFunction.exponent; // RCVT doesn't like passing a double and a float to pow, so promote this to double
        double val = 255.0 * (transferFunction.amplitude * pow((i / 255.0), exponent) + transferFunction.offset);
        val = clampTo(val, 0.0, 255.0);
        values[i] = static_cast<unsigned char>(val);
    }
}
ShadowData ShadowData::blend(const ShadowData& from, double progress, const Color& currentColor) const
{
    ASSERT(style() == from.style());
    return ShadowData(blink::blend(from.location(), location(), progress),
        clampTo(blink::blend(from.blur(), blur(), progress), 0.0f),
        blink::blend(from.spread(), spread(), progress),
        style(),
        blink::blend(from.color().resolve(currentColor), color().resolve(currentColor), progress));
}
示例#15
0
void GraphicsLayerBlackBerry::setOpacity(float opacity)
{
    float clampedOpacity = clampTo(opacity, 0.0f, 1.0f);

    if (m_opacity == clampedOpacity)
        return;

    GraphicsLayer::setOpacity(clampedOpacity);
    primaryLayer()->setOpacity(opacity);
}
float OcclusionEngine::getDepthBufferPixel(const int x, const int y)
{
	int clampedX, clampedY;

	clampedX = clampTo(x, 0, bufferWidth - 1);
	clampedY = clampTo(y, 0, bufferHeight - 1);

	if( engineMode == Optimized ) 
	{
		return tiledDepthBuffer->getValue(clampedX, clampedY);
	}

	if( engineMode == NormalRasterization ) 
	{
		return depthBuffer->getValue(clampedX, clampedY);
	}

	return 0;
}
示例#17
0
float PageViewportController::outerBoundedViewportScale(float viewportScale) const
{
    if (m_allowsUserScaling) {
        // Bounded by [0.1, 10.0] like the viewport meta code in WebCore.
        float hardMin = toViewportScale(std::max<float>(0.1, 0.5 * m_minimumScaleToFit));
        float hardMax = toViewportScale(std::min<float>(10, 2 * m_rawAttributes.maximumScale));
        return clampTo(viewportScale, hardMin, hardMax);
    }
    return innerBoundedViewportScale(viewportScale);
}
示例#18
0
FELighting::FELighting(Filter* filter, LightingType lightingType, const Color& lightingColor, float surfaceScale,
    float diffuseConstant, float specularConstant, float specularExponent,
    PassRefPtr<LightSource> lightSource)
    : FilterEffect(filter)
    , m_lightingType(lightingType)
    , m_lightSource(lightSource)
    , m_lightingColor(lightingColor)
    , m_surfaceScale(surfaceScale)
    , m_diffuseConstant(std::max(diffuseConstant, 0.0f))
    , m_specularConstant(std::max(specularConstant, 0.0f))
    , m_specularExponent(clampTo(specularExponent, 1.0f, 128.0f))
{
}
int ScrollbarThemeOverlay::thumbLength(const ScrollbarThemeClient& scrollbar)
{
    int trackLen = trackLength(scrollbar);

    if (!scrollbar.totalSize())
        return trackLen;

    float proportion = static_cast<float>(scrollbar.visibleSize()) / scrollbar.totalSize();
    int length = round(proportion * trackLen);
    int minLen = std::min(minimumThumbLength(scrollbar), trackLen);
    length = clampTo(length, minLen, trackLen);
    return length;
}
static void discrete(unsigned char* values, const ComponentTransferFunction& transferFunction)
{
    const Vector<float>& tableValues = transferFunction.tableValues;
    unsigned n = tableValues.size();
    if (n < 1)
        return;
    for (unsigned i = 0; i < 256; ++i) {
        unsigned k = static_cast<unsigned>((i * n) / 255.0);
        k = std::min(k, n - 1);
        double val = 255 * tableValues[k];
        val = clampTo(val, 0.0, 255.0);
        values[i] = static_cast<unsigned char>(val);
    }
}
示例#21
0
	void update(double dt) {
		double v = m_Channel->value();
		v += m_Increment * dt * m_Rate;
		if (m_DecayCount > 0) {
			m_DecayCount--;
			if (m_Increment == 0.0) {
				if (m_DecayCount == 0) {
					v = 0.0;
				} else {
					v *= m_Decay;
				}
			}
		}
		m_Channel->value() = clampTo(v, m_Minimum, m_Maximum);
	}
static void table(unsigned char* values, const ComponentTransferFunction& transferFunction)
{
    const Vector<float>& tableValues = transferFunction.tableValues;
    unsigned n = tableValues.size();
    if (n < 1)
        return;
    for (unsigned i = 0; i < 256; ++i) {
        double c = i / 255.0;
        unsigned k = static_cast<unsigned>(c * (n - 1));
        double v1 = tableValues[k];
        double v2 = tableValues[std::min((k + 1), (n - 1))];
        double val = 255.0 * (v1 + (c * (n - 1) - k) * (v2 - v1));
        val = clampTo(val, 0.0, 255.0);
        values[i] = static_cast<unsigned char>(val);
    }
}
示例#23
0
double F16FlightModel::calculateYawMoment() const {
	const double p = -m_AngularVelocityBody.y();
	/**
	 * negative since yaw axis (and hence yaw rate) is opposite nasa 1979.
	 */
	const double r = -m_AngularVelocityBody.z();

	/**
	 * cn_da = dcn,da + dcn,da,lef * (1 - dlef/25)
	 */
	double cn_da = m_Cn_da_a_b[m_Alpha][(m_Aileron > 0) ? m_Beta : -m_Beta];
	cn_da += m_ScaleLEF * (m_Cn_da_lef_a_b[m_Alpha][(m_Aileron > 0) ? m_Beta : -m_Beta] - cn_da);

	double cn_p = (m_Cn_p_a[m_Alpha] + m_Cn_p_lef_a[m_Alpha] * m_ScaleLEF) * p;
	double cn_r = (m_Cn_r_a[m_Alpha] + m_Cn_r_lef_a[m_Alpha] * m_ScaleLEF) * r;
	double cn_dr = m_Cn_dr_a_b[m_Alpha][(m_Rudder > 0) ? m_Beta : -m_Beta];

	/**
	 * XXX hack (testing spin control in deep stall trim)  without this "boost" the yaw rate in
	 * a deep stall is about 45 deg/sec, compared with about 20 deg/sec cited in the nasa paper.
	 * this could be due to differences between the nasa data and the data used in the fm.  For
	 * convenience, the fm data was taken from the "non-linear f-16 simulation using simulink
	 * and matlab" package in predigitized form.  This data should be identical to the nasa data,
	 * but in practice there are small variations.
	 */
	cn_dr *= clampTo((toDegrees(m_Alpha) - 40) * 0.8, 1.0, 20.0);
	cn_dr = -fabs(cn_dr);

	/**
	 * note that these offsets are in internal body coordinates, not fm coordinates.
	 */
	double offset_y = m_CenterOfMassBody.y() - m_CL_x_m[0.0];  /** @todo should this vary with mach? */
	double offset_x = m_CenterOfMassBody.x();

	double moment =
		m_Cn_de_a_b[m_Elevator][m_Alpha][m_Beta] +
		m_Cn_lef_a_b[m_Alpha][m_Beta] * m_ScaleLEF +
		(cn_p + cn_r) * m_WingSpan * m_Inv2V +
		cn_da * m_Aileron +
		cn_dr * m_Rudder +
		(offset_x * m_CX - offset_y * m_CY) / m_WingSpan;

	/**
	 * negative since yaw axis (and hence yaw moment) is opposite nasa 1979.
	 */
	return -moment * m_qBarS * m_WingSpan;
}
示例#24
0
double StepsTimingFunction::evaluate(double fraction, double) const
{
    double startOffset = 0;
    switch (m_stepAtPosition) {
    case Start:
        startOffset = 1;
        break;
    case Middle:
        startOffset = 0.5;
        break;
    case End:
        startOffset = 0;
        break;
    default:
        ASSERT_NOT_REACHED();
        break;
    }
    return clampTo(floor((m_steps * fraction) + startOffset) / m_steps, 0.0, 1.0);
}
示例#25
0
int HRTFPanner::calculateDesiredAzimuthIndexAndBlend(double azimuth,
                                                     double& azimuthBlend) {
  // Convert the azimuth angle from the range -180 -> +180 into the range 0 ->
  // 360.  The azimuth index may then be calculated from this positive value.
  if (azimuth < 0)
    azimuth += 360.0;

  int numberOfAzimuths = HRTFDatabase::numberOfAzimuths();
  const double angleBetweenAzimuths = 360.0 / numberOfAzimuths;

  // Calculate the azimuth index and the blend (0 -> 1) for interpolation.
  double desiredAzimuthIndexFloat = azimuth / angleBetweenAzimuths;
  int desiredAzimuthIndex = static_cast<int>(desiredAzimuthIndexFloat);
  azimuthBlend =
      desiredAzimuthIndexFloat - static_cast<double>(desiredAzimuthIndex);

  // We don't immediately start using this azimuth index, but instead approach
  // this index from the last index we rendered at.  This minimizes the clicks
  // and graininess for moving sources which occur otherwise.
  desiredAzimuthIndex = clampTo(desiredAzimuthIndex, 0, numberOfAzimuths - 1);
  return desiredAzimuthIndex;
}
示例#26
0
void FilterEffectRenderer::build(Document* document, const FilterOperations& operations)
{
#if !ENABLE(CSS_SHADERS) || !ENABLE(WEBGL)
    UNUSED_PARAM(document);
#else
    CustomFilterProgramList cachedCustomFilterPrograms;
#endif

    m_effects.clear();

    RefPtr<FilterEffect> previousEffect;
    for (size_t i = 0; i < operations.operations().size(); ++i) {
        RefPtr<FilterEffect> effect;
        FilterOperation* filterOperation = operations.operations().at(i).get();
        switch (filterOperation->getOperationType()) {
        case FilterOperation::REFERENCE: {
            // FIXME: Not yet implemented.
            // https://bugs.webkit.org/show_bug.cgi?id=72443
            break;
        }
        case FilterOperation::GRAYSCALE: {
            BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
            Vector<float> inputParameters;
            double oneMinusAmount = clampTo(1 - colorMatrixOperation->amount(), 0.0, 1.0);

            // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#grayscaleEquivalent
            // for information on parameters.

            inputParameters.append(narrowPrecisionToFloat(0.2126 + 0.7874 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.7152 + 0.2848 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.0722 + 0.9278 * oneMinusAmount));
            endMatrixRow(inputParameters);

            lastMatrixRow(inputParameters);

            effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_MATRIX, inputParameters);
            break;
        }
        case FilterOperation::SEPIA: {
            BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
            Vector<float> inputParameters;
            double oneMinusAmount = clampTo(1 - colorMatrixOperation->amount(), 0.0, 1.0);

            // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#sepiaEquivalent
            // for information on parameters.

            inputParameters.append(narrowPrecisionToFloat(0.393 + 0.607 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.769 - 0.769 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.189 - 0.189 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.349 - 0.349 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.686 + 0.314 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.168 - 0.168 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.272 - 0.272 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.534 - 0.534 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.131 + 0.869 * oneMinusAmount));
            endMatrixRow(inputParameters);

            lastMatrixRow(inputParameters);

            effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_MATRIX, inputParameters);
            break;
        }
        case FilterOperation::SATURATE: {
            BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
            Vector<float> inputParameters;
            inputParameters.append(narrowPrecisionToFloat(colorMatrixOperation->amount()));
            effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_SATURATE, inputParameters);
            break;
        }
        case FilterOperation::HUE_ROTATE: {
            BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
            Vector<float> inputParameters;
            inputParameters.append(narrowPrecisionToFloat(colorMatrixOperation->amount()));
            effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_HUEROTATE, inputParameters);
            break;
        }
        case FilterOperation::INVERT: {
            BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
            Vector<float> transferParameters;
            transferParameters.append(narrowPrecisionToFloat(componentTransferOperation->amount()));
            transferParameters.append(narrowPrecisionToFloat(1 - componentTransferOperation->amount()));
            transferFunction.tableValues = transferParameters;

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction);
            break;
        }
        case FilterOperation::OPACITY: {
            BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
            Vector<float> transferParameters;
            transferParameters.append(0);
            transferParameters.append(narrowPrecisionToFloat(componentTransferOperation->amount()));
            transferFunction.tableValues = transferParameters;

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(this, nullFunction, nullFunction, nullFunction, transferFunction);
            break;
        }
        case FilterOperation::BRIGHTNESS: {
            BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
            transferFunction.slope = 1;
            transferFunction.intercept = narrowPrecisionToFloat(componentTransferOperation->amount());

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction);
            break;
        }
        case FilterOperation::CONTRAST: {
            BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
            float amount = narrowPrecisionToFloat(componentTransferOperation->amount());
            transferFunction.slope = amount;
            transferFunction.intercept = -0.5 * amount + 0.5;
            
            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction);
            break;
        }
        case FilterOperation::BLUR: {
            BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation);
            float stdDeviation = blurOperation->stdDeviation().calcFloatValue(0);
            effect = FEGaussianBlur::create(this, stdDeviation, stdDeviation);
            break;
        }
        case FilterOperation::DROP_SHADOW: {
            DropShadowFilterOperation* dropShadowOperation = static_cast<DropShadowFilterOperation*>(filterOperation);
            effect = FEDropShadow::create(this, dropShadowOperation->stdDeviation(), dropShadowOperation->stdDeviation(),
                                                dropShadowOperation->x(), dropShadowOperation->y(), dropShadowOperation->color(), 1);
            break;
        }
#if ENABLE(CSS_SHADERS)
        case FilterOperation::CUSTOM: {
#if ENABLE(WEBGL)
            if (!isCSSCustomFilterEnabled(document))
                continue;
            
            CustomFilterOperation* customFilterOperation = static_cast<CustomFilterOperation*>(filterOperation);
            RefPtr<CustomFilterProgram> program = customFilterOperation->program();
            cachedCustomFilterPrograms.append(program);
            program->addClient(this);
            if (program->isLoaded()) {
                effect = FECustomFilter::create(this, document, program, customFilterOperation->parameters(),
                                                customFilterOperation->meshRows(), customFilterOperation->meshColumns(),
                                                customFilterOperation->meshBoxType(), customFilterOperation->meshType());
            }
#endif
            break;
        }
#endif
        default:
            break;
        }

        if (effect) {
            // Unlike SVG, filters applied here should not clip to their primitive subregions.
            effect->setClipsToBounds(false);
            
            if (previousEffect)
                effect->inputEffects().append(previousEffect);
            m_effects.append(effect);
            previousEffect = effect.release();
        }
    }

    // If we didn't make a real filter, create a null-op (FEMerge with one input).
    if (!previousEffect)
        m_effects.append(FEMerge::create(this));

    m_effects.first()->inputEffects().append(m_sourceGraphic);
    setMaxEffectRects(m_sourceDrawingRegion);
    
#if ENABLE(CSS_SHADERS) && ENABLE(WEBGL)
    removeCustomFilterClients();
    m_cachedCustomFilterPrograms.swap(cachedCustomFilterPrograms);
#endif
}
bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations& operations)
{
    m_hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels();

    // Inverse zoom the pre-zoomed CSS shorthand filters, so that they are in the same zoom as the unzoomed reference filters.
    const RenderStyle* style = renderer->style();
    float invZoom = style ? 1.0f / style->effectiveZoom() : 1.0f;

    RefPtr<FilterEffect> previousEffect = m_sourceGraphic;
    for (size_t i = 0; i < operations.operations().size(); ++i) {
        RefPtr<FilterEffect> effect;
        FilterOperation* filterOperation = operations.operations().at(i).get();
        switch (filterOperation->type()) {
        case FilterOperation::REFERENCE: {
            effect = ReferenceFilterBuilder::build(this, renderer, previousEffect.get(), toReferenceFilterOperation(filterOperation));
            break;
        }
        case FilterOperation::GRAYSCALE: {
            Vector<float> inputParameters;
            double oneMinusAmount = clampTo(1 - toBasicColorMatrixFilterOperation(filterOperation)->amount(), 0.0, 1.0);

            // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#grayscaleEquivalent
            // for information on parameters.

            inputParameters.append(narrowPrecisionToFloat(0.2126 + 0.7874 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.7152 + 0.2848 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.0722 + 0.9278 * oneMinusAmount));
            endMatrixRow(inputParameters);

            lastMatrixRow(inputParameters);

            effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_MATRIX, inputParameters);
            break;
        }
        case FilterOperation::SEPIA: {
            Vector<float> inputParameters;
            double oneMinusAmount = clampTo(1 - toBasicColorMatrixFilterOperation(filterOperation)->amount(), 0.0, 1.0);

            // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#sepiaEquivalent
            // for information on parameters.

            inputParameters.append(narrowPrecisionToFloat(0.393 + 0.607 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.769 - 0.769 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.189 - 0.189 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.349 - 0.349 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.686 + 0.314 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.168 - 0.168 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.272 - 0.272 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.534 - 0.534 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.131 + 0.869 * oneMinusAmount));
            endMatrixRow(inputParameters);

            lastMatrixRow(inputParameters);

            effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_MATRIX, inputParameters);
            break;
        }
        case FilterOperation::SATURATE: {
            Vector<float> inputParameters;
            inputParameters.append(narrowPrecisionToFloat(toBasicColorMatrixFilterOperation(filterOperation)->amount()));
            effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_SATURATE, inputParameters);
            break;
        }
        case FilterOperation::HUE_ROTATE: {
            Vector<float> inputParameters;
            inputParameters.append(narrowPrecisionToFloat(toBasicColorMatrixFilterOperation(filterOperation)->amount()));
            effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_HUEROTATE, inputParameters);
            break;
        }
        case FilterOperation::INVERT: {
            BasicComponentTransferFilterOperation* componentTransferOperation = toBasicComponentTransferFilterOperation(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
            Vector<float> transferParameters;
            transferParameters.append(narrowPrecisionToFloat(componentTransferOperation->amount()));
            transferParameters.append(narrowPrecisionToFloat(1 - componentTransferOperation->amount()));
            transferFunction.tableValues = transferParameters;

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction);
            break;
        }
        case FilterOperation::OPACITY: {
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
            Vector<float> transferParameters;
            transferParameters.append(0);
            transferParameters.append(narrowPrecisionToFloat(toBasicComponentTransferFilterOperation(filterOperation)->amount()));
            transferFunction.tableValues = transferParameters;

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(this, nullFunction, nullFunction, nullFunction, transferFunction);
            break;
        }
        case FilterOperation::BRIGHTNESS: {
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
            transferFunction.slope = narrowPrecisionToFloat(toBasicComponentTransferFilterOperation(filterOperation)->amount());
            transferFunction.intercept = 0;

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction);
            break;
        }
        case FilterOperation::CONTRAST: {
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
            float amount = narrowPrecisionToFloat(toBasicComponentTransferFilterOperation(filterOperation)->amount());
            transferFunction.slope = amount;
            transferFunction.intercept = -0.5 * amount + 0.5;

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction);
            break;
        }
        case FilterOperation::BLUR: {
            float stdDeviation = floatValueForLength(toBlurFilterOperation(filterOperation)->stdDeviation(), 0) * invZoom;
            effect = FEGaussianBlur::create(this, stdDeviation, stdDeviation);
            break;
        }
        case FilterOperation::DROP_SHADOW: {
            DropShadowFilterOperation* dropShadowOperation = toDropShadowFilterOperation(filterOperation);
            float stdDeviation = dropShadowOperation->stdDeviation() * invZoom;
            float x = dropShadowOperation->x() * invZoom;
            float y = dropShadowOperation->y() * invZoom;
            effect = FEDropShadow::create(this, stdDeviation, stdDeviation, x, y, dropShadowOperation->color(), 1);
            break;
        }
        default:
            break;
        }

        if (effect) {
            if (filterOperation->type() != FilterOperation::REFERENCE) {
                // Unlike SVG, filters applied here should not clip to their primitive subregions.
                effect->setClipsToBounds(false);
                effect->setOperatingColorSpace(ColorSpaceDeviceRGB);
                effect->inputEffects().append(previousEffect);
            }
            previousEffect = effect.release();
        }
    }

    // We need to keep the old effects alive until this point, so that SVG reference filters
    // can share cached resources across frames.
    m_lastEffect = previousEffect;

    // If we didn't make any effects, tell our caller we are not valid
    if (!m_lastEffect.get())
        return false;

    return true;
}
示例#28
0
bool FilterEffectRenderer::build(Document* document, const FilterOperations& operations)
{
#if !ENABLE(CSS_SHADERS) || !USE(3D_GRAPHICS)
    UNUSED_PARAM(document);
#endif

#if ENABLE(CSS_SHADERS)
    m_hasCustomShaderFilter = false;
#endif
    m_hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels();
    if (m_hasFilterThatMovesPixels)
        operations.getOutsets(m_topOutset, m_rightOutset, m_bottomOutset, m_leftOutset);
    
    // Keep the old effects on the stack until we've created the new effects.
    // New FECustomFilters can reuse cached resources from old FECustomFilters.
    FilterEffectList oldEffects;
    m_effects.swap(oldEffects);

    RefPtr<FilterEffect> previousEffect = m_sourceGraphic;
    for (size_t i = 0; i < operations.operations().size(); ++i) {
        RefPtr<FilterEffect> effect;
        FilterOperation* filterOperation = operations.operations().at(i).get();
        switch (filterOperation->getOperationType()) {
        case FilterOperation::REFERENCE: {
            ReferenceFilterOperation* referenceOperation = static_cast<ReferenceFilterOperation*>(filterOperation);
            effect = buildReferenceFilter(document, previousEffect, referenceOperation);
            referenceOperation->setFilterEffect(effect);
            break;
        }
        case FilterOperation::GRAYSCALE: {
            BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
            Vector<float> inputParameters;
            double oneMinusAmount = clampTo(1 - colorMatrixOperation->amount(), 0.0, 1.0);

            // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#grayscaleEquivalent
            // for information on parameters.

            inputParameters.append(narrowPrecisionToFloat(0.2126 + 0.7874 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.7152 + 0.2848 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.0722 + 0.9278 * oneMinusAmount));
            endMatrixRow(inputParameters);

            lastMatrixRow(inputParameters);

            effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_MATRIX, inputParameters);
            break;
        }
        case FilterOperation::SEPIA: {
            BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
            Vector<float> inputParameters;
            double oneMinusAmount = clampTo(1 - colorMatrixOperation->amount(), 0.0, 1.0);

            // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#sepiaEquivalent
            // for information on parameters.

            inputParameters.append(narrowPrecisionToFloat(0.393 + 0.607 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.769 - 0.769 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.189 - 0.189 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.349 - 0.349 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.686 + 0.314 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.168 - 0.168 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.272 - 0.272 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.534 - 0.534 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.131 + 0.869 * oneMinusAmount));
            endMatrixRow(inputParameters);

            lastMatrixRow(inputParameters);

            effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_MATRIX, inputParameters);
            break;
        }
        case FilterOperation::SATURATE: {
            BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
            Vector<float> inputParameters;
            inputParameters.append(narrowPrecisionToFloat(colorMatrixOperation->amount()));
            effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_SATURATE, inputParameters);
            break;
        }
        case FilterOperation::HUE_ROTATE: {
            BasicColorMatrixFilterOperation* colorMatrixOperation = static_cast<BasicColorMatrixFilterOperation*>(filterOperation);
            Vector<float> inputParameters;
            inputParameters.append(narrowPrecisionToFloat(colorMatrixOperation->amount()));
            effect = FEColorMatrix::create(this, FECOLORMATRIX_TYPE_HUEROTATE, inputParameters);
            break;
        }
        case FilterOperation::INVERT: {
            BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
            Vector<float> transferParameters;
            transferParameters.append(narrowPrecisionToFloat(componentTransferOperation->amount()));
            transferParameters.append(narrowPrecisionToFloat(1 - componentTransferOperation->amount()));
            transferFunction.tableValues = transferParameters;

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction);
            break;
        }
        case FilterOperation::OPACITY: {
            BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
            Vector<float> transferParameters;
            transferParameters.append(0);
            transferParameters.append(narrowPrecisionToFloat(componentTransferOperation->amount()));
            transferFunction.tableValues = transferParameters;

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(this, nullFunction, nullFunction, nullFunction, transferFunction);
            break;
        }
        case FilterOperation::BRIGHTNESS: {
            BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
            transferFunction.slope = 1;
            transferFunction.intercept = narrowPrecisionToFloat(componentTransferOperation->amount());

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction);
            break;
        }
        case FilterOperation::CONTRAST: {
            BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
            float amount = narrowPrecisionToFloat(componentTransferOperation->amount());
            transferFunction.slope = amount;
            transferFunction.intercept = -0.5 * amount + 0.5;
            
            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction);
            break;
        }
        case FilterOperation::BLUR: {
            BlurFilterOperation* blurOperation = static_cast<BlurFilterOperation*>(filterOperation);
            float stdDeviation = floatValueForLength(blurOperation->stdDeviation(), 0);
            effect = FEGaussianBlur::create(this, stdDeviation, stdDeviation);
            break;
        }
        case FilterOperation::DROP_SHADOW: {
            DropShadowFilterOperation* dropShadowOperation = static_cast<DropShadowFilterOperation*>(filterOperation);
            effect = FEDropShadow::create(this, dropShadowOperation->stdDeviation(), dropShadowOperation->stdDeviation(),
                                                dropShadowOperation->x(), dropShadowOperation->y(), dropShadowOperation->color(), 1);
            break;
        }
#if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
        case FilterOperation::CUSTOM:
            // CUSTOM operations are always converted to VALIDATED_CUSTOM before getting here.
            // The conversion happens in RenderLayer::computeFilterOperations.
            ASSERT_NOT_REACHED();
            break;
        case FilterOperation::VALIDATED_CUSTOM: {
            ValidatedCustomFilterOperation* customFilterOperation = static_cast<ValidatedCustomFilterOperation*>(filterOperation);
            effect = createCustomFilterEffect(this, document, customFilterOperation);
            if (effect)
                m_hasCustomShaderFilter = true;
            break;
        }
#endif
        default:
            break;
        }

        if (effect) {
            // Unlike SVG, filters applied here should not clip to their primitive subregions.
            effect->setClipsToBounds(false);
            effect->setColorSpace(ColorSpaceDeviceRGB);
            
            if (filterOperation->getOperationType() != FilterOperation::REFERENCE) {
                effect->inputEffects().append(previousEffect);
                m_effects.append(effect);
            }
            previousEffect = effect.release();
        }
    }

    // If we didn't make any effects, tell our caller we are not valid
    if (!m_effects.size())
        return false;

    setMaxEffectRects(m_sourceDrawingRegion);
    
    return true;
}
示例#29
0
float PageViewportController::innerBoundedViewportScale(float viewportScale) const
{
    return clampTo(viewportScale, toViewportScale(m_minimumScaleToFit), toViewportScale(m_rawAttributes.maximumScale));
}
示例#30
0
bool FilterEffectRenderer::build(RenderElement* renderer, const FilterOperations& operations, FilterConsumer consumer)
{
    m_hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels();
    if (m_hasFilterThatMovesPixels)
        m_outsets = operations.outsets();

    m_effects.clear();

    RefPtr<FilterEffect> previousEffect = m_sourceGraphic;
    for (size_t i = 0; i < operations.operations().size(); ++i) {
        RefPtr<FilterEffect> effect;
        FilterOperation& filterOperation = *operations.operations().at(i);
        switch (filterOperation.type()) {
        case FilterOperation::REFERENCE: {
            ReferenceFilterOperation& referenceOperation = downcast<ReferenceFilterOperation>(filterOperation);
            effect = buildReferenceFilter(renderer, previousEffect, &referenceOperation);
            referenceOperation.setFilterEffect(effect);
            break;
        }
        case FilterOperation::GRAYSCALE: {
            BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
            Vector<float> inputParameters;
            double oneMinusAmount = clampTo(1 - colorMatrixOperation.amount(), 0.0, 1.0);

            // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#grayscaleEquivalent
            // for information on parameters.

            inputParameters.append(narrowPrecisionToFloat(0.2126 + 0.7874 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.7152 + 0.2848 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.0722 - 0.0722 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.2126 - 0.2126 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.7152 - 0.7152 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.0722 + 0.9278 * oneMinusAmount));
            endMatrixRow(inputParameters);

            lastMatrixRow(inputParameters);

            effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_MATRIX, inputParameters);
            break;
        }
        case FilterOperation::SEPIA: {
            BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
            Vector<float> inputParameters;
            double oneMinusAmount = clampTo(1 - colorMatrixOperation.amount(), 0.0, 1.0);

            // See https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#sepiaEquivalent
            // for information on parameters.

            inputParameters.append(narrowPrecisionToFloat(0.393 + 0.607 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.769 - 0.769 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.189 - 0.189 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.349 - 0.349 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.686 + 0.314 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.168 - 0.168 * oneMinusAmount));
            endMatrixRow(inputParameters);

            inputParameters.append(narrowPrecisionToFloat(0.272 - 0.272 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.534 - 0.534 * oneMinusAmount));
            inputParameters.append(narrowPrecisionToFloat(0.131 + 0.869 * oneMinusAmount));
            endMatrixRow(inputParameters);

            lastMatrixRow(inputParameters);

            effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_MATRIX, inputParameters);
            break;
        }
        case FilterOperation::SATURATE: {
            BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
            Vector<float> inputParameters;
            inputParameters.append(narrowPrecisionToFloat(colorMatrixOperation.amount()));
            effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_SATURATE, inputParameters);
            break;
        }
        case FilterOperation::HUE_ROTATE: {
            BasicColorMatrixFilterOperation& colorMatrixOperation = downcast<BasicColorMatrixFilterOperation>(filterOperation);
            Vector<float> inputParameters;
            inputParameters.append(narrowPrecisionToFloat(colorMatrixOperation.amount()));
            effect = FEColorMatrix::create(*this, FECOLORMATRIX_TYPE_HUEROTATE, inputParameters);
            break;
        }
        case FilterOperation::INVERT: {
            BasicComponentTransferFilterOperation& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
            Vector<float> transferParameters;
            transferParameters.append(narrowPrecisionToFloat(componentTransferOperation.amount()));
            transferParameters.append(narrowPrecisionToFloat(1 - componentTransferOperation.amount()));
            transferFunction.tableValues = transferParameters;

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(*this, transferFunction, transferFunction, transferFunction, nullFunction);
            break;
        }
        case FilterOperation::OPACITY: {
            BasicComponentTransferFilterOperation& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_TABLE;
            Vector<float> transferParameters;
            transferParameters.append(0);
            transferParameters.append(narrowPrecisionToFloat(componentTransferOperation.amount()));
            transferFunction.tableValues = transferParameters;

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(*this, nullFunction, nullFunction, nullFunction, transferFunction);
            break;
        }
        case FilterOperation::BRIGHTNESS: {
            BasicComponentTransferFilterOperation& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
            transferFunction.slope = narrowPrecisionToFloat(componentTransferOperation.amount());
            transferFunction.intercept = 0;

            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(*this, transferFunction, transferFunction, transferFunction, nullFunction);
            break;
        }
        case FilterOperation::CONTRAST: {
            BasicComponentTransferFilterOperation& componentTransferOperation = downcast<BasicComponentTransferFilterOperation>(filterOperation);
            ComponentTransferFunction transferFunction;
            transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
            float amount = narrowPrecisionToFloat(componentTransferOperation.amount());
            transferFunction.slope = amount;
            transferFunction.intercept = -0.5 * amount + 0.5;
            
            ComponentTransferFunction nullFunction;
            effect = FEComponentTransfer::create(*this, transferFunction, transferFunction, transferFunction, nullFunction);
            break;
        }
        case FilterOperation::BLUR: {
            BlurFilterOperation& blurOperation = downcast<BlurFilterOperation>(filterOperation);
            float stdDeviation = floatValueForLength(blurOperation.stdDeviation(), 0);
            effect = FEGaussianBlur::create(*this, stdDeviation, stdDeviation, consumer == FilterProperty ? EDGEMODE_NONE : EDGEMODE_DUPLICATE);
            break;
        }
        case FilterOperation::DROP_SHADOW: {
            DropShadowFilterOperation& dropShadowOperation = downcast<DropShadowFilterOperation>(filterOperation);
            effect = FEDropShadow::create(*this, dropShadowOperation.stdDeviation(), dropShadowOperation.stdDeviation(),
                dropShadowOperation.x(), dropShadowOperation.y(), dropShadowOperation.color(), 1);
            break;
        }
        default:
            break;
        }

        if (effect) {
            // Unlike SVG Filters and CSSFilterImages, filter functions on the filter
            // property applied here should not clip to their primitive subregions.
            effect->setClipsToBounds(consumer == FilterFunction);
            effect->setOperatingColorSpace(ColorSpaceSRGB);
            
            if (filterOperation.type() != FilterOperation::REFERENCE) {
                effect->inputEffects().append(previousEffect);
                m_effects.append(effect);
            }
            previousEffect = effect.release();
        }
    }

    // If we didn't make any effects, tell our caller we are not valid
    if (!m_effects.size())
        return false;

    setMaxEffectRects(m_sourceDrawingRegion);
    
    return true;
}