summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp6
-rw-r--r--Source/WebCore/dom/Document.cpp6
-rw-r--r--Source/WebCore/dom/Document.h1
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp13
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontCacheAndroid.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/fonts/FontPlatformData.h3
-rw-r--r--Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp8
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp17
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.h6
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.cpp44
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp16
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h3
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp33
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h2
-rw-r--r--Source/WebKit/android/jni/WebViewCore.cpp184
-rw-r--r--Source/WebKit/android/jni/WebViewCore.h10
-rw-r--r--Source/WebKit/android/nav/SelectText.h10
-rw-r--r--Source/WebKit/android/nav/WebView.cpp18
18 files changed, 235 insertions, 147 deletions
diff --git a/Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp b/Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
index 7cad58e..d142a9f 100644
--- a/Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
+++ b/Source/WebCore/bindings/v8/custom/V8DocumentCustom.cpp
@@ -43,6 +43,7 @@
#include "V8CanvasRenderingContext2D.h"
#include "V8CustomXPathNSResolver.h"
#include "V8DOMImplementation.h"
+#include "V8DOMWrapper.h"
#include "V8HTMLDocument.h"
#include "V8IsolatedContext.h"
#include "V8Node.h"
@@ -144,9 +145,8 @@ v8::Handle<v8::Value> V8Document::createTouchListCallback(const v8::Arguments& a
RefPtr<TouchList> touchList = TouchList::create();
for (int i = 0; i < args.Length(); i++) {
- if (!args[i]->IsObject())
- return v8::Undefined();
- touchList->append(V8Touch::toNative(args[i]->ToObject()));
+ Touch* touch = V8DOMWrapper::isWrapperOfType(args[i], &V8Touch::info) ? V8Touch::toNative(args[i]->ToObject()) : 0;
+ touchList->append(touch);
}
return toV8(touchList.release());
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index ff50390..b6a1393 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -5064,15 +5064,9 @@ PassRefPtr<Touch> Document::createTouch(DOMWindow* window, EventTarget* target,
// http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/DocumentAdditionsReference/DocumentAdditions/DocumentAdditions.html
// when this method should throw and nor is it by inspection of iOS behavior. It would be nice to verify any cases where it throws under iOS
// and implement them here. See https://bugs.webkit.org/show_bug.cgi?id=47819
- // Ditto for the createTouchList method below.
Frame* frame = window ? window->frame() : this->frame();
return Touch::create(frame, target, identifier, screenX, screenY, pageX, pageY);
}
-
-PassRefPtr<TouchList> Document::createTouchList(ExceptionCode&) const
-{
- return TouchList::create();
-}
#endif
DocumentLoader* Document::loader() const
diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h
index a4fc266..ce82b2e 100644
--- a/Source/WebCore/dom/Document.h
+++ b/Source/WebCore/dom/Document.h
@@ -1085,7 +1085,6 @@ public:
#if ENABLE(TOUCH_EVENTS)
PassRefPtr<Touch> createTouch(DOMWindow*, EventTarget*, int identifier, int pageX, int pageY, int screenX, int screenY, ExceptionCode&) const;
- PassRefPtr<TouchList> createTouchList(ExceptionCode&) const;
#endif
const DocumentTiming* timing() const { return &m_documentTiming; }
diff --git a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp
index e26fa9e..7bed5bb 100644
--- a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp
@@ -63,6 +63,7 @@ using namespace android;
namespace WebCore {
typedef std::pair<int, float> FallbackFontKey;
+
typedef HashMap<FallbackFontKey, FontPlatformData*> FallbackHash;
static void updateForFont(SkPaint* paint, const SimpleFontData* font) {
@@ -696,7 +697,17 @@ const FontPlatformData* TextRunWalker::setupComplexFont(
{
static FallbackHash fallbackPlatformData;
- FallbackFontKey key(script, platformData.size());
+ // generate scriptStyleIndex - we need unique hash IDs for each style
+ // of each script - normal, bold, italic, bolditalic. the first set of
+ // NUM_SCRIPTS are the normal style version, followed by bold, then
+ // italic, then bold italic. additional fake style bits can be added.
+ int scriptStyleIndex = script;
+ if (platformData.isFakeBold())
+ scriptStyleIndex += NUM_SCRIPTS;
+ if (platformData.isFakeItalic())
+ scriptStyleIndex += NUM_SCRIPTS << 1;
+
+ FallbackFontKey key(scriptStyleIndex, platformData.size());
FontPlatformData* newPlatformData = 0;
if (!fallbackPlatformData.contains(key)) {
diff --git a/Source/WebCore/platform/graphics/android/fonts/FontCacheAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/FontCacheAndroid.cpp
index 5696a46..4bb388c 100644
--- a/Source/WebCore/platform/graphics/android/fonts/FontCacheAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/fonts/FontCacheAndroid.cpp
@@ -175,7 +175,7 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD
}
result = new FontPlatformData(tf, fontDescription.computedSize(),
- (style & SkTypeface::kBold) && !tf->isBold(),
+ (style & SkTypeface::kBold),
(style & SkTypeface::kItalic) && !tf->isItalic(),
fontDescription.orientation(),
fontDescription.textOrientation());
diff --git a/Source/WebCore/platform/graphics/android/fonts/FontPlatformData.h b/Source/WebCore/platform/graphics/android/fonts/FontPlatformData.h
index 1e46971..02a0cea 100644
--- a/Source/WebCore/platform/graphics/android/fonts/FontPlatformData.h
+++ b/Source/WebCore/platform/graphics/android/fonts/FontPlatformData.h
@@ -92,6 +92,9 @@ public:
HB_FaceRec_* harfbuzzFace() const;
SkTypeface* typeface() const { return mTypeface; }
+ bool isFakeBold() const { return mFakeBold; }
+ bool isFakeItalic() const { return mFakeItalic; }
+
private:
class RefCountedHarfbuzzFace : public RefCounted<RefCountedHarfbuzzFace> {
public:
diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
index 82af3bf..9ee97ac 100644
--- a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
@@ -84,7 +84,13 @@ void BaseLayerAndroid::updatePositionsRecursive(const SkRect& visibleContentRect
updateLayerPositions(visibleContentRect);
TransformationMatrix ident;
- FloatRect clip(0, 0, getWidth(), getHeight());
+
+ // Start with an unnecessarily large clip, since the base layer can
+ // dynamically increase in size to cover the viewport, and we cache its draw
+ // clip. This way the base layer will never have it's visible area clipped
+ // by its m_clippingRect, only the viewport.
+ // Note: values larger than this suffer from floating point rounding issues
+ FloatRect clip(0, 0, 1e7, 1e7);
bool forcePositionCalculation = !m_positionsCalculated;
float scale = 1.0f;
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
index 293bbbc..d709a9c 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
@@ -122,6 +122,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
m_transform = layer.m_transform;
m_drawTransform = layer.m_drawTransform;
+ m_drawTransformUnfudged = layer.m_drawTransformUnfudged;
m_childrenTransform = layer.m_childrenTransform;
m_dirtyRegion = layer.m_dirtyRegion;
@@ -272,6 +273,9 @@ void LayerAndroid::addDirtyArea()
return;
}
+ // TODO: rewrite this to handle partial invalidate, and to handle base
+ // layer's large clip correctly
+
IntSize layerSize(getSize().width(), getSize().height());
FloatRect area =
@@ -283,6 +287,7 @@ void LayerAndroid::addDirtyArea()
area.intersect(clip);
IntRect dirtyArea(area.x(), area.y(), area.width(), area.height());
+
state()->addDirtyArea(dirtyArea);
}
@@ -407,6 +412,7 @@ void LayerAndroid::updateLocalTransformAndClip(const TransformationMatrix& paren
-originY,
-anchorPointZ());
+ m_drawTransformUnfudged = m_drawTransform;
if (m_drawTransform.isIdentityOrTranslation()
&& surface() && surface()->allowTransformFudging()) {
// adjust the translation coordinates of the draw transform matrix so
@@ -455,9 +461,8 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM
setDrawOpacity(opacity);
// constantly recalculate the draw transform of layers that may require it (and their children)
- forceCalculation |= isPositionFixed()
- || contentIsScrollable()
- || (m_animations.size() != 0);
+ forceCalculation |= hasDynamicTransform();
+
forceCalculation &= !(disableFixedElemUpdate && isPositionFixed());
if (forceCalculation)
updateLocalTransformAndClip(parentMatrix, clipping);
@@ -465,7 +470,7 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM
if (!countChildren() || !m_visible)
return;
- TransformationMatrix localMatrix = m_drawTransform;
+ TransformationMatrix localMatrix = m_drawTransformUnfudged;
// Flatten to 2D if the layer doesn't preserve 3D.
if (!preserves3D()) {
@@ -682,7 +687,7 @@ void LayerAndroid::assignSurfaces(LayerMergeState* mergeState)
mergeState->currentSurface->addLayer(this, m_drawTransform);
m_surface = mergeState->currentSurface;
- if (contentIsScrollable() || isPositionFixed()) {
+ if (hasDynamicTransform()) {
// disable layer merging within the children of these layer types
mergeState->nonMergeNestedLevel++;
}
@@ -704,7 +709,7 @@ void LayerAndroid::assignSurfaces(LayerMergeState* mergeState)
mergeState->depth--;
}
- if (contentIsScrollable() || isPositionFixed()) {
+ if (hasDynamicTransform()) {
// re-enable joining
mergeState->nonMergeNestedLevel--;
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
index c56d50a..f821d89 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
@@ -166,7 +166,7 @@ public:
void setPreserves3D(bool value) { m_preserves3D = value; }
void setAnchorPointZ(float z) { m_anchorPointZ = z; }
float anchorPointZ() { return m_anchorPointZ; }
- void setDrawTransform(const TransformationMatrix& transform) { m_drawTransform = transform; }
+ void setDrawTransform(const TransformationMatrix& transform) { m_drawTransform = m_drawTransformUnfudged = transform; }
virtual const TransformationMatrix* drawTransform() const { return &m_drawTransform; }
void setChildrenTransform(const TransformationMatrix& t) { m_childrenTransform = t; }
void setDrawClip(const FloatRect& rect) { m_clippingRect = rect; }
@@ -300,11 +300,15 @@ protected:
virtual void onDraw(SkCanvas*, SkScalar opacity, android::DrawExtra* extra, PaintStyle style);
virtual InvalidateFlags onSetHwAccelerated(bool hwAccelerated) { return InvalidateNone; }
TransformationMatrix m_drawTransform;
+ TransformationMatrix m_drawTransformUnfudged;
int m_uniqueId;
private:
void updateLocalTransformAndClip(const TransformationMatrix& parentMatrix,
const FloatRect& clip);
+ bool hasDynamicTransform() {
+ return contentIsScrollable() || isPositionFixed() || (m_animations.size() != 0);
+ }
#if DUMP_NAV_CACHE
friend class CachedLayer::Debug; // debugging access only
diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
index 9df1a7a..73466d3 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
@@ -90,13 +90,24 @@ bool Surface::tryUpdateSurface(Surface* oldSurface)
return true;
}
+ SkRegion invalRegion;
+ bool fullInval = false;
if (singleLayer() && oldSurface->singleLayer()) {
// both are single matching layers, simply apply inval
SkRegion* layerInval = getFirstLayer()->getInvalRegion();
- m_surfaceBacking->markAsDirty(*layerInval);
+ 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 {
- SkRegion invalRegion;
- bool fullInval = m_layers.size() != oldSurface->m_layers.size();
+ 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())
@@ -111,16 +122,15 @@ bool Surface::tryUpdateSurface(Surface* oldSurface)
FloatRect layerPos = m_layers[i]->fullContentAreaMapped();
m_layers[i]->getInvalRegion()->translate(layerPos.x(), layerPos.y());
invalRegion.op(*(m_layers[i]->getInvalRegion()), SkRegion::kUnion_Op);
- break;
}
}
}
+ }
- if (fullInval)
- invalRegion.setRect(-1e8, -1e8, 2e8, 2e8);
+ if (fullInval)
+ invalRegion.setRect(-1e8, -1e8, 2e8, 2e8);
- m_surfaceBacking->markAsDirty(invalRegion);
- }
+ m_surfaceBacking->markAsDirty(invalRegion);
return true;
}
@@ -230,17 +240,15 @@ bool Surface::drawGL(bool layerTilesDisabled)
if (singleLayer() && !getFirstLayer()->visible())
return false;
- bool isBaseLayer = isBase()
- || getFirstLayer()->subclassType() == LayerAndroid::FixedBackgroundImageLayer
- || getFirstLayer()->subclassType() == LayerAndroid::ForegroundBaseLayer;
-
- FloatRect drawClip = getFirstLayer()->drawClip();
- if (!singleLayer()) {
- for (unsigned int i = 1; i < m_layers.size(); i++)
- drawClip.unite(m_layers[i]->drawClip());
+ if (!isBase()) {
+ FloatRect drawClip = getFirstLayer()->drawClip();
+ if (!singleLayer()) {
+ for (unsigned int i = 1; i < m_layers.size(); i++)
+ drawClip.unite(m_layers[i]->drawClip());
+ }
+ FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip);
+ TilesManager::instance()->shader()->clip(clippingRect);
}
- FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip);
- TilesManager::instance()->shader()->clip(clippingRect);
bool askRedraw = false;
if (m_surfaceBacking && !tilesDisabled) {
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
index 3cfabe1..1c769bf 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
@@ -151,10 +151,8 @@ void SurfaceCollection::addFrameworkInvals()
bool SurfaceCollection::isReady()
{
// Override layer readiness check for single surface mode
- if (m_compositedRoot->state()->isSingleSurfaceRenderingMode()) {
- // TODO: single surface mode should be properly double buffered
- return true;
- }
+ if (m_compositedRoot->state()->isSingleSurfaceRenderingMode())
+ return m_surfaces[0]->isReady();
for (unsigned int i = 0; i < m_surfaces.size(); i++) {
if (!m_surfaces[i]->isReady()) {
@@ -165,12 +163,6 @@ bool SurfaceCollection::isReady()
return true;
}
-bool SurfaceCollection::isBaseSurfaceReady()
-{
- // m_surfaces[0] should be the base surface when in single surface mode.
- return m_surfaces[0]->isReady();
-}
-
bool SurfaceCollection::isMissingBackgroundContent()
{
// return true when the first surface is missing content (indicating the
@@ -222,9 +214,9 @@ void SurfaceCollection::mergeInvalsInto(SurfaceCollection* replacementSurface)
m_compositedRoot->mergeInvalsInto(replacementSurface->m_compositedRoot);
}
-void SurfaceCollection::evaluateAnimations(double currentTime)
+bool SurfaceCollection::evaluateAnimations(double currentTime)
{
- m_compositedRoot->evaluateAnimations(currentTime);
+ return m_compositedRoot->evaluateAnimations(currentTime);
}
bool SurfaceCollection::hasCompositedLayers()
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
index ff4195f..a903015 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
@@ -54,7 +54,6 @@ public:
void swapTiles();
void addFrameworkInvals();
bool isReady();
- bool isBaseSurfaceReady();
bool isMissingBackgroundContent();
void removePainterOperations();
void computeTexturesAmount(TexturesResult* result);
@@ -63,7 +62,7 @@ public:
void setIsPainting(SurfaceCollection* drawingSurfaceCollection);
void setIsDrawing();
void mergeInvalsInto(SurfaceCollection* replacementSurfaceCollection);
- void evaluateAnimations(double currentTime);
+ bool evaluateAnimations(double currentTime);
bool hasCompositedLayers();
bool hasCompositedAnimations();
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
index 724bf89..174720f 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
@@ -171,7 +171,8 @@ void SurfaceCollectionManager::updateScrollableLayer(int layerId, int x, int y)
}
-int SurfaceCollectionManager::singleSurfaceModeInvalidation(bool scrolling,
+int SurfaceCollectionManager::singleSurfaceModeInvalidation(bool hasRunningAnimation,
+ bool scrolling,
bool shouldDraw)
{
int returnFlags = 0;
@@ -179,21 +180,28 @@ int SurfaceCollectionManager::singleSurfaceModeInvalidation(bool scrolling,
// scrolling or have an incoming painting tree.
bool requireDirtyAll = (m_previouslyScrolling && !scrolling)
|| m_newPaintingCollection;
- if (requireDirtyAll)
- TilesManager::instance()->dirtyAllTiles();
// We also need to tell the framework to continue to invoke until
// the base layer is ready.
bool drawingBaseSurfaceReady = m_drawingCollection
- && m_drawingCollection->isBaseSurfaceReady();
+ && m_drawingCollection->isReady();
+
+ // When the base layer is ready, we can ask the framework to draw. And if
+ // animation is running, dirty all the tiles, otherwise the animation will
+ // be paused.
+ if (drawingBaseSurfaceReady) {
+ if (!shouldDraw)
+ returnFlags |= DrawGlInfo::kStatusDraw;
+ else
+ requireDirtyAll |= hasRunningAnimation;
+ }
+ if (requireDirtyAll)
+ TilesManager::instance()->dirtyAllTiles();
+
bool requireInvoke = requireDirtyAll || !drawingBaseSurfaceReady;
if (requireInvoke)
returnFlags |= DrawGlInfo::kStatusInvoke;
- // When the base layer is ready, we can ask the framework to draw.
- if (!shouldDraw && drawingBaseSurfaceReady)
- returnFlags |= DrawGlInfo::kStatusDraw;
-
m_newPaintingCollection = false;
m_previouslyScrolling = scrolling;
@@ -246,9 +254,6 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
if (m_paintingCollection)
returnFlags |= DrawGlInfo::kStatusInvoke;
- if (singleSurfaceMode)
- returnFlags |= singleSurfaceModeInvalidation(scrolling, shouldDraw);
-
if (!shouldDraw) {
if (didCollectionSwap
|| (!m_paintingCollection
@@ -270,6 +275,7 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
// Don't have a drawing collection, draw white background
Color background = Color::white;
bool drawBackground = true;
+ bool hasRunningAnimation = false;
if (m_drawingCollection) {
bool drawingReady = didCollectionSwap || m_drawingCollection->isReady();
@@ -288,7 +294,7 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
returnFlags |= DrawGlInfo::kStatusInvoke;
}
- m_drawingCollection->evaluateAnimations(currentTime);
+ hasRunningAnimation = m_drawingCollection->evaluateAnimations(currentTime);
ALOGV("drawing collection %p", m_drawingCollection);
background = m_drawingCollection->getBackgroundColor();
@@ -298,6 +304,9 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
background = m_paintingCollection->getBackgroundColor();
}
+ if (singleSurfaceMode)
+ returnFlags |= singleSurfaceModeInvalidation(hasRunningAnimation,
+ scrolling, shouldDraw);
// Start doing the actual GL drawing.
if (drawBackground) {
ALOGV("background is %x", background.rgb());
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h
index 6aed060..53b5bb6 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h
@@ -59,7 +59,7 @@ private:
void swap();
void clearCollections();
void updatePaintingCollection(SurfaceCollection* newCollection);
- int singleSurfaceModeInvalidation(bool scrolling, bool shouldDraw);
+ int singleSurfaceModeInvalidation(bool hasRunningAnimation, bool scrolling, bool shouldDraw);
SurfaceCollection* m_drawingCollection;
SurfaceCollection* m_paintingCollection;
SurfaceCollection* m_queuedCollection;
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp
index 161c0b2..c0766e4 100644
--- a/Source/WebKit/android/jni/WebViewCore.cpp
+++ b/Source/WebKit/android/jni/WebViewCore.cpp
@@ -401,7 +401,7 @@ struct WebViewCore::TextFieldInitDataGlue {
jfieldID m_maxLength;
jfieldID m_contentBounds;
jfieldID m_nodeLayerId;
- jfieldID m_contentRect;
+ jfieldID m_clientRect;
};
/*
@@ -526,7 +526,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_textFieldInitDataGlue->m_maxLength = env->GetFieldID(tfidClazz, "mMaxLength", "I");
m_textFieldInitDataGlue->m_contentBounds = env->GetFieldID(tfidClazz, "mContentBounds", "Landroid/graphics/Rect;");
m_textFieldInitDataGlue->m_nodeLayerId = env->GetFieldID(tfidClazz, "mNodeLayerId", "I");
- m_textFieldInitDataGlue->m_contentRect = env->GetFieldID(tfidClazz, "mContentRect", "Landroid/graphics/Rect;");
+ m_textFieldInitDataGlue->m_clientRect = env->GetFieldID(tfidClazz, "mClientRect", "Landroid/graphics/Rect;");
m_textFieldInitDataGlue->m_constructor = GetJMethod(env, tfidClazz, "<init>", "()V");
env->DeleteLocalRef(tfidClazz);
@@ -1507,6 +1507,7 @@ bool WebViewCore::selectWordAroundPosition(Frame* frame, VisiblePosition pos)
VisibleSelection selection(pos);
selection.expandUsingGranularity(WordGranularity);
SelectionController* selectionController = frame->selection();
+ selection = VisibleSelection(selection.start(), selection.end());
bool wordSelected = false;
if (selectionController->shouldChangeSelection(selection)) {
@@ -1566,7 +1567,8 @@ void WebViewCore::layerToAbsoluteOffset(const LayerAndroid* layer, IntPoint& off
void WebViewCore::setSelectionCaretInfo(SelectText* selectTextContainer,
const WebCore::Position& pos, const IntPoint& frameOffset,
- SelectText::HandleId handleId, int caretRectOffset, EAffinity affinity)
+ SelectText::HandleId handleId, SelectText::HandleType handleType,
+ int caretRectOffset, EAffinity affinity)
{
Node* node = pos.anchorNode();
LayerAndroid* layer = 0;
@@ -1584,6 +1586,7 @@ void WebViewCore::setSelectionCaretInfo(SelectText* selectTextContainer,
caretRect.setX(absoluteOffset.x() - offset.x() + caretRectOffset);
caretRect.setY(absoluteOffset.y() - offset.y());
selectTextContainer->setCaretRect(handleId, caretRect);
+ selectTextContainer->setHandleType(handleId, handleType);
selectTextContainer->setTextRect(handleId,
positionToTextRect(pos, affinity, offset));
}
@@ -1604,11 +1607,11 @@ bool WebViewCore::isLtr(const Position& position)
SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
{
bool isCaret = selection.isCaret();
+ Position base = selection.base();
+ Position extent = selection.extent();
if (selection.isNone() || (!selection.isContentEditable() && isCaret)
- || !selection.start().anchorNode()
- || !selection.start().anchorNode()->renderer()
- || !selection.end().anchorNode()
- || !selection.end().anchorNode()->renderer())
+ || !base.anchorNode() || !base.anchorNode()->renderer()
+ || !extent.anchorNode() || !extent.anchorNode()->renderer())
return 0;
RefPtr<Range> range = selection.firstRange();
@@ -1624,20 +1627,27 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection)
IntPoint frameOffset = convertGlobalContentToFrameContent(IntPoint());
SelectText* selectTextContainer = new SelectText();
if (isCaret) {
- setSelectionCaretInfo(selectTextContainer, selection.start(), frameOffset,
- SelectText::LeftHandle, 0, selection.affinity());
- setSelectionCaretInfo(selectTextContainer, selection.start(), frameOffset,
- SelectText::RightHandle, 0, selection.affinity());
+ setSelectionCaretInfo(selectTextContainer, base, frameOffset,
+ SelectText::BaseHandle, SelectText::CenterHandle, 0,
+ selection.affinity());
+ setSelectionCaretInfo(selectTextContainer, base, frameOffset,
+ SelectText::ExtentHandle, SelectText::CenterHandle, 0,
+ selection.affinity());
} else {
- bool ltr = isLtr(selection.start());
- Position left = ltr ? selection.start() : selection.end();
- Position right = ltr ? selection.end() : selection.start();
- int leftOffset = isLtr(left) ? 0 : -1;
- int rightOffset = isLtr(right) ? 0 : -1;
- setSelectionCaretInfo(selectTextContainer, left, frameOffset,
- SelectText::LeftHandle, leftOffset, selection.affinity());
- setSelectionCaretInfo(selectTextContainer, right, frameOffset,
- SelectText::RightHandle, rightOffset, selection.affinity());
+ bool isBaseLtr = isLtr(base);
+ bool isBaseStart = selection.base() == selection.start();
+ int baseOffset = isBaseLtr ? 0 : -1;
+ SelectText::HandleType baseHandleType = (isBaseLtr == isBaseStart)
+ ? SelectText::LeftHandle : SelectText::RightHandle;
+ EAffinity affinity = selection.affinity();
+ setSelectionCaretInfo(selectTextContainer, base, frameOffset,
+ SelectText::BaseHandle, baseHandleType, baseOffset, affinity);
+ bool isExtentLtr = isLtr(extent);
+ int extentOffset = isExtentLtr ? 0 : -1;
+ SelectText::HandleType extentHandleType = (isExtentLtr == isBaseStart)
+ ? SelectText::RightHandle : SelectText::LeftHandle;
+ setSelectionCaretInfo(selectTextContainer, extent, frameOffset,
+ SelectText::ExtentHandle, extentHandleType, extentOffset, affinity);
Node* stopNode = range->pastLastNode();
for (Node* node = range->firstNode(); node != stopNode; node = node->traverseNextNode()) {
@@ -1726,47 +1736,65 @@ Position WebViewCore::trimSelectionPosition(const Position &start, const Positio
return pos;
}
-void WebViewCore::selectText(int startX, int startY, int endX, int endY)
+void WebViewCore::selectText(SelectText::HandleId handleId, int x, int y)
{
SelectionController* sc = focusedFrame()->selection();
- IntPoint startPoint = convertGlobalContentToFrameContent(IntPoint(startX, startY));
- VisiblePosition startPosition(visiblePositionForContentPoint(startPoint));
- IntPoint endPoint = convertGlobalContentToFrameContent(IntPoint(endX, endY));
- VisiblePosition endPosition(visiblePositionForContentPoint(endPoint));
+ VisibleSelection selection = sc->selection();
+ Position base = selection.base();
+ Position extent = selection.extent();
+ IntPoint dragPoint = convertGlobalContentToFrameContent(IntPoint(x, y));
+ VisiblePosition dragPosition(visiblePositionForContentPoint(dragPoint));
- if (startPosition.isNull() || endPosition.isNull())
+ if (base.isNull() || extent.isNull() || dragPosition.isNull())
return;
-
- // Ensure startPosition is before endPosition
- if (comparePositions(startPosition, endPosition) > 0)
- swap(startPosition, endPosition);
-
- if (sc->isContentEditable()) {
- startPosition = sc->selection().visibleStart().honorEditableBoundaryAtOrAfter(startPosition);
- endPosition = sc->selection().visibleEnd().honorEditableBoundaryAtOrBefore(endPosition);
- if (startPosition.isNull() || endPosition.isNull()) {
+ bool draggingBase = (handleId == SelectText::BaseHandle);
+ if (draggingBase)
+ base = dragPosition.deepEquivalent();
+ else
+ extent = dragPosition.deepEquivalent();
+
+ bool baseIsStart = (comparePositions(base, extent) <= 0);
+ Position& start = baseIsStart ? base : extent;
+ Position& end = baseIsStart ? extent : base;
+ VisiblePosition startPosition(start, selection.affinity());
+ VisiblePosition endPosition(end, selection.affinity());
+ bool draggingStart = (baseIsStart == draggingBase);
+
+ if (draggingStart) {
+ startPosition = endPosition.honorEditableBoundaryAtOrAfter(startPosition);
+ if (startPosition.isNull())
return;
+ if (selection.isCaret())
+ start = end = startPosition.deepEquivalent();
+ else {
+ if ((startPosition != endPosition) && isEndOfBlock(startPosition)) {
+ // Ensure startPosition is not at end of block
+ VisiblePosition nextStartPosition(startPosition.next());
+ if (nextStartPosition.isNotNull())
+ startPosition = nextStartPosition;
+ }
+ start = startPosition.deepEquivalent();
+ start = trimSelectionPosition(start, end);
+ }
+ } else {
+ endPosition = startPosition.honorEditableBoundaryAtOrAfter(endPosition);
+ if (endPosition.isNull())
+ return;
+ if (selection.isCaret())
+ start = end = endPosition.deepEquivalent();
+ else {
+ if ((startPosition != endPosition) && isStartOfBlock(endPosition)) {
+ // Ensure endPosition is not at start of block
+ VisiblePosition prevEndPosition(endPosition.previous());
+ if (!prevEndPosition.isNull())
+ endPosition = prevEndPosition;
+ }
+ end = endPosition.deepEquivalent();
+ end = trimSelectionPosition(end, start);
}
}
- // Ensure startPosition is not at end of block
- if (startPosition != endPosition && isEndOfBlock(startPosition)) {
- VisiblePosition nextStartPosition(startPosition.next());
- if (!nextStartPosition.isNull())
- startPosition = nextStartPosition;
- }
- // Ensure endPosition is not at start of block
- if (startPosition != endPosition && isStartOfBlock(endPosition)) {
- VisiblePosition prevEndPosition(endPosition.previous());
- if (!prevEndPosition.isNull())
- endPosition = prevEndPosition;
- }
-
- Position start = startPosition.deepEquivalent();
- Position end = endPosition.deepEquivalent();
- start = trimSelectionPosition(start, end);
- end = trimSelectionPosition(end, start);
- VisibleSelection selection(start, end);
+ selection = VisibleSelection(base, extent);
// Only allow changes between caret positions or to text selection.
bool selectChangeAllowed = (!selection.isCaret() || sc->isCaret());
if (selectChangeAllowed && sc->shouldChangeSelection(selection))
@@ -2950,27 +2978,25 @@ void WebViewCore::passToJs(int generation, const WTF::String& current,
updateTextSelection();
}
-WebCore::IntRect WebViewCore::scrollFocusedTextInput(float xPercent, int y)
+void WebViewCore::scrollFocusedTextInput(float xPercent, int y)
{
WebCore::Node* focus = currentFocus();
if (!focus) {
clearTextEntry();
- return WebCore::IntRect();
+ return;
}
WebCore::RenderTextControl* renderText = toRenderTextControl(focus);
if (!renderText) {
clearTextEntry();
- return WebCore::IntRect();
+ return;
}
- int x = (int) (xPercent * (renderText->scrollWidth() -
+ int x = (int)round(xPercent * (renderText->scrollWidth() -
renderText->clientWidth()));
renderText->setScrollLeft(x);
renderText->setScrollTop(y);
focus->document()->frame()->selection()->recomputeCaretRect();
- LayerAndroid* layer = 0;
- platformLayerIdFromNode(focus, &layer);
- return absoluteContentRect(focus, layer);
+ updateTextSelection();
}
void WebViewCore::setFocusControllerActive(bool active)
@@ -3364,10 +3390,10 @@ bool WebViewCore::isAutoCompleteEnabled(Node* node)
return isEnabled;
}
-WebCore::IntRect WebViewCore::absoluteContentRect(WebCore::Node* node,
+WebCore::IntRect WebViewCore::absoluteClientRect(WebCore::Node* node,
LayerAndroid* layer)
{
- IntRect contentRect;
+ IntRect clientRect;
if (node) {
RenderObject* render = node->renderer();
if (render && render->isBox() && !render->isBody()) {
@@ -3376,11 +3402,12 @@ WebCore::IntRect WebViewCore::absoluteContentRect(WebCore::Node* node,
WebViewCore::layerToAbsoluteOffset(layer, offset);
RenderBox* renderBox = toRenderBox(render);
- contentRect = renderBox->absoluteContentBox();
- contentRect.move(-offset.x(), -offset.y());
+ clientRect = renderBox->clientBoxRect();
+ FloatPoint absPos = renderBox->localToAbsolute(FloatPoint());
+ clientRect.move(absPos.x() - offset.x(), absPos.y() - offset.y());
}
}
- return contentRect;
+ return clientRect;
}
jobject WebViewCore::createTextFieldInitData(Node* node)
@@ -3413,11 +3440,11 @@ jobject WebViewCore::createTextFieldInitData(Node* node)
env->SetObjectField(initData, classDef->m_name, fieldName.get());
ScopedLocalRef<jstring> label(env,
wtfStringToJstring(env, requestLabel(document->frame(), node), false));
- env->SetObjectField(initData, classDef->m_name, label.get());
+ env->SetObjectField(initData, classDef->m_label, label.get());
env->SetIntField(initData, classDef->m_maxLength, getMaxLength(node));
LayerAndroid* layer = 0;
int layerId = platformLayerIdFromNode(node, &layer);
- IntRect bounds = absoluteContentRect(node, layer);
+ IntRect bounds = absoluteClientRect(node, layer);
ScopedLocalRef<jobject> jbounds(env, intRectToRect(env, bounds));
env->SetObjectField(initData, classDef->m_contentBounds, jbounds.get());
env->SetIntField(initData, classDef->m_nodeLayerId, layerId);
@@ -3429,7 +3456,7 @@ jobject WebViewCore::createTextFieldInitData(Node* node)
contentRect.move(-rtc->scrollLeft(), -rtc->scrollTop());
}
ScopedLocalRef<jobject> jcontentRect(env, intRectToRect(env, contentRect));
- env->SetObjectField(initData, classDef->m_contentRect, jcontentRect.get());
+ env->SetObjectField(initData, classDef->m_clientRect, jcontentRect.get());
return initData;
}
@@ -3888,11 +3915,18 @@ void WebViewCore::setBackgroundColor(SkColor c)
// need (int) cast to find the right constructor
WebCore::Color bcolor((int)SkColorGetR(c), (int)SkColorGetG(c),
(int)SkColorGetB(c), (int)SkColorGetA(c));
+
+ if (view->baseBackgroundColor() == bcolor)
+ return;
+
view->setBaseBackgroundColor(bcolor);
// Background color of 0 indicates we want a transparent background
if (c == 0)
view->setTransparent(true);
+
+ //invalidate so the new color is shown
+ contentInvalidateAll();
}
jclass WebViewCore::getPluginClass(const WTF::String& libName, const char* className)
@@ -4498,12 +4532,10 @@ static void PassToJs(JNIEnv* env, jobject obj, jint nativeClass,
}
static void ScrollFocusedTextInput(JNIEnv* env, jobject obj, jint nativeClass,
- jfloat xPercent, jint y, jobject contentBounds)
+ jfloat xPercent, jint y)
{
WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
- IntRect bounds = viewImpl->scrollFocusedTextInput(xPercent, y);
- if (contentBounds)
- GraphicsJNI::irect_to_jrect(bounds, env, contentBounds);
+ viewImpl->scrollFocusedTextInput(xPercent, y);
}
static void SetFocusControllerActive(JNIEnv* env, jobject obj, jint nativeClass,
@@ -4928,10 +4960,10 @@ static jobject GetText(JNIEnv* env, jobject obj, jint nativeClass,
}
static void SelectText(JNIEnv* env, jobject obj, jint nativeClass,
- jint startX, jint startY, jint endX, jint endY)
+ jint handleId, jint x, jint y)
{
WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
- viewImpl->selectText(startX, startY, endX, endY);
+ viewImpl->selectText(static_cast<SelectText::HandleId>(handleId), x, y);
}
static void ClearSelection(JNIEnv* env, jobject obj, jint nativeClass)
@@ -5003,7 +5035,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) MoveMouse },
{ "passToJs", "(IILjava/lang/String;IIZZZZ)V",
(void*) PassToJs },
- { "nativeScrollFocusedTextInput", "(IFILandroid/graphics/Rect;)V",
+ { "nativeScrollFocusedTextInput", "(IFI)V",
(void*) ScrollFocusedTextInput },
{ "nativeSetFocusControllerActive", "(IZ)V",
(void*) SetFocusControllerActive },
@@ -5068,7 +5100,7 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) InsertText },
{ "nativeGetText", "(IIIII)Ljava/lang/String;",
(void*) GetText },
- { "nativeSelectText", "(IIIII)V",
+ { "nativeSelectText", "(IIII)V",
(void*) SelectText },
{ "nativeClearTextSelection", "(I)V",
(void*) ClearSelection },
diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h
index 7cc3fd6..cf1295c 100644
--- a/Source/WebKit/android/jni/WebViewCore.h
+++ b/Source/WebKit/android/jni/WebViewCore.h
@@ -397,7 +397,7 @@ namespace android {
/**
* Scroll the focused textfield to (x, y) in document space
*/
- WebCore::IntRect scrollFocusedTextInput(float x, int y);
+ void scrollFocusedTextInput(float x, int y);
/**
* Set the FocusController's active and focused states, so that
* the caret will draw (true) or not.
@@ -580,7 +580,7 @@ namespace android {
int startX, int startY, int endX, int endY);
static int platformLayerIdFromNode(WebCore::Node* node,
WebCore::LayerAndroid** outLayer = 0);
- void selectText(int startX, int startY, int endX, int endY);
+ void selectText(SelectText::HandleId handleId, int x, int y);
bool selectWordAt(int x, int y);
// Converts from the global content coordinates that WebView sends
@@ -728,12 +728,12 @@ namespace android {
void setSelectionCaretInfo(SelectText* selectTextContainer,
const WebCore::Position& position,
const WebCore::IntPoint& frameOffset,
- SelectText::HandleId handleId, int offset,
- EAffinity affinity);
+ SelectText::HandleId handleId, SelectText::HandleType handleType,
+ int offset, EAffinity affinity);
static int getMaxLength(WebCore::Node* node);
static WTF::String getFieldName(WebCore::Node* node);
static bool isAutoCompleteEnabled(WebCore::Node* node);
- WebCore::IntRect absoluteContentRect(WebCore::Node* node,
+ WebCore::IntRect absoluteClientRect(WebCore::Node* node,
WebCore::LayerAndroid* layer);
static WebCore::IntRect positionToTextRect(const WebCore::Position& position,
WebCore::EAffinity affinity, const WebCore::IntPoint& offset);
diff --git a/Source/WebKit/android/nav/SelectText.h b/Source/WebKit/android/nav/SelectText.h
index aaaf3bb..8f7592d 100644
--- a/Source/WebKit/android/nav/SelectText.h
+++ b/Source/WebKit/android/nav/SelectText.h
@@ -35,8 +35,13 @@ namespace android {
class SelectText : public RegionLayerDrawExtra {
public:
enum HandleId {
+ BaseHandle = 0,
+ ExtentHandle = 1,
+ };
+ enum HandleType {
LeftHandle = 0,
- RightHandle = 1,
+ CenterHandle = 1,
+ RightHandle = 2,
};
IntRect& caretRect(HandleId id) { return m_caretRects[id]; }
@@ -48,11 +53,14 @@ public:
void setText(const String& text) { m_text = text.threadsafeCopy(); }
String& getText() { return m_text; }
+ HandleType getHandleType(HandleId id) { return m_handleType[id]; }
+ void setHandleType(HandleId id, HandleType type) { m_handleType[id] = type; }
private:
IntRect m_caretRects[2];
IntRect m_textRects[2];
int m_caretLayerId[2];
+ HandleType m_handleType[2];
String m_text;
};
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index a277fc3..fae566c 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -731,6 +731,15 @@ void findMaxVisibleRect(int movingLayerId, SkIRect& visibleContentRect)
}
}
+bool isHandleLeft(SelectText::HandleId handleId)
+{
+ SelectText* selectText = static_cast<SelectText*>(getDrawExtra(DrawExtrasSelection));
+ if (!selectText)
+ return (handleId == SelectText::BaseHandle);
+
+ return (selectText->getHandleType(handleId) == SelectText::LeftHandle);
+}
+
private: // local state for WebView
bool m_isDrawingPaused;
// private to getFrameCache(); other functions operate in a different thread
@@ -1287,6 +1296,13 @@ static void nativeFindMaxVisibleRect(JNIEnv *env, jobject obj, jint nativeView,
GraphicsJNI::irect_to_jrect(nativeRect, env, visibleContentRect);
}
+static bool nativeIsHandleLeft(JNIEnv *env, jobject obj, jint nativeView,
+ jint handleId)
+{
+ WebView* webview = reinterpret_cast<WebView*>(nativeView);
+ return webview->isHandleLeft(static_cast<SelectText::HandleId>(handleId));
+}
+
/*
* JNI registration
*/
@@ -1365,6 +1381,8 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeSetHwAccelerated },
{ "nativeFindMaxVisibleRect", "(IILandroid/graphics/Rect;)V",
(void*) nativeFindMaxVisibleRect },
+ { "nativeIsHandleLeft", "(II)Z",
+ (void*) nativeIsHandleLeft },
};
int registerWebView(JNIEnv* env)