本文整理汇总了C++中FloatRect::x方法的典型用法代码示例。如果您正苦于以下问题:C++ FloatRect::x方法的具体用法?C++ FloatRect::x怎么用?C++ FloatRect::x使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类FloatRect
的用法示例。
在下文中一共展示了FloatRect::x方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ASSERT
void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, const FloatRect& srcRect,
const FloatRect& dstRect, ExceptionCode& ec)
{
ASSERT(canvas);
ec = 0;
FloatRect srcCanvasRect = FloatRect(FloatPoint(), canvas->size());
if (!(srcCanvasRect.contains(srcRect) && srcRect.width() >= 0 && srcRect.height() >= 0
&& dstRect.width() >= 0 && dstRect.height() >= 0)) {
ec = INDEX_SIZE_ERR;
return;
}
if (srcRect.isEmpty() || dstRect.isEmpty())
return;
GraphicsContext* c = drawingContext();
if (!c)
return;
FloatRect sourceRect = c->roundToDevicePixels(srcRect);
FloatRect destRect = c->roundToDevicePixels(dstRect);
// FIXME: Do this through platform-independent GraphicsContext API.
#if PLATFORM(CG)
CGImageRef platformImage = canvas->createPlatformImage();
if (!platformImage)
return;
willDraw(destRect);
float iw = CGImageGetWidth(platformImage);
float ih = CGImageGetHeight(platformImage);
if (sourceRect.x() == 0 && sourceRect.y() == 0 && iw == sourceRect.width() && ih == sourceRect.height()) {
// Fast path, yay!
CGContextDrawImage(c->platformContext(), destRect, platformImage);
} else {
// Slow path, boo!
// Create a new bitmap of the appropriate size and then draw that into our context.
size_t csw = static_cast<size_t>(ceilf(sourceRect.width()));
size_t csh = static_cast<size_t>(ceilf(sourceRect.height()));
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
size_t bytesPerRow = csw * 4;
void* buffer = fastMalloc(csh * bytesPerRow);
CGContextRef clippedSourceContext = CGBitmapContextCreate(buffer, csw, csh,
8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
CGContextTranslateCTM(clippedSourceContext, -sourceRect.x(), -sourceRect.y());
CGContextDrawImage(clippedSourceContext, CGRectMake(0, 0, iw, ih), platformImage);
CGImageRef clippedSourceImage = CGBitmapContextCreateImage(clippedSourceContext);
CGContextRelease(clippedSourceContext);
CGContextDrawImage(c->platformContext(), destRect, clippedSourceImage);
CGImageRelease(clippedSourceImage);
fastFree(buffer);
}
CGImageRelease(platformImage);
#elif PLATFORM(QT)
QPixmap px = canvas->createPlatformImage();
if (px.isNull())
return;
willDraw(dstRect);
QPainter* painter = static_cast<QPainter*>(c->platformContext());
painter->drawPixmap(dstRect, px, srcRect);
#endif
}
示例2: addEllipse
void Path::addEllipse(const FloatRect& r)
{
m_path->addEllipse(r.x(), r.y(), r.width(), r.height());
}
示例3: applyResource
bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
{
ASSERT(object);
ASSERT(context);
ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);
// Returning false here, to avoid drawings onto the context. We just want to
// draw the stored filter output, not the unfiltered object as well.
if (m_filter.contains(object)) {
FilterData* filterData = m_filter.get(object);
if (filterData->builded)
return false;
delete m_filter.take(object); // Oops, have to rebuild, go through normal code path
}
OwnPtr<FilterData> filterData(adoptPtr(new FilterData));
FloatRect targetBoundingBox = object->objectBoundingBox();
SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement>(filterElement, filterElement->filterUnits(), targetBoundingBox);
if (filterData->boundaries.isEmpty())
return false;
// Determine absolute transformation matrix for filter.
AffineTransform absoluteTransform;
SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform);
if (!absoluteTransform.isInvertible())
return false;
// Eliminate shear of the absolute transformation matrix, to be able to produce unsheared tile images for feTile.
filterData->shearFreeAbsoluteTransform = AffineTransform(absoluteTransform.xScale(), 0, 0, absoluteTransform.yScale(), 0, 0);
// Determine absolute boundaries of the filter and the drawing region.
FloatRect absoluteFilterBoundaries = filterData->shearFreeAbsoluteTransform.mapRect(filterData->boundaries);
FloatRect drawingRegion = object->strokeBoundingBox();
drawingRegion.intersect(filterData->boundaries);
FloatRect absoluteDrawingRegion = filterData->shearFreeAbsoluteTransform.mapRect(drawingRegion);
// Create the SVGFilter object.
bool primitiveBoundingBoxMode = filterElement->primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
filterData->filter = SVGFilter::create(filterData->shearFreeAbsoluteTransform, absoluteDrawingRegion, targetBoundingBox, filterData->boundaries, primitiveBoundingBoxMode);
// Create all relevant filter primitives.
filterData->builder = buildPrimitives(filterData->filter.get());
if (!filterData->builder)
return false;
// Calculate the scale factor for the use of filterRes.
// Also see http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
FloatSize scale(1, 1);
if (filterElement->hasAttribute(SVGNames::filterResAttr)) {
scale.setWidth(filterElement->filterResX() / absoluteFilterBoundaries.width());
scale.setHeight(filterElement->filterResY() / absoluteFilterBoundaries.height());
}
if (scale.isEmpty())
return false;
// Determine scale factor for filter. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
FloatRect tempSourceRect = absoluteDrawingRegion;
tempSourceRect.scale(scale.width(), scale.height());
fitsInMaximumImageSize(tempSourceRect.size(), scale);
// Set the scale level in SVGFilter.
filterData->filter->setFilterResolution(scale);
FilterEffect* lastEffect = filterData->builder->lastEffect();
if (!lastEffect)
return false;
RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect);
FloatRect subRegion = lastEffect->maxEffectRect();
// At least one FilterEffect has a too big image size,
// recalculate the effect sizes with new scale factors.
if (!fitsInMaximumImageSize(subRegion.size(), scale)) {
filterData->filter->setFilterResolution(scale);
RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect);
}
// If the drawingRegion is empty, we have something like <g filter=".."/>.
// Even if the target objectBoundingBox() is empty, we still have to draw the last effect result image in postApplyResource.
if (drawingRegion.isEmpty()) {
ASSERT(!m_filter.contains(object));
filterData->savedContext = context;
m_filter.set(object, filterData.leakPtr());
return false;
}
absoluteDrawingRegion.scale(scale.width(), scale.height());
OwnPtr<ImageBuffer> sourceGraphic;
if (!SVGImageBufferTools::createImageBuffer(absoluteDrawingRegion, absoluteDrawingRegion, sourceGraphic, ColorSpaceLinearRGB)) {
ASSERT(!m_filter.contains(object));
filterData->savedContext = context;
m_filter.set(object, filterData.leakPtr());
return false;
}
GraphicsContext* sourceGraphicContext = sourceGraphic->context();
//.........这里部分代码省略.........
示例4: tryPathOnlyClipping
bool RenderSVGResourceClipper::tryPathOnlyClipping(GraphicsContext* context,
const AffineTransform& animatedLocalTransform, const FloatRect& objectBoundingBox) {
// If the current clip-path gets clipped itself, we have to fallback to masking.
if (!style()->svgStyle().clipperResource().isEmpty())
return false;
WindRule clipRule = RULE_NONZERO;
Path clipPath = Path();
for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
RenderObject* renderer = childElement->renderer();
if (!renderer)
continue;
// Only shapes or paths are supported for direct clipping. We need to fallback to masking for texts.
if (renderer->isSVGText())
return false;
if (!childElement->isSVGGraphicsElement())
continue;
SVGGraphicsElement* styled = toSVGGraphicsElement(childElement);
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
continue;
const SVGRenderStyle& svgStyle = style->svgStyle();
// Current shape in clip-path gets clipped too. Fallback to masking.
if (!svgStyle.clipperResource().isEmpty())
return false;
if (clipPath.isEmpty()) {
// First clip shape.
styled->toClipPath(clipPath);
clipRule = svgStyle.clipRule();
clipPath.setWindRule(clipRule);
continue;
}
if (RuntimeEnabledFeatures::pathOpsSVGClippingEnabled()) {
// Attempt to generate a combined clip path, fall back to masking if not possible.
Path subPath;
styled->toClipPath(subPath);
subPath.setWindRule(svgStyle.clipRule());
if (!clipPath.unionPath(subPath))
return false;
} else {
return false;
}
}
// Only one visible shape/path was found. Directly continue clipping and transform the content to userspace if necessary.
if (clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
AffineTransform transform;
transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
clipPath.transform(transform);
}
// Transform path by animatedLocalTransform.
clipPath.transform(animatedLocalTransform);
// The SVG specification wants us to clip everything, if clip-path doesn't have a child.
if (clipPath.isEmpty())
clipPath.addRect(FloatRect());
context->clipPath(clipPath, clipRule);
return true;
}
示例5: path
void BasicShapePolygon::path(Path& path, const FloatRect& boundingBox)
{
ASSERT(path.isEmpty());
ASSERT(!(m_values.size() % 2));
size_t length = m_values.size();
if (!length)
return;
path.moveTo(FloatPoint(floatValueForLength(m_values.at(0), boundingBox.width()) + boundingBox.x(),
floatValueForLength(m_values.at(1), boundingBox.height()) + boundingBox.y()));
for (size_t i = 2; i < length; i = i + 2) {
path.addLineTo(FloatPoint(floatValueForLength(m_values.at(i), boundingBox.width()) + boundingBox.x(),
floatValueForLength(m_values.at(i + 1), boundingBox.height()) + boundingBox.y()));
}
path.closeSubpath();
}
示例6: shapeAndPlaceItem
bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const Font* fontData, GlyphBuffer* glyphBuffer)
{
// Determine the string for this item.
const UChar* str = cp + m_items[i].iCharPos;
int len = m_items[i+1].iCharPos - m_items[i].iCharPos;
SCRIPT_ITEM item = m_items[i];
// Set up buffers to hold the results of shaping the item.
Vector<WORD> glyphs;
Vector<WORD> clusters;
Vector<SCRIPT_VISATTR> visualAttributes;
clusters.resize(len);
// Shape the item.
// The recommended size for the glyph buffer is 1.5 * the character length + 16 in the uniscribe docs.
// Apparently this is a good size to avoid having to make repeated calls to ScriptShape.
glyphs.resize(1.5 * len + 16);
visualAttributes.resize(glyphs.size());
if (!shape(str, len, item, fontData, glyphs, clusters, visualAttributes))
return true;
// We now have a collection of glyphs.
Vector<GOFFSET> offsets;
Vector<int> advances;
offsets.resize(glyphs.size());
advances.resize(glyphs.size());
int glyphCount = 0;
HRESULT placeResult = ScriptPlace(0, fontData->scriptCache(), glyphs.data(), glyphs.size(), visualAttributes.data(),
&item.a, advances.data(), offsets.data(), 0);
if (placeResult == E_PENDING) {
// The script cache isn't primed with enough info yet. We need to select our HFONT into
// a DC and pass the DC in to ScriptPlace.
HWndDC hdc(0);
HFONT hfont = fontData->platformData().hfont();
HFONT oldFont = (HFONT)SelectObject(hdc, hfont);
placeResult = ScriptPlace(hdc, fontData->scriptCache(), glyphs.data(), glyphs.size(), visualAttributes.data(),
&item.a, advances.data(), offsets.data(), 0);
SelectObject(hdc, oldFont);
}
if (FAILED(placeResult) || glyphs.isEmpty())
return true;
// Convert all chars that should be treated as spaces to use the space glyph.
// We also create a map that allows us to quickly go from space glyphs back to their corresponding characters.
Vector<int> spaceCharacters(glyphs.size());
spaceCharacters.fill(-1);
const float cLogicalScale = fontData->platformData().useGDI() ? 1.0f : 32.0f;
float spaceWidth = fontData->spaceWidth() - fontData->syntheticBoldOffset();
unsigned logicalSpaceWidth = spaceWidth * cLogicalScale;
for (int k = 0; k < len; k++) {
UChar ch = *(str + k);
bool treatAsSpace = FontCascade::treatAsSpace(ch);
bool treatAsZeroWidthSpace = FontCascade::treatAsZeroWidthSpace(ch);
if (treatAsSpace || treatAsZeroWidthSpace) {
// Substitute in the space glyph at the appropriate place in the glyphs
// array.
glyphs[clusters[k]] = fontData->spaceGlyph();
advances[clusters[k]] = treatAsSpace ? logicalSpaceWidth : 0;
if (treatAsSpace)
spaceCharacters[clusters[k]] = m_currentCharacter + k + item.iCharPos;
}
}
// Populate our glyph buffer with this information.
bool hasExtraSpacing = m_font.letterSpacing() || m_font.wordSpacing() || m_padding;
float leftEdge = m_runWidthSoFar;
for (unsigned k = 0; k < glyphs.size(); k++) {
Glyph glyph = glyphs[k];
float advance = advances[k] / cLogicalScale;
float offsetX = offsets[k].du / cLogicalScale;
float offsetY = offsets[k].dv / cLogicalScale;
// Match AppKit's rules for the integer vs. non-integer rendering modes.
float roundedAdvance = roundf(advance);
if (!fontData->platformData().isSystemFont()) {
advance = roundedAdvance;
offsetX = roundf(offsetX);
offsetY = roundf(offsetY);
}
advance += fontData->syntheticBoldOffset();
if (hasExtraSpacing) {
// If we're a glyph with an advance, go ahead and add in letter-spacing.
// That way we weed out zero width lurkers. This behavior matches the fast text code path.
if (advance && m_font.letterSpacing())
advance += m_font.letterSpacing();
// Handle justification and word-spacing.
int characterIndex = spaceCharacters[k];
// characterIndex is left at the initial value of -1 for glyphs that do not map back to treated-as-space characters.
if (characterIndex != -1) {
// Account for padding. WebCore uses space padding to justify text.
// We distribute the specified padding over the available spaces in the run.
//.........这里部分代码省略.........
示例7: adjustTileCoverageRect
void TileController::adjustTileCoverageRect(FloatRect& coverageRect, const FloatSize& newSize, const FloatRect& previousVisibleRect, const FloatRect& visibleRect, float contentsScale) const
{
// If the page is not in a window (for example if it's in a background tab), we limit the tile coverage rect to the visible rect.
if (!m_isInWindow) {
coverageRect = visibleRect;
return;
}
#if PLATFORM(IOS)
// FIXME: unify the iOS and Mac code.
UNUSED_PARAM(previousVisibleRect);
if (m_tileCoverage == CoverageForVisibleArea || MemoryPressureHandler::singleton().isUnderMemoryPressure()) {
coverageRect = visibleRect;
return;
}
double horizontalMargin = tileSize().width() / contentsScale;
double verticalMargin = tileSize().height() / contentsScale;
double currentTime = monotonicallyIncreasingTime();
double timeDelta = currentTime - m_velocity.lastUpdateTime;
FloatRect futureRect = visibleRect;
futureRect.setLocation(FloatPoint(
futureRect.location().x() + timeDelta * m_velocity.horizontalVelocity,
futureRect.location().y() + timeDelta * m_velocity.verticalVelocity));
if (m_velocity.horizontalVelocity) {
futureRect.setWidth(futureRect.width() + horizontalMargin);
if (m_velocity.horizontalVelocity < 0)
futureRect.setX(futureRect.x() - horizontalMargin);
}
if (m_velocity.verticalVelocity) {
futureRect.setHeight(futureRect.height() + verticalMargin);
if (m_velocity.verticalVelocity < 0)
futureRect.setY(futureRect.y() - verticalMargin);
}
if (!m_velocity.horizontalVelocity && !m_velocity.verticalVelocity) {
if (m_velocity.scaleChangeRate > 0) {
coverageRect = visibleRect;
return;
}
futureRect.setWidth(futureRect.width() + horizontalMargin);
futureRect.setHeight(futureRect.height() + verticalMargin);
futureRect.setX(futureRect.x() - horizontalMargin / 2);
futureRect.setY(futureRect.y() - verticalMargin / 2);
}
// Can't use m_tileCacheLayer->bounds() here, because the size of the underlying platform layer
// hasn't been updated for the current commit.
IntSize contentSize = expandedIntSize(newSize);
if (futureRect.maxX() > contentSize.width())
futureRect.setX(contentSize.width() - futureRect.width());
if (futureRect.maxY() > contentSize.height())
futureRect.setY(contentSize.height() - futureRect.height());
if (futureRect.x() < 0)
futureRect.setX(0);
if (futureRect.y() < 0)
futureRect.setY(0);
coverageRect.unite(futureRect);
return;
#else
UNUSED_PARAM(contentsScale);
// FIXME: look at how far the document can scroll in each dimension.
FloatSize coverageSize = visibleRect.size();
bool largeVisibleRectChange = !previousVisibleRect.isEmpty() && !visibleRect.intersects(previousVisibleRect);
// Inflate the coverage rect so that it covers 2x of the visible width and 3x of the visible height.
// These values were chosen because it's more common to have tall pages and to scroll vertically,
// so we keep more tiles above and below the current area.
float widthScale = 1;
float heightScale = 1;
if (m_tileCoverage & CoverageForHorizontalScrolling && !largeVisibleRectChange)
widthScale = 2;
if (m_tileCoverage & CoverageForVerticalScrolling && !largeVisibleRectChange)
heightScale = 3;
coverageSize.scale(widthScale, heightScale);
FloatRect coverageBounds = boundsForSize(newSize);
FloatRect coverage = expandRectWithinRect(visibleRect, coverageSize, coverageBounds);
LOG_WITH_STREAM(Scrolling, stream << "TileController::computeTileCoverageRect newSize=" << newSize << " mode " << m_tileCoverage << " expanded to " << coverageSize << " bounds with margin " << coverageBounds << " coverage " << coverage);
coverageRect.unite(coverage);
#endif
}
示例8: clampToInteger
IntRect::IntRect(const FloatRect& r)
: m_location(clampToInteger(r.x()), clampToInteger(r.y()))
, m_size(clampToInteger(r.width()), clampToInteger(r.height()))
{
}
示例9: clip
void GraphicsContext::clip(const FloatRect& r)
{
m_data->context->SetClippingRegion(r.x(), r.y(), r.width(), r.height());
}
示例10: drawSurfaceToContext
void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& originalSrcRect, GraphicsContext& context)
{
// Avoid invalid cairo matrix with small values.
if (std::fabs(destRect.width()) < 0.5f || std::fabs(destRect.height()) < 0.5f)
return;
FloatRect srcRect = originalSrcRect;
// We need to account for negative source dimensions by flipping the rectangle.
if (originalSrcRect.width() < 0) {
srcRect.setX(originalSrcRect.x() + originalSrcRect.width());
srcRect.setWidth(std::fabs(originalSrcRect.width()));
}
if (originalSrcRect.height() < 0) {
srcRect.setY(originalSrcRect.y() + originalSrcRect.height());
srcRect.setHeight(std::fabs(originalSrcRect.height()));
}
RefPtr<cairo_surface_t> patternSurface = surface;
float leftPadding = 0;
float topPadding = 0;
if (srcRect.x() || srcRect.y() || srcRect.size() != cairoSurfaceSize(surface)) {
// Cairo subsurfaces don't support floating point boundaries well, so we expand the rectangle.
IntRect expandedSrcRect(enclosingIntRect(srcRect));
// We use a subsurface here so that we don't end up sampling outside the originalSrcRect rectangle.
// See https://bugs.webkit.org/show_bug.cgi?id=58309
patternSurface = adoptRef(cairo_surface_create_for_rectangle(surface, expandedSrcRect.x(),
expandedSrcRect.y(), expandedSrcRect.width(), expandedSrcRect.height()));
leftPadding = static_cast<float>(expandedSrcRect.x()) - floorf(srcRect.x());
topPadding = static_cast<float>(expandedSrcRect.y()) - floorf(srcRect.y());
}
RefPtr<cairo_pattern_t> pattern = adoptRef(cairo_pattern_create_for_surface(patternSurface.get()));
ASSERT(m_state);
switch (m_state->m_imageInterpolationQuality) {
case InterpolationNone:
case InterpolationLow:
cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_FAST);
break;
case InterpolationMedium:
case InterpolationDefault:
cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_GOOD);
break;
case InterpolationHigh:
cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_BEST);
break;
}
cairo_pattern_set_extend(pattern.get(), CAIRO_EXTEND_PAD);
// The pattern transformation properly scales the pattern for when the source rectangle is a
// different size than the destination rectangle. We also account for any offset we introduced
// by expanding floating point source rectangle sizes. It's important to take the absolute value
// of the scale since the original width and height might be negative.
float scaleX = std::fabs(srcRect.width() / destRect.width());
float scaleY = std::fabs(srcRect.height() / destRect.height());
cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, leftPadding, topPadding };
cairo_pattern_set_matrix(pattern.get(), &matrix);
ShadowBlur& shadow = context.platformContext()->shadowBlur();
if (shadow.type() != ShadowBlur::NoShadow) {
if (GraphicsContext* shadowContext = shadow.beginShadowLayer(context, destRect)) {
drawPatternToCairoContext(shadowContext->platformContext()->cr(), pattern.get(), destRect, 1);
shadow.endShadowLayer(context);
}
}
cairo_save(m_cr.get());
drawPatternToCairoContext(m_cr.get(), pattern.get(), destRect, globalAlpha());
cairo_restore(m_cr.get());
}
示例11: determineFilterPrimitiveSubregion
FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect* effect, SVGFilter* filter)
{
FloatRect uniteRect;
FloatRect subregionBoundingBox = effect->effectBoundaries();
FloatRect subregion = subregionBoundingBox;
if (effect->filterEffectType() != FilterEffectTypeTile) {
// FETurbulence, FEImage and FEFlood don't have input effects, take the filter region as unite rect.
if (unsigned numberOfInputEffects = effect->inputEffects().size()) {
for (unsigned i = 0; i < numberOfInputEffects; ++i)
uniteRect.unite(determineFilterPrimitiveSubregion(effect->inputEffect(i), filter));
} else
uniteRect = filter->filterRegionInUserSpace();
} else {
determineFilterPrimitiveSubregion(effect->inputEffect(0), filter);
uniteRect = filter->filterRegionInUserSpace();
}
if (filter->effectBoundingBoxMode()) {
subregion = uniteRect;
// Avoid the calling of a virtual method several times.
FloatRect targetBoundingBox = filter->targetBoundingBox();
if (effect->hasX())
subregion.setX(targetBoundingBox.x() + subregionBoundingBox.x() * targetBoundingBox.width());
if (effect->hasY())
subregion.setY(targetBoundingBox.y() + subregionBoundingBox.y() * targetBoundingBox.height());
if (effect->hasWidth())
subregion.setWidth(subregionBoundingBox.width() * targetBoundingBox.width());
if (effect->hasHeight())
subregion.setHeight(subregionBoundingBox.height() * targetBoundingBox.height());
} else {
if (!effect->hasX())
subregion.setX(uniteRect.x());
if (!effect->hasY())
subregion.setY(uniteRect.y());
if (!effect->hasWidth())
subregion.setWidth(uniteRect.width());
if (!effect->hasHeight())
subregion.setHeight(uniteRect.height());
}
effect->setFilterPrimitiveSubregion(subregion);
FloatRect absoluteSubregion = filter->mapLocalRectToAbsoluteRect(subregion);
FloatSize filterResolution = filter->filterResolution();
absoluteSubregion.scale(filterResolution.width(), filterResolution.height());
// FEImage needs the unclipped subregion in absolute coordinates to determine the correct
// destination rect in combination with preserveAspectRatio.
if (effect->filterEffectType() == FilterEffectTypeImage)
reinterpret_cast<FEImage*>(effect)->setAbsoluteSubregion(absoluteSubregion);
// Clip every filter effect to the filter region.
FloatRect absoluteScaledFilterRegion = filter->filterRegion();
absoluteScaledFilterRegion.scale(filterResolution.width(), filterResolution.height());
absoluteSubregion.intersect(absoluteScaledFilterRegion);
effect->setMaxEffectRect(enclosingIntRect(absoluteSubregion));
return subregion;
}
示例12: tryUpdateSurface
bool Surface::tryUpdateSurface(Surface* oldSurface)
{
if (!needsTexture() || !oldSurface->needsTexture())
return false;
// merge surfaces based on first layer ID
if (getFirstLayer()->uniqueId() != oldSurface->getFirstLayer()->uniqueId())
return false;
m_surfaceBacking = oldSurface->m_surfaceBacking;
SkSafeRef(m_surfaceBacking);
ALOGV("%p taking old SurfBack %p from surface %p, nt %d",
this, m_surfaceBacking, oldSurface, oldSurface->needsTexture());
if (!m_surfaceBacking) {
// no SurfBack to inval, so don't worry about it.
return true;
}
SkRegion invalRegion;
bool fullInval = false;
if (singleLayer() && oldSurface->singleLayer()) {
// both are single matching layers, simply apply inval
SkRegion* layerInval = getFirstLayer()->getInvalRegion();
invalRegion = *layerInval;
if (isBase()) {
// the base layer paints outside it's content area to ensure the
// viewport is convered, so fully invalidate all tiles if its size
// changes to ensure no stale content remains
LayerContent* newContent = getFirstLayer()->content();
LayerContent* oldContent = oldSurface->getFirstLayer()->content();
fullInval = newContent->width() != oldContent->width()
|| newContent->height() != oldContent->height();
}
} else {
fullInval = m_layers.size() != oldSurface->m_layers.size();
if (!fullInval) {
for (unsigned int i = 0; i < m_layers.size(); i++) {
if ((m_layers[i]->uniqueId() != oldSurface->m_layers[i]->uniqueId())
|| (m_layers[i]->fullContentAreaMapped() != oldSurface->m_layers[i]->fullContentAreaMapped())) {
// layer list has changed, fully invalidate
// TODO: partially invalidate based on layer size/position
fullInval = true;
break;
} else if (!m_layers[i]->getInvalRegion()->isEmpty()) {
// merge layer inval - translate the layer's inval region into surface coordinates
// TODO: handle scale/3d transform mapping
FloatRect layerPos = m_layers[i]->fullContentAreaMapped();
m_layers[i]->getInvalRegion()->translate(layerPos.x(), layerPos.y());
invalRegion.op(*(m_layers[i]->getInvalRegion()), SkRegion::kUnion_Op);
}
}
}
}
if (fullInval)
invalRegion.setRect(-1e8, -1e8, 2e8, 2e8);
m_surfaceBacking->markAsDirty(invalRegion);
return true;
}
示例13: scissorToRect
// Sets the scissor region to the given rectangle. The coordinate system for the
// scissorRect has its origin at the top left corner of the current visible rect.
void LayerRendererChromium::scissorToRect(const FloatRect& scissorRect)
{
// Compute the lower left corner of the scissor rect.
float bottom = std::max((float)m_rootVisibleRect.height() - scissorRect.bottom(), 0.f);
GLC(glScissor(scissorRect.x(), bottom, scissorRect.width(), scissorRect.height()));
}
示例14: adjustRectsForAspectRatio
void RenderSVGImage::adjustRectsForAspectRatio(FloatRect& destRect, FloatRect& srcRect, SVGPreserveAspectRatio* aspectRatio)
{
float origDestWidth = destRect.width();
float origDestHeight = destRect.height();
if (aspectRatio->meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET) {
float widthToHeightMultiplier = srcRect.height() / srcRect.width();
if (origDestHeight > (origDestWidth * widthToHeightMultiplier)) {
destRect.setHeight(origDestWidth * widthToHeightMultiplier);
switch(aspectRatio->align()) {
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
destRect.setY(destRect.y() + origDestHeight / 2.0f - destRect.height() / 2.0f);
break;
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
destRect.setY(destRect.y() + origDestHeight - destRect.height());
break;
}
}
if (origDestWidth > (origDestHeight / widthToHeightMultiplier)) {
destRect.setWidth(origDestHeight / widthToHeightMultiplier);
switch(aspectRatio->align()) {
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
destRect.setX(destRect.x() + origDestWidth / 2.0f - destRect.width() / 2.0f);
break;
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
destRect.setX(destRect.x() + origDestWidth - destRect.width());
break;
}
}
} else if (aspectRatio->meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE) {
float widthToHeightMultiplier = srcRect.height() / srcRect.width();
// if the destination height is less than the height of the image we'll be drawing
if (origDestHeight < (origDestWidth * widthToHeightMultiplier)) {
float destToSrcMultiplier = srcRect.width() / destRect.width();
srcRect.setHeight(destRect.height() * destToSrcMultiplier);
switch(aspectRatio->align()) {
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
srcRect.setY(destRect.y() + image()->height() / 2.0f - srcRect.height() / 2.0f);
break;
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
srcRect.setY(destRect.y() + image()->height() - srcRect.height());
break;
}
}
// if the destination width is less than the width of the image we'll be drawing
if (origDestWidth < (origDestHeight / widthToHeightMultiplier)) {
float destToSrcMultiplier = srcRect.height() / destRect.height();
srcRect.setWidth(destRect.width() * destToSrcMultiplier);
switch(aspectRatio->align()) {
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
srcRect.setX(destRect.x() + image()->width() / 2.0f - srcRect.width() / 2.0f);
break;
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
srcRect.setX(destRect.x() + image()->width() - srcRect.width());
break;
}
}
}
}
示例15: addRect
void Path::addRect(const FloatRect& rect)
{
cairo_t* cr = platformPath()->context();
cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
}