Beispiel #1
0
void LineWidth::shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject* newFloat)
{
    LayoutUnit height = m_block.logicalHeight();
    if (height < m_block.logicalTopForFloat(newFloat) || height >= m_block.logicalBottomForFloat(newFloat))
        return;

#if ENABLE(CSS_SHAPES)
    // When floats with shape outside are stacked, the floats are positioned based on the margin box of the float,
    // not the shape's contour. Since we computed the width based on the shape contour when we added the float,
    // when we add a subsequent float on the same line, we need to undo the shape delta in order to position
    // based on the margin box. In order to do this, we need to walk back through the floating object list to find
    // the first previous float that is on the same side as our newFloat.
    ShapeOutsideInfo* previousShapeOutsideInfo = 0;
    const FloatingObjectSet& floatingObjectSet = m_block.m_floatingObjects->set();
    auto it = floatingObjectSet.end();
    auto begin = floatingObjectSet.begin();
    LayoutUnit lineHeight = m_block.lineHeight(m_isFirstLine, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
    for (--it; it != begin; --it) {
        FloatingObject* previousFloat = it->get();
        if (previousFloat != newFloat && previousFloat->type() == newFloat->type()) {
            previousShapeOutsideInfo = previousFloat->renderer().shapeOutsideInfo();
            if (previousShapeOutsideInfo)
                previousShapeOutsideInfo->updateDeltasForContainingBlockLine(&m_block, previousFloat, m_block.logicalHeight(), lineHeight);
            break;
        }
    }

    ShapeOutsideInfo* shapeOutsideInfo = newFloat->renderer().shapeOutsideInfo();
    if (shapeOutsideInfo)
        shapeOutsideInfo->updateDeltasForContainingBlockLine(&m_block, newFloat, m_block.logicalHeight(), lineHeight);
#endif

    if (newFloat->type() == FloatingObject::FloatLeft) {
        float newLeft = m_block.logicalRightForFloat(newFloat);
#if ENABLE(CSS_SHAPES)
        if (previousShapeOutsideInfo)
            newLeft -= previousShapeOutsideInfo->rightMarginBoxDelta();
        if (shapeOutsideInfo)
            newLeft += shapeOutsideInfo->rightMarginBoxDelta();
#endif

        if (shouldIndentText() && m_block.style()->isLeftToRightDirection())
            newLeft += floorToInt(m_block.textIndentOffset());
        m_left = std::max<float>(m_left, newLeft);
    } else {
        float newRight = m_block.logicalLeftForFloat(newFloat);
#if ENABLE(CSS_SHAPES)
        if (previousShapeOutsideInfo)
            newRight -= previousShapeOutsideInfo->leftMarginBoxDelta();
        if (shapeOutsideInfo)
            newRight += shapeOutsideInfo->leftMarginBoxDelta();
#endif

        if (shouldIndentText() && !m_block.style()->isLeftToRightDirection())
            newRight -= floorToInt(m_block.textIndentOffset());
        m_right = std::min<float>(m_right, newRight);
    }

    computeAvailableWidthFromLeftAndRight();
}
Beispiel #2
0
Spectrum MIPMap::getValue(Float u, Float v, 
		Float dudx, Float dudy, Float dvdx, Float dvdy) const {
	if (m_filterType == ETrilinear) {
		++mipmapLookups;
		/* Conservatively estimate a square lookup region */
		Float width = 2.0f * std::max(
			std::max(std::abs(dudx), std::abs(dudy)),
			std::max(std::abs(dvdx), std::abs(dvdy)));
		Float mipmapLevel = m_levels - 1 + 
			log2(std::max(width, (Float) 1e-8f));

		if (mipmapLevel < 0) {
			/* The lookup is smaller than one pixel */
			return triangle(0, u, v);
		} else if (mipmapLevel >= m_levels - 1) {
			/* The lookup is larger than the whole texture */
			return getTexel(m_levels - 1, 0, 0);
		} else {
			/* Tri-linear interpolation */
			int level = (int) mipmapLevel;
			Float delta = mipmapLevel - level;
			return triangle(level, u, v) * (1.0f - delta)
				+ triangle(level, u, v) * delta;
		}
	} else if (m_filterType == EEWA) {
		if (dudx*dudx + dudy*dudy < dvdx*dvdx + dvdy*dvdy) {
			std::swap(dudx, dvdx);
			std::swap(dudy, dvdy);
		}

		Float majorLength = std::sqrt(dudx * dudx + dudy * dudy);
		Float minorLength = std::sqrt(dvdx * dvdx + dvdy * dvdy);

		if (minorLength * m_maxAnisotropy < majorLength && minorLength > 0.0f) {
			Float scale = majorLength / (minorLength * m_maxAnisotropy);
			dvdx *= scale; dvdy *= scale;
			minorLength *= scale;
		}

		if (minorLength == 0)
			return triangle(0, u, v);
	
		// The min() below avoids overflow in the int conversion when lod=inf
		Float lod = 
			std::min(std::max((Float) 0, m_levels - 1 + log2(minorLength)), 
				(Float) (m_levels-1));
		int ilod = floorToInt(lod);
		Float d = lod - ilod;

		return EWA(u, v, dudx, dudy, dvdx, dvdy, ilod)   * (1-d) +
			   EWA(u, v, dudx, dudy, dvdx, dvdy, ilod+1) * d;
	} else {
		int xPos = floorToInt(u*m_levelWidth[0]),
			yPos = floorToInt(v*m_levelHeight[0]);
		return getTexel(0, xPos, yPos);
	}
}
Beispiel #3
0
void LineWidth::shrinkAvailableWidthForNewFloatIfNeeded(
    const FloatingObject& newFloat) {
  LayoutUnit height = m_block.logicalHeight();
  if (height < m_block.logicalTopForFloat(newFloat) ||
      height >= m_block.logicalBottomForFloat(newFloat))
    return;

  ShapeOutsideDeltas shapeDeltas;
  if (ShapeOutsideInfo* shapeOutsideInfo =
          newFloat.layoutObject()->shapeOutsideInfo()) {
    LayoutUnit lineHeight = m_block.lineHeight(
        m_isFirstLine,
        m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine,
        PositionOfInteriorLineBoxes);
    shapeDeltas = shapeOutsideInfo->computeDeltasForContainingBlockLine(
        m_block, newFloat, m_block.logicalHeight(), lineHeight);
  }

  if (newFloat.getType() == FloatingObject::FloatLeft) {
    LayoutUnit newLeft = m_block.logicalRightForFloat(newFloat);
    if (shapeDeltas.isValid()) {
      if (shapeDeltas.lineOverlapsShape()) {
        newLeft += shapeDeltas.rightMarginBoxDelta();
      } else {
        // Per the CSS Shapes spec, If the line doesn't overlap the shape, then
        // ignore this shape for this line.
        newLeft = m_left;
      }
    }
    if (indentText() == IndentText && m_block.style()->isLeftToRightDirection())
      newLeft += floorToInt(m_block.textIndentOffset());
    m_left = std::max(m_left, newLeft);
  } else {
    LayoutUnit newRight = m_block.logicalLeftForFloat(newFloat);
    if (shapeDeltas.isValid()) {
      if (shapeDeltas.lineOverlapsShape()) {
        newRight += shapeDeltas.leftMarginBoxDelta();
      } else {
        // Per the CSS Shapes spec, If the line doesn't overlap the shape, then
        // ignore this shape for this line.
        newRight = m_right;
      }
    }
    if (indentText() == IndentText &&
        !m_block.style()->isLeftToRightDirection())
      newRight -= floorToInt(m_block.textIndentOffset());
    m_right = std::min(m_right, newRight);
  }

  computeAvailableWidthFromLeftAndRight();
}
	inline Spectrum getValue(const Point2 &uv) const {
		Float x = uv.x - floorToInt(uv.x);
		Float y = uv.y - floorToInt(uv.y);

		if (x > .5)
			x -= 1;
		if (y > .5)
			y -= 1;

		if (std::abs(x) < m_lineWidth || std::abs(y) < m_lineWidth)
			return m_color1;
		else
			return m_color0;
	}
Beispiel #5
0
Spectrum MIPMap::triangle(int level, Float x, Float y) const {
	if (m_filterType == ENone) {
		int xPos = floorToInt(x*m_levelWidth[0]),
			yPos = floorToInt(y*m_levelHeight[0]);
		return getTexel(0, xPos, yPos);
	} else {
		level = clamp(level, 0, m_levels - 1);
		x = x * m_levelWidth[level] - 0.5f;
		y = y * m_levelHeight[level] - 0.5f;
		int xPos = floorToInt(x), yPos = floorToInt(y);
		Float dx = x - xPos, dy = y - yPos;
		return getTexel(level, xPos, yPos) * (1.0f - dx) * (1.0f - dy)
			+ getTexel(level, xPos, yPos + 1) * (1.0f - dx) * dy
			+ getTexel(level, xPos + 1, yPos) * dx * (1.0f - dy)
			+ getTexel(level, xPos + 1, yPos + 1) * dx * dy;
	}	
}
Beispiel #6
0
void LineWidth::shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject* newFloat)
{
    LayoutUnit height = m_block.logicalHeight();
    if (height < m_block.logicalTopForFloat(newFloat) || height >= m_block.logicalBottomForFloat(newFloat))
        return;

#if ENABLE(CSS_SHAPES)
    ShapeOutsideDeltas shapeDeltas;
    if (ShapeOutsideInfo* shapeOutsideInfo = newFloat->renderer().shapeOutsideInfo()) {
        LayoutUnit lineHeight = m_block.lineHeight(m_isFirstLine, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
        shapeDeltas = shapeOutsideInfo->computeDeltasForContainingBlockLine(m_block, *newFloat, m_block.logicalHeight(), lineHeight);
    }
#endif

    if (newFloat->type() == FloatingObject::FloatLeft) {
        float newLeft = m_block.logicalRightForFloat(newFloat);
        if (shouldIndentText() && m_block.style().isLeftToRightDirection())
            newLeft += floorToInt(m_block.textIndentOffset());
#if ENABLE(CSS_SHAPES)
        if (shapeDeltas.isValid()) {
            if (shapeDeltas.lineOverlapsShape())
                newLeft += shapeDeltas.rightMarginBoxDelta();
            else // If the line doesn't overlap the shape, then we need to act as if this float didn't exist.
                newLeft = m_left;
        }
#endif
        m_left = std::max<float>(m_left, newLeft);
    } else {
        float newRight = m_block.logicalLeftForFloat(newFloat);
        if (shouldIndentText() && !m_block.style().isLeftToRightDirection())
            newRight -= floorToInt(m_block.textIndentOffset());
#if ENABLE(CSS_SHAPES)
        if (shapeDeltas.isValid()) {
            if (shapeDeltas.lineOverlapsShape())
                newRight += shapeDeltas.leftMarginBoxDelta();
            else // If the line doesn't overlap the shape, then we need to act as if this float didn't exist.
                newRight = m_right;
        }
#endif
        m_right = std::min<float>(m_right, newRight);
    }

    computeAvailableWidthFromLeftAndRight();
}
Beispiel #7
0
void LineWidth::shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject* newFloat)
{
    LayoutUnit height = m_block.logicalHeight();
    if (height < m_block.logicalTopForFloat(newFloat) || height >= m_block.logicalBottomForFloat(newFloat))
        return;

    ShapeOutsideInfo* shapeOutsideInfo = newFloat->renderer()->shapeOutsideInfo();
    if (shapeOutsideInfo) {
        LayoutUnit lineHeight = m_block.lineHeight(m_isFirstLine, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
        shapeOutsideInfo->updateDeltasForContainingBlockLine(m_block, *newFloat, m_block.logicalHeight(), lineHeight);
    }

    if (newFloat->type() == FloatingObject::FloatLeft) {
        float newLeft = m_block.logicalRightForFloat(newFloat).toFloat();
        if (shapeOutsideInfo) {
            if (shapeOutsideInfo->lineOverlapsShape())
                newLeft += shapeOutsideInfo->rightMarginBoxDelta();
            else // Per the CSS Shapes spec, If the line doesn't overlap the shape, then ignore this shape for this line.
                newLeft = m_left;
        }
        if (shouldIndentText() && m_block.style()->isLeftToRightDirection())
            newLeft += floorToInt(m_block.textIndentOffset());
        m_left = std::max<float>(m_left, newLeft);
    } else {
        float newRight = m_block.logicalLeftForFloat(newFloat).toFloat();
        if (shapeOutsideInfo) {
            if (shapeOutsideInfo->lineOverlapsShape())
                newRight += shapeOutsideInfo->leftMarginBoxDelta();
            else // Per the CSS Shapes spec, If the line doesn't overlap the shape, then ignore this shape for this line.
                newRight = m_right;
        }
        if (shouldIndentText() && !m_block.style()->isLeftToRightDirection())
            newRight -= floorToInt(m_block.textIndentOffset());
        m_right = std::min<float>(m_right, newRight);
    }

    computeAvailableWidthFromLeftAndRight();
}
Beispiel #8
0
Float Noise::perlinNoise(const Point &p) {
    // Compute noise cell coordinates and offsets
    int ix = floorToInt(p.x),
		iy = floorToInt(p.y),
		iz = floorToInt(p.z);

    Float dx = p.x - ix,
		  dy = p.y - iy,
		  dz = p.z - iz;

    // Compute gradient weights
    ix &= (NOISE_PERM_SIZE-1);
    iy &= (NOISE_PERM_SIZE-1);
    iz &= (NOISE_PERM_SIZE-1);
    
	Float w000 = grad(ix,   iy,   iz,   dx,   dy,   dz);
    Float w100 = grad(ix+1, iy,   iz,   dx-1, dy,   dz);
    Float w010 = grad(ix,   iy+1, iz,   dx,   dy-1, dz);
    Float w110 = grad(ix+1, iy+1, iz,   dx-1, dy-1, dz);
    Float w001 = grad(ix,   iy,   iz+1, dx,   dy,   dz-1);
    Float w101 = grad(ix+1, iy,   iz+1, dx-1, dy,   dz-1);
    Float w011 = grad(ix,   iy+1, iz+1, dx,   dy-1, dz-1);
    Float w111 = grad(ix+1, iy+1, iz+1, dx-1, dy-1, dz-1);

    // Compute trilinear interpolation of weights
    Float wx = noiseWeight(dx),
		  wy = noiseWeight(dy),
		  wz = noiseWeight(dz);

	Float x00 = lerp(wx, w000, w100),
		  x10 = lerp(wx, w010, w110),
		  x01 = lerp(wx, w001, w101),
		  x11 = lerp(wx, w011, w111),
		  y0 = lerp(wy, x00, x10),
		  y1 = lerp(wy, x01, x11);
	
    return lerp(wz, y0, y1);
}
Beispiel #9
0
MIPMap::ResampleWeight *MIPMap::resampleWeights(int oldRes, int newRes) const {
	/* Resample using a Lanczos windowed sinc reconstruction filter */
	Assert(newRes >= oldRes);
	Float filterWidth = 2.0f;
	ResampleWeight *weights = new ResampleWeight[newRes];
	for (int i=0; i<newRes; i++) {
		Float center = (i + .5f) * oldRes / newRes;
		weights[i].firstTexel = floorToInt(center - filterWidth + (Float) 0.5f);
		Float weightSum = 0;
		for (int j=0; j<4; j++) {
			Float pos = weights[i].firstTexel + j + .5f;
			Float weight = lanczosSinc((pos - center) / filterWidth);
			weightSum += weight;
			weights[i].weight[j] = weight;
		}

		/* Normalize */
		Float invWeights = 1.0f / weightSum;
		for (int j=0; j<4; j++)
			weights[i].weight[j] *= invWeights;
	}
	return weights;
}