本文整理汇总了C++中FloatRect::setY方法的典型用法代码示例。如果您正苦于以下问题:C++ FloatRect::setY方法的具体用法?C++ FloatRect::setY怎么用?C++ FloatRect::setY使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类FloatRect
的用法示例。
在下文中一共展示了FloatRect::setY方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: 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;
}
示例2: paintSliderTicks
void RenderTheme::paintSliderTicks(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
{
Node* node = o->node();
if (!isHTMLInputElement(node))
return;
HTMLInputElement* input = toHTMLInputElement(node);
if (!input->isRangeControl())
return;
HTMLDataListElement* dataList = input->dataList();
if (!dataList)
return;
double min = input->minimum();
double max = input->maximum();
ControlPart part = o->style()->appearance();
// We don't support ticks on alternate sliders like MediaVolumeSliders.
if (part != SliderHorizontalPart && part != SliderVerticalPart)
return;
bool isHorizontal = part == SliderHorizontalPart;
IntSize thumbSize;
RenderObject* thumbRenderer = input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderThumb())->renderer();
if (thumbRenderer) {
RenderStyle* thumbStyle = thumbRenderer->style();
int thumbWidth = thumbStyle->width().intValue();
int thumbHeight = thumbStyle->height().intValue();
thumbSize.setWidth(isHorizontal ? thumbWidth : thumbHeight);
thumbSize.setHeight(isHorizontal ? thumbHeight : thumbWidth);
}
IntSize tickSize = sliderTickSize();
float zoomFactor = o->style()->effectiveZoom();
FloatRect tickRect;
int tickRegionSideMargin = 0;
int tickRegionWidth = 0;
IntRect trackBounds;
RenderObject* trackRenderer = input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderTrack())->renderer();
// We can ignoring transforms because transform is handled by the graphics context.
if (trackRenderer)
trackBounds = trackRenderer->absoluteBoundingBoxRectIgnoringTransforms();
IntRect sliderBounds = o->absoluteBoundingBoxRectIgnoringTransforms();
// Make position relative to the transformed ancestor element.
trackBounds.setX(trackBounds.x() - sliderBounds.x() + rect.x());
trackBounds.setY(trackBounds.y() - sliderBounds.y() + rect.y());
if (isHorizontal) {
tickRect.setWidth(floor(tickSize.width() * zoomFactor));
tickRect.setHeight(floor(tickSize.height() * zoomFactor));
tickRect.setY(floor(rect.y() + rect.height() / 2.0 + sliderTickOffsetFromTrackCenter() * zoomFactor));
tickRegionSideMargin = trackBounds.x() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0;
tickRegionWidth = trackBounds.width() - thumbSize.width();
} else {
tickRect.setWidth(floor(tickSize.height() * zoomFactor));
tickRect.setHeight(floor(tickSize.width() * zoomFactor));
tickRect.setX(floor(rect.x() + rect.width() / 2.0 + sliderTickOffsetFromTrackCenter() * zoomFactor));
tickRegionSideMargin = trackBounds.y() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0;
tickRegionWidth = trackBounds.height() - thumbSize.width();
}
RefPtrWillBeRawPtr<HTMLCollection> options = dataList->options();
GraphicsContextStateSaver stateSaver(*paintInfo.context);
paintInfo.context->setFillColor(o->resolveColor(CSSPropertyColor));
for (unsigned i = 0; Element* element = options->item(i); i++) {
ASSERT(isHTMLOptionElement(*element));
HTMLOptionElement& optionElement = toHTMLOptionElement(*element);
String value = optionElement.value();
if (!input->isValidValue(value))
continue;
double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(value));
double tickFraction = (parsedValue - min) / (max - min);
double tickRatio = isHorizontal && o->style()->isLeftToRightDirection() ? tickFraction : 1.0 - tickFraction;
double tickPosition = round(tickRegionSideMargin + tickRegionWidth * tickRatio);
if (isHorizontal)
tickRect.setX(tickPosition);
else
tickRect.setY(tickPosition);
paintInfo.context->fillRect(tickRect);
}
}
示例3: transformRect
void SVGPreserveAspectRatio::transformRect(FloatRect& destRect, FloatRect& srcRect)
{
if (m_align == SVG_PRESERVEASPECTRATIO_NONE)
return;
FloatSize imageSize = srcRect.size();
float origDestWidth = destRect.width();
float origDestHeight = destRect.height();
switch (m_meetOrSlice) {
case SVGPreserveAspectRatio::SVG_MEETORSLICE_UNKNOWN:
break;
case SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET: {
float widthToHeightMultiplier = srcRect.height() / srcRect.width();
if (origDestHeight > origDestWidth * widthToHeightMultiplier) {
destRect.setHeight(origDestWidth * widthToHeightMultiplier);
switch (m_align) {
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
destRect.setY(destRect.y() + origDestHeight / 2 - destRect.height() / 2);
break;
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
destRect.setY(destRect.y() + origDestHeight - destRect.height());
break;
default:
break;
}
}
if (origDestWidth > origDestHeight / widthToHeightMultiplier) {
destRect.setWidth(origDestHeight / widthToHeightMultiplier);
switch (m_align) {
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
destRect.setX(destRect.x() + origDestWidth / 2 - destRect.width() / 2);
break;
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
destRect.setX(destRect.x() + origDestWidth - destRect.width());
break;
default:
break;
}
}
break;
}
case 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 (m_align) {
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
srcRect.setY(srcRect.y() + imageSize.height() / 2 - srcRect.height() / 2);
break;
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
srcRect.setY(srcRect.y() + imageSize.height() - srcRect.height());
break;
default:
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 (m_align) {
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
srcRect.setX(srcRect.x() + imageSize.width() / 2 - srcRect.width() / 2);
break;
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
srcRect.setX(srcRect.x() + imageSize.width() - srcRect.width());
break;
default:
break;
}
}
break;
}
}
}
示例4: createWindow
static LocalFrame* createWindow(LocalFrame& openerFrame, LocalFrame& lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer, bool& created)
{
ASSERT(!features.dialog || request.frameName().isEmpty());
if (!request.frameName().isEmpty() && request.frameName() != "_blank" && policy == NavigationPolicyIgnore) {
if (LocalFrame* frame = lookupFrame.loader().findFrameForNavigation(request.frameName(), openerFrame.document())) {
if (request.frameName() != "_self")
frame->page()->focusController().setFocusedFrame(frame);
created = false;
return frame;
}
}
// Sandboxed frames cannot open new auxiliary browsing contexts.
if (openerFrame.document()->isSandboxed(SandboxPopups)) {
// FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
openerFrame.document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked opening '" + request.resourceRequest().url().elidedString() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.");
return 0;
}
if (openerFrame.settings() && !openerFrame.settings()->supportsMultipleWindows()) {
created = false;
return openerFrame.tree().top();
}
Page* oldPage = openerFrame.page();
if (!oldPage)
return 0;
Page* page = oldPage->chrome().client().createWindow(&openerFrame, request, features, policy, shouldSendReferrer);
if (!page)
return 0;
FrameHost* host = &page->frameHost();
ASSERT(page->mainFrame());
LocalFrame& frame = *page->mainFrame();
if (request.frameName() != "_blank")
frame.tree().setName(request.frameName());
host->chrome().setWindowFeatures(features);
// 'x' and 'y' specify the location of the window, while 'width' and 'height'
// specify the size of the viewport. We can only resize the window, so adjust
// for the difference between the window size and the viewport size.
FloatRect windowRect = host->chrome().windowRect();
FloatSize viewportSize = host->chrome().pageRect().size();
if (features.xSet)
windowRect.setX(features.x);
if (features.ySet)
windowRect.setY(features.y);
if (features.widthSet)
windowRect.setWidth(features.width + (windowRect.width() - viewportSize.width()));
if (features.heightSet)
windowRect.setHeight(features.height + (windowRect.height() - viewportSize.height()));
// Ensure non-NaN values, minimum size as well as being within valid screen area.
FloatRect newWindowRect = DOMWindow::adjustWindowRect(frame, windowRect);
host->chrome().setWindowRect(newWindowRect);
host->chrome().show(policy);
created = true;
return &frame;
}
示例5: 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());
}
示例6: 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;
}
}
}
}
示例7: draw
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOp)
{
startAnimation();
CGImageRef image = frameAtIndex(m_currentFrame);
if (!image) // If it's too early we won't have an image yet.
return;
if (mayFillWithSolidColor()) {
fillWithSolidColor(ctxt, destRect, solidColor(), compositeOp);
return;
}
float currHeight = CGImageGetHeight(image);
if (currHeight <= srcRect.y())
return;
CGContextRef context = ctxt->platformContext();
ctxt->save();
bool shouldUseSubimage = false;
// If the source rect is a subportion of the image, then we compute an inflated destination rect that will hold the entire image
// and then set a clip to the portion that we want to display.
FloatRect adjustedDestRect = destRect;
FloatSize selfSize = currentFrameSize();
if (srcRect.size() != selfSize) {
CGInterpolationQuality interpolationQuality = CGContextGetInterpolationQuality(context);
// When the image is scaled using high-quality interpolation, we create a temporary CGImage
// containing only the portion we want to display. We need to do this because high-quality
// interpolation smoothes sharp edges, causing pixels from outside the source rect to bleed
// into the destination rect. See <rdar://problem/6112909>.
shouldUseSubimage = (interpolationQuality == kCGInterpolationHigh || interpolationQuality == kCGInterpolationDefault) && srcRect.size() != destRect.size();
float xScale = srcRect.width() / destRect.width();
float yScale = srcRect.height() / destRect.height();
if (shouldUseSubimage) {
FloatRect subimageRect = srcRect;
float leftPadding = srcRect.x() - floorf(srcRect.x());
float topPadding = srcRect.y() - floorf(srcRect.y());
subimageRect.move(-leftPadding, -topPadding);
adjustedDestRect.move(-leftPadding / xScale, -topPadding / yScale);
subimageRect.setWidth(ceilf(subimageRect.width() + leftPadding));
adjustedDestRect.setWidth(subimageRect.width() / xScale);
subimageRect.setHeight(ceilf(subimageRect.height() + topPadding));
adjustedDestRect.setHeight(subimageRect.height() / yScale);
image = CGImageCreateWithImageInRect(image, subimageRect);
if (currHeight < srcRect.bottom()) {
ASSERT(CGImageGetHeight(image) == currHeight - CGRectIntegral(srcRect).origin.y);
adjustedDestRect.setHeight(CGImageGetHeight(image) / yScale);
}
} else {
adjustedDestRect.setLocation(FloatPoint(destRect.x() - srcRect.x() / xScale, destRect.y() - srcRect.y() / yScale));
adjustedDestRect.setSize(FloatSize(selfSize.width() / xScale, selfSize.height() / yScale));
}
CGContextClipToRect(context, destRect);
}
// If the image is only partially loaded, then shrink the destination rect that we're drawing into accordingly.
if (!shouldUseSubimage && currHeight < selfSize.height())
adjustedDestRect.setHeight(adjustedDestRect.height() * currHeight / selfSize.height());
ctxt->setCompositeOperation(compositeOp);
// Flip the coords.
CGContextScaleCTM(context, 1, -1);
adjustedDestRect.setY(-adjustedDestRect.bottom());
// Draw the image.
CGContextDrawImage(context, adjustedDestRect, image);
if (shouldUseSubimage)
CGImageRelease(image);
ctxt->restore();
if (imageObserver())
imageObserver()->didDraw(this);
}
示例8: drawTiled
void Image::drawTiled(GraphicsContext& ctxt, const FloatRect& destRect, const FloatPoint& srcPoint, const FloatSize& scaledTileSize, const FloatSize& spacing, CompositeOperator op, BlendMode blendMode)
{
if (mayFillWithSolidColor()) {
fillWithSolidColor(ctxt, destRect, solidColor(), op);
return;
}
ASSERT(!isBitmapImage() || notSolidColor());
#if PLATFORM(IOS)
FloatSize intrinsicTileSize = originalSize();
#else
FloatSize intrinsicTileSize = size();
#endif
if (hasRelativeWidth())
intrinsicTileSize.setWidth(scaledTileSize.width());
if (hasRelativeHeight())
intrinsicTileSize.setHeight(scaledTileSize.height());
FloatSize scale(scaledTileSize.width() / intrinsicTileSize.width(),
scaledTileSize.height() / intrinsicTileSize.height());
FloatRect oneTileRect;
FloatSize actualTileSize(scaledTileSize.width() + spacing.width(), scaledTileSize.height() + spacing.height());
oneTileRect.setX(destRect.x() + fmodf(fmodf(-srcPoint.x(), actualTileSize.width()) - actualTileSize.width(), actualTileSize.width()));
oneTileRect.setY(destRect.y() + fmodf(fmodf(-srcPoint.y(), actualTileSize.height()) - actualTileSize.height(), actualTileSize.height()));
oneTileRect.setSize(scaledTileSize);
// Check and see if a single draw of the image can cover the entire area we are supposed to tile.
if (oneTileRect.contains(destRect) && !ctxt.drawLuminanceMask()) {
FloatRect visibleSrcRect;
visibleSrcRect.setX((destRect.x() - oneTileRect.x()) / scale.width());
visibleSrcRect.setY((destRect.y() - oneTileRect.y()) / scale.height());
visibleSrcRect.setWidth(destRect.width() / scale.width());
visibleSrcRect.setHeight(destRect.height() / scale.height());
draw(ctxt, destRect, visibleSrcRect, op, blendMode, ImageOrientationDescription());
return;
}
#if PLATFORM(IOS)
// When using accelerated drawing on iOS, it's faster to stretch an image than to tile it.
if (ctxt.isAcceleratedContext()) {
if (size().width() == 1 && intersection(oneTileRect, destRect).height() == destRect.height()) {
FloatRect visibleSrcRect;
visibleSrcRect.setX(0);
visibleSrcRect.setY((destRect.y() - oneTileRect.y()) / scale.height());
visibleSrcRect.setWidth(1);
visibleSrcRect.setHeight(destRect.height() / scale.height());
draw(ctxt, destRect, visibleSrcRect, op, BlendModeNormal, ImageOrientationDescription());
return;
}
if (size().height() == 1 && intersection(oneTileRect, destRect).width() == destRect.width()) {
FloatRect visibleSrcRect;
visibleSrcRect.setX((destRect.x() - oneTileRect.x()) / scale.width());
visibleSrcRect.setY(0);
visibleSrcRect.setWidth(destRect.width() / scale.width());
visibleSrcRect.setHeight(1);
draw(ctxt, destRect, visibleSrcRect, op, BlendModeNormal, ImageOrientationDescription());
return;
}
}
#endif
// Patterned images and gradients can use lots of memory for caching when the
// tile size is large (<rdar://problem/4691859>, <rdar://problem/6239505>).
// Memory consumption depends on the transformed tile size which can get
// larger than the original tile if user zooms in enough.
#if PLATFORM(IOS)
const float maxPatternTilePixels = 512 * 512;
#else
const float maxPatternTilePixels = 2048 * 2048;
#endif
FloatRect transformedTileSize = ctxt.getCTM().mapRect(FloatRect(FloatPoint(), scaledTileSize));
float transformedTileSizePixels = transformedTileSize.width() * transformedTileSize.height();
FloatRect currentTileRect = oneTileRect;
if (transformedTileSizePixels > maxPatternTilePixels) {
GraphicsContextStateSaver stateSaver(ctxt);
ctxt.clip(destRect);
currentTileRect.shiftYEdgeTo(destRect.y());
float toY = currentTileRect.y();
while (toY < destRect.maxY()) {
currentTileRect.shiftXEdgeTo(destRect.x());
float toX = currentTileRect.x();
while (toX < destRect.maxX()) {
FloatRect toRect(toX, toY, currentTileRect.width(), currentTileRect.height());
FloatRect fromRect(toFloatPoint(currentTileRect.location() - oneTileRect.location()), currentTileRect.size());
fromRect.scale(1 / scale.width(), 1 / scale.height());
draw(ctxt, toRect, fromRect, op, BlendModeNormal, ImageOrientationDescription());
toX += currentTileRect.width();
currentTileRect.shiftXEdgeTo(oneTileRect.x());
}
toY += currentTileRect.height();
currentTileRect.shiftYEdgeTo(oneTileRect.y());
}
return;
}
AffineTransform patternTransform = AffineTransform().scaleNonUniform(scale.width(), scale.height());
//.........这里部分代码省略.........
示例9: computeTileCoverageRect
FloatRect TileController::computeTileCoverageRect(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)
return visibleRect;
#if PLATFORM(IOS)
// FIXME: unify the iOS and Mac code.
UNUSED_PARAM(previousVisibleRect);
if (m_tileCoverage == CoverageForVisibleArea || MemoryPressureHandler::singleton().isUnderMemoryPressure())
return visibleRect;
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)
return visibleRect;
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);
return futureRect;
#else
UNUSED_PARAM(contentsScale);
// FIXME: look at how far the document can scroll in each dimension.
float coverageHorizontalSize = visibleRect.width();
float coverageVerticalSize = visibleRect.height();
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.
if (m_tileCoverage & CoverageForHorizontalScrolling && !largeVisibleRectChange)
coverageHorizontalSize *= 2;
if (m_tileCoverage & CoverageForVerticalScrolling && !largeVisibleRectChange)
coverageVerticalSize *= 3;
coverageVerticalSize += topMarginHeight() + bottomMarginHeight();
coverageHorizontalSize += leftMarginWidth() + rightMarginWidth();
// Can't use m_tileCacheLayer->bounds() here, because the size of the underlying platform layer
// hasn't been updated for the current commit.
FloatRect coverageBounds = boundsForSize(newSize);
float coverageLeft = visibleRect.x() - (coverageHorizontalSize - visibleRect.width()) / 2;
coverageLeft = std::min(coverageLeft, coverageBounds.maxX() - coverageHorizontalSize);
coverageLeft = std::max(coverageLeft, coverageBounds.x());
float coverageTop = visibleRect.y() - (coverageVerticalSize - visibleRect.height()) / 2;
coverageTop = std::min(coverageTop, coverageBounds.maxY() - coverageVerticalSize);
coverageTop = std::max(coverageTop, coverageBounds.y());
return FloatRect(coverageLeft, coverageTop, coverageHorizontalSize, coverageVerticalSize);
#endif
}