diff options
Diffstat (limited to 'Source')
10 files changed, 157 insertions, 33 deletions
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp index 06bb767..68f452a 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp @@ -199,6 +199,22 @@ bool GraphicsLayerAndroid::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* return ret; } +void GraphicsLayerAndroid::setReplicatedLayer(GraphicsLayer* layer) +{ + GraphicsLayer::setReplicatedLayer(layer); + if (m_replicatedLayer) { + GraphicsLayerAndroid* graphicsLayer = static_cast<GraphicsLayerAndroid*>(m_replicatedLayer); + if (graphicsLayer->m_contentLayer) + graphicsLayer->m_contentLayer->setReplicatedLayer(m_contentLayer); + if (maskLayer()) { + GraphicsLayerAndroid* maskLayer = static_cast<GraphicsLayerAndroid*>(GraphicsLayer::maskLayer()); + m_contentLayer->setMaskLayer(maskLayer->m_contentLayer); + } + m_contentLayer->setReplicatedLayerPosition(replicatedLayerPosition()); + askForSync(); + } +} + void GraphicsLayerAndroid::removeFromParent() { ALOGV("(%x) removeFromParent()", this); @@ -745,6 +761,16 @@ bool GraphicsLayerAndroid::repaint() m_foregroundClipLayer->setPosition(layerBounds.x(), layerBounds.y()); m_foregroundClipLayer->setSize(layerBounds.width(), layerBounds.height()); } else { + + // If we are replicated, paint the mask + if (isReplicated()) { + GraphicsLayerAndroid* replicatedLayer = static_cast<GraphicsLayerAndroid*>(replicaLayer()); + if (replicatedLayer->maskLayer()) { + GraphicsLayerAndroid* mask = static_cast<GraphicsLayerAndroid*>(replicatedLayer->maskLayer()); + mask->paintContext(mask->m_contentLayer, layerBounds, false); + } + } + // If there is no contents clip, we can draw everything into one // picture. bool painting = paintContext(m_contentLayer, layerBounds); @@ -806,7 +832,8 @@ SkPicture* GraphicsLayerAndroid::paintPicture(const IntRect& rect) } bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer, - const IntRect& rect) + const IntRect& rect, + bool checkOptimisations) { if (!layer) return false; @@ -817,7 +844,10 @@ bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer, picture->endRecording(); PictureLayerContent* layerContent = new PictureLayerContent(picture); - layerContent->checkForOptimisations(); + if (checkOptimisations) + layerContent->checkForOptimisations(); + else + layerContent->setCheckForOptimisations(false); layer->setContent(layerContent); SkSafeUnref(layerContent); SkSafeUnref(picture); @@ -1079,10 +1109,15 @@ void GraphicsLayerAndroid::askForSync() void GraphicsLayerAndroid::syncChildren() { - if (m_needsSyncChildren && !m_contentLayer->isFixedBackground()) { + if (m_needsSyncChildren || isReplicated()) { m_contentLayer->removeChildren(); LayerAndroid* layer = m_contentLayer; + if (isReplicated()) { + GraphicsLayerAndroid* replicatedLayer = static_cast<GraphicsLayerAndroid*>(replicaLayer()); + m_contentLayer->addChild(replicatedLayer->m_contentLayer); + } + if (m_contentLayer->isFixedBackground()) { m_contentLayer->addChild(m_foregroundClipLayer); m_contentLayer->addChild(m_foregroundLayer); diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h index 278bd7e..0fc0790 100644 --- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h @@ -57,6 +57,7 @@ public: virtual void addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling); virtual void addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling); virtual bool replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild); + virtual void setReplicatedLayer(GraphicsLayer* layer); virtual void removeFromParent(); @@ -147,7 +148,9 @@ private: void needsNotifyClient(); SkPicture* paintPicture(const IntRect& rect); - bool paintContext(LayerAndroid* layer, const IntRect& rect); + bool paintContext(LayerAndroid* layer, + const IntRect& rect, + bool checkOptimisations = true); bool m_needsSyncChildren; bool m_needsSyncMask; diff --git a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp index 6c76965..0bd443b 100644 --- a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp @@ -461,9 +461,12 @@ private: Devanagari, Hebrew, HebrewBold, + Kannada, + Malayalam, Naskh, Tamil, TamilBold, + Telugu, Thai, NUM_SCRIPTS }; @@ -521,9 +524,12 @@ const char* TextRunWalker::paths[] = { "/system/fonts/DroidSansDevanagari-Regular.ttf", "/system/fonts/DroidSansHebrew-Regular.ttf", "/system/fonts/DroidSansHebrew-Bold.ttf", + "/system/fonts/Lohit-Kannada.ttf", + "/system/fonts/AnjaliNewLipi-light.ttf", "/system/fonts/DroidNaskh-Regular.ttf", "/system/fonts/DroidSansTamil-Regular.ttf", "/system/fonts/DroidSansTamil-Bold.ttf", + "/system/fonts/Lohit-Telugu.ttf", "/system/fonts/DroidSansThai.ttf" }; @@ -730,6 +736,12 @@ void TextRunWalker::setupFontForScriptRun() break; } break; + case HB_Script_Kannada: + complexPlatformData = setupComplexFont(Kannada, platformData); + break; + case HB_Script_Malayalam: + complexPlatformData = setupComplexFont(Malayalam, platformData); + break; case HB_Script_Arabic: complexPlatformData = setupComplexFont(Naskh, platformData); break; @@ -746,6 +758,9 @@ void TextRunWalker::setupFontForScriptRun() break; } break; + case HB_Script_Telugu: + complexPlatformData = setupComplexFont(Telugu, platformData); + break; case HB_Script_Thai: complexPlatformData = setupComplexFont(Thai, platformData); break; diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp index 2deeede..73ae26f 100644 --- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp @@ -22,9 +22,11 @@ #include "PictureLayerContent.h" #include "PrerenderedInval.h" #include "SkBitmapRef.h" +#include "SkDevice.h" #include "SkDrawFilter.h" #include "SkPaint.h" #include "SkPicture.h" +#include "SkTypeface.h" #include "Surface.h" #include "TilesManager.h" @@ -72,7 +74,10 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(), m_owningLayer(owner), m_type(LayerAndroid::WebCoreLayer), m_intrinsicallyComposited(true), - m_surface(0) + m_surface(0), + m_replicatedLayer(0), + m_originalLayer(0), + m_maskLayer(0) { m_backgroundColor = 0; @@ -93,7 +98,10 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_owningLayer(layer.m_owningLayer), m_type(LayerAndroid::UILayer), m_intrinsicallyComposited(layer.m_intrinsicallyComposited), - m_surface(0) + m_surface(0), + m_replicatedLayer(0), + m_originalLayer(0), + m_maskLayer(0) { m_imageCRC = layer.m_imageCRC; if (m_imageCRC) @@ -123,6 +131,8 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_scale = layer.m_scale; m_lastComputeTextureSize = 0; + m_replicatedLayerPosition = layer.m_replicatedLayerPosition; + // If we have absolute elements, we may need to reorder them if they // are followed by another layer that is not also absolutely positioned. // (as absolutely positioned elements are out of the normal flow) @@ -165,6 +175,15 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer), m_animations.add(it->first, it->second); } + if (layer.m_replicatedLayer) { + // The replicated layer is always the first child + m_replicatedLayer = getChild(0); + m_replicatedLayer->setOriginalLayer(this); + } + + if (layer.m_maskLayer) + m_maskLayer = layer.m_maskLayer->copy(); + #ifdef DEBUG_COUNT ClassTracker::instance()->increment("LayerAndroid - recopy (UI)"); ClassTracker::instance()->add(this); @@ -178,6 +197,7 @@ LayerAndroid::~LayerAndroid() if (m_fixedPosition) delete m_fixedPosition; + SkSafeUnref(m_maskLayer); SkSafeUnref(m_content); // Don't unref m_surface, owned by BaseLayerAndroid m_animations.clear(); @@ -299,6 +319,7 @@ void LayerAndroid::removeAnimationsForKeyframes(const String& name) // FIXME: use a real mask? void LayerAndroid::setMaskLayer(LayerAndroid* layer) { + m_maskLayer = layer; if (layer) m_haveClip = true; } @@ -418,7 +439,8 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM { IntSize layerSize(getSize().width(), getSize().height()); FloatPoint anchorPoint(getAnchorPoint().fX, getAnchorPoint().fY); - FloatPoint position(getPosition().fX - m_offset.x(), getPosition().fY - m_offset.y()); + FloatPoint position(getPosition().fX + m_replicatedLayerPosition.x() - m_offset.x(), + getPosition().fY + m_replicatedLayerPosition.y() - m_offset.y()); float originX = anchorPoint.x() * layerSize.width(); float originY = anchorPoint.y() * layerSize.height(); TransformationMatrix localMatrix; @@ -552,7 +574,8 @@ bool LayerAndroid::canUpdateWithBlit() bool LayerAndroid::needsTexture() { - return m_content && !m_content->isEmpty(); + return (m_content && !m_content->isEmpty()) + || (m_originalLayer && m_originalLayer->needsTexture()); } IntRect LayerAndroid::clippedRect() const @@ -604,10 +627,10 @@ void LayerAndroid::showLayer(int indent) IntRect visible = visibleContentArea(); IntRect clip(m_clippingRect.x(), m_clippingRect.y(), m_clippingRect.width(), m_clippingRect.height()); - ALOGD("%s %s %s (%d) [%d:0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) " - "clip (%d, %d, %d, %d) %s %s m_content(%x), pic w: %d h: %d", + ALOGD("%s %s %s (%d) [%d:%x - 0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) " + "clip (%d, %d, %d, %d) %s %s m_content(%x), pic w: %d h: %d originalLayer: %x %d", spaces, m_haveClip ? "CLIP LAYER" : "", subclassName().ascii().data(), - subclassType(), uniqueId(), m_owningLayer, + subclassType(), uniqueId(), this, m_owningLayer, needsTexture() ? "needs a texture" : "no texture", m_imageCRC ? "has an image" : "no image", tr.x(), tr.y(), tr.width(), tr.height(), @@ -617,7 +640,8 @@ void LayerAndroid::showLayer(int indent) isPositionFixed() ? "FIXED" : "", m_content, m_content ? m_content->width() : -1, - m_content ? m_content->height() : -1); + m_content ? m_content->height() : -1, + m_originalLayer, m_originalLayer ? m_originalLayer->uniqueId() : -1); int count = this->countChildren(); for (int i = 0; i < count; i++) @@ -879,7 +903,22 @@ bool LayerAndroid::drawChildrenCanvas(SkCanvas* canvas, PaintStyle style) void LayerAndroid::contentDraw(SkCanvas* canvas, PaintStyle style) { - if (m_content) + if (m_maskLayer && m_maskLayer->m_content) { + // TODO: we should use a shader instead of doing + // the masking in software + + if (m_originalLayer) + m_originalLayer->m_content->draw(canvas); + else if (m_content) + m_content->draw(canvas); + + SkPaint maskPaint; + maskPaint.setXfermodeMode(SkXfermode::kDstIn_Mode); + int count = canvas->saveLayer(0, &maskPaint, SkCanvas::kHasAlphaLayer_SaveFlag); + m_maskLayer->m_content->draw(canvas); + canvas->restoreToCount(count); + + } else if (m_content) m_content->draw(canvas); if (TilesManager::instance()->getShowVisualIndicator()) { @@ -901,6 +940,16 @@ void LayerAndroid::contentDraw(SkCanvas* canvas, PaintStyle style) canvas->drawLine(0, h-1, w-1, h-1, paint); canvas->drawLine(w-1, h-1, w-1, 0, paint); canvas->drawLine(w-1, 0, 0, 0, paint); + + static SkTypeface* s_typeface = 0; + if (!s_typeface) + s_typeface = SkTypeface::CreateFromName("", SkTypeface::kBold); + paint.setARGB(255, 0, 0, 255); + paint.setTextSize(17); + char str[256]; + snprintf(str, 256, "%d", uniqueId()); + paint.setTypeface(s_typeface); + canvas->drawText(str, strlen(str), 2, h - 2, paint); } if (m_fixedPosition) diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h index 3bab5ab..687f146 100644 --- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h @@ -289,6 +289,16 @@ public: int setHwAccelerated(bool hwAccelerated); + void setReplicatedLayer(LayerAndroid* layer) { m_replicatedLayer = layer; } + void setReplicatedLayerPosition(const FloatPoint& p) { m_replicatedLayerPosition = p; } + void setOriginalLayer(LayerAndroid* layer) { m_originalLayer = layer; } + bool hasReplicatedLayer() { return m_replicatedLayer; } + const TransformationMatrix* replicatedLayerDrawTransform() { + if (m_replicatedLayer) + return m_replicatedLayer->drawTransform(); + return 0; + } + protected: virtual void onDraw(SkCanvas*, SkScalar opacity, android::DrawExtra* extra, PaintStyle style); virtual InvalidateFlags onSetHwAccelerated(bool hwAccelerated) { return InvalidateNone; } @@ -381,6 +391,13 @@ private: Surface* m_surface; + // link to a replicated layer (used e.g. for reflections) + LayerAndroid* m_replicatedLayer; + FloatPoint m_replicatedLayerPosition; + LayerAndroid* m_originalLayer; + // link to a mask layer + LayerAndroid* m_maskLayer; + typedef Layer INHERITED; }; diff --git a/Source/WebCore/platform/graphics/android/layers/LayerContent.h b/Source/WebCore/platform/graphics/android/layers/LayerContent.h index 2cd90a90..10b6507 100644 --- a/Source/WebCore/platform/graphics/android/layers/LayerContent.h +++ b/Source/WebCore/platform/graphics/android/layers/LayerContent.h @@ -43,6 +43,7 @@ public: virtual int width() = 0; virtual int height() = 0; virtual bool isEmpty() { return !width() || !height(); } + virtual void setCheckForOptimisations(bool check) = 0; virtual void checkForOptimisations() = 0; virtual bool hasText() = 0; virtual void draw(SkCanvas* canvas) = 0; diff --git a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h index 94bdfac..1567f44 100644 --- a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h +++ b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h @@ -39,6 +39,7 @@ public: virtual int width(); virtual int height(); virtual bool isEmpty(); + virtual void setCheckForOptimisations(bool check) { m_checkedContent = !check; } virtual void checkForOptimisations(); virtual bool hasText(); virtual void draw(SkCanvas* canvas); diff --git a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h index 4216617..4fc123e 100644 --- a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h +++ b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h @@ -37,6 +37,7 @@ public: virtual int width() { return m_picturePile.size().width(); } virtual int height() { return m_picturePile.size().height(); } + virtual void setCheckForOptimisations(bool check) {} virtual void checkForOptimisations() {} virtual bool hasText() { return true; } virtual void draw(SkCanvas* canvas); diff --git a/Source/WebCore/rendering/break_lines.cpp b/Source/WebCore/rendering/break_lines.cpp index 9ac3375..4dbf81b 100644 --- a/Source/WebCore/rendering/break_lines.cpp +++ b/Source/WebCore/rendering/break_lines.cpp @@ -119,29 +119,21 @@ COMPILE_ASSERT(WTF_ARRAY_LENGTH(asciiLineBreakTable) == asciiLineBreakTableLastC static inline bool shouldBreakAfter(UChar ch, UChar nextCh) { - switch (ch) { - case ideographicComma: - case ideographicFullStop: - // FIXME: cases for ideographicComma and ideographicFullStop are a workaround for an issue in Unicode 5.0 - // which is likely to be resolved in Unicode 5.1 <http://bugs.webkit.org/show_bug.cgi?id=17411>. - // We may want to remove or conditionalize this workaround at some point. #ifdef ANDROID_LAYOUT - // as '/' is used in uri which is always long, we would like to break it - case '/': -#endif + if (ch == '/') // as '/' is used in uri which is always long, we would like to break it return true; - default: - // If both ch and nextCh are ASCII characters, use a lookup table for enhanced speed and for compatibility - // with other browsers (see comments for asciiLineBreakTable for details). - if (ch >= asciiLineBreakTableFirstChar && ch <= asciiLineBreakTableLastChar - && nextCh >= asciiLineBreakTableFirstChar && nextCh <= asciiLineBreakTableLastChar) { - const unsigned char* tableRow = asciiLineBreakTable[ch - asciiLineBreakTableFirstChar]; - int nextChIndex = nextCh - asciiLineBreakTableFirstChar; - return tableRow[nextChIndex / 8] & (1 << (nextChIndex % 8)); - } - // Otherwise defer to the Unicode algorithm by returning false. - return false; +#endif + + // If both ch and nextCh are ASCII characters, use a lookup table for enhanced speed and for compatibility + // with other browsers (see comments for asciiLineBreakTable for details). + if (ch >= asciiLineBreakTableFirstChar && ch <= asciiLineBreakTableLastChar + && nextCh >= asciiLineBreakTableFirstChar && nextCh <= asciiLineBreakTableLastChar) { + const unsigned char* tableRow = asciiLineBreakTable[ch - asciiLineBreakTableFirstChar]; + int nextChIndex = nextCh - asciiLineBreakTableFirstChar; + return tableRow[nextChIndex / 8] & (1 << (nextChIndex % 8)); } + // Otherwise defer to the Unicode algorithm by returning false. + return false; } static inline bool needsLineBreakIterator(UChar ch) diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index e621644..1fe4a1d 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -1164,6 +1164,16 @@ void WebViewCore::setSizeScreenWidthAndScale(int width, int height, m_mainFrame->eventHandler()->hitTestResultAtPoint( anchorPoint, false); node = hitTestResult.innerNode(); + if (node && !node->isTextNode()) { + // If the hitTestResultAtPoint didn't find a suitable node + // for anchoring, try again with some slop. + static const int HIT_SLOP = 30; + anchorPoint.move(HIT_SLOP, HIT_SLOP); + hitTestResult = + m_mainFrame->eventHandler()->hitTestResultAtPoint( + anchorPoint, false); + node = hitTestResult.innerNode(); + } } if (node) { bounds = node->getRect(); |