FloatRect AffineTransform::mapRect(const FloatRect& rect) const { if (isIdentityOrTranslation()) { FloatRect mappedRect(rect); mappedRect.move(narrowPrecisionToFloat(m_transform[4]), narrowPrecisionToFloat(m_transform[5])); return mappedRect; } FloatQuad result; result.setP1(mapPoint(rect.location())); result.setP2(mapPoint(FloatPoint(rect.right(), rect.y()))); result.setP3(mapPoint(FloatPoint(rect.right(), rect.bottom()))); result.setP4(mapPoint(FloatPoint(rect.x(), rect.bottom()))); return result.boundingBox(); }
bool FloatRect::intersects(const FloatRect& other) const { // Checking emptiness handles negative widths as well as zero. return !isEmpty() && !other.isEmpty() && x() < other.right() && other.x() < right() && y() < other.bottom() && other.y() < bottom(); }
static inline FloatRect normalizeRect(const FloatRect& rect) { return FloatRect(min(rect.x(), rect.right()), min(rect.y(), rect.bottom()), max(rect.width(), -rect.width()), max(rect.height(), -rect.height())); }
IntRect enclosingIntRect(const FloatRect& rect) { int l = static_cast<int>(floorf(rect.x())); int t = static_cast<int>(floorf(rect.y())); int r = static_cast<int>(ceilf(rect.right())); int b = static_cast<int>(ceilf(rect.bottom())); return IntRect(l, t, r - l, b - t); }
IntRect enclosingIntRect(const FloatRect& rect) { int l = static_cast<int>(rect.x()); int t = static_cast<int>(rect.y()); // FIXME: These two need to be a "ceiling" operation, not rounding. // We changed them to do "+ 0.5f" to compile on Win32 where there's // no ceilf, but they should be changed back to "ceiling" at some point // and we should provide an implementation of ceilf for Win32. int r = static_cast<int>(rect.right() + 0.5f); int b = static_cast<int>(rect.bottom() + 0.5f); return IntRect(l, t, r - l, b - t); }
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOp) { 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; } CGContextRef context = ctxt->platformContext(); ctxt->save(); // 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. CGSize selfSize = size(); FloatRect adjustedDestRect = destRect; if (srcRect.width() != selfSize.width || srcRect.height() != selfSize.height) { // A subportion of the image is drawing. Adjust the destination rect to // account for this. float xScale = srcRect.width() / destRect.width(); float yScale = srcRect.height() / destRect.height(); adjustedDestRect.setLocation(FloatPoint(destRect.x() - srcRect.x() / xScale, destRect.y() - srcRect.y() / yScale)); adjustedDestRect.setSize(FloatSize(size().width() / xScale, size().height() / yScale)); CGContextClipToRect(context, destRect); } // If the image is only partially loaded, then shrink the destination rect that we're drawing into accordingly. float currHeight = CGImageGetHeight(image); if (currHeight < selfSize.height) adjustedDestRect.setHeight(adjustedDestRect.height() * currHeight / selfSize.height); // Flip the coords. ctxt->setCompositeOperation(compositeOp); CGContextTranslateCTM(context, adjustedDestRect.x(), adjustedDestRect.bottom()); CGContextScaleCTM(context, 1, -1); adjustedDestRect.setLocation(FloatPoint()); // Draw the image. CGContextDrawImage(context, adjustedDestRect, image); ctxt->restore(); startAnimation(); if (imageObserver()) imageObserver()->didDraw(this); }
WindowFeatures::WindowFeatures(const String& dialogFeaturesString, const FloatRect& screenAvailableRect) : widthSet(true) , heightSet(true) , menuBarVisible(false) , toolBarVisible(false) , locationBarVisible(false) , fullscreen(false) , dialog(true) { DialogFeaturesMap features; parseDialogFeatures(dialogFeaturesString, features); const bool trusted = false; // The following features from Microsoft's documentation are not implemented: // - default font settings // - width, height, left, and top specified in units other than "px" // - edge (sunken or raised, default is raised) // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?) // - unadorned: trusted && boolFeature(features, "unadorned"); width = floatFeature(features, "dialogwidth", 100, screenAvailableRect.width(), 620); // default here came from frame size of dialog in MacIE height = floatFeature(features, "dialogheight", 100, screenAvailableRect.height(), 450); // default here came from frame size of dialog in MacIE x = floatFeature(features, "dialogleft", screenAvailableRect.x(), screenAvailableRect.right() - width, -1); xSet = x > 0; y = floatFeature(features, "dialogtop", screenAvailableRect.y(), screenAvailableRect.bottom() - height, -1); ySet = y > 0; if (boolFeature(features, "center", true)) { if (!xSet) { x = screenAvailableRect.x() + (screenAvailableRect.width() - width) / 2; xSet = true; } if (!ySet) { y = screenAvailableRect.y() + (screenAvailableRect.height() - height) / 2; ySet = true; } } resizable = boolFeature(features, "resizable"); scrollbarsVisible = boolFeature(features, "scroll", true); statusBarVisible = boolFeature(features, "status", !trusted); }
void FloatRect::unite(const FloatRect& other) { // Handle empty special cases first. if (other.isEmpty()) return; if (isEmpty()) { *this = other; return; } float l = min(x(), other.x()); float t = min(y(), other.y()); float r = max(right(), other.right()); float b = max(bottom(), other.bottom()); m_location.setX(l); m_location.setY(t); m_size.setWidth(r - l); m_size.setHeight(b - t); }
void FloatRect::intersect(const FloatRect& other) { float l = max(x(), other.x()); float t = max(y(), other.y()); float r = min(right(), other.right()); float b = min(bottom(), other.bottom()); // Return a clean empty rectangle for non-intersecting cases. if (l >= r || t >= b) { l = 0; t = 0; r = 0; b = 0; } m_location.setX(l); m_location.setY(t); m_size.setWidth(r - l); m_size.setHeight(b - t); }
IntRect TiledImageOpenVG::tilesInRect(const FloatRect& rect) const { int leftIndex = static_cast<int>(rect.x()) / m_maxTileSize.width(); int topIndex = static_cast<int>(rect.y()) / m_maxTileSize.height(); if (leftIndex < 0) leftIndex = 0; if (topIndex < 0) topIndex = 0; // Round rect edges up to get the outer pixel boundaries. int rightIndex = (static_cast<int>(ceil(rect.right())) - 1) / m_maxTileSize.width(); int bottomIndex = (static_cast<int>(ceil(rect.bottom())) - 1) / m_maxTileSize.height(); int columns = (rightIndex - leftIndex) + 1; int rows = (bottomIndex - topIndex) + 1; return IntRect(leftIndex, topIndex, (columns <= m_numColumns) ? columns : m_numColumns, (rows <= (m_tiles.size() / m_numColumns)) ? rows : (m_tiles.size() / m_numColumns)); }
void SVGRenderStyle::inflateForShadow(FloatRect& repaintRect) const { ShadowData* svgShadow = shadow(); if (!svgShadow) return; int shadowTop; int shadowRight; int shadowBottom; int shadowLeft; getSVGShadowExtent(svgShadow, shadowTop, shadowRight, shadowBottom, shadowLeft); int overflowLeft = repaintRect.x() + shadowLeft; int overflowRight = repaintRect.right() + shadowRight; int overflowTop = repaintRect.y() + shadowTop; int overflowBottom = repaintRect.bottom() + shadowBottom; repaintRect.setX(overflowLeft); repaintRect.setY(overflowTop); repaintRect.setWidth(overflowRight - overflowLeft); repaintRect.setHeight(overflowBottom - overflowTop); }
void GraphicsContextPlatformPrivate::clip(const FloatRect& clipRect) { if (!m_hdc) return; IntersectClipRect(m_hdc, clipRect.x(), clipRect.y(), clipRect.right(), clipRect.bottom()); }
bool FloatRect::contains(const FloatRect& other) const { return x() <= other.x() && right() >= other.right() && y() <= other.y() && bottom() >= other.bottom(); }
void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) { if (offset > m_end) offset = m_end; int currentCharacter = m_currentCharacter; const UChar* cp = m_run.data(currentCharacter); bool rtl = m_run.rtl(); bool hasExtraSpacing = (m_font->letterSpacing() || m_font->wordSpacing() || m_padding) && !m_run.spacingDisabled(); float widthSinceLastRounding = m_runWidthSoFar; m_runWidthSoFar = floorf(m_runWidthSoFar); widthSinceLastRounding -= m_runWidthSoFar; float lastRoundingWidth = m_finalRoundingWidth; FloatRect bounds; const SimpleFontData* primaryFont = m_font->primaryFont(); const SimpleFontData* lastFontData = primaryFont; while (currentCharacter < offset) { UChar32 c = *cp; unsigned clusterLength = 1; if (c >= 0x3041) { if (c <= 0x30FE) { // Deal with Hiragana and Katakana voiced and semi-voiced syllables. // Normalize into composed form, and then look for glyph with base + combined mark. // Check above for character range to minimize performance impact. UChar32 normalized = normalizeVoicingMarks(currentCharacter); if (normalized) { c = normalized; clusterLength = 2; } } else if (U16_IS_SURROGATE(c)) { if (!U16_IS_SURROGATE_LEAD(c)) break; // Do we have a surrogate pair? If so, determine the full Unicode (32 bit) // code point before glyph lookup. // Make sure we have another character and it's a low surrogate. if (currentCharacter + 1 >= m_run.length()) break; UChar low = cp[1]; if (!U16_IS_TRAIL(low)) break; c = U16_GET_SUPPLEMENTARY(c, low); clusterLength = 2; } } const GlyphData& glyphData = m_font->glyphDataForCharacter(c, rtl); Glyph glyph = glyphData.glyph; const SimpleFontData* fontData = glyphData.fontData; ASSERT(fontData); // Now that we have a glyph and font data, get its width. float width; if (c == '\t' && m_run.allowTabs()) { float tabWidth = m_font->tabWidth(*fontData); width = tabWidth - fmodf(m_run.xPos() + m_runWidthSoFar + widthSinceLastRounding, tabWidth); } else { width = fontData->widthForGlyph(glyph); #if ENABLE(SVG) // SVG uses horizontalGlyphStretch(), when textLength is used to stretch/squeeze text. width *= m_run.horizontalGlyphStretch(); #endif // We special case spaces in two ways when applying word rounding. // First, we round spaces to an adjusted width in all fonts. // Second, in fixed-pitch fonts we ensure that all characters that // match the width of the space character have the same width as the space character. if (width == fontData->spaceWidth() && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) && m_run.applyWordRounding()) width = fontData->adjustedSpaceWidth(); } if (fontData != lastFontData && width) { lastFontData = fontData; if (m_fallbackFonts && fontData != primaryFont) { // FIXME: This does a little extra work that could be avoided if // glyphDataForCharacter() returned whether it chose to use a small caps font. if (!m_font->isSmallCaps() || c == toUpper(c)) m_fallbackFonts->add(fontData); else { const GlyphData& uppercaseGlyphData = m_font->glyphDataForCharacter(toUpper(c), rtl); if (uppercaseGlyphData.fontData != primaryFont) m_fallbackFonts->add(uppercaseGlyphData.fontData); } } } if (hasExtraSpacing) { // Account for letter-spacing. if (width && m_font->letterSpacing()) width += m_font->letterSpacing(); if (Font::treatAsSpace(c)) { // Account for padding. WebCore uses space padding to justify text. // We distribute the specified padding over the available spaces in the run. if (m_padding) { // Use left over padding if not evenly divisible by number of spaces. if (m_padding < m_padPerSpace) { width += m_padding; m_padding = 0; } else { float previousPadding = m_padding; m_padding -= m_padPerSpace; width += roundf(previousPadding) - roundf(m_padding); } } // Account for word spacing. // We apply additional space between "words" by adding width to the space character. if (currentCharacter != 0 && !Font::treatAsSpace(cp[-1]) && m_font->wordSpacing()) width += m_font->wordSpacing(); } } if (m_accountForGlyphBounds) { bounds = fontData->boundsForGlyph(glyph); if (!currentCharacter) m_firstGlyphOverflow = max<float>(0, -bounds.x()); } if (m_forTextEmphasis && !Font::canReceiveTextEmphasis(c)) glyph = 0; // Advance past the character we just dealt with. cp += clusterLength; currentCharacter += clusterLength; // Account for float/integer impedance mismatch between CG and KHTML. "Words" (characters // followed by a character defined by isRoundingHackCharacter()) are always an integer width. // We adjust the width of the last character of a "word" to ensure an integer width. // If we move KHTML to floats we can remove this (and related) hacks. float oldWidth = width; // Force characters that are used to determine word boundaries for the rounding hack // to be integer width, so following words will start on an integer boundary. if (m_run.applyWordRounding() && Font::isRoundingHackCharacter(c)) { width = ceilf(width); // Since widthSinceLastRounding can lose precision if we include measurements for // preceding whitespace, we bypass it here. m_runWidthSoFar += width; // Since this is a rounding hack character, we should have reset this sum on the previous // iteration. ASSERT(!widthSinceLastRounding); } else { // Check to see if the next character is a "rounding hack character", if so, adjust // width so that the total run width will be on an integer boundary. if ((m_run.applyWordRounding() && currentCharacter < m_run.length() && Font::isRoundingHackCharacter(*cp)) || (m_run.applyRunRounding() && currentCharacter >= m_end)) { float totalWidth = widthSinceLastRounding + width; widthSinceLastRounding = ceilf(totalWidth); width += widthSinceLastRounding - totalWidth; m_runWidthSoFar += widthSinceLastRounding; widthSinceLastRounding = 0; } else widthSinceLastRounding += width; } if (glyphBuffer) glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width)); lastRoundingWidth = width - oldWidth; if (m_accountForGlyphBounds) { m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, bounds.bottom()); m_minGlyphBoundingBoxY = min(m_minGlyphBoundingBoxY, bounds.y()); m_lastGlyphOverflow = max<float>(0, bounds.right() - width); } } m_currentCharacter = currentCharacter; m_runWidthSoFar += widthSinceLastRounding; m_finalRoundingWidth = lastRoundingWidth; }
// 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())); }
void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace, CompositeOperator, const FloatRect& dstRect) { #if USE(WXGC) wxGCDC* context = (wxGCDC*)ctxt->platformContext(); wxGraphicsBitmap* bitmap = nativeImageForCurrentFrame(); #else wxDC* context = ctxt->platformContext(); wxBitmap* bitmap = nativeImageForCurrentFrame(); #endif if (!bitmap) // If it's too early we won't have an image yet. return; ctxt->save(); ctxt->clip(IntRect(dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height())); float currentW = 0; float currentH = 0; #if USE(WXGC) wxGraphicsContext* gc = context->GetGraphicsContext(); float adjustedX = phase.x() + srcRect.x() * narrowPrecisionToFloat(patternTransform.a()); float adjustedY = phase.y() + srcRect.y() * narrowPrecisionToFloat(patternTransform.d()); gc->ConcatTransform(patternTransform); #else float adjustedX = phase.x(); float adjustedY = phase.y(); wxMemoryDC mydc; mydc.SelectObject(*bitmap); ctxt->concatCTM(patternTransform); #endif //wxPoint origin(context->GetDeviceOrigin()); AffineTransform mat(ctxt->getCTM()); wxPoint origin(mat.mapPoint(IntPoint(0, 0))); wxSize clientSize(context->GetSize()); wxCoord w = srcRect.width(); wxCoord h = srcRect.height(); wxCoord srcx = srcRect.x(); wxCoord srcy = srcRect.y(); while (currentW < dstRect.right() - phase.x() && origin.x + adjustedX + currentW < clientSize.x) { while (currentH < dstRect.bottom() - phase.y() && origin.y + adjustedY + currentH < clientSize.y) { #if USE(WXGC) #if wxCHECK_VERSION(2,9,0) gc->DrawBitmap(*bitmap, adjustedX + currentW, adjustedY + currentH, (wxDouble)srcRect.width(), (wxDouble)srcRect.height()); #else gc->DrawGraphicsBitmap(*bitmap, adjustedX + currentW, adjustedY + currentH, (wxDouble)srcRect.width(), (wxDouble)srcRect.height()); #endif #else context->Blit(adjustedX + currentW, adjustedY + currentH, w, h, &mydc, srcx, srcy, wxCOPY, true); #endif currentH += srcRect.height(); } currentW += srcRect.width(); currentH = 0; } ctxt->restore(); #if !USE(WXGC) mydc.SelectObject(wxNullBitmap); #endif // NB: delete is causing crashes during page load, but not during the deletion // itself. It occurs later on when a valid bitmap created in frameAtIndex // suddenly becomes invalid after returning. It's possible these errors deal // with reentrancy and threding problems. //delete bitmap; startAnimation(); if (ImageObserver* observer = imageObserver()) observer->didDraw(this); }
void BackingStoreScrollbar::repaint(const WebCore::IntRect& hotRect, bool vertical) { SurfaceOpenVG* surface = SurfacePool::globalSurfacePool()->tileRenderingSurface(); const IntSize surfaceSize(surface->width(), surface->height()); PainterOpenVG painter(surface); // If the rendering surface is smaller than the scrollbar // (e.g. when the screen is rotated), paint it multiple times. int lastXTile = (m_size.width() - 1) / surfaceSize.width(); int lastYTile = (m_size.height() - 1) / surfaceSize.height(); FloatRect innerRect = hotRect; innerRect.move(0.5, 0.5); // draw it pixel-perfect with a 1.0 wide stroke int radius = vertical ? hotRect.width() / 2 : hotRect.height() / 2; if (vertical) innerRect.inflateY(-radius); else innerRect.inflateX(-radius); Path path; if (vertical) { path.moveTo(FloatPoint(innerRect.x(), innerRect.y())); path.addArc(FloatPoint(innerRect.x() + radius, innerRect.y()), radius, piFloat, 0, false); path.addLineTo(FloatPoint(innerRect.right(), innerRect.bottom())); path.addArc(FloatPoint(innerRect.x() + radius, innerRect.bottom()), radius, 0, piFloat, false); path.closeSubpath(); } else { path.moveTo(FloatPoint(innerRect.right(), innerRect.y())); path.addArc(FloatPoint(innerRect.right(), innerRect.y() + radius), radius, piFloat + piFloat / 2, piFloat / 2, false); path.addLineTo(FloatPoint(innerRect.x(), innerRect.bottom())); path.addArc(FloatPoint(innerRect.x(), innerRect.y() + radius), radius, piFloat / 2, piFloat + piFloat / 2, false); path.closeSubpath(); } for (int i = 0; i <= lastXTile; ++i) { for (int j = 0; j <= lastYTile; ++j) { const int dstX = i * surfaceSize.width(); const int dstY = j * surfaceSize.height(); const int dstRight = (i == lastXTile) ? m_size.width() : (i + 1) * surfaceSize.width(); const int dstBottom = (j == lastYTile) ? m_size.height() : (j + 1) * surfaceSize.height(); painter.translate(rect().x(), rect().y()); if (dstX || dstY) painter.translate(-dstX, -dstY); // Paint the actual scrollbar. painter.setFillColor(Color(255, 255, 255)); painter.drawRect(IntRect(IntPoint(0, 0), rect().size()), VG_FILL_PATH); painter.setFillColor(Color(173, 176, 178)); painter.drawPath(path, VG_FILL_PATH, WebCore::RULE_NONZERO); surface->makeCurrent(); unsigned char* dstBufferStart = m_image + (dstY * imageStride()) + (dstX * imageBytesPerPixel()); vgReadPixels(dstBufferStart, imageStride(), VG_sRGB_565, 0, 0, dstRight - dstX, dstBottom - dstY); ASSERT_VG_NO_ERROR(); // Paint the alpha channel for the actual scrollbar. painter.setCompositeOperation(CompositeClear); painter.setFillColor(Color(0, 0, 0)); painter.drawRect(IntRect(IntPoint(0, 0), rect().size()), VG_FILL_PATH); painter.setCompositeOperation(CompositeSourceOver); painter.setFillColor(Color(255, 255, 255)); painter.drawPath(path, VG_FILL_PATH, WebCore::RULE_NONZERO); surface->makeCurrent(); // FIXME: We need VG_A_4 until proper alpha blending is available. // When we get 8-bit formats, make sure to adapt both the format // and remove the division by two when determining the dstAlphaBufferStart. unsigned char* dstAlphaBufferStart = m_alphaImage + (dstY * alphaImageStride()) + dstX / 2; vgReadPixels(dstAlphaBufferStart, alphaImageStride(), VG_A_4, 0, 0, dstRight - dstX, dstBottom - dstY); ASSERT_VG_NO_ERROR(); if (dstX || dstY) painter.translate(dstX, dstY); } } }
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp) { startAnimation(); RetainPtr<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(), styleColorSpace, compositeOp); return; } float currHeight = CGImageGetHeight(image.get()); 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() || !ctxt->getCTM().isIdentityOrTranslationOrFlipped()); 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.adoptCF(CGImageCreateWithImageInRect(image.get(), subimageRect)); if (currHeight < srcRect.bottom()) { ASSERT(CGImageGetHeight(image.get()) == currHeight - CGRectIntegral(srcRect).origin.y); adjustedDestRect.setHeight(CGImageGetHeight(image.get()) / 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()); // Adjust the color space. image = imageWithColorSpace(image.get(), styleColorSpace); // Draw the image. CGContextDrawImage(context, adjustedDestRect, image.get()); ctxt->restore(); if (imageObserver()) imageObserver()->didDraw(this); }
JSValue JSDOMWindow::showModalDialog(ExecState* exec) { String url = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(0)); JSValue dialogArgs = exec->argument(1); String featureArgs = valueToStringWithUndefinedOrNullCheck(exec, exec->argument(2)); Frame* frame = impl()->frame(); if (!frame) return jsUndefined(); Frame* lexicalFrame = toLexicalFrame(exec); if (!lexicalFrame) return jsUndefined(); Frame* dynamicFrame = toDynamicFrame(exec); if (!dynamicFrame) return jsUndefined(); if (!DOMWindow::canShowModalDialogNow(frame) || !domWindowAllowPopUp(dynamicFrame)) return jsUndefined(); HashMap<String, String> features; DOMWindow::parseModalDialogFeatures(featureArgs, features); const bool trusted = false; // The following features from Microsoft's documentation are not implemented: // - default font settings // - width, height, left, and top specified in units other than "px" // - edge (sunken or raised, default is raised) // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?) // - unadorned: trusted && boolFeature(features, "unadorned"); FloatRect screenRect = screenAvailableRect(frame->view()); WindowFeatures wargs; wargs.width = WindowFeatures::floatFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE wargs.widthSet = true; wargs.height = WindowFeatures::floatFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE wargs.heightSet = true; wargs.x = WindowFeatures::floatFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1); wargs.xSet = wargs.x > 0; wargs.y = WindowFeatures::floatFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1); wargs.ySet = wargs.y > 0; if (WindowFeatures::boolFeature(features, "center", true)) { if (!wargs.xSet) { wargs.x = screenRect.x() + (screenRect.width() - wargs.width) / 2; wargs.xSet = true; } if (!wargs.ySet) { wargs.y = screenRect.y() + (screenRect.height() - wargs.height) / 2; wargs.ySet = true; } } wargs.dialog = true; wargs.resizable = WindowFeatures::boolFeature(features, "resizable"); wargs.scrollbarsVisible = WindowFeatures::boolFeature(features, "scroll", true); wargs.statusBarVisible = WindowFeatures::boolFeature(features, "status", !trusted); wargs.menuBarVisible = false; wargs.toolBarVisible = false; wargs.locationBarVisible = false; wargs.fullscreen = false; Frame* dialogFrame = createWindow(exec, lexicalFrame, dynamicFrame, frame, url, "", wargs, dialogArgs); if (!dialogFrame) return jsUndefined(); JSDOMWindow* dialogWindow = toJSDOMWindow(dialogFrame, currentWorld(exec)); dialogFrame->page()->chrome()->runModal(); Identifier returnValue(exec, "returnValue"); if (dialogWindow->allowsAccessFromNoErrorMessage(exec)) { PropertySlot slot; // This is safe, we have already performed the origin security check and we are // not interested in any of the DOM properties of the window. if (dialogWindow->JSGlobalObject::getOwnPropertySlot(exec, returnValue, slot)) return slot.getValue(exec, returnValue); } return jsUndefined(); }
static JSValuePtr showModalDialog(ExecState* exec, Frame* frame, const String& url, JSValuePtr dialogArgs, const String& featureArgs) { if (!canShowModalDialogNow(frame) || !allowPopUp(exec)) return jsUndefined(); const HashMap<String, String> features = parseModalDialogFeatures(featureArgs); const bool trusted = false; // The following features from Microsoft's documentation are not implemented: // - default font settings // - width, height, left, and top specified in units other than "px" // - edge (sunken or raised, default is raised) // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog hide when you print // - help: boolFeature(features, "help", true), makes help icon appear in dialog (what does it do on Windows?) // - unadorned: trusted && boolFeature(features, "unadorned"); if (!frame) return jsUndefined(); FloatRect screenRect = screenAvailableRect(frame->view()); WindowFeatures wargs; wargs.width = WindowFeatures::floatFeature(features, "dialogwidth", 100, screenRect.width(), 620); // default here came from frame size of dialog in MacIE wargs.widthSet = true; wargs.height = WindowFeatures::floatFeature(features, "dialogheight", 100, screenRect.height(), 450); // default here came from frame size of dialog in MacIE wargs.heightSet = true; wargs.x = WindowFeatures::floatFeature(features, "dialogleft", screenRect.x(), screenRect.right() - wargs.width, -1); wargs.xSet = wargs.x > 0; wargs.y = WindowFeatures::floatFeature(features, "dialogtop", screenRect.y(), screenRect.bottom() - wargs.height, -1); wargs.ySet = wargs.y > 0; if (WindowFeatures::boolFeature(features, "center", true)) { if (!wargs.xSet) { wargs.x = screenRect.x() + (screenRect.width() - wargs.width) / 2; wargs.xSet = true; } if (!wargs.ySet) { wargs.y = screenRect.y() + (screenRect.height() - wargs.height) / 2; wargs.ySet = true; } } wargs.dialog = true; wargs.resizable = WindowFeatures::boolFeature(features, "resizable"); wargs.scrollbarsVisible = WindowFeatures::boolFeature(features, "scroll", true); wargs.statusBarVisible = WindowFeatures::boolFeature(features, "status", !trusted); wargs.menuBarVisible = false; wargs.toolBarVisible = false; wargs.locationBarVisible = false; wargs.fullscreen = false; Frame* dialogFrame = createWindow(exec, frame, url, "", wargs, dialogArgs); if (!dialogFrame) return jsUndefined(); JSDOMWindow* dialogWindow = toJSDOMWindow(dialogFrame); // Get the return value either just before clearing the dialog window's // properties (in JSDOMWindowBase::clear), or when on return from runModal. JSValuePtr returnValue = noValue(); dialogWindow->setReturnValueSlot(&returnValue); dialogFrame->page()->chrome()->runModal(); dialogWindow->setReturnValueSlot(0); // If we don't have a return value, get it now. // Either JSDOMWindowBase::clear was not called yet, or there was no return value, // and in that case, there's no harm in trying again (no benefit either). if (!returnValue) returnValue = dialogWindow->getDirect(Identifier(exec, "returnValue")); return returnValue ? returnValue : jsUndefined(); }
void FindIndicator::draw(GraphicsContext& graphicsContext, const IntRect& dirtyRect) { for (size_t i = 0; i < m_textRects.size(); ++i) { FloatRect textRect = m_textRects[i]; textRect.move(leftBorderThickness, topBorderThickness); graphicsContext.save(); FloatRect outerPathRect = inflateRect(textRect, horizontalOutsetToCenterOfLightBorder, verticalOutsetToCenterOfLightBorder); graphicsContext.setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowBlurRadius, shadowColor(), ColorSpaceSRGB); graphicsContext.addPath(pathWithRoundedRect(outerPathRect, cornerRadius)); graphicsContext.setFillColor(lightBorderColor(), ColorSpaceDeviceRGB); graphicsContext.fillPath(); graphicsContext.restore(); graphicsContext.save(); FloatRect innerPathRect = inflateRect(textRect, horizontalPaddingInsideLightBorder, verticalPaddingInsideLightBorder); graphicsContext.clip(pathWithRoundedRect(innerPathRect, cornerRadius)); RefPtr<Gradient> gradient = Gradient::create(FloatPoint(innerPathRect.x(), innerPathRect.y()), FloatPoint(innerPathRect.x(), innerPathRect.bottom())); gradient->addColorStop(0, gradientLightColor()); gradient->addColorStop(1, gradientDarkColor()); graphicsContext.setFillGradient(gradient); graphicsContext.fillRect(outerPathRect); graphicsContext.restore(); graphicsContext.save(); graphicsContext.translate(FloatSize(roundf(leftBorderThickness), roundf(topBorderThickness) + m_contentImage->bounds().height())); graphicsContext.scale(FloatSize(1, -1)); m_contentImage->paint(&graphicsContext, m_contentImage->bounds()); graphicsContext.restore(); } }