Exemple #1
0
static void fillSmoothEdgedRect(GraphicsContext* context, const IntRect& rect, const Color& color)
{
    Color halfColor(color.red(), color.green(), color.blue(), color.alpha() / 2);

    IntRect topRect = rect;
    topRect.inflateX(-1);
    topRect.setHeight(1);
    context->fillRect(topRect, halfColor, ColorSpaceDeviceRGB);

    IntRect leftRect = rect;
    leftRect.inflateY(-1);
    leftRect.setWidth(1);
    context->fillRect(leftRect, halfColor, ColorSpaceDeviceRGB);

    IntRect centerRect = rect;
    centerRect.inflate(-1);
    context->fillRect(centerRect, color, ColorSpaceDeviceRGB);

    IntRect rightRect = rect;
    rightRect.inflateY(-1);
    rightRect.setX(centerRect.maxX());
    rightRect.setWidth(1);
    context->fillRect(rightRect, halfColor, ColorSpaceDeviceRGB);

    IntRect bottomRect = rect;
    bottomRect.inflateX(-1);
    bottomRect.setY(centerRect.maxY());
    bottomRect.setHeight(1);
    context->fillRect(bottomRect, halfColor, ColorSpaceDeviceRGB);
}
IntRect Surface::computePrepareArea()
{
    IntRect area;

    if (!getFirstLayer()->contentIsScrollable()
        && !isBase()
        && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) {

        area = fullContentArea();

        double total = ((double) area.width()) * ((double) area.height());
        if (total > MAX_FULL_CONTENT_AREA)
            area = visibleContentArea();
        /// M: Willy, limit the max number of tile is 64. @{
        else {
            float scale = getFirstLayer()->state()->scale();
            int x = ((double)area.width() * scale) / TilesManager::tileWidth();
            int y = ((double)area.height() * scale) / TilesManager::tileHeight();
            if ((x * y) > 64) {
                IntRect a = visibleContentArea();
                IntRect tmpArea = a;
                tmpArea.inflateX(TilesManager::tileWidth() << 1);
                tmpArea.inflateY(TilesManager::tileHeight() << 1);
                tmpArea.intersect(area);
                area = tmpArea;
            }
        }
        /// @}
    } else
        area = visibleContentArea();

    return area;
}
Exemple #3
0
void TiledBackingStore::adjustForContentsRect(IntRect& rect) const
{
    IntRect bounds = contentsRect();
    IntSize candidateSize = rect.size();

    // We will try to keep the cover and keep rect the same size at all time, which
    // might not be the case when at the content edges.

    // We start by moving when at the edges.
    rect.move(std::max(0, bounds.x() - rect.x()), std::max(0, bounds.y() - rect.y()));
    rect.move(std::min(0, bounds.maxX() - rect.maxX()), std::min(0, bounds.maxY() - rect.maxY()));

    rect.intersect(bounds);

    if (rect.size() == candidateSize)
        return;

    // Even now we might cover more than the content area so let's inflate in the
    // opposite directions.
    int pixelsCovered = candidateSize.width() * candidateSize.height();

    if (rect.width() != candidateSize.width())
        rect.inflateY(((pixelsCovered / rect.width()) - rect.height()) / 2);
    if (rect.height() != candidateSize.height())
        rect.inflateX(((pixelsCovered / rect.height()) - rect.width()) / 2);

    rect.intersect(bounds);
}
Exemple #4
0
IntRect TiledDrawingAreaProxy::calculateCoverRect(const IntRect& visibleRect) const
{
    IntRect result = visibleRect;
    result.inflateX(visibleRect.width() * (m_coverAreaMultiplier.width() - 1));
    result.inflateY(visibleRect.height() * (m_coverAreaMultiplier.height() - 1));
    result.intersect(contentsRect());
    return result;
}
Exemple #5
0
void TiledBackingStore::computeCoverAndKeepRect(const IntRect& visibleRect, IntRect& coverRect, IntRect& keepRect) const
{
    coverRect = visibleRect;
    keepRect = visibleRect;

    // If we cover more that the actual viewport we can be smart about which tiles we choose to render.
    if (m_coverAreaMultiplier > 1) {
        // The initial cover area covers equally in each direction, according to the coverAreaMultiplier.
        coverRect.inflateX(visibleRect.width() * (m_coverAreaMultiplier - 1) / 2);
        coverRect.inflateY(visibleRect.height() * (m_coverAreaMultiplier - 1) / 2);
        keepRect = coverRect;

        if (m_trajectoryVector != FloatPoint::zero()) {
            // A null trajectory vector (no motion) means that tiles for the coverArea will be created.
            // A non-null trajectory vector will shrink the covered rect to visibleRect plus its expansion from its
            // center toward the cover area edges in the direction of the given vector.

            // E.g. if visibleRect == (10,10)5x5 and coverAreaMultiplier == 3.0:
            // a (0,0) trajectory vector will create tiles intersecting (5,5)15x15,
            // a (1,0) trajectory vector will create tiles intersecting (10,10)10x5,
            // and a (1,1) trajectory vector will create tiles intersecting (10,10)10x10.

            // Multiply the vector by the distance to the edge of the cover area.
            float trajectoryVectorMultiplier = (m_coverAreaMultiplier - 1) / 2;

            // Unite the visible rect with a "ghost" of the visible rect moved in the direction of the trajectory vector.
            coverRect = visibleRect;
            coverRect.move(coverRect.width() * m_trajectoryVector.x() * trajectoryVectorMultiplier,
                           coverRect.height() * m_trajectoryVector.y() * trajectoryVectorMultiplier);

            coverRect.unite(visibleRect);
        }
        ASSERT(keepRect.contains(coverRect));
    }

    adjustForContentsRect(coverRect);

    // The keep rect is an inflated version of the cover rect, inflated in tile dimensions.
    keepRect.unite(coverRect);
    keepRect.inflateX(m_tileSize.width() / 2);
    keepRect.inflateY(m_tileSize.height() / 2);
    keepRect.intersect(m_rect);

    ASSERT(coverRect.isEmpty() || keepRect.contains(coverRect));
}
Exemple #6
0
IntRect Scrollbar::trackRect()
{
    IntRect rect = frameRect();
    if (orientation() == HorizontalScrollbar)
        rect.inflateX(-kScrollbarMargin);
    else
        rect.inflateY(-kScrollbarMargin);
    return rect;
}
IntRect ScrollbarThemeOverlay::trackRect(const ScrollbarThemeClient& scrollbar, bool)
{
    IntRect rect = scrollbar.frameRect();
    if (scrollbar.orientation() == HorizontalScrollbar)
        rect.inflateX(-m_scrollbarMargin);
    else
        rect.inflateY(-m_scrollbarMargin);
    return rect;
}
IntRect ScrollbarThemeChromiumAndroid::trackRect(ScrollbarThemeClient* scrollbar, bool)
{
    IntRect rect = scrollbar->frameRect();
    if (scrollbar->orientation() == HorizontalScrollbar)
        rect.inflateX(-scrollbarMargin);
    else
        rect.inflateY(-scrollbarMargin);
    return rect;
}
Exemple #9
0
IntRect TiledBackingStore::computeKeepRect(const IntRect& visibleRect) const
{
    IntRect result = visibleRect;
    // Inflates to both sides, so divide the inflate delta by 2.
    result.inflateX(visibleRect.width() * (m_keepAreaMultiplier - 1) / 2);
    result.inflateY(visibleRect.height() * (m_keepAreaMultiplier - 1) / 2);
    result.intersect(contentsRect());

    return result;
}
Exemple #10
0
IntRect TiledLayerChromium::idlePaintRect(const IntRect& visibleLayerRect)
{
    IntRect prepaintRect = visibleLayerRect;
    // FIXME: This can be made a lot larger if we can:
    // - reserve memory at a lower priority than for visible content
    // - only reserve idle paint tiles up to a memory reclaim threshold and
    // - insure we play nicely with other layers
    prepaintRect.inflateX(m_tiler->tileSize().width());
    prepaintRect.inflateY(m_tiler->tileSize().height());
    prepaintRect.intersect(IntRect(IntPoint::zero(), contentBounds()));
    return prepaintRect;
}
Exemple #11
0
bool RenderThemeQStyle::paintInnerSpinButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
{
    StylePainterQStyle p(this, paintInfo);
    if (!p.isValid())
       return true;

    QStyleOptionSpinBox option;
    initStyleOption(p.widget, option);
    option.subControls = QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown;
    if (!isReadOnlyControl(o)) {
        if (isEnabled(o))
            option.stepEnabled = QAbstractSpinBox::StepUpEnabled | QAbstractSpinBox::StepDownEnabled;
        if (isPressed(o)) {
            option.state |= QStyle::State_Sunken;
            if (isSpinUpButtonPartPressed(o))
                option.activeSubControls = QStyle::SC_SpinBoxUp;
            else
                option.activeSubControls = QStyle::SC_SpinBoxDown;
        }
    }
    // Render the spin buttons for LTR or RTL accordingly.
    option.direction = o->style()->isLeftToRightDirection() ? Qt::LeftToRight : Qt::RightToLeft;

    IntRect buttonRect = rect;
    // Default to moving the buttons a little bit within the editor frame.
    int inflateX = -2;
    int inflateY = -2;
#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
    // QMacStyle will position the aqua buttons flush to the right.
    // This will move them more within the control for better style, a la
    // Chromium look & feel.
    if (qobject_cast<QMacStyle*>(p.style)) {
        inflateX = -4;
        // Render mini aqua spin buttons for QMacStyle to fit nicely into
        // the editor area, like Chromium.
        option.state |= QStyle::State_Mini;
    }
#endif
#if !defined(QT_NO_STYLE_PLASTIQUE)
    // QPlastiqueStyle looks best when the spin buttons are flush with the frame's edge.
    if (qobject_cast<QPlastiqueStyle*>(p.style)) {
        inflateX = 0;
        inflateY = 0;
    }
#endif

    buttonRect.inflateX(inflateX);
    buttonRect.inflateY(inflateY);
    option.rect = buttonRect;

    p.drawComplexControl(QStyle::CC_SpinBox, option);
    return false;
}
Exemple #12
0
bool ScrollbarThemeWin::shouldSnapBackToDragOrigin(Scrollbar* scrollbar, const PlatformMouseEvent& evt)
{
    // Find the rect within which we shouldn't snap, by expanding the track rect
    // in both dimensions.
    IntRect rect = trackRect(scrollbar);
    const bool horz = scrollbar->orientation() == HorizontalScrollbar;
    const int thickness = scrollbarThickness(scrollbar->controlSize());
    rect.inflateX((horz ? kOffEndMultiplier : kOffSideMultiplier) * thickness);
    rect.inflateY((horz ? kOffSideMultiplier : kOffEndMultiplier) * thickness);

    // Convert the event to local coordinates.
    IntPoint mousePosition = scrollbar->convertFromContainingWindow(evt.pos());
    mousePosition.move(scrollbar->x(), scrollbar->y());

    // We should snap iff the event is outside our calculated rect.
    return !rect.contains(mousePosition);
}
Exemple #13
0
// A null trajectory vector means that tiles intersecting all the coverArea (i.e. visibleRect * coverMultiplier) will be created.
// A non-null trajectory vector will shrink the intersection rect to visibleRect plus its expansion from its
// center toward the cover area edges in the direction of the given vector.
// E.g. if visibleRect == (10,10)5x5 and coverMultiplier == 3.0:
// a (0,0) trajectory vector will create tiles intersecting (5,5)15x15,
// a (1,0) trajectory vector will create tiles intersecting (10,10)10x5,
// and a (1,1) trajectory vector will create tiles intersecting (10,10)10x10.
IntRect TiledBackingStore::computeCoverRect(const IntRect& visibleRect) const
{
    IntRect result = visibleRect;
    float trajectoryVectorNorm = sqrt(pow(m_visibleRectTrajectoryVector.x(), 2) + pow(m_visibleRectTrajectoryVector.y(), 2));
    if (trajectoryVectorNorm > 0) {
        // Multiply the vector by the distance to the edge of the cover area.
        float trajectoryVectorMultiplier = (m_coverAreaMultiplier - 1) / 2;
        // Unite the visible rect with a "ghost" of the visible rect moved in the direction of the trajectory vector.
        result.move(result.width() * m_visibleRectTrajectoryVector.x() / trajectoryVectorNorm * trajectoryVectorMultiplier,
                    result.height() * m_visibleRectTrajectoryVector.y() / trajectoryVectorNorm * trajectoryVectorMultiplier);
        result.unite(visibleRect);
    } else {
        result.inflateX(visibleRect.width() * (m_coverAreaMultiplier - 1) / 2);
        result.inflateY(visibleRect.height() * (m_coverAreaMultiplier - 1) / 2);
    }
    result.intersect(contentsRect());

    return result;
}
void RenderThemeGtk::adjustRepaintRect(const RenderObject* renderObject, IntRect& rect)
{
    ControlPart part = renderObject->style().appearance();
    switch (part) {
    case CheckboxPart:
    case RadioPart: {
        // We ignore the interior focus property and always expand the focus rect. In GTK+, the
        // focus indicator is usually on the text next to a checkbox or radio button, but that doesn't
        // happen in WebCore. By expanding the focus rectangle unconditionally we increase its prominence.
        adjustRectForFocus(part == CheckboxPart ? gtkCheckButton() : gtkRadioButton(), rect, true);
        return;
    }
    case InnerSpinButtonPart:
        // See paintInnerSpinButton for an explanation of why we expand the painting rect.
        rect.inflateY(2);
        rect.setWidth(rect.width() + 2);
    default:
        return;
    }
}
Exemple #15
0
void TiledBackingStore::adjustForContentsRect(IntRect& rect) const
{
    IntRect bounds = m_rect;
    IntSize candidateSize = rect.size();

    rect.intersect(bounds);

    if (rect.size() == candidateSize)
        return;

    /*
     * In the following case, there is no intersection of the contents rect and the cover rect.
     * Thus the latter should not be inflated.
     *
     *  +---------------+
     *  |   m_rect      |
     *  +---------------+
     *
     *          +-------------------------------+
     *          |          cover rect           |
     *          |         +---------+           |
     *          |         | visible |           |
     *          |         |  rect   |           |
     *          |         +---------+           |
     *          +-------------------------------+
     */
    if (rect.isEmpty())
        return;

    // Try to create a cover rect of the same size as the candidate, but within content bounds.
    int pixelsCovered = candidateSize.width() * candidateSize.height();

    if (rect.width() < candidateSize.width())
        rect.inflateY(((pixelsCovered / rect.width()) - rect.height()) / 2);
    if (rect.height() < candidateSize.height())
        rect.inflateX(((pixelsCovered / rect.height()) - rect.width()) / 2);

    rect.intersect(bounds);
}
void TiledBackingStore::createTiles()
{
    if (m_contentsFrozen)
        return;
    
    IntRect visibleRect = mapFromContents(m_client->tiledBackingStoreVisibleRect());
    m_previousVisibleRect = visibleRect;

    if (visibleRect.isEmpty())
        return;

    // Remove tiles that extend outside the current contents rect.
    dropOverhangingTiles();

    IntRect keepRect = visibleRect;
    // Inflates to both sides, so divide inflate delta by 2
    keepRect.inflateX(visibleRect.width() * (m_keepAreaMultiplier.width() - 1.f) / 2);
    keepRect.inflateY(visibleRect.height() * (m_keepAreaMultiplier.height() - 1.f) / 2);
    keepRect.intersect(contentsRect());
    
    dropTilesOutsideRect(keepRect);
    
    IntRect coverRect = visibleRect;
    // Inflates to both sides, so divide inflate delta by 2
    coverRect.inflateX(visibleRect.width() * (m_coverAreaMultiplier.width() - 1.f) / 2);
    coverRect.inflateY(visibleRect.height() * (m_coverAreaMultiplier.height() - 1.f) / 2);
    coverRect.intersect(contentsRect());
    
    // Search for the tile position closest to the viewport center that does not yet contain a tile. 
    // Which position is considered the closest depends on the tileDistance function.
    double shortestDistance = std::numeric_limits<double>::infinity();
    Vector<Tile::Coordinate> tilesToCreate;
    unsigned requiredTileCount = 0;
    Tile::Coordinate topLeft = tileCoordinateForPoint(coverRect.location());
    Tile::Coordinate bottomRight = tileCoordinateForPoint(IntPoint(coverRect.maxX(), coverRect.maxY()));
    for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
        for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
            Tile::Coordinate currentCoordinate(xCoordinate, yCoordinate);
            if (tileAt(currentCoordinate))
                continue;
            ++requiredTileCount;
            // Distance is 0 for all currently visible tiles.
            double distance = tileDistance(visibleRect, currentCoordinate);
            if (distance > shortestDistance)
                continue;
            if (distance < shortestDistance) {
                tilesToCreate.clear();
                shortestDistance = distance;
            }
            tilesToCreate.append(currentCoordinate);
        }
    }
    
    // Now construct the tile(s)
    unsigned tilesToCreateCount = tilesToCreate.size();
    for (unsigned n = 0; n < tilesToCreateCount; ++n) {
        Tile::Coordinate coordinate = tilesToCreate[n];
        setTile(coordinate, Tile::create(this, coordinate));
    }
    requiredTileCount -= tilesToCreateCount;
    
    // Paint the content of the newly created tiles
    if (tilesToCreateCount)
        updateTileBuffers();

    // Keep creating tiles until the whole coverRect is covered.
    if (requiredTileCount)
        m_tileCreationTimer->startOneShot(m_tileCreationDelay);
}
Exemple #17
0
void TileGrid::prepareGL(GLWebViewState* state, float scale,
                         const IntRect& prepareArea, const IntRect& fullContentArea,
                         TilePainter* painter, int regionFlags, bool isLowResPrefetch,
                         bool updateWithBlit)
{
    // first, how many tiles do we need
    m_area = computeTilesArea(prepareArea, scale);
    if (m_area.isEmpty())
        return;

    ALOGV("prepare TileGrid %p with scale %.2f, prepareArea "
          " %d, %d - %d x %d, corresponding to %d, %d x - %d x %d tiles",
          this, scale,
          prepareArea.x(), prepareArea.y(),
          prepareArea.width(), prepareArea.height(),
          m_area.x(), m_area.y(),
          m_area.width(), m_area.height());

    bool goingDown = m_prevTileY < m_area.y();
    m_prevTileY = m_area.y();

    TilesManager* tilesManager = TilesManager::instance();
    if (scale != m_scale)
        tilesManager->removeOperationsForFilter(new ScaleFilter(painter, m_scale));

    m_scale = scale;

    // apply dirty region to affected tiles
    if (!m_dirtyRegion.isEmpty()) {
        for (unsigned int i = 0; i < m_tiles.size(); i++)
            m_tiles[i]->markAsDirty(m_dirtyRegion);

        // log inval region for the base surface
        if (m_isBaseSurface && tilesManager->getProfiler()->enabled()) {
            SkRegion::Iterator iterator(m_dirtyRegion);
            while (!iterator.done()) {
                SkIRect r = iterator.rect();
                tilesManager->getProfiler()->nextInval(r, scale);
                iterator.next();
            }
        }
        m_dirtyRegion.setEmpty();
    }

    if (regionFlags & StandardRegion) {
        for (int i = 0; i < m_area.width(); i++) {
            if (goingDown) {
                for (int j = 0; j < m_area.height(); j++)
                    prepareTile(m_area.x() + i, m_area.y() + j,
                                painter, state, isLowResPrefetch, false, updateWithBlit);
            } else {
                for (int j = m_area.height() - 1; j >= 0; j--)
                    prepareTile(m_area.x() + i, m_area.y() + j,
                                painter, state, isLowResPrefetch, false, updateWithBlit);
            }
        }
    }

    if (regionFlags & ExpandedRegion) {
        IntRect fullArea = computeTilesArea(fullContentArea, scale);
        IntRect expandedArea = m_area;

        // on systems reporting highEndGfx=true and useMinimalMemory not set, use expanded bounds
        if (tilesManager->highEndGfx() && !tilesManager->useMinimalMemory())
            expandedArea.inflate(EXPANDED_BOUNDS_INFLATE);

        if (isLowResPrefetch)
            expandedArea.inflateY(EXPANDED_PREFETCH_BOUNDS_Y_INFLATE);

        // clip painting area to content
        expandedArea.intersect(fullArea);

        for (int i = expandedArea.x(); i < expandedArea.maxX(); i++)
            for (int j = expandedArea.y(); j < expandedArea.maxY(); j++)
                if (!m_area.contains(i, j))
                    prepareTile(i, j, painter, state, isLowResPrefetch, true, updateWithBlit);
    }
}
Exemple #18
0
void RenderRadio::paintObject(PaintInfo& i, int _tx, int _ty)
{
    ASSERT(node());
    Element* element = static_cast<Element*>(node());
    InputElement* inputElement = toInputElement(element);
    bool isEnabled = element->isEnabledFormControl();
    bool isChecked = inputElement->isChecked();
    
    i.context->save();

	RefPtr<Image> image = Image::loadPlatformResource( "radioButtonStates" ).get();
	IntPoint destPt( _tx, _ty );
	IntRect srcRect( 0, 0, 14, 16 );

    if (isEnabled)
	{
		if (node()->active())
		{
			if (isChecked)
			{
				srcRect.move( 75, 0 );
			}
			else
			{
				srcRect.move( 60, 0 );
			}
		}
		else if (node()->hovered())
		{
			if (isChecked)
			{
				srcRect.move( 45, 0 );
			}
			else
			{
				srcRect.move( 30, 0 );
			}
		}
		else
		{
			if (isChecked)
			{
				srcRect.move( 15, 0 );
			}
			else
			{
			}
		}
	}
	else 
	{
	    if (isChecked)
		{
			srcRect.move( 105, 0 );
		}
		else
		{
			srcRect.move( 90, 0 );
		}
	}

	i.context->drawImage( image.get(), DeviceColorSpace, destPt, srcRect ); 

    // draw the focus ring.
    //
    if (node()->focused())
    {
        IntRect focusRingSrcRect( 120, 0, 15, 17 );
        i.context->drawImage( image.get(), DeviceColorSpace, destPt, focusRingSrcRect ); 
    }

#if 0 
	// this is the old "moveto - lineto" drawing code

	IntRect checkRect(_tx + borderLeft()
                     , _ty + borderTop()
                     , width() - borderLeft() - borderRight()
                     , height() - borderBottom() - borderTop());
    Color fillColor(0xff, 0xff, 0xff, 0x00);
    Color rectColor(0x18, 0x52, 0x84);
    Color checkColor(0x21, 0xa5, 0x21);
    if (!node()->isEnabled()) {
        rectColor = Color(0xce, 0xce, 0xdb);
        checkColor = Color(0xce, 0xce, 0xdb);
    }
    i.context->setStrokeThickness(1);
    i.context->setStrokeStyle(SolidStroke);
    i.context->setStrokeColor(rectColor);
    i.context->setFillColor(fillColor);
    i.context->drawEllipse(checkRect);

    if(node()->isEnabled() && node()->hovered()) {
        i.context->setStrokeColor(Color(0xff, 0xb5, 0x31));
        
        IntRect hoverRect = checkRect;
        hoverRect.inflateX(-1);
        hoverRect.inflateY(-1);
        i.context->drawEllipse( hoverRect );
        hoverRect.inflateX(-1);
        hoverRect.inflateY(-1);
        i.context->drawEllipse( hoverRect );

    }

    if (isChecked) {
        i.context->setStrokeThickness(2);
        i.context->setStrokeColor(checkColor);
        i.context->setFillColor(checkColor);

        IntRect fillRect = checkRect;
        fillRect.inflateX(-2);
        fillRect.inflateY(-2);
        i.context->drawEllipse(fillRect);

    }
#endif

    i.context->restore();
}