diff options
Diffstat (limited to 'Source')
10 files changed, 231 insertions, 25 deletions
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk index 5df4d93..a516f48 100644 --- a/Source/WebCore/Android.mk +++ b/Source/WebCore/Android.mk @@ -681,6 +681,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ platform/graphics/android/TiledTexture.cpp \ platform/graphics/android/TransferQueue.cpp \ platform/graphics/android/UpdateManager.cpp \ + platform/graphics/android/VerticalTextMap.cpp \ platform/graphics/android/VideoLayerAndroid.cpp \ platform/graphics/android/VideoLayerManager.cpp \ platform/graphics/android/ZoomManager.cpp \ diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index 2d7b177..bf392578 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -296,10 +296,8 @@ void GLWebViewState::setViewport(SkRect& viewport, float scale) // allocate max possible number of tiles visible with this viewport int viewMaxTileX = static_cast<int>(ceilf((viewport.width()-1) * invTileContentWidth)) + 1; int viewMaxTileY = static_cast<int>(ceilf((viewport.height()-1) * invTileContentHeight)) + 1; - - // NOTE: fetching 4 viewports worth, may need to be adjusted per-device int maxTextureCount = (viewMaxTileX + TILE_PREFETCH_DISTANCE * 2) * - (viewMaxTileY + TILE_PREFETCH_DISTANCE * 2) * 4; + (viewMaxTileY + TILE_PREFETCH_DISTANCE * 2) * 2; TilesManager::instance()->setMaxTextureCount(maxTextureCount); m_tiledPageA->updateBaseTileSize(); m_tiledPageB->updateBaseTileSize(); @@ -453,8 +451,10 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, // TODO: upload as many textures as possible within a certain time limit bool ret = ImagesManager::instance()->uploadTextures(); - if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) + if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) { XLOGC("WARNING, scale seems corrupted after update: %e", scale); + CRASH(); + } // gather the textures we can use TilesManager::instance()->gatherLayerTextures(); diff --git a/Source/WebCore/platform/graphics/android/GlyphMapAndroid.cpp b/Source/WebCore/platform/graphics/android/GlyphMapAndroid.cpp index da9d99a..c5193b7 100644 --- a/Source/WebCore/platform/graphics/android/GlyphMapAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/GlyphMapAndroid.cpp @@ -32,6 +32,11 @@ #include "SkPaint.h" #include "SkUtils.h" #include "SimpleFontData.h" +#include "Font.h" +#include "SkFontHost.h" +#include "HarfbuzzSkia.h" +#include "VerticalTextMap.h" + using namespace android; @@ -39,6 +44,36 @@ namespace WebCore { #define NO_BREAK_SPACE_UNICHAR 0xA0 +static int substituteWithVerticalGlyphs(const FontPlatformData& platformData, uint16_t* glyphs, unsigned bufferLength) +{ + HB_FaceRec_* hbFace = platformData.harfbuzzFace(); + if (!hbFace->gsub) { + // if there is no GSUB table, treat it as not covered + return 0Xffff; + } + + HB_Buffer buffer; + hb_buffer_new(&buffer); + for (unsigned i = 0; i < bufferLength; ++i) + hb_buffer_add_glyph(buffer, glyphs[i], 0, i); + + HB_UShort scriptIndex; + HB_UShort featureIndex; + + HB_GSUB_Select_Script(hbFace->gsub, HB_MAKE_TAG('D', 'F', 'L', 'T'), &scriptIndex); + HB_GSUB_Select_Feature(hbFace->gsub, HB_MAKE_TAG('v', 'e', 'r', 't'), scriptIndex, 0xffff, &featureIndex); + HB_GSUB_Add_Feature(hbFace->gsub, featureIndex, 1); + HB_GSUB_Select_Feature(hbFace->gsub, HB_MAKE_TAG('v', 'r', 't', '2'), scriptIndex, 0xffff, &featureIndex); + HB_GSUB_Add_Feature(hbFace->gsub, featureIndex, 1); + + int error = HB_GSUB_Apply_String(hbFace->gsub, buffer); + if (!error) { + for (unsigned i = 0; i < bufferLength; ++i) + glyphs[i] = static_cast<Glyph>(buffer->out_string[i].gindex); + } + return error; +} + bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) { if (SkUTF16_IsHighSurrogate(buffer[bufferLength-1])) { @@ -49,21 +84,47 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b SkPaint paint; fontData->platformData().setupPaint(&paint); paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); - + SkAutoSTMalloc <GlyphPage::size, uint16_t> glyphStorage(length); uint16_t* glyphs = glyphStorage.get(); - unsigned count = paint.textToGlyphs(buffer, bufferLength << 1, glyphs); + UChar *textBuffer = buffer; + UChar vTextBuffer[bufferLength]; + + if (fontData->platformData().orientation() == Vertical && + !fontData->hasVerticalGlyphs()) { + // Convert to vertical form if there is no vertical glyphs. + for (unsigned i = 0; i < bufferLength; ++i) { + vTextBuffer[i] = VerticalTextMap::getVerticalForm(buffer[i]); + if (!vTextBuffer[i]) + vTextBuffer[i] = buffer[i]; + } + textBuffer = vTextBuffer; + } + + unsigned count = paint.textToGlyphs(textBuffer, bufferLength << 1, glyphs); if (count != length) { SkDebugf("%s count != length\n", __FUNCTION__); return false; } + if (fontData->hasVerticalGlyphs()) { + bool lookVariants = false; + for (unsigned i = 0; i < bufferLength; ++i) { + if (!Font::isCJKIdeograph(textBuffer[i])) { + lookVariants = true; + continue; + } + } + if (lookVariants) + substituteWithVerticalGlyphs(fontData->platformData(), glyphs, bufferLength); + } + unsigned allGlyphs = 0; // track if any of the glyphIDs are non-zero // search for emoji. If we knew for sure that buffer was a contiguous range // of chars, we could quick-reject the range to avoid this loop (usually) if (EmojiFont::IsAvailable()) { - const UChar* curr = buffer; + const UChar* curr = textBuffer; for (unsigned i = 0; i < length; i++) { SkUnichar uni = SkUTF16_NextUnichar(&curr); uint16_t glyphID = glyphs[i]; diff --git a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp index bbde998..691fbca 100644 --- a/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/ImageBufferAndroid.cpp @@ -85,11 +85,9 @@ PassRefPtr<Image> ImageBuffer::copyImage() const SkDevice* device = canvas->getDevice(); const SkBitmap& orig = device->accessBitmap(false); - if (!PlatformBridge::canSatisfyMemoryAllocation(orig.getSize())) - return 0; - SkBitmap copy; - orig.copyTo(©, orig.config()); + if (PlatformBridge::canSatisfyMemoryAllocation(orig.getSize())) + orig.copyTo(©, orig.config()); SkBitmapRef* ref = new SkBitmapRef(copy); RefPtr<Image> image = BitmapImage::create(ref, 0); diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp index 7edc4b8..74cc764 100644 --- a/Source/WebCore/platform/graphics/android/TilesManager.cpp +++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp @@ -69,7 +69,7 @@ // number to cap the layer tile texturs, it worked on both phones and tablets. // TODO: after merge the pool of base tiles and layer tiles, we should revisit // the logic of allocation management. -#define MAX_TEXTURE_ALLOCATION ((6+TILE_PREFETCH_DISTANCE*2)*(5+TILE_PREFETCH_DISTANCE*2)*4) +#define MAX_TEXTURE_ALLOCATION ((6+TILE_PREFETCH_DISTANCE*2)*(5+TILE_PREFETCH_DISTANCE*2)*2) #define TILE_WIDTH 256 #define TILE_HEIGHT 256 #define LAYER_TILE_WIDTH 256 diff --git a/Source/WebCore/platform/graphics/android/VerticalTextMap.cpp b/Source/WebCore/platform/graphics/android/VerticalTextMap.cpp new file mode 100644 index 0000000..2bb008f --- /dev/null +++ b/Source/WebCore/platform/graphics/android/VerticalTextMap.cpp @@ -0,0 +1,104 @@ +/* + * Copyright 2011, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "VerticalTextMap.h" + +#include <wtf/Forward.h> +#include <wtf/MessageQueue.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +static const UChar vTextCnvTable[][2] = { + // TODO: uncomment mappings once we add glyphs for vertical forms. + // {0x0021, 0xfe15}, // exclamation mark + {0x0028, 0xfe35}, // left paren + {0x0029, 0xfe36}, // right paren + // {0x002c, 0xfe10}, // comma + {0x003a, 0xfe30}, // colon + {0x003b, 0x007c}, // hyphen + // {0x003f, 0xfe16}, // question mark + // {0x005b, 0xfe14}, // semicolon + {0x005d, 0xfe47}, // left square bracket + {0x005f, 0xfe48}, // right square bracket + {0x007b, 0xfe37}, // left curly bracket + {0x007d, 0xfe38}, // right curly bracket + {0x007e, 0x007c}, // tilde to vertical line + {0x2013, 0xfe32}, // en dash + {0x2014, 0xfe31}, // em dash + {0x2015, 0xfe31}, // horizontal bar + {0x2025, 0xfe30}, // two dot leader + // TODO: change the mapping 0x2026 -> 0xFE19 once Android has the glyph for 0xFE19. + {0x2026, 0xfe30}, // three dot leader + // {0x3001, 0xfe11}, // Ideographic comma + // {0x3002, 0xfe12}, // Ideographic full stop + {0x3008, 0xfe3f}, // left angle bracket + {0x3009, 0xfe40}, // right angle bracket + {0x300a, 0xfe3d}, // left double angle bracket + {0x300b, 0xfe3e}, // right double angle bracket + {0x300c, 0xfe41}, // left corner bracket + {0x300d, 0xfe42}, // right corner bracket + {0x300e, 0xfe43}, // left white corner bracket + {0x300f, 0xfe44}, // right white corner bracket + {0x3010, 0xfe3b}, // left black lenticular bracket + {0x3011, 0xfe3c}, // right black lenticular bracket + {0x3014, 0xfe39}, // left black lenticular bracket + {0x3015, 0xfe3a}, // right tortise shell bracket + // {0x3016, 0xfe17}, // left white lenticular bracket + // {0x3017, 0xfe18}, // right white lenticular bracket + // {0x3019, 0xfe19}, // horizontal ellipses + {0x30fc, 0x3021}, // prolonged sound + {0xfe4f, 0xfe34}, // wavy low line + {0xff08, 0xfe35}, // full width left paren + {0xff09, 0xfe36}, // full width right paren + {0xff3b, 0xfe47}, // full width left square bracket + {0xff3d, 0xfe48}, // full width right square bracket + {0xff5b, 0xfe37}, // full width left curly bracket + {0xff5d, 0xfe38}, // full width right curly bracket + // {0xff64, 0xfe11}, // halfwidth ideo comma + // {0xff61, 0xfe12}, // halfwidth ideo full stop +}; + +using namespace android; + +namespace WebCore { + +static WTF::Mutex m_verticalTextHashMapMutex; +static HashMap<UChar, UChar>* verticalTextHashMap = 0; + +UChar VerticalTextMap::getVerticalForm(UChar c) { + { + MutexLocker lock(m_verticalTextHashMapMutex); + if (!verticalTextHashMap) { + // Lazy initialization. + verticalTextHashMap = new HashMap<UChar, UChar>; + for (size_t i = 0; i < WTF_ARRAY_LENGTH(vTextCnvTable); ++i) + verticalTextHashMap->set(vTextCnvTable[i][0], vTextCnvTable[i][1]); + } + } + return verticalTextHashMap->get(c); +} + +} diff --git a/Source/WebCore/platform/graphics/android/VerticalTextMap.h b/Source/WebCore/platform/graphics/android/VerticalTextMap.h new file mode 100644 index 0000000..f614633 --- /dev/null +++ b/Source/WebCore/platform/graphics/android/VerticalTextMap.h @@ -0,0 +1,47 @@ +/* + * Copyright 2011, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef android_VerticalTextMap_DEFINED +#define android_VerticalTextMap_DEFINED + +#include "config.h" +#include "WebViewCore.h" +#include <wtf/StdLibExtras.h> +#include <wtf/HashMap.h> +#include <wtf/unicode/CharacterNames.h> + +using namespace android; + +namespace WebCore { + class VerticalTextMap { + public: + // This function converts given char to its corresponding vertical form. + // Rerturns 0 if there is no vertical form. + static UChar getVerticalForm(UChar c); + }; +} + +#endif diff --git a/Source/WebKit/android/nav/CacheBuilder.cpp b/Source/WebKit/android/nav/CacheBuilder.cpp index a4bc758..623d2cb 100644 --- a/Source/WebKit/android/nav/CacheBuilder.cpp +++ b/Source/WebKit/android/nav/CacheBuilder.cpp @@ -1406,7 +1406,6 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, else if (cachedNode.clip(clip) == false) continue; // skip this node if outside of the clip } - cachedNode.setNavableRects(); cachedNode.setColorIndex(colorIndex); cachedNode.setExport(exported); cachedNode.setHasCursorRing(hasCursorRing); @@ -1478,7 +1477,6 @@ bool CacheBuilder::CleanUpContainedNodes(CachedRoot* cachedRoot, lastNode->hasTagName(HTMLNames::formTag)) { lastCached->setBounds(IntRect(0, 0, 0, 0)); lastCached->mCursorRing.clear(); - lastCached->setNavableRects(); return false; } CachedNode* onlyChildCached = cachedFrame->lastNode(); diff --git a/Source/WebKit/android/nav/CachedNode.cpp b/Source/WebKit/android/nav/CachedNode.cpp index 86c2a38..e500875 100644 --- a/Source/WebKit/android/nav/CachedNode.cpp +++ b/Source/WebKit/android/nav/CachedNode.cpp @@ -92,10 +92,9 @@ void CachedNode::cursorRings(const CachedFrame* frame, WebCore::IntRect CachedNode::cursorRingBounds(const CachedFrame* frame) const { - int partMax = mNavableRects; - ASSERT(partMax > 0); - WebCore::IntRect bounds = mCursorRing[0]; - for (int partIndex = 1; partIndex < partMax; partIndex++) + int partMax = navableRects(); + WebCore::IntRect bounds; + for (int partIndex = 0; partIndex < partMax; partIndex++) bounds.unite(mCursorRing[partIndex]); bounds.inflate(CURSOR_RING_HIT_TEST_RADIUS); return mIsInLayer ? frame->adjustBounds(this, bounds) : bounds; @@ -116,7 +115,7 @@ void CachedNode::fixUpCursorRects(const CachedFrame* frame) mUseHitBounds = true; return; } - if (mNavableRects <= 1) + if (navableRects() <= 1) return; // if there is more than 1 rect, and the bounds doesn't intersect // any other cursor ring bounds, use it @@ -290,8 +289,8 @@ void CachedNode::move(int x, int y) bool CachedNode::partRectsContains(const CachedNode* other) const { int outerIndex = 0; - int outerMax = mNavableRects; - int innerMax = other->mNavableRects; + int outerMax = navableRects(); + int innerMax = other->navableRects(); do { const WebCore::IntRect& outerBounds = mCursorRing[outerIndex]; int innerIndex = 0; @@ -403,7 +402,7 @@ void CachedNode::Debug::print() const DUMP_NAV_LOGD("// void* mParentGroup=%p; // (%d) \n", b->mParentGroup, mParentGroupIndex); DUMP_NAV_LOGD("// int mDataIndex=%d;\n", b->mDataIndex); DUMP_NAV_LOGD("// int mIndex=%d;\n", b->mIndex); - DUMP_NAV_LOGD("// int mNavableRects=%d;\n", b->mNavableRects); + DUMP_NAV_LOGD("// int navableRects()=%d;\n", b->navableRects()); DUMP_NAV_LOGD("// int mParentIndex=%d;\n", b->mParentIndex); DUMP_NAV_LOGD("// int mTabIndex=%d;\n", b->mTabIndex); DUMP_NAV_LOGD("// int mColorIndex=%d;\n", b->mColorIndex); diff --git a/Source/WebKit/android/nav/CachedNode.h b/Source/WebKit/android/nav/CachedNode.h index 602dda6..321b7fd 100644 --- a/Source/WebKit/android/nav/CachedNode.h +++ b/Source/WebKit/android/nav/CachedNode.h @@ -136,7 +136,7 @@ public: WebCore::IntRect localHitBounds(const CachedFrame* ) const; WebCore::IntRect localRing(const CachedFrame* , size_t part) const; void move(int x, int y); - int navableRects() const { return mNavableRects; } + int navableRects() const { return mCursorRing.size(); } void* nodePointer() const { return mNode; } bool noSecondChance() const { return mCondition > SECOND_CHANCE_END; } const WebCore::IntRect& originalAbsoluteBounds() const { @@ -169,7 +169,6 @@ public: void setIsTransparent(bool isTransparent) { mIsTransparent = isTransparent; } void setIsUnclipped(bool unclipped) { mIsUnclipped = unclipped; } void setLast() { mLast = true; } - void setNavableRects() { mNavableRects = mCursorRing.size(); } void setParentGroup(void* group) { mParentGroup = group; } void setParentIndex(int parent) { mParentIndex = parent; } void setSingleImage(bool single) { mSingleImage = single; } @@ -195,7 +194,6 @@ private: void* mParentGroup; // WebCore::Node*, only used to match pointers int mDataIndex; // child frame if a frame; input data index; or -1 int mIndex; // index of itself, to find first in array (document) - int mNavableRects; // FIXME: could be bitfield once I limit max number of rects int mParentIndex; int mTabIndex; int mColorIndex; // index to ring color and other stylable properties |